ffi 1.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (530) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +25 -0
  3. data/.gitmodules +4 -0
  4. data/.travis.yml +42 -0
  5. data/.yardopts +5 -0
  6. data/CHANGELOG.md +131 -0
  7. data/COPYING +49 -0
  8. data/Gemfile +15 -0
  9. data/LICENSE +24 -0
  10. data/LICENSE.SPECS +22 -0
  11. data/README.md +115 -0
  12. data/Rakefile +195 -0
  13. data/appveyor.yml +27 -0
  14. data/ext/ffi_c/AbstractMemory.c +1109 -0
  15. data/ext/ffi_c/AbstractMemory.h +175 -0
  16. data/ext/ffi_c/ArrayType.c +162 -0
  17. data/ext/ffi_c/ArrayType.h +59 -0
  18. data/ext/ffi_c/Buffer.c +365 -0
  19. data/ext/ffi_c/Call.c +503 -0
  20. data/ext/ffi_c/Call.h +107 -0
  21. data/ext/ffi_c/ClosurePool.c +283 -0
  22. data/ext/ffi_c/ClosurePool.h +57 -0
  23. data/ext/ffi_c/DynamicLibrary.c +339 -0
  24. data/ext/ffi_c/DynamicLibrary.h +98 -0
  25. data/ext/ffi_c/Function.c +917 -0
  26. data/ext/ffi_c/Function.h +87 -0
  27. data/ext/ffi_c/FunctionInfo.c +271 -0
  28. data/ext/ffi_c/LastError.c +229 -0
  29. data/ext/ffi_c/LastError.h +47 -0
  30. data/ext/ffi_c/LongDouble.c +63 -0
  31. data/ext/ffi_c/LongDouble.h +51 -0
  32. data/ext/ffi_c/MappedType.c +168 -0
  33. data/ext/ffi_c/MappedType.h +59 -0
  34. data/ext/ffi_c/MemoryPointer.c +197 -0
  35. data/ext/ffi_c/MemoryPointer.h +53 -0
  36. data/ext/ffi_c/MethodHandle.c +358 -0
  37. data/ext/ffi_c/MethodHandle.h +55 -0
  38. data/ext/ffi_c/Platform.c +82 -0
  39. data/ext/ffi_c/Platform.h +45 -0
  40. data/ext/ffi_c/Pointer.c +508 -0
  41. data/ext/ffi_c/Pointer.h +63 -0
  42. data/ext/ffi_c/Struct.c +829 -0
  43. data/ext/ffi_c/Struct.h +106 -0
  44. data/ext/ffi_c/StructByValue.c +150 -0
  45. data/ext/ffi_c/StructByValue.h +55 -0
  46. data/ext/ffi_c/StructLayout.c +698 -0
  47. data/ext/ffi_c/Thread.c +137 -0
  48. data/ext/ffi_c/Thread.h +84 -0
  49. data/ext/ffi_c/Type.c +379 -0
  50. data/ext/ffi_c/Type.h +61 -0
  51. data/ext/ffi_c/Types.c +139 -0
  52. data/ext/ffi_c/Types.h +89 -0
  53. data/ext/ffi_c/Variadic.c +298 -0
  54. data/ext/ffi_c/compat.h +78 -0
  55. data/ext/ffi_c/extconf.rb +86 -0
  56. data/ext/ffi_c/ffi.c +93 -0
  57. data/ext/ffi_c/libffi.bsd.mk +40 -0
  58. data/ext/ffi_c/libffi.darwin.mk +105 -0
  59. data/ext/ffi_c/libffi.gnu.mk +32 -0
  60. data/ext/ffi_c/libffi.mk +18 -0
  61. data/ext/ffi_c/libffi.vc.mk +26 -0
  62. data/ext/ffi_c/libffi.vc64.mk +26 -0
  63. data/ext/ffi_c/libffi/.appveyor.yml +50 -0
  64. data/ext/ffi_c/libffi/.github/issue_template.md +10 -0
  65. data/ext/ffi_c/libffi/.gitignore +38 -0
  66. data/ext/ffi_c/libffi/.travis.yml +34 -0
  67. data/ext/ffi_c/libffi/.travis/ar-lib +270 -0
  68. data/ext/ffi_c/libffi/.travis/build.sh +34 -0
  69. data/ext/ffi_c/libffi/.travis/compile +351 -0
  70. data/ext/ffi_c/libffi/.travis/install.sh +22 -0
  71. data/ext/ffi_c/libffi/.travis/moxie-sim.exp +60 -0
  72. data/ext/ffi_c/libffi/.travis/site.exp +18 -0
  73. data/ext/ffi_c/libffi/ChangeLog.libffi +584 -0
  74. data/ext/ffi_c/libffi/ChangeLog.libffi-3.1 +6000 -0
  75. data/ext/ffi_c/libffi/ChangeLog.libgcj +40 -0
  76. data/ext/ffi_c/libffi/ChangeLog.v1 +764 -0
  77. data/ext/ffi_c/libffi/LICENSE +21 -0
  78. data/ext/ffi_c/libffi/LICENSE-BUILDTOOLS +352 -0
  79. data/ext/ffi_c/libffi/Makefile.am +166 -0
  80. data/ext/ffi_c/libffi/README.md +461 -0
  81. data/ext/ffi_c/libffi/acinclude.m4 +479 -0
  82. data/ext/ffi_c/libffi/autogen.sh +2 -0
  83. data/ext/ffi_c/libffi/config.guess +1466 -0
  84. data/ext/ffi_c/libffi/config.sub +1836 -0
  85. data/ext/ffi_c/libffi/configure.ac +394 -0
  86. data/ext/ffi_c/libffi/configure.host +289 -0
  87. data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +203 -0
  88. data/ext/ffi_c/libffi/include/Makefile.am +9 -0
  89. data/ext/ffi_c/libffi/include/ffi.h.in +511 -0
  90. data/ext/ffi_c/libffi/include/ffi_cfi.h +55 -0
  91. data/ext/ffi_c/libffi/include/ffi_common.h +149 -0
  92. data/ext/ffi_c/libffi/libffi.map.in +80 -0
  93. data/ext/ffi_c/libffi/libffi.pc.in +11 -0
  94. data/ext/ffi_c/libffi/libffi.xcodeproj/project.pbxproj +1043 -0
  95. data/ext/ffi_c/libffi/libtool-version +29 -0
  96. data/ext/ffi_c/libffi/m4/asmcfi.m4 +13 -0
  97. data/ext/ffi_c/libffi/m4/ax_append_flag.m4 +71 -0
  98. data/ext/ffi_c/libffi/m4/ax_cc_maxopt.m4 +194 -0
  99. data/ext/ffi_c/libffi/m4/ax_cflags_warn_all.m4 +122 -0
  100. data/ext/ffi_c/libffi/m4/ax_check_compile_flag.m4 +74 -0
  101. data/ext/ffi_c/libffi/m4/ax_compiler_vendor.m4 +87 -0
  102. data/ext/ffi_c/libffi/m4/ax_configure_args.m4 +70 -0
  103. data/ext/ffi_c/libffi/m4/ax_enable_builddir.m4 +302 -0
  104. data/ext/ffi_c/libffi/m4/ax_gcc_archflag.m4 +263 -0
  105. data/ext/ffi_c/libffi/m4/ax_gcc_x86_cpuid.m4 +89 -0
  106. data/ext/ffi_c/libffi/m4/ax_require_defined.m4 +37 -0
  107. data/ext/ffi_c/libffi/man/Makefile.am +8 -0
  108. data/ext/ffi_c/libffi/man/ffi.3 +41 -0
  109. data/ext/ffi_c/libffi/man/ffi_call.3 +103 -0
  110. data/ext/ffi_c/libffi/man/ffi_prep_cif.3 +68 -0
  111. data/ext/ffi_c/libffi/man/ffi_prep_cif_var.3 +73 -0
  112. data/ext/ffi_c/libffi/msvcc.sh +328 -0
  113. data/ext/ffi_c/libffi/src/aarch64/ffi.c +941 -0
  114. data/ext/ffi_c/libffi/src/aarch64/ffitarget.h +81 -0
  115. data/ext/ffi_c/libffi/src/aarch64/internal.h +67 -0
  116. data/ext/ffi_c/libffi/src/aarch64/sysv.S +438 -0
  117. data/ext/ffi_c/libffi/src/alpha/ffi.c +521 -0
  118. data/ext/ffi_c/libffi/src/alpha/ffitarget.h +57 -0
  119. data/ext/ffi_c/libffi/src/alpha/internal.h +23 -0
  120. data/ext/ffi_c/libffi/src/alpha/osf.S +282 -0
  121. data/ext/ffi_c/libffi/src/arc/arcompact.S +135 -0
  122. data/ext/ffi_c/libffi/src/arc/ffi.c +266 -0
  123. data/ext/ffi_c/libffi/src/arc/ffitarget.h +53 -0
  124. data/ext/ffi_c/libffi/src/arm/ffi.c +819 -0
  125. data/ext/ffi_c/libffi/src/arm/ffitarget.h +82 -0
  126. data/ext/ffi_c/libffi/src/arm/internal.h +7 -0
  127. data/ext/ffi_c/libffi/src/arm/sysv.S +383 -0
  128. data/ext/ffi_c/libffi/src/avr32/ffi.c +423 -0
  129. data/ext/ffi_c/libffi/src/avr32/ffitarget.h +55 -0
  130. data/ext/ffi_c/libffi/src/avr32/sysv.S +208 -0
  131. data/ext/ffi_c/libffi/src/bfin/ffi.c +196 -0
  132. data/ext/ffi_c/libffi/src/bfin/ffitarget.h +43 -0
  133. data/ext/ffi_c/libffi/src/bfin/sysv.S +179 -0
  134. data/ext/ffi_c/libffi/src/closures.c +966 -0
  135. data/ext/ffi_c/libffi/src/cris/ffi.c +386 -0
  136. data/ext/ffi_c/libffi/src/cris/ffitarget.h +56 -0
  137. data/ext/ffi_c/libffi/src/cris/sysv.S +215 -0
  138. data/ext/ffi_c/libffi/src/debug.c +64 -0
  139. data/ext/ffi_c/libffi/src/dlmalloc.c +5166 -0
  140. data/ext/ffi_c/libffi/src/frv/eabi.S +128 -0
  141. data/ext/ffi_c/libffi/src/frv/ffi.c +292 -0
  142. data/ext/ffi_c/libffi/src/frv/ffitarget.h +62 -0
  143. data/ext/ffi_c/libffi/src/ia64/ffi.c +604 -0
  144. data/ext/ffi_c/libffi/src/ia64/ffitarget.h +56 -0
  145. data/ext/ffi_c/libffi/src/ia64/ia64_flags.h +40 -0
  146. data/ext/ffi_c/libffi/src/ia64/unix.S +567 -0
  147. data/ext/ffi_c/libffi/src/java_raw_api.c +374 -0
  148. data/ext/ffi_c/libffi/src/m32r/ffi.c +232 -0
  149. data/ext/ffi_c/libffi/src/m32r/ffitarget.h +53 -0
  150. data/ext/ffi_c/libffi/src/m32r/sysv.S +121 -0
  151. data/ext/ffi_c/libffi/src/m68k/ffi.c +362 -0
  152. data/ext/ffi_c/libffi/src/m68k/ffitarget.h +54 -0
  153. data/ext/ffi_c/libffi/src/m68k/sysv.S +357 -0
  154. data/ext/ffi_c/libffi/src/m88k/ffi.c +400 -0
  155. data/ext/ffi_c/libffi/src/m88k/ffitarget.h +49 -0
  156. data/ext/ffi_c/libffi/src/m88k/obsd.S +209 -0
  157. data/ext/ffi_c/libffi/src/metag/ffi.c +330 -0
  158. data/ext/ffi_c/libffi/src/metag/ffitarget.h +53 -0
  159. data/ext/ffi_c/libffi/src/metag/sysv.S +311 -0
  160. data/ext/ffi_c/libffi/src/microblaze/ffi.c +321 -0
  161. data/ext/ffi_c/libffi/src/microblaze/ffitarget.h +53 -0
  162. data/ext/ffi_c/libffi/src/microblaze/sysv.S +302 -0
  163. data/ext/ffi_c/libffi/src/mips/ffi.c +1130 -0
  164. data/ext/ffi_c/libffi/src/mips/ffitarget.h +244 -0
  165. data/ext/ffi_c/libffi/src/mips/n32.S +663 -0
  166. data/ext/ffi_c/libffi/src/mips/o32.S +502 -0
  167. data/ext/ffi_c/libffi/src/moxie/eabi.S +101 -0
  168. data/ext/ffi_c/libffi/src/moxie/ffi.c +285 -0
  169. data/ext/ffi_c/libffi/src/moxie/ffitarget.h +52 -0
  170. data/ext/ffi_c/libffi/src/nios2/ffi.c +304 -0
  171. data/ext/ffi_c/libffi/src/nios2/ffitarget.h +52 -0
  172. data/ext/ffi_c/libffi/src/nios2/sysv.S +136 -0
  173. data/ext/ffi_c/libffi/src/or1k/ffi.c +328 -0
  174. data/ext/ffi_c/libffi/src/or1k/ffitarget.h +58 -0
  175. data/ext/ffi_c/libffi/src/or1k/sysv.S +107 -0
  176. data/ext/ffi_c/libffi/src/pa/ffi.c +719 -0
  177. data/ext/ffi_c/libffi/src/pa/ffitarget.h +85 -0
  178. data/ext/ffi_c/libffi/src/pa/hpux32.S +368 -0
  179. data/ext/ffi_c/libffi/src/pa/linux.S +357 -0
  180. data/ext/ffi_c/libffi/src/powerpc/aix.S +566 -0
  181. data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +694 -0
  182. data/ext/ffi_c/libffi/src/powerpc/asm.h +125 -0
  183. data/ext/ffi_c/libffi/src/powerpc/darwin.S +378 -0
  184. data/ext/ffi_c/libffi/src/powerpc/darwin_closure.S +571 -0
  185. data/ext/ffi_c/libffi/src/powerpc/ffi.c +173 -0
  186. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +1440 -0
  187. data/ext/ffi_c/libffi/src/powerpc/ffi_linux64.c +974 -0
  188. data/ext/ffi_c/libffi/src/powerpc/ffi_powerpc.h +94 -0
  189. data/ext/ffi_c/libffi/src/powerpc/ffi_sysv.c +923 -0
  190. data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +198 -0
  191. data/ext/ffi_c/libffi/src/powerpc/linux64.S +228 -0
  192. data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +488 -0
  193. data/ext/ffi_c/libffi/src/powerpc/ppc_closure.S +397 -0
  194. data/ext/ffi_c/libffi/src/powerpc/sysv.S +175 -0
  195. data/ext/ffi_c/libffi/src/prep_cif.c +261 -0
  196. data/ext/ffi_c/libffi/src/raw_api.c +267 -0
  197. data/ext/ffi_c/libffi/src/riscv/ffi.c +481 -0
  198. data/ext/ffi_c/libffi/src/riscv/ffitarget.h +69 -0
  199. data/ext/ffi_c/libffi/src/riscv/sysv.S +293 -0
  200. data/ext/ffi_c/libffi/src/s390/ffi.c +756 -0
  201. data/ext/ffi_c/libffi/src/s390/ffitarget.h +70 -0
  202. data/ext/ffi_c/libffi/src/s390/internal.h +11 -0
  203. data/ext/ffi_c/libffi/src/s390/sysv.S +325 -0
  204. data/ext/ffi_c/libffi/src/sh/ffi.c +717 -0
  205. data/ext/ffi_c/libffi/src/sh/ffitarget.h +54 -0
  206. data/ext/ffi_c/libffi/src/sh/sysv.S +850 -0
  207. data/ext/ffi_c/libffi/src/sh64/ffi.c +469 -0
  208. data/ext/ffi_c/libffi/src/sh64/ffitarget.h +58 -0
  209. data/ext/ffi_c/libffi/src/sh64/sysv.S +539 -0
  210. data/ext/ffi_c/libffi/src/sparc/ffi.c +468 -0
  211. data/ext/ffi_c/libffi/src/sparc/ffi64.c +608 -0
  212. data/ext/ffi_c/libffi/src/sparc/ffitarget.h +81 -0
  213. data/ext/ffi_c/libffi/src/sparc/internal.h +26 -0
  214. data/ext/ffi_c/libffi/src/sparc/v8.S +443 -0
  215. data/ext/ffi_c/libffi/src/sparc/v9.S +440 -0
  216. data/ext/ffi_c/libffi/src/tile/ffi.c +355 -0
  217. data/ext/ffi_c/libffi/src/tile/ffitarget.h +65 -0
  218. data/ext/ffi_c/libffi/src/tile/tile.S +360 -0
  219. data/ext/ffi_c/libffi/src/types.c +108 -0
  220. data/ext/ffi_c/libffi/src/vax/elfbsd.S +195 -0
  221. data/ext/ffi_c/libffi/src/vax/ffi.c +276 -0
  222. data/ext/ffi_c/libffi/src/vax/ffitarget.h +49 -0
  223. data/ext/ffi_c/libffi/src/x86/asmnames.h +30 -0
  224. data/ext/ffi_c/libffi/src/x86/ffi.c +754 -0
  225. data/ext/ffi_c/libffi/src/x86/ffi64.c +884 -0
  226. data/ext/ffi_c/libffi/src/x86/ffitarget.h +147 -0
  227. data/ext/ffi_c/libffi/src/x86/ffiw64.c +308 -0
  228. data/ext/ffi_c/libffi/src/x86/internal.h +29 -0
  229. data/ext/ffi_c/libffi/src/x86/internal64.h +22 -0
  230. data/ext/ffi_c/libffi/src/x86/sysv.S +1129 -0
  231. data/ext/ffi_c/libffi/src/x86/unix64.S +566 -0
  232. data/ext/ffi_c/libffi/src/x86/win64.S +232 -0
  233. data/ext/ffi_c/libffi/src/x86/win64_intel.S +237 -0
  234. data/ext/ffi_c/libffi/src/xtensa/ffi.c +298 -0
  235. data/ext/ffi_c/libffi/src/xtensa/ffitarget.h +53 -0
  236. data/ext/ffi_c/libffi/src/xtensa/sysv.S +258 -0
  237. data/ext/ffi_c/libffi/stamp-h.in +1 -0
  238. data/ext/ffi_c/libffi/testsuite/Makefile.am +117 -0
  239. data/ext/ffi_c/libffi/testsuite/config/default.exp +1 -0
  240. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +636 -0
  241. data/ext/ffi_c/libffi/testsuite/lib/target-libpath.exp +283 -0
  242. data/ext/ffi_c/libffi/testsuite/lib/wrapper.exp +45 -0
  243. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/Makefile +28 -0
  244. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/README +78 -0
  245. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/alignof.h +50 -0
  246. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/bhaible.exp +58 -0
  247. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-call.c +1745 -0
  248. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-callback.c +2885 -0
  249. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/testcases.c +743 -0
  250. data/ext/ffi_c/libffi/testsuite/libffi.call/align_mixed.c +46 -0
  251. data/ext/ffi_c/libffi/testsuite/libffi.call/align_stdcall.c +46 -0
  252. data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +43 -0
  253. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn0.c +89 -0
  254. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn1.c +81 -0
  255. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn2.c +81 -0
  256. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn3.c +82 -0
  257. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn4.c +89 -0
  258. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn5.c +92 -0
  259. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn6.c +90 -0
  260. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_loc_fn0.c +95 -0
  261. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_simple.c +55 -0
  262. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_12byte.c +94 -0
  263. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_16byte.c +95 -0
  264. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_18byte.c +96 -0
  265. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_19byte.c +102 -0
  266. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_1_1byte.c +89 -0
  267. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte.c +91 -0
  268. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte1.c +93 -0
  269. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_24byte.c +113 -0
  270. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_2byte.c +90 -0
  271. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3_1byte.c +95 -0
  272. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte1.c +90 -0
  273. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte2.c +90 -0
  274. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3float.c +95 -0
  275. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4_1byte.c +98 -0
  276. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4byte.c +90 -0
  277. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5_1_byte.c +109 -0
  278. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5byte.c +98 -0
  279. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_64byte.c +124 -0
  280. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6_1_byte.c +113 -0
  281. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6byte.c +99 -0
  282. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7_1_byte.c +117 -0
  283. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7byte.c +97 -0
  284. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_8byte.c +88 -0
  285. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte1.c +90 -0
  286. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte2.c +91 -0
  287. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_double.c +93 -0
  288. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_float.c +91 -0
  289. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble.c +92 -0
  290. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split.c +132 -0
  291. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c +115 -0
  292. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_pointer.c +95 -0
  293. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint16.c +91 -0
  294. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint32.c +91 -0
  295. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint64.c +92 -0
  296. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint16.c +91 -0
  297. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint32.c +91 -0
  298. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint64.c +93 -0
  299. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_dbls_struct.c +66 -0
  300. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_double.c +43 -0
  301. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_double_va.c +61 -0
  302. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_float.c +42 -0
  303. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble.c +105 -0
  304. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble_va.c +61 -0
  305. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_many_mixed_args.c +70 -0
  306. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_many_mixed_float_double.c +55 -0
  307. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_schar.c +74 -0
  308. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshort.c +74 -0
  309. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshortchar.c +86 -0
  310. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_uchar.c +91 -0
  311. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushort.c +74 -0
  312. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushortchar.c +86 -0
  313. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer.c +74 -0
  314. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer_stack.c +142 -0
  315. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_schar.c +44 -0
  316. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_sint.c +42 -0
  317. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_sshort.c +42 -0
  318. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_struct_va1.c +114 -0
  319. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uchar.c +42 -0
  320. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uchar_va.c +44 -0
  321. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uint.c +43 -0
  322. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uint_va.c +45 -0
  323. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulong_va.c +45 -0
  324. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulonglong.c +47 -0
  325. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ushort.c +43 -0
  326. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ushort_va.c +44 -0
  327. data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_abi.c +36 -0
  328. data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_typedef.c +26 -0
  329. data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +138 -0
  330. data/ext/ffi_c/libffi/testsuite/libffi.call/float.c +59 -0
  331. data/ext/ffi_c/libffi/testsuite/libffi.call/float1.c +60 -0
  332. data/ext/ffi_c/libffi/testsuite/libffi.call/float2.c +60 -0
  333. data/ext/ffi_c/libffi/testsuite/libffi.call/float3.c +74 -0
  334. data/ext/ffi_c/libffi/testsuite/libffi.call/float4.c +62 -0
  335. data/ext/ffi_c/libffi/testsuite/libffi.call/float_va.c +107 -0
  336. data/ext/ffi_c/libffi/testsuite/libffi.call/huge_struct.c +341 -0
  337. data/ext/ffi_c/libffi/testsuite/libffi.call/many.c +59 -0
  338. data/ext/ffi_c/libffi/testsuite/libffi.call/many2.c +57 -0
  339. data/ext/ffi_c/libffi/testsuite/libffi.call/many_double.c +70 -0
  340. data/ext/ffi_c/libffi/testsuite/libffi.call/many_mixed.c +78 -0
  341. data/ext/ffi_c/libffi/testsuite/libffi.call/negint.c +52 -0
  342. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct.c +152 -0
  343. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct1.c +161 -0
  344. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct10.c +134 -0
  345. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct11.c +121 -0
  346. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct2.c +110 -0
  347. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct3.c +111 -0
  348. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct4.c +111 -0
  349. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct5.c +112 -0
  350. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct6.c +131 -0
  351. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct7.c +111 -0
  352. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct8.c +131 -0
  353. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct9.c +131 -0
  354. data/ext/ffi_c/libffi/testsuite/libffi.call/offsets.c +46 -0
  355. data/ext/ffi_c/libffi/testsuite/libffi.call/pr1172638.c +127 -0
  356. data/ext/ffi_c/libffi/testsuite/libffi.call/problem1.c +90 -0
  357. data/ext/ffi_c/libffi/testsuite/libffi.call/promotion.c +59 -0
  358. data/ext/ffi_c/libffi/testsuite/libffi.call/pyobjc-tc.c +114 -0
  359. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl.c +36 -0
  360. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl1.c +43 -0
  361. data/ext/ffi_c/libffi/testsuite/libffi.call/return_dbl2.c +42 -0
  362. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl.c +35 -0
  363. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl1.c +36 -0
  364. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl2.c +49 -0
  365. data/ext/ffi_c/libffi/testsuite/libffi.call/return_fl3.c +42 -0
  366. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ldl.c +34 -0
  367. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll.c +41 -0
  368. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll1.c +43 -0
  369. data/ext/ffi_c/libffi/testsuite/libffi.call/return_sc.c +36 -0
  370. data/ext/ffi_c/libffi/testsuite/libffi.call/return_sl.c +38 -0
  371. data/ext/ffi_c/libffi/testsuite/libffi.call/return_uc.c +38 -0
  372. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ul.c +38 -0
  373. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_large.c +145 -0
  374. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_large2.c +148 -0
  375. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium.c +124 -0
  376. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium2.c +125 -0
  377. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen.c +44 -0
  378. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen2.c +49 -0
  379. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen3.c +49 -0
  380. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen4.c +55 -0
  381. data/ext/ffi_c/libffi/testsuite/libffi.call/struct1.c +67 -0
  382. data/ext/ffi_c/libffi/testsuite/libffi.call/struct10.c +57 -0
  383. data/ext/ffi_c/libffi/testsuite/libffi.call/struct2.c +67 -0
  384. data/ext/ffi_c/libffi/testsuite/libffi.call/struct3.c +60 -0
  385. data/ext/ffi_c/libffi/testsuite/libffi.call/struct4.c +64 -0
  386. data/ext/ffi_c/libffi/testsuite/libffi.call/struct5.c +66 -0
  387. data/ext/ffi_c/libffi/testsuite/libffi.call/struct6.c +64 -0
  388. data/ext/ffi_c/libffi/testsuite/libffi.call/struct7.c +74 -0
  389. data/ext/ffi_c/libffi/testsuite/libffi.call/struct8.c +81 -0
  390. data/ext/ffi_c/libffi/testsuite/libffi.call/struct9.c +68 -0
  391. data/ext/ffi_c/libffi/testsuite/libffi.call/testclosure.c +70 -0
  392. data/ext/ffi_c/libffi/testsuite/libffi.call/uninitialized.c +61 -0
  393. data/ext/ffi_c/libffi/testsuite/libffi.call/unwindtest.cc +117 -0
  394. data/ext/ffi_c/libffi/testsuite/libffi.call/unwindtest_ffi_call.cc +54 -0
  395. data/ext/ffi_c/libffi/testsuite/libffi.call/va_1.c +196 -0
  396. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct1.c +121 -0
  397. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct2.c +123 -0
  398. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct3.c +125 -0
  399. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex.inc +91 -0
  400. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_double.c +10 -0
  401. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_float.c +10 -0
  402. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_align_complex_longdouble.c +10 -0
  403. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex.inc +42 -0
  404. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_double.c +10 -0
  405. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_float.c +10 -0
  406. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_longdouble.c +10 -0
  407. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct.inc +71 -0
  408. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_double.c +10 -0
  409. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_float.c +10 -0
  410. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_struct_longdouble.c +10 -0
  411. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va.inc +80 -0
  412. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_double.c +10 -0
  413. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_float.c +16 -0
  414. data/ext/ffi_c/libffi/testsuite/libffi.complex/cls_complex_va_longdouble.c +10 -0
  415. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex.exp +36 -0
  416. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex.inc +51 -0
  417. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_double.inc +7 -0
  418. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_float.inc +7 -0
  419. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_defs_longdouble.inc +7 -0
  420. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_double.c +10 -0
  421. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_float.c +10 -0
  422. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_int.c +86 -0
  423. data/ext/ffi_c/libffi/testsuite/libffi.complex/complex_longdouble.c +10 -0
  424. data/ext/ffi_c/libffi/testsuite/libffi.complex/ffitest.h +1 -0
  425. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex.inc +78 -0
  426. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_double.c +10 -0
  427. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_float.c +10 -0
  428. data/ext/ffi_c/libffi/testsuite/libffi.complex/many_complex_longdouble.c +10 -0
  429. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex.inc +37 -0
  430. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1.inc +41 -0
  431. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_double.c +10 -0
  432. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_float.c +10 -0
  433. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex1_longdouble.c +10 -0
  434. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2.inc +44 -0
  435. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_double.c +10 -0
  436. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_float.c +10 -0
  437. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex2_longdouble.c +10 -0
  438. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_double.c +10 -0
  439. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_float.c +10 -0
  440. data/ext/ffi_c/libffi/testsuite/libffi.complex/return_complex_longdouble.c +10 -0
  441. data/ext/ffi_c/libffi/testsuite/libffi.go/aa-direct.c +34 -0
  442. data/ext/ffi_c/libffi/testsuite/libffi.go/closure1.c +28 -0
  443. data/ext/ffi_c/libffi/testsuite/libffi.go/ffitest.h +1 -0
  444. data/ext/ffi_c/libffi/testsuite/libffi.go/go.exp +36 -0
  445. data/ext/ffi_c/libffi/testsuite/libffi.go/static-chain.h +19 -0
  446. data/ext/ffi_c/rbffi.h +55 -0
  447. data/ext/ffi_c/rbffi_endian.h +59 -0
  448. data/ext/ffi_c/win32/stdbool.h +8 -0
  449. data/ext/ffi_c/win32/stdint.h +201 -0
  450. data/ffi.gemspec +43 -0
  451. data/lib/ffi.rb +20 -0
  452. data/lib/ffi/autopointer.rb +203 -0
  453. data/lib/ffi/buffer.rb +4 -0
  454. data/lib/ffi/callback.rb +4 -0
  455. data/lib/ffi/data_converter.rb +67 -0
  456. data/lib/ffi/enum.rb +296 -0
  457. data/lib/ffi/errno.rb +43 -0
  458. data/lib/ffi/ffi.rb +45 -0
  459. data/lib/ffi/io.rb +62 -0
  460. data/lib/ffi/library.rb +588 -0
  461. data/lib/ffi/managedstruct.rb +84 -0
  462. data/lib/ffi/memorypointer.rb +1 -0
  463. data/lib/ffi/platform.rb +172 -0
  464. data/lib/ffi/platform/aarch64-freebsd/types.conf +128 -0
  465. data/lib/ffi/platform/aarch64-freebsd12/types.conf +128 -0
  466. data/lib/ffi/platform/aarch64-linux/types.conf +104 -0
  467. data/lib/ffi/platform/arm-freebsd/types.conf +152 -0
  468. data/lib/ffi/platform/arm-freebsd12/types.conf +152 -0
  469. data/lib/ffi/platform/arm-linux/types.conf +104 -0
  470. data/lib/ffi/platform/i386-cygwin/types.conf +3 -0
  471. data/lib/ffi/platform/i386-darwin/types.conf +100 -0
  472. data/lib/ffi/platform/i386-freebsd/types.conf +152 -0
  473. data/lib/ffi/platform/i386-freebsd12/types.conf +152 -0
  474. data/lib/ffi/platform/i386-gnu/types.conf +107 -0
  475. data/lib/ffi/platform/i386-linux/types.conf +103 -0
  476. data/lib/ffi/platform/i386-netbsd/types.conf +126 -0
  477. data/lib/ffi/platform/i386-openbsd/types.conf +128 -0
  478. data/lib/ffi/platform/i386-solaris/types.conf +122 -0
  479. data/lib/ffi/platform/i386-windows/types.conf +105 -0
  480. data/lib/ffi/platform/ia64-linux/types.conf +104 -0
  481. data/lib/ffi/platform/mips-linux/types.conf +102 -0
  482. data/lib/ffi/platform/mips64-linux/types.conf +104 -0
  483. data/lib/ffi/platform/mips64el-linux/types.conf +104 -0
  484. data/lib/ffi/platform/mipsel-linux/types.conf +102 -0
  485. data/lib/ffi/platform/mipsisa32r6-linux/types.conf +102 -0
  486. data/lib/ffi/platform/mipsisa32r6el-linux/types.conf +102 -0
  487. data/lib/ffi/platform/mipsisa64r6-linux/types.conf +104 -0
  488. data/lib/ffi/platform/mipsisa64r6el-linux/types.conf +104 -0
  489. data/lib/ffi/platform/powerpc-aix/types.conf +180 -0
  490. data/lib/ffi/platform/powerpc-darwin/types.conf +100 -0
  491. data/lib/ffi/platform/powerpc-linux/types.conf +100 -0
  492. data/lib/ffi/platform/powerpc64-linux/types.conf +104 -0
  493. data/lib/ffi/platform/s390-linux/types.conf +102 -0
  494. data/lib/ffi/platform/s390x-linux/types.conf +102 -0
  495. data/lib/ffi/platform/sparc-linux/types.conf +102 -0
  496. data/lib/ffi/platform/sparc-solaris/types.conf +128 -0
  497. data/lib/ffi/platform/sparc64-linux/types.conf +102 -0
  498. data/lib/ffi/platform/sparcv9-solaris/types.conf +128 -0
  499. data/lib/ffi/platform/x86_64-cygwin/types.conf +3 -0
  500. data/lib/ffi/platform/x86_64-darwin/types.conf +126 -0
  501. data/lib/ffi/platform/x86_64-freebsd/types.conf +128 -0
  502. data/lib/ffi/platform/x86_64-freebsd12/types.conf +128 -0
  503. data/lib/ffi/platform/x86_64-linux/types.conf +102 -0
  504. data/lib/ffi/platform/x86_64-netbsd/types.conf +128 -0
  505. data/lib/ffi/platform/x86_64-openbsd/types.conf +134 -0
  506. data/lib/ffi/platform/x86_64-solaris/types.conf +122 -0
  507. data/lib/ffi/platform/x86_64-windows/types.conf +120 -0
  508. data/lib/ffi/pointer.rb +160 -0
  509. data/lib/ffi/struct.rb +311 -0
  510. data/lib/ffi/struct_by_reference.rb +72 -0
  511. data/lib/ffi/struct_layout.rb +96 -0
  512. data/lib/ffi/struct_layout_builder.rb +227 -0
  513. data/lib/ffi/tools/const_generator.rb +230 -0
  514. data/lib/ffi/tools/generator.rb +105 -0
  515. data/lib/ffi/tools/generator_task.rb +32 -0
  516. data/lib/ffi/tools/struct_generator.rb +194 -0
  517. data/lib/ffi/tools/types_generator.rb +134 -0
  518. data/lib/ffi/types.rb +194 -0
  519. data/lib/ffi/union.rb +43 -0
  520. data/lib/ffi/variadic.rb +78 -0
  521. data/lib/ffi/version.rb +3 -0
  522. data/samples/getlogin.rb +8 -0
  523. data/samples/getpid.rb +8 -0
  524. data/samples/gettimeofday.rb +18 -0
  525. data/samples/hello.rb +7 -0
  526. data/samples/inotify.rb +60 -0
  527. data/samples/pty.rb +76 -0
  528. data/samples/qsort.rb +21 -0
  529. data/samples/sample_helper.rb +6 -0
  530. metadata +663 -0
