Commit 0acc9e13 authored by yangguo@chromium.org's avatar yangguo@chromium.org

Make sure double to int conversion is correct.

R=svenpanne@chromium.org
BUG=v8:2260
TEST=test-utils/Utils1

Review URL: https://chromiumcodereview.appspot.com/10820047

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12216 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent a448d424
...@@ -57,13 +57,21 @@ inline double SignedZero(bool negative) { ...@@ -57,13 +57,21 @@ inline double SignedZero(bool negative) {
} }
// The fast double-to-(unsigned-)int conversion routine does not guarantee
// rounding towards zero.
// For NaN and values outside the int range, return INT_MIN or INT_MAX.
inline int FastD2IChecked(double x) {
if (!(x >= INT_MIN)) return INT_MIN; // Negation to catch NaNs.
if (x > INT_MAX) return INT_MAX;
return static_cast<int>(x);
}
// The fast double-to-(unsigned-)int conversion routine does not guarantee // The fast double-to-(unsigned-)int conversion routine does not guarantee
// rounding towards zero. // rounding towards zero.
// The result is unspecified if x is infinite or NaN, or if the rounded // The result is unspecified if x is infinite or NaN, or if the rounded
// integer value is outside the range of type int. // integer value is outside the range of type int.
inline int FastD2I(double x) { inline int FastD2I(double x) {
// The static_cast convertion from double to int used to be slow, but
// as new benchmarks show, now it is much faster than lrint().
return static_cast<int>(x); return static_cast<int>(x);
} }
......
...@@ -800,7 +800,7 @@ class FastElementsAccessor ...@@ -800,7 +800,7 @@ class FastElementsAccessor
} }
} else { } else {
// Otherwise, fill the unused tail with holes. // Otherwise, fill the unused tail with holes.
int old_length = FastD2I(array->length()->Number()); int old_length = FastD2IChecked(array->length()->Number());
for (int i = length; i < old_length; i++) { for (int i = length; i < old_length; i++) {
backing_store->set_the_hole(i); backing_store->set_the_hole(i);
} }
......
...@@ -3755,8 +3755,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SubString) { ...@@ -3755,8 +3755,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SubString) {
} else { } else {
CONVERT_DOUBLE_ARG_CHECKED(from_number, 1); CONVERT_DOUBLE_ARG_CHECKED(from_number, 1);
CONVERT_DOUBLE_ARG_CHECKED(to_number, 2); CONVERT_DOUBLE_ARG_CHECKED(to_number, 2);
start = FastD2I(from_number); start = FastD2IChecked(from_number);
end = FastD2I(to_number); end = FastD2IChecked(to_number);
} }
RUNTIME_ASSERT(end >= start); RUNTIME_ASSERT(end >= start);
RUNTIME_ASSERT(start >= 0); RUNTIME_ASSERT(start >= 0);
...@@ -4224,7 +4224,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToFixed) { ...@@ -4224,7 +4224,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToFixed) {
return *isolate->factory()->infinity_symbol(); return *isolate->factory()->infinity_symbol();
} }
CONVERT_DOUBLE_ARG_CHECKED(f_number, 1); CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
int f = FastD2I(f_number); int f = FastD2IChecked(f_number);
RUNTIME_ASSERT(f >= 0); RUNTIME_ASSERT(f >= 0);
char* str = DoubleToFixedCString(value, f); char* str = DoubleToFixedCString(value, f);
MaybeObject* res = MaybeObject* res =
...@@ -4249,7 +4249,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToExponential) { ...@@ -4249,7 +4249,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToExponential) {
return *isolate->factory()->infinity_symbol(); return *isolate->factory()->infinity_symbol();
} }
CONVERT_DOUBLE_ARG_CHECKED(f_number, 1); CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
int f = FastD2I(f_number); int f = FastD2IChecked(f_number);
RUNTIME_ASSERT(f >= -1 && f <= 20); RUNTIME_ASSERT(f >= -1 && f <= 20);
char* str = DoubleToExponentialCString(value, f); char* str = DoubleToExponentialCString(value, f);
MaybeObject* res = MaybeObject* res =
...@@ -4274,7 +4274,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToPrecision) { ...@@ -4274,7 +4274,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_NumberToPrecision) {
return *isolate->factory()->infinity_symbol(); return *isolate->factory()->infinity_symbol();
} }
CONVERT_DOUBLE_ARG_CHECKED(f_number, 1); CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
int f = FastD2I(f_number); int f = FastD2IChecked(f_number);
RUNTIME_ASSERT(f >= 1 && f <= 21); RUNTIME_ASSERT(f >= 1 && f <= 21);
char* str = DoubleToPrecisionCString(value, f); char* str = DoubleToPrecisionCString(value, f);
MaybeObject* res = MaybeObject* res =
......
...@@ -55,6 +55,22 @@ TEST(Utils1) { ...@@ -55,6 +55,22 @@ TEST(Utils1) {
CHECK_EQ(-2, -8 >> 2); CHECK_EQ(-2, -8 >> 2);
CHECK_EQ(-2, static_cast<int8_t>(-8) >> 2); CHECK_EQ(-2, static_cast<int8_t>(-8) >> 2);
CHECK_EQ(-2, static_cast<int>(static_cast<intptr_t>(-8) >> 2)); CHECK_EQ(-2, static_cast<int>(static_cast<intptr_t>(-8) >> 2));
CHECK_EQ(-1000000, FastD2IChecked(-1000000.0));
CHECK_EQ(-1, FastD2IChecked(-1.0));
CHECK_EQ(0, FastD2IChecked(0.0));
CHECK_EQ(1, FastD2IChecked(1.0));
CHECK_EQ(1000000, FastD2IChecked(1000000.0));
CHECK_EQ(-1000000, FastD2IChecked(-1000000.123));
CHECK_EQ(-1, FastD2IChecked(-1.234));
CHECK_EQ(0, FastD2IChecked(0.345));
CHECK_EQ(1, FastD2IChecked(1.234));
CHECK_EQ(1000000, FastD2IChecked(1000000.123));
CHECK_EQ(INT_MAX, FastD2IChecked(1.0e100));
CHECK_EQ(INT_MIN, FastD2IChecked(-1.0e100));
CHECK_EQ(INT_MIN, FastD2IChecked(NAN));
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment