From: Naohisa Goto Date: 2009-08-22T00:21:47+09:00 Subject: [ruby-dev:39152] [Bug #1977] test failed in test_isdigit in test/dl/test_func.rb on sparc-solaris-2.10 (64bit) Bug #1977: test failed in test_isdigit in test/dl/test_func.rb on sparc-solaris-2.10 (64bit) http://redmine.ruby-lang.org/issues/show/1977 起票者: Naohisa Goto ステータス: Open, 優先度: Normal ruby -v: ruby 1.9.2dev (2009-08-19) [sparc-solaris2.10] sparc-solaris-2.10 にて64ビットコンパイルした場合、Bug #1967 ([ruby-dev:39146])のパッチを適用した後では、以下の2つのdl関連 のテストが失敗(Failure)します。 1) Failure: test_isdigit(DL::TestFunc) [/XXX/test/dl/test_func.rb:21]: Failed assertion, no message given. 2) Failure: test_isdigit(DL::TestImport) [/XXX/test/dl/test_import.rb:126]: Failed assertion, no message given. Solaris付属のシステムコール追跡コマンドtrussを使って、 $ truss -t '!all' -u 'libc:isdigit' /XXX/trunk-24578/bin/testrb test/dl -v のような感じで、isdigit関数の呼び出しを追跡したところ、 (前略) DL::TestFunc#test_isdigit: /1@1: -> libc:isdigit(0x3100000000, 0xc, 0xffffffffffffffff, 0xfffffffffffffff8) /1@1: <- libc:isdigit() = 0 /1@1: -> libc:isdigit(0x3200000000, 0xc, 0xffffffffffffffff, 0xfffffffffffffff8) /1@1: <- libc:isdigit() = 0 /1@1: -> libc:isdigit(0x7200000000, 0xc, 0xffffffffffffffff, 0xfffffffffffffff8) /1@1: <- libc:isdigit() = 0 0.01 s: F (中略) DL::TestImport#test_isdigit: /1@1: -> libc:isdigit(0x3100000000, 0xc, 0xffffffffffffffff, 0xfffffffffffffff8) /1@1: <- libc:isdigit() = 0 /1@1: -> libc:isdigit(0x3200000000, 0xc, 0xffffffffffffffff, 0xfffffffffffffff8) /1@1: <- libc:isdigit() = 0 /1@1: -> libc:isdigit(0x7200000000, 0xc, 0xffffffffffffffff, 0xfffffffffffffff8) /1@1: <- libc:isdigit() = 0 0.00 s: F (後略) 1番目の引数は、本来 0x31, 0x32, 0x72 といった数であるべきところが、 0x3100000000, 0x3200000000, 0x7200000000 になってしまっています。 どうやら、sparc 環境では、引数のint は long に符号拡張されるようです。 (参考文献: http://sdc.sun.co.jp/solaris/tools/private/amd64_migration.html ) 標準関数 int putchar(char) にて確認したところ、char も同様に long に拡張されるので、short もおそらく同様だと思います。 float が double に拡張されるかどうかは確認できていません。 また、sparc上のLinuxなど、Solaris以外ではどうなのかは未確認です。 sparcの場合だけ特別な PACK_MAP と SIZE_MAP を持つようにしたパッチを 以下に添付します。このパッチを当てると dl のテストはすべて成功します。 (注:差分を小さくするためインデントが少々おかしくなっています。) Index: ext/dl/lib/dl/stack.rb =================================================================== --- ext/dl/lib/dl/stack.rb (revision 24578) +++ ext/dl/lib/dl/stack.rb (working copy) @@ -61,6 +61,36 @@ TYPE_DOUBLE => ALIGN_DOUBLE, } + case RUBY_PLATFORM + + when /sparc/i + PACK_MAP = { + TYPE_VOIDP => ((SIZEOF_VOIDP == SIZEOF_LONG_LONG)? "q" : "l!"), + TYPE_CHAR => "l!", + TYPE_SHORT => "l!", + TYPE_INT => "l!", + TYPE_LONG => "l!", + TYPE_FLOAT => "f", + TYPE_DOUBLE => "d", + } + + SIZE_MAP = { + TYPE_VOIDP => SIZEOF_VOIDP, + TYPE_CHAR => SIZEOF_LONG, + TYPE_SHORT => SIZEOF_LONG, + TYPE_INT => SIZEOF_LONG, + TYPE_LONG => SIZEOF_LONG, + TYPE_FLOAT => SIZEOF_FLOAT, + TYPE_DOUBLE => SIZEOF_DOUBLE, + } + if defined?(TYPE_LONG_LONG) + ALIGN_MAP[TYPE_LONG_LONG] = ALIGN_LONG_LONG + PACK_MAP[TYPE_LONG_LONG] = "q" + SIZE_MAP[TYPE_LONG_LONG] = SIZEOF_LONG_LONG + end + + else + PACK_MAP = { TYPE_VOIDP => ((SIZEOF_VOIDP == SIZEOF_LONG_LONG)? "q" : "l!"), TYPE_CHAR => "c", @@ -86,6 +116,8 @@ SIZE_MAP[TYPE_LONG_LONG] = SIZEOF_LONG_LONG end + end + def parse_types(types) @types = types @template = "" ---------------------------------------- http://redmine.ruby-lang.org