diff options
author | Steve Block <steveblock@google.com> | 2010-08-27 11:02:25 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-09-02 17:17:20 +0100 |
commit | e8b154fd68f9b33be40a3590e58347f353835f5c (patch) | |
tree | 0733ce26384183245aaa5656af26c653636fe6c1 /JavaScriptCore/wtf | |
parent | da56157816334089526a7a115a85fd85a6e9a1dc (diff) | |
download | external_webkit-e8b154fd68f9b33be40a3590e58347f353835f5c.zip external_webkit-e8b154fd68f9b33be40a3590e58347f353835f5c.tar.gz external_webkit-e8b154fd68f9b33be40a3590e58347f353835f5c.tar.bz2 |
Merge WebKit at r66079 : Initial merge by git
Change-Id: Ie2e1440fb9d487d24e52c247342c076fecaecac7
Diffstat (limited to 'JavaScriptCore/wtf')
-rw-r--r-- | JavaScriptCore/wtf/DecimalNumber.h | 328 | ||||
-rw-r--r-- | JavaScriptCore/wtf/ListHashSet.h | 3 | ||||
-rw-r--r-- | JavaScriptCore/wtf/PageReservation.h | 4 | ||||
-rw-r--r-- | JavaScriptCore/wtf/PlatformRefPtr.h | 193 | ||||
-rw-r--r-- | JavaScriptCore/wtf/dtoa.cpp | 79 | ||||
-rw-r--r-- | JavaScriptCore/wtf/dtoa.h | 6 | ||||
-rw-r--r-- | JavaScriptCore/wtf/gobject/GRefPtr.cpp | 25 | ||||
-rw-r--r-- | JavaScriptCore/wtf/gobject/GRefPtr.h | 160 | ||||
-rw-r--r-- | JavaScriptCore/wtf/text/WTFString.cpp | 39 | ||||
-rw-r--r-- | JavaScriptCore/wtf/text/WTFString.h | 7 |
10 files changed, 603 insertions, 241 deletions
diff --git a/JavaScriptCore/wtf/DecimalNumber.h b/JavaScriptCore/wtf/DecimalNumber.h new file mode 100644 index 0000000..118c492 --- /dev/null +++ b/JavaScriptCore/wtf/DecimalNumber.h @@ -0,0 +1,328 @@ +/* + * 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 DecimalNumber_h +#define DecimalNumber_h + +#include <math.h> +#include <wtf/dtoa.h> +#include <wtf/MathExtras.h> +#include <wtf/text/WTFString.h> + +namespace WTF { + +enum RoundingSignificantFiguresType { RoundingSignificantFigures }; +enum RoundingDecimalPlacesType { RoundingDecimalPlaces }; + +class DecimalNumber { +public: + DecimalNumber(double d) + { + bool sign = d < 0; // This (correctly) ignores the sign on -0.0. + init(sign, d); + } + + // 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); + + // 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; + + // Make sure the significand does not contain more digits than requested. + roundToPrecision(significantFigures); + } + + // 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); + + unsigned significantFigures = 1 + m_exponent + decimalPlaces; + ASSERT(significantFigures && significantFigures <= 41); + roundToPrecision(significantFigures); + } + + unsigned toStringDecimal(NumberToStringBuffer& buffer) + { + // Should always be at least one digit to add to the string! + ASSERT(m_precision); + UChar* next = buffer; + + // if the exponent is negative the number decimal representation is of the form: + // [<sign>]0.[<zeros>]<significand> + if (m_exponent < 0) { + unsigned zeros = -m_exponent - 1; + + if (m_sign) + *next++ = '-'; + *next++ = '0'; + *next++ = '.'; + for (unsigned i = 0; i < zeros; ++i) + *next++ = '0'; + for (unsigned i = 0; i < m_precision; ++i) + *next++ = m_significand[i]; + + return next - buffer; + } + + unsigned digitsBeforeDecimalPoint = m_exponent + 1; + + // If the precision is <= than the number of digits to get up to the decimal + // point, then there is no fractional part, number is of the form: + // [<sign>]<significand>[<zeros>] + if (m_precision <= digitsBeforeDecimalPoint) { + if (m_sign) + *next++ = '-'; + for (unsigned i = 0; i < m_precision; ++i) + *next++ = m_significand[i]; + for (unsigned i = 0; i < (digitsBeforeDecimalPoint - m_precision); ++i) + *next++ = '0'; + + return next - buffer; + } + + // If we get here, number starts before the decimal point, and ends after it, + // as such is of the form: + // [<sign>]<significand-begin>.<significand-end> + + if (m_sign) + *next++ = '-'; + for (unsigned i = 0; i < digitsBeforeDecimalPoint; ++i) + *next++ = m_significand[i]; + *next++ = '.'; + for (unsigned i = digitsBeforeDecimalPoint; i < m_precision; ++i) + *next++ = m_significand[i]; + + return next - buffer; + } + + unsigned toStringExponential(NumberToStringBuffer &buffer) + { + // Should always be at least one digit to add to the string! + ASSERT(m_precision); + + UChar* next = buffer; + + // Add the sign + if (m_sign) + *next++ = '-'; + + // Add the significand + *next++ = m_significand[0]; + if (m_precision > 1) { + *next++ = '.'; + for (unsigned i = 1; i < m_precision; ++i) + *next++ = m_significand[i]; + } + + // Add "e+" or "e-" + *next++ = 'e'; + int exponent; + if (m_exponent >= 0) { + *next++ = '+'; + exponent = m_exponent; + } else { + *next++ = '-'; + exponent = -m_exponent; + } + + // Add the exponent + if (exponent >= 100) + *next++ = '0' + exponent / 100; + if (exponent >= 10) + *next++ = '0' + (exponent % 100) / 10; + *next++ = '0' + exponent % 10; + + return next - buffer; + } + + bool sign() { return m_sign; } + int exponent() { return m_exponent; } + const char* significand() { return m_significand; } // significand contains precision characters, is not null-terminated. + 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; + unsigned m_precision; +}; + +} // namespace WTF + +using WTF::DecimalNumber; +using WTF::RoundingSignificantFigures; +using WTF::RoundingDecimalPlaces; + +#endif // DecimalNumber_h diff --git a/JavaScriptCore/wtf/ListHashSet.h b/JavaScriptCore/wtf/ListHashSet.h index 09355ad..e14ac45 100644 --- a/JavaScriptCore/wtf/ListHashSet.h +++ b/JavaScriptCore/wtf/ListHashSet.h @@ -24,6 +24,7 @@ #include "Assertions.h" #include "HashSet.h" #include "OwnPtr.h" +#include "StdLibExtras.h" namespace WTF { @@ -171,7 +172,7 @@ namespace WTF { } private: - Node* pool() { return reinterpret_cast<Node*>(m_pool.pool); } + Node* pool() { return reinterpret_cast_ptr<Node*>(m_pool.pool); } Node* pastPool() { return pool() + m_poolSize; } bool inPool(Node* node) diff --git a/JavaScriptCore/wtf/PageReservation.h b/JavaScriptCore/wtf/PageReservation.h index 906b5a4..cfc7cd9 100644 --- a/JavaScriptCore/wtf/PageReservation.h +++ b/JavaScriptCore/wtf/PageReservation.h @@ -226,14 +226,14 @@ inline PageReservation PageReservation::systemReserve(size_t size, Usage usage, inline bool PageReservation::systemCommit(void* start, size_t size) { - intptr_t offset = reinterpret_cast<intptr_t>(m_base) - reinterpret_cast<intptr_t>(start); + intptr_t offset = reinterpret_cast<intptr_t>(start) - reinterpret_cast<intptr_t>(m_base); m_chunk->Commit(offset, size); return true; } inline void PageReservation::systemDecommit(void* start, size_t size) { - intptr_t offset = reinterpret_cast<intptr_t>(m_base) - reinterpret_cast<intptr_t>(start); + intptr_t offset = reinterpret_cast<intptr_t>(start) - reinterpret_cast<intptr_t>(m_base); m_chunk->Decommit(offset, size); } diff --git a/JavaScriptCore/wtf/PlatformRefPtr.h b/JavaScriptCore/wtf/PlatformRefPtr.h new file mode 100644 index 0000000..2d05ac9 --- /dev/null +++ b/JavaScriptCore/wtf/PlatformRefPtr.h @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008 Collabora Ltd. + * Copyright (C) 2009 Martin Robinson + * + * 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 PlatformRefPtr_h +#define PlatformRefPtr_h + +#include "AlwaysInline.h" +#include <algorithm> + +namespace WTF { + +enum PlatformRefPtrAdoptType { PlatformRefPtrAdopt }; +template <typename T> inline T* refPlatformPtr(T*); +template <typename T> inline void derefPlatformPtr(T*); +template <typename T> class PlatformRefPtr; +template <typename T> PlatformRefPtr<T> adoptPlatformRef(T*); + +template <typename T> class PlatformRefPtr { +public: + PlatformRefPtr() : m_ptr(0) { } + + PlatformRefPtr(T* ptr) + : m_ptr(ptr) + { + if (ptr) + refPlatformPtr(ptr); + } + + PlatformRefPtr(const PlatformRefPtr& o) + : m_ptr(o.m_ptr) + { + if (T* ptr = m_ptr) + refPlatformPtr(ptr); + } + + template <typename U> PlatformRefPtr(const PlatformRefPtr<U>& o) + : m_ptr(o.get()) + { + if (T* ptr = m_ptr) + refPlatformPtr(ptr); + } + + ~PlatformRefPtr() + { + if (T* ptr = m_ptr) + derefPlatformPtr(ptr); + } + + void clear() + { + T* ptr = m_ptr; + m_ptr = 0; + if (ptr) + derefPlatformPtr(ptr); + } + + T* get() const { return m_ptr; } + T& operator*() const { return *m_ptr; } + ALWAYS_INLINE T* operator->() const { return m_ptr; } + + bool operator!() const { return !m_ptr; } + + // This conversion operator allows implicit conversion to bool but not to other integer types. + typedef T* PlatformRefPtr::*UnspecifiedBoolType; + operator UnspecifiedBoolType() const { return m_ptr ? &PlatformRefPtr::m_ptr : 0; } + + PlatformRefPtr& operator=(const PlatformRefPtr&); + PlatformRefPtr& operator=(T*); + template <typename U> PlatformRefPtr& operator=(const PlatformRefPtr<U>&); + + void swap(PlatformRefPtr&); + friend PlatformRefPtr adoptPlatformRef<T>(T*); + +private: + static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); } + // Adopting constructor. + PlatformRefPtr(T* ptr, PlatformRefPtrAdoptType) : m_ptr(ptr) {} + + T* m_ptr; +}; + +template <typename T> inline PlatformRefPtr<T>& PlatformRefPtr<T>::operator=(const PlatformRefPtr<T>& o) +{ + T* optr = o.get(); + if (optr) + refPlatformPtr(optr); + T* ptr = m_ptr; + m_ptr = optr; + if (ptr) + derefPlatformPtr(ptr); + return *this; +} + +template <typename T> inline PlatformRefPtr<T>& PlatformRefPtr<T>::operator=(T* optr) +{ + T* ptr = m_ptr; + if (optr) + refPlatformPtr(optr); + m_ptr = optr; + if (ptr) + derefPlatformPtr(ptr); + return *this; +} + +template <class T> inline void PlatformRefPtr<T>::swap(PlatformRefPtr<T>& o) +{ + std::swap(m_ptr, o.m_ptr); +} + +template <class T> inline void swap(PlatformRefPtr<T>& a, PlatformRefPtr<T>& b) +{ + a.swap(b); +} + +template <typename T, typename U> inline bool operator==(const PlatformRefPtr<T>& a, const PlatformRefPtr<U>& b) +{ + return a.get() == b.get(); +} + +template <typename T, typename U> inline bool operator==(const PlatformRefPtr<T>& a, U* b) +{ + return a.get() == b; +} + +template <typename T, typename U> inline bool operator==(T* a, const PlatformRefPtr<U>& b) +{ + return a == b.get(); +} + +template <typename T, typename U> inline bool operator!=(const PlatformRefPtr<T>& a, const PlatformRefPtr<U>& b) +{ + return a.get() != b.get(); +} + +template <typename T, typename U> inline bool operator!=(const PlatformRefPtr<T>& a, U* b) +{ + return a.get() != b; +} + +template <typename T, typename U> inline bool operator!=(T* a, const PlatformRefPtr<U>& b) +{ + return a != b.get(); +} + +template <typename T, typename U> inline PlatformRefPtr<T> static_pointer_cast(const PlatformRefPtr<U>& p) +{ + return PlatformRefPtr<T>(static_cast<T*>(p.get())); +} + +template <typename T, typename U> inline PlatformRefPtr<T> const_pointer_cast(const PlatformRefPtr<U>& p) +{ + return PlatformRefPtr<T>(const_cast<T*>(p.get())); +} + +template <typename T> inline T* getPtr(const PlatformRefPtr<T>& p) +{ + return p.get(); +} + +template <typename T> PlatformRefPtr<T> adoptPlatformRef(T* p) +{ + return PlatformRefPtr<T>(p, PlatformRefPtrAdopt); +} + +} // namespace WTF + +using WTF::PlatformRefPtr; +using WTF::refPlatformPtr; +using WTF::derefPlatformPtr; +using WTF::adoptPlatformRef; +using WTF::static_pointer_cast; +using WTF::const_pointer_cast; + +#endif // PlatformRefPtr_h diff --git a/JavaScriptCore/wtf/dtoa.cpp b/JavaScriptCore/wtf/dtoa.cpp index f7e19bf..88e5692 100644 --- a/JavaScriptCore/wtf/dtoa.cpp +++ b/JavaScriptCore/wtf/dtoa.cpp @@ -2285,83 +2285,4 @@ ret: *rve = s; } -static ALWAYS_INLINE void append(char*& next, const char* src, unsigned size) -{ - for (unsigned i = 0; i < size; ++i) - *next++ = *src++; -} - -void doubleToStringInJavaScriptFormat(double d, DtoaBuffer buffer, unsigned* resultLength) -{ - ASSERT(buffer); - - // avoid ever printing -NaN, in JS conceptually there is only one NaN value - if (isnan(d)) { - append(buffer, "NaN", 3); - if (resultLength) - *resultLength = 3; - return; - } - // -0 -> "0" - if (!d) { - buffer[0] = '0'; - if (resultLength) - *resultLength = 1; - return; - } - - int decimalPoint; - int sign; - - DtoaBuffer result; - char* resultEnd = 0; - WTF::dtoa(result, d, 0, &decimalPoint, &sign, &resultEnd); - int length = resultEnd - result; - - char* next = buffer; - if (sign) - *next++ = '-'; - - if (decimalPoint <= 0 && decimalPoint > -6) { - *next++ = '0'; - *next++ = '.'; - for (int j = decimalPoint; j < 0; j++) - *next++ = '0'; - append(next, result, length); - } else if (decimalPoint <= 21 && decimalPoint > 0) { - if (length <= decimalPoint) { - append(next, result, length); - for (int j = 0; j < decimalPoint - length; j++) - *next++ = '0'; - } else { - append(next, result, decimalPoint); - *next++ = '.'; - append(next, result + decimalPoint, length - decimalPoint); - } - } else if (result[0] < '0' || result[0] > '9') - append(next, result, length); - else { - *next++ = result[0]; - if (length > 1) { - *next++ = '.'; - append(next, result + 1, length - 1); - } - - *next++ = 'e'; - *next++ = (decimalPoint >= 0) ? '+' : '-'; - // decimalPoint can't be more than 3 digits decimal given the - // nature of float representation - int exponential = decimalPoint - 1; - if (exponential < 0) - exponential = -exponential; - if (exponential >= 100) - *next++ = static_cast<char>('0' + exponential / 100); - if (exponential >= 10) - *next++ = static_cast<char>('0' + (exponential % 100) / 10); - *next++ = static_cast<char>('0' + exponential % 10); - } - if (resultLength) - *resultLength = next - buffer; -} - } // namespace WTF diff --git a/JavaScriptCore/wtf/dtoa.h b/JavaScriptCore/wtf/dtoa.h index e0938ff..bf00ccc 100644 --- a/JavaScriptCore/wtf/dtoa.h +++ b/JavaScriptCore/wtf/dtoa.h @@ -36,14 +36,8 @@ 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); -// dtoa() for ECMA-262 'ToString Applied to the Number Type.' -// The *resultLength will have the length of the resultant string in bufer. -// The resultant string isn't terminated by 0. -void doubleToStringInJavaScriptFormat(double, DtoaBuffer, unsigned* resultLength); - } // namespace WTF using WTF::DtoaBuffer; -using WTF::doubleToStringInJavaScriptFormat; #endif // WTF_dtoa_h diff --git a/JavaScriptCore/wtf/gobject/GRefPtr.cpp b/JavaScriptCore/wtf/gobject/GRefPtr.cpp index 9d16cb5..c16024c 100644 --- a/JavaScriptCore/wtf/gobject/GRefPtr.cpp +++ b/JavaScriptCore/wtf/gobject/GRefPtr.cpp @@ -23,30 +23,47 @@ namespace WTF { -template <> GHashTable* refGPtr(GHashTable* ptr) +template <> GHashTable* refPlatformPtr(GHashTable* ptr) { if (ptr) g_hash_table_ref(ptr); return ptr; } -template <> void derefGPtr(GHashTable* ptr) +template <> void derefPlatformPtr(GHashTable* ptr) { g_hash_table_unref(ptr); } #if GLIB_CHECK_VERSION(2, 24, 0) -template <> GVariant* refGPtr(GVariant* ptr) +template <> GVariant* refPlatformPtr(GVariant* ptr) { if (ptr) g_variant_ref(ptr); return ptr; } -template <> void derefGPtr(GVariant* ptr) +template <> void derefPlatformPtr(GVariant* ptr) { g_variant_unref(ptr); } + +#else + +// We do this so that we can avoid including the glib.h header in GRefPtr.h. +typedef struct _GVariant { + bool fake; +} GVariant; + +template <> GVariant* refPlatformPtr(GVariant* ptr) +{ + return ptr; +} + +template <> void derefPlatformPtr(GVariant* ptr) +{ +} + #endif } // namespace WTF diff --git a/JavaScriptCore/wtf/gobject/GRefPtr.h b/JavaScriptCore/wtf/gobject/GRefPtr.h index 9a07d93..064c87e 100644 --- a/JavaScriptCore/wtf/gobject/GRefPtr.h +++ b/JavaScriptCore/wtf/gobject/GRefPtr.h @@ -24,157 +24,30 @@ #define WTF_GRefPtr_h #include "AlwaysInline.h" +#include "PlatformRefPtr.h" #include <algorithm> -#include <glib.h> -namespace WTF { - -enum GRefPtrAdoptType { GRefPtrAdopt }; -template <typename T> inline T* refGPtr(T*); -template <typename T> inline void derefGPtr(T*); -template <typename T> class GRefPtr; -template <typename T> GRefPtr<T> adoptGRef(T*); -template <> GHashTable* refGPtr(GHashTable* ptr); -template <> void derefGPtr(GHashTable* ptr); - -#if GLIB_CHECK_VERSION(2, 24, 0) -template <> GVariant* refGPtr(GVariant* ptr); -template <> void derefGPtr(GVariant* ptr); -#endif - -template <typename T> class GRefPtr { -public: - GRefPtr() : m_ptr(0) { } - GRefPtr(T* ptr) : m_ptr(ptr) { if (ptr) refGPtr(ptr); } - GRefPtr(const GRefPtr& o) : m_ptr(o.m_ptr) { if (T* ptr = m_ptr) refGPtr(ptr); } - template <typename U> GRefPtr(const GRefPtr<U>& o) : m_ptr(o.get()) { if (T* ptr = m_ptr) refGPtr(ptr); } - - ~GRefPtr() { if (T* ptr = m_ptr) derefGPtr(ptr); } - - void clear() - { - T* ptr = m_ptr; - m_ptr = 0; - if (ptr) - derefGPtr(ptr); - } - - T* get() const { return m_ptr; } - T& operator*() const { return *m_ptr; } - ALWAYS_INLINE T* operator->() const { return m_ptr; } - - bool operator!() const { return !m_ptr; } +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); - // This conversion operator allows implicit conversion to bool but not to other integer types. - typedef T* GRefPtr::*UnspecifiedBoolType; - operator UnspecifiedBoolType() const { return m_ptr ? &GRefPtr::m_ptr : 0; } - - GRefPtr& operator=(const GRefPtr&); - GRefPtr& operator=(T*); - template <typename U> GRefPtr& operator=(const GRefPtr<U>&); - - void swap(GRefPtr&); - friend GRefPtr adoptGRef<T>(T*); - -private: - static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); } - // Adopting constructor. - GRefPtr(T* ptr, GRefPtrAdoptType) : m_ptr(ptr) {} - - T* m_ptr; -}; - -template <typename T> inline GRefPtr<T>& GRefPtr<T>::operator=(const GRefPtr<T>& o) -{ - T* optr = o.get(); - if (optr) - refGPtr(optr); - T* ptr = m_ptr; - m_ptr = optr; - if (ptr) - derefGPtr(ptr); - return *this; -} - -template <typename T> inline GRefPtr<T>& GRefPtr<T>::operator=(T* optr) -{ - T* ptr = m_ptr; - if (optr) - refGPtr(optr); - m_ptr = optr; - if (ptr) - derefGPtr(ptr); - return *this; -} - -template <class T> inline void GRefPtr<T>::swap(GRefPtr<T>& o) -{ - std::swap(m_ptr, o.m_ptr); -} - -template <class T> inline void swap(GRefPtr<T>& a, GRefPtr<T>& b) -{ - a.swap(b); -} - -template <typename T, typename U> inline bool operator==(const GRefPtr<T>& a, const GRefPtr<U>& b) -{ - return a.get() == b.get(); -} - -template <typename T, typename U> inline bool operator==(const GRefPtr<T>& a, U* b) -{ - return a.get() == b; -} - -template <typename T, typename U> inline bool operator==(T* a, const GRefPtr<U>& b) -{ - return a == b.get(); -} - -template <typename T, typename U> inline bool operator!=(const GRefPtr<T>& a, const GRefPtr<U>& b) -{ - return a.get() != b.get(); -} - -template <typename T, typename U> inline bool operator!=(const GRefPtr<T>& a, U* b) -{ - return a.get() != b; -} - -template <typename T, typename U> inline bool operator!=(T* a, const GRefPtr<U>& b) -{ - return a != b.get(); -} - -template <typename T, typename U> inline GRefPtr<T> static_pointer_cast(const GRefPtr<U>& p) -{ - return GRefPtr<T>(static_cast<T*>(p.get())); -} - -template <typename T, typename U> inline GRefPtr<T> const_pointer_cast(const GRefPtr<U>& p) -{ - return GRefPtr<T>(const_cast<T*>(p.get())); -} +namespace WTF { -template <typename T> inline T* getPtr(const GRefPtr<T>& p) -{ - return p.get(); -} +template <> GHashTable* refPlatformPtr(GHashTable* ptr); +template <> void derefPlatformPtr(GHashTable* ptr); +template <> GVariant* refPlatformPtr(GVariant* ptr); +template <> void derefPlatformPtr(GVariant* ptr); -template <typename T> GRefPtr<T> adoptGRef(T* p) -{ - return GRefPtr<T>(p, GRefPtrAdopt); -} - -template <typename T> inline T* refGPtr(T* ptr) +template <typename T> inline T* refPlatformPtr(T* ptr) { if (ptr) g_object_ref_sink(ptr); return ptr; } -template <typename T> inline void derefGPtr(T* ptr) +template <typename T> inline void derefPlatformPtr(T* ptr) { if (ptr) g_object_unref(ptr); @@ -182,11 +55,4 @@ template <typename T> inline void derefGPtr(T* ptr) } // namespace WTF -using WTF::GRefPtr; -using WTF::refGPtr; -using WTF::derefGPtr; -using WTF::adoptGRef; -using WTF::static_pointer_cast; -using WTF::const_pointer_cast; - #endif // WTF_GRefPtr_h diff --git a/JavaScriptCore/wtf/text/WTFString.cpp b/JavaScriptCore/wtf/text/WTFString.cpp index 7d44d21..bbff576 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/text/CString.h> +#include <wtf/DecimalNumber.h> #include <wtf/StringExtras.h> #include <wtf/Vector.h> -#include <wtf/dtoa.h> +#include <wtf/text/CString.h> #include <wtf/unicode/UTF8.h> #include <wtf/unicode/Unicode.h> @@ -947,6 +947,41 @@ 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; +} + +static NEVER_INLINE unsigned nanOrInfToString(double x, NumberToStringBuffer& buffer) +{ + 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); +} + +// 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) +{ + // Handle NaN and Infinity. + if (UNLIKELY(isnan(x) || isinf(x))) + return nanOrInfToString(x, buffer); + + // Convert to decimal, no rounding. + DecimalNumber number(x); + + // Format as decimal or exponential, depending on the exponent. + return number.exponent() >= -6 && number.exponent() < 21 + ? number.toStringDecimal(buffer) + : number.toStringExponential(buffer); +} + } // namespace WTF #ifndef NDEBUG diff --git a/JavaScriptCore/wtf/text/WTFString.h b/JavaScriptCore/wtf/text/WTFString.h index fafef12..8a6bab6 100644 --- a/JavaScriptCore/wtf/text/WTFString.h +++ b/JavaScriptCore/wtf/text/WTFString.h @@ -52,6 +52,10 @@ 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 @@ -453,4 +457,7 @@ using WTF::charactersToInt; using WTF::charactersToFloat; using WTF::charactersToDouble; +using WTF::NumberToStringBuffer; +using WTF::numberToString; + #endif |