[前][次][番号順一覧][スレッド一覧]

ruby-changes:26145

From: ngoto <ko1@a...>
Date: Wed, 5 Dec 2012 12:20:16 +0900 (JST)
Subject: [ruby-changes:26145] ngoto:r38202 (trunk): * ext/dl/lib/dl/func.rb (DL::Function#initialize, DL::Function#bind):

ngoto	2012-12-05 12:20:05 +0900 (Wed, 05 Dec 2012)

  New Revision: 38202

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=38202

  Log:
    * 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.

  Modified files:
    trunk/ChangeLog
    trunk/ext/dl/lib/dl/func.rb
    trunk/ext/dl/lib/dl/import.rb
    trunk/test/dl/test_func.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 38201)
+++ ChangeLog	(revision 38202)
@@ -1,3 +1,16 @@
+Wed Dec  5 12:17:11 2012  Naohisa Goto  <ngotogenome@g...>
+
+	* 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@z...>
 
 	* doc/shell.rd, doc/shell.rd.ja: Removed stale doc files
Index: ext/dl/lib/dl/import.rb
===================================================================
--- ext/dl/lib/dl/import.rb	(revision 38201)
+++ ext/dl/lib/dl/import.rb	(revision 38202)
@@ -243,11 +243,13 @@
 
     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)
Index: ext/dl/lib/dl/func.rb
===================================================================
--- ext/dl/lib/dl/func.rb	(revision 38201)
+++ ext/dl/lib/dl/func.rb	(revision 38202)
@@ -11,13 +11,45 @@
     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 @@
 
     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.")
Index: test/dl/test_func.rb
===================================================================
--- test/dl/test_func.rb	(revision 38201)
+++ test/dl/test_func.rb	(revision 38202)
@@ -9,6 +9,12 @@
       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])

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]