From b386fe21eca01e03a5ca447792354632e549c94e Mon Sep 17 00:00:00 2001 From: tenderlove Date: Wed, 3 Feb 2010 01:23:48 +0000 Subject: Wed Feb 3 10:12:09 2010 Aaron Patterson * ext/dl/function.c: DL::Function now uses libffi * ext/dl/cfunc.c (rb_dl_set_last_error): set to non static so errors can be exposed. * ext/dl/closure.c: DL::Closure will now be used in place of ext/dl/callback/*. * ext/dl/dl.c: legacy callbacks removed in favor of libffi * ext/dl/dl_converions.(c,h): used for converting ruby types to FFI types. * ext/dl/callback/*: replaced by libffi callbacks. * ext/dl/lib/dl/callback.rb: Converting internal callbacks to use DL::Closure * ext/dl/lib/dl/closure.rb: Ruby parts of the new DL::Closure object * ext/dl/lib/dl/import.rb: More conversion to use DL::Closure object * ext/dl/lib/dl/value.rb (ruby2ffi): adding private method for DL::CPtr to ffi value conversion. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26545 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- test/dl/test_base.rb | 2 +- test/dl/test_closure.rb | 130 ++++++++++++++++++++++++++++++++++++++++++++++++ test/dl/test_dl2.rb | 12 +++-- test/dl/test_func.rb | 18 +++++++ 4 files changed, 156 insertions(+), 6 deletions(-) create mode 100644 test/dl/test_closure.rb (limited to 'test/dl') diff --git a/test/dl/test_base.rb b/test/dl/test_base.rb index 7eddbf8226..e67f0795d5 100644 --- a/test/dl/test_base.rb +++ b/test/dl/test_base.rb @@ -74,7 +74,7 @@ module DL end def assert_zero(actual) - assert(actual == 0) + assert_equal(0, actual) end def assert_negative(actual) diff --git a/test/dl/test_closure.rb b/test/dl/test_closure.rb new file mode 100644 index 0000000000..965d195df1 --- /dev/null +++ b/test/dl/test_closure.rb @@ -0,0 +1,130 @@ +require_relative 'test_base' +require 'dl/func' +require 'dl/closure' + +module DL + class TestClosure < Test::Unit::TestCase + class Returner < DL::Closure + attr_accessor :called + attr_accessor :called_with + def call *args + @called = true + @called_with = args + a = args.first + DL::CPtr === a ? a.to_i : a + end + end + + if defined?(TYPE_LONG_LONG) + def test_long_long + type = TYPE_LONG_LONG + addr = Returner.new(type, [type]) do |num| + called = true + called_with = num + end + func = DL::Function.new(addr, [type]) + assert_equal(9223372036854775807, func.call(9223372036854775807)) + end + end + + def test_with_abi + called = false + addr = DL::Closure::BlockCaller.new( + TYPE_INT, + [TYPE_INT], + DL::Function::DEFAULT + ) do |num| + called = true + num + end + func = DL::Function.new(addr, [TYPE_INT]) + func.call(50) + assert called + end + + def test_block_caller + called = false + called_with = nil + addr = DL::Closure::BlockCaller.new(TYPE_INT, [TYPE_INT]) do |num| + called = true + called_with = num + end + func = DL::Function.new(addr, [TYPE_INT]) + func.call(50) + assert called, 'function was called' + assert_equal 50, called_with + end + + def test_multival + adder = Class.new(DL::Closure) { + def call a, b + a + b + end + }.new(TYPE_INT, [TYPE_INT, TYPE_INT]) + + assert_equal [TYPE_INT, TYPE_INT], adder.args + func = DL::Function.new(adder, adder.args) + assert_equal 70, func.call(50, 20) + end + + def test_call + closure = Class.new(DL::Closure) { + attr_accessor :called_with + def call num + @called_with = num + end + }.new(TYPE_INT, [TYPE_INT]) + + func = DL::Function.new(closure, [TYPE_INT]) + func.call(50) + + assert_equal 50, closure.called_with + end + + def test_return_value + closure = Returner.new(TYPE_INT, [TYPE_INT]) + + func = DL::Function.new(closure, [TYPE_INT]) + assert_equal 50, func.call(50) + end + + def test_float + closure = Returner.new(TYPE_FLOAT, [TYPE_FLOAT]) + func = DL::Function.new(closure, [TYPE_FLOAT]) + assert_equal 2.0, func.call(2.0) + end + + def test_char + closure = Returner.new(TYPE_CHAR, [TYPE_CHAR]) + func = DL::Function.new(closure, [TYPE_CHAR]) + assert_equal 60, func.call(60) + end + + def test_long + closure = Returner.new(TYPE_LONG, [TYPE_LONG]) + func = DL::Function.new(closure, [TYPE_LONG]) + assert_equal 60, func.call(60) + end + + def test_double + closure = Returner.new(TYPE_DOUBLE, [TYPE_DOUBLE]) + func = DL::Function.new(closure, [TYPE_DOUBLE]) + assert_equal 60, func.call(60) + end + + def test_voidp + closure = Returner.new(TYPE_VOIDP, [TYPE_VOIDP]) + func = DL::Function.new(closure, [TYPE_VOIDP]) + + voidp = CPtr['foo'] + assert_equal voidp, func.call(voidp) + end + + def test_void + closure = Returner.new(TYPE_VOID, [TYPE_VOID]) + func = DL::Function.new(closure, [TYPE_VOID]) + func.call() + assert closure.called + end + end +end diff --git a/test/dl/test_dl2.rb b/test/dl/test_dl2.rb index ac1414920f..7b47fc8024 100644 --- a/test/dl/test_dl2.rb +++ b/test/dl/test_dl2.rb @@ -88,14 +88,16 @@ class TestDL < TestBase assert_in_delta(-0.1, x) end - def test_sin() + def test_sin pi_2 = Math::PI/2 - cfunc = CFunc.new(@libm['sin'], TYPE_DOUBLE, 'sin') - x = cfunc.call([pi_2].pack("d").unpack("l!*")) + cfunc = Function.new(CFunc.new(@libm['sin'], TYPE_DOUBLE, 'sin'), + [TYPE_DOUBLE]) + x = cfunc.call(pi_2) assert_equal(Math.sin(pi_2), x) - cfunc = CFunc.new(@libm['sin'], TYPE_DOUBLE, 'sin') - x = cfunc.call([-pi_2].pack("d").unpack("l!*")) + cfunc = Function.new(CFunc.new(@libm['sin'], TYPE_DOUBLE, 'sin'), + [TYPE_DOUBLE]) + x = cfunc.call(-pi_2) assert_equal(Math.sin(-pi_2), x) end diff --git a/test/dl/test_func.rb b/test/dl/test_func.rb index 5503f350c8..3900af3d5f 100644 --- a/test/dl/test_func.rb +++ b/test/dl/test_func.rb @@ -15,6 +15,24 @@ module DL assert_equal cfunc.to_i, f.to_i end + def test_random + f = Function.new(CFunc.new(@libc['srand'], TYPE_VOID, 'srand'), + [-TYPE_LONG]) + assert_nil f.call(10) + end + + def test_sinf + f = Function.new(CFunc.new(@libm['sinf'], TYPE_FLOAT, 'sinf'), + [TYPE_FLOAT]) + assert_in_delta 1.0, f.call(90 * Math::PI / 180), 0.0001 + end + + def test_sin + f = Function.new(CFunc.new(@libm['sin'], TYPE_DOUBLE, 'sin'), + [TYPE_DOUBLE]) + assert_in_delta 1.0, f.call(90 * Math::PI / 180), 0.0001 + end + def test_strcpy() f = Function.new(CFunc.new(@libc['strcpy'], TYPE_VOIDP, 'strcpy'), [TYPE_VOIDP, TYPE_VOIDP]) -- cgit v1.2.3