ffi 1.10.0 → 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.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.gitmodules +2 -1
- data/.travis.yml +17 -18
- data/CHANGELOG.md +33 -0
- data/Gemfile +1 -1
- data/README.md +20 -17
- data/Rakefile +10 -83
- data/appveyor.yml +6 -1
- data/ext/ffi_c/Call.c +16 -33
- data/ext/ffi_c/Call.h +2 -5
- data/ext/ffi_c/Function.c +24 -108
- data/ext/ffi_c/Platform.c +0 -47
- data/ext/ffi_c/Thread.c +6 -222
- data/ext/ffi_c/Thread.h +2 -13
- data/ext/ffi_c/Type.c +0 -18
- data/ext/ffi_c/Type.h +0 -1
- data/ext/ffi_c/Variadic.c +9 -15
- data/ext/ffi_c/extconf.rb +34 -20
- data/ext/ffi_c/ffi.c +3 -8
- data/ext/ffi_c/libffi/configure.ac +5 -1
- data/ext/ffi_c/libffi/include/ffi_common.h +1 -1
- data/ext/ffi_c/libffi/src/aarch64/ffi.c +2 -2
- data/ext/ffi_c/libffi/src/frv/ffi.c +1 -1
- data/ext/ffi_c/libffi/src/metag/ffi.c +1 -1
- data/ext/ffi_c/libffi/src/moxie/ffi.c +1 -1
- data/ext/ffi_c/libffi/src/riscv/ffi.c +42 -6
- data/ext/ffi_c/libffi/src/riscv/ffitarget.h +1 -0
- data/ext/ffi_c/libffi/src/riscv/sysv.S +86 -7
- data/ext/ffi_c/libffi/src/x86/ffi.c +2 -1
- data/ext/ffi_c/libffi/src/x86/ffiw64.c +1 -1
- data/ext/ffi_c/libffi/src/x86/sysv.S +88 -2
- data/ext/ffi_c/libffi/src/x86/unix64.S +41 -0
- data/ext/ffi_c/rbffi.h +0 -2
- data/ffi.gemspec +11 -4
- data/lib/ffi/data_converter.rb +67 -0
- data/lib/ffi/ffi.rb +1 -0
- data/lib/ffi/platform.rb +2 -0
- data/lib/ffi/pointer.rb +1 -1
- data/lib/ffi/struct.rb +3 -63
- data/lib/ffi/struct_by_reference.rb +72 -0
- data/lib/ffi/struct_layout.rb +96 -0
- data/lib/ffi/tools/const_generator.rb +5 -4
- data/lib/ffi/tools/generator.rb +47 -2
- data/lib/ffi/tools/generator_task.rb +13 -17
- data/lib/ffi/tools/struct_generator.rb +4 -4
- data/lib/ffi/types.rb +1 -1
- data/lib/ffi/version.rb +1 -1
- metadata +18 -13
- data/ext/ffi_c/DataConverter.c +0 -91
- data/ext/ffi_c/StructByReference.c +0 -190
- data/ext/ffi_c/StructByReference.h +0 -50
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 041f37e7f1d2ed3857caabe7c68a68d3d8a9b403c5d03e8df59d0277a48f17e2
         | 
| 4 | 
            +
              data.tar.gz: 4c9bcdce1d0ba85318109bb074a0e19c87f5c004440a491d5f532ac2ec20b82c
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 4ae610d83039e9edc3ce4fe3708319cc4c1fc0d8d6dbddc96b4f4b51eec5875fb9052adfce7620664707a73696f3d17c4c1c956037ac252e1924a36fde57ad4c
         | 
| 7 | 
            +
              data.tar.gz: 3a745c80a61c816826ded2c3e29eb13746e1686edcd14f98d06d012d31352b7eaf30e15d9517e662a80beb65f48e1af6e0bceddbf23346d3268ccf6d6ea820ea
         | 
    
        data/.gitignore
    CHANGED
    
    
    
        data/.gitmodules
    CHANGED
    
    
    
        data/.travis.yml
    CHANGED
    
    | @@ -1,12 +1,11 @@ | |
| 1 1 | 
             
            dist: trusty
         | 
| 2 | 
            -
            sudo: false
         | 
| 3 2 | 
             
            group: beta
         | 
| 4 3 | 
             
            language: ruby
         | 
| 5 | 
            -
             | 
| 6 | 
            -
              - gem install bundler
         | 
| 4 | 
            +
             | 
| 7 5 | 
             
            script:
         | 
| 8 6 | 
             
              - bundle exec rake compile || bundle exec rake compile
         | 
| 9 7 | 
             
              - bundle exec rake test
         | 
| 8 | 
            +
              - ITER=10 bundle exec rake bench:all
         | 
