Skip to content

Instantly share code, notes, and snippets.

@shyouhei
Created March 8, 2017 04:55
Show Gist options
  • Save shyouhei/9e7df99afdbd27293e1d4b3ec72f0ca3 to your computer and use it in GitHub Desktop.
Save shyouhei/9e7df99afdbd27293e1d4b3ec72f0ca3 to your computer and use it in GitHub Desktop.
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