ffi 1.13.0 → 1.15.5

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 (122) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +127 -0
  3. data/Gemfile +1 -4
  4. data/README.md +14 -2
  5. data/Rakefile +43 -29
  6. data/ext/ffi_c/AbstractMemory.c +24 -25
  7. data/ext/ffi_c/Buffer.c +2 -7
  8. data/ext/ffi_c/Call.c +3 -9
  9. data/ext/ffi_c/ClosurePool.c +64 -11
  10. data/ext/ffi_c/ClosurePool.h +3 -1
  11. data/ext/ffi_c/DynamicLibrary.c +1 -6
  12. data/ext/ffi_c/Function.c +31 -16
  13. data/ext/ffi_c/Function.h +0 -4
  14. data/ext/ffi_c/FunctionInfo.c +2 -6
  15. data/ext/ffi_c/LastError.c +2 -6
  16. data/ext/ffi_c/MemoryPointer.c +2 -7
  17. data/ext/ffi_c/MemoryPointer.h +0 -4
  18. data/ext/ffi_c/MethodHandle.c +4 -8
  19. data/ext/ffi_c/Platform.c +4 -9
  20. data/ext/ffi_c/Pointer.c +24 -25
  21. data/ext/ffi_c/Pointer.h +0 -4
  22. data/ext/ffi_c/Struct.c +3 -6
  23. data/ext/ffi_c/StructByValue.c +2 -7
  24. data/ext/ffi_c/StructLayout.c +2 -6
  25. data/ext/ffi_c/Thread.c +0 -5
  26. data/ext/ffi_c/Thread.h +1 -6
  27. data/ext/ffi_c/Type.c +1 -1
  28. data/ext/ffi_c/Types.c +6 -7
  29. data/ext/ffi_c/Types.h +3 -4
  30. data/ext/ffi_c/Variadic.c +14 -9
  31. data/ext/ffi_c/extconf.rb +25 -10
  32. data/ext/ffi_c/libffi/.travis/bfin-sim.exp +1 -1
  33. data/ext/ffi_c/libffi/.travis/m32r-sim.exp +1 -1
  34. data/ext/ffi_c/libffi/.travis/moxie-sim.exp +1 -1
  35. data/ext/ffi_c/libffi/.travis/or1k-sim.exp +1 -1
  36. data/ext/ffi_c/libffi/.travis/powerpc-eabisim.exp +1 -1
  37. data/ext/ffi_c/libffi/.travis/wine-sim.exp +1 -1
  38. data/ext/ffi_c/libffi/Makefile.am +48 -58
  39. data/ext/ffi_c/libffi/Makefile.in +420 -156
  40. data/ext/ffi_c/libffi/README.md +4 -0
  41. data/ext/ffi_c/libffi/config.guess +552 -331
  42. data/ext/ffi_c/libffi/config.sub +1321 -1306
  43. data/ext/ffi_c/libffi/configure +158 -96
  44. data/ext/ffi_c/libffi/configure.ac +6 -1
  45. data/ext/ffi_c/libffi/configure.host +32 -20
  46. data/ext/ffi_c/libffi/doc/Makefile.in +8 -5
  47. data/ext/ffi_c/libffi/fficonfig.h.in +6 -0
  48. data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +1 -1
  49. data/ext/ffi_c/libffi/include/Makefile.in +8 -5
  50. data/ext/ffi_c/libffi/install-sh +23 -13
  51. data/ext/ffi_c/libffi/ltmain.sh +156 -61
  52. data/ext/ffi_c/libffi/man/Makefile.in +8 -5
  53. data/ext/ffi_c/libffi/missing +8 -8
  54. data/ext/ffi_c/libffi/msvcc.sh +11 -11
  55. data/ext/ffi_c/libffi/src/aarch64/ffi.c +45 -35
  56. data/ext/ffi_c/libffi/src/aarch64/ffitarget.h +10 -5
  57. data/ext/ffi_c/libffi/src/aarch64/internal.h +1 -0
  58. data/ext/ffi_c/libffi/src/aarch64/sysv.S +1 -1
  59. data/ext/ffi_c/libffi/src/aarch64/win64_armasm.S +1 -1
  60. data/ext/ffi_c/libffi/src/arm/ffi.c +22 -0
  61. data/ext/ffi_c/libffi/src/arm/sysv.S +4 -4
  62. data/ext/ffi_c/libffi/src/closures.c +23 -6
  63. data/ext/ffi_c/libffi/src/csky/ffi.c +395 -0
  64. data/ext/ffi_c/libffi/src/csky/ffitarget.h +63 -0
  65. data/ext/ffi_c/libffi/src/csky/sysv.S +371 -0
  66. data/ext/ffi_c/libffi/src/dlmalloc.c +1 -1
  67. data/ext/ffi_c/libffi/src/kvx/asm.h +5 -0
  68. data/ext/ffi_c/libffi/src/kvx/ffi.c +273 -0
  69. data/ext/ffi_c/libffi/src/kvx/ffitarget.h +75 -0
  70. data/ext/ffi_c/libffi/src/kvx/sysv.S +127 -0
  71. data/ext/ffi_c/libffi/src/mips/ffi.c +5 -1
  72. data/ext/ffi_c/libffi/src/mips/ffitarget.h +1 -1
  73. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +13 -1
  74. data/ext/ffi_c/libffi/src/powerpc/ffi_powerpc.h +1 -1
  75. data/ext/ffi_c/libffi/src/powerpc/linux64.S +8 -0
  76. data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +13 -1
  77. data/ext/ffi_c/libffi/src/prep_cif.c +1 -1
  78. data/ext/ffi_c/libffi/src/x86/ffi.c +8 -2
  79. data/ext/ffi_c/libffi/src/x86/ffi64.c +7 -0
  80. data/ext/ffi_c/libffi/src/x86/ffiw64.c +5 -0
  81. data/ext/ffi_c/libffi/src/x86/sysv.S +2 -2
  82. data/ext/ffi_c/libffi/src/x86/unix64.S +1 -2
  83. data/ext/ffi_c/libffi/src/x86/win64.S +3 -2
  84. data/ext/ffi_c/libffi/src/x86/win64_intel.S +3 -2
  85. data/ext/ffi_c/libffi/testsuite/Makefile.in +9 -6
  86. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +22 -2
  87. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-call.c +4 -4
  88. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-callback.c +2 -2
  89. data/ext/ffi_c/libffi/testsuite/libffi.closures/huge_struct.c +2 -0
  90. data/ffi.gemspec +1 -2
  91. data/lib/ffi/abstract_memory.rb +44 -0
  92. data/lib/ffi/autopointer.rb +1 -1
  93. data/lib/ffi/ffi.rb +1 -0
  94. data/lib/ffi/io.rb +3 -3
  95. data/lib/ffi/library.rb +3 -3
  96. data/lib/ffi/managedstruct.rb +2 -2
  97. data/lib/ffi/platform/aarch64-darwin/types.conf +130 -0
  98. data/lib/ffi/platform/aarch64-freebsd/types.conf +2 -2
  99. data/lib/ffi/platform/aarch64-freebsd12/types.conf +113 -60
  100. data/lib/ffi/platform/aarch64-openbsd/types.conf +134 -0
  101. data/lib/ffi/platform/powerpc64le-linux/types.conf +100 -0
  102. data/lib/ffi/platform/riscv64-linux/types.conf +104 -0
  103. data/lib/ffi/platform/x86_64-dragonflybsd/types.conf +4 -22
  104. data/lib/ffi/platform/x86_64-haiku/types.conf +117 -0
  105. data/lib/ffi/platform/x86_64-msys/types.conf +119 -0
  106. data/lib/ffi/platform.rb +17 -7
  107. data/lib/ffi/pointer.rb +2 -2
  108. data/lib/ffi/tools/const_generator.rb +6 -4
  109. data/lib/ffi/tools/struct_generator.rb +2 -1
  110. data/lib/ffi/variadic.rb +1 -10
  111. data/lib/ffi/version.rb +1 -1
  112. data/lib/ffi.rb +3 -4
  113. data/rakelib/ffi_gem_helper.rb +65 -0
  114. metadata +21 -28
  115. data/.appveyor.yml +0 -30
  116. data/.github/workflows/ci.yml +0 -64
  117. data/.gitignore +0 -25
  118. data/.gitmodules +0 -4
  119. data/.travis.yml +0 -58
  120. data/.yardopts +0 -5
  121. data/ext/ffi_c/win32/stdbool.h +0 -8
  122. data/ext/ffi_c/win32/stdint.h +0 -201
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e96bb396dbe6fdc7c8a68b4328bb9142e50a9c934a94aa79837fb26bfb195a97
4
- data.tar.gz: efb9edb9a7e79911a1860d7ceb60b842840c2f469f248b7795c38cede57fddbe
3
+ metadata.gz: d6f15f4e38ad34949be88341216eed2ea132c4e5763d333c20c240491b033ff6
4
+ data.tar.gz: deefb7285ccae7d7248ee2697709e859d4c0017e3aab7e183ce7fc2a824bd395
5
5
  SHA512:
