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,416 @@
1
+ /* -----------------------------------------------------------------------
2
+ darwin64.S - Copyright (c) 2006 Free Software Foundation, Inc.
3
+ Copyright (c) 2008 Red Hat, Inc.
4
+ derived from unix64.S
5
+
6
+ x86-64 Foreign Function Interface for Darwin.
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining
9
+ a copy of this software and associated documentation files (the
10
+ ``Software''), to deal in the Software without restriction, including
11
+ without limitation the rights to use, copy, modify, merge, publish,
12
+ distribute, sublicense, and/or sell copies of the Software, and to
13
+ permit persons to whom the Software is furnished to do so, subject to
14
+ the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included
17
+ in all copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
20
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
23
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
+ OTHER DEALINGS IN THE SOFTWARE.
26
+ ----------------------------------------------------------------------- */
27
+
28
+ #ifdef __x86_64__
29
+ #define LIBFFI_ASM
30
+ #include <fficonfig.h>
31
+ #include <ffi.h>
32
+
33
+ .file "darwin64.S"
34
+ .text
35
+
36
+ /* ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags,
37
+ void *raddr, void (*fnaddr)(void));
38
+
39
+ Bit o trickiness here -- ARGS+BYTES is the base of the stack frame
40
+ for this function. This has been allocated by ffi_call. We also
41
+ deallocate some of the stack that has been alloca'd. */
42
+
43
+ .align 3
44
+ .globl _ffi_call_unix64
45
+
46
+ _ffi_call_unix64:
47
+ LUW0:
48
+ movq (%rsp), %r10 /* Load return address. */
49
+ leaq (%rdi, %rsi), %rax /* Find local stack base. */
50
+ movq %rdx, (%rax) /* Save flags. */
51
+ movq %rcx, 8(%rax) /* Save raddr. */
52
+ movq %rbp, 16(%rax) /* Save old frame pointer. */
53
+ movq %r10, 24(%rax) /* Relocate return address. */
54
+ movq %rax, %rbp /* Finalize local stack frame. */
55
+ LUW1:
56
+ movq %rdi, %r10 /* Save a copy of the register area. */
57
+ movq %r8, %r11 /* Save a copy of the target fn. */
58
+ movl %r9d, %eax /* Set number of SSE registers. */
59
+
60
+ /* Load up all argument registers. */
61
+ movq (%r10), %rdi
62
+ movq 8(%r10), %rsi
63
+ movq 16(%r10), %rdx
64
+ movq 24(%r10), %rcx
65
+ movq 32(%r10), %r8
66
+ movq 40(%r10), %r9
67
+ testl %eax, %eax
68
+ jnz Lload_sse
69
+ Lret_from_load_sse:
70
+
71
+ /* Deallocate the reg arg area. */
72
+ leaq 176(%r10), %rsp
73
+
74
+ /* Call the user function. */
75
+ call *%r11
76
+
77
+ /* Deallocate stack arg area; local stack frame in redzone. */
78
+ leaq 24(%rbp), %rsp
79
+
80
+ movq 0(%rbp), %rcx /* Reload flags. */
81
+ movq 8(%rbp), %rdi /* Reload raddr. */
82
+ movq 16(%rbp), %rbp /* Reload old frame pointer. */
83
+ LUW2:
84
+
85
+ /* The first byte of the flags contains the FFI_TYPE. */
86
+ movzbl %cl, %r10d
87
+ leaq Lstore_table(%rip), %r11
88
+ movslq (%r11, %r10, 4), %r10
89
+ addq %r11, %r10
90
+ jmp *%r10
91
+
92
+ Lstore_table:
93
+ .long Lst_void-Lstore_table /* FFI_TYPE_VOID */
94
+ .long Lst_sint32-Lstore_table /* FFI_TYPE_INT */
95
+ .long Lst_float-Lstore_table /* FFI_TYPE_FLOAT */
96
+ .long Lst_double-Lstore_table /* FFI_TYPE_DOUBLE */
97
+ .long Lst_ldouble-Lstore_table /* FFI_TYPE_LONGDOUBLE */
98
+ .long Lst_uint8-Lstore_table /* FFI_TYPE_UINT8 */
99
+ .long Lst_sint8-Lstore_table /* FFI_TYPE_SINT8 */
100
+ .long Lst_uint16-Lstore_table /* FFI_TYPE_UINT16 */
101
+ .long Lst_sint16-Lstore_table /* FFI_TYPE_SINT16 */
102
+ .long Lst_uint32-Lstore_table /* FFI_TYPE_UINT32 */
103
+ .long Lst_sint32-Lstore_table /* FFI_TYPE_SINT32 */
104
+ .long Lst_int64-Lstore_table /* FFI_TYPE_UINT64 */
105
+ .long Lst_int64-Lstore_table /* FFI_TYPE_SINT64 */
106
+ .long Lst_struct-Lstore_table /* FFI_TYPE_STRUCT */
107
+ .long Lst_int64-Lstore_table /* FFI_TYPE_POINTER */
108
+
109
+ .text
110
+ .align 3
111
+ Lst_void:
112
+ ret
113
+ .align 3
114
+ Lst_uint8:
115
+ movzbq %al, %rax
116
+ movq %rax, (%rdi)
117
+ ret
118
+ .align 3
119
+ Lst_sint8:
120
+ movsbq %al, %rax
121
+ movq %rax, (%rdi)
122
+ ret
123
+ .align 3
124
+ Lst_uint16:
125
+ movzwq %ax, %rax
126
+ movq %rax, (%rdi)
127
+ .align 3
128
+ Lst_sint16:
129
+ movswq %ax, %rax
130
+ movq %rax, (%rdi)
131
+ ret
132
+ .align 3
133
+ Lst_uint32:
134
+ movl %eax, %eax
135
+ movq %rax, (%rdi)
136
+ .align 3
137
+ Lst_sint32:
138
+ cltq
139
+ movq %rax, (%rdi)
140
+ ret
141
+ .align 3
142
+ Lst_int64:
143
+ movq %rax, (%rdi)
144
+ ret
145
+ .align 3
146
+ Lst_float:
147
+ movss %xmm0, (%rdi)
148
+ ret
149
+ .align 3
150
+ Lst_double:
151
+ movsd %xmm0, (%rdi)
152
+ ret
153
+ Lst_ldouble:
154
+ fstpt (%rdi)
155
+ ret
156
+ .align 3
157
+ Lst_struct:
158
+ leaq -20(%rsp), %rsi /* Scratch area in redzone. */
159
+
160
+ /* We have to locate the values now, and since we don't want to
161
+ write too much data into the user's return value, we spill the
162
+ value to a 16 byte scratch area first. Bits 8, 9, and 10
163
+ control where the values are located. Only one of the three
164
+ bits will be set; see ffi_prep_cif_machdep for the pattern. */
165
+ movd %xmm0, %r10
166
+ movd %xmm1, %r11
167
+ testl $0x100, %ecx
168
+ cmovnz %rax, %rdx
169
+ cmovnz %r10, %rax
170
+ testl $0x200, %ecx
171
+ cmovnz %r10, %rdx
172
+ testl $0x400, %ecx
173
+ cmovnz %r10, %rax
174
+ cmovnz %r11, %rdx
175
+ movq %rax, (%rsi)
176
+ movq %rdx, 8(%rsi)
177
+
178
+ /* Bits 12-31 contain the true size of the structure. Copy from
179
+ the scratch area to the true destination. */
180
+ shrl $12, %ecx
181
+ rep movsb
182
+ ret
183
+
184
+ /* Many times we can avoid loading any SSE registers at all.
185
+ It's not worth an indirect jump to load the exact set of
186
+ SSE registers needed; zero or all is a good compromise. */
187
+ .align 3
188
+ LUW3:
189
+ Lload_sse:
190
+ movdqa 48(%r10), %xmm0
191
+ movdqa 64(%r10), %xmm1
192
+ movdqa 80(%r10), %xmm2
193
+ movdqa 96(%r10), %xmm3
194
+ movdqa 112(%r10), %xmm4
195
+ movdqa 128(%r10), %xmm5
196
+ movdqa 144(%r10), %xmm6
197
+ movdqa 160(%r10), %xmm7
198
+ jmp Lret_from_load_sse
199
+
200
+ LUW4:
201
+ .align 3
202
+ .globl _ffi_closure_unix64
203
+
204
+ _ffi_closure_unix64:
205
+ LUW5:
206
+ /* The carry flag is set by the trampoline iff SSE registers
207
+ are used. Don't clobber it before the branch instruction. */
208
+ leaq -200(%rsp), %rsp
209
+ LUW6:
210
+ movq %rdi, (%rsp)
211
+ movq %rsi, 8(%rsp)
212
+ movq %rdx, 16(%rsp)
213
+ movq %rcx, 24(%rsp)
214
+ movq %r8, 32(%rsp)
215
+ movq %r9, 40(%rsp)
216
+ jc Lsave_sse
217
+ Lret_from_save_sse:
218
+
219
+ movq %r10, %rdi
220
+ leaq 176(%rsp), %rsi
221
+ movq %rsp, %rdx
222
+ leaq 208(%rsp), %rcx
223
+ call _ffi_closure_unix64_inner
224
+
225
+ /* Deallocate stack frame early; return value is now in redzone. */
226
+ addq $200, %rsp
227
+ LUW7:
228
+
229
+ /* The first byte of the return value contains the FFI_TYPE. */
230
+ movzbl %al, %r10d
231
+ leaq Lload_table(%rip), %r11
232
+ movslq (%r11, %r10, 4), %r10
233
+ addq %r11, %r10
234
+ jmp *%r10
235
+
236
+ Lload_table:
237
+ .long Lld_void-Lload_table /* FFI_TYPE_VOID */
238
+ .long Lld_int32-Lload_table /* FFI_TYPE_INT */
239
+ .long Lld_float-Lload_table /* FFI_TYPE_FLOAT */
240
+ .long Lld_double-Lload_table /* FFI_TYPE_DOUBLE */
241
+ .long Lld_ldouble-Lload_table /* FFI_TYPE_LONGDOUBLE */
242
+ .long Lld_int8-Lload_table /* FFI_TYPE_UINT8 */
243
+ .long Lld_int8-Lload_table /* FFI_TYPE_SINT8 */
244
+ .long Lld_int16-Lload_table /* FFI_TYPE_UINT16 */
245
+ .long Lld_int16-Lload_table /* FFI_TYPE_SINT16 */
246
+ .long Lld_int32-Lload_table /* FFI_TYPE_UINT32 */
247
+ .long Lld_int32-Lload_table /* FFI_TYPE_SINT32 */
248
+ .long Lld_int64-Lload_table /* FFI_TYPE_UINT64 */
249
+ .long Lld_int64-Lload_table /* FFI_TYPE_SINT64 */
250
+ .long Lld_struct-Lload_table /* FFI_TYPE_STRUCT */
251
+ .long Lld_int64-Lload_table /* FFI_TYPE_POINTER */
252
+
253
+ .text
254
+ .align 3
255
+ Lld_void:
256
+ ret
257
+ .align 3
258
+ Lld_int8:
259
+ movzbl -24(%rsp), %eax
260
+ ret
261
+ .align 3
262
+ Lld_int16:
263
+ movzwl -24(%rsp), %eax
264
+ ret
265
+ .align 3
266
+ Lld_int32:
267
+ movl -24(%rsp), %eax
268
+ ret
269
+ .align 3
270
+ Lld_int64:
271
+ movq -24(%rsp), %rax
272
+ ret
273
+ .align 3
274
+ Lld_float:
275
+ movss -24(%rsp), %xmm0
276
+ ret
277
+ .align 3
278
+ Lld_double:
279
+ movsd -24(%rsp), %xmm0
280
+ ret
281
+ .align 3
282
+ Lld_ldouble:
283
+ fldt -24(%rsp)
284
+ ret
285
+ .align 3
286
+ Lld_struct:
287
+ /* There are four possibilities here, %rax/%rdx, %xmm0/%rax,
288
+ %rax/%xmm0, %xmm0/%xmm1. We collapse two by always loading
289
+ both rdx and xmm1 with the second word. For the remaining,
290
+ bit 8 set means xmm0 gets the second word, and bit 9 means
291
+ that rax gets the second word. */
292
+ movq -24(%rsp), %rcx
293
+ movq -16(%rsp), %rdx
294
+ movq -16(%rsp), %xmm1
295
+ testl $0x100, %eax
296
+ cmovnz %rdx, %rcx
297
+ movd %rcx, %xmm0
298
+ testl $0x200, %eax
299
+ movq -24(%rsp), %rax
300
+ cmovnz %rdx, %rax
301
+ ret
302
+
303
+ /* See the comment above Lload_sse; the same logic applies here. */
304
+ .align 3
305
+ LUW8:
306
+ Lsave_sse:
307
+ movdqa %xmm0, 48(%rsp)
308
+ movdqa %xmm1, 64(%rsp)
309
+ movdqa %xmm2, 80(%rsp)
310
+ movdqa %xmm3, 96(%rsp)
311
+ movdqa %xmm4, 112(%rsp)
312
+ movdqa %xmm5, 128(%rsp)
313
+ movdqa %xmm6, 144(%rsp)
314
+ movdqa %xmm7, 160(%rsp)
315
+ jmp Lret_from_save_sse
316
+
317
+ LUW9:
318
+ .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
319
+ EH_frame1:
320
+ .set L$set$0,LECIE1-LSCIE1 /* CIE Length */
321
+ .long L$set$0
322
+ LSCIE1:
323
+ .long 0x0 /* CIE Identifier Tag */
324
+ .byte 0x1 /* CIE Version */
325
+ .ascii "zR\0" /* CIE Augmentation */
326
+ .byte 0x1 /* uleb128 0x1; CIE Code Alignment Factor */
327
+ .byte 0x78 /* sleb128 -8; CIE Data Alignment Factor */
328
+ .byte 0x10 /* CIE RA Column */
329
+ .byte 0x1 /* uleb128 0x1; Augmentation size */
330
+ .byte 0x10 /* FDE Encoding (pcrel sdata4) */
331
+ .byte 0xc /* DW_CFA_def_cfa, %rsp offset 8 */
332
+ .byte 0x7 /* uleb128 0x7 */
333
+ .byte 0x8 /* uleb128 0x8 */
334
+ .byte 0x90 /* DW_CFA_offset, column 0x10 */
335
+ .byte 0x1
336
+ .align 3
337
+ LECIE1:
338
+ .globl _ffi_call_unix64.eh
339
+ _ffi_call_unix64.eh:
340
+ LSFDE1:
341
+ .set L$set$1,LEFDE1-LASFDE1 /* FDE Length */
342
+ .long L$set$1
343
+ LASFDE1:
344
+ .long LASFDE1-EH_frame1 /* FDE CIE offset */
345
+ .quad LUW0-. /* FDE initial location */
346
+ .set L$set$2,LUW4-LUW0 /* FDE address range */
347
+ .quad L$set$2
348
+ .byte 0x0 /* Augmentation size */
349
+ .byte 0x4 /* DW_CFA_advance_loc4 */
350
+ .set L$set$3,LUW1-LUW0
351
+ .long L$set$3
352
+
353
+ /* New stack frame based off rbp. This is a itty bit of unwind
354
+ trickery in that the CFA *has* changed. There is no easy way
355
+ to describe it correctly on entry to the function. Fortunately,
356
+ it doesn't matter too much since at all points we can correctly
357
+ unwind back to ffi_call. Note that the location to which we
358
+ moved the return address is (the new) CFA-8, so from the
359
+ perspective of the unwind info, it hasn't moved. */
360
+ .byte 0xc /* DW_CFA_def_cfa, %rbp offset 32 */
361
+ .byte 0x6
362
+ .byte 0x20
363
+ .byte 0x80+6 /* DW_CFA_offset, %rbp offset 2*-8 */
364
+ .byte 0x2
365
+ .byte 0xa /* DW_CFA_remember_state */
366
+
367
+ .byte 0x4 /* DW_CFA_advance_loc4 */
368
+ .set L$set$4,LUW2-LUW1
369
+ .long L$set$4
370
+ .byte 0xc /* DW_CFA_def_cfa, %rsp offset 8 */
371
+ .byte 0x7
372
+ .byte 0x8
373
+ .byte 0xc0+6 /* DW_CFA_restore, %rbp */
374
+
375
+ .byte 0x4 /* DW_CFA_advance_loc4 */
376
+ .set L$set$5,LUW3-LUW2
377
+ .long L$set$5
378
+ .byte 0xb /* DW_CFA_restore_state */
379
+
380
+ .align 3
381
+ LEFDE1:
382
+ .globl _ffi_closure_unix64.eh
383
+ _ffi_closure_unix64.eh:
384
+ LSFDE3:
385
+ .set L$set$6,LEFDE3-LASFDE3 /* FDE Length */
386
+ .long L$set$6
387
+ LASFDE3:
388
+ .long LASFDE3-EH_frame1 /* FDE CIE offset */
389
+ .quad LUW5-. /* FDE initial location */
390
+ .set L$set$7,LUW9-LUW5 /* FDE address range */
391
+ .quad L$set$7
392
+ .byte 0x0 /* Augmentation size */
393
+
394
+ .byte 0x4 /* DW_CFA_advance_loc4 */
395
+ .set L$set$8,LUW6-LUW5
396
+ .long L$set$8
397
+ .byte 0xe /* DW_CFA_def_cfa_offset */
398
+ .byte 208,1 /* uleb128 208 */
399
+ .byte 0xa /* DW_CFA_remember_state */
400
+
401
+ .byte 0x4 /* DW_CFA_advance_loc4 */
402
+ .set L$set$9,LUW7-LUW6
403
+ .long L$set$9
404
+ .byte 0xe /* DW_CFA_def_cfa_offset */
405
+ .byte 0x8
406
+
407
+ .byte 0x4 /* DW_CFA_advance_loc4 */
408
+ .set L$set$10,LUW8-LUW7
409
+ .long L$set$10
410
+ .byte 0xb /* DW_CFA_restore_state */
411
+
412
+ .align 3
413
+ LEFDE3:
414
+ .subsections_via_symbols
415
+
416
+ #endif /* __x86_64__ */
@@ -0,0 +1,475 @@
1
+ /* -----------------------------------------------------------------------
2
+ ffi.c - Copyright (c) 1996, 1998, 1999, 2001, 2007, 2008 Red Hat, Inc.
3
+ Copyright (c) 2002 Ranjit Mathew
4
+ Copyright (c) 2002 Bo Thorsen
5
+ Copyright (c) 2002 Roger Sayle
6
+ Copyright (C) 2008 Free Software Foundation, Inc.
7
+
8
+ x86 Foreign Function Interface
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,
22
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28
+ DEALINGS IN THE SOFTWARE.
29
+ ----------------------------------------------------------------------- */
30
+
31
+ #ifndef __x86_64__
32
+
33
+ #include <ffi.h>
34
+ #include <ffi_common.h>
35
+
36
+ #include <stdlib.h>
37
+
38
+ /* ffi_prep_args is called by the assembly routine once stack space
39
+ has been allocated for the function's arguments */
40
+
41
+ void ffi_prep_args(char *stack, extended_cif *ecif)
42
+ {
43
+ register unsigned int i;
44
+ register void **p_argv;
45
+ register char *argp;
46
+ register ffi_type **p_arg;
47
+
48
+ argp = stack;
49
+
50
+ if (ecif->cif->flags == FFI_TYPE_STRUCT)
51
+ {
52
+ *(void **) argp = ecif->rvalue;
53
+ argp += 4;
54
+ }
55
+
56
+ p_argv = ecif->avalue;
57
+
58
+ for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
59
+ i != 0;
60
+ i--, p_arg++)
61
+ {
62
+ size_t z;
63
+
64
+ /* Align if necessary */
65
+ if ((sizeof(int) - 1) & (unsigned) argp)
66
+ argp = (char *) ALIGN(argp, sizeof(int));
67
+
68
+ z = (*p_arg)->size;
69
+ if (z < sizeof(int))
70
+ {
71
+ z = sizeof(int);
72
+ switch ((*p_arg)->type)
73
+ {
74
+ case FFI_TYPE_SINT8:
75
+ *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
76
+ break;
77
+
78
+ case FFI_TYPE_UINT8:
79
+ *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
80
+ break;
81
+
82
+ case FFI_TYPE_SINT16:
83
+ *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
84
+ break;
85
+
86
+ case FFI_TYPE_UINT16:
87
+ *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
88
+ break;
89
+
90
+ case FFI_TYPE_SINT32:
91
+ *(signed int *) argp = (signed int)*(SINT32 *)(* p_argv);
92
+ break;
93
+
94
+ case FFI_TYPE_UINT32:
95
+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
96
+ break;
97
+
98
+ case FFI_TYPE_STRUCT:
99
+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
100
+ break;
101
+
102
+ default:
103
+ FFI_ASSERT(0);
104
+ }
105
+ }
106
+ else
107
+ {
108
+ memcpy(argp, *p_argv, z);
109
+ }
110
+ p_argv++;
111
+ argp += z;
112
+ }
113
+
114
+ return;
115
+ }
116
+
117
+ /* Perform machine dependent cif processing */
118
+ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
119
+ {
120
+ /* Set the return type flag */
121
+ switch (cif->rtype->type)
122
+ {
123
+ case FFI_TYPE_VOID:
124
+ #ifdef X86
125
+ case FFI_TYPE_STRUCT:
126
+ #endif
127
+ #if defined(X86) || defined(X86_DARWIN)
128
+ case FFI_TYPE_UINT8:
129
+ case FFI_TYPE_UINT16:
130
+ case FFI_TYPE_SINT8:
131
+ case FFI_TYPE_SINT16:
132
+ #endif
133
+
134
+ case FFI_TYPE_SINT64:
135
+ case FFI_TYPE_FLOAT:
136
+ case FFI_TYPE_DOUBLE:
137
+ case FFI_TYPE_LONGDOUBLE:
138
+ cif->flags = (unsigned) cif->rtype->type;
139
+ break;
140
+
141
+ case FFI_TYPE_UINT64:
142
+ cif->flags = FFI_TYPE_SINT64;
143
+ break;
144
+
145
+ #ifndef X86
146
+ case FFI_TYPE_STRUCT:
147
+ if (cif->rtype->size == 1)
148
+ {
149
+ cif->flags = FFI_TYPE_SMALL_STRUCT_1B; /* same as char size */
150
+ }
151
+ else if (cif->rtype->size == 2)
152
+ {
153
+ cif->flags = FFI_TYPE_SMALL_STRUCT_2B; /* same as short size */
154
+ }
155
+ else if (cif->rtype->size == 4)
156
+ {
157
+ cif->flags = FFI_TYPE_INT; /* same as int type */
158
+ }
159
+ else if (cif->rtype->size == 8)
160
+ {
161
+ cif->flags = FFI_TYPE_SINT64; /* same as int64 type */
162
+ }
163
+ else
164
+ {
165
+ cif->flags = FFI_TYPE_STRUCT;
166
+ }
167
+ break;
168
+ #endif
169
+
170
+ default:
171
+ cif->flags = FFI_TYPE_INT;
172
+ break;
173
+ }
174
+
175
+ #ifdef X86_DARWIN
176
+ cif->bytes = (cif->bytes + 15) & ~0xF;
177
+ #endif
178
+
179
+ return FFI_OK;
180
+ }
181
+
182
+ extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
183
+ unsigned, unsigned, unsigned *, void (*fn)(void));
184
+
185
+ #ifdef X86_WIN32
186
+ extern void ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *,
187
+ unsigned, unsigned, unsigned *, void (*fn)(void));
188
+
189
+ #endif /* X86_WIN32 */
190
+
191
+ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
192
+ {
193
+ extended_cif ecif;
194
+
195
+ ecif.cif = cif;
196
+ ecif.avalue = avalue;
197
+
198
+ /* If the return value is a struct and we don't have a return */
199
+ /* value address then we need to make one */
200
+
201
+ if ((rvalue == NULL) &&
202
+ (cif->flags == FFI_TYPE_STRUCT))
203
+ {
204
+ ecif.rvalue = alloca(cif->rtype->size);
205
+ }
206
+ else
207
+ ecif.rvalue = rvalue;
208
+
209
+
210
+ switch (cif->abi)
211
+ {
212
+ case FFI_SYSV:
213
+ ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
214
+ fn);
215
+ break;
216
+ #ifdef X86_WIN32
217
+ case FFI_STDCALL:
218
+ ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes, cif->flags,
219
+ ecif.rvalue, fn);
220
+ break;
221
+ #endif /* X86_WIN32 */
222
+ default:
223
+ FFI_ASSERT(0);
224
+ break;
225
+ }
226
+ }
227
+
228
+
229
+ /** private members **/
230
+
231
+ static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
232
+ void** args, ffi_cif* cif);
233
+ void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *)
234
+ __attribute__ ((regparm(1)));
235
+ unsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *)
236
+ __attribute__ ((regparm(1)));
237
+ void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *)
238
+ __attribute__ ((regparm(1)));
239
+ #ifdef X86_WIN32
240
+ void FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *)
241
+ __attribute__ ((regparm(1)));
242
+ #endif
243
+
244
+ /* This function is jumped to by the trampoline */
245
+
246
+ unsigned int FFI_HIDDEN
247
+ ffi_closure_SYSV_inner (closure, respp, args)
248
+ ffi_closure *closure;
249
+ void **respp;
250
+ void *args;
251
+ {
252
+ /* our various things... */
253
+ ffi_cif *cif;
254
+ void **arg_area;
255
+
256
+ cif = closure->cif;
257
+ arg_area = (void**) alloca (cif->nargs * sizeof (void*));
258
+
259
+ /* this call will initialize ARG_AREA, such that each
260
+ * element in that array points to the corresponding
261
+ * value on the stack; and if the function returns
262
+ * a structure, it will re-set RESP to point to the
263
+ * structure return address. */
264
+
265
+ ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);
266
+
267
+ (closure->fun) (cif, *respp, arg_area, closure->user_data);
268
+
269
+ return cif->flags;
270
+ }
271
+
272
+ static void
273
+ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
274
+ ffi_cif *cif)
275
+ {
276
+ register unsigned int i;
277
+ register void **p_argv;
278
+ register char *argp;
279
+ register ffi_type **p_arg;
280
+
281
+ argp = stack;
282
+
283
+ if ( cif->flags == FFI_TYPE_STRUCT ) {
284
+ *rvalue = *(void **) argp;
285
+ argp += 4;
286
+ }
287
+
288
+ p_argv = avalue;
289
+
290
+ for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
291
+ {
292
+ size_t z;
293
+
294
+ /* Align if necessary */
295
+ if ((sizeof(int) - 1) & (unsigned) argp) {
296
+ argp = (char *) ALIGN(argp, sizeof(int));
297
+ }
298
+
299
+ z = (*p_arg)->size;
300
+
301
+ /* because we're little endian, this is what it turns into. */
302
+
303
+ *p_argv = (void*) argp;
304
+
305
+ p_argv++;
306
+ argp += z;
307
+ }
308
+
309
+ return;
310
+ }
311
+
312
+ /* How to make a trampoline. Derived from gcc/config/i386/i386.c. */
313
+
314
+ #define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
315
+ ({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
316
+ unsigned int __fun = (unsigned int)(FUN); \
317
+ unsigned int __ctx = (unsigned int)(CTX); \
318
+ unsigned int __dis = __fun - (__ctx + 10); \
319
+ *(unsigned char*) &__tramp[0] = 0xb8; \
320
+ *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
321
+ *(unsigned char *) &__tramp[5] = 0xe9; \
322
+ *(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \
323
+ })
324
+
325
+ #define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX,SIZE) \
326
+ ({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
327
+ unsigned int __fun = (unsigned int)(FUN); \
328
+ unsigned int __ctx = (unsigned int)(CTX); \
329
+ unsigned int __dis = __fun - (__ctx + 10); \
330
+ unsigned short __size = (unsigned short)(SIZE); \
331
+ *(unsigned char*) &__tramp[0] = 0xb8; \
332
+ *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
333
+ *(unsigned char *) &__tramp[5] = 0xe8; \
334
+ *(unsigned int*) &__tramp[6] = __dis; /* call __fun */ \
335
+ *(unsigned char *) &__tramp[10] = 0xc2; \
336
+ *(unsigned short*) &__tramp[11] = __size; /* ret __size */ \
337
+ })
338
+
339
+ /* the cif must already be prep'ed */
340
+
341
+ ffi_status
342
+ ffi_prep_closure_loc (ffi_closure* closure,
343
+ ffi_cif* cif,
344
+ void (*fun)(ffi_cif*,void*,void**,void*),
345
+ void *user_data,
346
+ void *codeloc)
347
+ {
348
+ if (cif->abi == FFI_SYSV)
349
+ {
350
+ FFI_INIT_TRAMPOLINE (&closure->tramp[0],
351
+ &ffi_closure_SYSV,
352
+ (void*)codeloc);
353
+ }
354
+ #ifdef X86_WIN32
355
+ else if (cif->abi == FFI_STDCALL)
356
+ {
357
+ FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0],
358
+ &ffi_closure_STDCALL,
359
+ (void*)codeloc, cif->bytes);
360
+ }
361
+ #endif
362
+ else
363
+ {
364
+ return FFI_BAD_ABI;
365
+ }
366
+
367
+ closure->cif = cif;
368
+ closure->user_data = user_data;
369
+ closure->fun = fun;
370
+
371
+ return FFI_OK;
372
+ }
373
+
374
+ /* ------- Native raw API support -------------------------------- */
375
+
376
+ #if !FFI_NO_RAW_API
377
+
378
+ ffi_status
379
+ ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
380
+ ffi_cif* cif,
381
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
382
+ void *user_data,
383
+ void *codeloc)
384
+ {
385
+ int i;
386
+
387
+ if (cif->abi != FFI_SYSV) {
388
+ return FFI_BAD_ABI;
389
+ }
390
+
391
+ // we currently don't support certain kinds of arguments for raw
392
+ // closures. This should be implemented by a separate assembly language
393
+ // routine, since it would require argument processing, something we
394
+ // don't do now for performance.
395
+
396
+ for (i = cif->nargs-1; i >= 0; i--)
397
+ {
398
+ FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT);
399
+ FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
400
+ }
401
+
402
+
403
+ FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
404
+ codeloc);
405
+
406
+ closure->cif = cif;
407
+ closure->user_data = user_data;
408
+ closure->fun = fun;
409
+
410
+ return FFI_OK;
411
+ }
412
+
413
+ static void
414
+ ffi_prep_args_raw(char *stack, extended_cif *ecif)
415
+ {
416
+ memcpy (stack, ecif->avalue, ecif->cif->bytes);
417
+ }
418
+
419
+ /* we borrow this routine from libffi (it must be changed, though, to
420
+ * actually call the function passed in the first argument. as of
421
+ * libffi-1.20, this is not the case.)
422
+ */
423
+
424
+ extern void
425
+ ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, unsigned,
426
+ unsigned, unsigned *, void (*fn)(void));
427
+
428
+ #ifdef X86_WIN32
429
+ extern void
430
+ ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *, unsigned,
431
+ unsigned, unsigned *, void (*fn)(void));
432
+ #endif /* X86_WIN32 */
433
+
434
+ void
435
+ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
436
+ {
437
+ extended_cif ecif;
438
+ void **avalue = (void **)fake_avalue;
439
+
440
+ ecif.cif = cif;
441
+ ecif.avalue = avalue;
442
+
443
+ /* If the return value is a struct and we don't have a return */
444
+ /* value address then we need to make one */
445
+
446
+ if ((rvalue == NULL) &&
447
+ (cif->rtype->type == FFI_TYPE_STRUCT))
448
+ {
449
+ ecif.rvalue = alloca(cif->rtype->size);
450
+ }
451
+ else
452
+ ecif.rvalue = rvalue;
453
+
454
+
455
+ switch (cif->abi)
456
+ {
457
+ case FFI_SYSV:
458
+ ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
459
+ ecif.rvalue, fn);
460
+ break;
461
+ #ifdef X86_WIN32
462
+ case FFI_STDCALL:
463
+ ffi_call_STDCALL(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
464
+ ecif.rvalue, fn);
465
+ break;
466
+ #endif /* X86_WIN32 */
467
+ default:
468
+ FFI_ASSERT(0);
469
+ break;
470
+ }
471
+ }
472
+
473
+ #endif
474
+
475
+ #endif /* __x86_64__ */