summaryrefslogtreecommitdiff
path: root/ext/dl/lib/dl
diff options
context:
space:
mode:
authorngoto <ngoto@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-12-05 03:20:05 +0000
committerngoto <ngoto@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-12-05 03:20:05 +0000
commitf1841f43eb9d7ec45bcbee7f70abae77d999f76d (patch)
tree5bfae3093e806b84d48b05590ab886663ac93576 /ext/dl/lib/dl
parent342d2f2aa6037bd126c2247c6c6b9bf97f8c42bd (diff)
* 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
Diffstat (limited to 'ext/dl/lib/dl')
-rw-r--r--ext/dl/lib/dl/func.rb46
-rw-r--r--ext/dl/lib/dl/import.rb8
2 files changed, 44 insertions, 10 deletions
diff --git a/ext/dl/lib/dl/func.rb b/ext/dl/lib/dl/func.rb
index c5d569575c..fd92c119ac 100644
--- a/ext/dl/lib/dl/func.rb
+++ b/ext/dl/lib/dl/func.rb
@@ -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.")
diff --git a/ext/dl/lib/dl/import.rb b/ext/dl/lib/dl/import.rb
index 9005153624..6f157ccf28 100644
--- a/ext/dl/lib/dl/import.rb
+++ b/ext/dl/lib/dl/import.rb
@@ -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)