| Index: test/cctest/test-api.cc
|
| diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
|
| index a943f303ee7bda448d024a250e26169a73667815..7ec5e64dc12ceb5105193d9743209c5580da3141 100644
|
| --- a/test/cctest/test-api.cc
|
| +++ b/test/cctest/test-api.cc
|
| @@ -8495,3 +8495,104 @@ THREADED_TEST(GetHeapStatistics) {
|
| CHECK_NE(heap_statistics.total_heap_size(), 0);
|
| CHECK_NE(heap_statistics.used_heap_size(), 0);
|
| }
|
| +
|
| +
|
| +static double DoubleFromBits(uint64_t value) {
|
| + double target;
|
| + memcpy(&target, &value, sizeof(target));
|
| + return target;
|
| +}
|
| +
|
| +
|
| +static uint64_t DoubleToBits(double value) {
|
| + uint64_t target;
|
| + memcpy(&target, &value, sizeof(target));
|
| + return target;
|
| +}
|
| +
|
| +
|
| +static double DoubleToDateTime(double input) {
|
| + double date_limit = 864e13;
|
| + if (IsNaN(input) || input < -date_limit || input > date_limit) {
|
| + return i::OS::nan_value();
|
| + }
|
| + return (input < 0) ? -(floor(-input)) : floor(input);
|
| +}
|
| +
|
| +// We don't have a consistent way to write 64-bit constants syntactically, so we
|
| +// split them into two 32-bit constants and combine them programmatically.
|
| +static double DoubleFromBits(uint32_t high_bits, uint32_t low_bits) {
|
| + return DoubleFromBits((static_cast<uint64_t>(high_bits) << 32) | low_bits);
|
| +}
|
| +
|
| +
|
| +THREADED_TEST(QuietSignalingNaNs) {
|
| + v8::HandleScope scope;
|
| + LocalContext context;
|
| + v8::TryCatch try_catch;
|
| +
|
| + // Special double values.
|
| + double snan = DoubleFromBits(0x7ff00000, 0x00000001);
|
| + double qnan = DoubleFromBits(0x7ff80000, 0x00000000);
|
| + double infinity = DoubleFromBits(0x7ff00000, 0x00000000);
|
| + double max_normal = DoubleFromBits(0x7fefffff, 0xffffffffu);
|
| + double min_normal = DoubleFromBits(0x00100000, 0x00000000);
|
| + double max_denormal = DoubleFromBits(0x000fffff, 0xffffffffu);
|
| + double min_denormal = DoubleFromBits(0x00000000, 0x00000001);
|
| +
|
| + // Date values are capped at +/-100000000 days (times 864e5 ms per day)
|
| + // on either side of the epoch.
|
| + double date_limit = 864e13;
|
| +
|
| + double test_values[] = {
|
| + snan,
|
| + qnan,
|
| + infinity,
|
| + max_normal,
|
| + date_limit + 1,
|
| + date_limit,
|
| + min_normal,
|
| + max_denormal,
|
| + min_denormal,
|
| + 0,
|
| + -0,
|
| + -min_denormal,
|
| + -max_denormal,
|
| + -min_normal,
|
| + -date_limit,
|
| + -date_limit - 1,
|
| + -max_normal,
|
| + -infinity,
|
| + -qnan,
|
| + -snan
|
| + };
|
| + int num_test_values = 20;
|
| +
|
| + for (int i = 0; i < num_test_values; i++) {
|
| + double test_value = test_values[i];
|
| +
|
| + // Check that Number::New preserves non-NaNs and quiets SNaNs.
|
| + v8::Handle<v8::Value> number = v8::Number::New(test_value);
|
| + double stored_number = number->NumberValue();
|
| + if (!IsNaN(test_value)) {
|
| + CHECK_EQ(test_value, stored_number);
|
| + } else {
|
| + uint64_t stored_bits = DoubleToBits(stored_number);
|
| + // Check if quiet nan (bits 51..62 all set).
|
| + CHECK_EQ(0xfff, (stored_bits >> 51) & 0xfff);
|
| + }
|
| +
|
| + // Check that Date::New preserves non-NaNs in the date range and
|
| + // quiets SNaNs.
|
| + v8::Handle<v8::Value> date = v8::Date::New(test_value);
|
| + double expected_stored_date = DoubleToDateTime(test_value);
|
| + double stored_date = date->NumberValue();
|
| + if (!IsNaN(expected_stored_date)) {
|
| + CHECK_EQ(expected_stored_date, stored_date);
|
| + } else {
|
| + uint64_t stored_bits = DoubleToBits(stored_date);
|
| + // Check if quiet nan (bits 51..62 all set).
|
| + CHECK_EQ(0xfff, (stored_bits >> 51) & 0xfff);
|
| + }
|
| + }
|
| +}
|
|
|