| 10 9 | 
             
            os:
         | 
| 11 10 | 
             
              - linux
         | 
| 12 11 | 
             
              - osx
         | 
| @@ -16,28 +15,28 @@ rvm: | |
| 16 15 | 
             
              - 2.5.3
         | 
| 17 16 | 
             
              - 2.6.0
         | 
| 18 17 | 
             
              - ruby-head
         | 
| 19 | 
            -
             | 
| 18 | 
            +
             | 
| 20 19 | 
             
            env:
         | 
| 21 20 | 
             
              - CC=gcc
         | 
| 22 21 | 
             
              - CC=clang
         | 
| 23 22 | 
             
            matrix:
         | 
| 24 23 | 
             
              allow_failures:
         | 
| 25 | 
            -
                - rvm: system
         | 
| 26 24 | 
             
                - os: osx
         | 
| 27 25 | 
             
                  rvm: ruby-head
         | 
| 28 | 
            -
              exclude: # ruby 2.4.2 needs build with xcode9 or later on osx
         | 
| 29 | 
            -
                - os: osx
         | 
| 30 | 
            -
                  rvm: 2.4.2
         | 
| 31 26 | 
             
              include:
         | 
| 32 | 
            -
                -  | 
| 33 | 
            -
                   | 
| 34 | 
            -
                   | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 40 | 
            -
                   | 
| 41 | 
            -
                   | 
| 27 | 
            +
                - name: powerpc
         | 
| 28 | 
            +
                  language: generic
         | 
| 29 | 
            +
                  before_install: |
         | 
| 30 | 
            +
                    docker run --rm --privileged multiarch/qemu-user-static:register --reset &&
         | 
| 31 | 
            +
                      docker build --rm -t ffi-powerpc -f spec/env/Dockerfile.powerpc .
         | 
| 32 | 
            +
                  script: |
         | 
| 33 | 
            +
                    docker run --rm -t -v `pwd`:/ffi ffi-powerpc
         | 
| 34 | 
            +
                - name: armhf
         | 
| 35 | 
            +
                  language: generic
         | 
| 36 | 
            +
                  before_install: |
         | 
| 37 | 
            +
                    docker run --rm --privileged multiarch/qemu-user-static:register --reset &&
         | 
| 38 | 
            +
                      docker build --rm -t ffi-armhf -f spec/env/Dockerfile.armhf .
         | 
| 39 | 
            +
                  script: |
         | 
| 40 | 
            +
                    docker run --rm -t -v `pwd`:/ffi ffi-armhf
         | 
| 42 41 | 
             
            after_failure:
         | 
| 43 42 | 
             
              - "find build -name mkmf.log | xargs cat"
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,3 +1,36 @@ | |
| 1 | 
            +
            1.11.1 / 2019-05-20
         | 
| 2 | 
            +
            -------------------
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            Changed:
         | 
| 5 | 
            +
            * Raise required ruby version to >=2.0. #699, #700
         | 
| 6 | 
            +
            * Fix a possible linker error on ruby < 2.3 on Linux.
         | 
| 7 | 
            +
             | 
| 8 | 
            +
             | 
| 9 | 
            +
            1.11.0 / 2019-05-17
         | 
| 10 | 
            +
            -------------------
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            Added:
         | 
| 13 | 
            +
            * Add ability to disable or force use of system libffi. #669
         | 
| 14 | 
            +
              Use like `gem inst ffi -- --enable-system-libffi` .
         | 
| 15 | 
            +
            * Add ability to call FFI callbacks from outside of FFI call frame. #584
         | 
| 16 | 
            +
            * Add proper documentation to FFI::Generator and ::Task
         | 
| 17 | 
            +
            * Add gemspec metadata. #696, #698
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            Changed:
         | 
| 20 | 
            +
            * Fix stdcall on Win32. #649, #669
         | 
| 21 | 
            +
            * Fix load paths for FFI::Generator::Task
         | 
| 22 | 
            +
            * Fix FFI::Pointer#read_string(0) to return a binary String. #692
         | 
| 23 | 
            +
            * Fix benchmark suite so that it runs on ruby-2.x
         | 
| 24 | 
            +
            * Move FFI::Platform::CPU from C to Ruby. #663
         | 
| 25 | 
            +
            * Move FFI::StructByReference to Ruby. #681
         | 
