From: wanabe Date: 2008-05-11T15:15:23+09:00 Subject: [ruby-dev:34648] Bignum のメソッドからの bigzero_p ワナベと申します。 Ruby から Bignum インスタンスのメソッドが呼ばれた場合には bigzero_p ですべてのビットを見る必要はあまり無いように思います。 そこで、確実に Fixnum の範囲にないことを示すフラグで分岐するパッチを書きました。 試験的に to_s が呼ばれたときにだけ付加しています。 Index: include/ruby/ruby.h =================================================================== --- include/ruby/ruby.h (revision 16344) +++ include/ruby/ruby.h (working copy) @@ -610,9 +610,11 @@ #define RBIGNUM_POSITIVE_P(b) RBIGNUM_SIGN(b) #define RBIGNUM_NEGATIVE_P(b) (!RBIGNUM_SIGN(b)) -#define RBIGNUM_EMBED_FLAG FL_USER2 -#define RBIGNUM_EMBED_LEN_MASK (FL_USER5|FL_USER4|FL_USER3) -#define RBIGNUM_EMBED_LEN_SHIFT (FL_USHIFT+3) +#define RBIGNUM_UNFIXABLE_FLAG FL_USER2 + +#define RBIGNUM_EMBED_FLAG FL_USER3 +#define RBIGNUM_EMBED_LEN_MASK (FL_USER6|FL_USER5|FL_USER4) +#define RBIGNUM_EMBED_LEN_SHIFT (FL_USHIFT+4) #define RBIGNUM_LEN(b) \ ((RBASIC(b)->flags & RBIGNUM_EMBED_FLAG) ? \ (long)((RBASIC(b)->flags >> RBIGNUM_EMBED_LEN_SHIFT) & \ Index: bignum.c =================================================================== --- bignum.c (revision 16344) +++ bignum.c (working copy) @@ -44,6 +44,10 @@ bigzero_p(VALUE x) { long i; + + if (FL_TEST(x, RBIGNUM_UNFIXABLE_FLAG)) { + return 0; + } for (i = 0; i < RBIGNUM_LEN(x); ++i) { if (BDIGITS(x)[i]) return 0; } @@ -1000,6 +1004,7 @@ { int base; + FL_SET(x, RBIGNUM_UNFIXABLE_FLAG); if (argc == 0) base = 10; else { VALUE b; -- ワナベ