mirror of
https://github.com/ruby/ruby.git
synced 2025-09-17 01:23:57 +02:00
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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_0_0@40602 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
b6f0a306a6
commit
555035a349
9 changed files with 108 additions and 56 deletions
24
ChangeLog
24
ChangeLog
|
@ -1,3 +1,27 @@
|
||||||
|
Wed May 8 01:18:41 2013 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* 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@ruby-lang.org>
|
Tue May 7 20:13:12 2013 CHIKANAGA Tomoyuki <nagachika@ruby-lang.org>
|
||||||
|
|
||||||
* test/ruby/test_thread.rb (invoke_rec): extend timeout 10 -> 50 sec,
|
* test/ruby/test_thread.rb (invoke_rec): extend timeout 10 -> 50 sec,
|
||||||
|
|
7
array.c
7
array.c
|
@ -5035,15 +5035,14 @@ rb_ary_product(int argc, VALUE *argv, VALUE ary)
|
||||||
else {
|
else {
|
||||||
/* Compute the length of the result array; return [] if any is empty */
|
/* Compute the length of the result array; return [] if any is empty */
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
long k = RARRAY_LEN(arrays[i]), l = resultlen;
|
long k = RARRAY_LEN(arrays[i]);
|
||||||
if (k == 0) {
|
if (k == 0) {
|
||||||
result = rb_ary_new2(0);
|
result = rb_ary_new2(0);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
resultlen *= k;
|
if (MUL_OVERFLOW_LONG_P(resultlen, k))
|
||||||
if (resultlen < k || resultlen < l || resultlen / k != l) {
|
|
||||||
rb_raise(rb_eRangeError, "too big to product");
|
rb_raise(rb_eRangeError, "too big to product");
|
||||||
}
|
resultlen *= k;
|
||||||
}
|
}
|
||||||
result = rb_ary_new2(resultlen);
|
result = rb_ary_new2(resultlen);
|
||||||
}
|
}
|
||||||
|
|
71
bignum.c
71
bignum.c
|
@ -309,13 +309,17 @@ VALUE
|
||||||
rb_int2big(SIGNED_VALUE n)
|
rb_int2big(SIGNED_VALUE n)
|
||||||
{
|
{
|
||||||
long neg = 0;
|
long neg = 0;
|
||||||
|
VALUE u;
|
||||||
VALUE big;
|
VALUE big;
|
||||||
|
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
n = -n;
|
u = 1 + (VALUE)(-(n + 1)); /* u = -n avoiding overflow */
|
||||||
neg = 1;
|
neg = 1;
|
||||||
}
|
}
|
||||||
big = rb_uint2big(n);
|
else {
|
||||||
|
u = n;
|
||||||
|
}
|
||||||
|
big = rb_uint2big(u);
|
||||||
if (neg) {
|
if (neg) {
|
||||||
RBIGNUM_SET_SIGN(big, 0);
|
RBIGNUM_SET_SIGN(big, 0);
|
||||||
}
|
}
|
||||||
|
@ -1222,12 +1226,15 @@ rb_big2ulong(VALUE x)
|
||||||
{
|
{
|
||||||
VALUE num = big2ulong(x, "unsigned long", TRUE);
|
VALUE num = big2ulong(x, "unsigned long", TRUE);
|
||||||
|
|
||||||
if (!RBIGNUM_SIGN(x)) {
|
if (RBIGNUM_POSITIVE_P(x)) {
|
||||||
unsigned long v = (unsigned long)(-(long)num);
|
return num;
|
||||||
|
}
|
||||||
if (v <= LONG_MAX)
|
else {
|
||||||
rb_raise(rb_eRangeError, "bignum out of range of unsigned long");
|
if (num <= LONG_MAX)
|
||||||
return (VALUE)v;
|
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;
|
return num;
|
||||||
}
|
}
|
||||||
|
@ -1237,12 +1244,18 @@ rb_big2long(VALUE x)
|
||||||
{
|
{
|
||||||
VALUE num = big2ulong(x, "long", TRUE);
|
VALUE num = big2ulong(x, "long", TRUE);
|
||||||
|
|
||||||
if ((long)num < 0 &&
|
if (RBIGNUM_POSITIVE_P(x)) {
|
||||||
(RBIGNUM_SIGN(x) || (long)num != LONG_MIN)) {
|
if (LONG_MAX < num)
|
||||||
rb_raise(rb_eRangeError, "bignum too big to convert into `long'");
|
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
|
#if HAVE_LONG_LONG
|
||||||
|
@ -1270,13 +1283,15 @@ rb_big2ull(VALUE x)
|
||||||
{
|
{
|
||||||
unsigned LONG_LONG num = big2ull(x, "unsigned long long");
|
unsigned LONG_LONG num = big2ull(x, "unsigned long long");
|
||||||
|
|
||||||
if (!RBIGNUM_SIGN(x)) {
|
if (RBIGNUM_POSITIVE_P(x)) {
|
||||||
LONG_LONG v = -(LONG_LONG)num;
|
return num;
|
||||||
|
}
|
||||||
/* FIXNUM_MIN-1 .. LLONG_MIN mapped into 0xbfffffffffffffff .. LONG_MAX+1 */
|
else {
|
||||||
if ((unsigned LONG_LONG)v <= LLONG_MAX)
|
if (num <= LLONG_MAX)
|
||||||
rb_raise(rb_eRangeError, "bignum out of range of unsigned long long");
|
return -(LONG_LONG)num;
|
||||||
return v;
|
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;
|
return num;
|
||||||
}
|
}
|
||||||
|
@ -1286,12 +1301,18 @@ rb_big2ll(VALUE x)
|
||||||
{
|
{
|
||||||
unsigned LONG_LONG num = big2ull(x, "long long");
|
unsigned LONG_LONG num = big2ull(x, "long long");
|
||||||
|
|
||||||
if ((LONG_LONG)num < 0 && (RBIGNUM_SIGN(x)
|
if (RBIGNUM_POSITIVE_P(x)) {
|
||||||
|| (LONG_LONG)num != LLONG_MIN)) {
|
if (LLONG_MAX < num)
|
||||||
rb_raise(rb_eRangeError, "bignum too big to convert into `long long'");
|
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 */
|
#endif /* HAVE_LONG_LONG */
|
||||||
|
|
13
insns.def
13
insns.def
|
@ -1418,16 +1418,13 @@ opt_mult
|
||||||
val = recv;
|
val = recv;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
volatile long c;
|
|
||||||
b = FIX2LONG(obj);
|
b = FIX2LONG(obj);
|
||||||
c = a * b;
|
if (MUL_OVERFLOW_FIXNUM_P(a, b)) {
|
||||||
|
|
||||||
if (FIXABLE(c) && c / a == b) {
|
|
||||||
val = LONG2FIX(c);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
val = rb_big_mul(rb_int2big(a), rb_int2big(b));
|
val = rb_big_mul(rb_int2big(a), rb_int2big(b));
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
val = LONG2FIX(a * b);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (FLONUM_2_P(recv, obj) &&
|
else if (FLONUM_2_P(recv, obj) &&
|
||||||
|
|
|
@ -19,6 +19,15 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
#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 {
|
struct rb_deprecated_classext_struct {
|
||||||
char conflict[sizeof(VALUE) * 3];
|
char conflict[sizeof(VALUE) * 3];
|
||||||
};
|
};
|
||||||
|
|
14
numeric.c
14
numeric.c
|
@ -2694,7 +2694,6 @@ fix_mul(VALUE x, VALUE y)
|
||||||
#if SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG
|
#if SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG
|
||||||
LONG_LONG d;
|
LONG_LONG d;
|
||||||
#else
|
#else
|
||||||
volatile long c;
|
|
||||||
VALUE r;
|
VALUE r;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -2708,13 +2707,11 @@ fix_mul(VALUE x, VALUE y)
|
||||||
#else
|
#else
|
||||||
if (FIT_SQRT_LONG(a) && FIT_SQRT_LONG(b))
|
if (FIT_SQRT_LONG(a) && FIT_SQRT_LONG(b))
|
||||||
return LONG2FIX(a*b);
|
return LONG2FIX(a*b);
|
||||||
c = a * b;
|
|
||||||
r = LONG2FIX(c);
|
|
||||||
|
|
||||||
if (a == 0) return x;
|
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));
|
r = rb_big_mul(rb_int2big(a), rb_int2big(b));
|
||||||
}
|
else
|
||||||
|
r = LONG2FIX(a * b);
|
||||||
return r;
|
return r;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -2936,11 +2933,10 @@ int_pow(long x, unsigned long y)
|
||||||
y >>= 1;
|
y >>= 1;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
volatile long xz = x * z;
|
if (MUL_OVERFLOW_FIXNUM_P(x, z)) {
|
||||||
if (!POSFIXABLE(xz) || xz / x != z) {
|
|
||||||
goto bignum;
|
goto bignum;
|
||||||
}
|
}
|
||||||
z = xz;
|
z = x * z;
|
||||||
}
|
}
|
||||||
} while (--y);
|
} while (--y);
|
||||||
if (neg) z = -z;
|
if (neg) z = -z;
|
||||||
|
|
|
@ -639,7 +639,6 @@ inline static VALUE
|
||||||
f_imul(long a, long b)
|
f_imul(long a, long b)
|
||||||
{
|
{
|
||||||
VALUE r;
|
VALUE r;
|
||||||
volatile long c;
|
|
||||||
|
|
||||||
if (a == 0 || b == 0)
|
if (a == 0 || b == 0)
|
||||||
return ZERO;
|
return ZERO;
|
||||||
|
@ -648,10 +647,10 @@ f_imul(long a, long b)
|
||||||
else if (b == 1)
|
else if (b == 1)
|
||||||
return LONG2NUM(a);
|
return LONG2NUM(a);
|
||||||
|
|
||||||
c = a * b;
|
if (MUL_OVERFLOW_LONG_P(a, b))
|
||||||
r = LONG2NUM(c);
|
|
||||||
if (NUM2LONG(r) != c || (c / a) != b)
|
|
||||||
r = rb_big_mul(rb_int2big(a), rb_int2big(b));
|
r = rb_big_mul(rb_int2big(a), rb_int2big(b));
|
||||||
|
else
|
||||||
|
r = LONG2NUM(a * b);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
13
thread.c
13
thread.c
|
@ -981,10 +981,17 @@ sleep_timeval(rb_thread_t *th, struct timeval tv, int spurious_check)
|
||||||
enum rb_thread_status prev_status = th->status;
|
enum rb_thread_status prev_status = th->status;
|
||||||
|
|
||||||
getclockofday(&to);
|
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) {
|
if ((to.tv_usec += tv.tv_usec) >= 1000000) {
|
||||||
to.tv_sec++;
|
if (to.tv_sec == TIMET_MAX)
|
||||||
to.tv_usec -= 1000000;
|
to.tv_usec = 999999;
|
||||||
|
else {
|
||||||
|
to.tv_sec++;
|
||||||
|
to.tv_usec -= 1000000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
th->status = THREAD_STOPPED;
|
th->status = THREAD_STOPPED;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
#define RUBY_VERSION "2.0.0"
|
#define RUBY_VERSION "2.0.0"
|
||||||
#define RUBY_RELEASE_DATE "2013-05-07"
|
#define RUBY_RELEASE_DATE "2013-05-08"
|
||||||
#define RUBY_PATCHLEVEL 186
|
#define RUBY_PATCHLEVEL 187
|
||||||
|
|
||||||
#define RUBY_RELEASE_YEAR 2013
|
#define RUBY_RELEASE_YEAR 2013
|
||||||
#define RUBY_RELEASE_MONTH 5
|
#define RUBY_RELEASE_MONTH 5
|
||||||
#define RUBY_RELEASE_DAY 7
|
#define RUBY_RELEASE_DAY 8
|
||||||
|
|
||||||
#include "ruby/version.h"
|
#include "ruby/version.h"
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue