[前][次][番号順一覧][スレッド一覧]

ruby-changes:28550

From: nagachika <ko1@a...>
Date: Wed, 8 May 2013 01:49:15 +0900 (JST)
Subject: [ruby-changes:28550] nagachika:r40602 (ruby_2_0_0): merge revision(s) 40208: [Backport #8380]

nagachika	2013-05-08 01:49:01 +0900 (Wed, 08 May 2013)

  New Revision: 40602

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=40602

  Log:
    merge revision(s) 40208: [Backport #8380]
    
    * internal.h (MUL_OVERFLOW_SIGNED_INTEGER_P): New macro.
      (MUL_OVERFLOW_FIXNUM_P): Ditto.
      (MUL_OVERFLOW_LONG_P): Ditto.
    
    * array.c (rb_ary_product): Don't overflow on signed integer
      multiplication.
    
    * numeric.c (fix_mul): Ditto.
      (int_pow): Ditto.
    
    * rational.c (f_imul): Ditto.
    
    * insns.def (opt_mult): Ditto.
    
    * thread.c (sleep_timeval): Don't overflow on signed integer addition.
    
    * bignum.c (rb_int2big): Don't overflow on signed integer negation.
      (rb_big2ulong): Ditto.
      (rb_big2long): Ditto.
      (rb_big2ull): Ditto.
      (rb_big2ll): Ditto.

  Modified directories:
    branches/ruby_2_0_0/
  Modified files:
    branches/ruby_2_0_0/ChangeLog
    branches/ruby_2_0_0/array.c
    branches/ruby_2_0_0/bignum.c
    branches/ruby_2_0_0/insns.def
    branches/ruby_2_0_0/internal.h
    branches/ruby_2_0_0/numeric.c
    branches/ruby_2_0_0/rational.c
    branches/ruby_2_0_0/thread.c
    branches/ruby_2_0_0/version.h

Index: ruby_2_0_0/array.c
===================================================================
--- ruby_2_0_0/array.c	(revision 40601)
+++ ruby_2_0_0/array.c	(revision 40602)
@@ -5035,15 +5035,14 @@ rb_ary_product(int argc, VALUE *argv, VA https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/array.c#L5035
     else {
 	/* Compute the length of the result array; return [] if any is empty */
 	for (i = 0; i < n; i++) {
-	    long k = RARRAY_LEN(arrays[i]), l = resultlen;
+	    long k = RARRAY_LEN(arrays[i]);
 	    if (k == 0) {
 		result = rb_ary_new2(0);
 		goto done;
 	    }
-	    resultlen *= k;
-	    if (resultlen < k || resultlen < l || resultlen / k != l) {
+            if (MUL_OVERFLOW_LONG_P(resultlen, k))
 		rb_raise(rb_eRangeError, "too big to product");
-	    }
+	    resultlen *= k;
 	}
 	result = rb_ary_new2(resultlen);
     }
Index: ruby_2_0_0/ChangeLog
===================================================================
--- ruby_2_0_0/ChangeLog	(revision 40601)
+++ ruby_2_0_0/ChangeLog	(revision 40602)
@@ -1,3 +1,27 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/ChangeLog#L1
+Wed May  8 01:18:41 2013  Tanaka Akira  <akr@f...>
+
+	* internal.h (MUL_OVERFLOW_SIGNED_INTEGER_P): New macro.
+	  (MUL_OVERFLOW_FIXNUM_P): Ditto.
+	  (MUL_OVERFLOW_LONG_P): Ditto.
+
+	* array.c (rb_ary_product): Don't overflow on signed integer
+	  multiplication.
+
+	* numeric.c (fix_mul): Ditto.
+	  (int_pow): Ditto.
+
+	* rational.c (f_imul): Ditto.
+
+	* insns.def (opt_mult): Ditto.
+
+	* thread.c (sleep_timeval): Don't overflow on signed integer addition.
+
+	* bignum.c (rb_int2big): Don't overflow on signed integer negation.
+	  (rb_big2ulong): Ditto.
+	  (rb_big2long): Ditto.
+	  (rb_big2ull): Ditto.
+	  (rb_big2ll): Ditto.
+
 Tue May  7 20:13:12 2013  CHIKANAGA Tomoyuki  <nagachika@r...>
 
 	* test/ruby/test_thread.rb (invoke_rec): extend timeout 10 -> 50 sec,
Index: ruby_2_0_0/insns.def
===================================================================
--- ruby_2_0_0/insns.def	(revision 40601)
+++ ruby_2_0_0/insns.def	(revision 40602)
@@ -1418,16 +1418,13 @@ opt_mult https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/insns.def#L1418
 	    val = recv;
 	}
 	else {
-	    volatile long c;
 	    b = FIX2LONG(obj);
-	    c = a * b;
-
-	    if (FIXABLE(c) && c / a == b) {
-		val = LONG2FIX(c);
-	    }
-	    else {
+            if (MUL_OVERFLOW_FIXNUM_P(a, b)) {
 		val = rb_big_mul(rb_int2big(a), rb_int2big(b));
-	    }
+            }
+            else {
+		val = LONG2FIX(a * b);
+            }
 	}
     }
     else if (FLONUM_2_P(recv, obj) &&
Index: ruby_2_0_0/thread.c
===================================================================
--- ruby_2_0_0/thread.c	(revision 40601)
+++ ruby_2_0_0/thread.c	(revision 40602)
@@ -981,10 +981,17 @@ sleep_timeval(rb_thread_t *th, struct ti https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/thread.c#L981
     enum rb_thread_status prev_status = th->status;
 
     getclockofday(&to);
-    to.tv_sec += tv.tv_sec;
+    if (TIMET_MAX - tv.tv_sec < to.tv_sec)
+        to.tv_sec = TIMET_MAX;
+    else
+        to.tv_sec += tv.tv_sec;
     if ((to.tv_usec += tv.tv_usec) >= 1000000) {
-	to.tv_sec++;
-	to.tv_usec -= 1000000;
+        if (to.tv_sec == TIMET_MAX)
+            to.tv_usec = 999999;
+        else {
+            to.tv_sec++;
+            to.tv_usec -= 1000000;
+        }
     }
 
     th->status = THREAD_STOPPED;
Index: ruby_2_0_0/numeric.c
===================================================================
--- ruby_2_0_0/numeric.c	(revision 40601)
+++ ruby_2_0_0/numeric.c	(revision 40602)
@@ -2694,7 +2694,6 @@ fix_mul(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/numeric.c#L2694
 #if SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG
 	LONG_LONG d;
 #else
-	volatile long c;
 	VALUE r;
 #endif
 
@@ -2708,13 +2707,11 @@ fix_mul(VALUE x, VALUE y) https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/numeric.c#L2707
 #else
 	if (FIT_SQRT_LONG(a) && FIT_SQRT_LONG(b))
 	    return LONG2FIX(a*b);
-	c = a * b;
-	r = LONG2FIX(c);
-
 	if (a == 0) return x;
-	if (FIX2LONG(r) != c || c/a != b) {
+        if (MUL_OVERFLOW_FIXNUM_P(a, b))
 	    r = rb_big_mul(rb_int2big(a), rb_int2big(b));
-	}
+        else
+            r = LONG2FIX(a * b);
 	return r;
 #endif
     }
@@ -2936,11 +2933,10 @@ int_pow(long x, unsigned long y) https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/numeric.c#L2933
 	    y >>= 1;
 	}
 	{
-	    volatile long xz = x * z;
-	    if (!POSFIXABLE(xz) || xz / x != z) {
+            if (MUL_OVERFLOW_FIXNUM_P(x, z)) {
 		goto bignum;
 	    }
-	    z = xz;
+	    z = x * z;
 	}
     } while (--y);
     if (neg) z = -z;
Index: ruby_2_0_0/internal.h
===================================================================
--- ruby_2_0_0/internal.h	(revision 40601)
+++ ruby_2_0_0/internal.h	(revision 40602)
@@ -19,6 +19,15 @@ extern "C" { https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/internal.h#L19
 #endif
 #endif
 
+#define MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, min, max) ( \
+    (a) == 0 ? 0 : \
+    (a) == -1 ? (b) < -(max) : \
+    (a) > 0 ? \
+      ((b) > 0 ? (max) / (a) < (b) : (min) / (a) > (b)) : \
+      ((b) > 0 ? (min) / (a) < (b) : (max) / (a) > (b)))
+#define MUL_OVERFLOW_FIXNUM_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, FIXNUM_MIN, FIXNUM_MAX)
+#define MUL_OVERFLOW_LONG_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, LONG_MIN, LONG_MAX)
+
 struct rb_deprecated_classext_struct {
     char conflict[sizeof(VALUE) * 3];
 };
Index: ruby_2_0_0/version.h
===================================================================
--- ruby_2_0_0/version.h	(revision 40601)
+++ ruby_2_0_0/version.h	(revision 40602)
@@ -1,10 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/version.h#L1
 #define RUBY_VERSION "2.0.0"
-#define RUBY_RELEASE_DATE "2013-05-07"
-#define RUBY_PATCHLEVEL 186
+#define RUBY_RELEASE_DATE "2013-05-08"
+#define RUBY_PATCHLEVEL 187
 
 #define RUBY_RELEASE_YEAR 2013
 #define RUBY_RELEASE_MONTH 5
-#define RUBY_RELEASE_DAY 7
+#define RUBY_RELEASE_DAY 8
 
 #include "ruby/version.h"
 
Index: ruby_2_0_0/bignum.c
===================================================================
--- ruby_2_0_0/bignum.c	(revision 40601)
+++ ruby_2_0_0/bignum.c	(revision 40602)
@@ -309,13 +309,17 @@ VALUE https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/bignum.c#L309
 rb_int2big(SIGNED_VALUE n)
 {
     long neg = 0;
+    VALUE u;
     VALUE big;
 
     if (n < 0) {
-	n = -n;
+        u = 1 + (VALUE)(-(n + 1)); /* u = -n avoiding overflow */
 	neg = 1;
     }
-    big = rb_uint2big(n);
+    else {
+        u = n;
+    }
+    big = rb_uint2big(u);
     if (neg) {
 	RBIGNUM_SET_SIGN(big, 0);
     }
@@ -1222,12 +1226,15 @@ rb_big2ulong(VALUE x) https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/bignum.c#L1226
 {
     VALUE num = big2ulong(x, "unsigned long", TRUE);
 
-    if (!RBIGNUM_SIGN(x)) {
-	unsigned long v = (unsigned long)(-(long)num);
-
-	if (v <= LONG_MAX)
-	    rb_raise(rb_eRangeError, "bignum out of range of unsigned long");
-	return (VALUE)v;
+    if (RBIGNUM_POSITIVE_P(x)) {
+        return num;
+    }
+    else {
+        if (num <= LONG_MAX)
+            return -(long)num;
+        if (num == 1+(unsigned long)(-(LONG_MIN+1)))
+            return LONG_MIN;
+        rb_raise(rb_eRangeError, "bignum out of range of unsigned long");
     }
     return num;
 }
@@ -1237,12 +1244,18 @@ rb_big2long(VALUE x) https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/bignum.c#L1244
 {
     VALUE num = big2ulong(x, "long", TRUE);
 
-    if ((long)num < 0 &&
-	(RBIGNUM_SIGN(x) || (long)num != LONG_MIN)) {
-	rb_raise(rb_eRangeError, "bignum too big to convert into `long'");
+    if (RBIGNUM_POSITIVE_P(x)) {
+        if (LONG_MAX < num)
+            rb_raise(rb_eRangeError, "bignum too big to convert into `long'");
+        return num;
+    }
+    else {
+        if (num <= LONG_MAX)
+            return -(long)num;
+        if (num == 1+(unsigned long)(-(LONG_MIN+1)))
+            return LONG_MIN;
+        rb_raise(rb_eRangeError, "bignum too big to convert into `long'");
     }
-    if (!RBIGNUM_SIGN(x)) return -(SIGNED_VALUE)num;
-    return num;
 }
 
 #if HAVE_LONG_LONG
@@ -1270,13 +1283,15 @@ rb_big2ull(VALUE x) https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/bignum.c#L1283
 {
     unsigned LONG_LONG num = big2ull(x, "unsigned long long");
 
-    if (!RBIGNUM_SIGN(x)) {
-	LONG_LONG v = -(LONG_LONG)num;
-
-	/* FIXNUM_MIN-1 .. LLONG_MIN mapped into 0xbfffffffffffffff .. LONG_MAX+1 */
-	if ((unsigned LONG_LONG)v <= LLONG_MAX)
-	    rb_raise(rb_eRangeError, "bignum out of range of unsigned long long");
-	return v;
+    if (RBIGNUM_POSITIVE_P(x)) {
+        return num;
+    }
+    else {
+        if (num <= LLONG_MAX)
+            return -(LONG_LONG)num;
+        if (num == 1+(unsigned LONG_LONG)(-(LLONG_MIN+1)))
+            return LLONG_MIN;
+        rb_raise(rb_eRangeError, "bignum out of range of unsigned long long");
     }
     return num;
 }
@@ -1286,12 +1301,18 @@ rb_big2ll(VALUE x) https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/bignum.c#L1301
 {
     unsigned LONG_LONG num = big2ull(x, "long long");
 
-    if ((LONG_LONG)num < 0 && (RBIGNUM_SIGN(x)
-			       || (LONG_LONG)num != LLONG_MIN)) {
-	rb_raise(rb_eRangeError, "bignum too big to convert into `long long'");
+    if (RBIGNUM_POSITIVE_P(x)) {
+        if (LLONG_MAX < num)
+            rb_raise(rb_eRangeError, "bignum too big to convert into `long long'");
+        return num;
+    }
+    else {
+        if (num <= LLONG_MAX)
+            return -(LONG_LONG)num;
+        if (num == 1+(unsigned LONG_LONG)(-(LLONG_MIN+1)))
+            return LLONG_MIN;
+        rb_raise(rb_eRangeError, "bignum too big to convert into `long long'");
     }
-    if (!RBIGNUM_SIGN(x)) return -(LONG_LONG)num;
-    return num;
 }
 
 #endif  /* HAVE_LONG_LONG */
Index: ruby_2_0_0/rational.c
===================================================================
--- ruby_2_0_0/rational.c	(revision 40601)
+++ ruby_2_0_0/rational.c	(revision 40602)
@@ -639,7 +639,6 @@ inline static VALUE https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/rational.c#L639
 f_imul(long a, long b)
 {
     VALUE r;
-    volatile long c;
 
     if (a == 0 || b == 0)
 	return ZERO;
@@ -648,10 +647,10 @@ f_imul(long a, long b) https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/rational.c#L647
     else if (b == 1)
 	return LONG2NUM(a);
 
-    c = a * b;
-    r = LONG2NUM(c);
-    if (NUM2LONG(r) != c || (c / a) != b)
+    if (MUL_OVERFLOW_LONG_P(a, b))
 	r = rb_big_mul(rb_int2big(a), rb_int2big(b));
+    else
+        r = LONG2NUM(a * b);
     return r;
 }
 

Property changes on: ruby_2_0_0
___________________________________________________________________
Modified: svn:mergeinfo
   Merged /trunk:r40208


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]