| 26 | 
            +
            * Move FFI::DataConverter to Ruby (#661)
         | 
| 27 | 
            +
            * Various cleanups and improvements of specs and benchmarks
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            Removed:
         | 
| 30 | 
            +
            * Remove ruby-1.8 and 1.9 compatibility code. #683
         | 
| 31 | 
            +
            * Remove unused spec files. #684
         | 
| 32 | 
            +
             | 
| 33 | 
            +
             | 
| 1 34 | 
             
            1.10.0 / 2019-01-06
         | 
| 2 35 | 
             
            -------------------
         | 
| 3 36 |  | 
    
        data/Gemfile
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -1,19 +1,19 @@ | |
| 1 | 
            -
            #  | 
| 1 | 
            +
            # Ruby-FFI https://github.com/ffi/ffi/wiki [](https://travis-ci.org/ffi/ffi) [](https://ci.appveyor.com/project/larskanis/ffi-aofqa/branch/master)
         | 
| 2 2 |  | 
| 3 3 | 
             
            ## Description
         | 
| 4 4 |  | 
| 5 | 
            -
            Ruby-FFI is a  | 
| 5 | 
            +
            Ruby-FFI is a gem for programmatically loading dynamically-linked native
         | 
| 6 6 | 
             
            libraries, binding functions within them, and calling those functions
         | 
| 7 7 | 
             
            from Ruby code. Moreover, a Ruby-FFI extension works without changes
         | 
| 8 | 
            -
            on  | 
| 9 | 
            -
            using Ruby-FFI](https:// | 
| 8 | 
            +
            on CRuby (MRI), JRuby, Rubinius and TruffleRuby. [Discover why you should write your next extension
         | 
| 9 | 
            +
            using Ruby-FFI](https://github.com/ffi/ffi/wiki/why-use-ffi).
         | 
| 10 10 |  | 
| 11 | 
            -
            ## Features | 
| 11 | 
            +
            ## Features
         | 
| 12 12 |  | 
| 13 13 | 
             
            * Intuitive DSL
         | 
| 14 14 | 
             
            * Supports all C native types
         | 
| 15 15 | 
             
            * C structs (also nested), enums and global variables
         | 
| 16 | 
            -
            * Callbacks from C to  | 
| 16 | 
            +
            * Callbacks from C to Ruby
         | 
| 17 17 | 
             
            * Automatic garbage collection of native memory
         | 
| 18 18 |  | 
| 19 19 | 
             
            ## Synopsis
         | 
| @@ -30,20 +30,23 @@ end | |
| 30 30 | 
             
            MyLib.puts 'Hello, World using libc!'
         | 
| 31 31 | 
             
            ```
         | 
| 32 32 |  | 
| 33 | 
            -
            For less minimalistic and more  | 
| 33 | 
            +
            For less minimalistic and more examples you may look at:
         | 
| 34 34 |  | 
| 35 | 
            -
            * the samples | 
| 36 | 
            -
            * the examples on the [wiki](https:// | 
| 37 | 
            -
            * the projects using FFI listed on  | 
| 35 | 
            +
            * the `samples/` folder
         | 
| 36 | 
            +
            * the examples on the [wiki](https://github.com/ffi/ffi/wiki)
         | 
| 37 | 
            +
            * the projects using FFI listed on the wiki: https://github.com/ffi/ffi/wiki/projects-using-ffi
         | 
| 38 38 |  | 
| 39 39 | 
             
            ## Requirements
         | 
| 40 40 |  | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
            *  | 
| 44 | 
            -
            * libffi development library - this is commonly in the libffi-dev or libffi-devel
         | 
| 41 | 
            +
            When installing the gem on CRuby (MRI) or Rubinius, you will need:
         | 
| 42 | 
            +
            * A C compiler (e.g., Xcode on macOS, `gcc` or `clang` on everything else)
         | 
| 43 | 
            +
            * The `libffi` library and development headers - this is commonly in the `libffi-dev` or `libffi-devel` packages
         | 
| 45 44 |  | 
| 46 | 
            -
            On Linux systems running with [PaX](https://en.wikipedia.org/wiki/PaX) (Gentoo, Alpine, etc.) FFI may trigger `mprotect` errors. You may need to disable [mprotect](https://en.wikibooks.org/wiki/Grsecurity/Appendix/Grsecurity_and_PaX_Configuration_Options#Restrict_mprotect.28.29) for ruby (`paxctl -m [/path/to/ruby]`) for the time being until a solution is found.
         | 
| 45 | 
            +
            On Linux systems running with [PaX](https://en.wikipedia.org/wiki/PaX) (Gentoo, Alpine, etc.), FFI may trigger `mprotect` errors. You may need to disable [mprotect](https://en.wikibooks.org/wiki/Grsecurity/Appendix/Grsecurity_and_PaX_Configuration_Options#Restrict_mprotect.28.29) for ruby (`paxctl -m [/path/to/ruby]`) for the time being until a solution is found.
         | 
| 46 | 
            +
             | 
| 47 | 
            +
            On FreeBSD systems pkgconf must be installed for the gem to be able to compile using clang. Install either via packages `pkg install pkgconf` or from ports via `devel/pkgconf`.
         | 
| 48 | 
            +
             | 
| 49 | 
            +
            On JRuby and TruffleRuby, there are no requirements to install the FFI gem, and `require 'ffi'` works even without installing the gem (i.e., the gem is preinstalled on these implementations).
         | 
| 47 50 |  | 
| 48 51 | 
             
            ## Installation
         | 
| 49 52 |  | 
| @@ -61,8 +64,7 @@ or from the git repository on github: | |
| 61 64 | 
             
            ## License
         | 
| 62 65 |  | 
| 63 66 | 
             
            The ffi library is covered by the BSD license, also see the LICENSE file.
         | 
| 64 | 
            -
            The specs are  | 
| 65 | 
            -
            as Rubyspec, see the LICENSE.SPECS file.
         | 
| 67 | 
            +
            The specs are covered by the same license as [ruby/spec](https://github.com/ruby/spec), the MIT license.
         | 
| 66 68 |  | 
| 67 69 | 
             
            ## Credits
         | 
| 68 70 |  | 
| @@ -74,6 +76,7 @@ The following people have submitted code, bug reports, or otherwise contributed | |
| 74 76 | 
             
            * Andreas Niederl <rico32@gmx.net>
         | 
| 75 77 | 
             
            * Andrew Cholakian <andrew@andrewvc.com>
         | 
| 76 78 | 
             
            * Antonio Terceiro <terceiro@softwarelivre.org>
         | 
| 79 | 
            +
            * Benoit Daloze <eregontp@gmail.com>
         | 
| 77 80 | 
             
            * Brian Candler <B.Candler@pobox.com>
         | 
| 78 81 | 
             
            * Brian D. Burns <burns180@gmail.com>
         | 
| 79 82 | 
             
            * Bryan Kearney <bkearney@redhat.com>
         | 
    
        data/Rakefile
    CHANGED
    
    | @@ -3,82 +3,16 @@ require 'rbconfig' | |
| 3 3 | 
             
            require 'rake/clean'
         | 
| 4 4 | 
             
            require File.expand_path("./lib/ffi/version")
         | 
| 5 5 |  | 
| 6 | 
            -
            USE_RAKE_COMPILER = (RUBY_PLATFORM =~ /java/) ? false : true
         | 
| 7 | 
            -
            if USE_RAKE_COMPILER
         | 
| 8 | 
            -
              require 'rake/extensiontask'
         | 
| 9 | 
            -
            end
         | 
| 10 | 
            -
             | 
| 11 6 | 
             
            require 'date'
         | 
| 12 7 | 
             
            require 'fileutils'
         | 
| 13 8 | 
             
            require 'rbconfig'
         | 
| 14 9 | 
             
            require 'rspec/core/rake_task'
         | 
| 15 10 | 
             
            require 'rubygems/package_task'
         | 
| 16 11 |  | 
| 17 | 
            -
             | 
| 18 | 
            -
               | 
| 19 | 
            -
                "dylib"
         | 
| 20 | 
            -
              when /mswin|mingw/
         | 
| 21 | 
            -
                "dll"
         | 
| 22 | 
            -
              else
         | 
| 23 | 
            -
                RbConfig::CONFIG['DLEXT']
         | 
| 24 | 
            -
              end
         | 
| 25 | 
            -
             | 
| 26 | 
            -
            CPU = case RbConfig::CONFIG['host_cpu'].downcase
         | 
| 27 | 
            -
              when /i[3456]86/
         | 
| 28 | 
            -
                # Darwin always reports i686, even when running in 64bit mode
         | 
| 29 | 
            -
                if RbConfig::CONFIG['host_os'] =~ /darwin/ && 0xfee1deadbeef.is_a?(Fixnum)
         | 
| 30 | 
            -
                  "x86_64"
         | 
| 31 | 
            -
                else
         | 
| 32 | 
            -
                  "i386"
         | 
| 33 | 
            -
                end
         | 
| 34 | 
            -
             | 
| 35 | 
            -
              when /amd64|x86_64/
         | 
| 36 | 
            -
                "x86_64"
         | 
| 37 | 
            -
             | 
| 38 | 
            -
              when /ppc64|powerpc64/
         | 
| 39 | 
            -
                "powerpc64"
         | 
| 40 | 
            -
             | 
| 41 | 
            -
              when /ppc|powerpc/
         | 
| 42 | 
            -
                "powerpc"
         | 
| 43 | 
            -
             | 
| 44 | 
            -
              when /^arm/
         | 
| 45 | 
            -
                "arm"
         | 
| 46 | 
            -
             | 
| 47 | 
            -
              else
         | 
| 48 | 
            -
                RbConfig::CONFIG['host_cpu']
         | 
| 49 | 
            -
              end
         | 
| 50 | 
            -
             | 
| 51 | 
            -
            OS = case RbConfig::CONFIG['host_os'].downcase
         | 
| 52 | 
            -
              when /linux/
         | 
| 53 | 
            -
                "linux"
         | 
| 54 | 
            -
              when /darwin/
         | 
| 55 | 
            -
                "darwin"
         | 
| 56 | 
            -
              when /freebsd/
         | 
| 57 | 
            -
                "freebsd"
         | 
| 58 | 
            -
              when /openbsd/
         | 
| 59 | 
            -
                "openbsd"
         | 
| 60 | 
            -
              when /sunos|solaris/
         | 
| 61 | 
            -
                "solaris"
         | 
| 62 | 
            -
              when /mswin|mingw/
         | 
| 63 | 
            -
                "win32"
         | 
| 64 | 
            -
              else
         | 
| 65 | 
            -
                RbConfig::CONFIG['host_os'].downcase
         | 
| 66 | 
            -
              end
         | 
| 67 | 
            -
             | 
| 68 | 
            -
            def which(name)
         | 
| 69 | 
            -
              exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
         | 
| 70 | 
            -
              ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
         | 
| 71 | 
            -
                exts.each do |ext|
         | 
| 72 | 
            -
                  app = File.join(path, name+ext)
         | 
| 73 | 
            -
                  return app if File.executable? app
         | 
| 74 | 
            -
                end
         | 
| 75 | 
            -
              end
         | 
| 76 | 
            -
              nil
         | 
| 12 | 
            +
            def java?
         | 
| 13 | 
            +
              /java/ === RUBY_PLATFORM
         | 
| 77 14 | 
             
            end
         | 
| 78 15 |  | 
| 79 | 
            -
            GMAKE = which('gmake').nil? ? 'make' : 'gmake'
         | 
| 80 | 
            -
             | 
| 81 | 
            -
            LIBTEST = "build/libtest.#{LIBEXT}"
         | 
| 82 16 | 
             
            BUILD_DIR = "build"
         | 
| 83 17 | 
             
            BUILD_EXT_DIR = File.join(BUILD_DIR, "#{RbConfig::CONFIG['arch']}", 'ffi_c', RUBY_VERSION)
         | 
| 84 18 |  | 
| @@ -86,7 +20,7 @@ def gem_spec | |
| 86 20 | 
             
              @gem_spec ||= Gem::Specification.load('ffi.gemspec')
         | 
| 87 21 | 
             
            end
         | 
| 88 22 |  | 
| 89 | 
            -
            TEST_DEPS = [ | 
| 23 | 
            +
            TEST_DEPS = []
         | 
| 90 24 | 
             
            if RUBY_PLATFORM == "java"
         | 
| 91 25 | 
             
              RSpec::Core::RakeTask.new(:spec) do |config|
         | 
| 92 26 | 
             
                config.rspec_opts = YAML.load_file 'spec/spec.opts'
         | 
| @@ -110,30 +44,22 @@ CLEAN.include 'build' | |
| 110 44 | 
             
            CLEAN.include 'conftest.dSYM'
         | 
| 111 45 | 
             
            CLEAN.include 'spec/ffi/fixtures/libtest.{dylib,so,dll}'
         | 
| 112 46 | 
             
            CLEAN.include 'spec/ffi/fixtures/*.o'
         | 
| 47 | 
            +
            CLEAN.include 'spec/ffi/embed-test/ext/*.{o,def}'
         | 
| 48 | 
            +
            CLEAN.include 'spec/ffi/embed-test/ext/Makefile'
         | 
| 113 49 | 
             
            CLEAN.include "pkg/ffi-*-{mingw32,java}"
         | 
| 114 50 | 
             
            CLEAN.include 'lib/1.*'
         | 
| 115 51 | 
             
            CLEAN.include 'lib/2.*'
         | 
| 116 | 
            -
            CLEAN.include 'bin'
         | 
| 117 52 |  | 
| 118 53 | 
             
            task :distclean => :clobber
         | 
| 119 54 |  | 
| 120 | 
            -
            desc "Build the native test lib"
         | 
| 121 | 
            -
            file "build/libtest.#{LIBEXT}" => FileList['libtest/**/*.[ch]'] do
         | 
| 122 | 
            -
              sh %{#{GMAKE} -f libtest/GNUmakefile CPU=#{CPU} OS=#{OS} }
         | 
| 123 | 
            -
            end
         | 
| 124 | 
            -
             | 
| 125 | 
            -
             | 
| 126 | 
            -
            desc "Build test helper lib"
         | 
| 127 | 
            -
            task :libtest => "build/libtest.#{LIBEXT}"
         | 
| 128 | 
            -
             | 
| 129 55 | 
             
            desc "Test the extension"
         | 
| 130 56 | 
             
            task :test => [ :spec ]
         | 
| 131 57 |  | 
| 132 58 |  | 
| 133 59 | 
             
            namespace :bench do
         | 
| 134 60 | 
             
              ITER = ENV['ITER'] ? ENV['ITER'].to_i : 100000
         | 
| 135 | 
            -
              bench_libs = "-Ilib | 
| 136 | 
            -
              bench_files = Dir["bench/bench_*.rb"].reject { |f| f == "bench_helper.rb" }
         | 
| 61 | 
            +
              bench_libs = "-Ilib" unless RUBY_PLATFORM == "java"
         | 
| 62 | 
            +
              bench_files = Dir["bench/bench_*.rb"].reject { |f| f == "bench/bench_helper.rb" }
         | 
| 137 63 | 
             
              bench_files.each do |bench|
         | 
| 138 64 | 
             
                task File.basename(bench, ".rb")[6..-1] => TEST_DEPS do
         | 
| 139 65 | 
             
                  sh %{#{Gem.ruby} #{bench_libs} #{bench} #{ITER}}
         | 
| @@ -175,8 +101,8 @@ end | |
| 175 101 |  | 
| 176 102 | 
             
            task 'gem:java' => 'java:gem'
         | 
| 177 103 |  | 
| 178 | 
            -
             | 
| 179 | 
            -
             | 
| 104 | 
            +
            unless java?
         | 
| 105 | 
            +
              require 'rake/extensiontask'
         | 
| 180 106 | 
             
              Rake::ExtensionTask.new('ffi_c', gem_spec) do |ext|
         | 
| 181 107 | 
             
                ext.name = 'ffi_c'                                        # indicate the name of the extension.
         | 
| 182 108 | 
             
                # ext.lib_dir = BUILD_DIR                                 # put binaries into this folder.
         | 
| @@ -212,6 +138,7 @@ file "ext/ffi_c/libffi/autogen.sh" => "ext/ffi_c/libffi" do | |
| 212 138 | 
             
              warn "Downloading libffi ..."
         | 
| 213 139 | 
             
              sh "git submodule update --init --recursive"
         | 
| 214 140 | 
             
            end
         | 
| 141 | 
            +
            task :libffi => "ext/ffi_c/libffi/autogen.sh"
         | 
| 215 142 |  | 
| 216 143 | 
             
            LIBFFI_GIT_FILES = `git --git-dir ext/ffi_c/libffi/.git ls-files -z`.split("\x0")
         | 
| 217 144 |  | 
    
        data/appveyor.yml
    CHANGED
    
    | @@ -12,11 +12,16 @@ install: | |
| 12 12 | 
             
              - bundle install
         | 
| 13 13 | 
             
            build: off
         | 
| 14 14 | 
             
            build_script:
         | 
| 15 | 
            -
              - bundle exec rake compile || bundle exec rake compile
         | 
| 15 | 
            +
              - bundle exec rake libffi compile -- %EXTCONFOPTS% || bundle exec rake compile -- %EXTCONFOPTS%
         | 
| 16 16 | 
             
            test_script:
         | 
| 17 17 | 
             
              - bundle exec rake test
         | 
| 18 18 | 
             
            environment:
         | 
| 19 19 | 
             
              matrix:
         | 
| 20 20 | 
             
                - RUBYVER: "head-x64"
         | 
| 21 | 
            +
                  EXTCONFOPTS: "--disable-system-libffi"
         | 
| 21 22 | 
             
                - RUBYVER: 24
         | 
| 23 | 
            +
                  EXTCONFOPTS: "--disable-system-libffi"
         | 
| 22 24 | 
             
                - RUBYVER: 25-x64
         | 
| 25 | 
            +
                  EXTCONFOPTS: "--enable-system-libffi"
         | 
| 26 | 
            +
                - RUBYVER: 25
         | 
| 27 | 
            +
                  EXTCONFOPTS: "--enable-system-libffi"
         | 
    
        data/ext/ffi_c/Call.c
    CHANGED
    
    | @@ -43,10 +43,8 @@ | |
| 43 43 | 
             
            #endif
         | 
| 44 44 | 
             
            #include <errno.h>
         | 
| 45 45 | 
             
            #include <ruby.h>
         | 
| 46 | 
            -
            #if defined(HAVE_RUBY_THREAD_H)
         | 
| 47 46 | 
             
            #include <ruby/thread.h>
         | 
| 48 | 
            -
            # | 
| 49 | 
            -
            #if defined(HAVE_NATIVETHREAD) && (defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)) && !defined(_WIN32)
         | 
| 47 | 
            +
            #if defined(HAVE_NATIVETHREAD) && !defined(_WIN32)
         | 
| 50 48 | 
             
            #  include <signal.h>
         | 
| 51 49 | 
             
            #  include <pthread.h>
         | 
| 52 50 | 
             
            #endif
         | 
| @@ -116,7 +114,7 @@ rbffi_SetupCallParams(int argc, VALUE* argv, int paramCount, Type** paramTypes, | |
| 116 114 | 
             
                    Type* paramType = paramTypes[i];
         | 
| 117 115 | 
             
                    int type;
         | 
| 118 116 |  | 
| 119 | 
            -
             | 
| 117 | 
            +
             | 
| 120 118 | 
             
                    if (unlikely(paramType->nativeType == NATIVE_MAPPED)) {
         | 
| 121 119 | 
             
                        VALUE values[] = { argv[argidx], Qnil };
         | 
| 122 120 | 
             
                        argv[argidx] = rb_funcall2(((MappedType *) paramType)->rbConverter, id_to_native, 2, values);
         | 
| @@ -297,8 +295,8 @@ rbffi_SetupCallParams(int argc, VALUE* argv, int paramCount, Type** paramTypes, | |
| 297 295 |  | 
| 298 296 | 
             
                        case NATIVE_STRING:
         | 
| 299 297 | 
             
                            if (type == T_NIL) {
         | 
| 300 | 
            -
                                param->ptr = NULL; | 
| 301 | 
            -
             | 
| 298 | 
            +
                                param->ptr = NULL;
         | 
| 299 | 
            +
             | 
| 302 300 | 
             
                            } else {
         | 
| 303 301 | 
             
                                if (rb_safe_level() >= 1 && OBJ_TAINTED(argv[argidx])) {
         | 
| 304 302 | 
             
                                    rb_raise(rb_eSecurityError, "Unsafe string parameter");
         | 
| @@ -345,9 +343,13 @@ static void * | |
| 345 343 | 
             
            call_blocking_function(void* data)
         | 
| 346 344 | 
             
            {
         | 
| 347 345 | 
             
                rbffi_blocking_call_t* b = (rbffi_blocking_call_t *) data;
         | 
| 346 | 
            +
            #ifndef HAVE_RUBY_THREAD_HAS_GVL_P
         | 
| 348 347 | 
             
                b->frame->has_gvl = false;
         | 
| 348 | 
            +
            #endif
         | 
| 349 349 | 
             
                ffi_call(&b->cif, FFI_FN(b->function), b->retval, b->ffiValues);
         | 
| 350 | 
            +
            #ifndef HAVE_RUBY_THREAD_HAS_GVL_P
         | 
| 350 351 | 
             
                b->frame->has_gvl = true;
         | 
| 352 | 
            +
            #endif
         | 
| 351 353 |  | 
| 352 354 | 
             
                return NULL;
         | 
| 353 355 | 
             
            }
         | 
| @@ -355,7 +357,7 @@ call_blocking_function(void* data) | |
| 355 357 | 
             
            VALUE
         | 
| 356 358 | 
             
            rbffi_do_blocking_call(void *data)
         | 
| 357 359 | 
             
            {
         | 
| 358 | 
            -
                 | 
| 360 | 
            +
                rb_thread_call_without_gvl(call_blocking_function, data, (void *) -1, NULL);
         | 
| 359 361 |  | 
| 360 362 | 
             
                return Qnil;
         | 
| 361 363 | 
             
            }
         | 
| @@ -376,28 +378,17 @@ rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo) | |
| 376 378 | 
             
                FFIStorage* params;
         | 
| 377 379 | 
             
                VALUE rbReturnValue;
         | 
| 378 380 | 
             
                rbffi_frame_t frame = { 0 };
         | 
| 379 | 
            -
             | 
| 381 | 
            +
             | 
| 380 382 | 
             
                retval = alloca(MAX(fnInfo->ffi_cif.rtype->size, FFI_SIZEOF_ARG));
         | 
| 381 | 
            -
             | 
| 383 | 
            +
             | 
| 382 384 | 
             
                if (unlikely(fnInfo->blocking)) {
         | 
| 383 385 | 
             
                    rbffi_blocking_call_t* bc;
         | 
| 384 386 |  | 
| 385 | 
            -
                    /*
         | 
| 386 | 
            -
                     * due to the way thread switching works on older ruby variants, we
         | 
| 387 | 
            -
                     * cannot allocate anything passed to the blocking function on the stack
         | 
| 388 | 
            -
                     */
         | 
| 389 | 
            -
            #if defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
         | 
| 387 | 
            +
                    /* allocate information passed to the blocking function on the stack */
         | 
| 390 388 | 
             
                    ffiValues = ALLOCA_N(void *, fnInfo->parameterCount);
         | 
| 391 389 | 
             
                    params = ALLOCA_N(FFIStorage, fnInfo->parameterCount);
         | 
| 392 390 | 
             
                    bc = ALLOCA_N(rbffi_blocking_call_t, 1);
         | 
| 393 391 | 
             
                    bc->retval = retval;
         | 
| 394 | 
            -
            #else
         | 
| 395 | 
            -
                    ffiValues = ALLOC_N(void *, fnInfo->parameterCount);
         | 
| 396 | 
            -
                    params = ALLOC_N(FFIStorage, fnInfo->parameterCount);
         | 
| 397 | 
            -
                    bc = ALLOC_N(rbffi_blocking_call_t, 1);
         | 
| 398 | 
            -
                    bc->retval = xmalloc(MAX(fnInfo->ffi_cif.rtype->size, FFI_SIZEOF_ARG));
         | 
| 399 | 
            -
                    bc->stkretval = retval;
         | 
| 400 | 
            -
            #endif
         | 
| 401 392 | 
             
                    bc->cif = fnInfo->ffi_cif;
         | 
| 402 393 | 
             
                    bc->function = function;
         | 
| 403 394 | 
             
                    bc->ffiValues = ffiValues;
         | 
| @@ -408,18 +399,10 @@ rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo) | |
| 408 399 | 
             
                        fnInfo->parameterCount, fnInfo->parameterTypes, params, ffiValues,
         | 
| 409 400 | 
             
                        fnInfo->callbackParameters, fnInfo->callbackCount, fnInfo->rbEnums);
         | 
| 410 401 |  | 
| 411 | 
            -
                    rbffi_frame_push(&frame); | 
| 402 | 
            +
                    rbffi_frame_push(&frame);
         | 
| 412 403 | 
             
                    rb_rescue2(rbffi_do_blocking_call, (VALUE) bc, rbffi_save_frame_exception, (VALUE) &frame, rb_eException, (VALUE) 0);
         | 
| 413 404 | 
             
                    rbffi_frame_pop(&frame);
         | 
| 414 405 |  | 
| 415 | 
            -
            #if !(defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL))
         | 
| 416 | 
            -
                    memcpy(bc->stkretval, bc->retval, MAX(bc->cif.rtype->size, FFI_SIZEOF_ARG));
         | 
| 417 | 
            -
                    xfree(bc->params);
         | 
| 418 | 
            -
                    xfree(bc->ffiValues);
         | 
| 419 | 
            -
                    xfree(bc->retval);
         | 
| 420 | 
            -
                    xfree(bc);
         | 
| 421 | 
            -
            #endif
         | 
| 422 | 
            -
                
         | 
| 423 406 | 
             
                } else {
         | 
| 424 407 |  | 
| 425 408 | 
             
                    ffiValues = ALLOCA_N(void *, fnInfo->parameterCount);
         | 
| @@ -436,7 +419,7 @@ rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo) | |
| 436 419 |  | 
| 437 420 | 
             
                if (unlikely(!fnInfo->ignoreErrno)) {
         | 
| 438 421 | 
             
                    rbffi_save_errno();
         | 
| 439 | 
            -
                } | 
| 422 | 
            +
                }
         | 
| 440 423 |  | 
| 441 424 | 
             
                if (RTEST(frame.exc) && frame.exc != Qnil) {
         | 
| 442 425 | 
             
                    rb_exc_raise(frame.exc);
         | 
| @@ -444,7 +427,7 @@ rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo) | |
| 444 427 |  | 
| 445 428 | 
             
                RB_GC_GUARD(rbReturnValue) = rbffi_NativeValue_ToRuby(fnInfo->returnType, fnInfo->rbReturnType, retval);
         | 
| 446 429 | 
             
                RB_GC_GUARD(fnInfo->rbReturnType);
         | 
| 447 | 
            -
             | 
| 430 | 
            +
             | 
| 448 431 | 
             
                return rbReturnValue;
         | 
| 449 432 | 
             
            }
         | 
| 450 433 |  | 
| @@ -461,7 +444,7 @@ getPointer(VALUE value, int type) | |
| 461 444 | 
             
                    return memory != NULL ? memory->address : NULL;
         | 
| 462 445 |  | 
| 463 446 | 
             
                } else if (type == T_STRING) {
         | 
| 464 | 
            -
             | 
| 447 | 
            +
             | 
| 465 448 | 
             
                    return StringValuePtr(value);
         | 
| 466 449 |  | 
| 467 450 | 
             
                } else if (type == T_NIL) {
         |