mirror of https://github.com/lukechilds/node.git
Ryan Dahl
14 years ago
78 changed files with 2217 additions and 3656 deletions
@ -1,197 +0,0 @@ |
|||
// Copyright 2010 the V8 project authors. All rights reserved.
|
|||
// Redistribution and use in source and binary forms, with or without
|
|||
// modification, are permitted provided that the following conditions are
|
|||
// met:
|
|||
//
|
|||
// * Redistributions of source code must retain the above copyright
|
|||
// notice, this list of conditions and the following disclaimer.
|
|||
// * Redistributions in binary form must reproduce the above
|
|||
// copyright notice, this list of conditions and the following
|
|||
// disclaimer in the documentation and/or other materials provided
|
|||
// with the distribution.
|
|||
// * Neither the name of Google Inc. nor the names of its
|
|||
// contributors may be used to endorse or promote products derived
|
|||
// from this software without specific prior written permission.
|
|||
//
|
|||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
|||
// This module wraps compiler specific syncronisation related intrinsics.
|
|||
|
|||
#ifndef V8_ATOMIC_H_ |
|||
#define V8_ATOMIC_H_ |
|||
|
|||
// Avoid warning when compiled with /Wp64.
|
|||
#ifndef _MSC_VER |
|||
#define __w64 |
|||
#endif |
|||
typedef __w64 int32_t Atomic32; |
|||
#ifdef V8_TARGET_ARCH_X64 |
|||
// We need to be able to go between Atomic64 and AtomicWord implicitly. This
|
|||
// means Atomic64 and AtomicWord should be the same type on 64-bit.
|
|||
typedef intptr_t Atomic64; |
|||
#endif |
|||
|
|||
// Use AtomicWord for a machine-sized pointer. It will use the Atomic32 or
|
|||
// Atomic64 routines below, depending on your architecture.
|
|||
typedef intptr_t AtomicWord; |
|||
|
|||
inline void AtomicAdd(volatile Atomic32* ptr, Atomic32 value); |
|||
inline void AtomicOr(volatile Atomic32* ptr, Atomic32 value); |
|||
inline void AtomicAnd(volatile Atomic32* ptr, Atomic32 value); |
|||
inline bool AtomicCompareAndSwap(volatile Atomic32* ptr, |
|||
Atomic32 old_value, |
|||
Atomic32 new_value); |
|||
|
|||
#if defined(V8_TARGET_ARCH_X64) |
|||
inline bool AtomicCompareAndSwap(volatile Atomic64* ptr, |
|||
Atomic64 old_value, |
|||
Atomic64 new_value); |
|||
#endif |
|||
|
|||
|
|||
#if defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_X64) |
|||
|
|||
// Microsoft Visual C++ specific stuff.
|
|||
#ifdef _MSC_VER |
|||
#if (_MSC_VER >= 1500) |
|||
#include <intrin.h> |
|||
#else |
|||
// For older versions we have to provide intrisic signatures.
|
|||
long _InterlockedExchangeAdd (long volatile* Addend, long Value); |
|||
long _InterlockedOr (long volatile* Value, long Mask); |
|||
long _InterlockedAnd (long volatile *Value, long Mask); |
|||
long _InterlockedCompareExchange (long volatile* Destination, |
|||
long Exchange, |
|||
long Comperand); |
|||
|
|||
#pragma intrinsic(_InterlockedExchangeAdd) |
|||
#pragma intrinsic(_InterlockedOr) |
|||
#pragma intrinsic(_InterlockedAnd) |
|||
#pragma intrinsic(_InterlockedCompareExchange) |
|||
#endif |
|||
|
|||
inline void AtomicAdd(volatile Atomic32* ptr, Atomic32 value) { |
|||
_InterlockedExchangeAdd(reinterpret_cast<long volatile*>(ptr), |
|||
static_cast<long>(value)); |
|||
} |
|||
|
|||
inline void AtomicOr(volatile Atomic32* ptr, Atomic32 value) { |
|||
_InterlockedOr(reinterpret_cast<long volatile*>(ptr), |
|||
static_cast<long>(value)); |
|||
} |
|||
|
|||
inline void AtomicAnd(volatile Atomic32* ptr, Atomic32 value) { |
|||
_InterlockedAnd(reinterpret_cast<long volatile*>(ptr), |
|||
static_cast<long>(value)); |
|||
} |
|||
|
|||
inline bool AtomicCompareAndSwap(volatile Atomic32* ptr, |
|||
Atomic32 old_value, |
|||
Atomic32 new_value) { |
|||
long result = _InterlockedCompareExchange( |
|||
reinterpret_cast<long volatile*>(ptr), |
|||
static_cast<long>(new_value), |
|||
static_cast<long>(old_value)); |
|||
return result == static_cast<long>(old_value); |
|||
} |
|||
|
|||
#if defined(V8_TARGET_ARCH_X64) |
|||
inline bool AtomicCompareAndSwap(volatile Atomic64* ptr, |
|||
Atomic64 old_value, |
|||
Atomic64 new_value) { |
|||
|
|||
__int64 result = _InterlockedCompareExchange_64( |
|||
reinterpret_cast<__int64 volatile*>(ptr), |
|||
static_cast<__int64>(new_value), |
|||
static_cast<__int64>(old_value)); |
|||
return result == static_cast<__int64>(old_value); |
|||
} |
|||
#endif |
|||
|
|||
#define ATOMIC_SUPPORTED 1 |
|||
|
|||
#endif // _MSC_VER
|
|||
|
|||
// GCC specific stuff
|
|||
#ifdef __GNUC__ |
|||
inline void AtomicAdd(volatile Atomic32* ptr, Atomic32 value) { |
|||
__sync_fetch_and_add(ptr, value); |
|||
} |
|||
|
|||
inline void AtomicOr(volatile Atomic32* ptr, Atomic32 value) { |
|||
__sync_fetch_and_or(ptr, value); |
|||
} |
|||
|
|||
inline void AtomicAnd(volatile Atomic32* ptr, Atomic32 value) { |
|||
__sync_fetch_and_and(ptr, value); |
|||
} |
|||
|
|||
inline bool AtomicCompareAndSwap(volatile Atomic32* ptr, |
|||
Atomic32 old_value, |
|||
Atomic32 new_value) { |
|||
return __sync_bool_compare_and_swap(ptr, old_value, new_value); |
|||
} |
|||
|
|||
#if defined(V8_TARGET_ARCH_X64) |
|||
inline bool AtomicCompareAndSwap(volatile Atomic64* ptr, |
|||
Atomic64 old_value, |
|||
Atomic64 new_value) { |
|||
return __sync_bool_compare_and_swap(ptr, old_value, new_value); |
|||
} |
|||
#endif |
|||
|
|||
#define ATOMIC_SUPPORTED 1 |
|||
#endif |
|||
|
|||
#endif // defined(V8_TARGET_ARCH_IA32) || defined(V8_TARGET_ARCH_X64)
|
|||
|
|||
#ifndef ATOMIC_SUPPORTED |
|||
inline void AtomicAdd(volatile Atomic32* ptr, Atomic32 value) { |
|||
*ptr += value; |
|||
} |
|||
|
|||
inline void AtomicOr(volatile Atomic32* ptr, Atomic32 value) { |
|||
*ptr |= value; |
|||
} |
|||
|
|||
inline void AtomicAnd(volatile Atomic32* ptr, Atomic32 value) { |
|||
*ptr &= value; |
|||
} |
|||
|
|||
inline bool AtomicCompareAndSwap(volatile Atomic32* ptr, |
|||
Atomic32 old_value, |
|||
Atomic32 new_value) { |
|||
if (*ptr == old_value) { |
|||
*ptr = new_value; |
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
#if defined(V8_TARGET_ARCH_X64) |
|||
inline bool AtomicCompareAndSwap(volatile Atomic64* ptr, |
|||
Atomic64 old_value, |
|||
Atomic64 new_value) { |
|||
if (*ptr == old_value) { |
|||
*ptr = new_value; |
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
#endif |
|||
|
|||
#define ATOMIC_SUPPORTED 0 |
|||
#endif |
|||
|
|||
|
|||
#endif |
@ -0,0 +1,152 @@ |
|||
// Copyright 2006-2008 the V8 project authors. All rights reserved.
|
|||
// Redistribution and use in source and binary forms, with or without
|
|||
// modification, are permitted provided that the following conditions are
|
|||
// met:
|
|||
//
|
|||
// * Redistributions of source code must retain the above copyright
|
|||
// notice, this list of conditions and the following disclaimer.
|
|||
// * Redistributions in binary form must reproduce the above
|
|||
// copyright notice, this list of conditions and the following
|
|||
// disclaimer in the documentation and/or other materials provided
|
|||
// with the distribution.
|
|||
// * Neither the name of Google Inc. nor the names of its
|
|||
// contributors may be used to endorse or promote products derived
|
|||
// from this software without specific prior written permission.
|
|||
//
|
|||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
|||
#include <stdarg.h> |
|||
#include <limits.h> |
|||
|
|||
#include "v8.h" |
|||
|
|||
#include "cached-powers.h" |
|||
|
|||
namespace v8 { |
|||
namespace internal { |
|||
|
|||
struct CachedPower { |
|||
uint64_t significand; |
|||
int16_t binary_exponent; |
|||
int16_t decimal_exponent; |
|||
}; |
|||
|
|||
static const CachedPower kCachedPowers[] = { |
|||
{V8_2PART_UINT64_C(0xe61acf03, 3d1a45df), -1087, -308}, |
|||
{V8_2PART_UINT64_C(0xab70fe17, c79ac6ca), -1060, -300}, |
|||
{V8_2PART_UINT64_C(0xff77b1fc, bebcdc4f), -1034, -292}, |
|||
{V8_2PART_UINT64_C(0xbe5691ef, 416bd60c), -1007, -284}, |
|||
{V8_2PART_UINT64_C(0x8dd01fad, 907ffc3c), -980, -276}, |
|||
{V8_2PART_UINT64_C(0xd3515c28, 31559a83), -954, -268}, |
|||
{V8_2PART_UINT64_C(0x9d71ac8f, ada6c9b5), -927, -260}, |
|||
{V8_2PART_UINT64_C(0xea9c2277, 23ee8bcb), -901, -252}, |
|||
{V8_2PART_UINT64_C(0xaecc4991, 4078536d), -874, -244}, |
|||
{V8_2PART_UINT64_C(0x823c1279, 5db6ce57), -847, -236}, |
|||
{V8_2PART_UINT64_C(0xc2109436, 4dfb5637), -821, -228}, |
|||
{V8_2PART_UINT64_C(0x9096ea6f, 3848984f), -794, -220}, |
|||
{V8_2PART_UINT64_C(0xd77485cb, 25823ac7), -768, -212}, |
|||
{V8_2PART_UINT64_C(0xa086cfcd, 97bf97f4), -741, -204}, |
|||
{V8_2PART_UINT64_C(0xef340a98, 172aace5), -715, -196}, |
|||
{V8_2PART_UINT64_C(0xb23867fb, 2a35b28e), -688, -188}, |
|||
{V8_2PART_UINT64_C(0x84c8d4df, d2c63f3b), -661, -180}, |
|||
{V8_2PART_UINT64_C(0xc5dd4427, 1ad3cdba), -635, -172}, |
|||
{V8_2PART_UINT64_C(0x936b9fce, bb25c996), -608, -164}, |
|||
{V8_2PART_UINT64_C(0xdbac6c24, 7d62a584), -582, -156}, |
|||
{V8_2PART_UINT64_C(0xa3ab6658, 0d5fdaf6), -555, -148}, |
|||
{V8_2PART_UINT64_C(0xf3e2f893, dec3f126), -529, -140}, |
|||
{V8_2PART_UINT64_C(0xb5b5ada8, aaff80b8), -502, -132}, |
|||
{V8_2PART_UINT64_C(0x87625f05, 6c7c4a8b), -475, -124}, |
|||
{V8_2PART_UINT64_C(0xc9bcff60, 34c13053), -449, -116}, |
|||
{V8_2PART_UINT64_C(0x964e858c, 91ba2655), -422, -108}, |
|||
{V8_2PART_UINT64_C(0xdff97724, 70297ebd), -396, -100}, |
|||
{V8_2PART_UINT64_C(0xa6dfbd9f, b8e5b88f), -369, -92}, |
|||
{V8_2PART_UINT64_C(0xf8a95fcf, 88747d94), -343, -84}, |
|||
{V8_2PART_UINT64_C(0xb9447093, 8fa89bcf), -316, -76}, |
|||
{V8_2PART_UINT64_C(0x8a08f0f8, bf0f156b), -289, -68}, |
|||
{V8_2PART_UINT64_C(0xcdb02555, 653131b6), -263, -60}, |
|||
{V8_2PART_UINT64_C(0x993fe2c6, d07b7fac), -236, -52}, |
|||
{V8_2PART_UINT64_C(0xe45c10c4, 2a2b3b06), -210, -44}, |
|||
{V8_2PART_UINT64_C(0xaa242499, 697392d3), -183, -36}, |
|||
{V8_2PART_UINT64_C(0xfd87b5f2, 8300ca0e), -157, -28}, |
|||
{V8_2PART_UINT64_C(0xbce50864, 92111aeb), -130, -20}, |
|||
{V8_2PART_UINT64_C(0x8cbccc09, 6f5088cc), -103, -12}, |
|||
{V8_2PART_UINT64_C(0xd1b71758, e219652c), -77, -4}, |
|||
{V8_2PART_UINT64_C(0x9c400000, 00000000), -50, 4}, |
|||
{V8_2PART_UINT64_C(0xe8d4a510, 00000000), -24, 12}, |
|||
{V8_2PART_UINT64_C(0xad78ebc5, ac620000), 3, 20}, |
|||
{V8_2PART_UINT64_C(0x813f3978, f8940984), 30, 28}, |
|||
{V8_2PART_UINT64_C(0xc097ce7b, c90715b3), 56, 36}, |
|||
{V8_2PART_UINT64_C(0x8f7e32ce, 7bea5c70), 83, 44}, |
|||
{V8_2PART_UINT64_C(0xd5d238a4, abe98068), 109, 52}, |
|||
{V8_2PART_UINT64_C(0x9f4f2726, 179a2245), 136, 60}, |
|||
{V8_2PART_UINT64_C(0xed63a231, d4c4fb27), 162, 68}, |
|||
{V8_2PART_UINT64_C(0xb0de6538, 8cc8ada8), 189, 76}, |
|||
{V8_2PART_UINT64_C(0x83c7088e, 1aab65db), 216, 84}, |
|||
{V8_2PART_UINT64_C(0xc45d1df9, 42711d9a), 242, 92}, |
|||
{V8_2PART_UINT64_C(0x924d692c, a61be758), 269, 100}, |
|||
{V8_2PART_UINT64_C(0xda01ee64, 1a708dea), 295, 108}, |
|||
{V8_2PART_UINT64_C(0xa26da399, 9aef774a), 322, 116}, |
|||
{V8_2PART_UINT64_C(0xf209787b, b47d6b85), 348, 124}, |
|||
{V8_2PART_UINT64_C(0xb454e4a1, 79dd1877), 375, 132}, |
|||
{V8_2PART_UINT64_C(0x865b8692, 5b9bc5c2), 402, 140}, |
|||
{V8_2PART_UINT64_C(0xc83553c5, c8965d3d), 428, 148}, |
|||
{V8_2PART_UINT64_C(0x952ab45c, fa97a0b3), 455, 156}, |
|||
{V8_2PART_UINT64_C(0xde469fbd, 99a05fe3), 481, 164}, |
|||
{V8_2PART_UINT64_C(0xa59bc234, db398c25), 508, 172}, |
|||
{V8_2PART_UINT64_C(0xf6c69a72, a3989f5c), 534, 180}, |
|||
{V8_2PART_UINT64_C(0xb7dcbf53, 54e9bece), 561, 188}, |
|||
{V8_2PART_UINT64_C(0x88fcf317, f22241e2), 588, 196}, |
|||
{V8_2PART_UINT64_C(0xcc20ce9b, d35c78a5), 614, 204}, |
|||
{V8_2PART_UINT64_C(0x98165af3, 7b2153df), 641, 212}, |
|||
{V8_2PART_UINT64_C(0xe2a0b5dc, 971f303a), 667, 220}, |
|||
{V8_2PART_UINT64_C(0xa8d9d153, 5ce3b396), 694, 228}, |
|||
{V8_2PART_UINT64_C(0xfb9b7cd9, a4a7443c), 720, 236}, |
|||
{V8_2PART_UINT64_C(0xbb764c4c, a7a44410), 747, 244}, |
|||
{V8_2PART_UINT64_C(0x8bab8eef, b6409c1a), 774, 252}, |
|||
{V8_2PART_UINT64_C(0xd01fef10, a657842c), 800, 260}, |
|||
{V8_2PART_UINT64_C(0x9b10a4e5, e9913129), 827, 268}, |
|||
{V8_2PART_UINT64_C(0xe7109bfb, a19c0c9d), 853, 276}, |
|||
{V8_2PART_UINT64_C(0xac2820d9, 623bf429), 880, 284}, |
|||
{V8_2PART_UINT64_C(0x80444b5e, 7aa7cf85), 907, 292}, |
|||
{V8_2PART_UINT64_C(0xbf21e440, 03acdd2d), 933, 300}, |
|||
{V8_2PART_UINT64_C(0x8e679c2f, 5e44ff8f), 960, 308}, |
|||
{V8_2PART_UINT64_C(0xd433179d, 9c8cb841), 986, 316}, |
|||
{V8_2PART_UINT64_C(0x9e19db92, b4e31ba9), 1013, 324}, |
|||
{V8_2PART_UINT64_C(0xeb96bf6e, badf77d9), 1039, 332}, |
|||
{V8_2PART_UINT64_C(0xaf87023b, 9bf0ee6b), 1066, 340}, |
|||
}; |
|||
|
|||
static const int kCachedPowersLength = ARRAY_SIZE(kCachedPowers); |
|||
static const int kCachedPowersOffset = -kCachedPowers[0].decimal_exponent; |
|||
static const double kD_1_LOG2_10 = 0.30102999566398114; // 1 / lg(10)
|
|||
static const int kCachedPowersDecimalDistance = |
|||
kCachedPowers[1].decimal_exponent - kCachedPowers[0].decimal_exponent; |
|||
|
|||
void GetCachedPowerForBinaryExponentRange(int min_exponent, |
|||
int max_exponent, |
|||
DiyFp* power, |
|||
int* decimal_exponent) { |
|||
int kQ = DiyFp::kSignificandSize; |
|||
double k = ceiling((min_exponent + kQ - 1) * kD_1_LOG2_10); |
|||
int foo = kCachedPowersOffset; |
|||
int index = |
|||
(foo + static_cast<int>(k) - 1) / kCachedPowersDecimalDistance + 1; |
|||
ASSERT(0 <= index && index < kCachedPowersLength); |
|||
CachedPower cached_power = kCachedPowers[index]; |
|||
ASSERT(min_exponent <= cached_power.binary_exponent); |
|||
ASSERT(cached_power.binary_exponent <= max_exponent); |
|||
*decimal_exponent = cached_power.decimal_exponent; |
|||
*power = DiyFp(cached_power.significand, cached_power.binary_exponent); |
|||
} |
|||
|
|||
} } // namespace v8::internal
|
File diff suppressed because it is too large
@ -0,0 +1,181 @@ |
|||
// Copyright 2010 the V8 project authors. All rights reserved.
|
|||
// Redistribution and use in source and binary forms, with or without
|
|||
// modification, are permitted provided that the following conditions are
|
|||
// met:
|
|||
//
|
|||
// * Redistributions of source code must retain the above copyright
|
|||
// notice, this list of conditions and the following disclaimer.
|
|||
// * Redistributions in binary form must reproduce the above
|
|||
// copyright notice, this list of conditions and the following
|
|||
// disclaimer in the documentation and/or other materials provided
|
|||
// with the distribution.
|
|||
// * Neither the name of Google Inc. nor the names of its
|
|||
// contributors may be used to endorse or promote products derived
|
|||
// from this software without specific prior written permission.
|
|||
//
|
|||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
|||
#include <stdarg.h> |
|||
#include <limits.h> |
|||
|
|||
#include "v8.h" |
|||
|
|||
#include "strtod.h" |
|||
// #include "cached-powers.h"
|
|||
|
|||
namespace v8 { |
|||
namespace internal { |
|||
|
|||
// 2^53 = 9007199254740992.
|
|||
// Any integer with at most 15 decimal digits will hence fit into a double
|
|||
// (which has a 53bit significand) without loss of precision.
|
|||
static const int kMaxExactDoubleIntegerDecimalDigits = 15; |
|||
// 2^64 = 18446744073709551616
|
|||
// Any integer with at most 19 digits will hence fit into a 64bit datatype.
|
|||
static const int kMaxUint64DecimalDigits = 19; |
|||
// Max double: 1.7976931348623157 x 10^308
|
|||
// Min non-zero double: 4.9406564584124654 x 10^-324
|
|||
// Any x >= 10^309 is interpreted as +infinity.
|
|||
// Any x <= 10^-324 is interpreted as 0.
|
|||
// Note that 2.5e-324 (despite being smaller than the min double) will be read
|
|||
// as non-zero (equal to the min non-zero double).
|
|||
static const int kMaxDecimalPower = 309; |
|||
static const int kMinDecimalPower = -324; |
|||
|
|||
static const double exact_powers_of_ten[] = { |
|||
1.0, // 10^0
|
|||
10.0, |
|||
100.0, |
|||
1000.0, |
|||
10000.0, |
|||
100000.0, |
|||
1000000.0, |
|||
10000000.0, |
|||
100000000.0, |
|||
1000000000.0, |
|||
10000000000.0, // 10^10
|
|||
100000000000.0, |
|||
1000000000000.0, |
|||
10000000000000.0, |
|||
100000000000000.0, |
|||
1000000000000000.0, |
|||
10000000000000000.0, |
|||
100000000000000000.0, |
|||
1000000000000000000.0, |
|||
10000000000000000000.0, |
|||
100000000000000000000.0, // 10^20
|
|||
1000000000000000000000.0, |
|||
// 10^22 = 0x21e19e0c9bab2400000 = 0x878678326eac9 * 2^22
|
|||
10000000000000000000000.0 |
|||
}; |
|||
|
|||
static const int kExactPowersOfTenSize = ARRAY_SIZE(exact_powers_of_ten); |
|||
|
|||
|
|||
extern "C" double gay_strtod(const char* s00, const char** se); |
|||
|
|||
static double old_strtod(Vector<const char> buffer, int exponent) { |
|||
char gay_buffer[1024]; |
|||
Vector<char> gay_buffer_vector(gay_buffer, sizeof(gay_buffer)); |
|||
int pos = 0; |
|||
for (int i = 0; i < buffer.length(); ++i) { |
|||
gay_buffer_vector[pos++] = buffer[i]; |
|||
} |
|||
gay_buffer_vector[pos++] = 'e'; |
|||
if (exponent < 0) { |
|||
gay_buffer_vector[pos++] = '-'; |
|||
exponent = -exponent; |
|||
} |
|||
const int kNumberOfExponentDigits = 5; |
|||
for (int i = kNumberOfExponentDigits - 1; i >= 0; i--) { |
|||
gay_buffer_vector[pos + i] = exponent % 10 + '0'; |
|||
exponent /= 10; |
|||
} |
|||
pos += kNumberOfExponentDigits; |
|||
gay_buffer_vector[pos] = '\0'; |
|||
return gay_strtod(gay_buffer, NULL); |
|||
} |
|||
|
|||
|
|||
static Vector<const char> TrimLeadingZeros(Vector<const char> buffer) { |
|||
for (int i = 0; i < buffer.length(); i++) { |
|||
if (buffer[i] != '0') { |
|||
return Vector<const char>(buffer.start() + i, buffer.length() - i); |
|||
} |
|||
} |
|||
return Vector<const char>(buffer.start(), 0); |
|||
} |
|||
|
|||
|
|||
static Vector<const char> TrimTrailingZeros(Vector<const char> buffer) { |
|||
for (int i = buffer.length() - 1; i >= 0; --i) { |
|||
if (buffer[i] != '0') { |
|||
return Vector<const char>(buffer.start(), i + 1); |
|||
} |
|||
} |
|||
return Vector<const char>(buffer.start(), 0); |
|||
} |
|||
|
|||
|
|||
uint64_t ReadUint64(Vector<const char> buffer) { |
|||
ASSERT(buffer.length() <= kMaxUint64DecimalDigits); |
|||
uint64_t result = 0; |
|||
for (int i = 0; i < buffer.length(); ++i) { |
|||
int digit = buffer[i] - '0'; |
|||
ASSERT(0 <= digit && digit <= 9); |
|||
result = 10 * result + digit; |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
|
|||
double Strtod(Vector<const char> buffer, int exponent) { |
|||
Vector<const char> left_trimmed = TrimLeadingZeros(buffer); |
|||
Vector<const char> trimmed = TrimTrailingZeros(left_trimmed); |
|||
exponent += left_trimmed.length() - trimmed.length(); |
|||
if (trimmed.length() == 0) return 0.0; |
|||
if (exponent + trimmed.length() - 1 >= kMaxDecimalPower) return V8_INFINITY; |
|||
if (exponent + trimmed.length() <= kMinDecimalPower) return 0.0; |
|||
if (trimmed.length() <= kMaxExactDoubleIntegerDecimalDigits) { |
|||
// The trimmed input fits into a double.
|
|||
// If the 10^exponent (resp. 10^-exponent) fits into a double too then we
|
|||
// can compute the result-double simply by multiplying (resp. dividing) the
|
|||
// two numbers.
|
|||
// This is possible because IEEE guarantees that floating-point operations
|
|||
// return the best possible approximation.
|
|||
if (exponent < 0 && -exponent < kExactPowersOfTenSize) { |
|||
// 10^-exponent fits into a double.
|
|||
double buffer_d = static_cast<double>(ReadUint64(trimmed)); |
|||
return buffer_d / exact_powers_of_ten[-exponent]; |
|||
} |
|||
if (0 <= exponent && exponent < kExactPowersOfTenSize) { |
|||
// 10^exponent fits into a double.
|
|||
double buffer_d = static_cast<double>(ReadUint64(trimmed)); |
|||
return buffer_d * exact_powers_of_ten[exponent]; |
|||
} |
|||
int remaining_digits = |
|||
kMaxExactDoubleIntegerDecimalDigits - trimmed.length(); |
|||
if ((0 <= exponent) && |
|||
(exponent - remaining_digits < kExactPowersOfTenSize)) { |
|||
// The trimmed string was short and we can multiply it with
|
|||
// 10^remaining_digits. As a result the remaining exponent now fits
|
|||
// into a double too.
|
|||
double buffer_d = static_cast<double>(ReadUint64(trimmed)); |
|||
buffer_d *= exact_powers_of_ten[remaining_digits]; |
|||
return buffer_d * exact_powers_of_ten[exponent - remaining_digits]; |
|||
} |
|||
} |
|||
return old_strtod(trimmed, exponent); |
|||
} |
|||
|
|||
} } // namespace v8::internal
|
@ -0,0 +1,40 @@ |
|||
// Copyright 2010 the V8 project authors. All rights reserved.
|
|||
// Redistribution and use in source and binary forms, with or without
|
|||
// modification, are permitted provided that the following conditions are
|
|||
// met:
|
|||
//
|
|||
// * Redistributions of source code must retain the above copyright
|
|||
// notice, this list of conditions and the following disclaimer.
|
|||
// * Redistributions in binary form must reproduce the above
|
|||
// copyright notice, this list of conditions and the following
|
|||
// disclaimer in the documentation and/or other materials provided
|
|||
// with the distribution.
|
|||
// * Neither the name of Google Inc. nor the names of its
|
|||
// contributors may be used to endorse or promote products derived
|
|||
// from this software without specific prior written permission.
|
|||
//
|
|||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
|||
#ifndef V8_STRTOD_H_ |
|||
#define V8_STRTOD_H_ |
|||
|
|||
namespace v8 { |
|||
namespace internal { |
|||
|
|||
// The buffer must only contain digits in the range [0-9]. It must not
|
|||
// contain a dot or a sign. It must not start with '0', and must not be empty.
|
|||
double Strtod(Vector<const char> buffer, int exponent); |
|||
|
|||
} } // namespace v8::internal
|
|||
|
|||
#endif // V8_STRTOD_H_
|
@ -0,0 +1,201 @@ |
|||
// Copyright 2006-2008 the V8 project authors. All rights reserved.
|
|||
|
|||
#include <stdlib.h> |
|||
|
|||
#include "v8.h" |
|||
|
|||
#include "cctest.h" |
|||
#include "strtod.h" |
|||
|
|||
using namespace v8::internal; |
|||
|
|||
static Vector<const char> StringToVector(const char* str) { |
|||
return Vector<const char>(str, StrLength(str)); |
|||
} |
|||
|
|||
|
|||
static double StrtodChar(const char* str, int exponent) { |
|||
return Strtod(StringToVector(str), exponent); |
|||
} |
|||
|
|||
|
|||
TEST(Strtod) { |
|||
Vector<const char> vector; |
|||
|
|||
vector = StringToVector("0"); |
|||
CHECK_EQ(0.0, Strtod(vector, 1)); |
|||
CHECK_EQ(0.0, Strtod(vector, 2)); |
|||
CHECK_EQ(0.0, Strtod(vector, -2)); |
|||
CHECK_EQ(0.0, Strtod(vector, -999)); |
|||
CHECK_EQ(0.0, Strtod(vector, +999)); |
|||
|
|||
vector = StringToVector("1"); |
|||
CHECK_EQ(1.0, Strtod(vector, 0)); |
|||
CHECK_EQ(10.0, Strtod(vector, 1)); |
|||
CHECK_EQ(100.0, Strtod(vector, 2)); |
|||
CHECK_EQ(1e20, Strtod(vector, 20)); |
|||
CHECK_EQ(1e22, Strtod(vector, 22)); |
|||
CHECK_EQ(1e23, Strtod(vector, 23)); |
|||
CHECK_EQ(1e35, Strtod(vector, 35)); |
|||
CHECK_EQ(1e36, Strtod(vector, 36)); |
|||
CHECK_EQ(1e37, Strtod(vector, 37)); |
|||
CHECK_EQ(1e-1, Strtod(vector, -1)); |
|||
CHECK_EQ(1e-2, Strtod(vector, -2)); |
|||
CHECK_EQ(1e-5, Strtod(vector, -5)); |
|||
CHECK_EQ(1e-20, Strtod(vector, -20)); |
|||
CHECK_EQ(1e-22, Strtod(vector, -22)); |
|||
CHECK_EQ(1e-23, Strtod(vector, -23)); |
|||
CHECK_EQ(1e-25, Strtod(vector, -25)); |
|||
CHECK_EQ(1e-39, Strtod(vector, -39)); |
|||
|
|||
vector = StringToVector("2"); |
|||
CHECK_EQ(2.0, Strtod(vector, 0)); |
|||
CHECK_EQ(20.0, Strtod(vector, 1)); |
|||
CHECK_EQ(200.0, Strtod(vector, 2)); |
|||
CHECK_EQ(2e20, Strtod(vector, 20)); |
|||
CHECK_EQ(2e22, Strtod(vector, 22)); |
|||
CHECK_EQ(2e23, Strtod(vector, 23)); |
|||
CHECK_EQ(2e35, Strtod(vector, 35)); |
|||
CHECK_EQ(2e36, Strtod(vector, 36)); |
|||
CHECK_EQ(2e37, Strtod(vector, 37)); |
|||
CHECK_EQ(2e-1, Strtod(vector, -1)); |
|||
CHECK_EQ(2e-2, Strtod(vector, -2)); |
|||
CHECK_EQ(2e-5, Strtod(vector, -5)); |
|||
CHECK_EQ(2e-20, Strtod(vector, -20)); |
|||
CHECK_EQ(2e-22, Strtod(vector, -22)); |
|||
CHECK_EQ(2e-23, Strtod(vector, -23)); |
|||
CHECK_EQ(2e-25, Strtod(vector, -25)); |
|||
CHECK_EQ(2e-39, Strtod(vector, -39)); |
|||
|
|||
vector = StringToVector("9"); |
|||
CHECK_EQ(9.0, Strtod(vector, 0)); |
|||
CHECK_EQ(90.0, Strtod(vector, 1)); |
|||
CHECK_EQ(900.0, Strtod(vector, 2)); |
|||
CHECK_EQ(9e20, Strtod(vector, 20)); |
|||
CHECK_EQ(9e22, Strtod(vector, 22)); |
|||
CHECK_EQ(9e23, Strtod(vector, 23)); |
|||
CHECK_EQ(9e35, Strtod(vector, 35)); |
|||
CHECK_EQ(9e36, Strtod(vector, 36)); |
|||
CHECK_EQ(9e37, Strtod(vector, 37)); |
|||
CHECK_EQ(9e-1, Strtod(vector, -1)); |
|||
CHECK_EQ(9e-2, Strtod(vector, -2)); |
|||
CHECK_EQ(9e-5, Strtod(vector, -5)); |
|||
CHECK_EQ(9e-20, Strtod(vector, -20)); |
|||
CHECK_EQ(9e-22, Strtod(vector, -22)); |
|||
CHECK_EQ(9e-23, Strtod(vector, -23)); |
|||
CHECK_EQ(9e-25, Strtod(vector, -25)); |
|||
CHECK_EQ(9e-39, Strtod(vector, -39)); |
|||
|
|||
vector = StringToVector("12345"); |
|||
CHECK_EQ(12345.0, Strtod(vector, 0)); |
|||
CHECK_EQ(123450.0, Strtod(vector, 1)); |
|||
CHECK_EQ(1234500.0, Strtod(vector, 2)); |
|||
CHECK_EQ(12345e20, Strtod(vector, 20)); |
|||
CHECK_EQ(12345e22, Strtod(vector, 22)); |
|||
CHECK_EQ(12345e23, Strtod(vector, 23)); |
|||
CHECK_EQ(12345e30, Strtod(vector, 30)); |
|||
CHECK_EQ(12345e31, Strtod(vector, 31)); |
|||
CHECK_EQ(12345e32, Strtod(vector, 32)); |
|||
CHECK_EQ(12345e35, Strtod(vector, 35)); |
|||
CHECK_EQ(12345e36, Strtod(vector, 36)); |
|||
CHECK_EQ(12345e37, Strtod(vector, 37)); |
|||
CHECK_EQ(12345e-1, Strtod(vector, -1)); |
|||
CHECK_EQ(12345e-2, Strtod(vector, -2)); |
|||
CHECK_EQ(12345e-5, Strtod(vector, -5)); |
|||
CHECK_EQ(12345e-20, Strtod(vector, -20)); |
|||
CHECK_EQ(12345e-22, Strtod(vector, -22)); |
|||
CHECK_EQ(12345e-23, Strtod(vector, -23)); |
|||
CHECK_EQ(12345e-25, Strtod(vector, -25)); |
|||
CHECK_EQ(12345e-39, Strtod(vector, -39)); |
|||
|
|||
vector = StringToVector("12345678901234"); |
|||
CHECK_EQ(12345678901234.0, Strtod(vector, 0)); |
|||
CHECK_EQ(123456789012340.0, Strtod(vector, 1)); |
|||
CHECK_EQ(1234567890123400.0, Strtod(vector, 2)); |
|||
CHECK_EQ(12345678901234e20, Strtod(vector, 20)); |
|||
CHECK_EQ(12345678901234e22, Strtod(vector, 22)); |
|||
CHECK_EQ(12345678901234e23, Strtod(vector, 23)); |
|||
CHECK_EQ(12345678901234e30, Strtod(vector, 30)); |
|||
CHECK_EQ(12345678901234e31, Strtod(vector, 31)); |
|||
CHECK_EQ(12345678901234e32, Strtod(vector, 32)); |
|||
CHECK_EQ(12345678901234e35, Strtod(vector, 35)); |
|||
CHECK_EQ(12345678901234e36, Strtod(vector, 36)); |
|||
CHECK_EQ(12345678901234e37, Strtod(vector, 37)); |
|||
CHECK_EQ(12345678901234e-1, Strtod(vector, -1)); |
|||
CHECK_EQ(12345678901234e-2, Strtod(vector, -2)); |
|||
CHECK_EQ(12345678901234e-5, Strtod(vector, -5)); |
|||
CHECK_EQ(12345678901234e-20, Strtod(vector, -20)); |
|||
CHECK_EQ(12345678901234e-22, Strtod(vector, -22)); |
|||
CHECK_EQ(12345678901234e-23, Strtod(vector, -23)); |
|||
CHECK_EQ(12345678901234e-25, Strtod(vector, -25)); |
|||
CHECK_EQ(12345678901234e-39, Strtod(vector, -39)); |
|||
|
|||
vector = StringToVector("123456789012345"); |
|||
CHECK_EQ(123456789012345.0, Strtod(vector, 0)); |
|||
CHECK_EQ(1234567890123450.0, Strtod(vector, 1)); |
|||
CHECK_EQ(12345678901234500.0, Strtod(vector, 2)); |
|||
CHECK_EQ(123456789012345e20, Strtod(vector, 20)); |
|||
CHECK_EQ(123456789012345e22, Strtod(vector, 22)); |
|||
CHECK_EQ(123456789012345e23, Strtod(vector, 23)); |
|||
CHECK_EQ(123456789012345e35, Strtod(vector, 35)); |
|||
CHECK_EQ(123456789012345e36, Strtod(vector, 36)); |
|||
CHECK_EQ(123456789012345e37, Strtod(vector, 37)); |
|||
CHECK_EQ(123456789012345e39, Strtod(vector, 39)); |
|||
CHECK_EQ(123456789012345e-1, Strtod(vector, -1)); |
|||
CHECK_EQ(123456789012345e-2, Strtod(vector, -2)); |
|||
CHECK_EQ(123456789012345e-5, Strtod(vector, -5)); |
|||
CHECK_EQ(123456789012345e-20, Strtod(vector, -20)); |
|||
CHECK_EQ(123456789012345e-22, Strtod(vector, -22)); |
|||
CHECK_EQ(123456789012345e-23, Strtod(vector, -23)); |
|||
CHECK_EQ(123456789012345e-25, Strtod(vector, -25)); |
|||
CHECK_EQ(123456789012345e-39, Strtod(vector, -39)); |
|||
|
|||
CHECK_EQ(0.0, StrtodChar("0", 12345)); |
|||
CHECK_EQ(0.0, StrtodChar("", 1324)); |
|||
CHECK_EQ(0.0, StrtodChar("000000000", 123)); |
|||
CHECK_EQ(0.0, StrtodChar("2", -324)); |
|||
CHECK_EQ(4e-324, StrtodChar("3", -324)); |
|||
// It would be more readable to put non-zero literals on the left side (i.e.
|
|||
// CHECK_EQ(1e-325, StrtodChar("1", -325))), but then Gcc complains that
|
|||
// they are truncated to zero.
|
|||
CHECK_EQ(0.0, StrtodChar("1", -325)); |
|||
CHECK_EQ(0.0, StrtodChar("1", -325)); |
|||
CHECK_EQ(0.0, StrtodChar("20000", -328)); |
|||
CHECK_EQ(40000e-328, StrtodChar("30000", -328)); |
|||
CHECK_EQ(0.0, StrtodChar("10000", -329)); |
|||
CHECK_EQ(0.0, StrtodChar("90000", -329)); |
|||
CHECK_EQ(0.0, StrtodChar("000000001", -325)); |
|||
CHECK_EQ(0.0, StrtodChar("000000001", -325)); |
|||
CHECK_EQ(0.0, StrtodChar("0000000020000", -328)); |
|||
CHECK_EQ(40000e-328, StrtodChar("00000030000", -328)); |
|||
CHECK_EQ(0.0, StrtodChar("0000000010000", -329)); |
|||
CHECK_EQ(0.0, StrtodChar("0000000090000", -329)); |
|||
|
|||
// It would be more readable to put the literals (and not V8_INFINITY) on the
|
|||
// left side (i.e. CHECK_EQ(1e309, StrtodChar("1", 309))), but then Gcc
|
|||
// complains that the floating constant exceeds range of 'double'.
|
|||
CHECK_EQ(V8_INFINITY, StrtodChar("1", 309)); |
|||
CHECK_EQ(1e308, StrtodChar("1", 308)); |
|||
CHECK_EQ(1234e305, StrtodChar("1234", 305)); |
|||
CHECK_EQ(1234e304, StrtodChar("1234", 304)); |
|||
CHECK_EQ(V8_INFINITY, StrtodChar("18", 307)); |
|||
CHECK_EQ(17e307, StrtodChar("17", 307)); |
|||
CHECK_EQ(V8_INFINITY, StrtodChar("0000001", 309)); |
|||
CHECK_EQ(1e308, StrtodChar("00000001", 308)); |
|||
CHECK_EQ(1234e305, StrtodChar("00000001234", 305)); |
|||
CHECK_EQ(1234e304, StrtodChar("000000001234", 304)); |
|||
CHECK_EQ(V8_INFINITY, StrtodChar("0000000018", 307)); |
|||
CHECK_EQ(17e307, StrtodChar("0000000017", 307)); |
|||
CHECK_EQ(V8_INFINITY, StrtodChar("1000000", 303)); |
|||
CHECK_EQ(1e308, StrtodChar("100000", 303)); |
|||
CHECK_EQ(1234e305, StrtodChar("123400000", 300)); |
|||
CHECK_EQ(1234e304, StrtodChar("123400000", 299)); |
|||
CHECK_EQ(V8_INFINITY, StrtodChar("180000000", 300)); |
|||
CHECK_EQ(17e307, StrtodChar("170000000", 300)); |
|||
CHECK_EQ(V8_INFINITY, StrtodChar("00000001000000", 303)); |
|||
CHECK_EQ(1e308, StrtodChar("000000000000100000", 303)); |
|||
CHECK_EQ(1234e305, StrtodChar("00000000123400000", 300)); |
|||
CHECK_EQ(1234e304, StrtodChar("0000000123400000", 299)); |
|||
CHECK_EQ(V8_INFINITY, StrtodChar("00000000180000000", 300)); |
|||
CHECK_EQ(17e307, StrtodChar("00000000170000000", 300)); |
|||
} |
@ -0,0 +1,35 @@ |
|||
// Copyright 2010 the V8 project authors. All rights reserved.
|
|||
// Redistribution and use in source and binary forms, with or without
|
|||
// modification, are permitted provided that the following conditions are
|
|||
// met:
|
|||
//
|
|||
// * Redistributions of source code must retain the above copyright
|
|||
// notice, this list of conditions and the following disclaimer.
|
|||
// * Redistributions in binary form must reproduce the above
|
|||
// copyright notice, this list of conditions and the following
|
|||
// disclaimer in the documentation and/or other materials provided
|
|||
// with the distribution.
|
|||
// * Neither the name of Google Inc. nor the names of its
|
|||
// contributors may be used to endorse or promote products derived
|
|||
// from this software without specific prior written permission.
|
|||
//
|
|||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
|||
// See: http://code.google.com/p/chromium/issues/detail?id=58740
|
|||
|
|||
var re = /.+/g; |
|||
re.exec(""); |
|||
re.exec("anystring"); |
|||
re=/.+/g; |
|||
re.exec(""); |
|||
assertEquals(0, re.lastIndex); |
@ -0,0 +1,58 @@ |
|||
// Copyright 2010 the V8 project authors. All rights reserved.
|
|||
// Redistribution and use in source and binary forms, with or without
|
|||
// modification, are permitted provided that the following conditions are
|
|||
// met:
|
|||
//
|
|||
// * Redistributions of source code must retain the above copyright
|
|||
// notice, this list of conditions and the following disclaimer.
|
|||
// * Redistributions in binary form must reproduce the above
|
|||
// copyright notice, this list of conditions and the following
|
|||
// disclaimer in the documentation and/or other materials provided
|
|||
// with the distribution.
|
|||
// * Neither the name of Google Inc. nor the names of its
|
|||
// contributors may be used to endorse or promote products derived
|
|||
// from this software without specific prior written permission.
|
|||
//
|
|||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
|||
// Flags: --max-new-space-size=256
|
|||
|
|||
// Check for GC bug constructing exceptions.
|
|||
var v = [1, 2, 3, 4] |
|||
|
|||
Object.preventExtensions(v); |
|||
|
|||
function foo() { |
|||
var re = /2147483647/; // Equal to 0x7fffffff.
|
|||
for (var i = 0; i < 10000; i++) { |
|||
var ok = false; |
|||
try { |
|||
var j = 1; |
|||
// Allocate some heap numbers in order to randomize the behaviour of the
|
|||
// garbage collector. 93 is chosen to be a prime number to avoid the
|
|||
// allocation settling into a too neat pattern.
|
|||
for (var j = 0; j < i % 93; j++) { |
|||
j *= 1.123567; // An arbitrary floating point number.
|
|||
} |
|||
v[0x7fffffff] = 0; // Trigger exception.
|
|||
assertTrue(false); |
|||
return j; // Make sure that future optimizations don't eliminate j.
|
|||
} catch(e) { |
|||
ok = true; |
|||
assertTrue(re.test(e)); |
|||
} |
|||
assertTrue(ok); |
|||
} |
|||
} |
|||
|
|||
foo(); |
Loading…
Reference in new issue