6
- metadata.gz: c1f23d12fdea63b629ca8a09fd39b6b60aae31a5b25b54e15c8519a9b1e71bf8ca93d01c34b4a424d68fae8d9a6b22e171c45eb2e357ccdd6df9eaf7e7dd60cd
7
- data.tar.gz: 0c47701aec04d869c1c62e71b88dbf5b33fbef3e1cf49819301e94e124817783db47e8e4427f3782b44f0516009e0e2def336423d594283f1d9b870bc4941765
6
+ metadata.gz: 7b2c32adb0af3689632c9b6113389245dba13d5f9e622efd2f322b0226933185ae0fbc128cb33c278dd2ef7fddda106fe8158904e95d1fa7d53b14ff72722ff6
7
+ data.tar.gz: 60ca6ad01c3d977b8b6efe0329683d4105cae8147848c9fcb0cabe643f5957e7a6ab6a06716e1f579ada6e0c3795f4fd4c0f16bda783342310a305423a5d7a60
data/CHANGELOG.md CHANGED
@@ -1,3 +1,130 @@
1
+ 1.15.5 / 2022-01-10
2
+ -------------------
3
+
4
+ Fixed:
5
+ * Fix long double argument or return values on 32bit i686. #849
6
+ * FFI::ConstGenerator: avoid usage of the same binary file simultaneously. #929
7
+
8
+ Added:
9
+ * Add Windows fat binary gem for Ruby-3.1
10
+
11
+ Removed:
12
+ * Remove Windows fat binary gem for Ruby < 2.4
13
+
14
+
15
+ 1.15.4 / 2021-09-01
16
+ -------------------
17
+
18
+ Fixed:
19
+ * Fix build for uClibc. #913
20
+ * Correct module lookup when including `ffi-module` gem. #912
21
+
22
+ Changed:
23
+ * Use ruby code of the ffi gem in JRuby-9.2.20+. #915
24
+
25
+
26
+ 1.15.3 / 2021-06-16
27
+ -------------------
28
+
29
+ Fixed:
30
+ * Fix temporary packaging issue with libffi. #904
31
+
32
+
33
+ 1.15.2 / 2021-06-16
34
+ -------------------
35
+
36
+ Added:
37
+ * Add support for Windows MINGW-UCRT build. #903
38
+ * Add `/opt/homebrew/lib/` to fallback search paths to improve homebrew support. #880 #882
39
+
40
+ Changed:
41
+ * Regenerate `types.conf` for FreeBSD12 aarch64. #902
42
+
43
+
44
+ 1.15.1 / 2021-05-22
45
+ -------------------
46
+
47
+ Fixed:
48
+ * Append -pthread to linker options. #893
49
+ * Use arm or aarch64 to identify Apple ARM CPU arch. #899
50
+ * Allow overriding `gcc` with the `CC` env var in `const_generator.rb` and `struct_generator.rb`. #897
51
+
52
+
53
+ 1.15.0 / 2021-03-05
54
+ -------------------
55
+
56
+ Fixed:
57
+ * Fix MSVC build
58
+ * Fix async callbacks in conjunction with fork(). #884
59
+
60
+ Added:
61
+ * Allow to pass callbacks in varargs. #885
62
+ * Name the threads for FFI callback dispatcher and async thread calls for easier debugging. #883
63
+ The name can be retrieved by Thread.name and is shown by Thread.list.inspect etc.
64
+ Even gdb shows the thread name on supported operating systems.
65
+ * Add types.conf for powerpc64le-linux
66
+ * Add types.conf for riscv64-linux
67
+ * More release automation of ffi gems
68
+
69
+ Changed:
70
+ * Switch from rubygems-tasks to bundler/gem_helper
71
+
72
+ Removed:
73
+ * Remove unused VariadicInvoker#init
74
+
75
+
76
+ 1.14.2 / 2020-12-21
77
+ -------------------
78
+
79
+ Fixed:
80
+ * Fix builtin libffi on newer Ubuntu caused by an outdated Makefile.in . #863
81
+
82
+
83
+ 1.14.1 / 2020-12-19
84
+ -------------------
85
+
86
+ Changed:
87
+ * Revert changes to FFI::Pointer#write_string made in ffi-1.14.0.
88
+ It breaks compatibilty in a way that can cause hard to find errors. #857
89
+
90
+
91
+ 1.14.0 / 2020-12-18
92
+ -------------------
93
+
94
+ Added:
95
+ * Add types.conf for x86_64-msys, x86_64-haiku, aarch64-openbsd and aarch64-darwin (alias arm64-darwin)
96
+ * Add method AbstractMemory#size_limit? . #829
97
+ * Add new extconf option --enable-libffi-alloc which is enabled per default on Apple M1 (arm64-darwin).
98
+
99
+ Changed:
100
+ * Do NULL pointer check only when array length > 0 . #305
101
+ * Raise an error on an unknown order argument. #830
102
+ * Change FFI::Pointer#write_string to terminate with a NUL byte like other string methods. #805
103
+ * Update bundled libffi to latest master.
104
+
105
+ Removed:
106
+ * Remove win32/stdint.h and stdbool.h because of copyright issue. #693
107
+
108
+ Fixed:
109
+ * Fix possible UTF-8 load error in loader script interpretation. #792
110
+ * Fix segfault on non-array argument to #write_array_of_*
111
+ * Fix memory leak in MethodHandle . #815
112
+ * Fix possible segfault in combination with fiddle or other libffi using gems . #835
113
+ * Fix possibility to use ffi ruby gem with JRuby-9.3 . #763
114
+ * Fix a GC issue, when a callback Proc is used on more than 2 callback signatures. #820
115
+
116
+
117
+ 1.13.1 / 2020-06-09
118
+ -------------------
119
+
120
+ Changed:
121
+ * Revert use of `ucrtbase.dll` as default C library on Windows-MINGW.
122
+ `ucrtbase.dll` is still used on MSWIN target. #790
123
+ * Test for `ffi_prep_closure_loc()` to make sure we can use this function.
124
+ This fixes incorrect use of system libffi on MacOS Mojave (10.14). #787
125
+ * Update types.conf on x86_64-dragonflybsd
126
+
127
+
1
128
  1.13.0 / 2020-06-01
