Created
March 8, 2017 04:55
-
-
Save shyouhei/9e7df99afdbd27293e1d4b3ec72f0ca3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Index: include/ruby/ruby.h | |
=================================================================== | |
--- include/ruby/ruby.h (revision 57788) | |
+++ include/ruby/ruby.h (revision 57807) | |
@@ -1504,6 +1504,17 @@ | |
} | |
#endif | |
+static inline int | |
+rb_long_is_fixable_p(long v) | |
+{ | |
+#ifdef HAVE_BUILTIN___BUILTIN_ADD_OVERFLOW | |
+ SIGNED_VALUE w; | |
+ return! __builtin_add_overflow(v, v, &w); | |
+#else | |
+ return RB_FIXABLE(v); | |
+#endif | |
+} | |
+ | |
#if SIZEOF_INT < SIZEOF_LONG | |
# define RB_INT2NUM(v) RB_INT2FIX((int)(v)) | |
# define RB_UINT2NUM(v) RB_LONG2FIX((unsigned int)(v)) | |
@@ -1511,7 +1522,7 @@ | |
static inline VALUE | |
rb_int2num_inline(int v) | |
{ | |
- if (RB_FIXABLE(v)) | |
+ if (rb_long_is_fixable_p(v)) | |
return RB_INT2FIX(v); | |
else | |
return rb_int2big(v); | |
@@ -1534,7 +1545,7 @@ | |
static inline VALUE | |
rb_long2num_inline(long v) | |
{ | |
- if (RB_FIXABLE(v)) | |
+ if (rb_long_is_fixable_p(v)) | |
return RB_LONG2FIX(v); | |
else | |
return rb_int2big(v); | |
Index: internal.h | |
=================================================================== | |
--- internal.h (revision 57788) | |
+++ internal.h (revision 57807) | |
@@ -1383,6 +1383,17 @@ | |
#define rb_float_value(v) rb_float_value_inline(v) | |
#define rb_float_new(d) rb_float_new_inline(d) | |
+static inline VALUE | |
+rb_dbl2ival(double d) | |
+{ | |
+ if (RB_FIXABLE(d)) { | |
+ return LONG2FIX((long)d); | |
+ } | |
+ else { | |
+ return rb_dbl2big(d); | |
+ } | |
+} | |
+ | |
/* object.c */ | |
void rb_obj_copy_ivar(VALUE dest, VALUE obj); | |
CONSTFUNC(VALUE rb_obj_equal(VALUE obj1, VALUE obj2)); | |
Index: bignum.c | |
=================================================================== | |
--- bignum.c (revision 57788) | |
+++ bignum.c (revision 57807) | |
@@ -3184,15 +3184,13 @@ | |
VALUE | |
rb_uint2inum(VALUE n) | |
{ | |
- if (POSFIXABLE(n)) return LONG2FIX(n); | |
- return rb_uint2big(n); | |
+ return ULONG2NUM(n); | |
} | |
VALUE | |
rb_int2inum(SIGNED_VALUE n) | |
{ | |
- if (FIXABLE(n)) return LONG2FIX(n); | |
- return rb_int2big(n); | |
+ return LONG2NUM(n); | |
} | |
void | |
Index: numeric.c | |
=================================================================== | |
--- numeric.c (revision 57788) | |
+++ numeric.c (revision 57807) | |
@@ -1279,10 +1279,7 @@ | |
static VALUE | |
dbl2ival(double d) | |
{ | |
- if (FIXABLE(d)) { | |
- return LONG2FIX((long)d); | |
- } | |
- return rb_dbl2big(d); | |
+ return rb_dbl2ival(d); | |
} | |
/* | |
@@ -1967,7 +1964,6 @@ | |
flo_floor(int argc, VALUE *argv, VALUE num) | |
{ | |
double number, f; | |
- long val; | |
int ndigits = 0; | |
if (rb_check_arity(argc, 0, 1)) { | |
@@ -1984,11 +1980,7 @@ | |
return DBL2NUM(f); | |
} | |
f = floor(number); | |
- if (!FIXABLE(f)) { | |
- return rb_dbl2big(f); | |
- } | |
- val = (long)f; | |
- return LONG2FIX(val); | |
+ return dbl2ival(f); | |
} | |
/* | |
@@ -2327,16 +2319,11 @@ | |
flo_to_i(VALUE num) | |
{ | |
double f = RFLOAT_VALUE(num); | |
- long val; | |
if (f > 0.0) f = floor(f); | |
if (f < 0.0) f = ceil(f); | |
- if (!FIXABLE(f)) { | |
- return rb_dbl2big(f); | |
- } | |
- val = (long)f; | |
- return LONG2FIX(val); | |
+ return dbl2ival(f); | |
} | |
/* | |
@@ -3021,12 +3008,15 @@ | |
{ | |
long v; | |
- if (FIXNUM_P(val)) return val; | |
- | |
- v = rb_num2long(val); | |
- if (!FIXABLE(v)) | |
+ if (FIXNUM_P(val)) { | |
+ return val; | |
+ } | |
+ else if (rb_long_is_fixable_p(v = rb_num2long(val))) { | |
+ return LONG2FIX(v); | |
+ } | |
+ else { | |
rb_raise(rb_eRangeError, "integer %ld out of range of fixnum", v); | |
- return LONG2FIX(v); | |
+ } | |
} | |
#if HAVE_LONG_LONG | |
Index: compile.c | |
=================================================================== | |
--- compile.c (revision 57788) | |
+++ compile.c (revision 57807) | |
@@ -3190,7 +3190,7 @@ | |
double ival; | |
if (RB_TYPE_P(v, T_FLOAT) && | |
modf(RFLOAT_VALUE(v), &ival) == 0.0) { | |
- return FIXABLE(ival) ? LONG2FIX((long)ival) : rb_dbl2big(ival); | |
+ return rb_dbl2ival(ival); | |
} | |
if (SYMBOL_P(v) || rb_obj_is_kind_of(v, rb_cNumeric)) { | |
return v; | |
Index: insns.def | |
=================================================================== | |
--- insns.def (revision 57788) | |
+++ insns.def (revision 57807) | |
@@ -1345,7 +1345,7 @@ | |
if (RB_FLOAT_TYPE_P(key)) { | |
double kval = RFLOAT_VALUE(key); | |
if (!isinf(kval) && modf(kval, &kval) == 0.0) { | |
- key = FIXABLE(kval) ? LONG2FIX((long)kval) : rb_dbl2big(kval); | |
+ key = rb_dbl2ival(kval); | |
} | |
} | |
if (st_lookup(RHASH_TBL_RAW(hash), key, &val)) { | |
Index: object.c | |
=================================================================== | |
--- object.c (revision 57788) | |
+++ object.c (revision 57807) | |
@@ -2747,11 +2747,8 @@ | |
VALUE tmp; | |
if (RB_FLOAT_TYPE_P(val)) { | |
- double f; | |
if (base != 0) goto arg_error; | |
- f = RFLOAT_VALUE(val); | |
- if (FIXABLE(f)) return LONG2FIX((long)f); | |
- return rb_dbl2big(f); | |
+ return rb_dbl2ival(RFLOAT_VALUE(val)); | |
} | |
else if (RB_INTEGER_TYPE_P(val)) { | |
if (base != 0) goto arg_error; | |
Index: sprintf.c | |
=================================================================== | |
--- sprintf.c (revision 57788) | |
+++ sprintf.c (revision 57807) | |
@@ -832,11 +832,7 @@ | |
bin_retry: | |
switch (TYPE(val)) { | |
case T_FLOAT: | |
- if (FIXABLE(RFLOAT_VALUE(val))) { | |
- val = LONG2FIX((long)RFLOAT_VALUE(val)); | |
- goto bin_retry; | |
- } | |
- val = rb_dbl2big(RFLOAT_VALUE(val)); | |
+ val = rb_dbl2ival(RFLOAT_VALUE(val)); | |
if (FIXNUM_P(val)) goto bin_retry; | |
bignum = 1; | |
break; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment