summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2010-08-27 11:02:25 +0100
committerSteve Block <steveblock@google.com>2010-09-02 17:17:20 +0100
commite8b154fd68f9b33be40a3590e58347f353835f5c (patch)
tree0733ce26384183245aaa5656af26c653636fe6c1 /JavaScriptCore
parentda56157816334089526a7a115a85fd85a6e9a1dc (diff)
downloadexternal_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')
-rw-r--r--JavaScriptCore/ChangeLog345
-rw-r--r--JavaScriptCore/GNUmakefile.am1
-rw-r--r--JavaScriptCore/JavaScriptCore.exp3
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def3
-rw-r--r--JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj5
-rw-r--r--JavaScriptCore/assembler/ARMAssembler.h12
-rw-r--r--JavaScriptCore/assembler/MacroAssemblerARM.h16
-rw-r--r--JavaScriptCore/interpreter/Interpreter.cpp2
-rw-r--r--JavaScriptCore/jit/JITStubs.cpp10
-rw-r--r--JavaScriptCore/jit/ThunkGenerators.cpp14
-rw-r--r--JavaScriptCore/runtime/JSArray.cpp9
-rw-r--r--JavaScriptCore/runtime/JSGlobalData.cpp1
-rw-r--r--JavaScriptCore/runtime/JSGlobalData.h2
-rw-r--r--JavaScriptCore/runtime/JSGlobalObject.cpp1
-rw-r--r--JavaScriptCore/runtime/JSGlobalObject.h10
-rw-r--r--JavaScriptCore/runtime/JSValue.cpp14
-rw-r--r--JavaScriptCore/runtime/JSValue.h36
-rw-r--r--JavaScriptCore/runtime/MathObject.cpp2
-rw-r--r--JavaScriptCore/runtime/NumberPrototype.cpp416
-rw-r--r--JavaScriptCore/runtime/RegExp.cpp31
-rw-r--r--JavaScriptCore/runtime/RegExp.h3
-rw-r--r--JavaScriptCore/runtime/StringBuilder.h9
-rw-r--r--JavaScriptCore/runtime/StringPrototype.cpp5
-rw-r--r--JavaScriptCore/runtime/UString.cpp10
-rw-r--r--JavaScriptCore/wscript13
-rw-r--r--JavaScriptCore/wtf/DecimalNumber.h328
-rw-r--r--JavaScriptCore/wtf/ListHashSet.h3
-rw-r--r--JavaScriptCore/wtf/PageReservation.h4
-rw-r--r--JavaScriptCore/wtf/PlatformRefPtr.h193
-rw-r--r--JavaScriptCore/wtf/dtoa.cpp79
-rw-r--r--JavaScriptCore/wtf/dtoa.h6
-rw-r--r--JavaScriptCore/wtf/gobject/GRefPtr.cpp25
-rw-r--r--JavaScriptCore/wtf/gobject/GRefPtr.h160
-rw-r--r--JavaScriptCore/wtf/text/WTFString.cpp39
-rw-r--r--JavaScriptCore/wtf/text/WTFString.h7
35 files changed, 1192 insertions, 625 deletions
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 1c7f689..fd23733 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,348 @@
+2010-08-25 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Kevin Ollivier.
+
+ [BREWMP] Add build system
+ https://bugs.webkit.org/show_bug.cgi?id=44645
+
+ Make waf script portable so that we can add more ports.
+
+ * wscript:
+
+2010-08-25 Michael Saboff <msaboff@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Remove the single entry regular expression cache introduced as part of
+ the fix for https://bugs.webkit.org/show_bug.cgi?id=41238.
+ The performance problem in Dromaeo that initiated that bug is no
+ longer present. Dromaeo has been modified so that the regular
+ expression tests are somewhat random and don't benefit from a
+ single entry cache.
+
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::RegExp):
+ (JSC::RegExp::match):
+ * runtime/RegExp.h:
+
+2010-08-25 Martin Robinson <mrobinson@igalia.com>
+
+ Reviewed by Gustavo Noronha Silva.
+
+ Cairo and EFL port shouldn't depend on glib.
+ https://bugs.webkit.org/show_bug.cgi?id=44354
+
+ Replace GRefPtr with PlatformRefPtr. Keep GLib specific bits in
+ GRefPtr.h.
+
+ * GNUmakefile.am: Add PlatformRefPtr.h to the source list.
+ * wtf/PlatformRefPtr.h: Migrated from GRefPtr.h.
+ (WTF::PlatformRefPtr::PlatformRefPtr): Ditto.
+ (WTF::PlatformRefPtr::~PlatformRefPtr): Ditto.
+ (WTF::PlatformRefPtr::clear): Ditto.
+ (WTF::PlatformRefPtr::get): Ditto.
+ (WTF::PlatformRefPtr::operator*): Ditto.
+ (WTF::PlatformRefPtr::operator->): Ditto.
+ (WTF::PlatformRefPtr::operator!): Ditto.
+ (WTF::PlatformRefPtr::operator UnspecifiedBoolType): Ditto.
+ (WTF::PlatformRefPtr::hashTableDeletedValue): Ditto.
+ (WTF::::operator): Ditto.
+ (WTF::::swap): Ditto.
+ (WTF::swap): Ditto.
+ (WTF::operator==): Ditto.
+ (WTF::operator!=): Ditto.
+ (WTF::static_pointer_cast): Ditto.
+ (WTF::const_pointer_cast): Ditto.
+ (WTF::getPtr): Ditto.
+ (WTF::adoptPlatformRef): Ditto.
+ * wtf/gobject/GRefPtr.cpp: Changes to reflect new names.
+ (WTF::refPlatformPtr):
+ (WTF::derefPlatformPtr):
+ * wtf/gobject/GRefPtr.h: Ditto.
+ (WTF::refPlatformPtr):
+ (WTF::derefPlatformPtr):
+
+2010-08-25 Xan Lopez <xlopez@igalia.com>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Remove dead code in JSGlobalObject
+ https://bugs.webkit.org/show_bug.cgi?id=44615
+
+ The recursion data member in the JSGlobalObject and its getter
+ plus inc/dec methods seems to be unused, remove them.
+
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::init):
+ * runtime/JSGlobalObject.h:
+
+2010-08-25 Michael Saboff <msaboff@apple.com>
+
+ Reviewed by Geoffrey Garen.
+
+ Changed the initial and subsequent allocation of vector storage to
+ Array()s. The changes are to limit sparse arrays to 100000 entries
+ and fixed the sparse map to vector storage conversion to use the
+ minimum amount of memory needed to store the current number of entries.
+ These changes address https://bugs.webkit.org/show_bug.cgi?id=43707
+
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::putSlowCase):
+ (JSC::JSArray::getNewVectorLength):
+
+2010-08-16 Gabor Loki <loki@webkit.org>
+
+ Reviewed by Gavin Barraclough.
+
+ Avoid increasing required alignment of target type warning
+ https://bugs.webkit.org/show_bug.cgi?id=43963
+
+ Fix platform independent alignment warnings.
+
+ * wtf/ListHashSet.h:
+ (WTF::ListHashSetNodeAllocator::pool):
+
+2010-08-19 Gabor Loki <loki@webkit.org>
+
+ Reviewed by Gavin Barraclough.
+
+ Enable truncated floating point feature on ARM
+ https://bugs.webkit.org/show_bug.cgi?id=44233
+
+ Enable truncated floating point feature with the help of VCVTR.S32.F64
+ instruction. If VCVTR.S32.F64 can't fit the result into a 32-bit
+ integer/register, it saturates at INT_MAX or INT_MIN. Testing this
+ looks quicker than testing FPSCR for exception.
+
+ Inspired by Jacob Bramley's patch from JaegerMonkey
+
+ * assembler/ARMAssembler.h:
+ (JSC::ARMAssembler::):
+ (JSC::ARMAssembler::cmn_r):
+ (JSC::ARMAssembler::vcvtr_s32_f64_r):
+ * assembler/MacroAssemblerARM.h:
+ (JSC::MacroAssemblerARM::supportsFloatingPointTruncate):
+ (JSC::MacroAssemblerARM::branchTruncateDoubleToInt32):
+
+2010-08-24 Gavin Barraclough <barraclough@apple.com>
+
+ Windows build fix.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-08-24 Gavin Barraclough <barraclough@apple.com>
+
+ Windows build fix.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * wtf/DecimalNumber.h:
+ (WTF::DecimalNumber::intPow10):
+ * wtf/dtoa.cpp:
+ * wtf/dtoa.h:
+
+2010-08-23 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=44487
+
+ Number.toExponential/toFixed/toPrecision all contain a spaghetti of duplicated
+ code & unnecessary complexity. Add a new DecimalNumber class to encapsulate
+ double to string conversion, share the implementations of rounding &
+ decimal-fraction/exponential formatting.
+
+ * JavaScriptCore.exp:
+ Update exports.
+
+ * runtime/NumberPrototype.cpp:
+ (JSC::toThisNumber):
+ (JSC::getIntegerArgumentInRange):
+ Helper methods used in implementing toExponential/toFixed/toString.
+ (JSC::numberProtoFuncToExponential):
+ (JSC::numberProtoFuncToFixed):
+ (JSC::numberProtoFuncToPrecision):
+ Reimplemented using new DecimalNumber class.
+
+ * runtime/UString.cpp:
+ (JSC::UString::number):
+ Updated to call numberToString.
+
+ * wtf/DecimalNumber.h: Added.
+ (WTF::):
+ (WTF::DecimalNumber::DecimalNumber):
+ (WTF::DecimalNumber::toStringDecimal):
+ (WTF::DecimalNumber::toStringExponential):
+ (WTF::DecimalNumber::sign):
+ (WTF::DecimalNumber::exponent):
+ (WTF::DecimalNumber::significand):
+ (WTF::DecimalNumber::precision):
+ (WTF::DecimalNumber::init):
+ (WTF::DecimalNumber::isZero):
+ (WTF::DecimalNumber::roundToPrecision):
+ New class to perform double to string conversion.
+ Has three constructors, which allow conversion with no rounding,
+ rounding to significant-figures, or rounding to decimal-places,
+ and two methods for formatting strings, either using decimal
+ fraction or exponential encoding. Internal implementation uses
+ pre-rounding of the values before calling dtoa rather than
+ relying on dtoa to correctly round, which does not produce
+ fully accurate results. Hopefully we can address this in the
+ near future.
+
+ * wtf/dtoa.cpp:
+ (WTF::intPow10):
+ * wtf/dtoa.h:
+ intPow10 is used internally by DecimalNumber.
+
+ * wtf/text/WTFString.cpp:
+ (WTF::copyToString):
+ (WTF::nanOrInfToString):
+ Used internally in numberToString for NaN/Infinity handling.
+ (WTF::numberToString):
+ Added new method to convert doubles to strings.
+
+ * wtf/text/WTFString.h:
+ Added declaration for numberToString. This is here because
+ we should switch over to using this for all double to string
+ conversion in WebCore (see section 2.4.4.3 of the HTML5 spec).
+
+2010-08-24 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Don't seed the JS random number generator from time()
+ https://bugs.webkit.org/show_bug.cgi?id=41868
+ <rdar://problem/8171025>
+
+ Switch to using the secure random number generator to
+ seed the fast random generator, and make the generator
+ be per global object.
+
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ * runtime/JSGlobalData.h:
+ * runtime/JSGlobalObject.h:
+ (JSC::JSGlobalObject::JSGlobalObjectData::JSGlobalObjectData):
+ (JSC::JSGlobalObject::weakRandomNumber):
+ * runtime/MathObject.cpp:
+ (JSC::mathProtoFuncRandom):
+
+2010-08-24 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Beth Dakin.
+
+ Make overflow guards in UString::utf8 explicit
+ https://bugs.webkit.org/show_bug.cgi?id=44540
+
+ Add an explicit overflow check prior to allocating our buffer,
+ rather than implicitly relying on the guard in convertUTF16ToUTF8.
+
+ * runtime/UString.cpp:
+ (JSC::UString::utf8):
+
+2010-08-24 Yael Aharon <yael.aharon@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Symbian] Fix commit/decommit of system memory using RChunk
+
+ Swap accidentially reversed start and m_base values for determining the
+ offset within the RChunk.
+
+ * wtf/PageReservation.h:
+ (WTF::PageReservation::systemCommit):
+ (WTF::PageReservation::systemDecommit):
+
+2010-08-23 Patrick Gansterer <paroga@paroga.com>
+
+ Rubber-stamped by Gabor Loki.
+
+ [WINCE] Buildfix for GeneratedJITStubs after r64818
+ https://bugs.webkit.org/show_bug.cgi?id=44469
+
+ Use " THUNK_RETURN_ADDRESS_OFFSET" instead of "#offset#".
+
+ * jit/JITStubs.cpp:
+
+2010-08-23 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Darin Adler.
+
+ [REGRESSION] Interpreter incorrectly excludes prototype chain when validating put_by_id_transition
+ https://bugs.webkit.org/show_bug.cgi?id=44240
+ <rdar://problem/8328995>
+
+ Fix an error I introduced when cleaning up the interpreter side of the logic
+ to prevent setters being called in object initialisers.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+
+2010-08-23 Michael Saboff <msaboff@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Fixed case where a single character search string in a string.replace()
+ did not properly handle back reference replacement. The fix is to
+ check for a '$' as part of the check to see if we can execute the
+ single character replace optimization.
+ https://bugs.webkit.org/show_bug.cgi?id=44067
+
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncReplace):
+
+2010-08-23 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ JSON.stringify is much slower than Firefox on particular pathological input
+ https://bugs.webkit.org/show_bug.cgi?id=44456
+
+ Make StringBuilder::reserveCapacity reserve additional space so we don't end up
+ repeatedly copying the entire result string.
+
+ * runtime/StringBuilder.h:
+ (JSC::StringBuilder::append):
+ (JSC::StringBuilder::reserveCapacity):
+
+2010-08-23 Jian Li <jianli@chromium.org>
+
+ Reviewed by Darin Fisher.
+
+ Handle blob resource.
+ https://bugs.webkit.org/show_bug.cgi?id=43941
+
+ * JavaScriptCore.exp: Add an export that is neede by BlobResourceHandle.
+
+2010-08-19 Andreas Kling <andreas.kling@nokia.com>
+
+ Reviewed by Geoffrey Garen.
+
+ JSC: Move the static_cast into to(U)Int32 fast case
+ https://bugs.webkit.org/show_bug.cgi?id=44037
+
+ Do the static_cast<(u)int32_t> inline to avoid the function call overhead
+ for easily converted values (within (u)int32_t range.)
+
+ * runtime/JSValue.cpp:
+ (JSC::toInt32SlowCase):
+ (JSC::toUInt32SlowCase):
+ * runtime/JSValue.h:
+ (JSC::JSValue::toInt32):
+ (JSC::JSValue::toUInt32):
+
+2010-08-18 Andreas Kling <andreas.kling@nokia.com>
+
+ Reviewed by Geoffrey Garen.
+
+ REGRESSION(r58469): Math.pow() always returns double-backed JSValue which is extremely slow as array subscript
+ https://bugs.webkit.org/show_bug.cgi?id=43742
+
+ Add codegen for pow() to return Int32 values when possible.
+
+ * jit/ThunkGenerators.cpp:
+ (JSC::powThunkGenerator):
+
2010-08-18 Gabor Loki <loki@webkit.org>
Reviewed by Gavin Barraclough.
diff --git a/JavaScriptCore/GNUmakefile.am b/JavaScriptCore/GNUmakefile.am
index fae85e1..ecd7ffe 100644
--- a/JavaScriptCore/GNUmakefile.am
+++ b/JavaScriptCore/GNUmakefile.am
@@ -469,6 +469,7 @@ javascriptcore_sources += \
JavaScriptCore/wtf/PassOwnPtr.h \
JavaScriptCore/wtf/PassRefPtr.h \
JavaScriptCore/wtf/Platform.h \
+ JavaScriptCore/wtf/PlatformRefPtr.h \
JavaScriptCore/wtf/PossiblyNull.h \
JavaScriptCore/wtf/RandomNumber.cpp \
JavaScriptCore/wtf/RandomNumber.h \
diff --git a/JavaScriptCore/JavaScriptCore.exp b/JavaScriptCore/JavaScriptCore.exp
index 5cfa1c2..4542730 100644
--- a/JavaScriptCore/JavaScriptCore.exp
+++ b/JavaScriptCore/JavaScriptCore.exp
@@ -377,6 +377,7 @@ __ZN3WTF13currentThreadEv
__ZN3WTF13tryFastCallocEmm
__ZN3WTF13tryFastMallocEm
__ZN3WTF14fastMallocSizeEPKv
+__ZN3WTF14numberToStringEdRA96_t
__ZN3WTF15ThreadCondition4waitERNS_5MutexE
__ZN3WTF15ThreadCondition6signalEv
__ZN3WTF15ThreadCondition9broadcastEv
@@ -411,7 +412,6 @@ __ZN3WTF23dayInMonthFromDayInYearEib
__ZN3WTF23waitForThreadCompletionEjPPv
__ZN3WTF27releaseFastMallocFreeMemoryEv
__ZN3WTF28setMainThreadCallbacksPausedEb
-__ZN3WTF32doubleToStringInJavaScriptFormatEdPcPj
__ZN3WTF36lockAtomicallyInitializedStaticMutexEv
__ZN3WTF37parseDateFromNullTerminatedCharactersEPKc
__ZN3WTF38unlockAtomicallyInitializedStaticMutexEv
@@ -534,6 +534,7 @@ __ZNK3JSC9HashTable11deleteTableEv
__ZNK3WTF12AtomicString5lowerEv
__ZNK3WTF6String11toIntStrictEPbi
__ZNK3WTF6String12toUIntStrictEPbi
+__ZNK3WTF6String13toInt64StrictEPbi
__ZNK3WTF6String14threadsafeCopyEv
__ZNK3WTF6String15stripWhiteSpaceEv
__ZNK3WTF6String16removeCharactersEPFbtE
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
index 934688f..eac99b9 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
+++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
@@ -126,7 +126,7 @@ EXPORTS
?detach@Debugger@JSC@@UAEXPAVJSGlobalObject@2@@Z
?detachThread@WTF@@YAXI@Z
?didTimeOut@TimeoutChecker@JSC@@QAE_NPAVExecState@2@@Z
- ?doubleToStringInJavaScriptFormat@WTF@@YAXNQADPAI@Z
+ ?dtoa@WTF@@YAXQADNHPAH1PAPAD@Z
?dumpSampleData@JSGlobalData@JSC@@QAEXPAVExecState@2@@Z
?empty@StringImpl@WTF@@SAPAV12@XZ
?enumerable@PropertyDescriptor@JSC@@QBE_NXZ
@@ -149,6 +149,7 @@ EXPORTS
?number@UString@JSC@@SA?AV12@H@Z
?number@UString@JSC@@SA?AV12@I@Z
?number@UString@JSC@@SA?AV12@N@Z
+ ?numberToString@WTF@@YAINAAY0GA@_W@Z
?functionGetter@PropertySlot@JSC@@ABE?AVJSValue@2@PAVExecState@2@@Z
?functionName@DebuggerCallFrame@JSC@@QBEPBVUString@2@XZ
?get@Structure@JSC@@QAEIPBVStringImpl@WTF@@AAIAAPAVJSCell@2@@Z
diff --git a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index 511a7a0..e11672c 100644
--- a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -200,6 +200,7 @@
8626BECF11928E3900782FAB /* StringStatics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8626BECE11928E3900782FAB /* StringStatics.cpp */; };
8627E5EB11F1281900A313B5 /* PageAllocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8627E5E911F1281900A313B5 /* PageAllocation.cpp */; };
8627E5EC11F1281900A313B5 /* PageAllocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 8627E5EA11F1281900A313B5 /* PageAllocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 862AF4B612239C7B0024E5B8 /* DecimalNumber.h in Headers */ = {isa = PBXBuildFile; fileRef = 862AF4B512239C7B0024E5B8 /* DecimalNumber.h */; };
863B23E00FC6118900703AA4 /* MacroAssemblerCodeRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 863B23DF0FC60E6200703AA4 /* MacroAssemblerCodeRef.h */; settings = {ATTRIBUTES = (Private, ); }; };
86565742115BE3DA00291F40 /* CString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86565740115BE3DA00291F40 /* CString.cpp */; };
86565743115BE3DA00291F40 /* CString.h in Headers */ = {isa = PBXBuildFile; fileRef = 86565741115BE3DA00291F40 /* CString.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -785,6 +786,7 @@
8626BECE11928E3900782FAB /* StringStatics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringStatics.cpp; path = text/StringStatics.cpp; sourceTree = "<group>"; };
8627E5E911F1281900A313B5 /* PageAllocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PageAllocation.cpp; sourceTree = "<group>"; };
8627E5EA11F1281900A313B5 /* PageAllocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PageAllocation.h; sourceTree = "<group>"; };
+ 862AF4B512239C7B0024E5B8 /* DecimalNumber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DecimalNumber.h; sourceTree = "<group>"; };
863B23DF0FC60E6200703AA4 /* MacroAssemblerCodeRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerCodeRef.h; sourceTree = "<group>"; };
86565740115BE3DA00291F40 /* CString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CString.cpp; path = text/CString.cpp; sourceTree = "<group>"; };
86565741115BE3DA00291F40 /* CString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CString.h; path = text/CString.h; sourceTree = "<group>"; };
@@ -1438,6 +1440,7 @@
180B9AF00F16C569009BDBC5 /* CurrentTime.h */,
41359CF40FDD89CB00206180 /* DateMath.cpp */,
41359CF50FDD89CB00206180 /* DateMath.h */,
+ 862AF4B512239C7B0024E5B8 /* DecimalNumber.h */,
5186111D0CC824830081412B /* Deque.h */,
938C4F6B0CA06BCE00D9310A /* DisallowCType.h */,
651F6412039D5B5F0078395C /* dtoa.cpp */,
@@ -2233,6 +2236,7 @@
DDE82AD81209D955005C1756 /* GCHandle.h in Headers */,
86F38859121130CA007A7CE3 /* AtomicStringHash.h in Headers */,
86B6DA0212132B9A000D316F /* StringConcatenate.h in Headers */,
+ 862AF4B612239C7B0024E5B8 /* DecimalNumber.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2326,6 +2330,7 @@
isa = PBXProject;
buildConfigurationList = 149C277108902AFE008A9EFC /* Build configuration list for PBXProject "JavaScriptCore" */;
compatibilityVersion = "Xcode 2.4";
+ developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
English,
diff --git a/JavaScriptCore/assembler/ARMAssembler.h b/JavaScriptCore/assembler/ARMAssembler.h
index da128e7..dfa726a 100644
--- a/JavaScriptCore/assembler/ARMAssembler.h
+++ b/JavaScriptCore/assembler/ARMAssembler.h
@@ -161,6 +161,7 @@ namespace JSC {
VMOV_ARM = 0x0e100a10,
VCVT_F64_S32 = 0x0eb80bc0,
VCVT_S32_F64 = 0x0ebd0b40,
+ VCVTR_S32_F64 = 0x0ebd0bc0,
VMRS_APSR = 0x0ef1fa10,
#if WTF_ARM_ARCH_AT_LEAST(5)
CLZ = 0x016f0f10,
@@ -371,6 +372,11 @@ namespace JSC {
emitInst(static_cast<ARMWord>(cc) | CMP | SET_CC, 0, rn, op2);
}
+ void cmn_r(int rn, ARMWord op2, Condition cc = AL)
+ {
+ emitInst(static_cast<ARMWord>(cc) | CMN | SET_CC, 0, rn, op2);
+ }
+
void orr_r(int rd, int rn, ARMWord op2, Condition cc = AL)
{
emitInst(static_cast<ARMWord>(cc) | ORR, rd, rn, op2);
@@ -578,6 +584,12 @@ namespace JSC {
emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VCVT_S32_F64, (sd >> 1), 0, dm);
}
+ void vcvtr_s32_f64_r(int sd, int dm, Condition cc = AL)
+ {
+ ASSERT(!(sd & 0x1)); // sd must be divisible by 2
+ emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VCVTR_S32_F64, (sd >> 1), 0, dm);
+ }
+
void vmrs_apsr(Condition cc = AL)
{
m_buffer.putInt(static_cast<ARMWord>(cc) | VMRS_APSR);
diff --git a/JavaScriptCore/assembler/MacroAssemblerARM.h b/JavaScriptCore/assembler/MacroAssemblerARM.h
index 48ddf24..5de8b34 100644
--- a/JavaScriptCore/assembler/MacroAssemblerARM.h
+++ b/JavaScriptCore/assembler/MacroAssemblerARM.h
@@ -769,7 +769,7 @@ public:
bool supportsFloatingPointTruncate() const
{
- return false;
+ return s_isVFPPresent;
}
bool supportsFloatingPointSqrt() const
@@ -878,13 +878,17 @@ public:
// Truncates 'src' to an integer, and places the resulting 'dest'.
// If the result is not representable as a 32 bit value, branch.
// May also branch for some values that are representable in 32 bits
- // (specifically, in this case, INT_MIN).
+ // (specifically, in this case, INT_MIN and INT_MAX).
Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest)
{
- UNUSED_PARAM(src);
- UNUSED_PARAM(dest);
- ASSERT_NOT_REACHED();
- return jump();
+ m_assembler.vcvtr_s32_f64_r(ARMRegisters::SD0 << 1, src);
+ // If VCVTR.S32.F64 can't fit the result into a 32-bit
+ // integer, it saturates at INT_MAX or INT_MIN. Testing this is
+ // probably quicker than testing FPSCR for exception.
+ m_assembler.vmov_arm_r(dest, ARMRegisters::SD0 << 1);
+ m_assembler.sub_r(ARMRegisters::S0, dest, ARMAssembler::getOp2(0x80000000));
+ m_assembler.cmn_r(ARMRegisters::S0, ARMAssembler::getOp2(1), ARMCondition(NotEqual));
+ return Jump(m_assembler.jmp(ARMCondition(Equal)));
}
// Convert 'src' to an integer, and places the resulting 'dest'.
diff --git a/JavaScriptCore/interpreter/Interpreter.cpp b/JavaScriptCore/interpreter/Interpreter.cpp
index b1049ad..d43eb57 100644
--- a/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/JavaScriptCore/interpreter/Interpreter.cpp
@@ -2952,7 +2952,7 @@ skip_id_custom_self:
JSObject* baseObject = asObject(baseCell);
int direct = vPC[8].u.operand;
- if (direct) {
+ if (!direct) {
RefPtr<Structure>* it = vPC[6].u.structureChain->head();
JSValue proto = baseObject->structure()->prototypeForLookup(callFrame);
diff --git a/JavaScriptCore/jit/JITStubs.cpp b/JavaScriptCore/jit/JITStubs.cpp
index f1808d5..b53e655 100644
--- a/JavaScriptCore/jit/JITStubs.cpp
+++ b/JavaScriptCore/jit/JITStubs.cpp
@@ -1164,13 +1164,13 @@ MSVC_BEGIN()
MSVC_BEGIN(ctiTrampoline PROC)
MSVC_BEGIN( stmdb sp!, {r1-r3})
MSVC_BEGIN( stmdb sp!, {r4-r8, lr})
-MSVC_BEGIN( sub sp, sp, ##offset#+4)
+MSVC_BEGIN( sub sp, sp, # THUNK_RETURN_ADDRESS_OFFSET + 4)
MSVC_BEGIN( mov r4, r2)
MSVC_BEGIN( mov r5, #512)
MSVC_BEGIN( ; r0 contains the code)
MSVC_BEGIN( mov lr, pc)
MSVC_BEGIN( bx r0)
-MSVC_BEGIN( add sp, sp, ##offset#+4)
+MSVC_BEGIN( add sp, sp, # THUNK_RETURN_ADDRESS_OFFSET + 4)
MSVC_BEGIN( ldmia sp!, {r4-r8, lr})
MSVC_BEGIN( add sp, sp, #12)
MSVC_BEGIN( bx lr)
@@ -1181,7 +1181,7 @@ MSVC_BEGIN( mov r0, sp)
MSVC_BEGIN( mov lr, pc)
MSVC_BEGIN( bl cti_vm_throw)
MSVC_BEGIN(ctiOpThrowNotCaught)
-MSVC_BEGIN( add sp, sp, ##offset#+4)
+MSVC_BEGIN( add sp, sp, # THUNK_RETURN_ADDRESS_OFFSET + 4)
MSVC_BEGIN( ldmia sp!, {r4-r8, lr})
MSVC_BEGIN( add sp, sp, #12)
MSVC_BEGIN( bx lr)
@@ -1191,9 +1191,9 @@ MSVC_BEGIN()
MSVC( EXPORT cti_#op#)
MSVC( IMPORT JITStubThunked_#op#)
MSVC(cti_#op# PROC)
-MSVC( str lr, [sp, ##offset#])
+MSVC( str lr, [sp, # THUNK_RETURN_ADDRESS_OFFSET])
MSVC( bl JITStubThunked_#op#)
-MSVC( ldr lr, [sp, ##offset#])
+MSVC( ldr lr, [sp, # THUNK_RETURN_ADDRESS_OFFSET])
MSVC( bx lr)
MSVC(cti_#op# ENDP)
MSVC()
diff --git a/JavaScriptCore/jit/ThunkGenerators.cpp b/JavaScriptCore/jit/ThunkGenerators.cpp
index 20857cb..4c7a354 100644
--- a/JavaScriptCore/jit/ThunkGenerators.cpp
+++ b/JavaScriptCore/jit/ThunkGenerators.cpp
@@ -134,7 +134,14 @@ MacroAssemblerCodePtr powThunkGenerator(JSGlobalData* globalData, ExecutablePool
jit.branchTest32(MacroAssembler::NonZero, SpecializedThunkJIT::regT0).linkTo(startLoop, &jit);
exponentIsZero.link(&jit);
- jit.returnDouble(SpecializedThunkJIT::fpRegT1);
+
+ {
+ SpecializedThunkJIT::JumpList doubleResult;
+ jit.branchConvertDoubleToInt32(SpecializedThunkJIT::fpRegT1, SpecializedThunkJIT::regT0, doubleResult, SpecializedThunkJIT::fpRegT0);
+ jit.returnInt32(SpecializedThunkJIT::regT0);
+ doubleResult.link(&jit);
+ jit.returnDouble(SpecializedThunkJIT::fpRegT1);
+ }
if (jit.supportsFloatingPointSqrt()) {
nonIntExponent.link(&jit);
@@ -144,6 +151,11 @@ MacroAssemblerCodePtr powThunkGenerator(JSGlobalData* globalData, ExecutablePool
jit.appendFailure(jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, SpecializedThunkJIT::fpRegT2, SpecializedThunkJIT::fpRegT3));
jit.sqrtDouble(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT0);
jit.divDouble(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT1);
+
+ SpecializedThunkJIT::JumpList doubleResult;
+ jit.branchConvertDoubleToInt32(SpecializedThunkJIT::fpRegT1, SpecializedThunkJIT::regT0, doubleResult, SpecializedThunkJIT::fpRegT0);
+ jit.returnInt32(SpecializedThunkJIT::regT0);
+ doubleResult.link(&jit);
jit.returnDouble(SpecializedThunkJIT::fpRegT1);
} else
jit.appendFailure(nonIntExponent);
diff --git a/JavaScriptCore/runtime/JSArray.cpp b/JavaScriptCore/runtime/JSArray.cpp
index 9c3570b..55aa327 100644
--- a/JavaScriptCore/runtime/JSArray.cpp
+++ b/JavaScriptCore/runtime/JSArray.cpp
@@ -421,9 +421,10 @@ NEVER_INLINE void JSArray::putSlowCase(ExecState* exec, unsigned i, JSValue valu
if (i >= MIN_SPARSE_ARRAY_INDEX)
newNumValuesInVector -= map->contains(i);
if (isDenseEnoughForVector(newVectorLength, newNumValuesInVector)) {
+ unsigned needLength = max(i + 1, storage->m_length);
unsigned proposedNewNumValuesInVector = newNumValuesInVector;
// If newVectorLength is already the maximum - MAX_STORAGE_VECTOR_LENGTH - then do not attempt to grow any further.
- while (newVectorLength < MAX_STORAGE_VECTOR_LENGTH) {
+ while ((newVectorLength < needLength) && (newVectorLength < MAX_STORAGE_VECTOR_LENGTH)) {
unsigned proposedNewVectorLength = getNewVectorLength(newVectorLength + 1);
for (unsigned j = max(newVectorLength, MIN_SPARSE_ARRAY_INDEX); j < proposedNewVectorLength; ++j)
proposedNewNumValuesInVector += map->contains(j);
@@ -553,10 +554,10 @@ ALWAYS_INLINE unsigned JSArray::getNewVectorLength(unsigned desiredLength)
ASSERT(desiredLength <= MAX_STORAGE_VECTOR_LENGTH);
unsigned increasedLength;
- unsigned length = m_storage->m_length;
+ unsigned maxInitLength = min(m_storage->m_length, 100000U);
- if (desiredLength < length)
- increasedLength = length;
+ if (desiredLength < maxInitLength)
+ increasedLength = maxInitLength;
else if (!m_vectorLength)
increasedLength = max(desiredLength, lastArraySize);
else {
diff --git a/JavaScriptCore/runtime/JSGlobalData.cpp b/JavaScriptCore/runtime/JSGlobalData.cpp
index ca8605b..97f9be5 100644
--- a/JavaScriptCore/runtime/JSGlobalData.cpp
+++ b/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -143,7 +143,6 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
, firstStringifierToMark(0)
, markStack(jsArrayVPtr)
, cachedUTCOffset(NaN)
- , weakRandom(static_cast<int>(currentTime()))
, maxReentryDepth(threadStackType == ThreadStackTypeSmall ? MaxSmallThreadReentryDepth : MaxLargeThreadReentryDepth)
, m_regExpCache(new RegExpCache(this))
#ifndef NDEBUG
diff --git a/JavaScriptCore/runtime/JSGlobalData.h b/JavaScriptCore/runtime/JSGlobalData.h
index 1928f77..07acb43 100644
--- a/JavaScriptCore/runtime/JSGlobalData.h
+++ b/JavaScriptCore/runtime/JSGlobalData.h
@@ -213,8 +213,6 @@ namespace JSC {
UString cachedDateString;
double cachedDateStringValue;
-
- WeakRandom weakRandom;
int maxReentryDepth;
diff --git a/JavaScriptCore/runtime/JSGlobalObject.cpp b/JavaScriptCore/runtime/JSGlobalObject.cpp
index c317e13..89c042a 100644
--- a/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -141,7 +141,6 @@ void JSGlobalObject::init(JSObject* thisValue)
} else
headObject = d()->next = d()->prev = this;
- d()->recursion = 0;
d()->debugger = 0;
d()->profileGroup = 0;
diff --git a/JavaScriptCore/runtime/JSGlobalObject.h b/JavaScriptCore/runtime/JSGlobalObject.h
index e57b737..f5d2fb0 100644
--- a/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/JavaScriptCore/runtime/JSGlobalObject.h
@@ -31,6 +31,7 @@
#include "StringPrototype.h"
#include <wtf/HashSet.h>
#include <wtf/OwnPtr.h>
+#include <wtf/RandomNumber.h>
namespace JSC {
@@ -92,6 +93,7 @@ namespace JSC {
, datePrototype(0)
, regExpPrototype(0)
, methodCallDummy(0)
+ , weakRandom(static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
{
}
@@ -107,8 +109,6 @@ namespace JSC {
ScopeChain globalScopeChain;
Register globalCallFrame[RegisterFile::CallFrameHeaderSize];
- int recursion;
-
RegExpConstructor* regExpConstructor;
ErrorConstructor* errorConstructor;
NativeErrorConstructor* evalErrorConstructor;
@@ -156,6 +156,7 @@ namespace JSC {
HashSet<GlobalCodeBlock*> codeBlocks;
WeakMapSet weakMaps;
+ WeakRandom weakRandom;
};
public:
@@ -254,10 +255,6 @@ namespace JSC {
virtual bool supportsProfiling() const { return false; }
- int recursion() { return d()->recursion; }
- void incRecursion() { ++d()->recursion; }
- void decRecursion() { --d()->recursion; }
-
ScopeChain& globalScopeChain() { return d()->globalScopeChain; }
virtual bool isGlobalObject() const { return true; }
@@ -295,6 +292,7 @@ namespace JSC {
d()->weakMaps.remove(map);
}
+ double weakRandomNumber() { return d()->weakRandom.get(); }
protected:
static const unsigned AnonymousSlotCount = JSVariableObject::AnonymousSlotCount + 1;
diff --git a/JavaScriptCore/runtime/JSValue.cpp b/JavaScriptCore/runtime/JSValue.cpp
index e752d3f..6db6954 100644
--- a/JavaScriptCore/runtime/JSValue.cpp
+++ b/JavaScriptCore/runtime/JSValue.cpp
@@ -137,16 +137,13 @@ char* JSValue::description()
int32_t toInt32SlowCase(double d, bool& ok)
{
- ok = true;
-
- if (d >= -D32 / 2 && d < D32 / 2)
- return static_cast<int32_t>(d);
-
if (isnan(d) || isinf(d)) {
ok = false;
return 0;
}
+ ok = true;
+
double d32 = fmod(trunc(d), D32);
if (d32 >= D32 / 2)
d32 -= D32;
@@ -157,16 +154,13 @@ int32_t toInt32SlowCase(double d, bool& ok)
uint32_t toUInt32SlowCase(double d, bool& ok)
{
- ok = true;
-
- if (d >= 0.0 && d < D32)
- return static_cast<uint32_t>(d);
-
if (isnan(d) || isinf(d)) {
ok = false;
return 0;
}
+ ok = true;
+
double d32 = fmod(trunc(d), D32);
if (d32 < 0)
d32 += D32;
diff --git a/JavaScriptCore/runtime/JSValue.h b/JavaScriptCore/runtime/JSValue.h
index 3c6bc09..af4b0f4 100644
--- a/JavaScriptCore/runtime/JSValue.h
+++ b/JavaScriptCore/runtime/JSValue.h
@@ -397,16 +397,28 @@ namespace JSC {
{
if (isInt32())
return asInt32();
+
+ double val = toNumber(exec);
+
+ if (val >= -2147483648.0 && val < 2147483648.0)
+ return static_cast<int32_t>(val);
+
bool ignored;
- return toInt32SlowCase(toNumber(exec), ignored);
+ return toInt32SlowCase(val, ignored);
}
inline uint32_t JSValue::toUInt32(ExecState* exec) const
{
if (isUInt32())
return asInt32();
+
+ double val = toNumber(exec);
+
+ if (val >= 0.0 && val < 4294967296.0)
+ return static_cast<uint32_t>(val);
+
bool ignored;
- return toUInt32SlowCase(toNumber(exec), ignored);
+ return toUInt32SlowCase(val, ignored);
}
inline int32_t JSValue::toInt32(ExecState* exec, bool& ok) const
@@ -415,7 +427,15 @@ namespace JSC {
ok = true;
return asInt32();
}
- return toInt32SlowCase(toNumber(exec), ok);
+
+ double val = toNumber(exec);
+
+ if (val >= -2147483648.0 && val < 2147483648.0) {
+ ok = true;
+ return static_cast<int32_t>(val);
+ }
+
+ return toInt32SlowCase(val, ok);
}
inline uint32_t JSValue::toUInt32(ExecState* exec, bool& ok) const
@@ -424,7 +444,15 @@ namespace JSC {
ok = true;
return asInt32();
}
- return toUInt32SlowCase(toNumber(exec), ok);
+
+ double val = toNumber(exec);
+
+ if (val >= 0.0 && val < 4294967296.0) {
+ ok = true;
+ return static_cast<uint32_t>(val);
+ }
+
+ return toUInt32SlowCase(val, ok);
}
#if USE(JSVALUE32_64)
diff --git a/JavaScriptCore/runtime/MathObject.cpp b/JavaScriptCore/runtime/MathObject.cpp
index cfbaab2..5648264 100644
--- a/JavaScriptCore/runtime/MathObject.cpp
+++ b/JavaScriptCore/runtime/MathObject.cpp
@@ -211,7 +211,7 @@ EncodedJSValue JSC_HOST_CALL mathProtoFuncPow(ExecState* exec)
EncodedJSValue JSC_HOST_CALL mathProtoFuncRandom(ExecState* exec)
{
- return JSValue::encode(jsDoubleNumber(exec, exec->globalData().weakRandom.get()));
+ return JSValue::encode(jsDoubleNumber(exec, exec->lexicalGlobalObject()->weakRandomNumber()));
}
EncodedJSValue JSC_HOST_CALL mathProtoFuncRound(ExecState* exec)
diff --git a/JavaScriptCore/runtime/NumberPrototype.cpp b/JavaScriptCore/runtime/NumberPrototype.cpp
index 80b7ce0..1a74375 100644
--- a/JavaScriptCore/runtime/NumberPrototype.cpp
+++ b/JavaScriptCore/runtime/NumberPrototype.cpp
@@ -29,8 +29,8 @@
#include "Operations.h"
#include "PrototypeFunction.h"
#include "StringBuilder.h"
-#include "dtoa.h"
#include <wtf/Assertions.h>
+#include <wtf/DecimalNumber.h>
#include <wtf/MathExtras.h>
#include <wtf/Vector.h>
@@ -66,75 +66,140 @@ NumberPrototype::NumberPrototype(ExecState* exec, JSGlobalObject* globalObject,
// ECMA 15.7.4.2 - 15.7.4.7
-static UString integerPartNoExp(double d)
+static ALWAYS_INLINE bool toThisNumber(JSValue thisValue, double &x)
{
- int decimalPoint;
- int sign;
- char result[80];
- WTF::dtoa(result, d, 0, &decimalPoint, &sign, NULL);
- bool resultIsInfOrNan = (decimalPoint == 9999);
- size_t length = strlen(result);
-
- StringBuilder builder;
- builder.append(sign ? "-" : "");
- if (resultIsInfOrNan)
- builder.append((const char*)result);
- else if (decimalPoint <= 0)
- builder.append("0");
- else {
- Vector<char, 1024> buf(decimalPoint + 1);
-
- if (static_cast<int>(length) <= decimalPoint) {
- ASSERT(decimalPoint < 1024);
- memcpy(buf.data(), result, length);
- memset(buf.data() + length, '0', decimalPoint - length);
- } else
- strncpy(buf.data(), result, decimalPoint);
- buf[decimalPoint] = '\0';
-
- builder.append((const char*)(buf.data()));
+ JSValue v = thisValue.getJSNumber();
+ if (UNLIKELY(!v))
+ return false;
+ x = v.uncheckedGetNumber();
+ return true;
+}
+
+static ALWAYS_INLINE bool getIntegerArgumentInRange(ExecState* exec, int low, int high, int& result, bool& isUndefined)
+{
+ result = 0;
+ isUndefined = false;
+
+ JSValue argument0 = exec->argument(0);
+ if (argument0.isUndefined()) {
+ isUndefined = true;
+ return true;
}
- return builder.build();
+ double asDouble = argument0.toInteger(exec);
+ if (asDouble < low || asDouble > high)
+ return false;
+
+ result = static_cast<int>(asDouble);
+ return true;
}
-static UString charSequence(char c, int count)
+// toExponential converts a number to a string, always formatting as an expoential.
+// This method takes an optional argument specifying a number of *decimal places*
+// to round the significand to (or, put another way, this method optionally rounds
+// to argument-plus-one significant figures).
+EncodedJSValue JSC_HOST_CALL numberProtoFuncToExponential(ExecState* exec)
{
- Vector<char, 2048> buf(count + 1, c);
- buf[count] = '\0';
+ // Get x (the double value of this, which should be a Number).
+ double x;
+ if (!toThisNumber(exec->hostThisValue(), x))
+ return throwVMTypeError(exec);
+
+ // Get the argument.
+ int decimalPlacesInExponent;
+ bool isUndefined;
+ if (!getIntegerArgumentInRange(exec, 0, 20, decimalPlacesInExponent, isUndefined))
+ return throwVMError(exec, createRangeError(exec, "toExponential() argument must be between 0 and 20"));
- return UString(buf.data());
+ // Handle NaN and Infinity.
+ if (isnan(x) || isinf(x))
+ return JSValue::encode(jsString(exec, UString::number(x)));
+
+ // Round if the argument is not undefined, always format as exponential.
+ NumberToStringBuffer buffer;
+ unsigned length = isUndefined
+ ? DecimalNumber(x).toStringExponential(buffer)
+ : DecimalNumber(x, RoundingSignificantFigures, decimalPlacesInExponent + 1).toStringExponential(buffer);
+
+ return JSValue::encode(jsString(exec, UString(buffer, length)));
}
-static double intPow10(int e)
+// toFixed converts a number to a string, always formatting as an a decimal fraction.
+// This method takes an argument specifying a number of decimal places to round the
+// significand to. However when converting large values (1e+21 and above) this
+// method will instead fallback to calling ToString.
+EncodedJSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState* exec)
{
- // 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 == 0)
- 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;
- }
- }
+ // Get x (the double value of this, which should be a Number).
+ JSValue thisValue = exec->hostThisValue();
+ JSValue v = thisValue.getJSNumber();
+ if (!v)
+ return throwVMTypeError(exec);
+ double x = v.uncheckedGetNumber();
+
+ // Get the argument.
+ int decimalPlaces;
+ bool isUndefined; // This is ignored; undefined treated as 0.
+ if (!getIntegerArgumentInRange(exec, 0, 20, decimalPlaces, isUndefined))
+ return throwVMError(exec, createRangeError(exec, "toFixed() argument must be between 0 and 20"));
+
+ // 15.7.4.5.7 states "If x >= 10^21, then let m = ToString(x)"
+ // This also covers Ininity, and structure the check so that NaN
+ // values are also handled by numberToString
+ if (!(fabs(x) < 1e+21))
+ return JSValue::encode(jsString(exec, UString::number(x)));
+
+ // The check above will return false for NaN or Infinity, these will be
+ // handled by numberToString.
+ ASSERT(!isnan(x) && !isinf(x));
+
+ // Convert to decimal with rounding, and format as decimal.
+ NumberToStringBuffer buffer;
+ unsigned length = DecimalNumber(x, RoundingDecimalPlaces, decimalPlaces).toStringDecimal(buffer);
+ return JSValue::encode(jsString(exec, UString(buffer, length)));
+}
- if (negative)
- return static_cast<double>(1.0 / result);
- return static_cast<double>(result);
+// toPrecision converts a number to a string, takeing an argument specifying a
+// number of significant figures to round the significand to. For positive
+// exponent, all values that can be represented using a decimal fraction will
+// be, e.g. when rounding to 3 s.f. any value up to 999 will be formated as a
+// decimal, whilst 1000 is converted to the exponential representation 1.00e+3.
+// For negative exponents values >= 1e-6 are formated as decimal fractions,
+// with smaller values converted to exponential representation.
+EncodedJSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec)
+{
+ // Get x (the double value of this, which should be a Number).
+ JSValue thisValue = exec->hostThisValue();
+ JSValue v = thisValue.getJSNumber();
+ if (!v)
+ return throwVMTypeError(exec);
+ double x = v.uncheckedGetNumber();
+
+ // Get the argument.
+ int significantFigures;
+ bool isUndefined;
+ if (!getIntegerArgumentInRange(exec, 1, 21, significantFigures, isUndefined))
+ return throwVMError(exec, createRangeError(exec, "toPrecision() argument must be between 1 and 21"));
+
+ // To precision called with no argument is treated as ToString.
+ if (isUndefined)
+ return JSValue::encode(jsString(exec, UString::number(x)));
+
+ // Handle NaN and Infinity.
+ if (isnan(x) || isinf(x))
+ return JSValue::encode(jsString(exec, UString::number(x)));
+
+ // Convert to decimal with rounding.
+ DecimalNumber number(x, RoundingSignificantFigures, significantFigures);
+ // If number is in the range 1e-6 <= x < pow(10, significantFigures) then format
+ // as decimal. Otherwise, format the number as an exponential. Decimal format
+ // demands a minimum of (exponent + 1) digits to represent a number, for example
+ // 1234 (1.234e+3) requires 4 digits. (See ECMA-262 15.7.4.7.10.c)
+ NumberToStringBuffer buffer;
+ unsigned length = number.exponent() >= -6 && number.exponent() < significantFigures
+ ? number.toStringDecimal(buffer)
+ : number.toStringExponential(buffer);
+ return JSValue::encode(jsString(exec, UString(buffer, length)));
}
EncodedJSValue JSC_HOST_CALL numberProtoFuncToString(ExecState* exec)
@@ -243,237 +308,4 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncValueOf(ExecState* exec)
return JSValue::encode(v);
}
-EncodedJSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState* exec)
-{
- JSValue thisValue = exec->hostThisValue();
- JSValue v = thisValue.getJSNumber();
- if (!v)
- return throwVMTypeError(exec);
-
- JSValue fractionDigits = exec->argument(0);
- double df = fractionDigits.toInteger(exec);
- if (!(df >= 0 && df <= 20))
- return throwVMError(exec, createRangeError(exec, "toFixed() digits argument must be between 0 and 20"));
- int f = static_cast<int>(df);
-
- double x = v.uncheckedGetNumber();
- if (isnan(x))
- return JSValue::encode(jsNontrivialString(exec, "NaN"));
-
- UString s;
- if (x < 0) {
- s = "-";
- x = -x;
- } else {
- s = "";
- if (x == -0.0)
- x = 0;
- }
-
- if (x >= pow(10.0, 21.0))
- return JSValue::encode(jsString(exec, makeString(s, UString::number(x))));
-
- const double tenToTheF = pow(10.0, f);
- double n = floor(x * tenToTheF);
- if (fabs(n / tenToTheF - x) >= fabs((n + 1) / tenToTheF - x))
- n++;
-
- UString m = integerPartNoExp(n);
-
- int k = m.length();
- if (k <= f) {
- StringBuilder z;
- for (int i = 0; i < f + 1 - k; i++)
- z.append('0');
- z.append(m);
- m = z.build();
- k = f + 1;
- ASSERT(k == static_cast<int>(m.length()));
- }
- int kMinusf = k - f;
-
- if (kMinusf < static_cast<int>(m.length()))
- return JSValue::encode(jsString(exec, makeString(s, m.substringSharingImpl(0, kMinusf), ".", m.substringSharingImpl(kMinusf))));
- return JSValue::encode(jsString(exec, makeString(s, m.substringSharingImpl(0, kMinusf))));
-}
-
-static void fractionalPartToString(char* buf, int& i, const char* result, int resultLength, int fractionalDigits)
-{
- if (fractionalDigits <= 0)
- return;
-
- int fDigitsInResult = static_cast<int>(resultLength) - 1;
- buf[i++] = '.';
- if (fDigitsInResult > 0) {
- if (fractionalDigits < fDigitsInResult) {
- strncpy(buf + i, result + 1, fractionalDigits);
- i += fractionalDigits;
- } else {
- ASSERT(i + resultLength - 1 < 80);
- memcpy(buf + i, result + 1, resultLength - 1);
- i += static_cast<int>(resultLength) - 1;
- }
- }
-
- for (int j = 0; j < fractionalDigits - fDigitsInResult; j++)
- buf[i++] = '0';
-}
-
-static void exponentialPartToString(char* buf, int& i, int decimalPoint)
-{
- buf[i++] = 'e';
- // decimalPoint can't be more than 3 digits decimal given the
- // nature of float representation
- int exponential = decimalPoint - 1;
- buf[i++] = (exponential >= 0) ? '+' : '-';
- if (exponential < 0)
- exponential *= -1;
- if (exponential >= 100)
- buf[i++] = static_cast<char>('0' + exponential / 100);
- if (exponential >= 10)
- buf[i++] = static_cast<char>('0' + (exponential % 100) / 10);
- buf[i++] = static_cast<char>('0' + exponential % 10);
-}
-
-EncodedJSValue JSC_HOST_CALL numberProtoFuncToExponential(ExecState* exec)
-{
- JSValue thisValue = exec->hostThisValue();
- JSValue v = thisValue.getJSNumber();
- if (!v)
- return throwVMTypeError(exec);
-
- double x = v.uncheckedGetNumber();
-
- if (isnan(x) || isinf(x))
- return JSValue::encode(jsString(exec, UString::number(x)));
-
- JSValue fractionalDigitsValue = exec->argument(0);
- double df = fractionalDigitsValue.toInteger(exec);
- if (!(df >= 0 && df <= 20))
- return throwVMError(exec, createRangeError(exec, "toExponential() argument must between 0 and 20"));
- int fractionalDigits = static_cast<int>(df);
- bool includeAllDigits = fractionalDigitsValue.isUndefined();
-
- int decimalAdjust = 0;
- if (x && !includeAllDigits) {
- double logx = floor(log10(fabs(x)));
- x /= pow(10.0, logx);
- const double tenToTheF = pow(10.0, fractionalDigits);
- double fx = floor(x * tenToTheF) / tenToTheF;
- double cx = ceil(x * tenToTheF) / tenToTheF;
-
- if (fabs(fx - x) < fabs(cx - x))
- x = fx;
- else
- x = cx;
-
- decimalAdjust = static_cast<int>(logx);
- }
-
- if (isnan(x))
- return JSValue::encode(jsNontrivialString(exec, "NaN"));
-
- if (x == -0.0) // (-0.0).toExponential() should print as 0 instead of -0
- x = 0;
-
- int decimalPoint;
- int sign;
- char result[80];
- WTF::dtoa(result, x, 0, &decimalPoint, &sign, NULL);
- size_t resultLength = strlen(result);
- decimalPoint += decimalAdjust;
-
- int i = 0;
- char buf[80]; // digit + '.' + fractionDigits (max 20) + 'e' + sign + exponent (max?)
- if (sign)
- buf[i++] = '-';
-
- // ? 9999 is the magical "result is Inf or NaN" value. what's 999??
- if (decimalPoint == 999) {
- ASSERT(i + resultLength < 80);
- memcpy(buf + i, result, resultLength);
- buf[i + resultLength] = '\0';
- } else {
- buf[i++] = result[0];
-
- if (includeAllDigits)
- fractionalDigits = static_cast<int>(resultLength) - 1;
-
- fractionalPartToString(buf, i, result, resultLength, fractionalDigits);
- exponentialPartToString(buf, i, decimalPoint);
- buf[i++] = '\0';
- }
- ASSERT(i <= 80);
-
- return JSValue::encode(jsString(exec, buf));
-}
-
-EncodedJSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec)
-{
- JSValue thisValue = exec->hostThisValue();
- JSValue v = thisValue.getJSNumber();
- if (!v)
- return throwVMTypeError(exec);
-
- double doublePrecision = exec->argument(0).toIntegerPreserveNaN(exec);
- double x = v.uncheckedGetNumber();
- if (exec->argument(0).isUndefined() || isnan(x) || isinf(x))
- return JSValue::encode(jsString(exec, v.toString(exec)));
-
- UString s;
- if (x < 0) {
- s = "-";
- x = -x;
- } else
- s = "";
-
- if (!(doublePrecision >= 1 && doublePrecision <= 21)) // true for NaN
- return throwVMError(exec, createRangeError(exec, "toPrecision() argument must be between 1 and 21"));
- int precision = static_cast<int>(doublePrecision);
-
- int e = 0;
- UString m;
- if (x) {
- e = static_cast<int>(log10(x));
- double tens = intPow10(e - precision + 1);
- double n = floor(x / tens);
- if (n < intPow10(precision - 1)) {
- e = e - 1;
- tens = intPow10(e - precision + 1);
- n = floor(x / tens);
- }
-
- if (fabs((n + 1.0) * tens - x) <= fabs(n * tens - x))
- ++n;
- // maintain n < 10^(precision)
- if (n >= intPow10(precision)) {
- n /= 10.0;
- e += 1;
- }
- ASSERT(intPow10(precision - 1) <= n);
- ASSERT(n < intPow10(precision));
-
- m = integerPartNoExp(n);
- if (e < -6 || e >= precision) {
- if (m.length() > 1)
- m = makeString(m.substringSharingImpl(0, 1), ".", m.substringSharingImpl(1));
- if (e >= 0)
- return JSValue::encode(jsMakeNontrivialString(exec, s, m, "e+", UString::number(e)));
- return JSValue::encode(jsMakeNontrivialString(exec, s, m, "e-", UString::number(-e)));
- }
- } else {
- m = charSequence('0', precision);
- e = 0;
- }
-
- if (e == precision - 1)
- return JSValue::encode(jsString(exec, makeString(s, m)));
- if (e >= 0) {
- if (e + 1 < static_cast<int>(m.length()))
- return JSValue::encode(jsString(exec, makeString(s, m.substringSharingImpl(0, e + 1), ".", m.substringSharingImpl(e + 1))));
- return JSValue::encode(jsString(exec, makeString(s, m)));
- }
- return JSValue::encode(jsMakeNontrivialString(exec, s, "0.", charSequence('0', -(e + 1)), m));
-}
-
} // namespace JSC
diff --git a/JavaScriptCore/runtime/RegExp.cpp b/JavaScriptCore/runtime/RegExp.cpp
index 2b844c1..5ad9f3f 100644
--- a/JavaScriptCore/runtime/RegExp.cpp
+++ b/JavaScriptCore/runtime/RegExp.cpp
@@ -51,7 +51,6 @@ inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern, const US
, m_flagBits(0)
, m_constructionError(0)
, m_numSubpatterns(0)
- , m_lastMatchStart(-1)
{
// NOTE: The global flag is handled on a case-by-case basis by functions like
// String::match and RegExpObject::match.
@@ -96,24 +95,8 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
if (ovector)
ovector->resize(0);
- if (static_cast<unsigned>(startOffset) > s.length() || s.isNull()) {
- m_lastMatchString = UString();
- m_lastMatchStart = -1;
- m_lastOVector.shrink(0);
+ if (static_cast<unsigned>(startOffset) > s.length() || s.isNull())
return -1;
- }
-
- // Perform check to see if this match call is the same as the last match invocation
- // and if it is return the prior result.
- if ((startOffset == m_lastMatchStart) && (s.impl() == m_lastMatchString.impl())) {
- if (ovector)
- *ovector = m_lastOVector;
-
- if (m_lastOVector.isEmpty())
- return -1;
-
- return m_lastOVector.at(0);
- }
#if ENABLE(YARR_JIT)
if (!!m_regExpJITCode) {
@@ -151,21 +134,9 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
ovector->clear();
}
- m_lastMatchString = s;
- m_lastMatchStart = startOffset;
-
- if (ovector)
- m_lastOVector = *ovector;
- else
- m_lastOVector = nonReturnedOvector;
-
return result;
}
- m_lastMatchString = UString();
- m_lastMatchStart = -1;
- m_lastOVector.shrink(0);
-
return -1;
}
diff --git a/JavaScriptCore/runtime/RegExp.h b/JavaScriptCore/runtime/RegExp.h
index 8ea44e3..aadad6b 100644
--- a/JavaScriptCore/runtime/RegExp.h
+++ b/JavaScriptCore/runtime/RegExp.h
@@ -65,9 +65,6 @@ namespace JSC {
int m_flagBits;
const char* m_constructionError;
unsigned m_numSubpatterns;
- UString m_lastMatchString;
- int m_lastMatchStart;
- Vector<int, 32> m_lastOVector;
#if ENABLE(YARR_JIT)
Yarr::RegexCodeBlock m_regExpJITCode;
diff --git a/JavaScriptCore/runtime/StringBuilder.h b/JavaScriptCore/runtime/StringBuilder.h
index a26b94c..27aa57f 100644
--- a/JavaScriptCore/runtime/StringBuilder.h
+++ b/JavaScriptCore/runtime/StringBuilder.h
@@ -44,7 +44,7 @@ public:
void append(const char* str, size_t len)
{
- buffer.reserveCapacity(buffer.size() + len);
+ reserveCapacity(buffer.size() + len);
for (size_t i = 0; i < len; i++)
buffer.append(static_cast<unsigned char>(str[i]));
}
@@ -60,7 +60,12 @@ public:
}
bool isEmpty() { return buffer.isEmpty(); }
- void reserveCapacity(size_t newCapacity) { buffer.reserveCapacity(newCapacity); }
+ void reserveCapacity(size_t newCapacity)
+ {
+ if (newCapacity < buffer.capacity())
+ return;
+ buffer.reserveCapacity(std::max(newCapacity, buffer.capacity() + buffer.capacity() / 4 + 1));
+ }
void resize(size_t size) { buffer.resize(size); }
size_t size() const { return buffer.size(); }
diff --git a/JavaScriptCore/runtime/StringPrototype.cpp b/JavaScriptCore/runtime/StringPrototype.cpp
index cfbb3be..91e9b06 100644
--- a/JavaScriptCore/runtime/StringPrototype.cpp
+++ b/JavaScriptCore/runtime/StringPrototype.cpp
@@ -425,9 +425,10 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec)
// Not a regular expression, so treat the pattern as a string.
UString patternString = pattern.toString(exec);
- if (patternString.length() == 1 && callType == CallTypeNone)
+ // Special case for single character patterns without back reference replacement
+ if (patternString.length() == 1 && callType == CallTypeNone && replacementString.find('$', 0) == notFound)
return JSValue::encode(sourceVal->replaceCharacter(exec, patternString[0], replacementString));
-
+
const UString& source = sourceVal->value(exec);
size_t matchPos = source.find(patternString);
diff --git a/JavaScriptCore/runtime/UString.cpp b/JavaScriptCore/runtime/UString.cpp
index ac3acfd..7362950 100644
--- a/JavaScriptCore/runtime/UString.cpp
+++ b/JavaScriptCore/runtime/UString.cpp
@@ -26,7 +26,6 @@
#include "JSGlobalObjectFunctions.h"
#include "Collector.h"
-#include "dtoa.h"
#include "Identifier.h"
#include "Operations.h"
#include <ctype.h>
@@ -39,6 +38,7 @@
#include <wtf/MathExtras.h>
#include <wtf/StringExtras.h>
#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
#include <wtf/unicode/UTF8.h>
#if HAVE(STRINGS_H)
@@ -198,10 +198,8 @@ UString UString::number(long l)
UString UString::number(double d)
{
- DtoaBuffer buffer;
- unsigned length;
- doubleToStringInJavaScriptFormat(d, buffer, &length);
- return UString(buffer, length);
+ NumberToStringBuffer buffer;
+ return StringImpl::create(buffer, numberToString(d, buffer));
}
UString UString::substringSharingImpl(unsigned offset, unsigned length) const
@@ -334,6 +332,8 @@ CString UString::utf8(bool strict) const
// * We could allocate a CStringBuffer with an appropriate size to
// have a good chance of being able to write the string into the
// buffer without reallocing (say, 1.5 x length).
+ if (length > numeric_limits<unsigned>::max() / 3)
+ return CString();
Vector<char, 1024> bufferVector(length * 3);
char* buffer = bufferVector.data();
diff --git a/JavaScriptCore/wscript b/JavaScriptCore/wscript
index e50b18d..d85364c 100644
--- a/JavaScriptCore/wscript
+++ b/JavaScriptCore/wscript
@@ -36,12 +36,13 @@ sources = []
jscore_excludes.extend(get_excludes(jscore_dir, ['*None.cpp']))
-if building_on_win32:
- jscore_excludes += ['MarkStackPosix.cpp', 'ThreadingPthreads.cpp']
- sources += ['runtime/MarkStackWin.cpp']
-else:
- jscore_excludes.append('JSStringRefBSTR.cpp')
- jscore_excludes.extend(get_excludes(jscore_dir, ['*Win.cpp']))
+if build_port == "wx":
+ if building_on_win32:
+ jscore_excludes += ['MarkStackPosix.cpp', 'ThreadingPthreads.cpp']
+ sources += ['runtime/MarkStackWin.cpp']
+ else:
+ jscore_excludes.append('JSStringRefBSTR.cpp')
+ jscore_excludes.extend(get_excludes(jscore_dir, ['*Win.cpp']))
def build(bld):
import Options
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