2
129
  -------------------
3
130
 
data/Gemfile CHANGED
@@ -5,10 +5,7 @@ group :development do
5
5
  gem 'rake-compiler', '~> 1.0.3'
6
6
  gem 'rake-compiler-dock', '~> 1.0'
7
7
  gem 'rspec', '~> 3.0'
8
- # irb is a dependency of rubygems-tasks 0.2.5.
9
- # irb versions > 1.1.1 depend on reline,
10
- # which sometimes causes 'bundle install' to fail on Ruby <= 2.4: https://github.com/rubygems/rubygems/issues/3463
11
- gem 'rubygems-tasks', '>= 0.2', '< 0.2.5', :require => 'rubygems/tasks'
8
+ gem 'bundler', '>= 1.16', '< 3'
12
9
  end
13
10
 
14
11
  group :doc do
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Ruby-FFI https://github.com/ffi/ffi/wiki [![Build Status](https://travis-ci.org/ffi/ffi.svg?branch=master)](https://travis-ci.org/ffi/ffi) [![Build status Windows](https://ci.appveyor.com/api/projects/status/r8wxn1sd4s794gg1/branch/master?svg=true)](https://ci.appveyor.com/project/larskanis/ffi-aofqa/branch/master)
1
+ # Ruby-FFI https://github.com/ffi/ffi/wiki [![Build Status](https://travis-ci.com/ffi/ffi.svg?branch=master)](https://travis-ci.com/ffi/ffi) [![Build status Windows](https://ci.appveyor.com/api/projects/status/r8wxn1sd4s794gg1/branch/master?svg=true)](https://ci.appveyor.com/project/larskanis/ffi-aofqa/branch/master)
2
2
 
