From: Takehiro Kubo Date: 2008-12-30T01:27:00+09:00 Subject: [ruby-core:20974] [Bug #948] dl: cannot pass double value correctly on all x86_64 systems Bug #948: dl: cannot pass double value correctly on all x86_64 systems http://redmine.ruby-lang.org/issues/show/948 Author: Takehiro Kubo Status: Open, Priority: Normal ext/dl/test/test_dl2.rb doesn't fail on x86_64 linux. But it is by chance. It fails just by changing as follows. --- ext/dl/test/test_dl2.rb (revision 21182) +++ ext/dl/test/test_dl2.rb (working copy) @@ -34,8 +34,8 @@ def test_sin() cfunc = CFunc.new(@libm['sin'], TYPE_DOUBLE, 'sin') - x = cfunc.call([3.14/2].pack("d").unpack("l!*")) - assert_equal(x, Math.sin(3.14/2)) + x = cfunc.call([1.57].pack("d").unpack("l!*")) + assert_equal(x, Math.sin(1.57)) cfunc = CFunc.new(@libm['sin'], TYPE_DOUBLE, 'sin') x = cfunc.call([-3.14/2].pack("d").unpack("l!*")) dl passes function arguments as long types. But on x86_64 linux, the first double value is passed by XMM0 register and the first long value is by RDI. sin() expects that the argument is passed by XMM0. But dl passes it by RDI. The test had passed because calculating 3.14/2 set XMM0 register and the value had not been changed until cfunc.call was called. sin() got the argument by XMM0 which happened to be 3.14/2. I have tested this on x86_64 linux. But I guess it will fail on all x86_64 systems. See: http://en.wikipedia.org/wiki/X86_calling_conventions "Microsoft x64 calling convention" and "AMD64 ABI convention" I guess it is extremely hard to fix this. ---------------------------------------- http://redmine.ruby-lang.org