diff options
author | Kristian Monsen <kristianm@google.com> | 2010-09-08 12:18:00 +0100 |
---|---|---|
committer | Kristian Monsen <kristianm@google.com> | 2010-09-11 12:08:58 +0100 |
commit | 5ddde30071f639962dd557c453f2ad01f8f0fd00 (patch) | |
tree | 775803c4ab35af50aa5f5472cd1fb95fe9d5152d /JavaScriptCore/wtf | |
parent | 3e63d9b33b753ca86d0765d1b3d711114ba9e34f (diff) | |
download | external_webkit-5ddde30071f639962dd557c453f2ad01f8f0fd00.zip external_webkit-5ddde30071f639962dd557c453f2ad01f8f0fd00.tar.gz external_webkit-5ddde30071f639962dd557c453f2ad01f8f0fd00.tar.bz2 |
Merge WebKit at r66666 : Initial merge by git.
Change-Id: I57dedeb49859adc9c539e760f0e749768c66626f
Diffstat (limited to 'JavaScriptCore/wtf')
30 files changed, 867 insertions, 964 deletions
diff --git a/JavaScriptCore/wtf/Assertions.cpp b/JavaScriptCore/wtf/Assertions.cpp index cadbc91..273e0e0 100644 --- a/JavaScriptCore/wtf/Assertions.cpp +++ b/JavaScriptCore/wtf/Assertions.cpp @@ -35,7 +35,7 @@ #include <CoreFoundation/CFString.h> #endif -#if COMPILER(MSVC) && !OS(WINCE) +#if COMPILER(MSVC) && !OS(WINCE) && !PLATFORM(BREWMP) #ifndef WINVER #define WINVER 0x0500 #endif @@ -50,8 +50,40 @@ #include <winbase.h> #endif +#if PLATFORM(BREWMP) +#include <AEEStdLib.h> +#include <wtf/Vector.h> +#endif + extern "C" { +#if PLATFORM(BREWMP) + +static void printLog(const Vector<char>& buffer) +{ + // Each call to DBGPRINTF generates at most 128 bytes of output on the Windows SDK. + // On Qualcomm chipset targets, DBGPRINTF() comes out the diag port (though this may change). + // The length of each output string is constrained even more than on the Windows SDK. +#if COMPILER(MSVC) + const int printBufferSize = 128; +#else + const int printBufferSize = 32; +#endif + + char printBuffer[printBufferSize + 1]; + printBuffer[printBufferSize] = 0; // to guarantee null termination + + const char* p = buffer.data(); + const char* end = buffer.data() + buffer.size(); + while (p < end) { + strncpy(printBuffer, p, printBufferSize); + DBGPRINTF(printBuffer); + p += printBufferSize; + } +} + +#endif + WTF_ATTRIBUTE_PRINTF(1, 0) static void vprintf_stderr_common(const char* format, va_list args) { @@ -71,6 +103,16 @@ static void vprintf_stderr_common(const char* format, va_list args) CFRelease(str); CFRelease(cfFormat); } else +#elif PLATFORM(BREWMP) + // When str is 0, the return value is the number of bytes needed + // to accept the result including null termination. + int size = vsnprintf(0, 0, format, args); + if (size > 0) { + Vector<char> buffer(size); + vsnprintf(buffer.data(), size, format, args); + printLog(buffer); + } + #elif COMPILER(MSVC) && !defined(WINCEBASIC) if (IsDebuggerPresent()) { size_t size = 1024; diff --git a/JavaScriptCore/wtf/Assertions.h b/JavaScriptCore/wtf/Assertions.h index afeae0c..c4e015d 100644 --- a/JavaScriptCore/wtf/Assertions.h +++ b/JavaScriptCore/wtf/Assertions.h @@ -212,7 +212,14 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann #define ASSERT(assertion) ((void)0) #define ASSERT_NOT_REACHED() ((void)0) + +#if COMPILER(INTEL) && !OS(WINDOWS) || COMPILER(RVCT) +template<typename T> +inline void assertUnused(T& x) { (void)x; } +#define ASSERT_UNUSED(variable, assertion) (assertUnused(variable)) +#else #define ASSERT_UNUSED(variable, assertion) ((void)variable) +#endif #else diff --git a/JavaScriptCore/wtf/Complex.h b/JavaScriptCore/wtf/Complex.h index cfd1d20..7da8511 100644 --- a/JavaScriptCore/wtf/Complex.h +++ b/JavaScriptCore/wtf/Complex.h @@ -26,13 +26,13 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef Complex_h -#define Complex_h +#ifndef WTF_Complex_h +#define WTF_Complex_h #include <complex> #include <wtf/MathExtras.h> -namespace WebCore { +namespace WTF { typedef std::complex<double> Complex; @@ -41,6 +41,6 @@ inline Complex complexFromMagnitudePhase(double magnitude, double phase) return Complex(magnitude * cos(phase), magnitude * sin(phase)); } -} // namespace WebCore +} // namespace WTF -#endif // Complex_h +#endif // WTF_Complex_h diff --git a/JavaScriptCore/wtf/DecimalNumber.h b/JavaScriptCore/wtf/DecimalNumber.h index 118c492..3a831b7 100644 --- a/JavaScriptCore/wtf/DecimalNumber.h +++ b/JavaScriptCore/wtf/DecimalNumber.h @@ -40,111 +40,48 @@ class DecimalNumber { public: DecimalNumber(double d) { - bool sign = d < 0; // This (correctly) ignores the sign on -0.0. - init(sign, d); + ASSERT(!isnan(d) && !isinf(d)); + dtoa(m_significand, d, m_sign, m_exponent, m_precision); + + ASSERT(m_precision); + // Zero should always have exponent 0. + ASSERT(m_significand[0] != '0' || !m_exponent); + // No values other than zero should have a leading zero. + ASSERT(m_significand[0] != '0' || m_precision == 1); + // No values other than zero should have trailing zeros. + ASSERT(m_significand[0] == '0' || m_significand[m_precision - 1] != '0'); } - // If our version of dtoa could round to a given number of significant figures then - // we could remove the pre-rounding code from here. We could also do so just by - // calling dtoa and post-rounding, however currently this is slower, since it forces - // dtoa to generate a higher presision result. DecimalNumber(double d, RoundingSignificantFiguresType, unsigned significantFigures) { ASSERT(!isnan(d) && !isinf(d)); - ASSERT(significantFigures && significantFigures <= 21); - - bool sign = d < 0; // This (correctly) ignores the sign on -0.0. - d = fabs(d); // make d positive before going any further. - - int adjust = 0; - if (d) { - // To round a number we align it such that the correct number of digits are - // to the left of the decimal point, then floor/ceil. For example, to round - // 13579 to 3 s.f. we first adjust it to 135.79, use floor/ceil to obtain the - // values 135/136, and then select 136 (since this is closest to 135.79). - // There are currently (exp + 1) digits to the left of the decimal point, - // and we want thsi to be significantFigures, so we're going to adjust the - // exponent by ((exp + 1) - significantFigures). Adjust is effectively - // a count of how many decimal digits to right-shift the number by. - int exp = static_cast<int>(floor(log10(d))); - adjust = (exp + 1) - significantFigures; - - // If the adjust value might be positive or negative - or zero. If zero, then - // nothing to do! - the number is already appropriately aligned. If adjust - // is positive then divide d by 10^adjust. If adjust is negative multiply d - // by 10^-adjust. This is mathematically the same, but avoids two fp divides - // (one inside intPow10, where the power is negative). - if (adjust > 0) - d /= intPow10(adjust); - else if (adjust < 0) - d *= intPow10(-adjust); - - // Try rounding up & rounding down, select whichever is closest (rounding up if equal distance). - double floorOfD = floor(d); - double ceilOfD = floorOfD + 1; - d = (fabs(ceilOfD - d) <= fabs(floorOfD - d)) ? ceilOfD : floorOfD; - - // The number's exponent has been altered - but don't change it back! We can - // just run dtoa on the modified value, and adjust the exponent afterward to - // account for this. - } - - init(sign, d); + dtoaRoundSF(m_significand, d, significantFigures, m_sign, m_exponent, m_precision); - // We alterered the value when rounding it - modify the exponent to adjust for this, - // but don't mess with the exponent of zero. - if (!isZero()) - m_exponent += adjust; + ASSERT(significantFigures && significantFigures <= sizeof(DtoaBuffer)); + while (m_precision < significantFigures) + m_significand[m_precision++] = '0'; - // Make sure the significand does not contain more digits than requested. - roundToPrecision(significantFigures); + ASSERT(m_precision); + // Zero should always have exponent 0. + ASSERT(m_significand[0] != '0' || !m_exponent); } - // If our version of dtoa could round to a given number of decimal places then we - // could remove the pre-rounding code from here. We could also do so just by calling - // dtoa and post-rounding, however currently this is slower, since it forces dtoa to - // generate a higher presision result. DecimalNumber(double d, RoundingDecimalPlacesType, unsigned decimalPlaces) { ASSERT(!isnan(d) && !isinf(d)); - ASSERT(decimalPlaces <= 20); - - bool sign = d < 0; // This (correctly) ignores the sign on -0.0. - d = fabs(d); // Make d positive before going any further. - - ASSERT(d < 1e+21); // We don't currently support rounding to decimal places for values >= 1e+21. - - // Adjust the number by increasing the exponent by decimalPlaces, such - // that we can round to this number of decimal places jsing floor. - if (decimalPlaces) - d *= intPow10(decimalPlaces); - // Try rounding up & rounding down, select whichever is closest (rounding up if equal distance). - double floorOfD = floor(d); - double ceilOfD = floorOfD + 1; - d = (fabs(ceilOfD - d) <= fabs(floorOfD - d)) ? ceilOfD : floorOfD; - // The number's exponent has been altered - but don't change it back! We can - // just run dtoa on the modified value, and adjust the exponent afterward to - // account for this. - - init(sign, d); - - // We rouned the value before calling dtoa, so the result should not be fractional. - ASSERT(m_exponent >= 0); - - // We alterered the value when rounding it - modify the exponent to adjust for this, - // but don't mess with the exponent of zero. - if (!isZero()) - m_exponent -= decimalPlaces; - - // The value was < 1e+21 before we started, should still be. - ASSERT(m_exponent < 21); + dtoaRoundDP(m_significand, d, decimalPlaces, m_sign, m_exponent, m_precision); unsigned significantFigures = 1 + m_exponent + decimalPlaces; - ASSERT(significantFigures && significantFigures <= 41); - roundToPrecision(significantFigures); + ASSERT(significantFigures && significantFigures <= sizeof(DtoaBuffer)); + while (m_precision < significantFigures) + m_significand[m_precision++] = '0'; + + ASSERT(m_precision); + // Zero should always have exponent 0. + ASSERT(m_significand[0] != '0' || !m_exponent); } - unsigned toStringDecimal(NumberToStringBuffer& buffer) + unsigned toStringDecimal(NumberToStringBuffer buffer) { // Should always be at least one digit to add to the string! ASSERT(m_precision); @@ -198,7 +135,7 @@ public: return next - buffer; } - unsigned toStringExponential(NumberToStringBuffer &buffer) + unsigned toStringExponential(NumberToStringBuffer buffer) { // Should always be at least one digit to add to the string! ASSERT(m_precision); @@ -244,75 +181,6 @@ public: unsigned precision() { return m_precision; } private: - void init(bool sign, double d) - { - ASSERT(!isnan(d) && !isinf(d)); - - int decimalPoint; - int signUnused; - char* resultEnd = 0; - WTF::dtoa(m_significand, d, 0, &decimalPoint, &signUnused, &resultEnd); - - m_sign = sign; - m_precision = resultEnd - m_significand; - m_exponent = decimalPoint - 1; - - // No values other than zero should have a leading zero. - ASSERT(m_significand[0] != '0' || m_precision == 1); - // Zero should always have exponent 0. - ASSERT(m_significand[0] != '0' || !m_exponent); - } - - bool isZero() - { - return m_significand[0] == '0'; - } - - // We pre-round the values to dtoa - which leads to it generating faster results. - // But dtoa won't have zero padded the significand to the precision we require, - // and also might have produced too many digits if rounding went wrong somehow. - // Adjust for this. - void roundToPrecision(unsigned significantFigures) - { - ASSERT(significantFigures && significantFigures <= sizeof(DtoaBuffer)); - - // If there are too few of too many digits in the significand then add more, or remove some! - for (unsigned i = m_precision; i < significantFigures; ++i) - m_significand[i] = '0'; - m_precision = significantFigures; - } - - double intPow10(int e) - { - // This function uses the "exponentiation by squaring" algorithm and - // long double to quickly and precisely calculate integer powers of 10.0. - - // This is a handy workaround for <rdar://problem/4494756> - - if (!e) - return 1.0; - - bool negative = e < 0; - unsigned exp = negative ? -e : e; - - long double result = 10.0; - bool foundOne = false; - for (int bit = 31; bit >= 0; bit--) { - if (!foundOne) { - if ((exp >> bit) & 1) - foundOne = true; - } else { - result = result * result; - if ((exp >> bit) & 1) - result = result * 10.0; - } - } - - if (negative) - return static_cast<double>(1.0 / result); - return static_cast<double>(result); - } - bool m_sign; int m_exponent; DtoaBuffer m_significand; diff --git a/JavaScriptCore/wtf/FastMalloc.cpp b/JavaScriptCore/wtf/FastMalloc.cpp index 39cd324..ee6b02c 100644 --- a/JavaScriptCore/wtf/FastMalloc.cpp +++ b/JavaScriptCore/wtf/FastMalloc.cpp @@ -1546,7 +1546,8 @@ void TCMalloc_PageHeap::scavenge() SpanList* slist = (static_cast<size_t>(i) == kMaxPages) ? &large_ : &free_[i]; // If the span size is bigger than kMinSpanListsWithSpans pages return all the spans in the list, else return all but 1 span. // Return only 50% of a spanlist at a time so spans of size 1 are not the only ones left. - size_t numSpansToReturn = (i > kMinSpanListsWithSpans) ? DLL_Length(&slist->normal) : static_cast<size_t>(.5 * DLL_Length(&slist->normal)); + size_t length = DLL_Length(&slist->normal); + size_t numSpansToReturn = (i > kMinSpanListsWithSpans) ? length : length / 2; for (int j = 0; static_cast<size_t>(j) < numSpansToReturn && !DLL_IsEmpty(&slist->normal) && free_committed_pages_ > targetPageCount; j++) { Span* s = slist->normal.prev; DLL_Remove(s); diff --git a/JavaScriptCore/wtf/Forward.h b/JavaScriptCore/wtf/Forward.h index 32435c8..3a9cfa7 100644 --- a/JavaScriptCore/wtf/Forward.h +++ b/JavaScriptCore/wtf/Forward.h @@ -27,6 +27,7 @@ namespace WTF { template<typename T> class ListRefPtr; template<typename T> class OwnArrayPtr; template<typename T> class OwnPtr; + template<typename T> class PassOwnArrayPtr; template<typename T> class PassOwnPtr; template<typename T> class PassRefPtr; template<typename T> class RefPtr; @@ -43,6 +44,7 @@ namespace WTF { using WTF::ListRefPtr; using WTF::OwnArrayPtr; using WTF::OwnPtr; +using WTF::PassOwnArrayPtr; using WTF::PassOwnPtr; using WTF::PassRefPtr; using WTF::RefPtr; diff --git a/JavaScriptCore/wtf/OwnArrayPtr.h b/JavaScriptCore/wtf/OwnArrayPtr.h index d40ea17..ce056b3 100644 --- a/JavaScriptCore/wtf/OwnArrayPtr.h +++ b/JavaScriptCore/wtf/OwnArrayPtr.h @@ -21,74 +21,154 @@ #ifndef WTF_OwnArrayPtr_h #define WTF_OwnArrayPtr_h +#include "Assertions.h" +#include "Noncopyable.h" +#include "OwnArrayPtrCommon.h" #include <algorithm> -#include <wtf/Assertions.h> -#include <wtf/Noncopyable.h> + +// Remove this once we make all WebKit code compatible with stricter rules about OwnArrayPtr. +#define LOOSE_OWN_ARRAY_PTR namespace WTF { - template <typename T> class OwnArrayPtr : public Noncopyable { - public: - explicit OwnArrayPtr(T* ptr = 0) : m_ptr(ptr) { } - ~OwnArrayPtr() { safeDelete(m_ptr); } +template<typename T> class PassOwnArrayPtr; +template<typename T> PassOwnArrayPtr<T> adoptArrayPtr(T*); + +template <typename T> class OwnArrayPtr : public Noncopyable { +public: + typedef T* PtrType; + + OwnArrayPtr() : m_ptr(0) { } - T* get() const { return m_ptr; } - T* release() { T* ptr = m_ptr; m_ptr = 0; return ptr; } + // See comment in PassOwnArrayPtr.h for why this takes a const reference. + template<typename U> OwnArrayPtr(const PassOwnArrayPtr<U>& o); - // FIXME: This should be removed and replaced with PassOwnArrayPtr. - void set(T* ptr) - { - ASSERT(!ptr || m_ptr != ptr); - T* oldPtr = m_ptr; - m_ptr = ptr; - safeDelete(oldPtr); - } + // This copy constructor is used implicitly by gcc when it generates + // transients for assigning a PassOwnArrayPtr<T> object to a stack-allocated + // OwnArrayPtr<T> object. It should never be called explicitly and gcc + // should optimize away the constructor when generating code. + OwnArrayPtr(const OwnArrayPtr<T>&); - void clear(); + ~OwnArrayPtr() { deleteOwnedArrayPtr(m_ptr); } - T& operator*() const { ASSERT(m_ptr); return *m_ptr; } - T* operator->() const { ASSERT(m_ptr); return m_ptr; } + PtrType get() const { return m_ptr; } - T& operator[](std::ptrdiff_t i) const { ASSERT(m_ptr); ASSERT(i >= 0); return m_ptr[i]; } + void clear(); + PassOwnArrayPtr<T> release(); + PtrType leakPtr() WARN_UNUSED_RETURN; - bool operator!() const { return !m_ptr; } + T& operator*() const { ASSERT(m_ptr); return *m_ptr; } + PtrType operator->() const { ASSERT(m_ptr); return m_ptr; } - // This conversion operator allows implicit conversion to bool but not to other integer types. + T& operator[](std::ptrdiff_t i) const { ASSERT(m_ptr); ASSERT(i >= 0); return m_ptr[i]; } + + bool operator!() const { return !m_ptr; } + + // This conversion operator allows implicit conversion to bool but not to other integer types. #if COMPILER(WINSCW) - operator bool() const { return m_ptr; } + operator bool() const { return m_ptr; } #else - typedef T* OwnArrayPtr::*UnspecifiedBoolType; - operator UnspecifiedBoolType() const { return m_ptr ? &OwnArrayPtr::m_ptr : 0; } + typedef T* OwnArrayPtr::*UnspecifiedBoolType; + operator UnspecifiedBoolType() const { return m_ptr ? &OwnArrayPtr::m_ptr : 0; } +#endif + + OwnArrayPtr& operator=(const PassOwnArrayPtr<T>&); + template<typename U> OwnArrayPtr& operator=(const PassOwnArrayPtr<U>&); + + void swap(OwnArrayPtr& o) { std::swap(m_ptr, o.m_ptr); } + +#ifdef LOOSE_OWN_ARRAY_PTR + explicit OwnArrayPtr(PtrType ptr) : m_ptr(ptr) { } + void set(PtrType); +#endif + +private: + PtrType m_ptr; +}; + +template<typename T> template<typename U> inline OwnArrayPtr<T>::OwnArrayPtr(const PassOwnArrayPtr<U>& o) + : m_ptr(o.leakPtr()) +{ +} + +template<typename T> inline void OwnArrayPtr<T>::clear() +{ + PtrType ptr = m_ptr; + m_ptr = 0; + deleteOwnedArrayPtr(ptr); +} + +template<typename T> inline PassOwnArrayPtr<T> OwnArrayPtr<T>::release() +{ + PtrType ptr = m_ptr; + m_ptr = 0; + return adoptArrayPtr(ptr); +} + +template<typename T> inline typename OwnArrayPtr<T>::PtrType OwnArrayPtr<T>::leakPtr() +{ + PtrType ptr = m_ptr; + m_ptr = 0; + return ptr; +} + +#ifdef LOOSE_OWN_ARRAY_PTR +template<typename T> inline void OwnArrayPtr<T>::set(PtrType ptr) +{ + ASSERT(!ptr || m_ptr != ptr); + PtrType oldPtr = m_ptr; + m_ptr = ptr; + deleteOwnedPtr(oldPtr); +} #endif - void swap(OwnArrayPtr& o) { std::swap(m_ptr, o.m_ptr); } - - private: - static void safeDelete(T*); - - T* m_ptr; - }; - - template<typename T> inline void OwnArrayPtr<T>::clear() - { - T* ptr = m_ptr; - m_ptr = 0; - safeDelete(ptr); - } - - template<typename T> inline void OwnArrayPtr<T>::safeDelete(T* ptr) - { - typedef char known[sizeof(T) ? 1 : -1]; - if (sizeof(known)) - delete [] ptr; - } - - template <typename T> inline void swap(OwnArrayPtr<T>& a, OwnArrayPtr<T>& b) { a.swap(b); } - - template <typename T> inline T* getPtr(const OwnArrayPtr<T>& p) - { - return p.get(); - } +template<typename T> inline OwnArrayPtr<T>& OwnArrayPtr<T>::operator=(const PassOwnArrayPtr<T>& o) +{ + PtrType ptr = m_ptr; + m_ptr = o.leakPtr(); + ASSERT(!ptr || m_ptr != ptr); + deleteOwnedArrayPtr(ptr); + return *this; +} + +template<typename T> template<typename U> inline OwnArrayPtr<T>& OwnArrayPtr<T>::operator=(const PassOwnArrayPtr<U>& o) +{ + PtrType ptr = m_ptr; + m_ptr = o.leakPtr(); + ASSERT(!ptr || m_ptr != ptr); + deleteOwnedArrayPtr(ptr); + return *this; +} + +template <typename T> inline void swap(OwnArrayPtr<T>& a, OwnArrayPtr<T>& b) +{ + a.swap(b); +} + +template<typename T, typename U> inline bool operator==(const OwnArrayPtr<T>& a, U* b) +{ + return a.get() == b; +} + +template<typename T, typename U> inline bool operator==(T* a, const OwnArrayPtr<U>& b) +{ + return a == b.get(); +} + +template<typename T, typename U> inline bool operator!=(const OwnArrayPtr<T>& a, U* b) +{ + return a.get() != b; +} + +template<typename T, typename U> inline bool operator!=(T* a, const OwnArrayPtr<U>& b) +{ + return a != b.get(); +} + +template <typename T> inline T* getPtr(const OwnArrayPtr<T>& p) +{ + return p.get(); +} } // namespace WTF diff --git a/JavaScriptCore/wtf/OwnArrayPtrCommon.h b/JavaScriptCore/wtf/OwnArrayPtrCommon.h new file mode 100644 index 0000000..0113aff --- /dev/null +++ b/JavaScriptCore/wtf/OwnArrayPtrCommon.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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 WTF_OwnArrayPtrCommon_h +#define WTF_OwnArrayPtrCommon_h + +namespace WTF { + +template<typename T> inline void deleteOwnedArrayPtr(T* ptr) +{ + typedef char known[sizeof(T) ? 1 : -1]; + if (sizeof(known)) + delete [] ptr; +} + +} // namespace WTF + +#endif // WTF_OwnArrayPtrCommon_h diff --git a/JavaScriptCore/wtf/PassOwnArrayPtr.h b/JavaScriptCore/wtf/PassOwnArrayPtr.h new file mode 100644 index 0000000..597339c --- /dev/null +++ b/JavaScriptCore/wtf/PassOwnArrayPtr.h @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE INC. 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 WTF_PassOwnArrayPtr_h +#define WTF_PassOwnArrayPtr_h + +#include "Assertions.h" +#include "OwnArrayPtrCommon.h" +#include "TypeTraits.h" + +// Remove this once we make all WebKit code compatible with stricter rules about PassOwnArrayPtr. +#define LOOSE_PASS_OWN_ARRAY_PTR + +namespace WTF { + +template<typename T> class OwnArrayPtr; +template<typename T> class PassOwnArrayPtr; +template<typename T> PassOwnArrayPtr<T> adoptArrayPtr(T*); + +template<typename T> class PassOwnArrayPtr { +public: + typedef T* PtrType; + + PassOwnArrayPtr() : m_ptr(0) { } + + // It somewhat breaks the type system to allow transfer of ownership out of + // a const PassOwnArrayPtr. However, it makes it much easier to work with PassOwnArrayPtr + // temporaries, and we don't have a need to use real const PassOwnArrayPtrs anyway. + PassOwnArrayPtr(const PassOwnArrayPtr& o) : m_ptr(o.leakPtr()) { } + template<typename U> PassOwnArrayPtr(const PassOwnArrayPtr<U>& o) : m_ptr(o.leakPtr()) { } + + ~PassOwnArrayPtr() { deleteOwnedArrayPtr(m_ptr); } + + PtrType get() const { return m_ptr; } + + void clear(); + PtrType leakPtr() const WARN_UNUSED_RETURN; + + T& operator*() const { ASSERT(m_ptr); return *m_ptr; } + PtrType operator->() const { ASSERT(m_ptr); return m_ptr; } + + bool operator!() const { return !m_ptr; } + + // This conversion operator allows implicit conversion to bool but not to other integer types. +#if COMPILER(WINSCW) + operator bool() const { return m_ptr; } +#else + typedef PtrType PassOwnArrayPtr::*UnspecifiedBoolType; + operator UnspecifiedBoolType() const { return m_ptr ? &PassOwnArrayPtr::m_ptr : 0; } +#endif + + PassOwnArrayPtr& operator=(const PassOwnArrayPtr<T>&); + template<typename U> PassOwnArrayPtr& operator=(const PassOwnArrayPtr<U>&); + + template<typename U> friend PassOwnArrayPtr<U> adoptArrayPtr(U*); + +#ifdef LOOSE_PASS_OWN_ARRAY_PTR + PassOwnArrayPtr(PtrType ptr) : m_ptr(ptr) { } + PassOwnArrayPtr& operator=(PtrType); +#endif + +private: +#ifndef LOOSE_PASS_OWN_ARRAY_PTR + explicit PassOwnArrayPtr(PtrType ptr) : m_ptr(ptr) { } +#endif + + mutable PtrType m_ptr; +}; + +template<typename T> inline void PassOwnArrayPtr<T>::clear() +{ + PtrType ptr = m_ptr; + m_ptr = 0; + deleteOwnedArrayPtr(ptr); +} + +template<typename T> inline typename PassOwnArrayPtr<T>::PtrType PassOwnArrayPtr<T>::leakPtr() const +{ + PtrType ptr = m_ptr; + m_ptr = 0; + return ptr; +} + +#ifdef LOOSE_PASS_OWN_ARRAY_PTR +template<typename T> inline PassOwnArrayPtr<T>& PassOwnArrayPtr<T>::operator=(PtrType optr) +{ + PtrType ptr = m_ptr; + m_ptr = optr; + ASSERT(!ptr || m_ptr != ptr); + if (ptr) + deleteOwnedArrayPtr(ptr); + return *this; +} +#endif + +template<typename T> inline PassOwnArrayPtr<T>& PassOwnArrayPtr<T>::operator=(const PassOwnArrayPtr<T>& optr) +{ + PtrType ptr = m_ptr; + m_ptr = optr.leakPtr(); + ASSERT(!ptr || m_ptr != ptr); + if (ptr) + deleteOwnedArrayPtr(ptr); + return *this; +} + +template<typename T> template<typename U> inline PassOwnArrayPtr<T>& PassOwnArrayPtr<T>::operator=(const PassOwnArrayPtr<U>& optr) +{ + PtrType ptr = m_ptr; + m_ptr = optr.leakPtr(); + ASSERT(!ptr || m_ptr != ptr); + if (ptr) + deleteOwnedArrayPtr(ptr); + return *this; +} + +template<typename T, typename U> inline bool operator==(const PassOwnArrayPtr<T>& a, const PassOwnArrayPtr<U>& b) +{ + return a.get() == b.get(); +} + +template<typename T, typename U> inline bool operator==(const PassOwnArrayPtr<T>& a, const OwnArrayPtr<U>& b) +{ + return a.get() == b.get(); +} + +template<typename T, typename U> inline bool operator==(const OwnArrayPtr<T>& a, const PassOwnArrayPtr<U>& b) +{ + return a.get() == b.get(); +} + +template<typename T, typename U> inline bool operator==(const PassOwnArrayPtr<T>& a, U* b) +{ + return a.get() == b; +} + +template<typename T, typename U> inline bool operator==(T* a, const PassOwnArrayPtr<U>& b) +{ + return a == b.get(); +} + +template<typename T, typename U> inline bool operator!=(const PassOwnArrayPtr<T>& a, const PassOwnArrayPtr<U>& b) +{ + return a.get() != b.get(); +} + +template<typename T, typename U> inline bool operator!=(const PassOwnArrayPtr<T>& a, const OwnArrayPtr<U>& b) +{ + return a.get() != b.get(); +} + +template<typename T, typename U> inline bool operator!=(const OwnArrayPtr<T>& a, const PassOwnArrayPtr<U>& b) +{ + return a.get() != b.get(); +} + +template<typename T, typename U> inline bool operator!=(const PassOwnArrayPtr<T>& a, U* b) +{ + return a.get() != b; +} + +template<typename T, typename U> inline bool operator!=(T* a, const PassOwnArrayPtr<U>& b) +{ + return a != b.get(); +} + +template<typename T> inline PassOwnArrayPtr<T> adoptArrayPtr(T* ptr) +{ + return PassOwnArrayPtr<T>(ptr); +} + +template<typename T, typename U> inline PassOwnArrayPtr<T> static_pointer_cast(const PassOwnArrayPtr<U>& p) +{ + return adoptArrayPtr(static_cast<T*>(p.leakPtr())); +} + +template<typename T, typename U> inline PassOwnArrayPtr<T> const_pointer_cast(const PassOwnArrayPtr<U>& p) +{ + return adoptArrayPtr(const_cast<T*>(p.leakPtr())); +} + +template<typename T> inline T* getPtr(const PassOwnArrayPtr<T>& p) +{ + return p.get(); +} + +} // namespace WTF + +using WTF::PassOwnArrayPtr; +using WTF::adoptArrayPtr; +using WTF::const_pointer_cast; +using WTF::static_pointer_cast; + +#endif // WTF_PassOwnArrayPtr_h diff --git a/JavaScriptCore/wtf/Platform.h b/JavaScriptCore/wtf/Platform.h index 727616f..4fc0a64 100644 --- a/JavaScriptCore/wtf/Platform.h +++ b/JavaScriptCore/wtf/Platform.h @@ -520,7 +520,6 @@ /* PLATFORM(SKIA) for Win/Linux, CG/CI for Mac */ #if PLATFORM(CHROMIUM) -#define ENABLE_HISTORY_ALWAYS_ASYNC 1 #if OS(DARWIN) #define WTF_PLATFORM_CG 1 #define WTF_PLATFORM_CI 1 @@ -528,7 +527,6 @@ #define WTF_USE_CORE_TEXT 1 #else #define WTF_PLATFORM_SKIA 1 -#define WTF_USE_GLES2_RENDERING 1 #endif #endif @@ -596,6 +594,7 @@ #endif #define HAVE_READLINE 1 #define HAVE_RUNLOOP_TIMER 1 +#define ENABLE_FULLSCREEN_API 1 #endif /* PLATFORM(MAC) && !PLATFORM(IOS) */ #if PLATFORM(MAC) @@ -617,6 +616,10 @@ #define WTF_PLATFORM_CF 1 #endif +#if OS(DARWIN) && !defined(BUILDING_ON_TIGER) && !PLATFORM(GTK) && !PLATFORM(QT) +#define ENABLE_PURGEABLE_MEMORY 1 +#endif + #if PLATFORM(IOS) #define ENABLE_CONTEXT_MENUS 0 #define ENABLE_DRAG_SUPPORT 0 @@ -858,6 +861,14 @@ #define ENABLE_NETSCAPE_PLUGIN_API 1 #endif +#if !defined(ENABLE_NETSCAPE_PLUGIN_METADATA_CACHE) +#define ENABLE_NETSCAPE_PLUGIN_METADATA_CACHE 0 +#endif + +#if !defined(ENABLE_PURGEABLE_MEMORY) +#define ENABLE_PURGEABLE_MEMORY 0 +#endif + #if !defined(WTF_USE_PLUGIN_HOST_PROCESS) #define WTF_USE_PLUGIN_HOST_PROCESS 0 #endif @@ -917,6 +928,10 @@ #define ENABLE_ON_FIRST_TEXTAREA_FOCUS_SELECT_ALL 0 #endif +#if !defined(ENABLE_FULLSCREEN_API) +#define ENABLE_FULLSCREEN_API 0 +#endif + #if !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32) && !defined(WTF_USE_JSVALUE32_64) #if (CPU(X86_64) && (OS(UNIX) || OS(WINDOWS))) \ || (CPU(IA64) && !CPU(IA64_32)) \ @@ -1118,4 +1133,8 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */ #define ENABLE_BRANCH_COMPACTION 1 #endif +#if PLATFORM(GTK) +#include "GtkTypedefs.h" +#endif + #endif /* WTF_Platform_h */ diff --git a/JavaScriptCore/wtf/TCPageMap.h b/JavaScriptCore/wtf/TCPageMap.h index 3f56c24..99bdc40 100644 --- a/JavaScriptCore/wtf/TCPageMap.h +++ b/JavaScriptCore/wtf/TCPageMap.h @@ -72,7 +72,7 @@ class TCMalloc_PageMap1 { // Ensure that the map contains initialized entries "x .. x+n-1". // Returns true if successful, false if we could not allocate memory. - bool Ensure(Number x, size_t n) { + bool Ensure(Number, size_t) { // Nothing to do since flat array was allocate at start return true; } diff --git a/JavaScriptCore/wtf/ThreadSpecific.h b/JavaScriptCore/wtf/ThreadSpecific.h index 893f561..93ed466 100644 --- a/JavaScriptCore/wtf/ThreadSpecific.h +++ b/JavaScriptCore/wtf/ThreadSpecific.h @@ -67,12 +67,17 @@ public: T* operator->(); operator T*(); T& operator*(); - ~ThreadSpecific(); private: #if !USE(PTHREADS) && !PLATFORM(QT) && !PLATFORM(GTK) && OS(WINDOWS) friend void ThreadSpecificThreadExit(); #endif + + // Not implemented. It's technically possible to destroy a thread specific key, but one would need + // to make sure that all values have been destroyed already (usually, that all threads that used it + // have exited). It's unlikely that any user of this call will be in that situation - and having + // a destructor defined can be confusing, given that it has such strong pre-requisites to work correctly. + ~ThreadSpecific(); T* get(); void set(T*); @@ -116,11 +121,6 @@ inline ThreadSpecific<T>::ThreadSpecific() } template<typename T> -inline ThreadSpecific<T>::~ThreadSpecific() -{ -} - -template<typename T> inline T* ThreadSpecific<T>::get() { return m_value; @@ -143,12 +143,6 @@ inline ThreadSpecific<T>::ThreadSpecific() } template<typename T> -inline ThreadSpecific<T>::~ThreadSpecific() -{ - pthread_key_delete(m_key); // Does not invoke destructor functions. -} - -template<typename T> inline T* ThreadSpecific<T>::get() { Data* data = static_cast<Data*>(pthread_getspecific(m_key)); @@ -170,12 +164,6 @@ inline ThreadSpecific<T>::ThreadSpecific() } template<typename T> -inline ThreadSpecific<T>::~ThreadSpecific() -{ - // Does not invoke destructor functions. QThreadStorage will do it -} - -template<typename T> inline T* ThreadSpecific<T>::get() { Data* data = static_cast<Data*>(m_key.localData()); @@ -199,12 +187,6 @@ inline ThreadSpecific<T>::ThreadSpecific() } template<typename T> -inline ThreadSpecific<T>::~ThreadSpecific() -{ - g_static_private_free(&m_key); -} - -template<typename T> inline T* ThreadSpecific<T>::get() { Data* data = static_cast<Data*>(g_static_private_get(&m_key)); diff --git a/JavaScriptCore/wtf/ThreadingPrimitives.h b/JavaScriptCore/wtf/ThreadingPrimitives.h index 66801c0..c11a6cb 100644 --- a/JavaScriptCore/wtf/ThreadingPrimitives.h +++ b/JavaScriptCore/wtf/ThreadingPrimitives.h @@ -45,8 +45,6 @@ #include <pthread.h> #elif PLATFORM(GTK) #include "GOwnPtr.h" -typedef struct _GMutex GMutex; -typedef struct _GCond GCond; #endif #if PLATFORM(QT) diff --git a/JavaScriptCore/wtf/UnusedParam.h b/JavaScriptCore/wtf/UnusedParam.h index 996f5c8..6ff6fd8 100644 --- a/JavaScriptCore/wtf/UnusedParam.h +++ b/JavaScriptCore/wtf/UnusedParam.h @@ -24,6 +24,14 @@ /* don't use this for C++, it should only be used in plain C files or ObjC methods, where leaving off the parameter name is not allowed. */ -#define UNUSED_PARAM(x) (void)x +#include "Platform.h" + +#if COMPILER(INTEL) && !OS(WINDOWS) || COMPILER(RVCT) +template<typename T> +inline void unusedParam(T& x) { (void)x; } +#define UNUSED_PARAM(variable) unusedParam(variable) +#else +#define UNUSED_PARAM(variable) (void)variable +#endif #endif /* WTF_UnusedParam_h */ diff --git a/JavaScriptCore/wtf/Vector3.h b/JavaScriptCore/wtf/Vector3.h index 3c40b61..1850929 100644 --- a/JavaScriptCore/wtf/Vector3.h +++ b/JavaScriptCore/wtf/Vector3.h @@ -26,12 +26,12 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef Vector3_h -#define Vector3_h +#ifndef WTF_Vector3_h +#define WTF_Vector3_h #include <math.h> -namespace WebCore { +namespace WTF { class Vector3 { public: @@ -133,6 +133,6 @@ inline double distance(const Vector3& v1, const Vector3& v2) return (v1 - v2).abs(); } -} // WebCore +} // WTF -#endif // Vector3_h +#endif // WTF_Vector3_h diff --git a/JavaScriptCore/wtf/WTFThreadData.cpp b/JavaScriptCore/wtf/WTFThreadData.cpp index 729b48e..702baed 100644 --- a/JavaScriptCore/wtf/WTFThreadData.cpp +++ b/JavaScriptCore/wtf/WTFThreadData.cpp @@ -43,6 +43,8 @@ WTFThreadData::WTFThreadData() , m_currentIdentifierTable(m_defaultIdentifierTable) #endif { + char sample = 0; + m_approximatedStackStart = &sample; } WTFThreadData::~WTFThreadData() diff --git a/JavaScriptCore/wtf/WTFThreadData.h b/JavaScriptCore/wtf/WTFThreadData.h index c596260..20ffaca 100644 --- a/JavaScriptCore/wtf/WTFThreadData.h +++ b/JavaScriptCore/wtf/WTFThreadData.h @@ -112,6 +112,11 @@ public: } #endif + char* approximatedStackStart() const + { + return m_approximatedStackStart; + } + private: AtomicStringTable* m_atomicStringTable; AtomicStringTableDestructor m_atomicStringTableDestructor; @@ -128,6 +133,8 @@ private: #endif friend WTFThreadData& wtfThreadData(); friend class AtomicStringTable; + + char* m_approximatedStackStart; }; inline WTFThreadData& wtfThreadData() diff --git a/JavaScriptCore/wtf/dtoa.cpp b/JavaScriptCore/wtf/dtoa.cpp index 88e5692..298bb27 100644 --- a/JavaScriptCore/wtf/dtoa.cpp +++ b/JavaScriptCore/wtf/dtoa.cpp @@ -3,7 +3,7 @@ * The author of this software is David M. Gay. * * Copyright (c) 1991, 2000, 2001 by Lucent Technologies. - * Copyright (C) 2002, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2002, 2005, 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. * * Permission to use, copy, modify, and distribute this software for any * purpose without fee is hereby granted, provided that this entire notice @@ -18,14 +18,8 @@ * ***************************************************************/ -/* Please send bug reports to - David M. Gay - Bell Laboratories, Room 2C-463 - 600 Mountain Avenue - Murray Hill, NJ 07974-0636 - U.S.A. - dmg@bell-labs.com - */ +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ /* On a machine with IEEE extended-precision registers, it is * necessary to specify double-precision (53-bit) rounding precision @@ -50,7 +44,7 @@ * * Modifications: * - * 1. We only require IEEE. + * 1. We only require IEEE double-precision arithmetic (not IEEE double-extended). * 2. We get by with floating-point arithmetic in a case that * Clinger missed -- when we're computing d * 10^n * for a small integer d and the integer n is not too @@ -67,64 +61,13 @@ * for 0 <= k <= 22). */ -/* - * #define IEEE_8087 for IEEE-arithmetic machines where the least - * significant byte has the lowest address. - * #define IEEE_MC68k for IEEE-arithmetic machines where the most - * significant byte has the lowest address. - * #define No_leftright to omit left-right logic in fast floating-point - * computation of dtoa. - * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 - * and Honor_FLT_ROUNDS is not #defined. - * #define Inaccurate_Divide for IEEE-format with correctly rounded - * products but inaccurate quotients, e.g., for Intel i860. - * #define USE_LONG_LONG on machines that have a "long long" - * integer type (of >= 64 bits), and performance testing shows that - * it is faster than 32-bit fallback (which is often not the case - * on 32-bit machines). On such machines, you can #define Just_16 - * to store 16 bits per 32-bit int32_t when doing high-precision integer - * arithmetic. Whether this speeds things up or slows things down - * depends on the machine and the number being converted. - * #define Bad_float_h if your system lacks a float.h or if it does not - * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, - * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. - * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that - * avoids underflows on inputs whose result does not underflow. - * If you #define NO_IEEE_Scale on a machine that uses IEEE-format - * floating-point numbers and flushes underflows to zero rather - * than implementing gradual underflow, then you must also #define - * Sudden_Underflow. - * #define YES_ALIAS to permit aliasing certain double values with - * arrays of ULongs. This leads to slightly better code with - * some compilers and was always used prior to 19990916, but it - * is not strictly legal and can cause trouble with aggressively - * optimizing compilers (e.g., gcc 2.95.1 under -O2). - * #define SET_INEXACT if IEEE arithmetic is being used and extra - * computation should be done to set the inexact flag when the - * result is inexact and avoid setting inexact when the result - * is exact. In this case, dtoa.c must be compiled in - * an environment, perhaps provided by #include "dtoa.c" in a - * suitable wrapper, that defines two functions, - * int get_inexact(void); - * void clear_inexact(void); - * such that get_inexact() returns a nonzero value if the - * inexact bit is already set, and clear_inexact() sets the - * inexact bit to 0. When SET_INEXACT is #defined, strtod - * also does extra computations to set the underflow and overflow - * flags when appropriate (i.e., when the result is tiny and - * inexact or when it is a numeric value rounded to +-infinity). - * #define NO_ERRNO if strtod should not assign errno = ERANGE when - * the result overflows to +-Infinity or underflows to 0. - */ - #include "config.h" #include "dtoa.h" #if HAVE(ERRNO_H) #include <errno.h> -#else -#define NO_ERRNO #endif +#include <float.h> #include <math.h> #include <stdint.h> #include <stdio.h> @@ -132,9 +75,11 @@ #include <string.h> #include <wtf/AlwaysInline.h> #include <wtf/Assertions.h> +#include <wtf/DecimalNumber.h> #include <wtf/FastMalloc.h> #include <wtf/MathExtras.h> #include <wtf/Threading.h> +#include <wtf/UnusedParam.h> #include <wtf/Vector.h> #if COMPILER(MSVC) @@ -143,18 +88,6 @@ #pragma warning(disable: 4554) #endif -#if CPU(BIG_ENDIAN) -#define IEEE_MC68k -#elif CPU(MIDDLE_ENDIAN) -#define IEEE_ARM -#else -#define IEEE_8087 -#endif - -#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(IEEE_ARM) != 1 -Exactly one of IEEE_8087, IEEE_ARM or IEEE_MC68k should be defined. -#endif - namespace WTF { #if ENABLE(JSC_MULTIPLE_THREADS) @@ -166,25 +99,14 @@ typedef union { uint32_t L[2]; } U; -#ifdef YES_ALIAS -#define dval(x) x -#ifdef IEEE_8087 -#define word0(x) ((uint32_t*)&x)[1] -#define word1(x) ((uint32_t*)&x)[0] -#else -#define word0(x) ((uint32_t*)&x)[0] -#define word1(x) ((uint32_t*)&x)[1] -#endif +#if CPU(BIG_ENDIAN) || CPU(MIDDLE_ENDIAN) +#define word0(x) (x)->L[0] +#define word1(x) (x)->L[1] #else -#ifdef IEEE_8087 #define word0(x) (x)->L[1] #define word1(x) (x)->L[0] -#else -#define word0(x) (x)->L[0] -#define word1(x) (x)->L[1] #endif #define dval(x) (x)->d -#endif /* The following definition of Storeinc is appropriate for MIPS processors. * An alternative that might be better on some machines is @@ -193,12 +115,12 @@ typedef union { static ALWAYS_INLINE uint32_t* storeInc(uint32_t* p, uint16_t high, uint16_t low) { uint16_t* p16 = reinterpret_cast<uint16_t*>(p); -#if defined(IEEE_8087) || defined(IEEE_ARM) - p16[1] = high; - p16[0] = low; -#else +#if CPU(BIG_ENDIAN) p16[0] = high; p16[1] = low; +#else + p16[1] = high; + p16[0] = low; #endif return p + 1; } @@ -228,51 +150,18 @@ static ALWAYS_INLINE uint32_t* storeInc(uint32_t* p, uint16_t high, uint16_t low #define Quick_max 14 #define Int_max 14 -#if !defined(NO_IEEE_Scale) -#undef Avoid_Underflow -#define Avoid_Underflow -#endif - -#if !defined(Flt_Rounds) -#if defined(FLT_ROUNDS) -#define Flt_Rounds FLT_ROUNDS -#else -#define Flt_Rounds 1 -#endif -#endif /* Flt_Rounds */ - - #define rounded_product(a, b) a *= b #define rounded_quotient(a, b) a /= b #define Big0 (Frac_mask1 | Exp_msk1 * (DBL_MAX_EXP + Bias - 1)) #define Big1 0xffffffff - -// FIXME: we should remove non-Pack_32 mode since it is unused and unmaintained -#ifndef Pack_32 -#define Pack_32 -#endif - #if CPU(PPC64) || CPU(X86_64) // FIXME: should we enable this on all 64-bit CPUs? // 64-bit emulation provided by the compiler is likely to be slower than dtoa own code on 32-bit hardware. #define USE_LONG_LONG #endif -#ifndef USE_LONG_LONG -#ifdef Just_16 -#undef Pack_32 -/* When Pack_32 is not defined, we store 16 bits per 32-bit int32_t. - * This makes some inner loops simpler and sometimes saves work - * during multiplications, but it often seems to make things slightly - * slower. Hence the default is now to store 32 bits per int32_t. - */ -#endif -#endif - -#define Kmax 15 - struct BigInt { BigInt() : sign(0) { } int sign; @@ -282,7 +171,7 @@ struct BigInt { sign = 0; m_words.clear(); } - + size_t size() const { return m_words.size(); @@ -292,7 +181,7 @@ struct BigInt { { m_words.resize(s); } - + uint32_t* words() { return m_words.data(); @@ -302,12 +191,12 @@ struct BigInt { { return m_words.data(); } - + void append(uint32_t w) { m_words.append(w); } - + Vector<uint32_t, 16> m_words; }; @@ -329,17 +218,11 @@ static void multadd(BigInt& b, int m, int a) /* multiply by m and add a */ carry = y >> 32; *x++ = (uint32_t)y & 0xffffffffUL; #else -#ifdef Pack_32 uint32_t xi = *x; uint32_t y = (xi & 0xffff) * m + carry; uint32_t z = (xi >> 16) * m + (y >> 16); carry = z >> 16; *x++ = (z << 16) + (y & 0xffff); -#else - uint32_t y = *x * m + carry; - carry = y >> 16; - *x++ = y & 0xffff; -#endif #endif } while (++i < wds); @@ -349,20 +232,9 @@ static void multadd(BigInt& b, int m, int a) /* multiply by m and add a */ static void s2b(BigInt& b, const char* s, int nd0, int nd, uint32_t y9) { - int k; - int32_t y; - int32_t x = (nd + 8) / 9; - - for (k = 0, y = 1; x > y; y <<= 1, k++) { } -#ifdef Pack_32 b.sign = 0; b.resize(1); b.words()[0] = y9; -#else - b.sign = 0; - b.resize((b->x[1] = y9 >> 16) ? 2 : 1); - b.words()[0] = y9 & 0xffff; -#endif int i = 9; if (9 < nd0) { @@ -440,7 +312,7 @@ static int lo0bits(uint32_t* y) if (!(x & 1)) { k++; x >>= 1; - if (!x & 1) + if (!x) return 32; } *y = x; @@ -479,7 +351,7 @@ static void mult(BigInt& aRef, const BigInt& bRef) a = b; b = tmp; } - + wa = a->size(); wb = b->size(); wc = wa + wb; @@ -507,7 +379,6 @@ static void mult(BigInt& aRef, const BigInt& bRef) } } #else -#ifdef Pack_32 for (; xb < xbe; xb++, xc0++) { if ((y = *xb & 0xffff)) { x = xa; @@ -537,21 +408,6 @@ static void mult(BigInt& aRef, const BigInt& bRef) *xc = z2; } } -#else - for (; xb < xbe; xc0++) { - if ((y = *xb++)) { - x = xa; - xc = xc0; - carry = 0; - do { - z = *x++ * y + *xc + carry; - carry = z >> 16; - *xc++ = z & 0xffff; - } while (x < xae); - *xc = carry; - } - } -#endif #endif for (xc0 = c.words(), xc = xc0 + wc; wc > 0 && !*--xc; --wc) { } c.resize(wc); @@ -562,7 +418,7 @@ struct P5Node : Noncopyable { BigInt val; P5Node* next; }; - + static P5Node* p5s; static int p5sCount; @@ -615,7 +471,7 @@ static ALWAYS_INLINE void pow5mult(BigInt& b, int k) mult(p5->next->val, p5->next->val); ++p5sCount; } - + p5sCountLocal = p5sCount; #if ENABLE(JSC_MULTIPLE_THREADS) s_dtoaP5Mutex->unlock(); @@ -627,11 +483,7 @@ static ALWAYS_INLINE void pow5mult(BigInt& b, int k) static ALWAYS_INLINE void lshift(BigInt& b, int k) { -#ifdef Pack_32 int n = k >> 5; -#else - int n = k >> 4; -#endif int origSize = b.size(); int n1 = n + origSize + 1; @@ -645,7 +497,6 @@ static ALWAYS_INLINE void lshift(BigInt& b, int k) uint32_t* dstStart = b.words(); const uint32_t* src = srcStart + origSize - 1; uint32_t* dst = dstStart + n1 - 1; -#ifdef Pack_32 if (k) { uint32_t hiSubword = 0; int s = 32 - k; @@ -658,19 +509,6 @@ static ALWAYS_INLINE void lshift(BigInt& b, int k) b.resize(origSize + n + !!b.words()[n1 - 1]); } -#else - if (k &= 0xf) { - uint32_t hiSubword = 0; - int s = 16 - k; - for (; src >= srcStart; --src) { - *dst-- = hiSubword | *src >> s; - hiSubword = (*src << k) & 0xffff; - } - *dst = hiSubword; - ASSERT(dst == dstStart + n); - result->wds = b->wds + n + !!result->x[n1 - 1]; - } -#endif else { do { *--dst = *src--; @@ -752,7 +590,6 @@ static ALWAYS_INLINE void diff(BigInt& c, const BigInt& aRef, const BigInt& bRef } #else uint32_t borrow = 0; -#ifdef Pack_32 do { uint32_t y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; borrow = (y & 0x10000) >> 16; @@ -767,18 +604,6 @@ static ALWAYS_INLINE void diff(BigInt& c, const BigInt& aRef, const BigInt& bRef borrow = (z & 0x10000) >> 16; xc = storeInc(xc, z, y); } -#else - do { - uint32_t y = *xa++ - *xb++ - borrow; - borrow = (y & 0x10000) >> 16; - *xc++ = y & 0xffff; - } while (xb < xbe); - while (xa < xae) { - uint32_t y = *xa++ - borrow; - borrow = (y & 0x10000) >> 16; - *xc++ = y & 0xffff; - } -#endif #endif while (!*--xc) wa--; @@ -791,28 +616,8 @@ static double ulp(U *x) U u; L = (word0(x) & Exp_mask) - (P - 1) * Exp_msk1; -#ifndef Avoid_Underflow -#ifndef Sudden_Underflow - if (L > 0) { -#endif -#endif word0(&u) = L; word1(&u) = 0; -#ifndef Avoid_Underflow -#ifndef Sudden_Underflow - } else { - L = -L >> Exp_shift; - if (L < Exp_shift) { - word0(&u) = 0x80000 >> L; - word1(&u) = 0; - } else { - word0(&u) = 0; - L -= Exp_shift; - word1(&u) = L >= 31 ? 1 : 1 << 31 - L; - } - } -#endif -#endif return dval(&u); } @@ -835,7 +640,6 @@ static double b2d(const BigInt& a, int* e) ASSERT(y); k = hi0bits(y); *e = 32 - k; -#ifdef Pack_32 if (k < Ebits) { d0 = Exp_1 | (y >> (Ebits - k)); w = xa > xa0 ? *--xa : 0; @@ -851,22 +655,6 @@ static double b2d(const BigInt& a, int* e) d0 = Exp_1 | y; d1 = z; } -#else - if (k < Ebits + 16) { - z = xa > xa0 ? *--xa : 0; - d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; - w = xa > xa0 ? *--xa : 0; - y = xa > xa0 ? *--xa : 0; - d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; - goto returnD; - } - z = xa > xa0 ? *--xa : 0; - w = xa > xa0 ? *--xa : 0; - k -= Ebits + 16; - d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; - y = xa > xa0 ? *--xa : 0; - d1 = w << k + 16 | y << k; -#endif returnD: #undef d0 #undef d1 @@ -878,104 +666,44 @@ static ALWAYS_INLINE void d2b(BigInt& b, U* d, int* e, int* bits) int de, k; uint32_t* x; uint32_t y, z; -#ifndef Sudden_Underflow int i; -#endif #define d0 word0(d) #define d1 word1(d) b.sign = 0; -#ifdef Pack_32 b.resize(1); -#else - b.resize(2); -#endif x = b.words(); z = d0 & Frac_mask; d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ -#ifdef Sudden_Underflow - de = (int)(d0 >> Exp_shift); -#else if ((de = (int)(d0 >> Exp_shift))) z |= Exp_msk1; -#endif -#ifdef Pack_32 if ((y = d1)) { if ((k = lo0bits(&y))) { x[0] = y | (z << (32 - k)); z >>= k; } else x[0] = y; - if (z) { - b.resize(2); - x[1] = z; - } + if (z) { + b.resize(2); + x[1] = z; + } -#ifndef Sudden_Underflow i = b.size(); -#endif } else { k = lo0bits(&z); x[0] = z; -#ifndef Sudden_Underflow i = 1; -#endif b.resize(1); k += 32; } -#else - if ((y = d1)) { - if ((k = lo0bits(&y))) { - if (k >= 16) { - x[0] = y | z << 32 - k & 0xffff; - x[1] = z >> k - 16 & 0xffff; - x[2] = z >> k; - i = 2; - } else { - x[0] = y & 0xffff; - x[1] = y >> 16 | z << 16 - k & 0xffff; - x[2] = z >> k & 0xffff; - x[3] = z >> k + 16; - i = 3; - } - } else { - x[0] = y & 0xffff; - x[1] = y >> 16; - x[2] = z & 0xffff; - x[3] = z >> 16; - i = 3; - } - } else { - k = lo0bits(&z); - if (k >= 16) { - x[0] = z; - i = 0; - } else { - x[0] = z & 0xffff; - x[1] = z >> 16; - i = 1; - } - k += 32; - } while (!x[i]) - --i; - b->resize(i + 1); -#endif -#ifndef Sudden_Underflow if (de) { -#endif *e = de - Bias - (P - 1) + k; *bits = P - k; -#ifndef Sudden_Underflow } else { *e = de - Bias - (P - 1) + 1 + k; -#ifdef Pack_32 *bits = (32 * i) - hi0bits(x[i - 1]); -#else - *bits = (i + 2) * 16 - hi0bits(x[i]); -#endif } -#endif } #undef d0 #undef d1 @@ -987,11 +715,7 @@ static double ratio(const BigInt& a, const BigInt& b) dval(&da) = b2d(a, &ka); dval(&db) = b2d(b, &kb); -#ifdef Pack_32 k = ka - kb + 32 * (a.size() - b.size()); -#else - k = ka - kb + 16 * (a.size() - b.size()); -#endif if (k > 0) word0(&da) += k * Exp_msk1; else { @@ -1002,19 +726,15 @@ static double ratio(const BigInt& a, const BigInt& b) } static const double tens[] = { - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, - 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, - 1e20, 1e21, 1e22 + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22 }; static const double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, -#ifdef Avoid_Underflow - 9007199254740992. * 9007199254740992.e-256 - /* = 2^106 * 1e-53 */ -#else - 1e-256 -#endif + 9007199254740992. * 9007199254740992.e-256 + /* = 2^106 * 1e-256 */ }; /* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ @@ -1024,20 +744,15 @@ static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, double strtod(const char* s00, char** se) { -#ifdef Avoid_Underflow int scale; -#endif int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, - e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; + e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; const char *s, *s0, *s1; double aadj, aadj1; U aadj2, adj, rv, rv0; int32_t L; uint32_t y, z; BigInt bb, bb1, bd, bd0, bs, delta; -#ifdef SET_INEXACT - int inexact, oldinexact; -#endif sign = nz0 = nz = 0; dval(&rv) = 0; @@ -1163,14 +878,9 @@ ret0: nd0 = nd; k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; dval(&rv) = y; - if (k > 9) { -#ifdef SET_INEXACT - if (k > DBL_DIG) - oldinexact = get_inexact(); -#endif + if (k > 9) dval(&rv) = tens[k - 9] * dval(&rv) + z; - } - if (nd <= DBL_DIG && Flt_Rounds == 1) { + if (nd <= DBL_DIG) { if (!e) goto ret; if (e > 0) { @@ -1188,24 +898,14 @@ ret0: /* rv = */ rounded_product(dval(&rv), tens[e]); goto ret; } - } -#ifndef Inaccurate_Divide - else if (e >= -Ten_pmax) { + } else if (e >= -Ten_pmax) { /* rv = */ rounded_quotient(dval(&rv), tens[-e]); goto ret; } -#endif } e1 += nd - k; -#ifdef SET_INEXACT - inexact = 1; - if (k <= DBL_DIG) - oldinexact = get_inexact(); -#endif -#ifdef Avoid_Underflow scale = 0; -#endif /* Get starting approximation = rv * 10**e1 */ @@ -1215,17 +915,12 @@ ret0: if (e1 &= ~15) { if (e1 > DBL_MAX_10_EXP) { ovfl: -#ifndef NO_ERRNO +#if HAVE(ERRNO_H) errno = ERANGE; #endif /* Can't trust HUGE_VAL */ word0(&rv) = Exp_mask; word1(&rv) = 0; -#ifdef SET_INEXACT - /* set overflow bit */ - dval(&rv0) = 1e300; - dval(&rv0) *= dval(&rv0); -#endif goto ret; } e1 >>= 4; @@ -1252,50 +947,30 @@ ovfl: if (e1 >>= 4) { if (e1 >= 1 << n_bigtens) goto undfl; -#ifdef Avoid_Underflow if (e1 & Scale_Bit) scale = 2 * P; for (j = 0; e1 > 0; j++, e1 >>= 1) if (e1 & 1) dval(&rv) *= tinytens[j]; if (scale && (j = (2 * P) + 1 - ((word0(&rv) & Exp_mask) >> Exp_shift)) > 0) { - /* scaled rv is denormal; zap j low bits */ + /* scaled rv is denormal; clear j low bits */ if (j >= 32) { word1(&rv) = 0; if (j >= 53) - word0(&rv) = (P + 2) * Exp_msk1; + word0(&rv) = (P + 2) * Exp_msk1; else - word0(&rv) &= 0xffffffff << (j - 32); + word0(&rv) &= 0xffffffff << (j - 32); } else word1(&rv) &= 0xffffffff << j; } -#else - for (j = 0; e1 > 1; j++, e1 >>= 1) - if (e1 & 1) - dval(&rv) *= tinytens[j]; - /* The last multiplication could underflow. */ - dval(&rv0) = dval(&rv); - dval(&rv) *= tinytens[j]; - if (!dval(&rv)) { - dval(&rv) = 2. * dval(&rv0); - dval(&rv) *= tinytens[j]; -#endif if (!dval(&rv)) { undfl: dval(&rv) = 0.; -#ifndef NO_ERRNO +#if HAVE(ERRNO_H) errno = ERANGE; #endif goto ret; } -#ifndef Avoid_Underflow - word0(&rv) = Tiny0; - word1(&rv) = Tiny1; - /* The refinement below will clean - * this approximation up. - */ - } -#endif } } @@ -1322,30 +997,15 @@ undfl: else bd2 -= bbe; bs2 = bb2; -#ifdef Avoid_Underflow j = bbe - scale; i = j + bbbits - 1; /* logb(rv) */ if (i < Emin) /* denormal */ j += P - Emin; else j = P + 1 - bbbits; -#else /*Avoid_Underflow*/ -#ifdef Sudden_Underflow - j = P + 1 - bbbits; -#else /*Sudden_Underflow*/ - j = bbe; - i = j + bbbits - 1; /* logb(rv) */ - if (i < Emin) /* denormal */ - j += P - Emin; - else - j = P + 1 - bbbits; -#endif /*Sudden_Underflow*/ -#endif /*Avoid_Underflow*/ bb2 += j; bd2 += j; -#ifdef Avoid_Underflow bd2 += scale; -#endif i = bb2 < bd2 ? bb2 : bd2; if (i > bs2) i = bs2; @@ -1376,23 +1036,12 @@ undfl: * special case of mantissa a power of two. */ if (dsign || word1(&rv) || word0(&rv) & Bndry_mask -#ifdef Avoid_Underflow || (word0(&rv) & Exp_mask) <= (2 * P + 1) * Exp_msk1 -#else - || (word0(&rv) & Exp_mask) <= Exp_msk1 -#endif ) { -#ifdef SET_INEXACT - if (!delta->words()[0] && delta->size() <= 1) - inexact = 0; -#endif break; } if (!delta.words()[0] && delta.size() <= 1) { /* exact result */ -#ifdef SET_INEXACT - inexact = 0; -#endif break; } lshift(delta, Log2P); @@ -1405,33 +1054,18 @@ undfl: if (dsign) { if ((word0(&rv) & Bndry_mask1) == Bndry_mask1 && word1(&rv) == ( -#ifdef Avoid_Underflow (scale && (y = word0(&rv) & Exp_mask) <= 2 * P * Exp_msk1) ? (0xffffffff & (0xffffffff << (2 * P + 1 - (y >> Exp_shift)))) : -#endif 0xffffffff)) { /*boundary case -- increment exponent*/ word0(&rv) = (word0(&rv) & Exp_mask) + Exp_msk1; word1(&rv) = 0; -#ifdef Avoid_Underflow dsign = 0; -#endif break; } } else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) { dropDown: /* boundary case -- decrement exponent */ -#ifdef Sudden_Underflow /*{{*/ - L = word0(&rv) & Exp_mask; -#ifdef Avoid_Underflow - if (L <= (scale ? (2 * P + 1) * Exp_msk1 : Exp_msk1)) -#else - if (L <= Exp_msk1) -#endif /*Avoid_Underflow*/ - goto undfl; - L -= Exp_msk1; -#else /*Sudden_Underflow}{*/ -#ifdef Avoid_Underflow if (scale) { L = word0(&rv) & Exp_mask; if (L <= (2 * P + 1) * Exp_msk1) { @@ -1443,9 +1077,7 @@ dropDown: goto undfl; } } -#endif /*Avoid_Underflow*/ L = (word0(&rv) & Exp_mask) - Exp_msk1; -#endif /*Sudden_Underflow}}*/ word0(&rv) = L | Bndry_mask1; word1(&rv) = 0xffffffff; break; @@ -1456,24 +1088,18 @@ dropDown: dval(&rv) += ulp(&rv); else { dval(&rv) -= ulp(&rv); -#ifndef Sudden_Underflow if (!dval(&rv)) goto undfl; -#endif } -#ifdef Avoid_Underflow dsign = 1 - dsign; -#endif break; } if ((aadj = ratio(delta, bs)) <= 2.) { if (dsign) aadj = aadj1 = 1.; else if (word1(&rv) || word0(&rv) & Bndry_mask) { -#ifndef Sudden_Underflow if (word1(&rv) == Tiny1 && !word0(&rv)) goto undfl; -#endif aadj = 1.; aadj1 = -1.; } else { @@ -1489,19 +1115,6 @@ dropDown: } else { aadj *= 0.5; aadj1 = dsign ? aadj : -aadj; -#ifdef Check_FLT_ROUNDS - switch (Rounding) { - case 2: /* towards +infinity */ - aadj1 -= 0.5; - break; - case 0: /* towards 0 */ - case 3: /* towards -infinity */ - aadj1 += 0.5; - } -#else - if (!Flt_Rounds) - aadj1 += 0.5; -#endif /*Check_FLT_ROUNDS*/ } y = word0(&rv) & Exp_mask; @@ -1521,7 +1134,6 @@ dropDown: } word0(&rv) += P * Exp_msk1; } else { -#ifdef Avoid_Underflow if (scale && y <= 2 * P * Exp_msk1) { if (aadj <= 0x7fffffff) { if ((z = (uint32_t)aadj) <= 0) @@ -1535,49 +1147,9 @@ dropDown: } adj.d = aadj1 * ulp(&rv); dval(&rv) += adj.d; -#else -#ifdef Sudden_Underflow - if ((word0(&rv) & Exp_mask) <= P * Exp_msk1) { - dval(&rv0) = dval(&rv); - word0(&rv) += P * Exp_msk1; - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; - if ((word0(&rv) & Exp_mask) <= P * Exp_msk1) { - if (word0(&rv0) == Tiny0 && word1(&rv0) == Tiny1) - goto undfl; - word0(&rv) = Tiny0; - word1(&rv) = Tiny1; - goto cont; - } - word0(&rv) -= P * Exp_msk1; - } else { - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; - } -#else /*Sudden_Underflow*/ - /* Compute adj so that the IEEE rounding rules will - * correctly round rv + adj in some half-way cases. - * If rv * ulp(rv) is denormalized (i.e., - * y <= (P - 1) * Exp_msk1), we must adjust aadj to avoid - * trouble from bits lost to denormalization; - * example: 1.2e-307 . - */ - if (y <= (P - 1) * Exp_msk1 && aadj > 1.) { - aadj1 = (double)(int)(aadj + 0.5); - if (!dsign) - aadj1 = -aadj1; - } - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; -#endif /*Sudden_Underflow*/ -#endif /*Avoid_Underflow*/ } z = word0(&rv) & Exp_mask; -#ifndef SET_INEXACT -#ifdef Avoid_Underflow - if (!scale) -#endif - if (y == z) { + if (!scale && y == z) { /* Can we stop now? */ L = (int32_t)aadj; aadj -= L; @@ -1588,39 +1160,19 @@ dropDown: } else if (aadj < .4999999 / FLT_RADIX) break; } -#endif cont: {} } -#ifdef SET_INEXACT - if (inexact) { - if (!oldinexact) { - word0(&rv0) = Exp_1 + (70 << Exp_shift); - word1(&rv0) = 0; - dval(&rv0) += 1.; - } - } else if (!oldinexact) - clear_inexact(); -#endif -#ifdef Avoid_Underflow if (scale) { word0(&rv0) = Exp_1 - 2 * P * Exp_msk1; word1(&rv0) = 0; dval(&rv) *= dval(&rv0); -#ifndef NO_ERRNO +#if HAVE(ERRNO_H) /* try to avoid the bug of testing an 8087 register value */ if (!word0(&rv) && !word1(&rv)) errno = ERANGE; #endif } -#endif /* Avoid_Underflow */ -#ifdef SET_INEXACT - if (inexact && !(word0(&rv) & Exp_mask)) { - /* set underflow bit */ - dval(&rv0) = 1e-300; - dval(&rv0) *= dval(&rv0); - } -#endif ret: if (se) *se = const_cast<char*>(s); @@ -1639,10 +1191,8 @@ static ALWAYS_INLINE int quorem(BigInt& b, BigInt& S) unsigned long long borrow, carry, y, ys; #else uint32_t borrow, carry, y, ys; -#ifdef Pack_32 uint32_t si, z, zs; #endif -#endif ASSERT(b.size() <= 1 || b.words()[b.size() - 1]); ASSERT(S.size() <= 1 || S.words()[S.size() - 1]); @@ -1667,7 +1217,6 @@ static ALWAYS_INLINE int quorem(BigInt& b, BigInt& S) borrow = y >> 32 & (uint32_t)1; *bx++ = (uint32_t)y & 0xffffffffUL; #else -#ifdef Pack_32 si = *sx++; ys = (si & 0xffff) * q + carry; zs = (si >> 16) * q + (ys >> 16); @@ -1677,13 +1226,6 @@ static ALWAYS_INLINE int quorem(BigInt& b, BigInt& S) z = (*bx >> 16) - (zs & 0xffff) - borrow; borrow = (z & 0x10000) >> 16; bx = storeInc(bx, z, y); -#else - ys = *sx++ * q + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - *bx++ = y & 0xffff; -#endif #endif } while (sx <= sxe); if (!*bxe) { @@ -1707,7 +1249,6 @@ static ALWAYS_INLINE int quorem(BigInt& b, BigInt& S) borrow = y >> 32 & (uint32_t)1; *bx++ = (uint32_t)y & 0xffffffffUL; #else -#ifdef Pack_32 si = *sx++; ys = (si & 0xffff) + carry; zs = (si >> 16) + (ys >> 16); @@ -1717,13 +1258,6 @@ static ALWAYS_INLINE int quorem(BigInt& b, BigInt& S) z = (*bx >> 16) - (zs & 0xffff) - borrow; borrow = (z & 0x10000) >> 16; bx = storeInc(bx, z, y); -#else - ys = *sx++ + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - *bx++ = y & 0xffff; -#endif #endif } while (sx <= sxe); bx = b.words(); @@ -1740,7 +1274,7 @@ static ALWAYS_INLINE int quorem(BigInt& b, BigInt& S) /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. * * Inspired by "How to Print Floating-Point Numbers Accurately" by - * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101]. + * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. * * Modifications: * 1. Rather than iterating, we use a simple numeric overestimate @@ -1769,78 +1303,54 @@ static ALWAYS_INLINE int quorem(BigInt& b, BigInt& S) * "uniformly" distributed input, the probability is * something like 10^(k-15) that we must resort to the int32_t * calculation. + * + * Note: 'leftright' translates to 'generate shortest possible string'. */ - -void dtoa(DtoaBuffer result, double dd, int ndigits, int* decpt, int* sign, char** rve) +template<bool roundingNone, bool roundingSignificantFigures, bool roundingDecimalPlaces, bool leftright> +void dtoa(DtoaBuffer result, double dd, int ndigits, bool& signOut, int& exponentOut, unsigned& precisionOut) { - /* - Arguments ndigits, decpt, sign are similar to those - of ecvt and fcvt; trailing zeros are suppressed from - the returned string. If not null, *rve is set to point - to the end of the return value. If d is +-Infinity or NaN, - then *decpt is set to 9999. + // Exactly one rounding mode must be specified. + ASSERT(roundingNone + roundingSignificantFigures + roundingDecimalPlaces == 1); + // roundingNone only allowed (only sensible?) with leftright set. + ASSERT(!roundingNone || leftright); - */ + ASSERT(!isnan(dd) && !isinf(dd)); int bbits, b2, b5, be, dig, i, ieps, ilim = 0, ilim0, ilim1 = 0, - j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, - spec_case, try_quick; + j, j1, k, k0, k_check, m2, m5, s2, s5, + spec_case; int32_t L; -#ifndef Sudden_Underflow int denorm; uint32_t x; -#endif - BigInt b, b1, delta, mlo, mhi, S; + BigInt b, delta, mlo, mhi, S; U d2, eps, u; double ds; char* s; char* s0; -#ifdef SET_INEXACT - int inexact, oldinexact; -#endif u.d = dd; - if (word0(&u) & Sign_bit) { - /* set sign for everything, including 0's and NaNs */ - *sign = 1; - word0(&u) &= ~Sign_bit; /* clear sign bit */ - } else - *sign = 0; - - if ((word0(&u) & Exp_mask) == Exp_mask) { - /* Infinity or NaN */ - *decpt = 9999; - if (!word1(&u) && !(word0(&u) & 0xfffff)) { - strcpy(result, "Infinity"); - if (rve) - *rve = result + 8; - } else { - strcpy(result, "NaN"); - if (rve) - *rve = result + 3; - } - return; - } + + /* Infinity or NaN */ + ASSERT((word0(&u) & Exp_mask) != Exp_mask); + + // JavaScript toString conversion treats -0 as 0. if (!dval(&u)) { - *decpt = 1; + signOut = false; + exponentOut = 0; + precisionOut = 1; result[0] = '0'; result[1] = '\0'; - if (rve) - *rve = result + 1; return; } -#ifdef SET_INEXACT - try_quick = oldinexact = get_inexact(); - inexact = 1; -#endif + if (word0(&u) & Sign_bit) { + signOut = true; + word0(&u) &= ~Sign_bit; // clear sign bit + } else + signOut = false; d2b(b, &u, &be, &bbits); -#ifdef Sudden_Underflow - i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask >> Exp_shift1)); -#else if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask >> Exp_shift1)))) { -#endif dval(&d2) = dval(&u); word0(&d2) &= Frac_mask1; word0(&d2) |= Exp_11; @@ -1868,7 +1378,6 @@ void dtoa(DtoaBuffer result, double dd, int ndigits, int* decpt, int* sign, char */ i -= Bias; -#ifndef Sudden_Underflow denorm = 0; } else { /* d is denormalized */ @@ -1881,7 +1390,6 @@ void dtoa(DtoaBuffer result, double dd, int ndigits, int* decpt, int* sign, char i -= (Bias + (P - 1) - 1) + 1; denorm = 1; } -#endif ds = (dval(&d2) - 1.5) * 0.289529654602168 + 0.1760912590558 + (i * 0.301029995663981); k = (int)ds; if (ds < 0. && ds != k) @@ -1910,22 +1418,27 @@ void dtoa(DtoaBuffer result, double dd, int ndigits, int* decpt, int* sign, char s5 = 0; } -#ifndef SET_INEXACT -#ifdef Check_FLT_ROUNDS - try_quick = Rounding == 1; -#else - try_quick = 1; -#endif -#endif /*SET_INEXACT*/ + if (roundingNone) { + ilim = ilim1 = -1; + i = 18; + ndigits = 0; + } + if (roundingSignificantFigures) { + if (ndigits <= 0) + ndigits = 1; + ilim = ilim1 = i = ndigits; + } + if (roundingDecimalPlaces) { + i = ndigits + k + 1; + ilim = i; + ilim1 = i - 1; + if (i <= 0) + i = 1; + } - leftright = 1; - ilim = ilim1 = -1; - i = 18; - ndigits = 0; s = s0 = result; - if (ilim >= 0 && ilim <= Quick_max && try_quick) { - + if (ilim >= 0 && ilim <= Quick_max) { /* Try to get by with floating-point arithmetic. */ i = 0; @@ -1978,7 +1491,6 @@ void dtoa(DtoaBuffer result, double dd, int ndigits, int* decpt, int* sign, char goto noDigits; goto fastFailed; } -#ifndef No_leftright if (leftright) { /* Use Steele & White method of only * generating digits needed. @@ -1998,7 +1510,6 @@ void dtoa(DtoaBuffer result, double dd, int ndigits, int* decpt, int* sign, char dval(&u) *= 10.; } } else { -#endif /* Generate ilim digits, then fix them up. */ dval(&eps) *= tens[ilim - 1]; for (i = 1;; i++, dval(&u) *= 10.) { @@ -2017,9 +1528,7 @@ void dtoa(DtoaBuffer result, double dd, int ndigits, int* decpt, int* sign, char break; } } -#ifndef No_leftright } -#endif fastFailed: s = s0; dval(&u) = dval(&d2); @@ -2042,18 +1551,8 @@ fastFailed: for (i = 1;; i++, dval(&u) *= 10.) { L = (int32_t)(dval(&u) / ds); dval(&u) -= L * ds; -#ifdef Check_FLT_ROUNDS - /* If FLT_ROUNDS == 2, L will usually be high by 1 */ - if (dval(&u) < 0) { - L--; - dval(&u) += ds; - } -#endif *s++ = '0' + (int)L; if (!dval(&u)) { -#ifdef SET_INEXACT - inexact = 0; -#endif break; } if (i == ilim) { @@ -2079,11 +1578,7 @@ bumpUp: mhi.clear(); mlo.clear(); if (leftright) { - i = -#ifndef Sudden_Underflow - denorm ? be + (Bias + (P - 1) - 1 + 1) : -#endif - 1 + P - bbits; + i = denorm ? be + (Bias + (P - 1) - 1 + 1) : 1 + P - bbits; b2 += i; s2 += i; i2b(mhi, 1); @@ -2104,7 +1599,7 @@ bumpUp: pow5mult(b, j); } else pow5mult(b, b5); - } + } i2b(S, 1); if (s5 > 0) pow5mult(S, s5); @@ -2112,11 +1607,7 @@ bumpUp: /* Check for special case that d is a normalized power of 2. */ spec_case = 0; - if (!word1(&u) && !(word0(&u) & Bndry_mask) -#ifndef Sudden_Underflow - && word0(&u) & (Exp_mask & ~Exp_msk1) -#endif - ) { + if ((roundingNone || leftright) && (!word1(&u) && !(word0(&u) & Bndry_mask) && word0(&u) & (Exp_mask & ~Exp_msk1))) { /* The special case */ b2 += Log2P; s2 += Log2P; @@ -2130,13 +1621,8 @@ bumpUp: * and for all and pass them and a shift to quorem, so it * can do shifts and ors to compute the numerator for q. */ -#ifdef Pack_32 if ((i = ((s5 ? 32 - hi0bits(S.words()[S.size() - 1]) : 1) + s2) & 0x1f)) i = 32 - i; -#else - if ((i = ((s5 ? 32 - hi0bits(S.words()[S.size() - 1]) : 1) + s2) & 0xf)) - i = 16 - i; -#endif if (i > 4) { i -= 4; b2 += i; @@ -2161,7 +1647,15 @@ bumpUp: ilim = ilim1; } } - + if (ilim <= 0 && roundingDecimalPlaces) { + if (ilim < 0) + goto noDigits; + multadd(S, 5, 0); + // For IEEE-754 unbiased rounding this check should be <=, such that 0.5 would flush to zero. + if (cmp(b, S) < 0) + goto noDigits; + goto oneDigit; + } if (leftright) { if (m2 > 0) lshift(mhi, m2); @@ -2171,10 +1665,8 @@ bumpUp: */ mlo = mhi; - if (spec_case) { - mhi = mlo; + if (spec_case) lshift(mhi, Log2P); - } for (i = 1;;i++) { dig = quorem(b, S) + '0'; @@ -2184,32 +1676,43 @@ bumpUp: j = cmp(b, mlo); diff(delta, S, mhi); j1 = delta.sign ? 1 : cmp(b, delta); +#ifdef DTOA_ROUND_BIASED + if (j < 0 || !j) { +#else + // FIXME: ECMA-262 specifies that equidistant results round away from + // zero, which probably means we shouldn't be on the unbiased code path + // (the (word1(&u) & 1) clause is looking highly suspicious). I haven't + // yet understood this code well enough to make the call, but we should + // probably be enabling DTOA_ROUND_BIASED. I think the interesting corner + // case to understand is probably "Math.pow(0.5, 24).toString()". + // I believe this value is interesting because I think it is precisely + // representable in binary floating point, and its decimal representation + // has a single digit that Steele & White reduction can remove, with the + // value 5 (thus equidistant from the next numbers above and below). + // We produce the correct answer using either codepath, and I don't as + // yet understand why. :-) if (!j1 && !(word1(&u) & 1)) { if (dig == '9') goto round9up; if (j > 0) dig++; -#ifdef SET_INEXACT - else if (!b->x[0] && b->wds <= 1) - inexact = 0; -#endif *s++ = dig; goto ret; } if (j < 0 || (!j && !(word1(&u) & 1))) { - if (!b.words()[0] && b.size() <= 1) { -#ifdef SET_INEXACT - inexact = 0; #endif - goto acceptDig; - } - if (j1 > 0) { + if ((b.words()[0] || b.size() > 1) && (j1 > 0)) { lshift(b, 1); j1 = cmp(b, S); - if ((j1 > 0 || (!j1 && (dig & 1))) && dig++ == '9') - goto round9up; + // For IEEE-754 round-to-even, this check should be (j1 > 0 || (!j1 && (dig & 1))), + // but ECMA-262 specifies that equidistant values (e.g. (.5).toFixed()) should + // be rounded away from zero. + if (j1 >= 0) { + if (dig == '9') + goto round9up; + dig++; + } } -acceptDig: *s++ = dig; goto ret; } @@ -2229,25 +1732,25 @@ round9up: multadd(mlo, 10, 0); multadd(mhi, 10, 0); } - } else + } else { for (i = 1;; i++) { *s++ = dig = quorem(b, S) + '0'; - if (!b.words()[0] && b.size() <= 1) { -#ifdef SET_INEXACT - inexact = 0; -#endif + if (!b.words()[0] && b.size() <= 1) goto ret; - } if (i >= ilim) break; multadd(b, 10, 0); } + } /* Round off last digit */ lshift(b, 1); j = cmp(b, S); - if (j > 0 || (!j && (dig & 1))) { + // For IEEE-754 round-to-even, this check should be (j > 0 || (!j && (dig & 1))), + // but ECMA-262 specifies that equidistant values (e.g. (.5).toFixed()) should + // be rounded away from zero. + if (j >= 0) { roundoff: while (*--s == '9') if (s == s0) { @@ -2262,27 +1765,67 @@ roundoff: } goto ret; noDigits: - k = -1 - ndigits; - goto ret; + exponentOut = 0; + precisionOut = 1; + result[0] = '0'; + result[1] = '\0'; + return; oneDigit: *s++ = '1'; k++; goto ret; ret: -#ifdef SET_INEXACT - if (inexact) { - if (!oldinexact) { - word0(&u) = Exp_1 + (70 << Exp_shift); - word1(&u) = 0; - dval(&u) += 1.; - } - } else if (!oldinexact) - clear_inexact(); -#endif + ASSERT(s > result); *s = 0; - *decpt = k + 1; - if (rve) - *rve = s; + exponentOut = k; + precisionOut = s - result; +} + +void dtoa(DtoaBuffer result, double dd, bool& sign, int& exponent, unsigned& precision) +{ + // flags are roundingNone, leftright. + dtoa<true, false, false, true>(result, dd, 0, sign, exponent, precision); +} + +void dtoaRoundSF(DtoaBuffer result, double dd, int ndigits, bool& sign, int& exponent, unsigned& precision) +{ + // flag is roundingSignificantFigures. + dtoa<false, true, false, false>(result, dd, ndigits, sign, exponent, precision); +} + +void dtoaRoundDP(DtoaBuffer result, double dd, int ndigits, bool& sign, int& exponent, unsigned& precision) +{ + // flag is roundingDecimalPlaces. + dtoa<false, false, true, false>(result, dd, ndigits, sign, exponent, precision); +} + +static ALWAYS_INLINE void copyAsciiToUTF16(UChar* next, const char* src, unsigned size) +{ + for (unsigned i = 0; i < size; ++i) + *next++ = *src++; +} + +unsigned numberToString(double d, NumberToStringBuffer buffer) +{ + // Handle NaN and Infinity. + if (isnan(d) || isinf(d)) { + if (isnan(d)) { + copyAsciiToUTF16(buffer, "NaN", 3); + return 3; + } + if (d > 0) { + copyAsciiToUTF16(buffer, "Infinity", 8); + return 8; + } + copyAsciiToUTF16(buffer, "-Infinity", 9); + return 9; + } + + // Convert to decimal with rounding. + DecimalNumber number(d); + return number.exponent() >= -6 && number.exponent() < 21 + ? number.toStringDecimal(buffer) + : number.toStringExponential(buffer); } } // namespace WTF diff --git a/JavaScriptCore/wtf/dtoa.h b/JavaScriptCore/wtf/dtoa.h index bf00ccc..7e4fc41 100644 --- a/JavaScriptCore/wtf/dtoa.h +++ b/JavaScriptCore/wtf/dtoa.h @@ -21,11 +21,10 @@ #ifndef WTF_dtoa_h #define WTF_dtoa_h -namespace WTF { -class Mutex; -} +#include <wtf/unicode/Unicode.h> namespace WTF { +class Mutex; extern WTF::Mutex* s_dtoaP5Mutex; @@ -34,10 +33,18 @@ extern WTF::Mutex* s_dtoaP5Mutex; double strtod(const char* s00, char** se); typedef char DtoaBuffer[80]; -void dtoa(DtoaBuffer result, double d, int ndigits, int* decpt, int* sign, char** rve); + +void dtoa(DtoaBuffer result, double dd, bool& sign, int& exponent, unsigned& precision); +void dtoaRoundSF(DtoaBuffer result, double dd, int ndigits, bool& sign, int& exponent, unsigned& precision); +void dtoaRoundDP(DtoaBuffer result, double dd, int ndigits, bool& sign, int& exponent, unsigned& precision); + +// Size = 80 for sizeof(DtoaBuffer) + some sign bits, decimal point, 'e', exponent digits. +typedef UChar NumberToStringBuffer[96]; +unsigned numberToString(double, NumberToStringBuffer); } // namespace WTF -using WTF::DtoaBuffer; +using WTF::NumberToStringBuffer; +using WTF::numberToString; #endif // WTF_dtoa_h diff --git a/JavaScriptCore/wtf/gobject/GOwnPtr.h b/JavaScriptCore/wtf/gobject/GOwnPtr.h index 731326e..e04ee9d 100644 --- a/JavaScriptCore/wtf/gobject/GOwnPtr.h +++ b/JavaScriptCore/wtf/gobject/GOwnPtr.h @@ -26,15 +26,6 @@ #include <wtf/Assertions.h> #include <wtf/Noncopyable.h> -// Forward delcarations at this point avoid the need to include GLib includes -// in WTF headers. -typedef struct _GError GError; -typedef struct _GList GList; -typedef struct _GCond GCond; -typedef struct _GMutex GMutex; -typedef struct _GPatternSpec GPatternSpec; -typedef struct _GDir GDir; -typedef struct _GFile GFile; extern "C" void g_free(void*); namespace WTF { diff --git a/JavaScriptCore/wtf/gobject/GRefPtr.h b/JavaScriptCore/wtf/gobject/GRefPtr.h index 064c87e..1ca55ce 100644 --- a/JavaScriptCore/wtf/gobject/GRefPtr.h +++ b/JavaScriptCore/wtf/gobject/GRefPtr.h @@ -27,11 +27,8 @@ #include "PlatformRefPtr.h" #include <algorithm> -typedef struct _GHashTable GHashTable; -typedef struct _GVariant GVariant; -typedef void* gpointer; -extern "C" void g_object_unref(gpointer object); -extern "C" gpointer g_object_ref_sink(gpointer object); +extern "C" void g_object_unref(gpointer); +extern "C" gpointer g_object_ref_sink(gpointer); namespace WTF { diff --git a/JavaScriptCore/wtf/gtk/GtkTypedefs.h b/JavaScriptCore/wtf/gtk/GtkTypedefs.h new file mode 100644 index 0000000..ee96f84 --- /dev/null +++ b/JavaScriptCore/wtf/gtk/GtkTypedefs.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2010 Igalia, S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef GtkTypedefs_h +#define GtkTypedefs_h + +/* Vanilla C code does not seem to be able to handle forward-declaration typedefs. */ +#ifdef __cplusplus + +typedef char gchar; +typedef double gdouble; +typedef float gfloat; +typedef int gint; +typedef gint gboolean; +typedef long glong; +typedef short gshort; +typedef unsigned char guchar; +typedef unsigned int guint; +typedef unsigned long gulong; +typedef unsigned short gushort; +typedef void* gpointer; + +typedef struct _cairo_surface cairo_surface_t; +typedef struct _GCond GCond; +typedef struct _GDir GDir; +typedef struct _GdkAtom* GdkAtom; +typedef struct _GdkCursor GdkCursor; +typedef struct _GdkDragContext GdkDragContext; +typedef struct _GdkDrawable GdkDrawable; +typedef struct _GdkEventConfigure GdkEventConfigure; +typedef struct _GdkPixbuf GdkPixbuf; +typedef struct _GError GError; +typedef struct _GFile GFile; +typedef struct _GHashTable GHashTable; +typedef struct _GList GList; +typedef struct _GMutex GMutex; +typedef struct _GPatternSpec GPatternSpec; +typedef struct _GtkAction GtkAction; +typedef struct _GtkAdjustment GtkAdjustment; +typedef struct _GtkBorder GtkBorder; +typedef struct _GtkClipboard GtkClipboard; +typedef struct _GtkContainer GtkContainer; +typedef struct _GtkIconInfo GtkIconInfo; +typedef struct _GtkMenu GtkMenu; +typedef struct _GtkMenuItem GtkMenuItem; +typedef struct _GtkObject GtkObject; +typedef struct _GtkSelectionData GtkSelectionData; +typedef struct _GtkStyle GtkStyle; +typedef struct _GtkTargetList GtkTargetList; +typedef struct _GtkThemeParts GtkThemeParts; +typedef struct _GtkWidget GtkWidget; +typedef struct _GVariant GVariant; +typedef union _GdkEvent GdkEvent; + +#ifdef GTK_API_VERSION_2 +typedef struct _GdkRectangle GdkRectangle; +#else +typedef struct _cairo_rectangle_int cairo_rectangle_int_t; +typedef cairo_rectangle_int_t GdkRectangle; +#endif + +#endif + +#endif /* GtkTypedefs_h */ diff --git a/JavaScriptCore/wtf/text/AtomicString.cpp b/JavaScriptCore/wtf/text/AtomicString.cpp index 6e95292..1981170 100644 --- a/JavaScriptCore/wtf/text/AtomicString.cpp +++ b/JavaScriptCore/wtf/text/AtomicString.cpp @@ -130,7 +130,7 @@ static inline bool equal(StringImpl* string, const UChar* characters, unsigned l // FIXME: perhaps we should have a more abstract macro that indicates when // going 4 bytes at a time is unsafe -#if CPU(ARM) || CPU(SH4) +#if CPU(ARM) || CPU(SH4) || CPU(MIPS) const UChar* stringCharacters = string->characters(); for (unsigned i = 0; i != length; ++i) { if (*stringCharacters++ != *characters++) diff --git a/JavaScriptCore/wtf/text/StringHash.h b/JavaScriptCore/wtf/text/StringHash.h index 8872fb3..bfd05eb 100644 --- a/JavaScriptCore/wtf/text/StringHash.h +++ b/JavaScriptCore/wtf/text/StringHash.h @@ -55,7 +55,7 @@ namespace WTF { // FIXME: perhaps we should have a more abstract macro that indicates when // going 4 bytes at a time is unsafe -#if CPU(ARM) || CPU(SH4) +#if CPU(ARM) || CPU(SH4) || CPU(MIPS) const UChar* aChars = a->characters(); const UChar* bChars = b->characters(); for (unsigned i = 0; i != aLength; ++i) { diff --git a/JavaScriptCore/wtf/text/StringImpl.cpp b/JavaScriptCore/wtf/text/StringImpl.cpp index ab0f009..a667525 100644 --- a/JavaScriptCore/wtf/text/StringImpl.cpp +++ b/JavaScriptCore/wtf/text/StringImpl.cpp @@ -31,6 +31,8 @@ #include <wtf/StdLibExtras.h> #include <wtf/WTFThreadData.h> +using namespace std; + namespace WTF { using namespace Unicode; @@ -776,6 +778,10 @@ PassRefPtr<StringImpl> StringImpl::replace(unsigned position, unsigned lengthToR if (!lengthToReplace && !lengthToInsert) return this; UChar* data; + + if ((length() - lengthToReplace) >= (numeric_limits<unsigned>::max() - lengthToInsert)) + CRASH(); + PassRefPtr<StringImpl> newImpl = createUninitialized(length() - lengthToReplace + lengthToInsert, data); memcpy(data, characters(), position * sizeof(UChar)); @@ -805,9 +811,18 @@ PassRefPtr<StringImpl> StringImpl::replace(UChar pattern, StringImpl* replacemen if (!matchCount) return this; + if (repStrLength && matchCount > numeric_limits<unsigned>::max() / repStrLength) + CRASH(); + + unsigned replaceSize = matchCount * repStrLength; + unsigned newSize = m_length - matchCount; + if (newSize >= (numeric_limits<unsigned>::max() - replaceSize)) + CRASH(); + + newSize += replaceSize; + UChar* data; - PassRefPtr<StringImpl> newImpl = - createUninitialized(m_length - matchCount + (matchCount * repStrLength), data); + PassRefPtr<StringImpl> newImpl = createUninitialized(newSize, data); // Construct the new data size_t srcSegmentEnd; @@ -855,9 +870,17 @@ PassRefPtr<StringImpl> StringImpl::replace(StringImpl* pattern, StringImpl* repl if (!matchCount) return this; + unsigned newSize = m_length - matchCount * patternLength; + if (repStrLength && matchCount > numeric_limits<unsigned>::max() / repStrLength) + CRASH(); + + if (newSize > (numeric_limits<unsigned>::max() - matchCount * repStrLength)) + CRASH(); + + newSize += matchCount * repStrLength; + UChar* data; - PassRefPtr<StringImpl> newImpl = - createUninitialized(m_length + matchCount * (repStrLength - patternLength), data); + PassRefPtr<StringImpl> newImpl = createUninitialized(newSize, data); // Construct the new data size_t srcSegmentEnd; diff --git a/JavaScriptCore/wtf/text/WTFString.cpp b/JavaScriptCore/wtf/text/WTFString.cpp index bbff576..a83dbba 100644 --- a/JavaScriptCore/wtf/text/WTFString.cpp +++ b/JavaScriptCore/wtf/text/WTFString.cpp @@ -25,10 +25,10 @@ #include <limits> #include <stdarg.h> #include <wtf/ASCIICType.h> -#include <wtf/DecimalNumber.h> +#include <wtf/text/CString.h> #include <wtf/StringExtras.h> #include <wtf/Vector.h> -#include <wtf/text/CString.h> +#include <wtf/dtoa.h> #include <wtf/unicode/UTF8.h> #include <wtf/unicode/Unicode.h> @@ -947,49 +947,42 @@ float charactersToFloat(const UChar* data, size_t length, bool* ok) return static_cast<float>(charactersToDouble(data, length, ok)); } -static unsigned copyToString(const char* string, unsigned length, NumberToStringBuffer& buffer) -{ - for (unsigned i = 0; i < length; ++i) - buffer[i] = string[i]; - return length; -} +} // namespace WTF -static NEVER_INLINE unsigned nanOrInfToString(double x, NumberToStringBuffer& buffer) +#ifndef NDEBUG +// For use in the debugger +String* string(const char*); +Vector<char> asciiDebug(StringImpl* impl); +Vector<char> asciiDebug(String& string); + +String* string(const char* s) { - ASSERT(isnan(x) || isinf(x)); - if (isnan(x)) - return copyToString("NaN", 3, buffer); - if (x < 0) - return copyToString("-Infinity", 9, buffer); - return copyToString("Infinity", 8, buffer); + // leaks memory! + return new String(s); } -// toString converts a number to a string without rounding. For values in the range -// 1e-6 <= x < 1e+21 the result is formatted as a decimal, with values outside of -// this range being formatted as an exponential. -unsigned numberToString(double x, NumberToStringBuffer& buffer) +Vector<char> asciiDebug(StringImpl* impl) { - // Handle NaN and Infinity. - if (UNLIKELY(isnan(x) || isinf(x))) - return nanOrInfToString(x, buffer); - - // Convert to decimal, no rounding. - DecimalNumber number(x); + if (!impl) + return asciiDebug(String("[null]").impl()); - // Format as decimal or exponential, depending on the exponent. - return number.exponent() >= -6 && number.exponent() < 21 - ? number.toStringDecimal(buffer) - : number.toStringExponential(buffer); -} + Vector<char> buffer; + unsigned length = impl->length(); + const UChar* characters = impl->characters(); -} // namespace WTF + buffer.resize(length + 1); + for (unsigned i = 0; i < length; ++i) { + UChar ch = characters[i]; + buffer[i] = ch && (ch < 0x20 || ch > 0x7f) ? '?' : ch; + } + buffer[length] = '\0'; -#ifndef NDEBUG -// For use in the debugger - leaks memory -String* string(const char*); + return buffer; +} -String* string(const char* s) +Vector<char> asciiDebug(String& string) { - return new String(s); + return asciiDebug(string.impl()); } + #endif diff --git a/JavaScriptCore/wtf/text/WTFString.h b/JavaScriptCore/wtf/text/WTFString.h index 8a6bab6..fafef12 100644 --- a/JavaScriptCore/wtf/text/WTFString.h +++ b/JavaScriptCore/wtf/text/WTFString.h @@ -52,10 +52,6 @@ class BString; namespace WTF { -// Size = 80 for sizeof(DtoaBuffer) + some sign bits, decimal point, 'e', exponent digits. -typedef UChar NumberToStringBuffer[96]; -unsigned numberToString(double, NumberToStringBuffer&); - class CString; // Declarations of string operations @@ -457,7 +453,4 @@ using WTF::charactersToInt; using WTF::charactersToFloat; using WTF::charactersToDouble; -using WTF::NumberToStringBuffer; -using WTF::numberToString; - #endif diff --git a/JavaScriptCore/wtf/unicode/glib/UnicodeMacrosFromICU.h b/JavaScriptCore/wtf/unicode/glib/UnicodeMacrosFromICU.h index 5d3eca6..1963576 100644 --- a/JavaScriptCore/wtf/unicode/glib/UnicodeMacrosFromICU.h +++ b/JavaScriptCore/wtf/unicode/glib/UnicodeMacrosFromICU.h @@ -27,6 +27,7 @@ // some defines from ICU +#define U_IS_BMP(c) ((UChar32)(c)<=0xffff) #define U16_IS_LEAD(c) (((c)&0xfffffc00)==0xd800) #define U16_IS_TRAIL(c) (((c)&0xfffffc00)==0xdc00) #define U16_SURROGATE_OFFSET ((0xd800<<10UL)+0xdc00-0x10000) diff --git a/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h b/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h index aa203a2..badab66 100644 --- a/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h +++ b/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h @@ -64,7 +64,9 @@ typedef uint16_t UChar; typedef uint32_t UChar32; // some defines from ICU +// FIXME: This should use UnicodeMacrosFromICU.h instead! +#define U_IS_BMP(c) ((UChar32)(c)<=0xffff) #define U16_IS_LEAD(c) (((c)&0xfffffc00)==0xd800) #define U16_IS_TRAIL(c) (((c)&0xfffffc00)==0xdc00) #define U16_SURROGATE_OFFSET ((0xd800<<10UL)+0xdc00-0x10000) diff --git a/JavaScriptCore/wtf/unicode/wince/UnicodeWince.h b/JavaScriptCore/wtf/unicode/wince/UnicodeWince.h index 68da35a..3866568 100644 --- a/JavaScriptCore/wtf/unicode/wince/UnicodeWince.h +++ b/JavaScriptCore/wtf/unicode/wince/UnicodeWince.h @@ -29,7 +29,9 @@ #define TO_MASK(x) (1 << (x)) // some defines from ICU needed one or two places +// FIXME: This should use UnicodeMacrosFromICU.h instead! +#define U_IS_BMP(c) ((UChar32)(c)<=0xffff) #define U16_IS_LEAD(c) (((c) & 0xfffffc00) == 0xd800) #define U16_IS_TRAIL(c) (((c) & 0xfffffc00) == 0xdc00) #define U16_SURROGATE_OFFSET ((0xd800 << 10UL) + 0xdc00 - 0x10000) |