@@ -0,0 +1,98 @@
1
+ /*
2
+ * Copyright (c) 2008-2010 Wayne Meissner
3
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions are met:
8
+ * * Redistributions of source code must retain the above copyright
9
+ * notice, this list of conditions and the following disclaimer.
10
+ * * Redistributions in binary form must reproduce the above copyright
11
+ * notice, this list of conditions and the following disclaimer in the
12
+ * documentation and/or other materials provided with the distribution.
13
+ * * Neither the name of the Ruby FFI project nor the
14
+ * names of its contributors may be used to endorse or promote products
15
+ * derived from this software without specific prior written permission.
16
+ *
17
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
21
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
+ */
28
+
29
+ #ifndef _LIBRARY_H
30
+ #define _LIBRARY_H
31
+
32
+ #ifdef __cplusplus
33
+ extern "C" {
34
+ #endif
35
+
36
+ /* if these aren't defined (eg. windows), we need sensible defaults */
37
+ #ifndef RTLD_LAZY
38
+ #define RTLD_LAZY 1
39
+ #endif
40
+
41
+ #ifndef RTLD_NOW
42
+ #define RTLD_NOW 2
43
+ #endif
44
+
45
+ #ifndef RTLD_LOCAL
46
+ #define RTLD_LOCAL 4
47
+ #endif
48
+
49
+ #ifndef RTLD_GLOBAL
50
+ #define RTLD_GLOBAL 8
51
+ #endif
52
+
53
+ /* If these aren't defined, they're not supported so define as 0 */
54
+ #ifndef RTLD_NOLOAD
55
+ #define RTLD_NOLOAD 0
56
+ #endif
57
+
58
+ #ifndef RTLD_NODELETE
59
+ #define RTLD_NODELETE 0
60
+ #endif
61
+
62
+ #ifndef RTLD_FIRST
63
+ #define RTLD_FIRST 0
64
+ #endif
65
+
66
+ #ifndef RTLD_DEEPBIND
67
+ #define RTLD_DEEPBIND 0
68
+ #endif
69
+
70
+ #ifndef RTLD_MEMBER
71
+ #define RTLD_MEMBER 0
72
+ #endif
73
+
74
+ /* convenience */
75
+ #ifndef RTLD_BINDING_MASK
76
+ #define RTLD_BINDING_MASK (RTLD_LAZY | RTLD_NOW)
77
+ #endif
78
+
79
+ #ifndef RTLD_LOCATION_MASK
80
+ #define RTLD_LOCATION_MASK (RTLD_LOCAL | RTLD_GLOBAL)
81
+ #endif
82
+
83
+ #ifndef RTLD_ALL_MASK
84
+ #define RTLD_ALL_MASK (RTLD_BINDING_MASK | RTLD_LOCATION_MASK | RTLD_NOLOAD | RTLD_NODELETE | RTLD_FIRST | RTLD_DEEPBIND | RTLD_MEMBER)
85
+ #endif
86
+
87
+ typedef struct Library {
88
+ void* handle;
89
+ } Library;
90
+
91
+ extern void rbffi_DynamicLibrary_Init(VALUE ffiModule);
92
+
93
+ #ifdef __cplusplus
94
+ }
95
+ #endif
96
+
97
+ #endif /* _LIBRARY_H */
98
+
@@ -0,0 +1,917 @@
1
+ /*
2
+ * Copyright (c) 2009-2011 Wayne Meissner
3
+ *
4
+ * Copyright (c) 2008-2013, Ruby FFI project contributors
5
+ * All rights reserved.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following conditions are met:
9
+ * * Redistributions of source code must retain the above copyright
10
+ * notice, this list of conditions and the following disclaimer.
11
+ * * Redistributions in binary form must reproduce the above copyright
12
+ * notice, this list of conditions and the following disclaimer in the
13
+ * documentation and/or other materials provided with the distribution.
14
+ * * Neither the name of the Ruby FFI project nor the
15
+ * names of its contributors may be used to endorse or promote products
16
+ * derived from this software without specific prior written permission.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
+ * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
22
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+ */
29
+
30
+ #ifndef _MSC_VER
31
+ #include <sys/param.h>
32
+ #endif
33
+ #include <sys/types.h>
34
+ #ifndef _WIN32
35
+ # include <sys/mman.h>
36
+ # include <unistd.h>
37
+ #endif
38
+
39
+ #include <stdio.h>
40
+ #ifndef _MSC_VER
41
+ # include <stdint.h>
42
+ # include <stdbool.h>
43
+ #else
44
+ # include "win32/stdbool.h"
45
+ # if !defined(INT8_MIN)
46
+ # include "win32/stdint.h"
47
+ # endif
48
+ #endif
49
+ #include <ruby.h>
50
+ #include <ruby/thread.h>
51
+
52
+ #include <ffi.h>
53
+ #if defined(HAVE_NATIVETHREAD) && !defined(_WIN32)
54
+ #include <pthread.h>
55
+ #endif
56
+ #include <fcntl.h>
57
+
58
+ #include "rbffi.h"
59
+ #include "compat.h"
60
+
61
+ #include "AbstractMemory.h"
62
+ #include "Pointer.h"
63
+ #include "Struct.h"
64
+ #include "Platform.h"
65
+ #include "Type.h"
66
+ #include "LastError.h"
67
+ #include "Call.h"
68
+ #include "ClosurePool.h"
69
+ #include "MappedType.h"
70
+ #include "Thread.h"
71
+ #include "LongDouble.h"
72
+ #include "MethodHandle.h"
73
+ #include "Function.h"
74
+
75
+ typedef struct Function_ {
76
+ Pointer base;
77
+ FunctionType* info;
78
+ MethodHandle* methodHandle;
79
+ bool autorelease;
80
+ Closure* closure;
81
+ VALUE rbProc;
82
+ VALUE rbFunctionInfo;
83
+ } Function;
84
+
85
+ static void function_mark(Function *);
86
+ static void function_free(Function *);
87
+ static VALUE function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc);
88
+ static void callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data);
89
+ static bool callback_prep(void* ctx, void* code, Closure* closure, char* errmsg, size_t errmsgsize);
90
+ static void* callback_with_gvl(void* data);
91
+ static VALUE invoke_callback(void* data);
92
+ static VALUE save_callback_exception(void* data, VALUE exc);
93
+
94
+ #define DEFER_ASYNC_CALLBACK 1
95
+
96
+
97
+ #if defined(DEFER_ASYNC_CALLBACK)
98
+ static VALUE async_cb_event(void *);
99
+ static VALUE async_cb_call(void *);
100
+ #endif
101
+
102
+ #ifdef HAVE_RUBY_THREAD_HAS_GVL_P
103
+ extern int ruby_thread_has_gvl_p(void);
104
+ #define rbffi_thread_has_gvl_p(frame) ruby_thread_has_gvl_p()
105
+ #else
106
+ static int rbffi_thread_has_gvl_p(rbffi_frame_t *frame)
107
+ {
108
+ return frame != NULL && frame->has_gvl;
109
+ }
110
+ #endif
111
+
112
+ #ifdef HAVE_RUBY_NATIVE_THREAD_P
113
+ extern int ruby_native_thread_p(void);
114
+ #define rbffi_native_thread_p(frame) ruby_native_thread_p()
115
+ #else
116
+ static int rbffi_native_thread_p(rbffi_frame_t *frame)
117
+ {
118
+ return frame != NULL;
119
+ }
120
+ #endif
121
+
122
+
123
+ VALUE rbffi_FunctionClass = Qnil;
124
+
125
+ #if defined(DEFER_ASYNC_CALLBACK)
126
+ static VALUE async_cb_thread = Qnil;
127
+ #endif
128
+
129
+ static ID id_call = 0, id_to_native = 0, id_from_native = 0, id_cbtable = 0, id_cb_ref = 0;
130
+
131
+ struct gvl_callback {
132
+ Closure* closure;
133
+ void* retval;
134
+ void** parameters;
135
+ bool done;
136
+ rbffi_frame_t *frame;
137
+ #if defined(DEFER_ASYNC_CALLBACK)
138
+ struct gvl_callback* next;
139
+ # ifndef _WIN32
140
+ pthread_cond_t async_cond;
141
+ pthread_mutex_t async_mutex;
142
+ # else
143
+ HANDLE async_event;
144
+ # endif
145
+ #endif
146
+ };
147
+
148
+
149
+ #if defined(DEFER_ASYNC_CALLBACK)
150
+ static struct gvl_callback* async_cb_list = NULL;
151
+ # ifndef _WIN32
152
+ static pthread_mutex_t async_cb_mutex = PTHREAD_MUTEX_INITIALIZER;
153
+ static pthread_cond_t async_cb_cond = PTHREAD_COND_INITIALIZER;
154
+ # else
155
+ static HANDLE async_cb_cond;
156
+ static CRITICAL_SECTION async_cb_lock;
157
+ # endif
158
+ #endif
159
+
160
+
161
+ static VALUE
162
+ function_allocate(VALUE klass)
163
+ {
164
+ Function *fn;
165
+ VALUE obj;
166
+
167
+ obj = Data_Make_Struct(klass, Function, function_mark, function_free, fn);
168
+
169
+ fn->base.memory.flags = MEM_RD;
170
+ fn->base.rbParent = Qnil;
171
+ fn->rbProc = Qnil;
172
+ fn->rbFunctionInfo = Qnil;
173
+ fn->autorelease = true;
174
+
175
+ return obj;
176
+ }
177
+
178
+ static void
179
+ function_mark(Function *fn)
180
+ {
181
+ rb_gc_mark(fn->base.rbParent);
182
+ rb_gc_mark(fn->rbProc);
183
+ rb_gc_mark(fn->rbFunctionInfo);
184
+ }
185
+
186
+ static void
187
+ function_free(Function *fn)
188
+ {
189
+ if (fn->methodHandle != NULL) {
190
+ rbffi_MethodHandle_Free(fn->methodHandle);
191
+ }
192
+
193
+ if (fn->closure != NULL && fn->autorelease) {
194
+ rbffi_Closure_Free(fn->closure);
195
+ }
196
+
197
+ xfree(fn);
198
+ }
199
+
200
+ /*
201
+ * @param [Type, Symbol] return_type return type for the function
202
+ * @param [Array<Type, Symbol>] param_types array of parameters types
203
+ * @param [Hash] options see {FFI::FunctionType} for available options
204
+ * @return [self]
205
+ * A new Function instance.
206
+ *
207
+ * Define a function from a Proc or a block.
208
+ *
209
+ * @overload initialize(return_type, param_types, options = {}) { |i| ... }
210
+ * @yieldparam i parameters for the function
211
+ * @overload initialize(return_type, param_types, proc, options = {})
212
+ * @param [Proc] proc
213
+ */
214
+ static VALUE
215
+ function_initialize(int argc, VALUE* argv, VALUE self)
216
+ {
217
+
218
+ VALUE rbReturnType = Qnil, rbParamTypes = Qnil, rbProc = Qnil, rbOptions = Qnil;
219
+ VALUE rbFunctionInfo = Qnil;
220
+ VALUE infoArgv[3];
221
+ int nargs;
222
+
223
+ nargs = rb_scan_args(argc, argv, "22", &rbReturnType, &rbParamTypes, &rbProc, &rbOptions);
224
+
225
+ /*
226
+ * Callback with block,
227
+ * e.g. Function.new(:int, [ :int ]) { |i| blah }
228
+ * or Function.new(:int, [ :int ], { :convention => :stdcall }) { |i| blah }
229
+ */
230
+ if (rb_block_given_p()) {
231
+ if (nargs > 3) {
232
+ rb_raise(rb_eArgError, "cannot create function with both proc/address and block");
233
+ }
234
+ rbOptions = rbProc;
235
+ rbProc = rb_block_proc();
236
+ } else {
237
+ /* Callback with proc, or Function with address
238
+ * e.g. Function.new(:int, [ :int ], Proc.new { |i| })
239
+ * Function.new(:int, [ :int ], Proc.new { |i| }, { :convention => :stdcall })
240
+ * Function.new(:int, [ :int ], addr)
241
+ * Function.new(:int, [ :int ], addr, { :convention => :stdcall })
242
+ */
243
+ }
244
+
245
+ infoArgv[0] = rbReturnType;
246
+ infoArgv[1] = rbParamTypes;
247
+ infoArgv[2] = rbOptions;
248
+ rbFunctionInfo = rb_class_new_instance(rbOptions != Qnil ? 3 : 2, infoArgv, rbffi_FunctionTypeClass);
249
+
250
+ function_init(self, rbFunctionInfo, rbProc);
251
+
252
+ return self;
253
+ }
254
+
255
+ /*
256
+ * call-seq: initialize_copy(other)
257
+ * @return [nil]
258
+ * DO NOT CALL THIS METHOD
259
+ */
260
+ static VALUE
261
+ function_initialize_copy(VALUE self, VALUE other)
262
+ {
263
+ rb_raise(rb_eRuntimeError, "cannot duplicate function instances");
264
+ return Qnil;
265
+ }
266
+
267
+ VALUE
268
+ rbffi_Function_NewInstance(VALUE rbFunctionInfo, VALUE rbProc)
269
+ {
270
+ return function_init(function_allocate(rbffi_FunctionClass), rbFunctionInfo, rbProc);
271
+ }
272
+
273
+ VALUE
274
+ rbffi_Function_ForProc(VALUE rbFunctionInfo, VALUE proc)
275
+ {
276
+ VALUE callback, cbref, cbTable;
277
+ Function* fp;
278
+
279
+ cbref = RTEST(rb_ivar_defined(proc, id_cb_ref)) ? rb_ivar_get(proc, id_cb_ref) : Qnil;
280
+ /* If the first callback reference has the same function function signature, use it */
281
+ if (cbref != Qnil && CLASS_OF(cbref) == rbffi_FunctionClass) {
282
+ Data_Get_Struct(cbref, Function, fp);
283
+ if (fp->rbFunctionInfo == rbFunctionInfo) {
284
+ return cbref;
285
+ }
286
+ }
287
+
288
+ cbTable = RTEST(rb_ivar_defined(proc, id_cbtable)) ? rb_ivar_get(proc, id_cbtable) : Qnil;
289
+ if (cbTable != Qnil && (callback = rb_hash_aref(cbTable, rbFunctionInfo)) != Qnil) {
290
+ return callback;
291
+ }
292
+
293
+ /* No existing function for the proc with that signature, create a new one and cache it */
294
+ callback = rbffi_Function_NewInstance(rbFunctionInfo, proc);
295
+ if (cbref == Qnil) {
296
+ /* If there is no other cb already cached for this proc, we can use the ivar slot */
297
+ rb_ivar_set(proc, id_cb_ref, callback);
298
+ } else {
299
+ /* The proc instance has been used as more than one type of callback, store extras in a hash */
300
+ cbTable = rb_hash_new();
301
+ rb_ivar_set(proc, id_cbtable, cbTable);
302
+ rb_hash_aset(cbTable, rbFunctionInfo, callback);
303
+ }
304
+
305
+ return callback;
306
+ }
307
+
308
+ static VALUE
309
+ function_init(VALUE self, VALUE rbFunctionInfo, VALUE rbProc)
310
+ {
311
+ Function* fn = NULL;
312
+
313
+ Data_Get_Struct(self, Function, fn);
314
+
315
+ fn->rbFunctionInfo = rbFunctionInfo;
316
+
317
+ Data_Get_Struct(fn->rbFunctionInfo, FunctionType, fn->info);
318
+
319
+ if (rb_obj_is_kind_of(rbProc, rbffi_PointerClass)) {
320
+ Pointer* orig;
321
+ Data_Get_Struct(rbProc, Pointer, orig);
322
+ fn->base.memory = orig->memory;
323
+ fn->base.rbParent = rbProc;
324
+
325
+ } else if (rb_obj_is_kind_of(rbProc, rb_cProc) || rb_respond_to(rbProc, id_call)) {
326
+ if (fn->info->closurePool == NULL) {
327
+ fn->info->closurePool = rbffi_ClosurePool_New(sizeof(ffi_closure), callback_prep, fn->info);
328
+ if (fn->info->closurePool == NULL) {
329
+ rb_raise(rb_eNoMemError, "failed to create closure pool");
330
+ }
331
+ }
332
+
333
+ #if defined(DEFER_ASYNC_CALLBACK)
334
+ if (async_cb_thread == Qnil) {
335
+ async_cb_thread = rb_thread_create(async_cb_event, NULL);
336
+ }
337
+ #endif
338
+
339
+ fn->closure = rbffi_Closure_Alloc(fn->info->closurePool);
340
+ fn->closure->info = fn;
341
+ fn->base.memory.address = fn->closure->code;
342
+ fn->base.memory.size = sizeof(*fn->closure);
343
+ fn->autorelease = true;
344
+
345
+ } else {
346
+ rb_raise(rb_eTypeError, "wrong argument type %s, expected pointer or proc",
347
+ rb_obj_classname(rbProc));
348
+ }
349
+
350
+ fn->rbProc = rbProc;
351
+
352
+ return self;
353
+ }
354
+
355
+ /*
356
+ * call-seq: call(*args)
357
+ * @param [Array] args function arguments
358
+ * @return [FFI::Type]
359
+ * Call the function
360
+ */
361
+ static VALUE
362
+ function_call(int argc, VALUE* argv, VALUE self)
363
+ {
364
+ Function* fn;
365
+
366
+ Data_Get_Struct(self, Function, fn);
367
+
368
+ return (*fn->info->invoke)(argc, argv, fn->base.memory.address, fn->info);
369
+ }
370
+
371
+ /*
372
+ * call-seq: attach(m, name)
373
+ * @param [Module] m
374
+ * @param [String] name
375
+ * @return [self]
376
+ * Attach a Function to the Module +m+ as +name+.
377
+ */
378
+ static VALUE
379
+ function_attach(VALUE self, VALUE module, VALUE name)
380
+ {
381
+ Function* fn;
382
+ char var[1024];
383
+
384
+ Data_Get_Struct(self, Function, fn);
385
+
386
+ if (fn->info->parameterCount == -1) {
387
+ rb_raise(rb_eRuntimeError, "cannot attach variadic functions");
388
+ return Qnil;
389
+ }
390
+
391
+ if (!rb_obj_is_kind_of(module, rb_cModule)) {
392
+ rb_raise(rb_eRuntimeError, "trying to attach function to non-module");
393
+ return Qnil;
394
+ }
395
+
396
+ if (fn->methodHandle == NULL) {
397
+ fn->methodHandle = rbffi_MethodHandle_Alloc(fn->info, fn->base.memory.address);
398
+ }
399
+
400
+ /*
401
+ * Stash the Function in a module variable so it does not get garbage collected
402
+ */
403
+ snprintf(var, sizeof(var), "@@%s", StringValueCStr(name));
404
+ rb_cv_set(module, var, self);
405
+
406
+ rb_define_singleton_method(module, StringValueCStr(name),
407
+ rbffi_MethodHandle_CodeAddress(fn->methodHandle), -1);
408
+
409
+
410
+ rb_define_method(module, StringValueCStr(name),
411
+ rbffi_MethodHandle_CodeAddress(fn->methodHandle), -1);
412
+
413
+ return self;
414
+ }
415
+
416
+ /*
417
+ * call-seq: autorelease = autorelease
418
+ * @param [Boolean] autorelease
419
+ * @return [self]
420
+ * Set +autorelease+ attribute (See {Pointer}).
421
+ */
422
+ static VALUE
423
+ function_set_autorelease(VALUE self, VALUE autorelease)
424
+ {
425
+ Function* fn;
426
+
427
+ Data_Get_Struct(self, Function, fn);
428
+
429
+ fn->autorelease = RTEST(autorelease);
430
+
431
+ return self;
432
+ }
433
+
434
+ static VALUE
435
+ function_autorelease_p(VALUE self)
436
+ {
437
+ Function* fn;
438
+
439
+ Data_Get_Struct(self, Function, fn);
440
+
441
+ return fn->autorelease ? Qtrue : Qfalse;
442
+ }
443
+
444
+ /*
445
+ * call-seq: free
446
+ * @return [self]
447
+ * Free memory allocated by Function.
448
+ */
449
+ static VALUE
450
+ function_release(VALUE self)
451
+ {
452
+ Function* fn;
453
+
454
+ Data_Get_Struct(self, Function, fn);
455
+
456
+ if (fn->closure == NULL) {
457
+ rb_raise(rb_eRuntimeError, "cannot free function which was not allocated");
458
+ }
459
+
460
+ rbffi_Closure_Free(fn->closure);
461
+ fn->closure = NULL;
462
+
463
+ return self;
464
+ }
465
+
466
+ static void
467
+ callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data)
468
+ {
469
+ struct gvl_callback cb = { 0 };
470
+
471
+ cb.closure = (Closure *) user_data;
472
+ cb.retval = retval;
473
+ cb.parameters = parameters;
474
+ cb.done = false;
475
+ cb.frame = rbffi_frame_current();
476
+
477
+ if (cb.frame != NULL) cb.frame->exc = Qnil;
478
+
479
+ if (rbffi_native_thread_p(cb.frame)) {
480
+ if(rbffi_thread_has_gvl_p(cb.frame)) {
481
+ callback_with_gvl(&cb);
482
+ } else {
483
+ rb_thread_call_with_gvl(callback_with_gvl, &cb);
484
+ }
485
+ #if defined(DEFER_ASYNC_CALLBACK) && !defined(_WIN32)
486
+ } else {
487
+ bool empty = false;
488
+
489
+ pthread_mutex_init(&cb.async_mutex, NULL);
490
+ pthread_cond_init(&cb.async_cond, NULL);
491
+
492
+ /* Now signal the async callback thread */
493
+ pthread_mutex_lock(&async_cb_mutex);
494
+ empty = async_cb_list == NULL;
495
+ cb.next = async_cb_list;
496
+ async_cb_list = &cb;
497
+
498
+ pthread_cond_signal(&async_cb_cond);
499
+ pthread_mutex_unlock(&async_cb_mutex);
500
+
501
+ /* Wait for the thread executing the ruby callback to signal it is done */
502
+ pthread_mutex_lock(&cb.async_mutex);
503
+ while (!cb.done) {
504
+ pthread_cond_wait(&cb.async_cond, &cb.async_mutex);
505
+ }
506
+ pthread_mutex_unlock(&cb.async_mutex);
507
+ pthread_cond_destroy(&cb.async_cond);
508
+ pthread_mutex_destroy(&cb.async_mutex);
509
+
510
+ #elif defined(DEFER_ASYNC_CALLBACK) && defined(_WIN32)
511
+ } else {
512
+ bool empty = false;
513
+
514
+ cb.async_event = CreateEvent(NULL, FALSE, FALSE, NULL);
515
+
516
+ /* Now signal the async callback thread */
517
+ EnterCriticalSection(&async_cb_lock);
518
+ empty = async_cb_list == NULL;
519
+ cb.next = async_cb_list;
520
+ async_cb_list = &cb;
521
+ LeaveCriticalSection(&async_cb_lock);
522
+
523
+ SetEvent(async_cb_cond);
524
+
525
+ /* Wait for the thread executing the ruby callback to signal it is done */
526
+ WaitForSingleObject(cb.async_event, INFINITE);
527
+ CloseHandle(cb.async_event);
528
+ #endif
529
+ }
530
+ }
531
+
532
+ #if defined(DEFER_ASYNC_CALLBACK)
533
+ struct async_wait {
534
+ void* cb;
535
+ bool stop;
536
+ };
537
+
538
+ static void * async_cb_wait(void *);
539
+ static void async_cb_stop(void *);
540
+
541
+ static VALUE
542
+ async_cb_event(void* unused)
543
+ {
544
+ struct async_wait w = { 0 };
545
+
546
+ w.stop = false;
547
+ while (!w.stop) {
548
+ rb_thread_call_without_gvl(async_cb_wait, &w, async_cb_stop, &w);
549
+ if (w.cb != NULL) {
550
+ /* Start up a new ruby thread to run the ruby callback */
551
+ rb_thread_create(async_cb_call, w.cb);
552
+ }
553
+ }
554
+
555
+ return Qnil;
556
+ }
557
+
558
+ #ifdef _WIN32
559
+ static void *
560
+ async_cb_wait(void *data)
561
+ {
562
+ struct async_wait* w = (struct async_wait *) data;
563
+
564
+ w->cb = NULL;
565
+
566
+ EnterCriticalSection(&async_cb_lock);
567
+
568
+ while (!w->stop && async_cb_list == NULL) {
569
+ LeaveCriticalSection(&async_cb_lock);
570
+ WaitForSingleObject(async_cb_cond, INFINITE);
571
+ EnterCriticalSection(&async_cb_lock);
572
+ }
573
+
574
+ if (async_cb_list != NULL) {
575
+ w->cb = async_cb_list;
576
+ async_cb_list = async_cb_list->next;
577
+ }
578
+
579
+ LeaveCriticalSection(&async_cb_lock);
580
+
581
+ return NULL;
582
+ }
583
+
584
+ static void
585
+ async_cb_stop(void *data)
586
+ {
587
+ struct async_wait* w = (struct async_wait *) data;
588
+
589
+ EnterCriticalSection(&async_cb_lock);
590
+ w->stop = true;
591
+ LeaveCriticalSection(&async_cb_lock);
592
+ SetEvent(async_cb_cond);
593
+ }
594
+
595
+ #else
596
+ static void *
597
+ async_cb_wait(void *data)
598
+ {
599
+ struct async_wait* w = (struct async_wait *) data;
600
+
601
+ w->cb = NULL;
602
+
603
+ pthread_mutex_lock(&async_cb_mutex);
604
+
605
+ while (!w->stop && async_cb_list == NULL) {
606
+ pthread_cond_wait(&async_cb_cond, &async_cb_mutex);
607
+ }
608
+
609
+ if (async_cb_list != NULL) {
610
+ w->cb = async_cb_list;
611
+ async_cb_list = async_cb_list->next;
612
+ }
613
+
614
+ pthread_mutex_unlock(&async_cb_mutex);
615
+
616
+ return NULL;
617
+ }
618
+
619
+ static void
620
+ async_cb_stop(void *data)
621
+ {
622
+ struct async_wait* w = (struct async_wait *) data;
623
+
624
+ pthread_mutex_lock(&async_cb_mutex);
625
+ w->stop = true;
626
+ pthread_cond_signal(&async_cb_cond);
627
+ pthread_mutex_unlock(&async_cb_mutex);
628
+ }
629
+ #endif
630
+
631
+ static VALUE
632
+ async_cb_call(void *data)
633
+ {
634
+ struct gvl_callback* cb = (struct gvl_callback *) data;
635
+
636
+ callback_with_gvl(data);
637
+
638
+ /* Signal the original native thread that the ruby code has completed */
639
+ #ifdef _WIN32
640
+ SetEvent(cb->async_event);
641
+ #else
642
+ pthread_mutex_lock(&cb->async_mutex);
643
+ cb->done = true;
644
+ pthread_cond_signal(&cb->async_cond);
645
+ pthread_mutex_unlock(&cb->async_mutex);
646
+ #endif
647
+
648
+ return Qnil;
649
+ }
650
+
651
+ #endif
652
+
653
+ static void *
654
+ callback_with_gvl(void* data)
655
+ {
656
+ rb_rescue2(invoke_callback, (VALUE) data, save_callback_exception, (VALUE) data, rb_eException, (VALUE) 0);
657
+ return NULL;
658
+ }
659
+
660
+ static VALUE
661
+ invoke_callback(void* data)
662
+ {
663
+ struct gvl_callback* cb = (struct gvl_callback *) data;
664
+
665
+ Function* fn = (Function *) cb->closure->info;
666
+ FunctionType *cbInfo = fn->info;
667
+ Type* returnType = cbInfo->returnType;
668
+ void* retval = cb->retval;
669
+ void** parameters = cb->parameters;
670
+ VALUE* rbParams;
671
+ VALUE rbReturnType = cbInfo->rbReturnType;
672
+ VALUE rbReturnValue;
673
+ int i;
674
+
675
+ rbParams = ALLOCA_N(VALUE, cbInfo->parameterCount);
676
+ for (i = 0; i < cbInfo->parameterCount; ++i) {
677
+ VALUE param;
678
+ Type* paramType = cbInfo->parameterTypes[i];
679
+ VALUE rbParamType = rb_ary_entry(cbInfo->rbParameterTypes, i);
680
+
681
+ if (unlikely(paramType->nativeType == NATIVE_MAPPED)) {
682
+ rbParamType = ((MappedType *) paramType)->rbType;
683
+ paramType = ((MappedType *) paramType)->type;
684
+ }
685
+
686
+ switch (paramType->nativeType) {
687
+ case NATIVE_INT8:
688
+ param = INT2NUM(*(int8_t *) parameters[i]);
689
+ break;
690
+ case NATIVE_UINT8:
691
+ param = UINT2NUM(*(uint8_t *) parameters[i]);
692
+ break;
693
+ case NATIVE_INT16:
694
+ param = INT2NUM(*(int16_t *) parameters[i]);
695
+ break;
696
+ case NATIVE_UINT16:
697
+ param = UINT2NUM(*(uint16_t *) parameters[i]);
698
+ break;
699
+ case NATIVE_INT32:
700
+ param = INT2NUM(*(int32_t *) parameters[i]);
701
+ break;
702
+ case NATIVE_UINT32:
703
+ param = UINT2NUM(*(uint32_t *) parameters[i]);
704
+ break;
705
+ case NATIVE_INT64:
706
+ param = LL2NUM(*(int64_t *) parameters[i]);
707
+ break;
708
+ case NATIVE_UINT64:
709
+ param = ULL2NUM(*(uint64_t *) parameters[i]);
710
+ break;
711
+ case NATIVE_LONG:
712
+ param = LONG2NUM(*(long *) parameters[i]);
713
+ break;
714
+ case NATIVE_ULONG:
715
+ param = ULONG2NUM(*(unsigned long *) parameters[i]);
716
+ break;
717
+ case NATIVE_FLOAT32:
718
+ param = rb_float_new(*(float *) parameters[i]);
719
+ break;
720
+ case NATIVE_FLOAT64:
721
+ param = rb_float_new(*(double *) parameters[i]);
722
+ break;
723
+ case NATIVE_LONGDOUBLE:
724
+ param = rbffi_longdouble_new(*(long double *) parameters[i]);
725
+ break;
726
+ case NATIVE_STRING:
727
+ param = (*(void **) parameters[i] != NULL) ? rb_tainted_str_new2(*(char **) parameters[i]) : Qnil;
728
+ break;
729
+ case NATIVE_POINTER:
730
+ param = rbffi_Pointer_NewInstance(*(void **) parameters[i]);
731
+ break;
732
+ case NATIVE_BOOL:
733
+ param = (*(uint8_t *) parameters[i]) ? Qtrue : Qfalse;
734
+ break;
735
+
736
+ case NATIVE_FUNCTION:
737
+ case NATIVE_CALLBACK:
738
+ case NATIVE_STRUCT:
739
+ param = rbffi_NativeValue_ToRuby(paramType, rbParamType, parameters[i]);
740
+ break;
741
+
742
+ default:
743
+ param = Qnil;
744
+ break;
745
+ }
746
+
747
+ /* Convert the native value into a custom ruby value */
748
+ if (unlikely(cbInfo->parameterTypes[i]->nativeType == NATIVE_MAPPED)) {
749
+ VALUE values[] = { param, Qnil };
750
+ param = rb_funcall2(((MappedType *) cbInfo->parameterTypes[i])->rbConverter, id_from_native, 2, values);
751
+ }
752
+
753
+ rbParams[i] = param;
754
+ }
755
+
756
+ rbReturnValue = rb_funcall2(fn->rbProc, id_call, cbInfo->parameterCount, rbParams);
757
+
758
+ if (unlikely(returnType->nativeType == NATIVE_MAPPED)) {
759
+ VALUE values[] = { rbReturnValue, Qnil };
760
+ rbReturnValue = rb_funcall2(((MappedType *) returnType)->rbConverter, id_to_native, 2, values);
761
+ rbReturnType = ((MappedType *) returnType)->rbType;
762
+ returnType = ((MappedType* ) returnType)->type;
763
+ }
764
+
765
+ if (rbReturnValue == Qnil || TYPE(rbReturnValue) == T_NIL) {
766
+ memset(retval, 0, returnType->ffiType->size);
767
+ } else switch (returnType->nativeType) {
768
+ case NATIVE_INT8:
769
+ case NATIVE_INT16:
770
+ case NATIVE_INT32:
771
+ *((ffi_sarg *) retval) = NUM2INT(rbReturnValue);
772
+ break;
773
+ case NATIVE_UINT8:
774
+ case NATIVE_UINT16:
775
+ case NATIVE_UINT32:
776
+ *((ffi_arg *) retval) = NUM2UINT(rbReturnValue);
777
+ break;
778
+ case NATIVE_INT64:
779
+ *((int64_t *) retval) = NUM2LL(rbReturnValue);
780
+ break;
781
+ case NATIVE_UINT64:
782
+ *((uint64_t *) retval) = NUM2ULL(rbReturnValue);
783
+ break;
784
+ case NATIVE_LONG:
785
+ *((ffi_sarg *) retval) = NUM2LONG(rbReturnValue);
786
+ break;
787
+ case NATIVE_ULONG:
788
+ *((ffi_arg *) retval) = NUM2ULONG(rbReturnValue);
789
+ break;
790
+ case NATIVE_FLOAT32:
791
+ *((float *) retval) = (float) NUM2DBL(rbReturnValue);
792
+ break;
793
+ case NATIVE_FLOAT64:
794
+ *((double *) retval) = NUM2DBL(rbReturnValue);
795
+ break;
796
+ case NATIVE_POINTER:
797
+ if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_PointerClass)) {
798
+ *((void **) retval) = ((AbstractMemory *) DATA_PTR(rbReturnValue))->address;
799
+ } else {
800
+ /* Default to returning NULL if not a value pointer object. handles nil case as well */
801
+ *((void **) retval) = NULL;
802
+ }
803
+ break;
804
+
805
+ case NATIVE_BOOL:
806
+ *((ffi_arg *) retval) = rbReturnValue == Qtrue;
807
+ break;
808
+
809
+ case NATIVE_FUNCTION:
810
+ case NATIVE_CALLBACK:
811
+ if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_PointerClass)) {
812
+
813
+ *((void **) retval) = ((AbstractMemory *) DATA_PTR(rbReturnValue))->address;
814
+
815
+ } else if (rb_obj_is_kind_of(rbReturnValue, rb_cProc) || rb_respond_to(rbReturnValue, id_call)) {
816
+ VALUE function;
817
+
818
+ function = rbffi_Function_ForProc(rbReturnType, rbReturnValue);
819
+
820
+ *((void **) retval) = ((AbstractMemory *) DATA_PTR(function))->address;
821
+ } else {
822
+ *((void **) retval) = NULL;
823
+ }
824
+ break;
825
+
826
+ case NATIVE_STRUCT:
827
+ if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_StructClass)) {
828
+ AbstractMemory* memory = ((Struct *) DATA_PTR(rbReturnValue))->pointer;
829
+
830
+ if (memory->address != NULL) {
831
+ memcpy(retval, memory->address, returnType->ffiType->size);
832
+
833
+ } else {
834
+ memset(retval, 0, returnType->ffiType->size);
835
+ }
836
+
837
+ } else {
838
+ memset(retval, 0, returnType->ffiType->size);
839
+ }
840
+ break;
841
+
842
+ default:
843
+ *((ffi_arg *) retval) = 0;
844
+ break;
845
+ }
846
+
847
+ return Qnil;
848
+ }
849
+
850
+ static VALUE
851
+ save_callback_exception(void* data, VALUE exc)
852
+ {
853
+ struct gvl_callback* cb = (struct gvl_callback *) data;
854
+
855
+ memset(cb->retval, 0, ((Function *) cb->closure->info)->info->returnType->ffiType->size);
856
+ if (cb->frame != NULL) cb->frame->exc = exc;
857
+
858
+ return Qnil;
859
+ }
860
+
861
+ static bool
862
+ callback_prep(void* ctx, void* code, Closure* closure, char* errmsg, size_t errmsgsize)
863
+ {
864
+ FunctionType* fnInfo = (FunctionType *) ctx;
865
+ ffi_status ffiStatus;
866
+
867
+ ffiStatus = ffi_prep_closure(code, &fnInfo->ffi_cif, callback_invoke, closure);
868
+ if (ffiStatus != FFI_OK) {
869
+ snprintf(errmsg, errmsgsize, "ffi_prep_closure failed. status=%#x", ffiStatus);
870
+ return false;
871
+ }
872
+
873
+ return true;
874
+ }
875
+
876
+ void
877
+ rbffi_Function_Init(VALUE moduleFFI)
878
+ {
879
+ rbffi_FunctionInfo_Init(moduleFFI);
880
+ /*
881
+ * Document-class: FFI::Function < FFI::Pointer
882
+ */
883
+ rbffi_FunctionClass = rb_define_class_under(moduleFFI, "Function", rbffi_PointerClass);
884
+
885
+ rb_global_variable(&rbffi_FunctionClass);
886
+ rb_define_alloc_func(rbffi_FunctionClass, function_allocate);
887
+
888
+ rb_define_method(rbffi_FunctionClass, "initialize", function_initialize, -1);
889
+ rb_define_method(rbffi_FunctionClass, "initialize_copy", function_initialize_copy, 1);
890
+ rb_define_method(rbffi_FunctionClass, "call", function_call, -1);
891
+ rb_define_method(rbffi_FunctionClass, "attach", function_attach, 2);
892
+ rb_define_method(rbffi_FunctionClass, "free", function_release, 0);
893
+ rb_define_method(rbffi_FunctionClass, "autorelease=", function_set_autorelease, 1);
894
+ /*
895
+ * call-seq: autorelease
896
+ * @return [Boolean]
897
+ * Get +autorelease+ attribute.
898
+ * Synonymous for {#autorelease?}.
899
+ */
900
+ rb_define_method(rbffi_FunctionClass, "autorelease", function_autorelease_p, 0);
901
+ /*
902
+ * call-seq: autorelease?
903
+ * @return [Boolean] +autorelease+ attribute
904
+ * Get +autorelease+ attribute.
905
+ */
906
+ rb_define_method(rbffi_FunctionClass, "autorelease?", function_autorelease_p, 0);
907
+
908
+ id_call = rb_intern("call");
909
+ id_cbtable = rb_intern("@__ffi_callback_table__");
910
+ id_cb_ref = rb_intern("@__ffi_callback__");
911
+ id_to_native = rb_intern("to_native");
912
+ id_from_native = rb_intern("from_native");
913
+ #if defined(_WIN32)
914
+ InitializeCriticalSection(&async_cb_lock);
915
+ async_cb_cond = CreateEvent(NULL, FALSE, FALSE, NULL);
916
+ #endif
917
+ }