3
3
  ## Description
4
4
 
@@ -62,14 +62,26 @@ On JRuby and TruffleRuby, there are no requirements to install the FFI gem, and
62
62
  From rubygems:
63
63
 
64
64
  [sudo] gem install ffi
65
+
66
+ From a Gemfile using git or GitHub
67
+
68
+ gem 'ffi', github: 'ffi/ffi', submodules: true
65
69
 
66
70
  or from the git repository on github:
67
71
 
68
72
  git clone git://github.com/ffi/ffi.git
69
- git submodule update --init --recursive
70
73
  cd ffi
74
+ git submodule update --init --recursive
75
+ bundle install
71
76
  rake install
72
77
 
78
+ ### Install options:
79
+
80
+ * `--enable-system-libffi` : Force usage of system libffi
81
+ * `--disable-system-libffi` : Force usage of builtin libffi
82
+ * `--enable-libffi-alloc` : Force closure allocation by libffi
83
+ * `--disable-libffi-alloc` : Force closure allocation by builtin method
84
+
73
85
  ## License
74
86
 
75
87
  The ffi library is covered by the BSD license, also see the LICENSE file.
data/Rakefile CHANGED
@@ -1,27 +1,24 @@
1
- require 'rubygems/tasks'
2
1
  require 'rbconfig'
3
- require 'rake/clean'
4
- require_relative "lib/ffi/version"
5
-
6
2
  require 'date'
7
3
  require 'fileutils'
8
4
  require 'rbconfig'
9
5
  require 'rspec/core/rake_task'
10
6
  require 'rubygems/package_task'
7
+ require 'rake/extensiontask'
8
+ require_relative "lib/ffi/version"
9
+ require_relative "rakelib/ffi_gem_helper"
11
10
 
12
11
  BUILD_DIR = "build"
13
12
  BUILD_EXT_DIR = File.join(BUILD_DIR, "#{RbConfig::CONFIG['arch']}", 'ffi_c', RUBY_VERSION)
14
13
 
15
- def gem_spec
16
- @gem_spec ||= Gem::Specification.load('ffi.gemspec')
17
- end
14
+ gem_spec = Bundler.load_gemspec('ffi.gemspec')
18
15
 
19
16
  RSpec::Core::RakeTask.new(:spec => :compile) do |config|
20
17
  config.rspec_opts = YAML.load_file 'spec/spec.opts'
21
18
  end
22
19
 
23
20
  desc "Build all packages"
24
- task :package => %w[ gem:java gem:windows ]
21
+ task :package => %w[ gem:java gem:native ]
25
22
 
26
23
  CLOBBER.include 'lib/ffi/types.conf'
27
24
  CLOBBER.include 'pkg'
@@ -37,6 +34,13 @@ CLEAN.include "pkg/ffi-*-{mingw32,java}"
37
34
  CLEAN.include 'lib/1.*'
38
35
  CLEAN.include 'lib/2.*'
39
36
 
37
+ # clean all shipped files, that are not in git
38
+ CLEAN.include(
39
+ gem_spec.files -
40
+ `git --git-dir ext/ffi_c/libffi/.git ls-files -z`.split("\x0").map { |f| File.join("ext/ffi_c/libffi", f) } -
41
+ `git ls-files -z`.split("\x0")
42
+ )
43
+
40
44
  task :distclean => :clobber
41
45
 
42
46
  desc "Test the extension"
@@ -80,6 +84,10 @@ end
80
84
 
81
85
  task 'gem:java' => 'java:gem'
82
86
 
