Skip to content

Commit

Permalink
Transplant bits of 'dl' library we still need for our fiddle.
Browse files Browse the repository at this point in the history
  • Loading branch information
headius committed Jan 14, 2015
1 parent 47bc672 commit f129eab
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 15 deletions.
57 changes: 57 additions & 0 deletions lib/ruby/stdlib/fiddle.rb
Expand Up @@ -67,6 +67,63 @@ def dlopen library
end
module_function :dlopen

class Handle
RTLD_GLOBAL = FFI::DynamicLibrary::RTLD_GLOBAL
RTLD_LAZY = FFI::DynamicLibrary::RTLD_LAZY
RTLD_NOW = FFI::DynamicLibrary::RTLD_NOW

def initialize(libname = nil, flags = RTLD_LAZY | RTLD_GLOBAL)
@lib = FFI::DynamicLibrary.open(libname, flags)
raise RuntimeError, "Could not open #{libname}" unless @lib

@open = true

begin
yield(self)
ensure
self.close
end if block_given?
end

def close
raise DLError.new("closed handle") unless @open
@open = false
0
end

def self.sym(func)
DEFAULT.sym(func)
end

def sym(func)
raise TypeError.new("invalid function name") unless func.is_a?(String)
raise DLError.new("closed handle") unless @open
address = @lib.find_function(func)
raise DLError.new("unknown symbol #{func}") if address.nil? || address.null?
address.to_i
end

def self.[](func)
self.sym(func)
end

def [](func)
sym(func)
end

def enable_close
@enable_close = true
end

def close_enabled?
@enable_close
end

def disable_close
@enable_close = false
end
end

# Add constants for backwards compat

RTLD_GLOBAL = Handle::RTLD_GLOBAL # :nodoc:
Expand Down
59 changes: 44 additions & 15 deletions lib/ruby/stdlib/fiddle/jruby.rb
@@ -1,19 +1,48 @@
require 'ffi'
require 'dl'

module Fiddle
TYPE_VOID = DL::TYPE_VOID
TYPE_VOIDP = DL::TYPE_VOIDP
TYPE_CHAR = DL::TYPE_CHAR
TYPE_SHORT = DL::TYPE_SHORT
TYPE_INT = DL::TYPE_INT
TYPE_LONG = DL::TYPE_LONG
TYPE_LONG_LONG = DL::TYPE_LONG_LONG
TYPE_FLOAT = DL::TYPE_FLOAT
TYPE_DOUBLE = DL::TYPE_DOUBLE
TYPE_VOID = 0
TYPE_VOIDP = 1
TYPE_CHAR = 2
TYPE_SHORT = 3
TYPE_INT = 4
TYPE_LONG = 5
TYPE_LONG_LONG = 6
TYPE_FLOAT = 7
TYPE_DOUBLE = 8

WINDOWS = FFI::Platform.windows?

module JRuby
FFITypes = {
'c' => FFI::Type::INT8,
'h' => FFI::Type::INT16,
'i' => FFI::Type::INT32,
'l' => FFI::Type::LONG,
'f' => FFI::Type::FLOAT32,
'd' => FFI::Type::FLOAT64,
'p' => FFI::Type::POINTER,
's' => FFI::Type::STRING,

TYPE_VOID => FFI::Type::Builtin::VOID,
TYPE_VOIDP => FFI::Type::Builtin::POINTER,
TYPE_CHAR => FFI::Type::Builtin::CHAR,
TYPE_SHORT => FFI::Type::Builtin::SHORT,
TYPE_INT => FFI::Type::Builtin::INT,
TYPE_LONG => FFI::Type::Builtin::LONG,
TYPE_LONG_LONG => FFI::Type::Builtin::LONG_LONG,
TYPE_FLOAT => FFI::Type::Builtin::FLOAT,
TYPE_DOUBLE => FFI::Type::Builtin::DOUBLE,
}

def self.__ffi_type__(dl_type)
ffi_type = FFITypes[dl_type]
ffi_type = FFITypes[-dl_type] if ffi_type.nil? && dl_type.is_a?(Integer) && dl_type < 0
raise TypeError.new("cannot convert #{dl_type} to ffi") unless ffi_type
ffi_type
end
end

class Function
DEFAULT = "default"
STDCALL = "stdcall"
Expand All @@ -24,9 +53,9 @@ def initialize(ptr, args, return_type, abi = DEFAULT)
raise TypeError.new "invalid return type" unless args.is_a?(Array)

@function = FFI::Function.new(
DL.__ffi_type__(@return_type),
@args.map { |t| DL.__ffi_type__(t) },
ptr.is_a?(DL::CPtr) ? ptr.ffi_ptr : FFI::Pointer.new(ptr.to_i),
Fiddle::JRuby::__ffi_type__(@return_type),
@args.map { |t| Fiddle::JRuby.__ffi_type__(t) },
FFI::Pointer.new(ptr.to_i),
:convention => @abi
)
@function.attach(self, "call")
Expand All @@ -43,8 +72,8 @@ def initialize(ret, args, abi = Function::DEFAULT)
raise TypeError.new "invalid return type" unless args.is_a?(Array)

@function = FFI::Function.new(
DL.__ffi_type__(@ctype),
@args.map { |t| DL.__ffi_type__(t) },
__ffi_type__(@ctype),
@args.map { |t| Fiddle::JRuby.__ffi_type__(t) },
self,
:convention => abi
)
Expand Down

0 comments on commit f129eab

Please sign in to comment.