ffi 0.5.0-x86-mingw32

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

Potentially problematic release.


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

Files changed (328) hide show
  1. data/LICENSE +51 -0
  2. data/README.rdoc +69 -0
  3. data/Rakefile +191 -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 +853 -0
  12. data/ext/ffi_c/Call.h +86 -0
  13. data/ext/ffi_c/ClosurePool.c +302 -0
  14. data/ext/ffi_c/ClosurePool.h +29 -0
  15. data/ext/ffi_c/DynamicLibrary.c +216 -0
  16. data/ext/ffi_c/DynamicLibrary.h +22 -0
  17. data/ext/ffi_c/Function.c +478 -0
  18. data/ext/ffi_c/Function.h +80 -0
  19. data/ext/ffi_c/FunctionInfo.c +221 -0
  20. data/ext/ffi_c/LastError.c +159 -0
  21. data/ext/ffi_c/LastError.h +18 -0
  22. data/ext/ffi_c/MemoryPointer.c +178 -0
  23. data/ext/ffi_c/MemoryPointer.h +20 -0
  24. data/ext/ffi_c/MethodHandle.c +346 -0
  25. data/ext/ffi_c/MethodHandle.h +53 -0
  26. data/ext/ffi_c/Platform.c +59 -0
  27. data/ext/ffi_c/Platform.h +16 -0
  28. data/ext/ffi_c/Pointer.c +224 -0
  29. data/ext/ffi_c/Pointer.h +49 -0
  30. data/ext/ffi_c/Struct.c +770 -0
  31. data/ext/ffi_c/Struct.h +80 -0
  32. data/ext/ffi_c/StructByValue.c +140 -0
  33. data/ext/ffi_c/StructByValue.h +53 -0
  34. data/ext/ffi_c/StructLayout.c +450 -0
  35. data/ext/ffi_c/Type.c +329 -0
  36. data/ext/ffi_c/Type.h +57 -0
  37. data/ext/ffi_c/Types.c +103 -0
  38. data/ext/ffi_c/Types.h +85 -0
  39. data/ext/ffi_c/Variadic.c +260 -0
  40. data/ext/ffi_c/compat.h +72 -0
  41. data/ext/ffi_c/endian.h +40 -0
  42. data/ext/ffi_c/extconf.rb +30 -0
  43. data/ext/ffi_c/ffi.c +82 -0
  44. data/ext/ffi_c/libffi.bsd.mk +34 -0
  45. data/ext/ffi_c/libffi.darwin.mk +75 -0
  46. data/ext/ffi_c/libffi.gnu.mk +29 -0
  47. data/ext/ffi_c/libffi.mk +13 -0
  48. data/ext/ffi_c/libffi/ChangeLog +3243 -0
  49. data/ext/ffi_c/libffi/ChangeLog.libffi +347 -0
  50. data/ext/ffi_c/libffi/ChangeLog.libgcj +40 -0
  51. data/ext/ffi_c/libffi/ChangeLog.v1 +764 -0
  52. data/ext/ffi_c/libffi/LICENSE +21 -0
  53. data/ext/ffi_c/libffi/Makefile.am +177 -0
  54. data/ext/ffi_c/libffi/Makefile.in +1640 -0
  55. data/ext/ffi_c/libffi/README +328 -0
  56. data/ext/ffi_c/libffi/TODO +1 -0
  57. data/ext/ffi_c/libffi/acinclude.m4 +92 -0
  58. data/ext/ffi_c/libffi/aclocal.m4 +7516 -0
  59. data/ext/ffi_c/libffi/compile +142 -0
  60. data/ext/ffi_c/libffi/config.guess +1516 -0
  61. data/ext/ffi_c/libffi/config.sub +1626 -0
  62. data/ext/ffi_c/libffi/configure +24414 -0
  63. data/ext/ffi_c/libffi/configure.ac +365 -0
  64. data/ext/ffi_c/libffi/configure.host +11 -0
  65. data/ext/ffi_c/libffi/depcomp +584 -0
  66. data/ext/ffi_c/libffi/doc/libffi.info +533 -0
  67. data/ext/ffi_c/libffi/doc/libffi.texi +541 -0
  68. data/ext/ffi_c/libffi/doc/stamp-vti +4 -0
  69. data/ext/ffi_c/libffi/doc/version.texi +4 -0
  70. data/ext/ffi_c/libffi/fficonfig.h.in +160 -0
  71. data/ext/ffi_c/libffi/include/Makefile.am +9 -0
  72. data/ext/ffi_c/libffi/include/Makefile.in +422 -0
  73. data/ext/ffi_c/libffi/include/ffi.h.in +393 -0
  74. data/ext/ffi_c/libffi/include/ffi_common.h +98 -0
  75. data/ext/ffi_c/libffi/install-sh +323 -0
  76. data/ext/ffi_c/libffi/libffi.pc.in +10 -0
  77. data/ext/ffi_c/libffi/libtool-version +29 -0
  78. data/ext/ffi_c/libffi/ltcf-c.sh +861 -0
  79. data/ext/ffi_c/libffi/ltcf-cxx.sh +1069 -0
  80. data/ext/ffi_c/libffi/ltcf-gcj.sh +700 -0
  81. data/ext/ffi_c/libffi/ltconfig +2862 -0
  82. data/ext/ffi_c/libffi/ltmain.sh +6930 -0
  83. data/ext/ffi_c/libffi/man/Makefile.am +8 -0
  84. data/ext/ffi_c/libffi/man/Makefile.in +395 -0
  85. data/ext/ffi_c/libffi/man/ffi.3 +31 -0
  86. data/ext/ffi_c/libffi/man/ffi_call.3 +103 -0
  87. data/ext/ffi_c/libffi/man/ffi_prep_cif.3 +66 -0
  88. data/ext/ffi_c/libffi/mdate-sh +201 -0
  89. data/ext/ffi_c/libffi/missing +353 -0
  90. data/ext/ffi_c/libffi/mkinstalldirs +158 -0
  91. data/ext/ffi_c/libffi/src/alpha/ffi.c +284 -0
  92. data/ext/ffi_c/libffi/src/alpha/ffitarget.h +48 -0
  93. data/ext/ffi_c/libffi/src/alpha/osf.S +366 -0
  94. data/ext/ffi_c/libffi/src/arm/ffi.c +309 -0
  95. data/ext/ffi_c/libffi/src/arm/ffitarget.h +49 -0
  96. data/ext/ffi_c/libffi/src/arm/sysv.S +299 -0
  97. data/ext/ffi_c/libffi/src/closures.c +596 -0
  98. data/ext/ffi_c/libffi/src/cris/ffi.c +383 -0
  99. data/ext/ffi_c/libffi/src/cris/ffitarget.h +51 -0
  100. data/ext/ffi_c/libffi/src/cris/sysv.S +215 -0
  101. data/ext/ffi_c/libffi/src/debug.c +59 -0
  102. data/ext/ffi_c/libffi/src/dlmalloc.c +5099 -0
  103. data/ext/ffi_c/libffi/src/frv/eabi.S +128 -0
  104. data/ext/ffi_c/libffi/src/frv/ffi.c +292 -0
  105. data/ext/ffi_c/libffi/src/frv/ffitarget.h +61 -0
  106. data/ext/ffi_c/libffi/src/ia64/ffi.c +580 -0
  107. data/ext/ffi_c/libffi/src/ia64/ffitarget.h +50 -0
  108. data/ext/ffi_c/libffi/src/ia64/ia64_flags.h +40 -0
  109. data/ext/ffi_c/libffi/src/ia64/unix.S +560 -0
  110. data/ext/ffi_c/libffi/src/java_raw_api.c +359 -0
  111. data/ext/ffi_c/libffi/src/m32r/ffi.c +232 -0
  112. data/ext/ffi_c/libffi/src/m32r/ffitarget.h +48 -0
  113. data/ext/ffi_c/libffi/src/m32r/sysv.S +121 -0
  114. data/ext/ffi_c/libffi/src/m68k/ffi.c +278 -0
  115. data/ext/ffi_c/libffi/src/m68k/ffitarget.h +49 -0
  116. data/ext/ffi_c/libffi/src/m68k/sysv.S +234 -0
  117. data/ext/ffi_c/libffi/src/mips/ffi.c +926 -0
  118. data/ext/ffi_c/libffi/src/mips/ffitarget.h +202 -0
  119. data/ext/ffi_c/libffi/src/mips/n32.S +534 -0
  120. data/ext/ffi_c/libffi/src/mips/o32.S +381 -0
  121. data/ext/ffi_c/libffi/src/pa/ffi.c +709 -0
  122. data/ext/ffi_c/libffi/src/pa/ffitarget.h +77 -0
  123. data/ext/ffi_c/libffi/src/pa/hpux32.S +368 -0
  124. data/ext/ffi_c/libffi/src/pa/linux.S +357 -0
  125. data/ext/ffi_c/libffi/src/powerpc/aix.S +225 -0
  126. data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +247 -0
  127. data/ext/ffi_c/libffi/src/powerpc/asm.h +125 -0
  128. data/ext/ffi_c/libffi/src/powerpc/darwin.S +245 -0
  129. data/ext/ffi_c/libffi/src/powerpc/darwin_closure.S +317 -0
  130. data/ext/ffi_c/libffi/src/powerpc/ffi.c +1429 -0
  131. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +800 -0
  132. data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +118 -0
  133. data/ext/ffi_c/libffi/src/powerpc/linux64.S +187 -0
  134. data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +236 -0
  135. data/ext/ffi_c/libffi/src/powerpc/ppc_closure.S +327 -0
  136. data/ext/ffi_c/libffi/src/powerpc/sysv.S +230 -0
  137. data/ext/ffi_c/libffi/src/prep_cif.c +174 -0
  138. data/ext/ffi_c/libffi/src/raw_api.c +254 -0
  139. data/ext/ffi_c/libffi/src/s390/ffi.c +780 -0
  140. data/ext/ffi_c/libffi/src/s390/ffitarget.h +60 -0
  141. data/ext/ffi_c/libffi/src/s390/sysv.S +434 -0
  142. data/ext/ffi_c/libffi/src/sh/ffi.c +716 -0
  143. data/ext/ffi_c/libffi/src/sh/ffitarget.h +49 -0
  144. data/ext/ffi_c/libffi/src/sh/sysv.S +850 -0
  145. data/ext/ffi_c/libffi/src/sh64/ffi.c +453 -0
  146. data/ext/ffi_c/libffi/src/sh64/ffitarget.h +53 -0
  147. data/ext/ffi_c/libffi/src/sh64/sysv.S +530 -0
  148. data/ext/ffi_c/libffi/src/sparc/ffi.c +610 -0
  149. data/ext/ffi_c/libffi/src/sparc/ffitarget.h +66 -0
  150. data/ext/ffi_c/libffi/src/sparc/v8.S +272 -0
  151. data/ext/ffi_c/libffi/src/sparc/v9.S +307 -0
  152. data/ext/ffi_c/libffi/src/types.c +77 -0
  153. data/ext/ffi_c/libffi/src/x86/darwin.S +443 -0
  154. data/ext/ffi_c/libffi/src/x86/darwin64.S +416 -0
  155. data/ext/ffi_c/libffi/src/x86/ffi.c +475 -0
  156. data/ext/ffi_c/libffi/src/x86/ffi64.c +572 -0
  157. data/ext/ffi_c/libffi/src/x86/ffitarget.h +90 -0
  158. data/ext/ffi_c/libffi/src/x86/freebsd.S +458 -0
  159. data/ext/ffi_c/libffi/src/x86/sysv.S +437 -0
  160. data/ext/ffi_c/libffi/src/x86/unix64.S +418 -0
  161. data/ext/ffi_c/libffi/src/x86/win32.S +391 -0
  162. data/ext/ffi_c/libffi/testsuite/Makefile.am +71 -0
  163. data/ext/ffi_c/libffi/testsuite/Makefile.in +447 -0
  164. data/ext/ffi_c/libffi/testsuite/config/default.exp +1 -0
  165. data/ext/ffi_c/libffi/testsuite/lib/libffi-dg.exp +289 -0
  166. data/ext/ffi_c/libffi/testsuite/lib/target-libpath.exp +263 -0
  167. data/ext/ffi_c/libffi/testsuite/lib/wrapper.exp +45 -0
  168. data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +36 -0
  169. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn0.c +97 -0
  170. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn1.c +89 -0
  171. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn2.c +89 -0
  172. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn3.c +90 -0
  173. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn4.c +97 -0
  174. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn5.c +99 -0
  175. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn6.c +98 -0
  176. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_stdcall.c +72 -0
  177. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_12byte.c +102 -0
  178. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_16byte.c +103 -0
  179. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_18byte.c +104 -0
  180. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_19byte.c +110 -0
  181. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_1_1byte.c +97 -0
  182. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte.c +99 -0
  183. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte1.c +101 -0
  184. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_24byte.c +121 -0
  185. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_2byte.c +98 -0
  186. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3_1byte.c +103 -0
  187. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte1.c +98 -0
  188. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte2.c +98 -0
  189. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4_1byte.c +106 -0
  190. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4byte.c +98 -0
  191. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5_1_byte.c +117 -0
  192. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5byte.c +106 -0
  193. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_64byte.c +132 -0
  194. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6_1_byte.c +121 -0
  195. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6byte.c +107 -0
  196. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7_1_byte.c +125 -0
  197. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7byte.c +105 -0
  198. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_8byte.c +96 -0
  199. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte1.c +98 -0
  200. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte2.c +99 -0
  201. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_double.c +101 -0
  202. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_float.c +99 -0
  203. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble.c +100 -0
  204. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_pointer.c +101 -0
  205. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint16.c +99 -0
  206. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint32.c +99 -0
  207. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint64.c +99 -0
  208. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint16.c +99 -0
  209. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint32.c +99 -0
  210. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint64.c +100 -0
  211. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_double.c +51 -0
  212. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_float.c +51 -0
  213. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_schar.c +82 -0
  214. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshort.c +82 -0
  215. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshortchar.c +94 -0
  216. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_uchar.c +99 -0
  217. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushort.c +82 -0
  218. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushortchar.c +94 -0
  219. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_schar.c +52 -0
  220. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_sint.c +50 -0
  221. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_sshort.c +50 -0
  222. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uchar.c +50 -0
  223. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uint.c +51 -0
  224. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulonglong.c +54 -0
  225. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ushort.c +51 -0
  226. data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +86 -0
  227. data/ext/ffi_c/libffi/testsuite/libffi.call/float.c +59 -0
  228. data/ext/ffi_c/libffi/testsuite/libffi.call/float1.c +58 -0
  229. data/ext/ffi_c/libffi/testsuite/libffi.call/float2.c +57 -0
  230. data/ext/ffi_c/libffi/testsuite/libffi.call/float3.c +72 -0
  231. data/ext/ffi_c/libffi/testsuite/libffi.call/float4.c +62 -0
  232. data/ext/ffi_c/libffi/testsuite/libffi.call/many.c +69 -0
  233. data/ext/ffi_c/libffi/testsuite/libffi.call/many_win32.c +63 -0
  234. data/ext/ffi_c/libffi/testsuite/libffi.call/negint.c +53 -0
  235. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct.c +160 -0
  236. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct1.c +169 -0
  237. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct10.c +141 -0
  238. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct2.c +118 -0
  239. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct3.c +119 -0
  240. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct4.c +119 -0
  241. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct5.c +120 -0
  242. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct6.c +139 -0
  243. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct7.c +119 -0
  244. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct8.c +139 -0
  245. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct9.c +139 -0
  246. data/ext/ffi_c/libffi/testsuite/libffi.call/problem1.c +98 -0
  247. data/ext/ffi_c/libffi/testsuite/libffi.call/promotion.c +59 -0
  248. data/ext/ffi_c/libffi/testsuite/libffi.call/pyobjc-tc.c +114 -0
  249. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl.c +35 -0
  250. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl1.c +43 -0
  251. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl2.c +42 -0
  252. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl.c +35 -0
  253. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl1.c +36 -0
  254. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl2.c +49 -0
  255. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl3.c +42 -0
  256. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ldl.c +34 -0
  257. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll.c +41 -0
  258. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll1.c +42 -0
  259. data/ext/ffi_c/libffi/testsuite/libffi.call/return_sc.c +36 -0
  260. data/ext/ffi_c/libffi/testsuite/libffi.call/return_sl.c +38 -0
  261. data/ext/ffi_c/libffi/testsuite/libffi.call/return_uc.c +38 -0
  262. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ul.c +38 -0
  263. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen.c +44 -0
  264. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen_win32.c +44 -0
  265. data/ext/ffi_c/libffi/testsuite/libffi.call/struct1.c +65 -0
  266. data/ext/ffi_c/libffi/testsuite/libffi.call/struct2.c +67 -0
  267. data/ext/ffi_c/libffi/testsuite/libffi.call/struct3.c +59 -0
  268. data/ext/ffi_c/libffi/testsuite/libffi.call/struct4.c +63 -0
  269. data/ext/ffi_c/libffi/testsuite/libffi.call/struct5.c +65 -0
  270. data/ext/ffi_c/libffi/testsuite/libffi.call/struct6.c +64 -0
  271. data/ext/ffi_c/libffi/testsuite/libffi.call/struct7.c +74 -0
  272. data/ext/ffi_c/libffi/testsuite/libffi.call/struct8.c +80 -0
  273. data/ext/ffi_c/libffi/testsuite/libffi.call/struct9.c +67 -0
  274. data/ext/ffi_c/libffi/testsuite/libffi.special/ffitestcxx.h +86 -0
  275. data/ext/ffi_c/libffi/testsuite/libffi.special/special.exp +38 -0
  276. data/ext/ffi_c/libffi/testsuite/libffi.special/unwindtest.cc +123 -0
  277. data/ext/ffi_c/libffi/testsuite/libffi.special/unwindtest_ffi_call.cc +53 -0
  278. data/ext/ffi_c/libffi/texinfo.tex +7482 -0
  279. data/ext/ffi_c/rbffi.h +26 -0
  280. data/gen/Rakefile +12 -0
  281. data/lib/1.8/ffi_c.so +0 -0
  282. data/lib/1.9/ffi_c.so +0 -0
  283. data/lib/ffi.rb +11 -0
  284. data/lib/ffi/autopointer.rb +61 -0
  285. data/lib/ffi/buffer.rb +0 -0
  286. data/lib/ffi/callback.rb +10 -0
  287. data/lib/ffi/enum.rb +78 -0
  288. data/lib/ffi/errno.rb +8 -0
  289. data/lib/ffi/ffi.rb +99 -0
  290. data/lib/ffi/io.rb +21 -0
  291. data/lib/ffi/library.rb +218 -0
  292. data/lib/ffi/managedstruct.rb +55 -0
  293. data/lib/ffi/memorypointer.rb +73 -0
  294. data/lib/ffi/platform.rb +88 -0
  295. data/lib/ffi/pointer.rb +119 -0
  296. data/lib/ffi/struct.rb +183 -0
  297. data/lib/ffi/tools/const_generator.rb +177 -0
  298. data/lib/ffi/tools/generator.rb +58 -0
  299. data/lib/ffi/tools/generator_task.rb +35 -0
  300. data/lib/ffi/tools/struct_generator.rb +194 -0
  301. data/lib/ffi/tools/types_generator.rb +123 -0
  302. data/lib/ffi/types.rb +153 -0
  303. data/lib/ffi/union.rb +12 -0
  304. data/lib/ffi/variadic.rb +25 -0
  305. data/spec/ffi/bool_spec.rb +24 -0
  306. data/spec/ffi/buffer_spec.rb +202 -0
  307. data/spec/ffi/callback_spec.rb +591 -0
  308. data/spec/ffi/enum_spec.rb +164 -0
  309. data/spec/ffi/errno_spec.rb +13 -0
  310. data/spec/ffi/function_spec.rb +73 -0
  311. data/spec/ffi/library_spec.rb +148 -0
  312. data/spec/ffi/managed_struct_spec.rb +56 -0
  313. data/spec/ffi/number_spec.rb +231 -0
  314. data/spec/ffi/pointer_spec.rb +195 -0
  315. data/spec/ffi/rbx/attach_function_spec.rb +27 -0
  316. data/spec/ffi/rbx/memory_pointer_spec.rb +102 -0
  317. data/spec/ffi/rbx/spec_helper.rb +1 -0
  318. data/spec/ffi/rbx/struct_spec.rb +13 -0
  319. data/spec/ffi/spec_helper.rb +17 -0
  320. data/spec/ffi/string_spec.rb +103 -0
  321. data/spec/ffi/struct_callback_spec.rb +64 -0
  322. data/spec/ffi/struct_initialize_spec.rb +30 -0
  323. data/spec/ffi/struct_spec.rb +529 -0
  324. data/spec/ffi/typedef_spec.rb +48 -0
  325. data/spec/ffi/union_spec.rb +60 -0
  326. data/spec/ffi/variadic_spec.rb +84 -0
  327. data/spec/spec.opts +4 -0
  328. metadata +396 -0