87
+ FfiGemHelper.install_tasks
88
+ # Register windows gems to be pushed to rubygems.org
89
+ Bundler::GemHelper.instance.cross_platforms = %w[x86-mingw32 x64-mingw-ucrt x64-mingw32]
90
+
83
91
  if RUBY_ENGINE == 'ruby' || RUBY_ENGINE == 'rbx'
84
92
  require 'rake/extensiontask'
85
93
  Rake::ExtensionTask.new('ffi_c', gem_spec) do |ext|
@@ -87,21 +95,11 @@ if RUBY_ENGINE == 'ruby' || RUBY_ENGINE == 'rbx'
87
95
  # ext.lib_dir = BUILD_DIR # put binaries into this folder.
88
96
  ext.tmp_dir = BUILD_DIR # temporary folder used during compilation.
89
97
  ext.cross_compile = true # enable cross compilation (requires cross compile toolchain)
90
- ext.cross_platform = %w[i386-mingw32 x64-mingw32] # forces the Windows platform instead of the default one
98
+ ext.cross_platform = Bundler::GemHelper.instance.cross_platforms
91
99
  ext.cross_compiling do |spec|
92
100
  spec.files.reject! { |path| File.fnmatch?('ext/*', path) }
93
101
  end
94
- end
95
102
 
96
- # To reduce the gem file size strip mingw32 dlls before packaging
97
- ENV['RUBY_CC_VERSION'].to_s.split(':').each do |ruby_version|
98
- task "build/i386-mingw32/stage/lib/#{ruby_version[/^\d+\.\d+/]}/ffi_c.so" do |t|
99
- sh "i686-w64-mingw32-strip -S build/i386-mingw32/stage/lib/#{ruby_version[/^\d+\.\d+/]}/ffi_c.so"
100
- end
101
-
102
- task "build/x64-mingw32/stage/lib/#{ruby_version[/^\d+\.\d+/]}/ffi_c.so" do |t|
103
- sh "x86_64-w64-mingw32-strip -S build/x64-mingw32/stage/lib/#{ruby_version[/^\d+\.\d+/]}/ffi_c.so"
104
- end
105
103
  end
106
104
  else
107
105
  task :compile do
@@ -109,11 +107,26 @@ else
109
107
  end
110
108
  end
111
109
 
112
- desc "build a windows gem without all the ceremony"
113
- task "gem:windows" do
114
- require "rake_compiler_dock"
115
- sh "bundle package"
116
- RakeCompilerDock.sh "sudo apt-get update && sudo apt-get install -y libltdl-dev && bundle --local && rake cross native gem MAKE='nice make -j`nproc`' RUBY_CC_VERSION=${RUBY_CC_VERSION/:2.2.2/}"
110
+
111
+ namespace "gem" do
112
+ task 'prepare' do
113
+ require 'rake_compiler_dock'
114
+ sh "bundle package --all"
115
+ end
116
+
117
+ Bundler::GemHelper.instance.cross_platforms.each do |plat|
118
+ desc "Build all native binary gems in parallel"
119
+ multitask 'native' => plat
120
+
121
+ desc "Build the native gem for #{plat}"
122
+ task plat => ['prepare', 'build'] do
123
+ RakeCompilerDock.sh <<-EOT, platform: plat
124
+ sudo apt-get update &&
125
+ sudo apt-get install -y libltdl-dev && bundle --local &&
126
+ rake cross native gem MAKE='nice make -j`nproc`' RUBY_CC_VERSION=${RUBY_CC_VERSION/:2.2.2/}
127
+ EOT
128
+ end
129
+ end
117
130
  end
118
131
 
119
132
  directory "ext/ffi_c/libffi"
@@ -125,7 +138,7 @@ task :libffi => "ext/ffi_c/libffi/autogen.sh"
125
138
 
126
139
  LIBFFI_GIT_FILES = `git --git-dir ext/ffi_c/libffi/.git ls-files -z`.split("\x0")
127
140
 
128
- # Generate files in gemspec but not in libffi's git repo by running autogen.sh
141
+ # Generate files which are in the gemspec but not in libffi's git repo by running autogen.sh
129
142
  gem_spec.files.select do |f|
130
143
  f =~ /ext\/ffi_c\/libffi\/(.*)/ && !LIBFFI_GIT_FILES.include?($1)
131
144
  end.each do |f|
@@ -141,6 +154,11 @@ end.each do |f|
141
154
  end
142
155
  end
143
156
 
157
+ # Make sure we have all gemspec files before packaging
158
+ task :build => gem_spec.files
159
+ task :gem => :build
160
+
161
+
144
162
  require_relative "lib/ffi/platform"
145
163
  types_conf = File.expand_path(File.join(FFI::Platform::CONF_DIR, 'types.conf'))
146
164
  logfile = File.join(File.dirname(__FILE__), 'types_log')
@@ -161,10 +179,6 @@ end
161
179
  desc "Create or update type information for platform #{FFI::Platform::NAME}"
162
180
  task :types_conf => types_conf
163
181
 
164
- Gem::Tasks.new do |t|
165
- t.scm.tag.format = '%s'
166
- end
167
-
168
182
  begin
169
183
  require 'yard'
170
184
 
@@ -32,12 +32,9 @@
32
32
  #include <sys/types.h>
33
33
  #ifndef _MSC_VER
