mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* ext/dl/lib/dl/func.rb (DL::Function#initialize, DL::Function#bind):
ABI should be set by using CFunc#calltype even when Fiddle is used. When Fiddle is used and a block is given, name shoud not be ignored. [ruby-core:50562] [Bug #7514] * ext/dl/lib/dl/import.rb (DL::Importer#bind_function): should respect abi and name when Fiddle is used. * test/dl/test_func.rb (test_name_with_block): test for "name" method with giving a block. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38202 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
342d2f2aa6
commit
f1841f43eb
4 changed files with 63 additions and 10 deletions
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
|||
Wed Dec 5 12:17:11 2012 Naohisa Goto <ngotogenome@gmail.com>
|
||||
|
||||
* ext/dl/lib/dl/func.rb (DL::Function#initialize, DL::Function#bind):
|
||||
ABI should be set by using CFunc#calltype even when Fiddle is used.
|
||||
When Fiddle is used and a block is given, name shoud not be ignored.
|
||||
[ruby-core:50562] [Bug #7514]
|
||||
|
||||
* ext/dl/lib/dl/import.rb (DL::Importer#bind_function): should respect
|
||||
abi and name when Fiddle is used.
|
||||
|
||||
* test/dl/test_func.rb (test_name_with_block): test for "name" method
|
||||
with giving a block.
|
||||
|
||||
Wed Dec 5 11:55:00 2012 Zachary Scott <zachary@zacharyscott.net>
|
||||
|
||||
* doc/shell.rd, doc/shell.rd.ja: Removed stale doc files
|
||||
|
|
|
@ -11,13 +11,45 @@ module DL
|
|||
include DL
|
||||
include ValueUtil
|
||||
|
||||
if DL.fiddle?
|
||||
CALL_TYPE_TO_ABI = Hash.new { |h, k|
|
||||
raise RuntimeError, "unsupported call type: #{k}"
|
||||
}.merge({ :stdcall =>
|
||||
(Fiddle::Function::STDCALL rescue Fiddle::Function::DEFAULT),
|
||||
:cdecl => Fiddle::Function::DEFAULT,
|
||||
nil => Fiddle::Function::DEFAULT
|
||||
}).freeze
|
||||
private_constant :CALL_TYPE_TO_ABI
|
||||
|
||||
def self.call_type_to_abi(call_type)
|
||||
CALL_TYPE_TO_ABI[call_type]
|
||||
end
|
||||
private_class_method :call_type_to_abi
|
||||
|
||||
class FiddleClosureCFunc < Fiddle::Closure
|
||||
def initialize ctype, arg, abi, name
|
||||
@name = name
|
||||
super(ctype, arg, abi)
|
||||
end
|
||||
def name
|
||||
@name
|
||||
end
|
||||
end
|
||||
private_constant :FiddleClosureCFunc
|
||||
|
||||
def self.class_fiddle_closure_cfunc
|
||||
FiddleClosureCFunc
|
||||
end
|
||||
private_class_method :class_fiddle_closure_cfunc
|
||||
end
|
||||
|
||||
def initialize cfunc, argtypes, abi = nil, &block
|
||||
if DL.fiddle?
|
||||
abi ||= Fiddle::Function::DEFAULT
|
||||
abi ||= CALL_TYPE_TO_ABI[(cfunc.calltype rescue nil)]
|
||||
if block_given?
|
||||
@cfunc = Class.new(Fiddle::Closure) {
|
||||
@cfunc = Class.new(FiddleClosureCFunc) {
|
||||
define_method(:call, block)
|
||||
}.new(cfunc.ctype, argtypes)
|
||||
}.new(cfunc.ctype, argtypes, abi, cfunc.name)
|
||||
else
|
||||
@cfunc = cfunc
|
||||
end
|
||||
|
@ -76,16 +108,16 @@ module DL
|
|||
|
||||
def bind(&block)
|
||||
if DL.fiddle?
|
||||
@cfunc = Class.new(Fiddle::Closure) {
|
||||
def initialize ctype, args, block
|
||||
super(ctype, args)
|
||||
@cfunc = Class.new(FiddleClosureCFunc) {
|
||||
def initialize ctype, args, abi, name, block
|
||||
super(ctype, args, abi, name)
|
||||
@block = block
|
||||
end
|
||||
|
||||
def call *args
|
||||
@block.call(*args)
|
||||
end
|
||||
}.new(@cfunc.ctype, @args, block)
|
||||
}.new(@cfunc.ctype, @args, abi, name, block)
|
||||
else
|
||||
if( !block )
|
||||
raise(RuntimeError, "block must be given.")
|
||||
|
|
|
@ -243,11 +243,13 @@ module DL
|
|||
|
||||
def bind_function(name, ctype, argtype, call_type = nil, &block)
|
||||
if DL.fiddle?
|
||||
closure = Class.new(Fiddle::Closure) {
|
||||
klass = Function.instance_eval { class_fiddle_closure_cfunc }
|
||||
abi = Function.instance_eval { call_type_to_abi(call_type) }
|
||||
closure = Class.new(klass) {
|
||||
define_method(:call, block)
|
||||
}.new(ctype, argtype)
|
||||
}.new(ctype, argtype, abi, name)
|
||||
|
||||
Function.new(closure, argtype)
|
||||
Function.new(closure, argtype, abi)
|
||||
else
|
||||
f = Function.new(CFunc.new(0, ctype, name, call_type || :cdecl), argtype)
|
||||
f.bind(&block)
|
||||
|
|
|
@ -9,6 +9,12 @@ module DL
|
|||
assert_equal 'strcpy', f.name
|
||||
end
|
||||
|
||||
def test_name_with_block
|
||||
cb = Function.new(CFunc.new(0, TYPE_INT, '<callback>qsort'),
|
||||
[TYPE_VOIDP, TYPE_VOIDP]){|x,y| CPtr.new(x)[0] <=> CPtr.new(y)[0]}
|
||||
assert_equal('<callback>qsort', cb.name)
|
||||
end
|
||||
|
||||
def test_to_i
|
||||
cfunc = CFunc.new(@libc['strcpy'], TYPE_VOIDP, 'strcpy')
|
||||
f = Function.new(cfunc, [TYPE_VOIDP, TYPE_VOIDP])
|
||||
|
|
Loading…
Add table
Reference in a new issue