@@ -0,0 +1,853 @@
1
+ /*
2
+ * Copyright (c) 2009, Wayne Meissner
3
+ * Copyright (c) 2009, Luc Heinrich <luc@honk-honk.com>
4
+ * Copyright (c) 2009, Mike Dalessio <mike.dalessio@gmail.com>
5
+ * Copyright (c) 2009, Aman Gupta.
6
+ * All rights reserved.
7
+ *
8
+ * Redistribution and use in source and binary forms, with or without
9
+ * modification, are permitted provided that the following conditions are met:
10
+ *
11
+ * * Redistributions of source code must retain the above copyright notice, this
12
+ * list of conditions and the following disclaimer.
13
+ * * Redistributions in binary form must reproduce the above copyright notice
14
+ * this list of conditions and the following disclaimer in the documentation
15
+ * and/or other materials provided with the distribution.
16
+ * * The name of the author or authors may not be used to endorse or promote
17
+ * products derived from this software without specific prior written permission.
18
+ *
19
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
23
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ */
30
+
31
+ #include <sys/param.h>
32
+ #include <sys/types.h>
33
+ #include <stdio.h>
34
+ #include <stdint.h>
35
+ #include <stdbool.h>
36
+ #include <errno.h>
37
+ #include <ruby.h>
38
+ #if defined(HAVE_NATIVETHREAD) && defined(HAVE_RB_THREAD_BLOCKING_REGION) && !defined(_WIN32)
39
+ # include <signal.h>
40
+ # include <pthread.h>
41
+ #endif
42
+ #include <ffi.h>
43
+ #include "extconf.h"
44
+ #include "rbffi.h"
45
+ #include "compat.h"
46
+ #include "AbstractMemory.h"
47
+ #include "Pointer.h"
48
+ #include "Struct.h"
49
+ #include "Function.h"
50
+ #include "Type.h"
51
+ #include "LastError.h"
52
+ #include "Call.h"
53
+
54
+ #ifdef USE_RAW
55
+ # ifndef __i386__
56
+ # error "RAW argument packing only supported on i386"
57
+ # endif
58
+
59
+ #define INT8_ADJ (4)
60
+ #define INT16_ADJ (4)
61
+ #define INT32_ADJ (4)
62
+ #define INT64_ADJ (8)
63
+ #define FLOAT32_ADJ (4)
64
+ #define FLOAT64_ADJ (8)
65
+ #define ADDRESS_ADJ (sizeof(void *))
66
+
67
+ #endif /* USE_RAW */
68
+
69
+ #ifdef USE_RAW
70
+ # define ADJ(p, a) ((p) = (FFIStorage*) (((char *) p) + a##_ADJ))
71
+ #else
72
+ # define ADJ(p, a) (++(p))
73
+ #endif
74
+
75
+ static void* callback_param(VALUE proc, VALUE cbinfo);
76
+ static inline int getSignedInt(VALUE value, int type, int minValue, int maxValue, const char* typeName, VALUE enums);
77
+ static inline int getUnsignedInt(VALUE value, int type, int maxValue, const char* typeName);
78
+ static inline unsigned int getUnsignedInt32(VALUE value, int type);
79
+ static inline void* getPointer(VALUE value, int type);
80
+ static inline char* getString(VALUE value, int type);
81
+
82
+
83
+ #ifdef BYPASS_FFI
84
+ static long rbffi_GetLongValue(int idx, VALUE* argv, FunctionType* fnInfo);
85
+ static VALUE rbffi_InvokeVrL(int argc, VALUE* argv, void* function, FunctionType* fnInfo);
86
+ static VALUE rbffi_InvokeLrL(int argc, VALUE* argv, void* function, FunctionType* fnInfo);
87
+ static VALUE rbffi_InvokeLLrL(int argc, VALUE* argv, void* function, FunctionType* fnInfo);
88
+ static VALUE rbffi_InvokeLLLrL(int argc, VALUE* argv, void* function, FunctionType* fnInfo);
89
+ static VALUE rbffi_InvokeLLLLrL(int argc, VALUE* argv, void* function, FunctionType* fnInfo);
90
+ static VALUE rbffi_InvokeLLLLLrL(int argc, VALUE* argv, void* function, FunctionType* fnInfo);
91
+ static VALUE rbffi_InvokeLLLLLLrL(int argc, VALUE* argv, void* function, FunctionType* fnInfo);
92
+ static VALUE rbffi_InvokeLongParams(int argc, VALUE* argv, void* function, FunctionType* fnInfo);
93
+ #endif
94
+
95
+
96
+ static ID id_to_ptr, id_map_symbol;
97
+
98
+ void
99
+ rbffi_SetupCallParams(int argc, VALUE* argv, int paramCount, NativeType* paramTypes,
100
+ FFIStorage* paramStorage, void** ffiValues,
101
+ VALUE* callbackParameters, int callbackCount, VALUE enums)
102
+ {
103
+ VALUE callbackProc = Qnil;
104
+ FFIStorage* param = &paramStorage[0];
105
+ int i, argidx, cbidx, argCount;
106
+
107
+ if (paramCount != -1 && paramCount != argc) {
108
+ if (argc == (paramCount - 1) && callbackCount == 1 && rb_block_given_p()) {
109
+ callbackProc = rb_block_proc();
110
+ } else {
111
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, paramCount);
112
+ }
113
+ }
114
+
115
+ argCount = paramCount != -1 ? paramCount : argc;
116
+
117
+ for (i = 0, argidx = 0, cbidx = 0; i < argCount; ++i) {
118
+ int type = argidx < argc ? TYPE(argv[argidx]) : T_NONE;
119
+ ffiValues[i] = param;
120
+
121
+ switch (paramTypes[i]) {
122
+
123
+ case NATIVE_INT8:
124
+ param->s8 = getSignedInt(argv[argidx++], type, -128, 127, "char", Qnil);
125
+ ADJ(param, INT8);
126
+ break;
127
+
128
+
129
+ case NATIVE_INT16:
130
+ param->s16 = getSignedInt(argv[argidx++], type, -0x8000, 0x7fff, "short", Qnil);
131
+ ADJ(param, INT16);
132
+ break;
133
+
134
+
135
+ case NATIVE_INT32:
136
+ case NATIVE_ENUM:
137
+ param->s32 = getSignedInt(argv[argidx++], type, -0x80000000, 0x7fffffff, "int", enums);
138
+ ADJ(param, INT32);
139
+ break;
140
+
141
+
142
+ case NATIVE_BOOL:
143
+ if (type != T_TRUE && type != T_FALSE) {
144
+ rb_raise(rb_eTypeError, "Expected a Boolean parameter");
145
+ }
146
+ param->s32 = argv[argidx++] == Qtrue;
147
+ ADJ(param, INT32);
148
+ break;
149
+
150
+
151
+ case NATIVE_UINT8:
152
+ param->u8 = getUnsignedInt(argv[argidx++], type, 0xff, "unsigned char");
153
+ ADJ(param, INT8);
154
+ break;
155
+
156
+
157
+ case NATIVE_UINT16:
158
+ param->u16 = getUnsignedInt(argv[argidx++], type, 0xffff, "unsigned short");
159
+ ADJ(param, INT16);
160
+ break;
161
+
162
+
163
+ case NATIVE_UINT32:
164
+ /* Special handling/checking for unsigned 32 bit integers */
165
+ param->u32 = getUnsignedInt32(argv[argidx++], type);
166
+ ADJ(param, INT32);
167
+ break;
168
+
169
+
170
+ case NATIVE_INT64:
171
+ if (type != T_FIXNUM && type != T_BIGNUM) {
172
+ rb_raise(rb_eTypeError, "Expected an Integer parameter");
173
+ }
174
+ param->i64 = NUM2LL(argv[argidx]);
175
+ ADJ(param, INT64);
176
+ ++argidx;
177
+ break;
178
+
179
+
180
+ case NATIVE_UINT64:
181
+ if (type != T_FIXNUM && type != T_BIGNUM) {
182
+ rb_raise(rb_eTypeError, "Expected an Integer parameter");
183
+ }
184
+ param->u64 = NUM2ULL(argv[argidx]);
185
+ ADJ(param, INT64);
186
+ ++argidx;
187
+ break;
188
+
189
+
190
+ case NATIVE_FLOAT32:
191
+ if (type != T_FLOAT && type != T_FIXNUM) {
192
+ rb_raise(rb_eTypeError, "Expected a Float parameter");
193
+ }
194
+ param->f32 = (float) NUM2DBL(argv[argidx]);
195
+ ADJ(param, FLOAT32);
196
+ ++argidx;
197
+ break;
198
+
199
+ case NATIVE_FLOAT64:
200
+ if (type != T_FLOAT && type != T_FIXNUM) {
201
+ rb_raise(rb_eTypeError, "Expected a Float parameter");
202
+ }
203
+ param->f64 = NUM2DBL(argv[argidx]);
204
+ ADJ(param, FLOAT64);
205
+ ++argidx;
206
+ break;
207
+
208
+
209
+ case NATIVE_STRING:
210
+ param->ptr = getString(argv[argidx++], type);
211
+ ADJ(param, ADDRESS);
212
+ break;
213
+
214
+ case NATIVE_POINTER:
215
+ case NATIVE_BUFFER_IN:
216
+ case NATIVE_BUFFER_OUT:
217
+ case NATIVE_BUFFER_INOUT:
218
+ param->ptr = getPointer(argv[argidx++], type);
219
+ ADJ(param, ADDRESS);
220
+ break;
221
+
222
+
223
+ case NATIVE_FUNCTION:
224
+ case NATIVE_CALLBACK:
225
+ if (callbackProc != Qnil) {
226
+ param->ptr = callback_param(callbackProc, callbackParameters[cbidx++]);
227
+ } else {
228
+ param->ptr = callback_param(argv[argidx], callbackParameters[cbidx++]);
229
+ ++argidx;
230
+ }
231
+ ADJ(param, ADDRESS);
232
+ break;
233
+
234
+ case NATIVE_STRUCT:
235
+ ffiValues[i] = getPointer(argv[argidx++], type);
236
+ break;
237
+
238
+ default:
239
+ rb_raise(rb_eArgError, "Invalid parameter type: %d", paramTypes[i]);
240
+ }
241
+ }
242
+ }
243
+
244
+
245
+ #if defined(HAVE_NATIVETHREAD) && defined(HAVE_RB_THREAD_BLOCKING_REGION)
246
+
247
+ typedef struct BlockingCall_ {
248
+ void* function;
249
+ FunctionType* info;
250
+ void **ffiValues;
251
+ FFIStorage* retval;
252
+ } BlockingCall;
253
+
254
+ static VALUE
255
+ call_blocking_function(void* data)
256
+ {
257
+ BlockingCall* b = (BlockingCall *) data;
258
+
259
+ ffi_call(&b->info->ffi_cif, FFI_FN(b->function), b->retval, b->ffiValues);
260
+
261
+ return Qnil;
262
+ }
263
+ #endif
264
+
265
+ VALUE
266
+ rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
267
+ {
268
+ void* retval;
269
+ void** ffiValues;
270
+ FFIStorage* params;
271
+
272
+ ffiValues = ALLOCA_N(void *, fnInfo->parameterCount);
273
+ params = ALLOCA_N(FFIStorage, fnInfo->parameterCount);
274
+ retval = alloca(MAX(fnInfo->ffi_cif.rtype->size, FFI_SIZEOF_ARG));
275
+
276
+ rbffi_SetupCallParams(argc, argv,
277
+ fnInfo->parameterCount, fnInfo->nativeParameterTypes, params, ffiValues,
278
+ fnInfo->callbackParameters, fnInfo->callbackCount, fnInfo->rbEnums);
279
+
280
+ #if defined(HAVE_NATIVETHREAD) && defined(HAVE_RB_THREAD_BLOCKING_REGION)
281
+ if (unlikely(fnInfo->blocking)) {
282
+ BlockingCall bc;
283
+
284
+ bc.info = fnInfo;
285
+ bc.function = function;
286
+ bc.ffiValues = ffiValues;
287
+ bc.retval = retval;
288
+
289
+ rb_thread_blocking_region(call_blocking_function, &bc, (void *) -1, NULL);
290
+ } else {
291
+ ffi_call(&fnInfo->ffi_cif, FFI_FN(function), retval, ffiValues);
292
+ }
293
+ #else
294
+ ffi_call(&fnInfo->ffi_cif, FFI_FN(function), retval, ffiValues);
295
+ #endif
296
+
297
+ if (!fnInfo->ignoreErrno) {
298
+ rbffi_save_errno();
299
+ }
300
+
301
+ return rbffi_NativeValue_ToRuby(fnInfo->returnType, fnInfo->rbReturnType, retval,
302
+ fnInfo->rbEnums);
303
+ }
304
+
305
+ static inline int
306
+ getSignedInt(VALUE value, int type, int minValue, int maxValue, const char* typeName, VALUE enums)
307
+ {
308
+ int i;
309
+
310
+ if (type == T_SYMBOL && enums != Qnil) {
311
+ value = rb_funcall2(enums, id_map_symbol, 1, &value);
312
+ if (value == Qnil) {
313
+ rb_raise(rb_eTypeError, "Expected a valid enum constant");
314
+ }
315
+
316
+ } else if (type != T_FIXNUM && type != T_BIGNUM) {
317
+ rb_raise(rb_eTypeError, "Expected an Integer parameter");
318
+ }
319
+
320
+ i = NUM2INT(value);
321
+ if (i < minValue || i > maxValue) {
322
+ rb_raise(rb_eRangeError, "Value %d outside %s range", i, typeName);
323
+ }
324
+
325
+ return i;
326
+ }
327
+
328
+ static inline int
329
+ getUnsignedInt(VALUE value, int type, int maxValue, const char* typeName)
330
+ {
331
+ int i;
332
+
333
+ if (type != T_FIXNUM && type != T_BIGNUM) {
334
+ rb_raise(rb_eTypeError, "Expected an Integer parameter");
335
+ }
336
+
337
+ i = NUM2INT(value);
338
+ if (i < 0 || i > maxValue) {
339
+ rb_raise(rb_eRangeError, "Value %d outside %s range", i, typeName);
340
+ }
341
+
342
+ return i;
343
+ }
344
+
345
+ /* Special handling/checking for unsigned 32 bit integers */
346
+ static inline unsigned int
347
+ getUnsignedInt32(VALUE value, int type)
348
+ {
349
+ long long i;
350
+
351
+ if (type != T_FIXNUM && type != T_BIGNUM) {
352
+ rb_raise(rb_eTypeError, "Expected an Integer parameter");
353
+ }
354
+
355
+ i = NUM2LL(value);
356
+ if (i < 0L || i > 0xffffffffL) {
357
+ rb_raise(rb_eRangeError, "Value %lld outside unsigned int range", i);
358
+ }
359
+
360
+ return (unsigned int) i;
361
+ }
362
+
363
+ static inline void*
364
+ getPointer(VALUE value, int type)
365
+ {
366
+ if (type == T_DATA && rb_obj_is_kind_of(value, rbffi_AbstractMemoryClass)) {
367
+
368
+ return ((AbstractMemory *) DATA_PTR(value))->address;
369
+
370
+ } else if (type == T_DATA && rb_obj_is_kind_of(value, rbffi_StructClass)) {
371
+
372
+ AbstractMemory* memory = ((Struct *) DATA_PTR(value))->pointer;
373
+ return memory != NULL ? memory->address : NULL;
374
+
375
+ } else if (type == T_STRING) {
376
+
377
+ if (rb_safe_level() >= 1 && OBJ_TAINTED(value)) {
378
+ rb_raise(rb_eSecurityError, "Unsafe string parameter");
379
+ }
380
+ return StringValuePtr(value);
381
+
382
+ } else if (type == T_NIL) {
383
+
384
+ return NULL;
385
+
386
+ } else if (rb_respond_to(value, id_to_ptr)) {
387
+
388
+ VALUE ptr = rb_funcall2(value, id_to_ptr, 0, NULL);
389
+ if (rb_obj_is_kind_of(ptr, rbffi_AbstractMemoryClass) && TYPE(ptr) == T_DATA) {
390
+ return ((AbstractMemory *) DATA_PTR(ptr))->address;
391
+ }
392
+ rb_raise(rb_eArgError, "to_ptr returned an invalid pointer");
393
+ }
394
+
395
+ rb_raise(rb_eArgError, ":pointer argument is not a valid pointer");
396
+ return NULL;
397
+ }
398
+
399
+ static inline char*
400
+ getString(VALUE value, int type)
401
+ {
402
+ if (type == T_STRING) {
403
+
404
+ if (rb_safe_level() >= 1 && OBJ_TAINTED(value)) {
405
+ rb_raise(rb_eSecurityError, "Unsafe string parameter");
406
+ }
407
+
408
+ return StringValueCStr(value);
409
+
410
+ } else if (type == T_NIL) {
411
+ return NULL;
412
+ }
413
+
414
+ rb_raise(rb_eArgError, "Invalid String value");
415
+ }
416
+
417
+
418
+ Invoker
419
+ rbffi_GetInvoker(FunctionType *fnInfo)
420
+ {
421
+ #if defined(BYPASS_FFI) && (defined(__i386__) || defined(__x86_64__))
422
+ int i;
423
+ bool fastLong = fnInfo->abi == FFI_DEFAULT_ABI && !fnInfo->blocking && !fnInfo->hasStruct;
424
+
425
+ switch (fnInfo->returnType->nativeType) {
426
+ case NATIVE_VOID:
427
+ case NATIVE_BOOL:
428
+ case NATIVE_INT8:
429
+ case NATIVE_UINT8:
430
+ case NATIVE_INT16:
431
+ case NATIVE_UINT16:
432
+ case NATIVE_INT32:
433
+ case NATIVE_UINT32:
434
+ #ifdef __x86_64__
435
+ case NATIVE_INT64:
436
+ case NATIVE_UINT64:
437
+ #endif
438
+ case NATIVE_STRING:
439
+ case NATIVE_POINTER:
440
+ break;
441
+ default:
442
+ fastLong = false;
443
+ break;
444
+ }
445
+
446
+ for (i = 0; fastLong && i < fnInfo->parameterCount; ++i) {
447
+ switch (fnInfo->nativeParameterTypes[i]) {
448
+ case NATIVE_BOOL:
449
+ case NATIVE_INT8:
450
+ case NATIVE_UINT8:
451
+ case NATIVE_INT16:
452
+ case NATIVE_UINT16:
453
+ case NATIVE_INT32:
454
+ case NATIVE_UINT32:
455
+ #ifdef __x86_64__
456
+ case NATIVE_INT64:
457
+ case NATIVE_UINT64:
458
+ #endif
459
+ case NATIVE_STRING:
460
+ case NATIVE_POINTER:
461
+ case NATIVE_BUFFER_IN:
462
+ case NATIVE_BUFFER_OUT:
463
+ case NATIVE_BUFFER_INOUT:
464
+ case NATIVE_FUNCTION:
465
+ case NATIVE_CALLBACK:
466
+ break;
467
+ default:
468
+ fastLong = false;
469
+ break;
470
+ }
471
+ }
472
+
473
+ if (fastLong && fnInfo->callbackCount < 1) {
474
+ switch (fnInfo->parameterCount) {
475
+ case 0:
476
+ return rbffi_InvokeVrL;
477
+ case 1:
478
+ return rbffi_InvokeLrL;
479
+ case 2:
480
+ return rbffi_InvokeLLrL;
481
+ case 3:
482
+ return rbffi_InvokeLLLrL;
483
+ case 4:
484
+ return rbffi_InvokeLLLLrL;
485
+ case 5:
486
+ return rbffi_InvokeLLLLLrL;
487
+ case 6:
488
+ return rbffi_InvokeLLLLLLrL;
489
+
490
+ default:
491
+ break;
492
+ }
493
+
494
+ } else if (fastLong && fnInfo->parameterCount <= 6) {
495
+ return rbffi_InvokeLongParams;
496
+ }
497
+ #endif
498
+
499
+ return rbffi_CallFunction;
500
+ }
501
+
502
+ #if defined(BYPASS_FFI) && (defined(__i386__) || defined(__x86_64__))
503
+ typedef long L;
504
+
505
+ static long
506
+ rbffi_GetLongValue(int idx, VALUE* argv, FunctionType* fnInfo)
507
+ {
508
+ VALUE value = argv[idx];
509
+ NativeType nativeType = fnInfo->nativeParameterTypes[idx];
510
+ int type = TYPE(value);
511
+
512
+ switch (nativeType) {
513
+ case NATIVE_INT8:
514
+ return getSignedInt(value, type, -128, 127, "char", fnInfo->rbEnums);
515
+
516
+ case NATIVE_INT16:
517
+ return getSignedInt(value, type, -0x8000, 0x7fff, "short", fnInfo->rbEnums);
518
+
519
+ case NATIVE_INT32:
520
+ case NATIVE_ENUM:
521
+ return getSignedInt(value, type, -0x80000000, 0x7fffffff, "int", fnInfo->rbEnums);
522
+
523
+ case NATIVE_BOOL:
524
+ if (type != T_TRUE && type != T_FALSE) {
525
+ rb_raise(rb_eTypeError, "Expected a Boolean parameter");
526
+ }
527
+ return RTEST(value) ? 1 : 0;
528
+
529
+ case NATIVE_UINT8:
530
+ return getUnsignedInt(value, type, 0xff, "unsigned char");
531
+
532
+ case NATIVE_UINT16:
533
+ return getUnsignedInt(value, type, 0xffff, "unsigned short");
534
+
535
+ case NATIVE_UINT32:
536
+ /* Special handling/checking for unsigned 32 bit integers */
537
+ return getUnsignedInt32(value, type);
538
+
539
+ #ifdef __x86_64__
540
+ case NATIVE_INT64:
541
+ if (type != T_FIXNUM && type != T_BIGNUM) {
542
+ rb_raise(rb_eTypeError, "Expected an Integer parameter");
543
+ }
544
+ return NUM2LL(value);
545
+
546
+ case NATIVE_UINT64:
547
+ if (type != T_FIXNUM && type != T_BIGNUM) {
548
+ rb_raise(rb_eTypeError, "Expected an Integer parameter");
549
+ }
550
+ return NUM2ULL(value);
551
+ #endif
552
+ case NATIVE_STRING:
553
+ return (intptr_t) getString(value, type);
554
+
555
+ case NATIVE_POINTER:
556
+ case NATIVE_BUFFER_IN:
557
+ case NATIVE_BUFFER_OUT:
558
+ case NATIVE_BUFFER_INOUT:
559
+ return (intptr_t) getPointer(value, type);
560
+
561
+ default:
562
+ rb_raise(rb_eTypeError, "unsupported integer type %d", nativeType);
563
+ return 0;
564
+ }
565
+ }
566
+
567
+ static inline void
568
+ checkArity(int argc, int arity) {
569
+ if (unlikely(argc != arity)) {
570
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, arity);
571
+ }
572
+ }
573
+
574
+ static inline bool
575
+ isLongValue(VALUE value)
576
+ {
577
+ int type = TYPE(value);
578
+
579
+ return type == T_FIXNUM || type == T_BIGNUM
580
+ || type == T_STRING || type == T_NIL
581
+ || (type == T_DATA && rb_obj_is_kind_of(value, rbffi_AbstractMemoryClass))
582
+ || (type == T_DATA && rb_obj_is_kind_of(value, rbffi_StructClass))
583
+ || rb_respond_to(value, id_to_ptr);
584
+ }
585
+
586
+ static VALUE
587
+ returnL(FunctionType* fnInfo, L* result)
588
+ {
589
+ if (unlikely(!fnInfo->ignoreErrno)) {
590
+ rbffi_save_errno();
591
+ }
592
+
593
+ /*
594
+ * This needs to do custom boxing of the return value, since a function
595
+ * may only fill out the lower 8, 16 or 32 bits of %al, %ah, %eax, %rax, and
596
+ * the upper part will be garbage. This will truncate the value again, then
597
+ * sign extend it.
598
+ */
599
+ switch (fnInfo->returnType->nativeType) {
600
+ case NATIVE_VOID:
601
+ return Qnil;
602
+
603
+ case NATIVE_INT8:
604
+ return INT2NUM(*(signed char *) result);
605
+
606
+ case NATIVE_INT16:
607
+ return INT2NUM(*(signed short *) result);
608
+
609
+ case NATIVE_INT32:
610
+ return INT2NUM(*(signed int *) result);
611
+
612
+ case NATIVE_UINT8:
613
+ return UINT2NUM(*(unsigned char *) result);
614
+
615
+ case NATIVE_UINT16:
616
+ return UINT2NUM(*(unsigned short *) result);
617
+
618
+ case NATIVE_UINT32:
619
+ return UINT2NUM(*(unsigned int *) result);
620
+
621
+ #ifdef __x86_64__
622
+ case NATIVE_INT64:
623
+ return LL2NUM(*(signed long long *) result);
624
+
625
+ case NATIVE_UINT64:
626
+ return ULL2NUM(*(unsigned long long *) result);
627
+ #endif /* __x86_64__ */
628
+
629
+ case NATIVE_STRING:
630
+ return *(void **) result != 0 ? rb_tainted_str_new2(*(char **) result) : Qnil;
631
+
632
+ case NATIVE_POINTER:
633
+ return rbffi_Pointer_NewInstance(*(void **) result);
634
+
635
+ case NATIVE_BOOL:
636
+ return *(char *) result != 0 ? Qtrue : Qfalse;
637
+
638
+ default:
639
+ rb_raise(rb_eRuntimeError, "invalid return type: %d", fnInfo->returnType->nativeType);
640
+ return Qnil;
641
+ }
642
+ }
643
+
644
+ static VALUE
645
+ rbffi_InvokeVrL(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
646
+ {
647
+ L (*fn)(void) = (L (*)(void)) function;
648
+ L result;
649
+
650
+ checkArity(argc, 0);
651
+
652
+ result = (*fn)();
653
+
654
+ return returnL(fnInfo, &result);
655
+ }
656
+
657
+ static bool
658
+ checkArgs(int argc, VALUE* argv, FunctionType* fnInfo)
659
+ {
660
+ int i;
661
+
662
+ checkArity(argc, fnInfo->parameterCount);
663
+ for (i = 0; i < fnInfo->parameterCount; ++i) {
664
+ if (unlikely(!isLongValue(argv[i]))) {
665
+ return false;
666
+ }
667
+ }
668
+
669
+ return true;
670
+ }
671
+
672
+ #define LARG(fnInfo, argv, i) \
673
+ rbffi_GetLongValue(i, argv, fnInfo)
674
+
675
+ #define LCALL(fnInfo, argc, argv, fn, a...) ({ \
676
+ L result; \
677
+ \
678
+ if (unlikely(!checkArgs(argc, argv, fnInfo))) { \
679
+ return rbffi_CallFunction(argc, argv, function, fnInfo); \
680
+ } \
681
+ \
682
+ result = (*(fn))(a); \
683
+ \
684
+ returnL(fnInfo, &result); \
685
+ })
686
+
687
+ static VALUE
688
+ rbffi_InvokeLrL(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
689
+ {
690
+ L (*fn)(L) = (L (*)(L)) function;
691
+ L result;
692
+
693
+ checkArity(argc, 1);
694
+
695
+ if (unlikely(!isLongValue(argv[0]))) {
696
+ return rbffi_CallFunction(argc, argv, function, fnInfo);
697
+ }
698
+
699
+ result = (*fn)(LARG(fnInfo, argv, 0));
700
+
701
+ return returnL(fnInfo, &result);
702
+ }
703
+
704
+ static VALUE
705
+ rbffi_InvokeLLrL(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
706
+ {
707
+ L (*fn)(L, L) = (L (*)(L, L)) function;
708
+ L result;
709
+
710
+ checkArity(argc, 2);
711
+
712
+ if (unlikely(!isLongValue(argv[0])) || unlikely(!isLongValue(argv[1]))) {
713
+ return rbffi_CallFunction(argc, argv, function, fnInfo);
714
+ }
715
+
716
+ result = (*fn)(LARG(fnInfo, argv, 0), LARG(fnInfo, argv, 1));
717
+
718
+ return returnL(fnInfo, &result);
719
+ }
720
+
721
+ static VALUE
722
+ rbffi_InvokeLLLrL(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
723
+ {
724
+ L (*fn)(L, L, L) = (L (*)(L, L, L)) function;
725
+ L result;
726
+
727
+ checkArity(argc, 3);
728
+
729
+ if (unlikely(!isLongValue(argv[0])) || unlikely(!isLongValue(argv[1])) || unlikely(!isLongValue(argv[2]))) {
730
+ return rbffi_CallFunction(argc, argv, function, fnInfo);
731
+ }
732
+
733
+ result = (*fn)(LARG(fnInfo, argv, 0), LARG(fnInfo, argv, 1), LARG(fnInfo, argv, 2));
734
+
735
+ return returnL(fnInfo, &result);
736
+ }
737
+
738
+
739
+ static VALUE
740
+ rbffi_InvokeLLLLrL(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
741
+ {
742
+ return LCALL(fnInfo, argc, argv, (L (*)(L, L, L, L)) function,
743
+ LARG(fnInfo, argv, 0), LARG(fnInfo, argv, 1),
744
+ LARG(fnInfo, argv, 2), LARG(fnInfo, argv, 3));
745
+ }
746
+
747
+ static VALUE
748
+ rbffi_InvokeLLLLLrL(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
749
+ {
750
+ return LCALL(fnInfo, argc, argv, (L (*)(L, L, L, L, L)) function,
751
+ LARG(fnInfo, argv, 0), LARG(fnInfo, argv, 1), LARG(fnInfo, argv, 2),
752
+ LARG(fnInfo, argv, 3), LARG(fnInfo, argv, 4));
753
+ }
754
+
755
+ static VALUE
756
+ rbffi_InvokeLLLLLLrL(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
757
+ {
758
+ return LCALL(fnInfo, argc, argv, (L (*)(L, L, L, L, L, L)) function,
759
+ LARG(fnInfo, argv, 0), LARG(fnInfo, argv, 1), LARG(fnInfo, argv, 2),
760
+ LARG(fnInfo, argv, 3), LARG(fnInfo, argv, 4), LARG(fnInfo, argv, 5));
761
+ }
762
+
763
+ static VALUE
764
+ rbffi_InvokeLongParams(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
765
+ {
766
+ void **ffiValues = NULL;
767
+ FFIStorage* params = NULL;
768
+ L result;
769
+
770
+ if (fnInfo->parameterCount > 0) {
771
+ ffiValues = ALLOCA_N(void *, fnInfo->parameterCount);
772
+ params = ALLOCA_N(FFIStorage, fnInfo->parameterCount);
773
+
774
+ rbffi_SetupCallParams(argc, argv,
775
+ fnInfo->parameterCount, fnInfo->nativeParameterTypes, params, ffiValues,
776
+ fnInfo->callbackParameters, fnInfo->callbackCount, fnInfo->rbEnums);
777
+
778
+ switch (fnInfo->parameterCount) {
779
+ case 0:
780
+ result = ((L(*)(void)) function)();
781
+ break;
782
+
783
+ case 1:
784
+ result = ((L(*)(L)) function)(*(L *) ffiValues[0]);
785
+ break;
786
+
787
+ case 2:
788
+ result = ((L(*)(L, L)) function)(*(L *) ffiValues[0],
789
+ *(L *) ffiValues[1]);
790
+ break;
791
+
792
+ case 3:
793
+ result = ((L(*)(L, L, L)) function)(*(L *) ffiValues[0],
794
+ *(L *) ffiValues[1], *(L *) ffiValues[2]);
795
+ break;
796
+
797
+ case 4:
798
+ result = ((L(*)(L, L, L, L)) function)(*(L *) ffiValues[0],
799
+ *(L *) ffiValues[1], *(L *) ffiValues[2], *(L *) ffiValues[3]);
800
+ break;
801
+
802
+ case 5:
803
+ result = ((L(*)(L, L, L, L, L)) function)(*(L *) ffiValues[0],
804
+ *(L *) ffiValues[1], *(L *) ffiValues[2], *(L *) ffiValues[3],
805
+ *(L *) ffiValues[4]);
806
+ break;
807
+
808
+ case 6:
809
+ result = ((L(*)(L, L, L, L, L, L)) function)(*(L *) ffiValues[0],
810
+ *(L *) ffiValues[1], *(L *) ffiValues[2], *(L *) ffiValues[3],
811
+ *(L *) ffiValues[4], *(L *) ffiValues[5]);
812
+ break;
813
+
814
+ default:
815
+ rb_raise(rb_eRuntimeError, "BUG: should not reach this point");
816
+ return Qnil;
817
+ }
818
+ }
819
+
820
+ return returnL(fnInfo, &result);
821
+ }
822
+
823
+ #endif /* BYPASS_FFI */
824
+
825
+ static void*
826
+ callback_param(VALUE proc, VALUE cbInfo)
827
+ {
828
+ VALUE callback ;
829
+ if (proc == Qnil) {
830
+ return NULL ;
831
+ }
832
+
833
+ // Handle Function pointers here
834
+ if (rb_obj_is_kind_of(proc, rbffi_FunctionClass)) {
835
+ AbstractMemory* ptr;
836
+ Data_Get_Struct(proc, AbstractMemory, ptr);
837
+ return ptr->address;
838
+ }
839
+
840
+ //callback = rbffi_NativeCallback_ForProc(proc, cbInfo);
841
+ callback = rbffi_Function_ForProc(cbInfo, proc);
842
+
843
+ return ((AbstractMemory *) DATA_PTR(callback))->address;
844
+ }
845
+
846
+
847
+ void
848
+ rbffi_Call_Init(VALUE moduleFFI)
849
+ {
850
+ id_to_ptr = rb_intern("to_ptr");
851
+ id_map_symbol = rb_intern("__map_symbol");
852
+ }
853
+