34
34
  # include <sys/param.h>
35
- # include <stdint.h>
36
- # include <stdbool.h>
37
- #else
38
- # include "win32/stdbool.h"
39
- # include "win32/stdint.h"
40
35
  #endif
36
+ #include <stdint.h>
37
+ #include <stdbool.h>
41
38
 
42
39
  #include <limits.h>
43
40
  #include <ruby.h>
@@ -135,11 +132,13 @@ static VALUE memory_put_array_of_##name(VALUE self, VALUE offset, VALUE ary); \
135
132
  static VALUE \
136
133
  memory_put_array_of_##name(VALUE self, VALUE offset, VALUE ary) \
137
134
  { \
138
- long count = RARRAY_LEN(ary); \
135
+ long count; \
139
136
  long off = NUM2LONG(offset); \
140
137
  AbstractMemory* memory = MEMORY(self); \
141
138
  long i; \
142
- checkWrite(memory); \
139
+ Check_Type(ary, T_ARRAY); \
140
+ count = RARRAY_LEN(ary); \
141
+ if (likely(count > 0)) checkWrite(memory); \
143
142
  checkBounds(memory, off, count * sizeof(type)); \
144
143
  for (i = 0; i < count; i++) { \
145
144
  type tmp = (type) VAL(toNative(RARRAY_PTR(ary)[i]), swap); \
@@ -162,7 +161,7 @@ memory_get_array_of_##name(VALUE self, VALUE offset, VALUE length) \
162
161
  AbstractMemory* memory = MEMORY(self); \
163
162
  VALUE retVal = rb_ary_new2(count); \
164
163
  long i; \
165
- checkRead(memory); \
164
+ if (likely(count > 0)) checkRead(memory); \
166
165
  checkBounds(memory, off, count * sizeof(type)); \
167
166
  for (i = 0; i < count; ++i) { \
168
167
  type tmp; \
@@ -209,13 +208,13 @@ SWAPU16(uint16_t x)
209
208
  ((x >> 40) & 0x000000000000ff00ULL) | \
210
209
  ((x >> 56) & 0x00000000000000ffULL))
211
210
 
212
- static inline int32_t
211
+ static inline int32_t
213
212
  SWAPS32(int32_t x)
214
213
  {
215
214
  return bswap32(x);
216
215
  }
217
216
 
218
- static inline uint32_t
217
+ static inline uint32_t
219
218
  SWAPU32(uint32_t x)
220
219
  {
221
220
  return bswap32(x);
@@ -450,7 +449,7 @@ memory_get_array_of_string(int argc, VALUE* argv, VALUE self)
450
449
  int i;
451
450
 
452
451
  checkBounds(ptr, off, count * sizeof (char*));
453
-
452
+
454
453
  for (i = 0; i < count; ++i) {
455
454
  const char* strptr = *((const char**) (ptr->address + off) + i);
456
455
  rb_ary_push(retVal, (strptr == NULL ? Qnil : rb_str_new2(strptr)));
@@ -477,7 +476,7 @@ memory_get_array_of_string(int argc, VALUE* argv, VALUE self)
477
476
  * @param [Numeric] count number of strings to get. If nil, return all strings
478
477
  * @return [Array<String>]
479
478
  */
480
- static VALUE
479
+ static VALUE
481
480
  memory_read_array_of_string(int argc, VALUE* argv, VALUE self)
482
481
  {
483
482
  VALUE* rargv = ALLOCA_N(VALUE, argc + 1);
@@ -535,13 +534,13 @@ memory_get_bytes(VALUE self, VALUE offset, VALUE length)
535
534
  {
536
535
  AbstractMemory* ptr = MEMORY(self);
537
536
  long off, len;
538
-
537
+
539
538
  off = NUM2LONG(offset);
540
539
  len = NUM2LONG(length);
541
540
 
542
541
  checkRead(ptr);
543
542
  checkBounds(ptr, off, len);
544
-
543
+
545
544
  return rb_str_new((char *) ptr->address + off, len);
546
545
  }
547
546
 
@@ -595,7 +594,7 @@ memory_put_bytes(int argc, VALUE* argv, VALUE self)
595
594
  * equivalent to :
596
595
  * memory.get_bytes(0, length)
597
596
  */
598
- static VALUE
597
+ static VALUE
599
598
  memory_read_bytes(VALUE self, VALUE length)
600
599
  {
601
600
  return memory_get_bytes(self, INT2FIX(0), length);
@@ -610,7 +609,7 @@ memory_read_bytes(VALUE self, VALUE length)
610
609
  * equivalent to :
611
610
  * memory.put_bytes(0, str, index, length)
612
611
  */
613
- static VALUE
612
+ static VALUE
614
613
  memory_write_bytes(int argc, VALUE* argv, VALUE self)
615
614
  {
616
615
  VALUE* wargv = ALLOCA_N(VALUE, argc + 1);
@@ -643,7 +642,7 @@ memory_type_size(VALUE self)
643
642
  * Document-method: []
644
643
  * call-seq: memory[idx]
645
644
  * @param [Numeric] idx index to access in memory
646
- * @return
645
+ * @return
647
646
  * Memory read accessor.
648
647
  */
649
648
  static VALUE
@@ -748,9 +747,9 @@ MemoryOps rbffi_AbstractMemoryOps = {
748
747
  void
749
748
  rbffi_AbstractMemory_Init(VALUE moduleFFI)
750
749
  {
751
- /*
750
+ /*
752
751
  * Document-class: FFI::AbstractMemory
753
- *
752
+ *
754
753
  * {AbstractMemory} is the base class for many memory management classes such as {Buffer}.
755
754
  *
756
755
  * This class has a lot of methods to work with integers :
@@ -778,8 +777,8 @@ rbffi_AbstractMemory_Init(VALUE moduleFFI)
778
777
  */
779
778
  VALUE classMemory = rb_define_class_under(moduleFFI, "AbstractMemory", rb_cObject);
780
779
  rbffi_AbstractMemoryClass = classMemory;
781
- /*
782
- * Document-variable: FFI::AbstractMemory
780
+ /*
781
+ * Document-variable: FFI::AbstractMemory
783
782
  */
784
783
  rb_global_variable(&rbffi_AbstractMemoryClass);
785
784
  rb_define_alloc_func(classMemory, memory_allocate);
@@ -807,13 +806,13 @@ rbffi_AbstractMemory_Init(VALUE moduleFFI)
807
806
  rb_define_method(classMemory, "read_array_of_" #type, memory_read_array_of_##type, 1); \
808
807
  rb_define_method(classMemory, "write_array_of_u" #type, memory_write_array_of_u##type, 1); \
809
808
  rb_define_method(classMemory, "read_array_of_u" #type, memory_read_array_of_u##type, 1);
810
-
809
+
811
810
  INT(int8);
812
811
  INT(int16);
813
812
  INT(int32);
814
813
  INT(int64);
815
814
  INT(long);
816
-
815
+
817
816
  #define ALIAS(name, old) \
818
817
  rb_define_alias(classMemory, "put_" #name, "put_" #old); \
819
818
  rb_define_alias(classMemory, "get_" #name, "get_" #old); \
@@ -831,12 +830,12 @@ rbffi_AbstractMemory_Init(VALUE moduleFFI)
831
830
  rb_define_alias(classMemory, "read_array_of_" #name, "read_array_of_" #old); \
832
831
  rb_define_alias(classMemory, "write_array_of_u" #name, "write_array_of_u" #old); \
833
832
  rb_define_alias(classMemory, "read_array_of_u" #name, "read_array_of_u" #old);
834
-
833
+
835
834
  ALIAS(char, int8);
836
835
  ALIAS(short, int16);
837
836
  ALIAS(int, int32);
838
837
  ALIAS(long_long, int64);
839
-
838
+
840
839
  /*
841
840
  * Document-method: put_float32
842
841
  * call-seq: memory.put_float32offset, value)
data/ext/ffi_c/Buffer.c CHANGED
@@ -28,13 +28,8 @@
28
28
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
29
  */
30
30
 
31
- #ifndef _MSC_VER
32
- # include <stdint.h>
33
- # include <stdbool.h>
34
- #else
35
- # include "win32/stdbool.h"
36
- # include "win32/stdint.h"
37
- #endif
31
+ #include <stdint.h>
32
+ #include <stdbool.h>
38
33
  #include <limits.h>
39
34
  #include <ruby.h>
40
35
  #include "rbffi.h"
data/ext/ffi_c/Call.c CHANGED
@@ -34,13 +34,8 @@
34
34
  #endif
35
35
  #include <sys/types.h>
36
36
  #include <stdio.h>
37
- #ifndef _MSC_VER
38
- # include <stdint.h>
39
- # include <stdbool.h>
40
- #else
41
- # include "win32/stdbool.h"
42
- # include "win32/stdint.h"
43
- #endif
37
+ #include <stdint.h>
38
+ #include <stdbool.h>
44
39
  #include <errno.h>
45
40
  #include <ruby.h>
46
41
  #include <ruby/thread.h>
@@ -76,7 +71,7 @@
76
71
  #define FLOAT32_ADJ (4)
77
72
  #define FLOAT64_ADJ (8)
78
73
  #define ADDRESS_ADJ (sizeof(void *))
79
- #define LONGDOUBLE_ADJ (ffi_type_longdouble.alignment)
74
+ #define LONGDOUBLE_ADJ (ffi_type_longdouble.alignment > sizeof(long double) ? ffi_type_longdouble.alignment : sizeof(long double))
80
75
 
81
76
  #endif /* USE_RAW */
82
77
 
@@ -315,7 +310,6 @@ rbffi_SetupCallParams(int argc, VALUE* argv, int paramCount, Type** paramTypes,
315
310
 
316
311
 
317
312
  case NATIVE_FUNCTION:
318
- case NATIVE_CALLBACK:
319
313
  if (callbackProc != Qnil) {
320
314
  param->ptr = callback_param(callbackProc, callbackParameters[cbidx++]);
321
315
  } else {
@@ -34,13 +34,8 @@
34
34
  # include <sys/mman.h>
35
35
  #endif
36
36
  #include <stdio.h>
37
- #ifndef _MSC_VER
38
- # include <stdint.h>
39
- # include <stdbool.h>
40
- #else
41
- # include "win32/stdbool.h"
42
- # include "win32/stdint.h"
43
- #endif
37
+ #include <stdint.h>
38
+ #include <stdbool.h>
44
39
  #if defined(__CYGWIN__) || !defined(_WIN32)
45
40
  # include <unistd.h>
46
41
  #else
@@ -51,9 +46,6 @@
51
46
  #include <errno.h>
52
47
  #include <ruby.h>
53
48
 
54
- #if defined(_MSC_VER) && !defined(INT8_MIN)
55
- # include "win32/stdint.h"
56
- #endif
57
49
  #include <ffi.h>
58
50
  #include "rbffi.h"
59
51
  #include "compat.h"
@@ -66,7 +58,6 @@
66
58
 
67
59
  #include "ClosurePool.h"
68
60
 
69
-
70
61
  #ifndef roundup
71
62
  # define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
72
63
  #endif
@@ -115,7 +106,11 @@ cleanup_closure_pool(ClosurePool* pool)
115
106
 
116
107
  for (memory = pool->blocks; memory != NULL; ) {
117
108
  Memory* next = memory->next;
109
+ #if !USE_FFI_ALLOC
118
110
  freePage(memory->code);
111
+ #else
112
+ ffi_closure_free(memory->code);
113
+ #endif
119
114
  free(memory->data);
120
115
  free(memory);
121
116
  memory = next;
@@ -134,6 +129,8 @@ rbffi_ClosurePool_Free(ClosurePool* pool)
134
129
  }
135
130
  }
136
131
 
132
+ #if !USE_FFI_ALLOC
133
+
137
134
  Closure*
138
135
  rbffi_Closure_Alloc(ClosurePool* pool)
139
136
  {
@@ -169,6 +166,7 @@ rbffi_Closure_Alloc(ClosurePool* pool)
169
166
  closure->next = &list[i + 1];
170
167
  closure->pool = pool;
171
168
  closure->code = ((char *)code + (i * trampolineSize));
169
+ closure->pcl = closure->code;
172
170
 
173
171
  if (!(*pool->prep)(pool->ctx, closure->code, closure, errmsg, sizeof(errmsg))) {
174
172
  goto error;
@@ -205,6 +203,57 @@ error:
205
203
  return NULL;
206
204
  }
207
205
 
206
+ #else
207
+
208
+ Closure*
209
+ rbffi_Closure_Alloc(ClosurePool* pool)
210
+ {
211
+ Closure *closure = NULL;
212
+ Memory* block = NULL;
213
+ void *code = NULL;
214
+ void *pcl = NULL;
215
+ char errmsg[256];
216
+
217
+ block = calloc(1, sizeof(*block));
218
+ closure = calloc(1, sizeof(*closure));
219
+ pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
220
+
221
+ if (block == NULL || closure == NULL || pcl == NULL) {
222
+ snprintf(errmsg, sizeof(errmsg), "failed to allocate a page. errno=%d (%s)", errno, strerror(errno));
223
+ goto error;
224
+ }
225
+
226
+ closure->pool = pool;
227
+ closure->code = code;
228
+ closure->pcl = pcl;
229
+
230
+ if (!(*pool->prep)(pool->ctx, closure->code, closure, errmsg, sizeof(errmsg))) {
231
+ goto error;
232
+ }
233
+
234
+ /* Track the allocated page + Closure memory area */
235
+ block->data = closure;
236
+ block->code = pcl;
237
+ pool->blocks = block;
238
+
239
+ /* Thread the new block onto the free list, apart from the first one. */
240
+ pool->refcnt++;
241
+
242
+ return closure;
243
+
244
+ error:
245
+ free(block);
246
+ free(closure);
247
+ if (pcl != NULL) {
248
+ ffi_closure_free(pcl);
249
+ }
250
+
251
+ rb_raise(rb_eRuntimeError, "%s", errmsg);
252
+ return NULL;
253
+ }
254
+
255
+ #endif /* !USE_FFI_ALLOC */
256
+
208
257
  void
209
258
  rbffi_Closure_Free(Closure* closure)
210
259
  {
@@ -240,6 +289,8 @@ getPageSize()
240
289
  #endif
241
290
  }
242
291
 
292
+ #if !USE_FFI_ALLOC
293
+
243
294
  static void*
244
295
  allocatePage(void)
245
296
  {
@@ -272,6 +323,8 @@ protectPage(void* page)
272
323
  #endif
273
324
  }
274
325
 
326
+ #endif /* !USE_FFI_ALLOC */
327
+
275
328
  void
276
329
  rbffi_ClosurePool_Init(VALUE module)
277
330
  {
@@ -35,7 +35,9 @@ typedef struct Closure_ Closure;
35
35
  struct Closure_ {
36
36
  void* info; /* opaque handle for storing closure-instance specific data */
37
37
  void* function; /* closure-instance specific function, called by custom trampoline */
38
- void* code; /* The native trampoline code location */
38
+ void* code; /* Executable address for the native trampoline code location */
39
+ void* pcl; /* Writeable address for the native trampoline code location */
40
+
39
41
  struct ClosurePool_* pool;
40
42
  Closure* next;
41
43
  };