summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2010-02-15 12:23:52 +0000
committerSteve Block <steveblock@google.com>2010-02-16 11:48:32 +0000
commit8a0914b749bbe7da7768e07a7db5c6d4bb09472b (patch)
tree73f9065f370435d6fde32ae129d458a8c77c8dff /JavaScriptCore
parentbf14be70295513b8076f3fa47a268a7e42b2c478 (diff)
downloadexternal_webkit-8a0914b749bbe7da7768e07a7db5c6d4bb09472b.zip
external_webkit-8a0914b749bbe7da7768e07a7db5c6d4bb09472b.tar.gz
external_webkit-8a0914b749bbe7da7768e07a7db5c6d4bb09472b.tar.bz2
Merge webkit.org at r54731 : Initial merge by git
Change-Id: Ia79977b6cf3b0b00c06ef39419989b28e57e4f4a
Diffstat (limited to 'JavaScriptCore')
-rw-r--r--JavaScriptCore/API/JSClassRef.cpp41
-rw-r--r--JavaScriptCore/API/JSStringRef.h3
-rw-r--r--JavaScriptCore/ChangeLog806
-rw-r--r--JavaScriptCore/Configurations/FeatureDefines.xcconfig3
-rw-r--r--JavaScriptCore/Configurations/Version.xcconfig4
-rw-r--r--JavaScriptCore/GNUmakefile.am2
-rw-r--r--JavaScriptCore/JavaScriptCore.exp8
-rw-r--r--JavaScriptCore/JavaScriptCore.gypi1
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def2
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj4
-rw-r--r--JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj18
-rw-r--r--JavaScriptCore/debugger/Debugger.cpp2
-rw-r--r--JavaScriptCore/debugger/DebuggerCallFrame.cpp4
-rw-r--r--JavaScriptCore/jit/JIT.h9
-rw-r--r--JavaScriptCore/jit/JITArithmetic.cpp56
-rw-r--r--JavaScriptCore/jit/JITOpcodes.cpp109
-rw-r--r--JavaScriptCore/jit/JITStubs.cpp2
-rw-r--r--JavaScriptCore/jit/JITStubs.h22
-rw-r--r--JavaScriptCore/parser/Grammar.y8
-rw-r--r--JavaScriptCore/parser/NodeConstructors.h6
-rw-r--r--JavaScriptCore/parser/Parser.cpp2
-rw-r--r--JavaScriptCore/profiler/Profile.cpp2
-rw-r--r--JavaScriptCore/profiler/ProfileGenerator.cpp2
-rw-r--r--JavaScriptCore/qt/api/qscriptengine.cpp20
-rw-r--r--JavaScriptCore/qt/api/qscriptengine.h2
-rw-r--r--JavaScriptCore/qt/api/qscriptvalue_p.h28
-rw-r--r--JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp19
-rw-r--r--JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h28
-rw-r--r--JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated.cpp447
-rw-r--r--JavaScriptCore/runtime/ArrayPrototype.cpp81
-rw-r--r--JavaScriptCore/runtime/Collector.cpp26
-rw-r--r--JavaScriptCore/runtime/Collector.h1
-rw-r--r--JavaScriptCore/runtime/CollectorHeapIterator.h22
-rw-r--r--JavaScriptCore/runtime/CommonIdentifiers.cpp3
-rw-r--r--JavaScriptCore/runtime/CommonIdentifiers.h1
-rw-r--r--JavaScriptCore/runtime/DateConstructor.cpp3
-rw-r--r--JavaScriptCore/runtime/DatePrototype.cpp7
-rw-r--r--JavaScriptCore/runtime/Error.cpp8
-rw-r--r--JavaScriptCore/runtime/ErrorPrototype.cpp5
-rw-r--r--JavaScriptCore/runtime/ExceptionHelpers.cpp7
-rw-r--r--JavaScriptCore/runtime/ExceptionHelpers.h1
-rw-r--r--JavaScriptCore/runtime/Executable.cpp2
-rw-r--r--JavaScriptCore/runtime/FunctionConstructor.cpp2
-rw-r--r--JavaScriptCore/runtime/FunctionPrototype.cpp7
-rw-r--r--JavaScriptCore/runtime/Identifier.cpp6
-rw-r--r--JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp26
-rw-r--r--JavaScriptCore/runtime/JSONObject.cpp2
-rw-r--r--JavaScriptCore/runtime/JSPropertyNameIterator.cpp18
-rw-r--r--JavaScriptCore/runtime/JSPropertyNameIterator.h34
-rw-r--r--JavaScriptCore/runtime/JSString.h5
-rw-r--r--JavaScriptCore/runtime/JSStringBuilder.h105
-rw-r--r--JavaScriptCore/runtime/JSValue.cpp4
-rw-r--r--JavaScriptCore/runtime/LiteralParser.cpp2
-rw-r--r--JavaScriptCore/runtime/NumberPrototype.cpp11
-rw-r--r--JavaScriptCore/runtime/ObjectPrototype.cpp3
-rw-r--r--JavaScriptCore/runtime/Operations.cpp7
-rw-r--r--JavaScriptCore/runtime/Operations.h2
-rw-r--r--JavaScriptCore/runtime/PropertyNameArray.cpp2
-rw-r--r--JavaScriptCore/runtime/RegExpPrototype.cpp3
-rw-r--r--JavaScriptCore/runtime/SmallStrings.cpp37
-rw-r--r--JavaScriptCore/runtime/SmallStrings.h1
-rw-r--r--JavaScriptCore/runtime/StringBuilder.h8
-rw-r--r--JavaScriptCore/runtime/StringPrototype.cpp118
-rw-r--r--JavaScriptCore/runtime/Structure.h8
-rw-r--r--JavaScriptCore/runtime/UString.cpp178
-rw-r--r--JavaScriptCore/runtime/UString.h129
-rw-r--r--JavaScriptCore/runtime/UStringImpl.cpp39
-rw-r--r--JavaScriptCore/runtime/UStringImpl.h18
-rw-r--r--JavaScriptCore/runtime/WeakGCPtr.h6
-rw-r--r--JavaScriptCore/wscript2
-rw-r--r--JavaScriptCore/wtf/Complex.h46
-rw-r--r--JavaScriptCore/wtf/FastMalloc.cpp20
-rw-r--r--JavaScriptCore/wtf/HashTable.h3
-rw-r--r--JavaScriptCore/wtf/HashTraits.h21
-rw-r--r--JavaScriptCore/wtf/MathExtras.h11
-rw-r--r--JavaScriptCore/wtf/PassRefPtr.h45
-rw-r--r--JavaScriptCore/wtf/Platform.h16
-rw-r--r--JavaScriptCore/wtf/RefPtr.h47
-rw-r--r--JavaScriptCore/wtf/ValueCheck.h64
-rw-r--r--JavaScriptCore/wtf/Vector.h21
-rw-r--r--JavaScriptCore/wtf/Vector3.h138
-rw-r--r--JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h2
82 files changed, 2501 insertions, 543 deletions
diff --git a/JavaScriptCore/API/JSClassRef.cpp b/JavaScriptCore/API/JSClassRef.cpp
index c6685bf..747aa16 100644
--- a/JavaScriptCore/API/JSClassRef.cpp
+++ b/JavaScriptCore/API/JSClassRef.cpp
@@ -33,12 +33,28 @@
#include <runtime/JSGlobalObject.h>
#include <runtime/ObjectPrototype.h>
#include <runtime/Identifier.h>
+#include <wtf/unicode/UTF8.h>
using namespace std;
using namespace JSC;
+using namespace WTF::Unicode;
const JSClassDefinition kJSClassDefinitionEmpty = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+static inline UString tryCreateStringFromUTF8(const char* string)
+{
+ if (!string)
+ return UString::null();
+
+ size_t length = strlen(string);
+ Vector<UChar, 1024> buffer(length);
+ UChar* p = buffer.data();
+ if (conversionOK != convertUTF8ToUTF16(&string, string + length, &p, p + length))
+ return UString::null();
+
+ return UString(buffer.data(), p - buffer.data());
+}
+
OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass* protoClass)
: parentClass(definition->parentClass)
, prototypeClass(0)
@@ -53,7 +69,7 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass*
, callAsConstructor(definition->callAsConstructor)
, hasInstance(definition->hasInstance)
, convertToType(definition->convertToType)
- , m_className(UString::createFromUTF8(definition->className).rep()->ref())
+ , m_className(tryCreateStringFromUTF8(definition->className))
, m_staticValues(0)
, m_staticFunctions(0)
{
@@ -62,9 +78,12 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass*
if (const JSStaticValue* staticValue = definition->staticValues) {
m_staticValues = new OpaqueJSClassStaticValuesTable();
while (staticValue->name) {
- // Use a local variable here to sidestep an RVCT compiler bug.
- StaticValueEntry* entry = new StaticValueEntry(staticValue->getProperty, staticValue->setProperty, staticValue->attributes);
- m_staticValues->add(UString::createFromUTF8(staticValue->name).rep()->ref(), entry);
+ UString valueName = tryCreateStringFromUTF8(staticValue->name);
+ if (!valueName.isNull()) {
+ // Use a local variable here to sidestep an RVCT compiler bug.
+ StaticValueEntry* entry = new StaticValueEntry(staticValue->getProperty, staticValue->setProperty, staticValue->attributes);
+ m_staticValues->add(valueName.rep()->ref(), entry);
+ }
++staticValue;
}
}
@@ -72,9 +91,12 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass*
if (const JSStaticFunction* staticFunction = definition->staticFunctions) {
m_staticFunctions = new OpaqueJSClassStaticFunctionsTable();
while (staticFunction->name) {
- // Use a local variable here to sidestep an RVCT compiler bug.
- StaticFunctionEntry* entry = new StaticFunctionEntry(staticFunction->callAsFunction, staticFunction->attributes);
- m_staticFunctions->add(UString::createFromUTF8(staticFunction->name).rep()->ref(), entry);
+ UString functionName = tryCreateStringFromUTF8(staticFunction->name);
+ if (!functionName.isNull()) {
+ // Use a local variable here to sidestep an RVCT compiler bug.
+ StaticFunctionEntry* entry = new StaticFunctionEntry(staticFunction->callAsFunction, staticFunction->attributes);
+ m_staticFunctions->add(functionName.rep()->ref(), entry);
+ }
++staticFunction;
}
}
@@ -118,7 +140,7 @@ static void clearReferenceToPrototype(JSObjectRef prototype)
{
OpaqueJSClassContextData* jsClassData = static_cast<OpaqueJSClassContextData*>(JSObjectGetPrivate(prototype));
ASSERT(jsClassData);
- jsClassData->cachedPrototype = 0;
+ jsClassData->cachedPrototype.clear(toJS(prototype));
}
PassRefPtr<OpaqueJSClass> OpaqueJSClass::create(const JSClassDefinition* clientDefinition)
@@ -146,12 +168,9 @@ OpaqueJSClassContextData::OpaqueJSClassContextData(OpaqueJSClass* jsClass)
// Use a local variable here to sidestep an RVCT compiler bug.
StaticValueEntry* entry = new StaticValueEntry(it->second->getProperty, it->second->setProperty, it->second->attributes);
staticValues->add(UString::Rep::create(it->first->data(), it->first->size()), entry);
-
}
-
} else
staticValues = 0;
-
if (jsClass->m_staticFunctions) {
staticFunctions = new OpaqueJSClassStaticFunctionsTable;
diff --git a/JavaScriptCore/API/JSStringRef.h b/JavaScriptCore/API/JSStringRef.h
index c58b958..92135b1 100644
--- a/JavaScriptCore/API/JSStringRef.h
+++ b/JavaScriptCore/API/JSStringRef.h
@@ -37,7 +37,8 @@
extern "C" {
#endif
-#if !defined(WIN32) && !defined(_WIN32) && !defined(__WINSCW__)
+#if !defined(WIN32) && !defined(_WIN32) && !defined(__WINSCW__) \
+ && !(defined(__CC_ARM) || defined(__ARMCC__)) /* RVCT */
/*!
@typedef JSChar
@abstract A Unicode character.
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 578e282..4257344 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,809 @@
+2010-02-12 Janne Koskinen <janne.p.koskinen@digia.com>
+
+ Reviewed by Tor Arne Vestbø.
+
+ Additional refptr/passrefptr workarounds for WINSCW compiler
+ https://bugs.webkit.org/show_bug.cgi?id=28054
+
+ * wtf/PassRefPtr.h:
+ (WTF::refIfNotNull):
+ (WTF::PassRefPtr::PassRefPtr):
+ (WTF::PassRefPtr::~PassRefPtr):
+ (WTF::PassRefPtr::clear):
+ (WTF::::operator):
+ * wtf/RefPtr.h:
+ (WTF::RefPtr::RefPtr):
+ (WTF::::operator):
+
+2010-02-12 Janne Koskinen <janne.p.koskinen@digia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Don't import the cmath functions from std:: for WINSCW.
+
+ * wtf/MathExtras.h:
+
+2010-02-12 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Adam Barth.
+
+ Typedef both JSChar and UChar to wchar_t in RVCT.
+ https://bugs.webkit.org/show_bug.cgi?id=34560
+
+ Define both JSChar and UChar to wchar_t as the size
+ of wchar_t is 2 bytes in RVCT.
+
+ * API/JSStringRef.h:
+ * wtf/unicode/qt4/UnicodeQt4.h:
+
+2010-02-11 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt and Darin Adler.
+
+ The rest of the fix for
+ https://bugs.webkit.org/show_bug.cgi?id=34864 | <rdar://problem/7594198>
+ Many objects left uncollected after visiting mail.google.com and closing
+ window
+
+ Don't unconditionally hang onto small strings. Instead, hang onto all
+ small strings as long as any small string is still referenced.
+
+ SunSpider reports no change.
+
+ * runtime/Collector.cpp:
+ (JSC::Heap::markRoots): Mark the small strings cache last, so it can
+ check if anything else has kept any strings alive.
+
+ * runtime/SmallStrings.cpp:
+ (JSC::isMarked):
+ (JSC::SmallStrings::markChildren): Only keep our strings alive if some
+ other reference to at least one of them exists, too.
+
+2010-02-11 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Some progress toward fixing
+ https://bugs.webkit.org/show_bug.cgi?id=34864 | <rdar://problem/7594198>
+ Many objects left uncollected after visiting mail.google.com and closing
+ window
+
+ SunSpider reports no change.
+
+ Keep weak references, rather than protected references, to cached for-in
+ property name enumerators.
+
+ One problem with protected references is that a chain like
+ [ gc object 1 ] => [ non-gc object ] => [ gc object 2 ]
+ takes two GC passes to break, since the first pass collects [ gc object 1 ],
+ releasing [ non-gc object ] and unprotecting [ gc object 2 ], and only
+ then can a second pass collect [ gc object 2 ].
+
+ Another problem with protected references is that they can keep a bunch
+ of strings alive long after they're useful. In SunSpider and a few popular
+ websites, the size-speed tradeoff seems to favor weak references.
+
+ * runtime/JSPropertyNameIterator.cpp:
+ (JSC::JSPropertyNameIterator::JSPropertyNameIterator): Moved this constructor
+ into the .cpp file, since it's not used elsewhere.
+
+ (JSC::JSPropertyNameIterator::~JSPropertyNameIterator): Added a destructor
+ to support our weak reference.
+
+ * runtime/JSPropertyNameIterator.h:
+ (JSC::Structure::setEnumerationCache):
+ (JSC::Structure::clearEnumerationCache):
+ (JSC::Structure::enumerationCache): Added a function for clearing a
+ Structure's enumeration cache, used by our new destructor. Also fixed
+ indentation to match the rest of the file.
+
+ * runtime/Structure.h: Changed from protected pointer to weak pointer.
+
+2010-02-11 Chris Rogers <crogers@google.com>
+
+ Reviewed by David Levin.
+
+ audio engine: add Complex number class
+ https://bugs.webkit.org/show_bug.cgi?id=34538
+
+ * wtf/Complex.h: Added.
+ (WebCore::complexFromMagnitudePhase):
+
+2010-02-10 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Added an SPI for asking about all the different live objects on the heap.
+ Useful for memory debugging.
+
+ * JavaScriptCore.exp: Export the new SPI.
+
+ * runtime/Collector.cpp:
+ (JSC::typeName): Use a little capitalization. Don't crash in the case of
+ a non-object cell, since it might just be an uninitialized cell.
+
+ (JSC::Heap::objectTypeCounts): The new SPI.
+
+ * runtime/Collector.h:
+ * runtime/CollectorHeapIterator.h:
+ (JSC::CollectorHeapIterator::advance):
+ (JSC::LiveObjectIterator::operator++):
+ (JSC::DeadObjectIterator::operator++):
+ (JSC::ObjectIterator::operator++): Made 2 tweaks to these iterators:
+ (1) Skip the last cell in the block, since it's a dummy sentinel, and
+ we don't want it to confuse the object count; (2) Fixed a logic error
+ in LiveObjectIterator that could cause it to iterate dead objects if
+ m_block were equal to m_heap.nextBlock and m_cell were less than
+ m_heap.nextCell. No test for this since I can't think of a way that this
+ could make WebKit behave badly.
+
+2010-02-11 Steve Block <steveblock@google.com>
+
+ Reviewed by Darin Adler.
+
+ Guard cmath using declarations in MathExtras.h on Android
+ https://bugs.webkit.org/show_bug.cgi?id=34840
+
+ Android does not provide these functions.
+
+ * wtf/MathExtras.h:
+
+2010-02-08 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Cameron Zwarich.
+
+ Restore ENABLE_RUBY flag so vendors can ship with Ruby disabled if they choose.
+ https://bugs.webkit.org/show_bug.cgi?id=34698
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2010-02-10 Kevin Watters <kevinwatters@gmail.com>
+
+ Reviewed by Kevin Ollivier.
+
+ [wx] Add Windows complex text support and Mac support for containsCharacters.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34759
+
+ * wscript:
+
+2010-02-10 Alexey Proskuryakov <ap@apple.com>
+
+ Addressing issues found by style bot.
+
+ * wtf/ValueCheck.h: Renamed header guard to match final file name.
+
+ * wtf/Vector.h: (WTF::::checkConsistency): Remove braces around a one-line clause.
+
+2010-02-09 Alexey Proskuryakov <ap@apple.com>
+
+ Reviewed by Geoffrey Garen.
+
+ https://bugs.webkit.org/show_bug.cgi?id=34490
+ WebCore::ImageEventSender::dispatchPendingEvents() crashes in certain conditions
+
+ * GNUmakefile.am:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ Added ValueCheck.h.
+
+ * wtf/ValueCheck.h: Added. Moved code out of HashTraits, since it would be awkward to
+ include that from Vector.h.
+ (WTF::ValueCheck::checkConsistency): Allow null pointers, those are pretty consistent.
+
+ * wtf/HashTraits.h: Moved value checking code out of here.
+
+ * wtf/HashTable.h: (WTF::::checkTableConsistencyExceptSize): Updated for the above changes.
+
+ * wtf/Vector.h:
+ (WTF::::checkConsistency): Check all vector elements.
+ (WTF::ValueCheck): Support checking a Vector as an element in other containers. Currently
+ unused.
+
+2010-02-10 Jedrzej Nowacki <jedrzej.nowacki@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Fix QScriptValue::toBool.
+
+ Fix ECMA compliance in the QScriptValue for values like 0, NaN and
+ empty strings.
+
+ [Qt] QScriptValue::toBool problem
+ https://bugs.webkit.org/show_bug.cgi?id=34793
+
+ * qt/api/qscriptvalue_p.h:
+ (QScriptValuePrivate::toBool):
+ * qt/tests/qscriptvalue/tst_qscriptvalue.h:
+ * qt/tests/qscriptvalue/tst_qscriptvalue_generated.cpp:
+ (tst_QScriptValue::toBool_initData):
+ (tst_QScriptValue::toBool_makeData):
+ (tst_QScriptValue::toBool_test):
+ (tst_QScriptValue::toBoolean_initData):
+ (tst_QScriptValue::toBoolean_makeData):
+ (tst_QScriptValue::toBoolean_test):
+
+2009-10-06 Yongjun Zhang <yongjun.zhang@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Use derefIfNotNull() to work around WINSCW compiler forward declaration bug
+
+ The compiler bug is reported at
+ https://xdabug001.ext.nokia.com/bugzilla/show_bug.cgi?id=9812.
+
+ The change should be reverted when the above bug is fixed in WINSCW compiler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=28054
+
+2009-10-06 Yongjun Zhang <yongjun.zhang@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Get rid of WINSCW hack for UnSpecifiedBoolType
+
+ Add parenthesis around (RefPtr::*UnspecifiedBoolType) to make the WINSCW
+ compiler work with the default UnSpecifiedBoolType() operator.
+
+ https://bugs.webkit.org/show_bug.cgi?id=28054
+
+ * wtf/RefPtr.h:
+
+2010-02-09 Jedrzej Nowacki <jedrzej.nowacki@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ New functions nullValue() and undefinedValue().
+
+ [Qt] QScriptEngine should contain nullValue and undefinedValue methods
+ https://bugs.webkit.org/show_bug.cgi?id=34749
+
+ * qt/api/qscriptengine.cpp:
+ (QScriptEngine::nullValue):
+ (QScriptEngine::undefinedValue):
+ * qt/api/qscriptengine.h:
+ * qt/tests/qscriptengine/tst_qscriptengine.cpp:
+ (tst_QScriptEngine::nullValue):
+ (tst_QScriptEngine::undefinedValue):
+
+2010-02-09 Jedrzej Nowacki <jedrzej.nowacki@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Fixes for QScriptValue::toNumber().
+
+ Fix ECMA compliance in QScriptValue for values unbound
+ to a QScriptEngine.
+
+ [Qt] QScriptValue::toNumber() is broken
+ https://bugs.webkit.org/show_bug.cgi?id=34592
+
+ * qt/api/qscriptvalue_p.h:
+ (QScriptValuePrivate::toNumber):
+ * qt/tests/qscriptvalue/tst_qscriptvalue.h:
+ * qt/tests/qscriptvalue/tst_qscriptvalue_generated.cpp:
+ (tst_QScriptValue::toNumber_initData):
+ (tst_QScriptValue::toNumber_makeData):
+ (tst_QScriptValue::toNumber_test):
+
+2010-02-09 Jedrzej Nowacki <jedrzej.nowacki@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Fix QScriptValue::isNumber().
+
+ The isNumber() should return 'true' if the value is in the CNumber
+ state.
+
+ [Qt] QScriptValue::isNumber() returns an incorrect value
+ https://bugs.webkit.org/show_bug.cgi?id=34575
+
+ * qt/api/qscriptvalue_p.h:
+ (QScriptValuePrivate::isNumber):
+ * qt/tests/qscriptvalue/tst_qscriptvalue.h:
+ * qt/tests/qscriptvalue/tst_qscriptvalue_generated.cpp:
+ (tst_QScriptValue::isNumber_initData):
+ (tst_QScriptValue::isNumber_makeData):
+ (tst_QScriptValue::isNumber_test):
+
+2010-02-09 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Small refactoring to the small strings cache to allow it to be cleared
+ dynamically.
+
+ * runtime/SmallStrings.cpp:
+ (JSC::SmallStrings::SmallStrings):
+ (JSC::SmallStrings::clear):
+ * runtime/SmallStrings.h: Moved initialization code into a shared function,
+ and changed the constructor to call it.
+
+2010-02-09 Gavin Barraclough <barraclough@apple.com>
+
+ Rubber Stamped by Geoff Garen.
+
+ Rename StringBuilder::release && JSStringBuilder::releaseJSString
+ to 'build()'.
+
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncToLocaleString):
+ (JSC::arrayProtoFuncJoin):
+ * runtime/Executable.cpp:
+ (JSC::FunctionExecutable::paramString):
+ * runtime/FunctionConstructor.cpp:
+ (JSC::constructFunction):
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::encode):
+ (JSC::decode):
+ (JSC::globalFuncEscape):
+ (JSC::globalFuncUnescape):
+ * runtime/JSONObject.cpp:
+ (JSC::Stringifier::stringify):
+ * runtime/JSStringBuilder.h:
+ (JSC::JSStringBuilder::build):
+ * runtime/LiteralParser.cpp:
+ (JSC::LiteralParser::Lexer::lexString):
+ * runtime/NumberPrototype.cpp:
+ (JSC::integerPartNoExp):
+ (JSC::numberProtoFuncToFixed):
+ * runtime/StringBuilder.h:
+ (JSC::StringBuilder::build):
+
+2010-02-09 John Sullivan <sullivan@apple.com>
+
+ https://bugs.webkit.org/show_bug.cgi?id=34772
+ Overzealous new assertion in URStringImpl::adopt()
+
+ Reviewed by Adam Barth.
+
+ * runtime/UStringImpl.h:
+ (JSC::UStringImpl::adopt):
+ Only assert that vector.data() is non-zero if vector.size() is non-zero.
+
+2010-02-09 Nikolas Zimmermann <nzimmermann@rim.com>
+
+ Not reviewed. Try to fix build problem on SnowLeopard slaves to bring them back.
+
+ * API/JSClassRef.cpp:
+ (tryCreateStringFromUTF8): Mark method as 'static inline' to suppress "warning: no previous prototype for ..."
+
+2010-02-09 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Three small string fixes:
+ (1) StringBuilder::release should CRASH if the buffer allocation failed.
+ (2) Remove weird, dead code from JSString::tryGetValue, replace with an ASSERT.
+ (3) Move UString::createFromUTF8 out to the API, as tryCreateStringFromUTF8.
+ This is only used from the API, and (now) unlike other UString::create
+ methods may return UString::null() to indicate failure cases. Better
+ handle these in the API.
+
+ * API/JSClassRef.cpp:
+ (tryCreateStringFromUTF8):
+ (OpaqueJSClass::OpaqueJSClass):
+ (OpaqueJSClassContextData::OpaqueJSClassContextData):
+ * runtime/JSString.h:
+ (JSC::Fiber::tryGetValue):
+ * runtime/StringBuilder.h:
+ (JSC::StringBuilder::release):
+ * runtime/UString.cpp:
+ (JSC::UString::UString):
+ (JSC::UString::from):
+ (JSC::UString::find):
+ * runtime/UString.h:
+
+2010-02-09 Janne Koskinen <janne.p.koskinen@digia.com>
+
+ Reviewed by Laszlo Gombos.
+
+ [Qt] use nanval() for Symbian as nonInlineNaN
+ https://bugs.webkit.org/show_bug.cgi?id=34170
+
+ numeric_limits<double>::quiet_NaN is broken in Symbian
+ causing NaN to be evaluated as a number.
+
+ * runtime/JSValue.cpp:
+ (JSC::nonInlineNaN):
+
+2010-02-09 Tamas Szirbucz <szirbucz@inf.u-szeged.hu>
+
+ Reviewed by Gavin Barraclough.
+
+ Add a soft modulo operation to ARM JIT using a trampoline function.
+ The performance progression is about ~1.8% on ARMv7
+ https://bugs.webkit.org/show_bug.cgi?id=34424
+
+ Developed in cooperation with Gabor Loki.
+
+ * jit/JIT.h:
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::emit_op_mod):
+ (JSC::JIT::emitSlow_op_mod):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::softModulo):
+ * jit/JITStubs.h:
+ (JSC::JITThunks::ctiSoftModulo):
+ * wtf/Platform.h:
+
+2010-02-08 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (SL/win build fixes).
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * runtime/StringPrototype.cpp:
+
+2010-02-08 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt
+
+ Make String.replace throw an exception on out-of-memory, rather than
+ returning a null (err, empty-ish) string. Move String::replaceRange
+ and String::spliceSubstringsWithSeparators out to StringPrototype -
+ these were fairly specific use anyway, and we can better integrate
+ throwing the JS expcetion this way.
+
+ Also removes redundant assignment operator from UString.
+
+ * JavaScriptCore.exp:
+ * runtime/StringPrototype.cpp:
+ (JSC::StringRange::StringRange):
+ (JSC::jsSpliceSubstringsWithSeparators):
+ (JSC::jsReplaceRange):
+ (JSC::stringProtoFuncReplace):
+ * runtime/UString.cpp:
+ * runtime/UString.h:
+
+2010-02-08 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Eric Seidel.
+
+ [BREWMP] Undefine WTF_OS_WINDOWS and WTF_PLATFORM_WIN
+ https://bugs.webkit.org/show_bug.cgi?id=34561
+
+ As the binary for simulator is built with MSVC 2005,
+ WTF_OS_WINDOWS and WTF_PLATFORM_WIN are defined.
+ Undefine them as we don't target Windows.
+
+ * wtf/Platform.h:
+
+2010-02-08 Chris Rogers <crogers@google.com>
+
+ Reviewed by Darin Adler.
+
+ audio engine: add Vector3 class
+ https://bugs.webkit.org/show_bug.cgi?id=34548
+
+ * wtf/Vector3.h: Added.
+ (WebCore::Vector3::Vector3):
+ (WebCore::Vector3::abs):
+ (WebCore::Vector3::isZero):
+ (WebCore::Vector3::normalize):
+ (WebCore::Vector3::x):
+ (WebCore::Vector3::y):
+ (WebCore::Vector3::z):
+ (WebCore::operator+):
+ (WebCore::operator-):
+ (WebCore::operator*):
+ (WebCore::dot):
+ (WebCore::cross):
+ (WebCore::distance):
+
+2010-02-08 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Fix warning in clang++
+
+ * runtime/Structure.h:
+ (JSC::Structure::propertyStorageSize):
+
+2010-02-08 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Make makeString CRASH if we fail to allocate a string.
+
+ (tryMakeString or jsMakeNontrivialString can be used where we
+ expect allocation may fail and want to handle the error).
+
+ * runtime/JSStringBuilder.h:
+ (JSC::jsMakeNontrivialString):
+ * runtime/UString.h:
+ (JSC::tryMakeString):
+ (JSC::makeString):
+
+2010-02-08 Gavin Barraclough <barraclough@apple.com>
+
+ Rubber Stamped by Oliver Hunt.
+
+ Remove a couple of unnecesary C-style casts spotted by Darin.
+
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::encode):
+ (JSC::globalFuncEscape):
+
+2010-02-08 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Switch some more StringBuilder/jsNontrivialString code to use
+ JSStringBuilder/jsMakeNontrivialString - these methods will
+ throw an exception if we hit out-of-memory, rather than just
+ CRASHing.
+
+ * runtime/FunctionPrototype.cpp:
+ (JSC::functionProtoFuncToString):
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::encode):
+ (JSC::decode):
+ (JSC::globalFuncEscape):
+
+2010-02-08 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Use an empty identifier instead of a null identifier for parse
+ tokens without an identifier.
+
+ This helps encapsulate the null UStringImpl within UString.
+
+ * parser/Grammar.y:
+ * parser/NodeConstructors.h:
+ (JSC::ContinueNode::ContinueNode):
+ (JSC::BreakNode::BreakNode):
+ (JSC::ForInNode::ForInNode):
+ * runtime/CommonIdentifiers.cpp:
+ (JSC::CommonIdentifiers::CommonIdentifiers):
+ * runtime/CommonIdentifiers.h:
+ * runtime/FunctionPrototype.cpp:
+ (JSC::FunctionPrototype::FunctionPrototype):
+
+2010-02-08 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk>
+
+ Build fix for make distcheck.
+
+ * GNUmakefile.am:
+
+2010-02-08 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Unreviewed RVCT build fix.
+
+ Similar to r54391, don't import the cmath functions from std:: for RVCT.
+
+ * wtf/MathExtras.h:
+
+2010-02-05 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Change UStringImpl::create to CRASH if the string cannot be allocated,
+ rather than returning a null string (which will behave like a zero-length
+ string if used).
+
+ Also move createRep function from UString to become new overloaded
+ UStringImpl::create methods. In doing so, bring their behaviour closer to
+ being in line with WebCore::StringImpl, in removing the behaviour that they
+ can be used to produce null UStrings (ASSERT the char* provided is non-null).
+ This behaviour of converting null C-strings to null UStrings is inefficient
+ (cmompared to just using UString::null()), incompatible with WebCore::StringImpl's
+ behaviour, and may generate unexpected behaviour, since in many cases a null
+ UString can be used like an empty string.
+
+ With these changes UStringImpl need not have a concept of null impls, we can
+ start transitioning this to become an implementation detail of UString, that
+ internally it chooses to use a null-object rather than an actually zero impl
+ pointer.
+
+ * JavaScriptCore.exp:
+ * debugger/Debugger.cpp:
+ (JSC::Debugger::recompileAllJSFunctions):
+ * debugger/DebuggerCallFrame.cpp:
+ (JSC::DebuggerCallFrame::calculatedFunctionName):
+ * parser/Parser.cpp:
+ (JSC::Parser::parse):
+ * profiler/Profile.cpp:
+ (JSC::Profile::Profile):
+ * profiler/ProfileGenerator.cpp:
+ (JSC::ProfileGenerator::stopProfiling):
+ * runtime/Error.cpp:
+ (JSC::Error::create):
+ (JSC::throwError):
+ * runtime/ExceptionHelpers.cpp:
+ (JSC::createError):
+ * runtime/Identifier.cpp:
+ (JSC::Identifier::add):
+ * runtime/PropertyNameArray.cpp:
+ (JSC::PropertyNameArray::add):
+ * runtime/UString.cpp:
+ (JSC::initializeUString):
+ (JSC::UString::UString):
+ (JSC::UString::operator=):
+ * runtime/UString.h:
+ (JSC::UString::isNull):
+ (JSC::UString::null):
+ (JSC::UString::rep):
+ (JSC::UString::UString):
+ * runtime/UStringImpl.cpp:
+ (JSC::UStringImpl::create):
+ * runtime/UStringImpl.h:
+
+2010-02-05 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Eric Seidel.
+
+ [BREWMP] Define SYSTEM_MALLOC 1
+ https://bugs.webkit.org/show_bug.cgi?id=34640
+
+ Make BREWMP use system malloc because FastMalloc is not ported.
+
+ * wtf/Platform.h:
+
+2010-02-05 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Alexey Proskuryakov.
+
+ Don't call CRASH() in fastMalloc and fastCalloc when the requested memory size is 0
+ https://bugs.webkit.org/show_bug.cgi?id=34569
+
+ With USE_SYSTEM_MALLOC=1, fastMalloc and fastCalloc call CRASH()
+ if the return value of malloc and calloc is 0.
+
+ However, these functions can return 0 when the request size is 0.
+ Libc manual says, "If size is 0, then malloc() returns either NULL,
+ or a unique pointer value that can later be successfully passed to free()."
+ Though malloc returns a unique pointer in most systems,
+ 0 can be returned in some systems. For instance, BREW's MALLOC returns 0
+ when size is 0.
+
+ If malloc or calloc returns 0 due to allocation size, increase the size
+ to 1 and try again.
+
+ * wtf/FastMalloc.cpp:
+ (WTF::fastMalloc):
+ (WTF::fastCalloc):
+
+2010-02-04 Mark Rowe <mrowe@apple.com>
+
+ Reviewed by Timothy Hatcher.
+
+ Build fix. Remove a symbol corresponding to an inline function from the linker export
+ file to prevent a weak external failure.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj: Accommodate rename of script.
+
+2010-02-04 Daniel Bates <dbates@webkit.org>
+
+ [Qt] Unreviewed, build fix for Qt bot.
+
+ * runtime/JSStringBuilder.h: Changed #include <X.h> notation #include "X.h".
+
+2010-02-04 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Clearing a WeakGCPtr is weird
+ https://bugs.webkit.org/show_bug.cgi?id=34627
+
+ Added a WeakGCPtr::clear interface.
+
+ As discussed in https://bugs.webkit.org/show_bug.cgi?id=33383, the old
+ interface made it pretty weird for a client to conditionally clear a
+ WeakGCPtr, which is exactly what clients want to do when objects are
+ finalized.
+
+ * API/JSClassRef.cpp:
+ (clearReferenceToPrototype): Use the new WeakGCPtr::clear() interface.
+
+ * runtime/WeakGCPtr.h:
+ (JSC::WeakGCPtr::clear): Added an interface for clearing a WeakGCPtr,
+ iff its current value is the value passed in. It's cumbersome for the
+ client to do this test, since WeakGCPtr sometimes pretends to be null.
+
+2010-02-04 Geoffrey Garen <ggaren@apple.com>
+
+ Build fix: export a header.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2010-02-04 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Add a JSStringBuilder class (similar-to, and derived-from StringBuilder) to
+ construct JSStrings, throwing a JS exception should we run out of memory whilst
+ allocating storage for the string.
+
+ Similarly, add jsMakeNontrivialString methods to use in cases where previously
+ we were calling makeString & passing the result to jsNontrivialString. Again,
+ these new methods throw if we hit an out of memory condition.
+
+ Move throwOutOfMemoryError into ExceptionHelpers, to make it more widely available.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncToString):
+ (JSC::arrayProtoFuncToLocaleString):
+ (JSC::arrayProtoFuncJoin):
+ * runtime/DateConstructor.cpp:
+ (JSC::callDate):
+ * runtime/DatePrototype.cpp:
+ (JSC::dateProtoFuncToString):
+ (JSC::dateProtoFuncToUTCString):
+ (JSC::dateProtoFuncToGMTString):
+ * runtime/ErrorPrototype.cpp:
+ (JSC::errorProtoFuncToString):
+ * runtime/ExceptionHelpers.cpp:
+ (JSC::throwOutOfMemoryError):
+ * runtime/ExceptionHelpers.h:
+ * runtime/JSStringBuilder.h: Added.
+ (JSC::JSStringBuilder::releaseJSString):
+ (JSC::jsMakeNontrivialString):
+ * runtime/NumberPrototype.cpp:
+ (JSC::numberProtoFuncToPrecision):
+ * runtime/ObjectPrototype.cpp:
+ (JSC::objectProtoFuncToString):
+ * runtime/Operations.cpp:
+ * runtime/Operations.h:
+ * runtime/RegExpPrototype.cpp:
+ (JSC::regExpProtoFuncToString):
+ * runtime/StringBuilder.h:
+ (JSC::StringBuilder::append):
+ * runtime/StringPrototype.cpp:
+ (JSC::stringProtoFuncBig):
+ (JSC::stringProtoFuncSmall):
+ (JSC::stringProtoFuncBlink):
+ (JSC::stringProtoFuncBold):
+ (JSC::stringProtoFuncFixed):
+ (JSC::stringProtoFuncItalics):
+ (JSC::stringProtoFuncStrike):
+ (JSC::stringProtoFuncSub):
+ (JSC::stringProtoFuncSup):
+ (JSC::stringProtoFuncFontcolor):
+ (JSC::stringProtoFuncFontsize):
+ (JSC::stringProtoFuncAnchor):
+
+2010-02-04 Steve Falkenburg <sfalken@apple.com>
+
+ Windows build fix.
+
+ * wtf/MathExtras.h:
+
+2010-02-04 Darin Adler <darin@apple.com>
+
+ Reviewed by David Levin.
+
+ Make MathExtras.h compatible with <cmath>
+ https://bugs.webkit.org/show_bug.cgi?id=34618
+
+ * wtf/MathExtras.h: Include <cmath> instead of <math.h>.
+ Use "using" as we do elsewhere in WTF for the four functions from <cmath>
+ we want to use without the prefix. Later we could consider making the std
+ explicit at call sites instead.
+
+2010-02-04 Tamas Szirbucz <szirbucz@inf.u-szeged.hu>
+
+ Reviewed by Gavin Barraclough.
+
+ Use an easily appendable structure for trampolines instead of pointer parameters.
+ https://bugs.webkit.org/show_bug.cgi?id=34424
+
+ * assembler/ARMAssembler.cpp:
+ (JSC::ARMAssembler::executableCopy):
+ * jit/JIT.h:
+ (JSC::JIT::compileCTIMachineTrampolines):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+ * jit/JITStubs.cpp:
+ (JSC::JITThunks::JITThunks):
+ * jit/JITStubs.h:
+ (JSC::JITThunks::ctiStringLengthTrampoline):
+ (JSC::JITThunks::ctiVirtualCallLink):
+ (JSC::JITThunks::ctiVirtualCall):
+ (JSC::JITThunks::ctiNativeCallThunk):
+
2010-02-04 Jedrzej Nowacki <jedrzej.nowacki@nokia.com>
Reviewed by Simon Hausmann.
diff --git a/JavaScriptCore/Configurations/FeatureDefines.xcconfig b/JavaScriptCore/Configurations/FeatureDefines.xcconfig
index 24589c7..8343ce7 100644
--- a/JavaScriptCore/Configurations/FeatureDefines.xcconfig
+++ b/JavaScriptCore/Configurations/FeatureDefines.xcconfig
@@ -56,6 +56,7 @@ ENABLE_JAVASCRIPT_DEBUGGER = ENABLE_JAVASCRIPT_DEBUGGER;
ENABLE_MATHML = ;
ENABLE_NOTIFICATIONS = ;
ENABLE_OFFLINE_WEB_APPLICATIONS = ENABLE_OFFLINE_WEB_APPLICATIONS;
+ENABLE_RUBY = ENABLE_RUBY;
ENABLE_SHARED_WORKERS = ENABLE_SHARED_WORKERS;
ENABLE_SVG = ENABLE_SVG;
ENABLE_SVG_ANIMATION = ENABLE_SVG_ANIMATION;
@@ -72,4 +73,4 @@ ENABLE_XHTMLMP = ;
ENABLE_XPATH = ENABLE_XPATH;
ENABLE_XSLT = ENABLE_XSLT;
-FEATURE_DEFINES = $(ENABLE_3D_CANVAS) $(ENABLE_3D_RENDERING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CLIENT_BASED_GEOLOCATION) $(ENABLE_DATABASE) $(ENABLE_DATAGRID) $(ENABLE_DATALIST) $(ENABLE_DOM_STORAGE) $(ENABLE_EVENTSOURCE) $(ENABLE_FILTERS) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_MATHML) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFLINE_WEB_APPLICATIONS) $(ENABLE_SHARED_WORKERS) $(ENABLE_SVG) $(ENABLE_SVG_ANIMATION) $(ENABLE_SVG_AS_IMAGE) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_SVG_FOREIGN_OBJECT) $(ENABLE_SVG_USE) $(ENABLE_VIDEO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WML) $(ENABLE_WORKERS) $(ENABLE_XHTMLMP) $(ENABLE_XPATH) $(ENABLE_XSLT);
+FEATURE_DEFINES = $(ENABLE_3D_CANVAS) $(ENABLE_3D_RENDERING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CLIENT_BASED_GEOLOCATION) $(ENABLE_DATABASE) $(ENABLE_DATAGRID) $(ENABLE_DATALIST) $(ENABLE_DOM_STORAGE) $(ENABLE_EVENTSOURCE) $(ENABLE_FILTERS) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_MATHML) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFLINE_WEB_APPLICATIONS) $(ENABLE_RUBY) $(ENABLE_SHARED_WORKERS) $(ENABLE_SVG) $(ENABLE_SVG_ANIMATION) $(ENABLE_SVG_AS_IMAGE) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_SVG_FOREIGN_OBJECT) $(ENABLE_SVG_USE) $(ENABLE_VIDEO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WML) $(ENABLE_WORKERS) $(ENABLE_XHTMLMP) $(ENABLE_XPATH) $(ENABLE_XSLT);
diff --git a/JavaScriptCore/Configurations/Version.xcconfig b/JavaScriptCore/Configurations/Version.xcconfig
index 75f9bd4..0e289b1 100644
--- a/JavaScriptCore/Configurations/Version.xcconfig
+++ b/JavaScriptCore/Configurations/Version.xcconfig
@@ -21,8 +21,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-MAJOR_VERSION = 532;
-MINOR_VERSION = 9;
+MAJOR_VERSION = 533;
+MINOR_VERSION = 1;
TINY_VERSION = 0;
FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION);
diff --git a/JavaScriptCore/GNUmakefile.am b/JavaScriptCore/GNUmakefile.am
index 7ac6a8c..4ac89d9 100644
--- a/JavaScriptCore/GNUmakefile.am
+++ b/JavaScriptCore/GNUmakefile.am
@@ -192,6 +192,7 @@ javascriptcore_sources += \
JavaScriptCore/runtime/JSONObject.h \
JavaScriptCore/runtime/JSPropertyNameIterator.cpp \
JavaScriptCore/runtime/JSPropertyNameIterator.h \
+ JavaScriptCore/runtime/JSStringBuilder.h \
JavaScriptCore/runtime/JSZombie.h \
JavaScriptCore/runtime/LiteralParser.cpp \
JavaScriptCore/runtime/LiteralParser.h \
@@ -288,6 +289,7 @@ javascriptcore_sources += \
JavaScriptCore/wtf/TypeTraits.cpp \
JavaScriptCore/wtf/TypeTraits.h \
JavaScriptCore/wtf/UnusedParam.h \
+ JavaScriptCore/wtf/ValueCheck.h \
JavaScriptCore/wtf/Vector.h \
JavaScriptCore/wtf/VectorTraits.h \
JavaScriptCore/wtf/gtk/GOwnPtr.cpp \
diff --git a/JavaScriptCore/JavaScriptCore.exp b/JavaScriptCore/JavaScriptCore.exp
index 01d3144..f562b52 100644
--- a/JavaScriptCore/JavaScriptCore.exp
+++ b/JavaScriptCore/JavaScriptCore.exp
@@ -104,7 +104,6 @@ __ZN3JSC11JSByteArray15createStructureENS_7JSValueE
__ZN3JSC11JSByteArrayC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS3_9ByteArrayEPKNS_9ClassInfoE
__ZN3JSC11ParserArena5resetEv
__ZN3JSC11UStringImpl12sharedBufferEv
-__ZN3JSC11UStringImpl6s_nullE
__ZN3JSC11UStringImpl7s_emptyE
__ZN3JSC11UStringImplD1Ev
__ZN3JSC11checkSyntaxEPNS_9ExecStateERKNS_10SourceCodeE
@@ -191,6 +190,7 @@ __ZN3JSC35createInterruptedExecutionExceptionEPNS_12JSGlobalDataE
__ZN3JSC3NaNE
__ZN3JSC4Heap14primaryHeapEndEv
__ZN3JSC4Heap15recordExtraCostEm
+__ZN3JSC4Heap16objectTypeCountsEv
__ZN3JSC4Heap16primaryHeapBeginEv
__ZN3JSC4Heap17collectAllGarbageEv
__ZN3JSC4Heap17globalObjectCountEv
@@ -238,9 +238,9 @@ __ZN3JSC7UString4fromEd
__ZN3JSC7UString4fromEi
__ZN3JSC7UString4fromEj
__ZN3JSC7UString4fromEl
+__ZN3JSC7UString9s_nullRepE
__ZN3JSC7UStringC1EPKc
__ZN3JSC7UStringC1EPKti
-__ZN3JSC7UStringaSEPKc
__ZN3JSC8Debugger23recompileAllJSFunctionsEPNS_12JSGlobalDataE
__ZN3JSC8Debugger6attachEPNS_14JSGlobalObjectE
__ZN3JSC8Debugger6detachEPNS_14JSGlobalObjectE
@@ -300,6 +300,7 @@ __ZN3JSCgtERKNS_7UStringES2_
__ZN3JSCltERKNS_7UStringES2_
__ZN3WTF10fastCallocEmm
__ZN3WTF10fastMallocEm
+__ZN3WTF10fastStrDupEPKc
__ZN3WTF11currentTimeEv
__ZN3WTF11fastReallocEPvm
__ZN3WTF12createThreadEPFPvS0_ES0_
@@ -348,10 +349,9 @@ __ZN3WTF8Collator18setOrderLowerFirstEb
__ZN3WTF8CollatorC1EPKc
__ZN3WTF8CollatorD1Ev
__ZN3WTF8fastFreeEPv
-__ZN3WTF10fastStrDupEPKc
__ZN3WTF8msToYearEd
-__ZN3WTF9dayInYearEdi
__ZN3WTF9ByteArray6createEm
+__ZN3WTF9dayInYearEdi
__ZNK3JSC10JSFunction23isHostFunctionNonInlineEv
__ZNK3JSC11Interpreter14retrieveCallerEPNS_9ExecStateEPNS_16InternalFunctionE
__ZNK3JSC11Interpreter18retrieveLastCallerEPNS_9ExecStateERiRlRNS_7UStringERNS_7JSValueE
diff --git a/JavaScriptCore/JavaScriptCore.gypi b/JavaScriptCore/JavaScriptCore.gypi
index 24577da..c67b6a8 100644
--- a/JavaScriptCore/JavaScriptCore.gypi
+++ b/JavaScriptCore/JavaScriptCore.gypi
@@ -441,6 +441,7 @@
'wtf/unicode/UTF8.cpp',
'wtf/unicode/UTF8.h',
'wtf/UnusedParam.h',
+ 'wtf/ValueCheck.h',
'wtf/Vector.h',
'wtf/VectorTraits.h',
'wtf/VMTags.h',
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
index 6a0f1d8..6afef77 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
+++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
@@ -32,7 +32,6 @@ EXPORTS
??1ThreadCondition@WTF@@QAE@XZ
??1UStringImpl@JSC@@AAE@XZ
??2JSGlobalObject@JSC@@SAPAXIPAVJSGlobalData@1@@Z
- ??4UString@JSC@@QAEAAV01@PBD@Z
??8JSC@@YA_NABVUString@0@0@Z
?NaN@JSC@@3NB
?UTF8String@UString@JSC@@QBE?AVCString@2@_N@Z
@@ -126,6 +125,7 @@ EXPORTS
?fastFree@WTF@@YAXPAX@Z
?fastMalloc@WTF@@YAPAXI@Z
?fastRealloc@WTF@@YAPAXPAXI@Z
+ ?fastStrDup@WTF@@YAPADPBD@Z
?fastZeroedMalloc@WTF@@YAPAXI@Z
?fillGetterPropertySlot@JSObject@JSC@@QAEXAAVPropertySlot@2@PAVJSValue@2@@Z
?focus@Profile@JSC@@QAEXPBVProfileNode@2@@Z
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
index 7a93632..c5b826c 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
+++ b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
@@ -545,6 +545,10 @@
>
</File>
<File
+ RelativePath="..\..\wtf\ValueCheck.h"
+ >
+ </File>
+ <File
RelativePath="..\..\wtf\Vector.h"
>
</File>
diff --git a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index 58016d0..5f904ce 100644
--- a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -44,7 +44,7 @@
0B4D7E630F319AC800AD7E58 /* TypeTraits.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B4D7E620F319AC800AD7E58 /* TypeTraits.h */; settings = {ATTRIBUTES = (Private, ); }; };
0BDFFAE00FC6192900D69EF4 /* CrossThreadRefCounted.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BDFFAD40FC6171000D69EF4 /* CrossThreadRefCounted.h */; settings = {ATTRIBUTES = (Private, ); }; };
0BDFFAE10FC6193100D69EF4 /* OwnFastMallocPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BDFFAD10FC616EC00D69EF4 /* OwnFastMallocPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 14035DB110DBFB2A00FFFFE7 /* WeakGCPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 14035DB010DBFB2A00FFFFE7 /* WeakGCPtr.h */; };
+ 14035DB110DBFB2A00FFFFE7 /* WeakGCPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 14035DB010DBFB2A00FFFFE7 /* WeakGCPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
140566C4107EC255005DBC8D /* JSAPIValueWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BC0894D50FAFBA2D00001865 /* JSAPIValueWrapper.cpp */; };
140566D1107EC267005DBC8D /* JSStaticScopeObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7E42C190E3938830065A544 /* JSStaticScopeObject.cpp */; };
140566D6107EC271005DBC8D /* JSFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F692A85E0255597D01FF60F7 /* JSFunction.cpp */; };
@@ -232,6 +232,7 @@
86D3B3C410159D7F002865E7 /* RepatchBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D3B3C210159D7F002865E7 /* RepatchBuffer.h */; };
86DB64640F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86DB64630F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp */; };
86E116B10FE75AC800B512BC /* CodeLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E116B00FE75AC800B512BC /* CodeLocation.h */; };
+ 86E85539111B9968001AF51E /* JSStringBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E85538111B9968001AF51E /* JSStringBuilder.h */; };
86EAC4950F93E8D1008EC948 /* RegexCompiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EAC48D0F93E8D1008EC948 /* RegexCompiler.cpp */; };
86EAC4960F93E8D1008EC948 /* RegexCompiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EAC48E0F93E8D1008EC948 /* RegexCompiler.h */; };
86EAC4970F93E8D1008EC948 /* RegexInterpreter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86EAC48F0F93E8D1008EC948 /* RegexInterpreter.cpp */; };
@@ -474,6 +475,7 @@
E124A8F70E555775003091F1 /* OpaqueJSString.h in Headers */ = {isa = PBXBuildFile; fileRef = E124A8F50E555775003091F1 /* OpaqueJSString.h */; settings = {ATTRIBUTES = (Private, ); }; };
E124A8F80E555775003091F1 /* OpaqueJSString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E124A8F60E555775003091F1 /* OpaqueJSString.cpp */; };
E178636D0D9BEEC300D74E75 /* InitializeThreading.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E178636C0D9BEEC300D74E75 /* InitializeThreading.cpp */; };
+ E17FF771112131D200076A19 /* ValueCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = E17FF770112131D200076A19 /* ValueCheck.h */; settings = {ATTRIBUTES = (Private, ); }; };
E18E3A590DF9278C00D90B34 /* JSGlobalData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E18E3A570DF9278C00D90B34 /* JSGlobalData.cpp */; };
E1A862A90D7EBB76001EC6AA /* CollatorICU.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1A862A80D7EBB76001EC6AA /* CollatorICU.cpp */; settings = {COMPILER_FLAGS = "-fno-strict-aliasing"; }; };
E1A862D60D7F2B5C001EC6AA /* CollatorDefault.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1A862D50D7F2B5C001EC6AA /* CollatorDefault.cpp */; };
@@ -766,6 +768,7 @@
86DB645F0F954E9100D7D921 /* ExecutableAllocatorWin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutableAllocatorWin.cpp; sourceTree = "<group>"; };
86DB64630F95C6FC00D7D921 /* ExecutableAllocatorFixedVMPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutableAllocatorFixedVMPool.cpp; sourceTree = "<group>"; };
86E116B00FE75AC800B512BC /* CodeLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodeLocation.h; sourceTree = "<group>"; };
+ 86E85538111B9968001AF51E /* JSStringBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringBuilder.h; sourceTree = "<group>"; };
86EAC48D0F93E8D1008EC948 /* RegexCompiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegexCompiler.cpp; path = yarr/RegexCompiler.cpp; sourceTree = "<group>"; };
86EAC48E0F93E8D1008EC948 /* RegexCompiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegexCompiler.h; path = yarr/RegexCompiler.h; sourceTree = "<group>"; };
86EAC48F0F93E8D1008EC948 /* RegexInterpreter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegexInterpreter.cpp; path = yarr/RegexInterpreter.cpp; sourceTree = "<group>"; };
@@ -977,6 +980,7 @@
E124A8F60E555775003091F1 /* OpaqueJSString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpaqueJSString.cpp; sourceTree = "<group>"; };
E178633F0D9BEC0000D74E75 /* InitializeThreading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InitializeThreading.h; sourceTree = "<group>"; };
E178636C0D9BEEC300D74E75 /* InitializeThreading.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InitializeThreading.cpp; sourceTree = "<group>"; };
+ E17FF770112131D200076A19 /* ValueCheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValueCheck.h; sourceTree = "<group>"; };
E18E3A560DF9278C00D90B34 /* JSGlobalData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalData.h; sourceTree = "<group>"; };
E18E3A570DF9278C00D90B34 /* JSGlobalData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGlobalData.cpp; sourceTree = "<group>"; };
E195678F09E7CF1200B89D13 /* UnicodeIcu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnicodeIcu.h; sourceTree = "<group>"; };
@@ -1384,6 +1388,7 @@
0B330C260F38C62300692DE3 /* TypeTraits.cpp */,
0B4D7E620F319AC800AD7E58 /* TypeTraits.h */,
935AF46B09E9D9DB00ACD1D8 /* UnusedParam.h */,
+ E17FF770112131D200076A19 /* ValueCheck.h */,
6592C316098B7DE10003D4F6 /* Vector.h */,
6592C317098B7DE10003D4F6 /* VectorTraits.h */,
96DD73780F9DA3100027FBCC /* VMTags.h */,
@@ -1544,6 +1549,7 @@
A7E42C180E3938830065A544 /* JSStaticScopeObject.h */,
BC02E9B60E1842FA000F9297 /* JSString.cpp */,
F692A8620255597D01FF60F7 /* JSString.h */,
+ 86E85538111B9968001AF51E /* JSStringBuilder.h */,
14ABB454099C2A0F00E2A24F /* JSType.h */,
6507D2970E871E4A00D7D896 /* JSTypeInfo.h */,
F692A8870255597D01FF60F7 /* JSValue.cpp */,
@@ -2050,6 +2056,8 @@
1429DAE00ED2645B00B89619 /* WRECGenerator.h in Headers */,
1429DABF0ED263E700B89619 /* WRECParser.h in Headers */,
9688CB160ED12B4E001D649F /* X86Assembler.h in Headers */,
+ 86E85539111B9968001AF51E /* JSStringBuilder.h in Headers */,
+ E17FF771112131D200076A19 /* ValueCheck.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2104,7 +2112,7 @@
932F5BD20822A1C700736975 /* Frameworks */,
9319586B09D9F91A00A56FD4 /* Check For Global Initializers */,
933457200EBFDC3F00B80894 /* Check For Exit Time Destructors */,
- 5D29D8BE0E9860B400C3D2D0 /* Check For Weak VTables */,
+ 5D29D8BE0E9860B400C3D2D0 /* Check For Weak VTables and Externals */,
);
buildRules = (
);
@@ -2203,7 +2211,7 @@
shellPath = /bin/sh;
shellScript = "# exclude NPN functions on 64-bit\nsed -e s/^.\\*NPN.\\*$// \"${SRCROOT}/JavaScriptCore.exp\" > \"${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore/JavaScriptCore.LP64.exp\"\n";
};
- 5D29D8BE0E9860B400C3D2D0 /* Check For Weak VTables */ = {
+ 5D29D8BE0E9860B400C3D2D0 /* Check For Weak VTables and Externals */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -2211,12 +2219,12 @@
inputPaths = (
"$(TARGET_BUILD_DIR)/$(EXECUTABLE_PATH)",
);
- name = "Check For Weak VTables";
+ name = "Check For Weak VTables and Externals";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "if [ -f ../WebKitTools/Scripts/check-for-weak-vtables ]; then\n ../WebKitTools/Scripts/check-for-weak-vtables || exit $?\nfi";
+ shellScript = "if [ -f ../WebKitTools/Scripts/check-for-weak-vtables-and-externals ]; then\n ../WebKitTools/Scripts/check-for-weak-vtables-and-externals || exit $?\nfi";
};
5D2F7CF90C6875BB00B5B72B /* Update Info.plist with version information */ = {
isa = PBXShellScriptBuildPhase;
diff --git a/JavaScriptCore/debugger/Debugger.cpp b/JavaScriptCore/debugger/Debugger.cpp
index 1d2e4fb..cbcbd21 100644
--- a/JavaScriptCore/debugger/Debugger.cpp
+++ b/JavaScriptCore/debugger/Debugger.cpp
@@ -94,7 +94,7 @@ void Debugger::recompileAllJSFunctions(JSGlobalData* globalData)
// JavaScript in the inspector.
SourceProviderMap::const_iterator end = sourceProviders.end();
for (SourceProviderMap::const_iterator iter = sourceProviders.begin(); iter != end; ++iter)
- sourceParsed(iter->second, SourceCode(iter->first), -1, 0);
+ sourceParsed(iter->second, SourceCode(iter->first), -1, UString());
}
JSValue evaluateInGlobalCallFrame(const UString& script, JSValue& exception, JSGlobalObject* globalObject)
diff --git a/JavaScriptCore/debugger/DebuggerCallFrame.cpp b/JavaScriptCore/debugger/DebuggerCallFrame.cpp
index c6b4223..05a385d 100644
--- a/JavaScriptCore/debugger/DebuggerCallFrame.cpp
+++ b/JavaScriptCore/debugger/DebuggerCallFrame.cpp
@@ -50,11 +50,11 @@ const UString* DebuggerCallFrame::functionName() const
UString DebuggerCallFrame::calculatedFunctionName() const
{
if (!m_callFrame->codeBlock())
- return 0;
+ return UString();
JSFunction* function = asFunction(m_callFrame->callee());
if (!function)
- return 0;
+ return UString();
return function->calculatedDisplayName(m_callFrame);
}
diff --git a/JavaScriptCore/jit/JIT.h b/JavaScriptCore/jit/JIT.h
index 8e0c9ac..bfbb1ee 100644
--- a/JavaScriptCore/jit/JIT.h
+++ b/JavaScriptCore/jit/JIT.h
@@ -317,10 +317,10 @@ namespace JSC {
jit.privateCompilePutByIdTransition(stubInfo, oldStructure, newStructure, cachedOffset, chain, returnAddress);
}
- static void compileCTIMachineTrampolines(JSGlobalData* globalData, RefPtr<ExecutablePool>* executablePool, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk)
+ static void compileCTIMachineTrampolines(JSGlobalData* globalData, RefPtr<ExecutablePool>* executablePool, TrampolineStructure *trampolines)
{
JIT jit(globalData);
- jit.privateCompileCTIMachineTrampolines(executablePool, globalData, ctiStringLengthTrampoline, ctiVirtualCallLink, ctiVirtualCall, ctiNativeCallThunk);
+ jit.privateCompileCTIMachineTrampolines(executablePool, globalData, trampolines);
}
static void patchGetByIdSelf(CodeBlock* codeblock, StructureStubInfo*, Structure*, size_t cachedOffset, ReturnAddressPtr returnAddress);
@@ -361,7 +361,7 @@ namespace JSC {
void privateCompileGetByIdChain(StructureStubInfo*, Structure*, StructureChain*, size_t count, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame);
void privateCompilePutByIdTransition(StructureStubInfo*, Structure*, Structure*, size_t cachedOffset, StructureChain*, ReturnAddressPtr returnAddress);
- void privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* data, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk);
+ void privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* data, TrampolineStructure *trampolines);
void privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress);
void addSlowCase(Jump);
@@ -800,6 +800,9 @@ namespace JSC {
void emit_op_to_jsnumber(Instruction*);
void emit_op_to_primitive(Instruction*);
void emit_op_unexpected_load(Instruction*);
+#if ENABLE(JIT_OPTIMIZE_MOD)
+ void softModulo();
+#endif
void emitSlow_op_add(Instruction*, Vector<SlowCaseEntry>::iterator&);
void emitSlow_op_bitand(Instruction*, Vector<SlowCaseEntry>::iterator&);
diff --git a/JavaScriptCore/jit/JITArithmetic.cpp b/JavaScriptCore/jit/JITArithmetic.cpp
index feee8d2..2f2ffe3 100644
--- a/JavaScriptCore/jit/JITArithmetic.cpp
+++ b/JavaScriptCore/jit/JITArithmetic.cpp
@@ -31,6 +31,7 @@
#include "CodeBlock.h"
#include "JITInlineMethods.h"
#include "JITStubCall.h"
+#include "JITStubs.h"
#include "JSArray.h"
#include "JSFunction.h"
#include "Interpreter.h"
@@ -1186,14 +1187,40 @@ void JIT::emit_op_mod(Instruction* currentInstruction)
unsigned op1 = currentInstruction[2].u.operand;
unsigned op2 = currentInstruction[3].u.operand;
+#if ENABLE(JIT_OPTIMIZE_MOD)
+ emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
+ addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+ addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+
+ addSlowCase(branch32(Equal, regT2, Imm32(0)));
+
+ emitNakedCall(m_globalData->jitStubs.ctiSoftModulo());
+
+ emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst));
+#else
JITStubCall stubCall(this, cti_op_mod);
stubCall.addArgument(op1);
stubCall.addArgument(op2);
stubCall.call(dst);
+#endif
}
-void JIT::emitSlow_op_mod(Instruction*, Vector<SlowCaseEntry>::iterator&)
+void JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
+#if ENABLE(JIT_OPTIMIZE_MOD)
+ unsigned result = currentInstruction[1].u.operand;
+ unsigned op1 = currentInstruction[2].u.operand;
+ unsigned op2 = currentInstruction[3].u.operand;
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+ JITStubCall stubCall(this, cti_op_mod);
+ stubCall.addArgument(op1);
+ stubCall.addArgument(op2);
+ stubCall.call(result);
+#else
+ ASSERT_NOT_REACHED();
+#endif
}
#endif // CPU(X86) || CPU(X86_64)
@@ -2138,15 +2165,40 @@ void JIT::emit_op_mod(Instruction* currentInstruction)
unsigned op1 = currentInstruction[2].u.operand;
unsigned op2 = currentInstruction[3].u.operand;
+#if ENABLE(JIT_OPTIMIZE_MOD)
+ emitGetVirtualRegisters(op1, regT0, op2, regT2);
+ emitJumpSlowCaseIfNotImmediateInteger(regT0);
+ emitJumpSlowCaseIfNotImmediateInteger(regT2);
+
+ addSlowCase(branch32(Equal, regT2, Imm32(1)));
+
+ emitNakedCall(m_globalData->jitStubs.ctiSoftModulo());
+
+ emitPutVirtualRegister(result, regT0);
+#else
JITStubCall stubCall(this, cti_op_mod);
stubCall.addArgument(op1, regT2);
stubCall.addArgument(op2, regT2);
stubCall.call(result);
+#endif
}
-void JIT::emitSlow_op_mod(Instruction*, Vector<SlowCaseEntry>::iterator&)
+void JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
{
+#if ENABLE(JIT_OPTIMIZE_MOD)
+ unsigned result = currentInstruction[1].u.operand;
+ unsigned op1 = currentInstruction[2].u.operand;
+ unsigned op2 = currentInstruction[3].u.operand;
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+ linkSlowCase(iter);
+ JITStubCall stubCall(this, cti_op_mod);
+ stubCall.addArgument(op1, regT2);
+ stubCall.addArgument(op2, regT2);
+ stubCall.call(result);
+#else
ASSERT_NOT_REACHED();
+#endif
}
#endif // CPU(X86) || CPU(X86_64)
diff --git a/JavaScriptCore/jit/JITOpcodes.cpp b/JavaScriptCore/jit/JITOpcodes.cpp
index d9a32d9..c3f20f1 100644
--- a/JavaScriptCore/jit/JITOpcodes.cpp
+++ b/JavaScriptCore/jit/JITOpcodes.cpp
@@ -40,8 +40,12 @@ namespace JSC {
#if USE(JSVALUE32_64)
-void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* globalData, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk)
+void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* globalData, TrampolineStructure *trampolines)
{
+#if ENABLE(JIT_OPTIMIZE_MOD)
+ Label softModBegin = align();
+ softModulo();
+#endif
#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
// (1) This function provides fast property access for string length
Label stringLengthBegin = align();
@@ -365,18 +369,21 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
CodeRef finalCode = patchBuffer.finalizeCode();
*executablePool = finalCode.m_executablePool;
- *ctiVirtualCall = trampolineAt(finalCode, virtualCallBegin);
- *ctiNativeCallThunk = trampolineAt(finalCode, nativeCallThunk);
+ trampolines->ctiVirtualCall = trampolineAt(finalCode, virtualCallBegin);
+ trampolines->ctiNativeCallThunk = trampolineAt(finalCode, nativeCallThunk);
#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
- *ctiStringLengthTrampoline = trampolineAt(finalCode, stringLengthBegin);
+ trampolines->ctiStringLengthTrampoline = trampolineAt(finalCode, stringLengthBegin);
#else
UNUSED_PARAM(ctiStringLengthTrampoline);
#endif
#if ENABLE(JIT_OPTIMIZE_CALL)
- *ctiVirtualCallLink = trampolineAt(finalCode, virtualCallLinkBegin);
+ trampolines->ctiVirtualCallLink = trampolineAt(finalCode, virtualCallLinkBegin);
#else
UNUSED_PARAM(ctiVirtualCallLink);
#endif
+#if ENABLE(JIT_OPTIMIZE_MOD)
+ trampolines->ctiSoftModulo = trampolineAt(finalCode, softModBegin);
+#endif
}
void JIT::emit_op_mov(Instruction* currentInstruction)
@@ -1495,8 +1502,12 @@ void JIT::emit_op_profile_did_call(Instruction* currentInstruction)
#define RECORD_JUMP_TARGET(targetOffset) \
do { m_labels[m_bytecodeIndex + (targetOffset)].used(); } while (false)
-void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* globalData, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk)
+void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* globalData, TrampolineStructure *trampolines)
{
+#if ENABLE(JIT_OPTIMIZE_MOD)
+ Label softModBegin = align();
+ softModulo();
+#endif
#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
// (2) The second function provides fast property access for string length
Label stringLengthBegin = align();
@@ -1827,11 +1838,14 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
CodeRef finalCode = patchBuffer.finalizeCode();
*executablePool = finalCode.m_executablePool;
- *ctiVirtualCallLink = trampolineAt(finalCode, virtualCallLinkBegin);
- *ctiVirtualCall = trampolineAt(finalCode, virtualCallBegin);
- *ctiNativeCallThunk = trampolineAt(finalCode, nativeCallThunk);
+ trampolines->ctiVirtualCallLink = trampolineAt(finalCode, virtualCallLinkBegin);
+ trampolines->ctiVirtualCall = trampolineAt(finalCode, virtualCallBegin);
+ trampolines->ctiNativeCallThunk = trampolineAt(finalCode, nativeCallThunk);
+#if ENABLE(JIT_OPTIMIZE_MOD)
+ trampolines->ctiSoftModulo = trampolineAt(finalCode, softModBegin);
+#endif
#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
- *ctiStringLengthTrampoline = trampolineAt(finalCode, stringLengthBegin);
+ trampolines->ctiStringLengthTrampoline = trampolineAt(finalCode, stringLengthBegin);
#else
UNUSED_PARAM(ctiStringLengthTrampoline);
#endif
@@ -2978,6 +2992,81 @@ void JIT::emitSlow_op_to_jsnumber(Instruction* currentInstruction, Vector<SlowCa
#endif // USE(JSVALUE32_64)
+// For both JSValue32_64 and JSValue32
+#if ENABLE(JIT_OPTIMIZE_MOD)
+#if CPU(ARM_TRADITIONAL)
+void JIT::softModulo()
+{
+ push(regS0);
+ push(regS1);
+ push(regT1);
+ push(regT3);
+#if USE(JSVALUE32_64)
+ m_assembler.mov_r(regT3, regT2);
+ m_assembler.mov_r(regT2, regT0);
+#else
+ m_assembler.mov_r(regT3, m_assembler.asr(regT2, 1));
+ m_assembler.mov_r(regT2, m_assembler.asr(regT0, 1));
+#endif
+ m_assembler.mov_r(regT1, ARMAssembler::getOp2(0));
+
+ m_assembler.teq_r(regT3, ARMAssembler::getOp2(0));
+ m_assembler.rsb_r(regT3, regT3, ARMAssembler::getOp2(0), ARMAssembler::MI);
+ m_assembler.eor_r(regT1, regT1, ARMAssembler::getOp2(1), ARMAssembler::MI);
+
+ m_assembler.teq_r(regT2, ARMAssembler::getOp2(0));
+ m_assembler.rsb_r(regT2, regT2, ARMAssembler::getOp2(0), ARMAssembler::MI);
+ m_assembler.eor_r(regT1, regT1, ARMAssembler::getOp2(2), ARMAssembler::MI);
+
+ Jump exitBranch = branch32(LessThan, regT2, regT3);
+
+ m_assembler.sub_r(regS1, regT3, ARMAssembler::getOp2(1));
+ m_assembler.tst_r(regS1, regT3);
+ m_assembler.and_r(regT2, regT2, regS1, ARMAssembler::EQ);
+ m_assembler.and_r(regT0, regS1, regT3);
+ Jump exitBranch2 = branchTest32(Zero, regT0);
+
+ m_assembler.clz_r(regS1, regT2);
+ m_assembler.clz_r(regS0, regT3);
+ m_assembler.sub_r(regS0, regS0, regS1);
+
+ m_assembler.rsbs_r(regS0, regS0, ARMAssembler::getOp2(31));
+
+ m_assembler.mov_r(regS0, m_assembler.lsl(regS0, 1), ARMAssembler::NE);
+
+ m_assembler.add_r(ARMRegisters::pc, ARMRegisters::pc, m_assembler.lsl(regS0, 2), ARMAssembler::NE);
+ m_assembler.mov_r(regT0, regT0);
+
+ for (int i = 31; i > 0; --i) {
+ m_assembler.cmp_r(regT2, m_assembler.lsl(regT3, i));
+ m_assembler.sub_r(regT2, regT2, m_assembler.lsl(regT3, i), ARMAssembler::CS);
+ }
+
+ m_assembler.cmp_r(regT2, regT3);
+ m_assembler.sub_r(regT2, regT2, regT3, ARMAssembler::CS);
+
+ exitBranch.link(this);
+ exitBranch2.link(this);
+
+ m_assembler.teq_r(regT1, ARMAssembler::getOp2(0));
+ m_assembler.rsb_r(regT2, regT2, ARMAssembler::getOp2(0), ARMAssembler::GT);
+
+#if USE(JSVALUE32_64)
+ m_assembler.mov_r(regT0, regT2);
+#else
+ m_assembler.mov_r(regT0, m_assembler.lsl(regT2, 1));
+ m_assembler.eor_r(regT0, regT0, ARMAssembler::getOp2(1));
+#endif
+ pop(regT3);
+ pop(regT1);
+ pop(regS1);
+ pop(regS0);
+ ret();
+}
+#else
+#error "JIT_OPTIMIZE_MOD not yet supported on this platform."
+#endif // CPU(ARM_TRADITIONAL)
+#endif
} // namespace JSC
#endif // ENABLE(JIT)
diff --git a/JavaScriptCore/jit/JITStubs.cpp b/JavaScriptCore/jit/JITStubs.cpp
index bf5168b..85471de 100644
--- a/JavaScriptCore/jit/JITStubs.cpp
+++ b/JavaScriptCore/jit/JITStubs.cpp
@@ -757,7 +757,7 @@ extern "C" {
JITThunks::JITThunks(JSGlobalData* globalData)
{
- JIT::compileCTIMachineTrampolines(globalData, &m_executablePool, &m_ctiStringLengthTrampoline, &m_ctiVirtualCallLink, &m_ctiVirtualCall, &m_ctiNativeCallThunk);
+ JIT::compileCTIMachineTrampolines(globalData, &m_executablePool, &m_trampolineStructure);
#if CPU(ARM_THUMB2)
// Unfortunate the arm compiler does not like the use of offsetof on JITStackFrame (since it contains non POD types),
diff --git a/JavaScriptCore/jit/JITStubs.h b/JavaScriptCore/jit/JITStubs.h
index 99c2dd2..17fd0d9 100644
--- a/JavaScriptCore/jit/JITStubs.h
+++ b/JavaScriptCore/jit/JITStubs.h
@@ -74,6 +74,14 @@ namespace JSC {
JSString* jsString() { return static_cast<JSString*>(asPointer); }
ReturnAddressPtr returnAddress() { return ReturnAddressPtr(asPointer); }
};
+
+ struct TrampolineStructure {
+ MacroAssemblerCodePtr ctiStringLengthTrampoline;
+ MacroAssemblerCodePtr ctiVirtualCallLink;
+ MacroAssemblerCodePtr ctiVirtualCall;
+ MacroAssemblerCodePtr ctiNativeCallThunk;
+ MacroAssemblerCodePtr ctiSoftModulo;
+ };
#if CPU(X86_64)
struct JITStackFrame {
@@ -239,18 +247,16 @@ namespace JSC {
static void tryCacheGetByID(CallFrame*, CodeBlock*, ReturnAddressPtr returnAddress, JSValue baseValue, const Identifier& propertyName, const PropertySlot&, StructureStubInfo* stubInfo);
static void tryCachePutByID(CallFrame*, CodeBlock*, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot&, StructureStubInfo* stubInfo);
- MacroAssemblerCodePtr ctiStringLengthTrampoline() { return m_ctiStringLengthTrampoline; }
- MacroAssemblerCodePtr ctiVirtualCallLink() { return m_ctiVirtualCallLink; }
- MacroAssemblerCodePtr ctiVirtualCall() { return m_ctiVirtualCall; }
- MacroAssemblerCodePtr ctiNativeCallThunk() { return m_ctiNativeCallThunk; }
+ MacroAssemblerCodePtr ctiStringLengthTrampoline() { return m_trampolineStructure.ctiStringLengthTrampoline; }
+ MacroAssemblerCodePtr ctiVirtualCallLink() { return m_trampolineStructure.ctiVirtualCallLink; }
+ MacroAssemblerCodePtr ctiVirtualCall() { return m_trampolineStructure.ctiVirtualCall; }
+ MacroAssemblerCodePtr ctiNativeCallThunk() { return m_trampolineStructure.ctiNativeCallThunk; }
+ MacroAssemblerCodePtr ctiSoftModulo() { return m_trampolineStructure.ctiSoftModulo; }
private:
RefPtr<ExecutablePool> m_executablePool;
- MacroAssemblerCodePtr m_ctiStringLengthTrampoline;
- MacroAssemblerCodePtr m_ctiVirtualCallLink;
- MacroAssemblerCodePtr m_ctiVirtualCall;
- MacroAssemblerCodePtr m_ctiNativeCallThunk;
+ TrampolineStructure m_trampolineStructure;
};
extern "C" {
diff --git a/JavaScriptCore/parser/Grammar.y b/JavaScriptCore/parser/Grammar.y
index 717a266..a017cff 100644
--- a/JavaScriptCore/parser/Grammar.y
+++ b/JavaScriptCore/parser/Grammar.y
@@ -1147,7 +1147,7 @@ ThrowStatement:
;
TryStatement:
- TRY Block FINALLY Block { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) TryNode(GLOBAL_DATA, $2.m_node, GLOBAL_DATA->propertyNames->nullIdentifier, false, 0, $4.m_node),
+ TRY Block FINALLY Block { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) TryNode(GLOBAL_DATA, $2.m_node, GLOBAL_DATA->propertyNames->emptyIdentifier, false, 0, $4.m_node),
mergeDeclarationLists($2.m_varDeclarations, $4.m_varDeclarations),
mergeDeclarationLists($2.m_funcDeclarations, $4.m_funcDeclarations),
$2.m_features | $4.m_features,
@@ -1188,10 +1188,10 @@ FunctionDeclaration:
;
FunctionExpr:
- FUNCTION '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, $5, GLOBAL_DATA->lexer->sourceCode($4, $6, @4.first_line)), ClosureFeature, 0); setStatementLocation($5, @4, @6); }
+ FUNCTION '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->emptyIdentifier, $5, GLOBAL_DATA->lexer->sourceCode($4, $6, @4.first_line)), ClosureFeature, 0); setStatementLocation($5, @4, @6); }
| FUNCTION '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE
{
- $$ = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, $6, GLOBAL_DATA->lexer->sourceCode($5, $7, @5.first_line), $3.m_node.head), $3.m_features | ClosureFeature, 0);
+ $$ = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->emptyIdentifier, $6, GLOBAL_DATA->lexer->sourceCode($5, $7, @5.first_line), $3.m_node.head), $3.m_features | ClosureFeature, 0);
if ($3.m_features & ArgumentsFeature)
$6->setUsesArguments();
setStatementLocation($6, @5, @7);
@@ -1981,7 +1981,7 @@ static PropertyNode* makeGetterOrSetterPropertyNode(JSGlobalData* globalData, co
type = PropertyNode::Setter;
else
return 0;
- return new (globalData) PropertyNode(globalData, name, new (globalData) FuncExprNode(globalData, globalData->propertyNames->nullIdentifier, body, source, params), type);
+ return new (globalData) PropertyNode(globalData, name, new (globalData) FuncExprNode(globalData, globalData->propertyNames->emptyIdentifier, body, source, params), type);
}
static ExpressionNode* makeNegateNode(JSGlobalData* globalData, ExpressionNode* n)
diff --git a/JavaScriptCore/parser/NodeConstructors.h b/JavaScriptCore/parser/NodeConstructors.h
index dd3b981..fa8dd4b 100644
--- a/JavaScriptCore/parser/NodeConstructors.h
+++ b/JavaScriptCore/parser/NodeConstructors.h
@@ -741,7 +741,7 @@ namespace JSC {
inline ContinueNode::ContinueNode(JSGlobalData* globalData)
: StatementNode(globalData)
- , m_ident(globalData->propertyNames->nullIdentifier)
+ , m_ident(globalData->propertyNames->emptyIdentifier)
{
}
@@ -753,7 +753,7 @@ namespace JSC {
inline BreakNode::BreakNode(JSGlobalData* globalData)
: StatementNode(globalData)
- , m_ident(globalData->propertyNames->nullIdentifier)
+ , m_ident(globalData->propertyNames->emptyIdentifier)
{
}
@@ -877,7 +877,7 @@ namespace JSC {
inline ForInNode::ForInNode(JSGlobalData* globalData, ExpressionNode* l, ExpressionNode* expr, StatementNode* statement)
: StatementNode(globalData)
- , m_ident(globalData->propertyNames->nullIdentifier)
+ , m_ident(globalData->propertyNames->emptyIdentifier)
, m_init(0)
, m_lexpr(l)
, m_expr(expr)
diff --git a/JavaScriptCore/parser/Parser.cpp b/JavaScriptCore/parser/Parser.cpp
index 003ca0b..56c96b4 100644
--- a/JavaScriptCore/parser/Parser.cpp
+++ b/JavaScriptCore/parser/Parser.cpp
@@ -57,7 +57,7 @@ void Parser::parse(JSGlobalData* globalData, int* errLine, UString* errMsg)
errMsg = &defaultErrMsg;
*errLine = -1;
- *errMsg = 0;
+ *errMsg = UString();
Lexer& lexer = *globalData->lexer;
lexer.setCode(*m_source, m_arena);
diff --git a/JavaScriptCore/profiler/Profile.cpp b/JavaScriptCore/profiler/Profile.cpp
index de75e71..c90f9b0 100644
--- a/JavaScriptCore/profiler/Profile.cpp
+++ b/JavaScriptCore/profiler/Profile.cpp
@@ -42,7 +42,7 @@ Profile::Profile(const UString& title, unsigned uid)
{
// FIXME: When multi-threading is supported this will be a vector and calls
// into the profiler will need to know which thread it is executing on.
- m_head = ProfileNode::create(CallIdentifier("Thread_1", 0, 0), 0, 0);
+ m_head = ProfileNode::create(CallIdentifier("Thread_1", UString(), 0), 0, 0);
}
Profile::~Profile()
diff --git a/JavaScriptCore/profiler/ProfileGenerator.cpp b/JavaScriptCore/profiler/ProfileGenerator.cpp
index 17d37d7..f367033 100644
--- a/JavaScriptCore/profiler/ProfileGenerator.cpp
+++ b/JavaScriptCore/profiler/ProfileGenerator.cpp
@@ -124,7 +124,7 @@ void ProfileGenerator::stopProfiling()
m_currentNode = m_currentNode->parent();
if (double headSelfTime = m_head->selfTime()) {
- RefPtr<ProfileNode> idleNode = ProfileNode::create(CallIdentifier(NonJSExecution, 0, 0), m_head.get(), m_head.get());
+ RefPtr<ProfileNode> idleNode = ProfileNode::create(CallIdentifier(NonJSExecution, UString(), 0), m_head.get(), m_head.get());
idleNode->setTotalTime(headSelfTime);
idleNode->setSelfTime(headSelfTime);
diff --git a/JavaScriptCore/qt/api/qscriptengine.cpp b/JavaScriptCore/qt/api/qscriptengine.cpp
index f12f410..fbeb902 100644
--- a/JavaScriptCore/qt/api/qscriptengine.cpp
+++ b/JavaScriptCore/qt/api/qscriptengine.cpp
@@ -86,3 +86,23 @@ void QScriptEngine::collectGarbage()
{
d_ptr->collectGarbage();
}
+
+/*!
+ Returns a QScriptValue of the primitive type Null.
+
+ \sa undefinedValue()
+*/
+QScriptValue QScriptEngine::nullValue()
+{
+ return QScriptValue(this, QScriptValue::NullValue);
+}
+
+/*!
+ Returns a QScriptValue of the primitive type Undefined.
+
+ \sa nullValue()
+*/
+QScriptValue QScriptEngine::undefinedValue()
+{
+ return QScriptValue(this, QScriptValue::UndefinedValue);
+}
diff --git a/JavaScriptCore/qt/api/qscriptengine.h b/JavaScriptCore/qt/api/qscriptengine.h
index cf61d35..b8bd5e6 100644
--- a/JavaScriptCore/qt/api/qscriptengine.h
+++ b/JavaScriptCore/qt/api/qscriptengine.h
@@ -38,6 +38,8 @@ public:
QScriptValue evaluate(const QString& program, const QString& fileName = QString(), int lineNumber = 1);
void collectGarbage();
+ QScriptValue nullValue();
+ QScriptValue undefinedValue();
private:
friend class QScriptEnginePrivate;
diff --git a/JavaScriptCore/qt/api/qscriptvalue_p.h b/JavaScriptCore/qt/api/qscriptvalue_p.h
index 6a5b388..dea2298 100644
--- a/JavaScriptCore/qt/api/qscriptvalue_p.h
+++ b/JavaScriptCore/qt/api/qscriptvalue_p.h
@@ -24,6 +24,8 @@
#include "qscriptengine_p.h"
#include "qscriptvalue.h"
#include <JavaScriptCore/JavaScript.h>
+#include <QtCore/qmath.h>
+#include <QtCore/qnumeric.h>
#include <QtCore/qshareddata.h>
#include <QtCore/qvarlengtharray.h>
@@ -337,7 +339,7 @@ bool QScriptValuePrivate::isNumber()
{
switch (m_state) {
case CNumber:
- return m_number;
+ return true;
case JSValue:
if (isObject())
return false;
@@ -468,20 +470,30 @@ QString QScriptValuePrivate::toString() const
qsreal QScriptValuePrivate::toNumber() const
{
- // TODO Check it.
switch (m_state) {
case JSValue:
case JSNative:
case JSObject:
return JSValueToNumber(context(), value(), /* exception */ 0);
case CNumber:
- case CBool:
return m_number;
+ case CBool:
+ return m_number ? 1 : 0;
case Invalid:
+ return 0;
case CSpecial:
- return false;
+ return m_number == QScriptValue::NullValue ? 0 : qQNaN();
case CString:
- return m_string.isEmpty();
+ bool ok;
+ qsreal result = m_string.toDouble(&ok);
+ if (ok)
+ return result;
+ result = m_string.toInt(&ok, 0); // Try other bases.
+ if (ok)
+ return result;
+ if (m_string == "Infinity" || m_string == "-Infinity")
+ return qInf();
+ return m_string.length() ? qQNaN() : 0;
}
Q_ASSERT_X(false, "toNumber()", "Not all states are included in the previous switch statement.");
@@ -493,16 +505,18 @@ bool QScriptValuePrivate::toBool() const
switch (m_state) {
case JSValue:
case JSNative:
- case JSObject:
return JSValueToBoolean(context(), value());
+ case JSObject:
+ return true;
case CNumber:
+ return !(qIsNaN(m_number) || !m_number);
case CBool:
return m_number;
case Invalid:
case CSpecial:
return false;
case CString:
- return m_string.isEmpty();
+ return m_string.length();
}
Q_ASSERT_X(false, "toBool()", "Not all states are included in the previous switch statement.");
diff --git a/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp b/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp
index 37f3d11..b36e364 100644
--- a/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp
+++ b/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp
@@ -35,6 +35,8 @@ public slots:
private slots:
void evaluate();
void collectGarbage();
+ void nullValue();
+ void undefinedValue();
};
/* Evaluating a script that throw an unhandled exception should return an invalid value. */
@@ -54,5 +56,22 @@ void tst_QScriptEngine::collectGarbage()
engine.collectGarbage();
QCOMPARE(foo.call().toString(), QString::fromAscii("pong"));
}
+
+void tst_QScriptEngine::nullValue()
+{
+ QScriptEngine engine;
+ QScriptValue value = engine.nullValue();
+ QVERIFY(value.isValid());
+ QVERIFY(value.isNull());
+}
+
+void tst_QScriptEngine::undefinedValue()
+{
+ QScriptEngine engine;
+ QScriptValue value = engine.undefinedValue();
+ QVERIFY(value.isValid());
+ QVERIFY(value.isUndefined());
+}
+
QTEST_MAIN(tst_QScriptEngine)
#include "tst_qscriptengine.moc"
diff --git a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h
index ae81c49..828ef96 100644
--- a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h
+++ b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h
@@ -55,6 +55,9 @@ private slots:
void isBoolean_data();
void isBoolean();
+ void isNumber_data();
+ void isNumber();
+
void isFunction_data();
void isFunction();
@@ -73,6 +76,15 @@ private slots:
void isValid_data();
void isValid();
+ void toNumber_data();
+ void toNumber();
+
+ void toBool_data();
+ void toBool();
+
+ void toBoolean_data();
+ void toBoolean();
+
private:
typedef void (tst_QScriptValue::*InitDataFunction)();
typedef void (tst_QScriptValue::*DefineDataFunction)(const char*);
@@ -94,6 +106,10 @@ private:
void isBoolean_makeData(const char* expr);
void isBoolean_test(const char* expr, const QScriptValue& value);
+ void isNumber_initData();
+ void isNumber_makeData(const char* expr);
+ void isNumber_test(const char* expr, const QScriptValue&);
+
void isFunction_initData();
void isFunction_makeData(const char* expr);
void isFunction_test(const char* expr, const QScriptValue& value);
@@ -118,6 +134,18 @@ private:
void isValid_makeData(const char* expr);
void isValid_test(const char* expr, const QScriptValue& value);
+ void toNumber_initData();
+ void toNumber_makeData(const char*);
+ void toNumber_test(const char*, const QScriptValue&);
+
+ void toBool_initData();
+ void toBool_makeData(const char*);
+ void toBool_test(const char*, const QScriptValue&);
+
+ void toBoolean_initData();
+ void toBoolean_makeData(const char*);
+ void toBoolean_test(const char*, const QScriptValue&);
+
private:
QScriptEngine* engine;
QHash<QString, QScriptValue> m_values;
diff --git a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated.cpp b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated.cpp
index 6d8ef48..f9891a6 100644
--- a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated.cpp
+++ b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated.cpp
@@ -315,6 +315,70 @@ void tst_QScriptValue::isBoolean_test(const char*, const QScriptValue& value)
DEFINE_TEST_FUNCTION(isBoolean)
+void tst_QScriptValue::isNumber_initData()
+{
+ QTest::addColumn<bool>("expected");
+ initScriptValues();
+}
+
+void tst_QScriptValue::isNumber_makeData(const char* expr)
+{
+ static QSet<QString> isNumber;
+ if (isNumber.isEmpty()) {
+ isNumber << "QScriptValue(int(122))"
+ << "QScriptValue(uint(124))"
+ << "QScriptValue(0)"
+ << "QScriptValue(0.0)"
+ << "QScriptValue(123.0)"
+ << "QScriptValue(6.37e-8)"
+ << "QScriptValue(-6.37e-8)"
+ << "QScriptValue(0x43211234)"
+ << "QScriptValue(0x10000)"
+ << "QScriptValue(0x10001)"
+ << "QScriptValue(qSNaN())"
+ << "QScriptValue(qQNaN())"
+ << "QScriptValue(qInf())"
+ << "QScriptValue(-qInf())"
+ << "QScriptValue(0, int(122))"
+ << "QScriptValue(0, uint(124))"
+ << "QScriptValue(0, 0)"
+ << "QScriptValue(0, 0.0)"
+ << "QScriptValue(0, 123.0)"
+ << "QScriptValue(0, 6.37e-8)"
+ << "QScriptValue(0, -6.37e-8)"
+ << "QScriptValue(0, 0x43211234)"
+ << "QScriptValue(0, 0x10000)"
+ << "QScriptValue(0, 0x10001)"
+ << "QScriptValue(0, qSNaN())"
+ << "QScriptValue(0, qQNaN())"
+ << "QScriptValue(0, qInf())"
+ << "QScriptValue(0, -qInf())"
+ << "QScriptValue(engine, int(122))"
+ << "QScriptValue(engine, uint(124))"
+ << "QScriptValue(engine, 0)"
+ << "QScriptValue(engine, 0.0)"
+ << "QScriptValue(engine, 123.0)"
+ << "QScriptValue(engine, 6.37e-8)"
+ << "QScriptValue(engine, -6.37e-8)"
+ << "QScriptValue(engine, 0x43211234)"
+ << "QScriptValue(engine, 0x10000)"
+ << "QScriptValue(engine, 0x10001)"
+ << "QScriptValue(engine, qSNaN())"
+ << "QScriptValue(engine, qQNaN())"
+ << "QScriptValue(engine, qInf())"
+ << "QScriptValue(engine, -qInf())";
+ }
+ newRow(expr) << isNumber.contains(expr);
+}
+
+void tst_QScriptValue::isNumber_test(const char*, const QScriptValue& value)
+{
+ QFETCH(bool, expected);
+ QCOMPARE(value.isNumber(), expected);
+}
+
+DEFINE_TEST_FUNCTION(isNumber)
+
void tst_QScriptValue::isFunction_initData()
{
@@ -492,4 +556,387 @@ void tst_QScriptValue::isObject_test(const char*, const QScriptValue& value)
DEFINE_TEST_FUNCTION(isObject)
+void tst_QScriptValue::toNumber_initData()
+{
+ QTest::addColumn<qsreal>("expected");
+ initScriptValues();
+}
+
+void tst_QScriptValue::toNumber_makeData(const char* expr)
+{
+ static QHash<QString, qsreal> toNumber;
+ if (toNumber.isEmpty()) {
+ toNumber.insert("QScriptValue()", 0);
+ toNumber.insert("QScriptValue(QScriptValue::UndefinedValue)", qQNaN());
+ toNumber.insert("QScriptValue(QScriptValue::NullValue)", 0);
+ toNumber.insert("QScriptValue(true)", 1);
+ toNumber.insert("QScriptValue(false)", 0);
+ toNumber.insert("QScriptValue(int(122))", 122);
+ toNumber.insert("QScriptValue(uint(124))", 124);
+ toNumber.insert("QScriptValue(0)", 0);
+ toNumber.insert("QScriptValue(0.0)", 0);
+ toNumber.insert("QScriptValue(123.0)", 123);
+ toNumber.insert("QScriptValue(6.37e-8)", 6.369999999999999e-08);
+ toNumber.insert("QScriptValue(-6.37e-8)", -6.369999999999999e-08);
+ toNumber.insert("QScriptValue(0x43211234)", 1126240820);
+ toNumber.insert("QScriptValue(0x10000)", 65536);
+ toNumber.insert("QScriptValue(0x10001)", 65537);
+ toNumber.insert("QScriptValue(qSNaN())", qQNaN());
+ toNumber.insert("QScriptValue(qQNaN())", qQNaN());
+ toNumber.insert("QScriptValue(qInf())", qInf());
+ toNumber.insert("QScriptValue(-qInf())", qInf());
+ toNumber.insert("QScriptValue(\"NaN\")", qQNaN());
+ toNumber.insert("QScriptValue(\"Infinity\")", qInf());
+ toNumber.insert("QScriptValue(\"-Infinity\")", qInf());
+ toNumber.insert("QScriptValue(\"ciao\")", qQNaN());
+ toNumber.insert("QScriptValue(QString::fromLatin1(\"ciao\"))", qQNaN());
+ toNumber.insert("QScriptValue(QString(\"\"))", 0);
+ toNumber.insert("QScriptValue(QString())", 0);
+ toNumber.insert("QScriptValue(QString(\"0\"))", 0);
+ toNumber.insert("QScriptValue(QString(\"123\"))", 123);
+ toNumber.insert("QScriptValue(QString(\"12.4\"))", 12.4);
+ toNumber.insert("QScriptValue(0, QScriptValue::UndefinedValue)", qQNaN());
+ toNumber.insert("QScriptValue(0, QScriptValue::NullValue)", 0);
+ toNumber.insert("QScriptValue(0, true)", 1);
+ toNumber.insert("QScriptValue(0, false)", 0);
+ toNumber.insert("QScriptValue(0, int(122))", 122);
+ toNumber.insert("QScriptValue(0, uint(124))", 124);
+ toNumber.insert("QScriptValue(0, 0)", 0);
+ toNumber.insert("QScriptValue(0, 0.0)", 0);
+ toNumber.insert("QScriptValue(0, 123.0)", 123);
+ toNumber.insert("QScriptValue(0, 6.37e-8)", 6.369999999999999e-08);
+ toNumber.insert("QScriptValue(0, -6.37e-8)", -6.369999999999999e-08);
+ toNumber.insert("QScriptValue(0, 0x43211234)", 1126240820);
+ toNumber.insert("QScriptValue(0, 0x10000)", 65536);
+ toNumber.insert("QScriptValue(0, 0x10001)", 65537);
+ toNumber.insert("QScriptValue(0, qSNaN())", qQNaN());
+ toNumber.insert("QScriptValue(0, qQNaN())", qQNaN());
+ toNumber.insert("QScriptValue(0, qInf())", qInf());
+ toNumber.insert("QScriptValue(0, -qInf())", qInf());
+ toNumber.insert("QScriptValue(0, \"NaN\")", qQNaN());
+ toNumber.insert("QScriptValue(0, \"Infinity\")", qInf());
+ toNumber.insert("QScriptValue(0, \"-Infinity\")", qInf());
+ toNumber.insert("QScriptValue(0, \"ciao\")", qQNaN());
+ toNumber.insert("QScriptValue(0, QString::fromLatin1(\"ciao\"))", qQNaN());
+ toNumber.insert("QScriptValue(0, QString(\"\"))", 0);
+ toNumber.insert("QScriptValue(0, QString())", 0);
+ toNumber.insert("QScriptValue(0, QString(\"0\"))", 0);
+ toNumber.insert("QScriptValue(0, QString(\"123\"))", 123);
+ toNumber.insert("QScriptValue(0, QString(\"12.3\"))", 12.3);
+ toNumber.insert("QScriptValue(engine, QScriptValue::UndefinedValue)", qQNaN());
+ toNumber.insert("QScriptValue(engine, QScriptValue::NullValue)", 0);
+ toNumber.insert("QScriptValue(engine, true)", 1);
+ toNumber.insert("QScriptValue(engine, false)", 0);
+ toNumber.insert("QScriptValue(engine, int(122))", 122);
+ toNumber.insert("QScriptValue(engine, uint(124))", 124);
+ toNumber.insert("QScriptValue(engine, 0)", 0);
+ toNumber.insert("QScriptValue(engine, 0.0)", 0);
+ toNumber.insert("QScriptValue(engine, 123.0)", 123);
+ toNumber.insert("QScriptValue(engine, 6.37e-8)", 6.369999999999999e-08);
+ toNumber.insert("QScriptValue(engine, -6.37e-8)", -6.369999999999999e-08);
+ toNumber.insert("QScriptValue(engine, 0x43211234)", 1126240820);
+ toNumber.insert("QScriptValue(engine, 0x10000)", 65536);
+ toNumber.insert("QScriptValue(engine, 0x10001)", 65537);
+ toNumber.insert("QScriptValue(engine, qSNaN())", qQNaN());
+ toNumber.insert("QScriptValue(engine, qQNaN())", qQNaN());
+ toNumber.insert("QScriptValue(engine, qInf())", qInf());
+ toNumber.insert("QScriptValue(engine, -qInf())", qInf());
+ toNumber.insert("QScriptValue(engine, \"NaN\")", qQNaN());
+ toNumber.insert("QScriptValue(engine, \"Infinity\")", qInf());
+ toNumber.insert("QScriptValue(engine, \"-Infinity\")", qInf());
+ toNumber.insert("QScriptValue(engine, \"ciao\")", qQNaN());
+ toNumber.insert("QScriptValue(engine, QString::fromLatin1(\"ciao\"))", qQNaN());
+ toNumber.insert("QScriptValue(engine, QString(\"\"))", 0);
+ toNumber.insert("QScriptValue(engine, QString())", 0);
+ toNumber.insert("QScriptValue(engine, QString(\"0\"))", 0);
+ toNumber.insert("QScriptValue(engine, QString(\"123\"))", 123);
+ toNumber.insert("QScriptValue(engine, QString(\"1.23\"))", 1.23);
+ toNumber.insert("engine->evaluate(\"[]\")", 0);
+ toNumber.insert("engine->evaluate(\"{}\")", qQNaN());
+ toNumber.insert("engine->evaluate(\"Object.prototype\")", qQNaN());
+ toNumber.insert("engine->evaluate(\"Date.prototype\")", qQNaN());
+ toNumber.insert("engine->evaluate(\"Array.prototype\")", 0);
+ toNumber.insert("engine->evaluate(\"Function.prototype\")", qQNaN());
+ toNumber.insert("engine->evaluate(\"Error.prototype\")", qQNaN());
+ toNumber.insert("engine->evaluate(\"Object\")", qQNaN());
+ toNumber.insert("engine->evaluate(\"Array\")", qQNaN());
+ toNumber.insert("engine->evaluate(\"Number\")", qQNaN());
+ toNumber.insert("engine->evaluate(\"Function\")", qQNaN());
+ toNumber.insert("engine->evaluate(\"(function() { return 1; })\")", qQNaN());
+ toNumber.insert("engine->evaluate(\"(function() { return 'ciao'; })\")", qQNaN());
+ toNumber.insert("engine->evaluate(\"(function() { throw new Error('foo'); })\")", qQNaN());
+ toNumber.insert("engine->evaluate(\"/foo/\")", qQNaN());
+ toNumber.insert("engine->evaluate(\"new Object()\")", qQNaN());
+ toNumber.insert("engine->evaluate(\"new Array()\")", 0);
+ toNumber.insert("engine->evaluate(\"new Error()\")", qQNaN());
+ }
+ newRow(expr) << toNumber.value(expr);
+}
+
+void tst_QScriptValue::toNumber_test(const char*, const QScriptValue& value)
+{
+ QFETCH(qsreal, expected);
+ if (qIsNaN(expected)) {
+ QVERIFY(qIsNaN(value.toNumber()));
+ return;
+ }
+ if (qIsInf(expected)) {
+ QVERIFY(qIsInf(value.toNumber()));
+ return;
+ }
+ QCOMPARE(value.toNumber(), expected);
+}
+
+DEFINE_TEST_FUNCTION(toNumber)
+
+
+void tst_QScriptValue::toBool_initData()
+{
+ QTest::addColumn<bool>("expected");
+ initScriptValues();
+}
+
+void tst_QScriptValue::toBool_makeData(const char* expr)
+{
+ static QHash<QString, bool> toBool;
+ if (toBool.isEmpty()) {
+ toBool.insert("QScriptValue()", false);
+ toBool.insert("QScriptValue(QScriptValue::UndefinedValue)", false);
+ toBool.insert("QScriptValue(QScriptValue::NullValue)", false);
+ toBool.insert("QScriptValue(true)", true);
+ toBool.insert("QScriptValue(false)", false);
+ toBool.insert("QScriptValue(int(122))", true);
+ toBool.insert("QScriptValue(uint(124))", true);
+ toBool.insert("QScriptValue(0)", false);
+ toBool.insert("QScriptValue(0.0)", false);
+ toBool.insert("QScriptValue(123.0)", true);
+ toBool.insert("QScriptValue(6.37e-8)", true);
+ toBool.insert("QScriptValue(-6.37e-8)", true);
+ toBool.insert("QScriptValue(0x43211234)", true);
+ toBool.insert("QScriptValue(0x10000)", true);
+ toBool.insert("QScriptValue(0x10001)", true);
+ toBool.insert("QScriptValue(qSNaN())", false);
+ toBool.insert("QScriptValue(qQNaN())", false);
+ toBool.insert("QScriptValue(qInf())", true);
+ toBool.insert("QScriptValue(-qInf())", true);
+ toBool.insert("QScriptValue(\"NaN\")", true);
+ toBool.insert("QScriptValue(\"Infinity\")", true);
+ toBool.insert("QScriptValue(\"-Infinity\")", true);
+ toBool.insert("QScriptValue(\"ciao\")", true);
+ toBool.insert("QScriptValue(QString::fromLatin1(\"ciao\"))", true);
+ toBool.insert("QScriptValue(QString(\"\"))", false);
+ toBool.insert("QScriptValue(QString())", false);
+ toBool.insert("QScriptValue(QString(\"0\"))", true);
+ toBool.insert("QScriptValue(QString(\"123\"))", true);
+ toBool.insert("QScriptValue(QString(\"12.4\"))", true);
+ toBool.insert("QScriptValue(0, QScriptValue::UndefinedValue)", false);
+ toBool.insert("QScriptValue(0, QScriptValue::NullValue)", false);
+ toBool.insert("QScriptValue(0, true)", true);
+ toBool.insert("QScriptValue(0, false)", false);
+ toBool.insert("QScriptValue(0, int(122))", true);
+ toBool.insert("QScriptValue(0, uint(124))", true);
+ toBool.insert("QScriptValue(0, 0)", false);
+ toBool.insert("QScriptValue(0, 0.0)", false);
+ toBool.insert("QScriptValue(0, 123.0)", true);
+ toBool.insert("QScriptValue(0, 6.37e-8)", true);
+ toBool.insert("QScriptValue(0, -6.37e-8)", true);
+ toBool.insert("QScriptValue(0, 0x43211234)", true);
+ toBool.insert("QScriptValue(0, 0x10000)", true);
+ toBool.insert("QScriptValue(0, 0x10001)", true);
+ toBool.insert("QScriptValue(0, qSNaN())", false);
+ toBool.insert("QScriptValue(0, qQNaN())", false);
+ toBool.insert("QScriptValue(0, qInf())", true);
+ toBool.insert("QScriptValue(0, -qInf())", true);
+ toBool.insert("QScriptValue(0, \"NaN\")", true);
+ toBool.insert("QScriptValue(0, \"Infinity\")", true);
+ toBool.insert("QScriptValue(0, \"-Infinity\")", true);
+ toBool.insert("QScriptValue(0, \"ciao\")", true);
+ toBool.insert("QScriptValue(0, QString::fromLatin1(\"ciao\"))", true);
+ toBool.insert("QScriptValue(0, QString(\"\"))", false);
+ toBool.insert("QScriptValue(0, QString())", false);
+ toBool.insert("QScriptValue(0, QString(\"0\"))", true);
+ toBool.insert("QScriptValue(0, QString(\"123\"))", true);
+ toBool.insert("QScriptValue(0, QString(\"12.3\"))", true);
+ toBool.insert("QScriptValue(engine, QScriptValue::UndefinedValue)", false);
+ toBool.insert("QScriptValue(engine, QScriptValue::NullValue)", false);
+ toBool.insert("QScriptValue(engine, true)", true);
+ toBool.insert("QScriptValue(engine, false)", false);
+ toBool.insert("QScriptValue(engine, int(122))", true);
+ toBool.insert("QScriptValue(engine, uint(124))", true);
+ toBool.insert("QScriptValue(engine, 0)", false);
+ toBool.insert("QScriptValue(engine, 0.0)", false);
+ toBool.insert("QScriptValue(engine, 123.0)", true);
+ toBool.insert("QScriptValue(engine, 6.37e-8)", true);
+ toBool.insert("QScriptValue(engine, -6.37e-8)", true);
+ toBool.insert("QScriptValue(engine, 0x43211234)", true);
+ toBool.insert("QScriptValue(engine, 0x10000)", true);
+ toBool.insert("QScriptValue(engine, 0x10001)", true);
+ toBool.insert("QScriptValue(engine, qSNaN())", false);
+ toBool.insert("QScriptValue(engine, qQNaN())", false);
+ toBool.insert("QScriptValue(engine, qInf())", true);
+ toBool.insert("QScriptValue(engine, -qInf())", true);
+ toBool.insert("QScriptValue(engine, \"NaN\")", true);
+ toBool.insert("QScriptValue(engine, \"Infinity\")", true);
+ toBool.insert("QScriptValue(engine, \"-Infinity\")", true);
+ toBool.insert("QScriptValue(engine, \"ciao\")", true);
+ toBool.insert("QScriptValue(engine, QString::fromLatin1(\"ciao\"))", true);
+ toBool.insert("QScriptValue(engine, QString(\"\"))", false);
+ toBool.insert("QScriptValue(engine, QString())", false);
+ toBool.insert("QScriptValue(engine, QString(\"0\"))", true);
+ toBool.insert("QScriptValue(engine, QString(\"123\"))", true);
+ toBool.insert("QScriptValue(engine, QString(\"1.23\"))", true);
+ toBool.insert("engine->evaluate(\"[]\")", true);
+ toBool.insert("engine->evaluate(\"{}\")", false);
+ toBool.insert("engine->evaluate(\"Object.prototype\")", true);
+ toBool.insert("engine->evaluate(\"Date.prototype\")", true);
+ toBool.insert("engine->evaluate(\"Array.prototype\")", true);
+ toBool.insert("engine->evaluate(\"Function.prototype\")", true);
+ toBool.insert("engine->evaluate(\"Error.prototype\")", true);
+ toBool.insert("engine->evaluate(\"Object\")", true);
+ toBool.insert("engine->evaluate(\"Array\")", true);
+ toBool.insert("engine->evaluate(\"Number\")", true);
+ toBool.insert("engine->evaluate(\"Function\")", true);
+ toBool.insert("engine->evaluate(\"(function() { return 1; })\")", true);
+ toBool.insert("engine->evaluate(\"(function() { return 'ciao'; })\")", true);
+ toBool.insert("engine->evaluate(\"(function() { throw new Error('foo'); })\")", true);
+ toBool.insert("engine->evaluate(\"/foo/\")", true);
+ toBool.insert("engine->evaluate(\"new Object()\")", true);
+ toBool.insert("engine->evaluate(\"new Array()\")", true);
+ toBool.insert("engine->evaluate(\"new Error()\")", true);
+ }
+ newRow(expr) << toBool.value(expr);
+}
+
+void tst_QScriptValue::toBool_test(const char*, const QScriptValue& value)
+{
+ QFETCH(bool, expected);
+ QCOMPARE(value.toBool(), expected);
+}
+
+DEFINE_TEST_FUNCTION(toBool)
+
+
+void tst_QScriptValue::toBoolean_initData()
+{
+ QTest::addColumn<bool>("expected");
+ initScriptValues();
+}
+
+void tst_QScriptValue::toBoolean_makeData(const char* expr)
+{
+ static QHash<QString, bool> toBoolean;
+ if (toBoolean.isEmpty()) {
+ toBoolean.insert("QScriptValue()", false);
+ toBoolean.insert("QScriptValue(QScriptValue::UndefinedValue)", false);
+ toBoolean.insert("QScriptValue(QScriptValue::NullValue)", false);
+ toBoolean.insert("QScriptValue(true)", true);
+ toBoolean.insert("QScriptValue(false)", false);
+ toBoolean.insert("QScriptValue(int(122))", true);
+ toBoolean.insert("QScriptValue(uint(124))", true);
+ toBoolean.insert("QScriptValue(0)", false);
+ toBoolean.insert("QScriptValue(0.0)", false);
+ toBoolean.insert("QScriptValue(123.0)", true);
+ toBoolean.insert("QScriptValue(6.37e-8)", true);
+ toBoolean.insert("QScriptValue(-6.37e-8)", true);
+ toBoolean.insert("QScriptValue(0x43211234)", true);
+ toBoolean.insert("QScriptValue(0x10000)", true);
+ toBoolean.insert("QScriptValue(0x10001)", true);
+ toBoolean.insert("QScriptValue(qSNaN())", false);
+ toBoolean.insert("QScriptValue(qQNaN())", false);
+ toBoolean.insert("QScriptValue(qInf())", true);
+ toBoolean.insert("QScriptValue(-qInf())", true);
+ toBoolean.insert("QScriptValue(\"NaN\")", true);
+ toBoolean.insert("QScriptValue(\"Infinity\")", true);
+ toBoolean.insert("QScriptValue(\"-Infinity\")", true);
+ toBoolean.insert("QScriptValue(\"ciao\")", true);
+ toBoolean.insert("QScriptValue(QString::fromLatin1(\"ciao\"))", true);
+ toBoolean.insert("QScriptValue(QString(\"\"))", false);
+ toBoolean.insert("QScriptValue(QString())", false);
+ toBoolean.insert("QScriptValue(QString(\"0\"))", true);
+ toBoolean.insert("QScriptValue(QString(\"123\"))", true);
+ toBoolean.insert("QScriptValue(QString(\"12.4\"))", true);
+ toBoolean.insert("QScriptValue(0, QScriptValue::UndefinedValue)", false);
+ toBoolean.insert("QScriptValue(0, QScriptValue::NullValue)", false);
+ toBoolean.insert("QScriptValue(0, true)", true);
+ toBoolean.insert("QScriptValue(0, false)", false);
+ toBoolean.insert("QScriptValue(0, int(122))", true);
+ toBoolean.insert("QScriptValue(0, uint(124))", true);
+ toBoolean.insert("QScriptValue(0, 0)", false);
+ toBoolean.insert("QScriptValue(0, 0.0)", false);
+ toBoolean.insert("QScriptValue(0, 123.0)", true);
+ toBoolean.insert("QScriptValue(0, 6.37e-8)", true);
+ toBoolean.insert("QScriptValue(0, -6.37e-8)", true);
+ toBoolean.insert("QScriptValue(0, 0x43211234)", true);
+ toBoolean.insert("QScriptValue(0, 0x10000)", true);
+ toBoolean.insert("QScriptValue(0, 0x10001)", true);
+ toBoolean.insert("QScriptValue(0, qSNaN())", false);
+ toBoolean.insert("QScriptValue(0, qQNaN())", false);
+ toBoolean.insert("QScriptValue(0, qInf())", true);
+ toBoolean.insert("QScriptValue(0, -qInf())", true);
+ toBoolean.insert("QScriptValue(0, \"NaN\")", true);
+ toBoolean.insert("QScriptValue(0, \"Infinity\")", true);
+ toBoolean.insert("QScriptValue(0, \"-Infinity\")", true);
+ toBoolean.insert("QScriptValue(0, \"ciao\")", true);
+ toBoolean.insert("QScriptValue(0, QString::fromLatin1(\"ciao\"))", true);
+ toBoolean.insert("QScriptValue(0, QString(\"\"))", false);
+ toBoolean.insert("QScriptValue(0, QString())", false);
+ toBoolean.insert("QScriptValue(0, QString(\"0\"))", true);
+ toBoolean.insert("QScriptValue(0, QString(\"123\"))", true);
+ toBoolean.insert("QScriptValue(0, QString(\"12.3\"))", true);
+ toBoolean.insert("QScriptValue(engine, QScriptValue::UndefinedValue)", false);
+ toBoolean.insert("QScriptValue(engine, QScriptValue::NullValue)", false);
+ toBoolean.insert("QScriptValue(engine, true)", true);
+ toBoolean.insert("QScriptValue(engine, false)", false);
+ toBoolean.insert("QScriptValue(engine, int(122))", true);
+ toBoolean.insert("QScriptValue(engine, uint(124))", true);
+ toBoolean.insert("QScriptValue(engine, 0)", false);
+ toBoolean.insert("QScriptValue(engine, 0.0)", false);
+ toBoolean.insert("QScriptValue(engine, 123.0)", true);
+ toBoolean.insert("QScriptValue(engine, 6.37e-8)", true);
+ toBoolean.insert("QScriptValue(engine, -6.37e-8)", true);
+ toBoolean.insert("QScriptValue(engine, 0x43211234)", true);
+ toBoolean.insert("QScriptValue(engine, 0x10000)", true);
+ toBoolean.insert("QScriptValue(engine, 0x10001)", true);
+ toBoolean.insert("QScriptValue(engine, qSNaN())", false);
+ toBoolean.insert("QScriptValue(engine, qQNaN())", false);
+ toBoolean.insert("QScriptValue(engine, qInf())", true);
+ toBoolean.insert("QScriptValue(engine, -qInf())", true);
+ toBoolean.insert("QScriptValue(engine, \"NaN\")", true);
+ toBoolean.insert("QScriptValue(engine, \"Infinity\")", true);
+ toBoolean.insert("QScriptValue(engine, \"-Infinity\")", true);
+ toBoolean.insert("QScriptValue(engine, \"ciao\")", true);
+ toBoolean.insert("QScriptValue(engine, QString::fromLatin1(\"ciao\"))", true);
+ toBoolean.insert("QScriptValue(engine, QString(\"\"))", false);
+ toBoolean.insert("QScriptValue(engine, QString())", false);
+ toBoolean.insert("QScriptValue(engine, QString(\"0\"))", true);
+ toBoolean.insert("QScriptValue(engine, QString(\"123\"))", true);
+ toBoolean.insert("QScriptValue(engine, QString(\"1.23\"))", true);
+ toBoolean.insert("engine->evaluate(\"[]\")", true);
+ toBoolean.insert("engine->evaluate(\"{}\")", false);
+ toBoolean.insert("engine->evaluate(\"Object.prototype\")", true);
+ toBoolean.insert("engine->evaluate(\"Date.prototype\")", true);
+ toBoolean.insert("engine->evaluate(\"Array.prototype\")", true);
+ toBoolean.insert("engine->evaluate(\"Function.prototype\")", true);
+ toBoolean.insert("engine->evaluate(\"Error.prototype\")", true);
+ toBoolean.insert("engine->evaluate(\"Object\")", true);
+ toBoolean.insert("engine->evaluate(\"Array\")", true);
+ toBoolean.insert("engine->evaluate(\"Number\")", true);
+ toBoolean.insert("engine->evaluate(\"Function\")", true);
+ toBoolean.insert("engine->evaluate(\"(function() { return 1; })\")", true);
+ toBoolean.insert("engine->evaluate(\"(function() { return 'ciao'; })\")", true);
+ toBoolean.insert("engine->evaluate(\"(function() { throw new Error('foo'); })\")", true);
+ toBoolean.insert("engine->evaluate(\"/foo/\")", true);
+ toBoolean.insert("engine->evaluate(\"new Object()\")", true);
+ toBoolean.insert("engine->evaluate(\"new Array()\")", true);
+ toBoolean.insert("engine->evaluate(\"new Error()\")", true);
+ }
+ newRow(expr) << toBoolean.value(expr);
+}
+
+void tst_QScriptValue::toBoolean_test(const char*, const QScriptValue& value)
+{
+ QFETCH(bool, expected);
+ QCOMPARE(value.toBoolean(), expected);
+}
+DEFINE_TEST_FUNCTION(toBoolean)
diff --git a/JavaScriptCore/runtime/ArrayPrototype.cpp b/JavaScriptCore/runtime/ArrayPrototype.cpp
index ce814b2..b64abad 100644
--- a/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -28,6 +28,7 @@
#include "CachedCall.h"
#include "Interpreter.h"
#include "JIT.h"
+#include "JSStringBuilder.h"
#include "ObjectPrototype.h"
#include "Lookup.h"
#include "Operations.h"
@@ -182,8 +183,7 @@ JSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue
totalSize += str.size();
if (!strBuffer.data()) {
- JSObject* error = Error::create(exec, GeneralError, "Out of memory");
- exec->setException(error);
+ throwOutOfMemoryError(exec);
}
if (exec->hadException())
@@ -195,7 +195,7 @@ JSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue
Vector<UChar> buffer;
buffer.reserveCapacity(totalSize);
if (!buffer.data())
- return throwError(exec, GeneralError, "Out of memory");
+ return throwOutOfMemoryError(exec);
for (unsigned i = 0; i < length; i++) {
if (i)
@@ -223,42 +223,28 @@ JSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, J
if (alreadyVisited)
return jsEmptyString(exec); // return an empty string, avoding infinite recursion.
- Vector<UChar, 256> strBuffer;
+ JSStringBuilder strBuffer;
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
for (unsigned k = 0; k < length; k++) {
if (k >= 1)
strBuffer.append(',');
- if (!strBuffer.data()) {
- JSObject* error = Error::create(exec, GeneralError, "Out of memory");
- exec->setException(error);
- break;
- }
JSValue element = thisObj->get(exec, k);
- if (element.isUndefinedOrNull())
- continue;
-
- JSObject* o = element.toObject(exec);
- JSValue conversionFunction = o->get(exec, exec->propertyNames().toLocaleString);
- UString str;
- CallData callData;
- CallType callType = conversionFunction.getCallData(callData);
- if (callType != CallTypeNone)
- str = call(exec, conversionFunction, callType, callData, element, exec->emptyList()).toString(exec);
- else
- str = element.toString(exec);
- strBuffer.append(str.data(), str.size());
-
- if (!strBuffer.data()) {
- JSObject* error = Error::create(exec, GeneralError, "Out of memory");
- exec->setException(error);
+ if (!element.isUndefinedOrNull()) {
+ JSObject* o = element.toObject(exec);
+ JSValue conversionFunction = o->get(exec, exec->propertyNames().toLocaleString);
+ UString str;
+ CallData callData;
+ CallType callType = conversionFunction.getCallData(callData);
+ if (callType != CallTypeNone)
+ str = call(exec, conversionFunction, callType, callData, element, exec->emptyList()).toString(exec);
+ else
+ str = element.toString(exec);
+ strBuffer.append(str);
}
-
- if (exec->hadException())
- break;
}
arrayVisitedElements.remove(thisObj);
- return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
+ return strBuffer.build(exec);
}
JSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
@@ -275,38 +261,27 @@ JSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec, JSObject*, JSValue thi
if (alreadyVisited)
return jsEmptyString(exec); // return an empty string, avoding infinite recursion.
- Vector<UChar, 256> strBuffer;
+ JSStringBuilder strBuffer;
- UChar comma = ',';
- UString separator = args.at(0).isUndefined() ? UString(&comma, 1) : args.at(0).toString(exec);
+ UString separator;
+ if (!args.at(0).isUndefined())
+ separator = args.at(0).toString(exec);
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
for (unsigned k = 0; k < length; k++) {
- if (k >= 1)
- strBuffer.append(separator.data(), separator.size());
- if (!strBuffer.data()) {
- JSObject* error = Error::create(exec, GeneralError, "Out of memory");
- exec->setException(error);
- break;
+ if (k >= 1) {
+ if (separator.isNull())
+ strBuffer.append(',');
+ else
+ strBuffer.append(separator);
}
JSValue element = thisObj->get(exec, k);
- if (element.isUndefinedOrNull())
- continue;
-
- UString str = element.toString(exec);
- strBuffer.append(str.data(), str.size());
-
- if (!strBuffer.data()) {
- JSObject* error = Error::create(exec, GeneralError, "Out of memory");
- exec->setException(error);
- }
-
- if (exec->hadException())
- break;
+ if (!element.isUndefinedOrNull())
+ strBuffer.append(element.toString(exec));
}
arrayVisitedElements.remove(thisObj);
- return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
+ return strBuffer.build(exec);
}
JSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
diff --git a/JavaScriptCore/runtime/Collector.cpp b/JavaScriptCore/runtime/Collector.cpp
index 63139a2..2873e0b 100644
--- a/JavaScriptCore/runtime/Collector.cpp
+++ b/JavaScriptCore/runtime/Collector.cpp
@@ -1122,12 +1122,15 @@ void Heap::markRoots()
MarkedArgumentBuffer::markLists(markStack, *m_markListSet);
if (m_globalData->exception)
markStack.append(m_globalData->exception);
- m_globalData->smallStrings.markChildren(markStack);
if (m_globalData->functionCodeBlockBeingReparsed)
m_globalData->functionCodeBlockBeingReparsed->markAggregate(markStack);
if (m_globalData->firstStringifierToMark)
JSONObject::markStringifiers(markStack, m_globalData->firstStringifierToMark);
+ // Mark the small strings cache last, since it will clear itself if nothing
+ // else has marked it.
+ m_globalData->smallStrings.markChildren(markStack);
+
markStack.drain();
markStack.compact();
@@ -1197,12 +1200,13 @@ static const char* typeName(JSCell* cell)
return "number";
#endif
if (cell->isGetterSetter())
- return "gettersetter";
+ return "Getter-Setter";
if (cell->isAPIValueWrapper())
- return "value wrapper";
+ return "API wrapper";
if (cell->isPropertyNameIterator())
- return "for-in iterator";
- ASSERT(cell->isObject());
+ return "For-in iterator";
+ if (!cell->isObject())
+ return "[empty cell]";
const ClassInfo* info = cell->classInfo();
return info ? info->className : "Object";
}
@@ -1218,6 +1222,18 @@ HashCountedSet<const char*>* Heap::protectedObjectTypeCounts()
return counts;
}
+HashCountedSet<const char*>* Heap::objectTypeCounts()
+{
+ HashCountedSet<const char*>* counts = new HashCountedSet<const char*>;
+
+ LiveObjectIterator it = primaryHeapBegin();
+ LiveObjectIterator heapEnd = primaryHeapEnd();
+ for ( ; it != heapEnd; ++it)
+ counts->add(typeName(*it));
+
+ return counts;
+}
+
bool Heap::isBusy()
{
return m_heap.operationInProgress != NoOperation;
diff --git a/JavaScriptCore/runtime/Collector.h b/JavaScriptCore/runtime/Collector.h
index 7f7a679..82aa8a1 100644
--- a/JavaScriptCore/runtime/Collector.h
+++ b/JavaScriptCore/runtime/Collector.h
@@ -100,6 +100,7 @@ namespace JSC {
size_t protectedObjectCount();
size_t protectedGlobalObjectCount();
HashCountedSet<const char*>* protectedObjectTypeCounts();
+ HashCountedSet<const char*>* objectTypeCounts();
void registerThread(); // Only needs to be called by clients that can use the same heap from multiple threads.
diff --git a/JavaScriptCore/runtime/CollectorHeapIterator.h b/JavaScriptCore/runtime/CollectorHeapIterator.h
index e4f2f91..be6f3c9 100644
--- a/JavaScriptCore/runtime/CollectorHeapIterator.h
+++ b/JavaScriptCore/runtime/CollectorHeapIterator.h
@@ -38,7 +38,7 @@ namespace JSC {
protected:
CollectorHeapIterator(CollectorHeap&, size_t startBlock, size_t startCell);
- void advance(size_t cellsPerBlock);
+ void advance(size_t max);
CollectorHeap& m_heap;
size_t m_block;
@@ -80,10 +80,12 @@ namespace JSC {
return reinterpret_cast<JSCell*>(m_heap.blocks[m_block]->cells + m_cell);
}
- inline void CollectorHeapIterator::advance(size_t cellsPerBlock)
+ // Iterators advance up to the next-to-last -- and not the last -- cell in a
+ // block, since the last cell is a dummy sentinel.
+ inline void CollectorHeapIterator::advance(size_t max)
{
++m_cell;
- if (m_cell == cellsPerBlock) {
+ if (m_cell == max) {
m_cell = 0;
++m_block;
}
@@ -97,14 +99,12 @@ namespace JSC {
inline LiveObjectIterator& LiveObjectIterator::operator++()
{
- if (m_block < m_heap.nextBlock || m_cell < m_heap.nextCell) {
- advance(HeapConstants::cellsPerBlock);
+ advance(HeapConstants::cellsPerBlock - 1);
+ if (m_block < m_heap.nextBlock || (m_block == m_heap.nextBlock && m_cell < m_heap.nextCell))
return *this;
- }
- do {
- advance(HeapConstants::cellsPerBlock);
- } while (m_block < m_heap.usedBlocks && !m_heap.blocks[m_block]->marked.get(m_cell));
+ while (m_block < m_heap.usedBlocks && !m_heap.blocks[m_block]->marked.get(m_cell))
+ advance(HeapConstants::cellsPerBlock - 1);
return *this;
}
@@ -117,7 +117,7 @@ namespace JSC {
inline DeadObjectIterator& DeadObjectIterator::operator++()
{
do {
- advance(HeapConstants::cellsPerBlock);
+ advance(HeapConstants::cellsPerBlock - 1);
ASSERT(m_block > m_heap.nextBlock || (m_block == m_heap.nextBlock && m_cell >= m_heap.nextCell));
} while (m_block < m_heap.usedBlocks && m_heap.blocks[m_block]->marked.get(m_cell));
return *this;
@@ -131,7 +131,7 @@ namespace JSC {
inline ObjectIterator& ObjectIterator::operator++()
{
- advance(HeapConstants::cellsPerBlock);
+ advance(HeapConstants::cellsPerBlock - 1);
return *this;
}
diff --git a/JavaScriptCore/runtime/CommonIdentifiers.cpp b/JavaScriptCore/runtime/CommonIdentifiers.cpp
index 3837817..ed5e304 100644
--- a/JavaScriptCore/runtime/CommonIdentifiers.cpp
+++ b/JavaScriptCore/runtime/CommonIdentifiers.cpp
@@ -28,8 +28,7 @@ static const char* const nullCString = 0;
#define INITIALIZE_PROPERTY_NAME(name) , name(globalData, #name)
CommonIdentifiers::CommonIdentifiers(JSGlobalData* globalData)
- : nullIdentifier(globalData, nullCString)
- , emptyIdentifier(globalData, "")
+ : emptyIdentifier(globalData, "")
, underscoreProto(globalData, "__proto__")
, thisIdentifier(globalData, "this")
JSC_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(INITIALIZE_PROPERTY_NAME)
diff --git a/JavaScriptCore/runtime/CommonIdentifiers.h b/JavaScriptCore/runtime/CommonIdentifiers.h
index de24f4a..0a3d774 100644
--- a/JavaScriptCore/runtime/CommonIdentifiers.h
+++ b/JavaScriptCore/runtime/CommonIdentifiers.h
@@ -90,7 +90,6 @@ namespace JSC {
friend class JSGlobalData;
public:
- const Identifier nullIdentifier;
const Identifier emptyIdentifier;
const Identifier underscoreProto;
const Identifier thisIdentifier;
diff --git a/JavaScriptCore/runtime/DateConstructor.cpp b/JavaScriptCore/runtime/DateConstructor.cpp
index e9a5c29..ab95d06 100644
--- a/JavaScriptCore/runtime/DateConstructor.cpp
+++ b/JavaScriptCore/runtime/DateConstructor.cpp
@@ -28,6 +28,7 @@
#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "JSString.h"
+#include "JSStringBuilder.h"
#include "ObjectPrototype.h"
#include "PrototypeFunction.h"
#include <math.h>
@@ -137,7 +138,7 @@ static JSValue JSC_HOST_CALL callDate(ExecState* exec, JSObject*, JSValue, const
DateConversionBuffer time;
formatDate(ts, date);
formatTime(ts, time);
- return jsNontrivialString(exec, makeString(date, " ", time));
+ return jsMakeNontrivialString(exec, date, " ", time);
}
CallType DateConstructor::getCallData(CallData& callData)
diff --git a/JavaScriptCore/runtime/DatePrototype.cpp b/JavaScriptCore/runtime/DatePrototype.cpp
index ca9d4ea..25b0ac4 100644
--- a/JavaScriptCore/runtime/DatePrototype.cpp
+++ b/JavaScriptCore/runtime/DatePrototype.cpp
@@ -26,6 +26,7 @@
#include "DateConversion.h"
#include "Error.h"
#include "JSString.h"
+#include "JSStringBuilder.h"
#include "ObjectPrototype.h"
#include "DateInstance.h"
@@ -427,7 +428,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToString(ExecState* exec, JSObject*, JSValue
DateConversionBuffer time;
formatDate(*gregorianDateTime, date);
formatTime(*gregorianDateTime, time);
- return jsNontrivialString(exec, makeString(date, " ", time));
+ return jsMakeNontrivialString(exec, date, " ", time);
}
JSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -444,7 +445,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSVal
DateConversionBuffer time;
formatDateUTCVariant(*gregorianDateTime, date);
formatTimeUTC(*gregorianDateTime, time);
- return jsNontrivialString(exec, makeString(date, " ", time));
+ return jsMakeNontrivialString(exec, date, " ", time);
}
JSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -570,7 +571,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToGMTString(ExecState* exec, JSObject*, JSVal
DateConversionBuffer time;
formatDateUTCVariant(*gregorianDateTime, date);
formatTimeUTC(*gregorianDateTime, time);
- return jsNontrivialString(exec, makeString(date, " ", time));
+ return jsMakeNontrivialString(exec, date, " ", time);
}
JSValue JSC_HOST_CALL dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
diff --git a/JavaScriptCore/runtime/Error.cpp b/JavaScriptCore/runtime/Error.cpp
index ddd4bc4..69464b7 100644
--- a/JavaScriptCore/runtime/Error.cpp
+++ b/JavaScriptCore/runtime/Error.cpp
@@ -94,7 +94,7 @@ JSObject* Error::create(ExecState* exec, ErrorType type, const UString& message,
JSObject* Error::create(ExecState* exec, ErrorType type, const char* message)
{
- return create(exec, type, message, -1, -1, NULL);
+ return create(exec, type, message, -1, -1, UString());
}
JSObject* throwError(ExecState* exec, JSObject* error)
@@ -105,21 +105,21 @@ JSObject* throwError(ExecState* exec, JSObject* error)
JSObject* throwError(ExecState* exec, ErrorType type)
{
- JSObject* error = Error::create(exec, type, UString(), -1, -1, NULL);
+ JSObject* error = Error::create(exec, type, UString(), -1, -1, UString());
exec->setException(error);
return error;
}
JSObject* throwError(ExecState* exec, ErrorType type, const UString& message)
{
- JSObject* error = Error::create(exec, type, message, -1, -1, NULL);
+ JSObject* error = Error::create(exec, type, message, -1, -1, UString());
exec->setException(error);
return error;
}
JSObject* throwError(ExecState* exec, ErrorType type, const char* message)
{
- JSObject* error = Error::create(exec, type, message, -1, -1, NULL);
+ JSObject* error = Error::create(exec, type, message, -1, -1, UString());
exec->setException(error);
return error;
}
diff --git a/JavaScriptCore/runtime/ErrorPrototype.cpp b/JavaScriptCore/runtime/ErrorPrototype.cpp
index be9e4b8..eb35733 100644
--- a/JavaScriptCore/runtime/ErrorPrototype.cpp
+++ b/JavaScriptCore/runtime/ErrorPrototype.cpp
@@ -23,6 +23,7 @@
#include "JSFunction.h"
#include "JSString.h"
+#include "JSStringBuilder.h"
#include "ObjectPrototype.h"
#include "PrototypeFunction.h"
#include "UString.h"
@@ -55,11 +56,11 @@ JSValue JSC_HOST_CALL errorProtoFuncToString(ExecState* exec, JSObject*, JSValue
if (!name.isUndefined()) {
if (!message.isUndefined())
- return jsNontrivialString(exec, makeString(name.toString(exec), ": ", message.toString(exec)));
+ return jsMakeNontrivialString(exec, name.toString(exec), ": ", message.toString(exec));
return jsNontrivialString(exec, name.toString(exec));
}
if (!message.isUndefined())
- return jsNontrivialString(exec, makeString("Error: ", message.toString(exec)));
+ return jsMakeNontrivialString(exec, "Error: ", message.toString(exec));
return jsNontrivialString(exec, "Error");
}
diff --git a/JavaScriptCore/runtime/ExceptionHelpers.cpp b/JavaScriptCore/runtime/ExceptionHelpers.cpp
index 9bb740e..b9c6319 100644
--- a/JavaScriptCore/runtime/ExceptionHelpers.cpp
+++ b/JavaScriptCore/runtime/ExceptionHelpers.cpp
@@ -58,7 +58,7 @@ JSValue createInterruptedExecutionException(JSGlobalData* globalData)
static JSValue createError(ExecState* exec, ErrorType e, const char* msg)
{
- return Error::create(exec, e, msg, -1, -1, 0);
+ return Error::create(exec, e, msg, -1, -1, UString());
}
JSValue createStackOverflowError(ExecState* exec)
@@ -188,4 +188,9 @@ JSObject* createNotAnObjectError(ExecState* exec, JSNotAnObjectErrorStub* error,
return exception;
}
+JSValue throwOutOfMemoryError(ExecState* exec)
+{
+ return throwError(exec, GeneralError, "Out of memory");
+}
+
} // namespace JSC
diff --git a/JavaScriptCore/runtime/ExceptionHelpers.h b/JavaScriptCore/runtime/ExceptionHelpers.h
index e739d09..b6e7373 100644
--- a/JavaScriptCore/runtime/ExceptionHelpers.h
+++ b/JavaScriptCore/runtime/ExceptionHelpers.h
@@ -51,6 +51,7 @@ namespace JSC {
JSObject* createNotAConstructorError(ExecState*, JSValue, unsigned bytecodeOffset, CodeBlock*);
JSValue createNotAFunctionError(ExecState*, JSValue, unsigned bytecodeOffset, CodeBlock*);
JSObject* createNotAnObjectError(ExecState*, JSNotAnObjectErrorStub*, unsigned bytecodeOffset, CodeBlock*);
+ JSValue throwOutOfMemoryError(ExecState*);
} // namespace JSC
diff --git a/JavaScriptCore/runtime/Executable.cpp b/JavaScriptCore/runtime/Executable.cpp
index bc18cc9..79900dc 100644
--- a/JavaScriptCore/runtime/Executable.cpp
+++ b/JavaScriptCore/runtime/Executable.cpp
@@ -272,7 +272,7 @@ UString FunctionExecutable::paramString() const
builder.append(", ");
builder.append(parameters[pos].ustring());
}
- return builder.release();
+ return builder.build();
}
};
diff --git a/JavaScriptCore/runtime/FunctionConstructor.cpp b/JavaScriptCore/runtime/FunctionConstructor.cpp
index 9d55dd1..9b0b1bb 100644
--- a/JavaScriptCore/runtime/FunctionConstructor.cpp
+++ b/JavaScriptCore/runtime/FunctionConstructor.cpp
@@ -89,7 +89,7 @@ JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifi
builder.append(") { ");
builder.append(args.at(args.size() - 1).toString(exec));
builder.append("\n})");
- program = builder.release();
+ program = builder.build();
}
int errLine;
diff --git a/JavaScriptCore/runtime/FunctionPrototype.cpp b/JavaScriptCore/runtime/FunctionPrototype.cpp
index f08bd5e..3475f08 100644
--- a/JavaScriptCore/runtime/FunctionPrototype.cpp
+++ b/JavaScriptCore/runtime/FunctionPrototype.cpp
@@ -25,6 +25,7 @@
#include "JSArray.h"
#include "JSFunction.h"
#include "JSString.h"
+#include "JSStringBuilder.h"
#include "Interpreter.h"
#include "Lexer.h"
#include "PrototypeFunction.h"
@@ -38,7 +39,7 @@ static JSValue JSC_HOST_CALL functionProtoFuncApply(ExecState*, JSObject*, JSVal
static JSValue JSC_HOST_CALL functionProtoFuncCall(ExecState*, JSObject*, JSValue, const ArgList&);
FunctionPrototype::FunctionPrototype(ExecState* exec, NonNullPassRefPtr<Structure> structure)
- : InternalFunction(&exec->globalData(), structure, exec->propertyNames().nullIdentifier)
+ : InternalFunction(&exec->globalData(), structure, exec->propertyNames().emptyIdentifier)
{
putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 0), DontDelete | ReadOnly | DontEnum);
}
@@ -90,13 +91,13 @@ JSValue JSC_HOST_CALL functionProtoFuncToString(ExecState* exec, JSObject*, JSVa
FunctionExecutable* executable = function->jsExecutable();
UString sourceString = executable->source().toString();
insertSemicolonIfNeeded(sourceString);
- return jsString(exec, makeString("function ", function->name(exec), "(", executable->paramString(), ") ", sourceString));
+ return jsMakeNontrivialString(exec, "function ", function->name(exec), "(", executable->paramString(), ") ", sourceString);
}
}
if (thisValue.inherits(&InternalFunction::info)) {
InternalFunction* function = asInternalFunction(thisValue);
- return jsString(exec, makeString("function ", function->name(exec), "() {\n [native code]\n}"));
+ return jsMakeNontrivialString(exec, "function ", function->name(exec), "() {\n [native code]\n}");
}
return throwError(exec, TypeError);
diff --git a/JavaScriptCore/runtime/Identifier.cpp b/JavaScriptCore/runtime/Identifier.cpp
index 747c4ac..97929e2 100644
--- a/JavaScriptCore/runtime/Identifier.cpp
+++ b/JavaScriptCore/runtime/Identifier.cpp
@@ -123,10 +123,8 @@ struct CStringTranslator {
PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const char* c)
{
- if (!c) {
- UString::Rep::null().hash();
- return &UString::Rep::null();
- }
+ ASSERT(c);
+
if (!c[0]) {
UString::Rep::empty().hash();
return &UString::Rep::empty();
diff --git a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
index 0bc1274..3ddac7c 100644
--- a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
+++ b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
@@ -30,11 +30,11 @@
#include "Interpreter.h"
#include "JSGlobalObject.h"
#include "JSString.h"
+#include "JSStringBuilder.h"
#include "Lexer.h"
#include "LiteralParser.h"
#include "Nodes.h"
#include "Parser.h"
-#include "StringBuilder.h"
#include "StringExtras.h"
#include "dtoa.h"
#include <stdio.h>
@@ -57,7 +57,7 @@ static JSValue encode(ExecState* exec, const ArgList& args, const char* doNotEsc
if (!cstr.c_str())
return throwError(exec, URIError, "String contained an illegal UTF-16 sequence.");
- StringBuilder builder;
+ JSStringBuilder builder;
const char* p = cstr.c_str();
for (size_t k = 0; k < cstr.size(); k++, p++) {
char c = *p;
@@ -66,15 +66,15 @@ static JSValue encode(ExecState* exec, const ArgList& args, const char* doNotEsc
else {
char tmp[4];
snprintf(tmp, 4, "%%%02X", static_cast<unsigned char>(c));
- builder.append((const char*)tmp);
+ builder.append(tmp);
}
}
- return jsString(exec, builder.release());
+ return builder.build(exec);
}
static JSValue decode(ExecState* exec, const ArgList& args, const char* doNotUnescape, bool strict)
{
- StringBuilder builder;
+ JSStringBuilder builder;
UString str = args.at(0).toString(exec);
int k = 0;
int len = str.size();
@@ -135,7 +135,7 @@ static JSValue decode(ExecState* exec, const ArgList& args, const char* doNotUne
k++;
builder.append(c);
}
- return jsString(exec, builder.release());
+ return builder.build(exec);
}
bool isStrWhiteSpace(UChar c)
@@ -378,8 +378,7 @@ JSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec, JSObject*, JSValue, cons
"0123456789"
"*+-./@_";
- StringBuilder builder;
- UString s;
+ JSStringBuilder builder;
UString str = args.at(0).toString(exec);
const UChar* c = str.data();
for (int k = 0; k < str.size(); k++, c++) {
@@ -387,18 +386,17 @@ JSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec, JSObject*, JSValue, cons
if (u > 255) {
char tmp[7];
sprintf(tmp, "%%u%04X", u);
- s = UString(tmp);
+ builder.append(tmp);
} else if (u != 0 && strchr(do_not_escape, static_cast<char>(u)))
- s = UString(c, 1);
+ builder.append(c, 1);
else {
char tmp[4];
sprintf(tmp, "%%%02X", u);
- s = UString(tmp);
+ builder.append(tmp);
}
- builder.append(s);
}
- return jsString(exec, builder.release());
+ return builder.build(exec);
}
JSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec, JSObject*, JSValue, const ArgList& args)
@@ -425,7 +423,7 @@ JSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec, JSObject*, JSValue, co
builder.append(*c);
}
- return jsString(exec, builder.release());
+ return jsString(exec, builder.build());
}
#ifndef NDEBUG
diff --git a/JavaScriptCore/runtime/JSONObject.cpp b/JavaScriptCore/runtime/JSONObject.cpp
index ce0dcff..acd9280 100644
--- a/JavaScriptCore/runtime/JSONObject.cpp
+++ b/JavaScriptCore/runtime/JSONObject.cpp
@@ -268,7 +268,7 @@ JSValue Stringifier::stringify(JSValue value)
if (m_exec->hadException())
return jsNull();
- return jsString(m_exec, result.release());
+ return jsString(m_exec, result.build());
}
void Stringifier::appendQuotedString(StringBuilder& builder, const UString& value)
diff --git a/JavaScriptCore/runtime/JSPropertyNameIterator.cpp b/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
index d3dcb83..a5d4da0 100644
--- a/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
+++ b/JavaScriptCore/runtime/JSPropertyNameIterator.cpp
@@ -35,6 +35,24 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(JSPropertyNameIterator);
+inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlots)
+ : JSCell(exec->globalData().propertyNameIteratorStructure.get())
+ , m_cachedStructure(0)
+ , m_numCacheableSlots(numCacheableSlots)
+ , m_jsStringsSize(propertyNameArrayData->propertyNameVector().size())
+ , m_jsStrings(new JSValue[m_jsStringsSize])
+{
+ PropertyNameArrayData::PropertyNameVector& propertyNameVector = propertyNameArrayData->propertyNameVector();
+ for (size_t i = 0; i < m_jsStringsSize; ++i)
+ m_jsStrings[i] = jsOwnedString(exec, propertyNameVector[i].ustring());
+}
+
+JSPropertyNameIterator::~JSPropertyNameIterator()
+{
+ if (m_cachedStructure)
+ m_cachedStructure->clearEnumerationCache(this);
+}
+
JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSObject* o)
{
ASSERT(!o->structure()->enumerationCache() ||
diff --git a/JavaScriptCore/runtime/JSPropertyNameIterator.h b/JavaScriptCore/runtime/JSPropertyNameIterator.h
index d18c2c5..3f533a0 100644
--- a/JavaScriptCore/runtime/JSPropertyNameIterator.h
+++ b/JavaScriptCore/runtime/JSPropertyNameIterator.h
@@ -49,6 +49,8 @@ namespace JSC {
{
return Structure::create(prototype, TypeInfo(CompoundType, OverridesMarkChildren), AnonymousSlotCount);
}
+
+ virtual ~JSPropertyNameIterator();
virtual bool isPropertyNameIterator() const { return true; }
@@ -81,23 +83,21 @@ namespace JSC {
OwnArrayPtr<JSValue> m_jsStrings;
};
-inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlots)
- : JSCell(exec->globalData().propertyNameIteratorStructure.get())
- , m_cachedStructure(0)
- , m_numCacheableSlots(numCacheableSlots)
- , m_jsStringsSize(propertyNameArrayData->propertyNameVector().size())
- , m_jsStrings(new JSValue[m_jsStringsSize])
-{
- PropertyNameArrayData::PropertyNameVector& propertyNameVector = propertyNameArrayData->propertyNameVector();
- for (size_t i = 0; i < m_jsStringsSize; ++i)
- m_jsStrings[i] = jsOwnedString(exec, propertyNameVector[i].ustring());
-}
-
-inline void Structure::setEnumerationCache(JSPropertyNameIterator* enumerationCache)
-{
- ASSERT(!isDictionary());
- m_enumerationCache = enumerationCache;
-}
+ inline void Structure::setEnumerationCache(JSPropertyNameIterator* enumerationCache)
+ {
+ ASSERT(!isDictionary());
+ m_enumerationCache = enumerationCache;
+ }
+
+ inline void Structure::clearEnumerationCache(JSPropertyNameIterator* enumerationCache)
+ {
+ m_enumerationCache.clear(enumerationCache);
+ }
+
+ inline JSPropertyNameIterator* Structure::enumerationCache()
+ {
+ return m_enumerationCache.get();
+ }
} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSString.h b/JavaScriptCore/runtime/JSString.h
index af03025..cff8e3a 100644
--- a/JavaScriptCore/runtime/JSString.h
+++ b/JavaScriptCore/runtime/JSString.h
@@ -283,8 +283,9 @@ namespace JSC {
}
const UString tryGetValue() const
{
- if (isRope())
- UString();
+ // If this is a rope, m_value should be null -
+ // if this is not a rope, m_value should be non-null.
+ ASSERT(isRope() == m_value.isNull());
return m_value;
}
unsigned length() { return m_stringLength; }
diff --git a/JavaScriptCore/runtime/JSStringBuilder.h b/JavaScriptCore/runtime/JSStringBuilder.h
new file mode 100644
index 0000000..2b11736
--- /dev/null
+++ b/JavaScriptCore/runtime/JSStringBuilder.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2009 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 JSStringBuilder_h
+#define JSStringBuilder_h
+
+#include "ExceptionHelpers.h"
+#include "JSString.h"
+#include "StringBuilder.h"
+
+namespace JSC {
+
+class JSStringBuilder : public StringBuilder {
+public:
+ JSValue build(ExecState* exec)
+ {
+ buffer.shrinkToFit();
+ if (!buffer.data())
+ return throwOutOfMemoryError(exec);
+ return jsString(exec, UString::adopt(buffer));
+ }
+
+private:
+ // Make attempts to call this compile error - if you only wanted a UString,
+ // Why didn't you just use a StringBuilder?! (This may change, maybe at some
+ // point in the future we'll need to start building a string not knowing whether
+ // we'll want a UString or a JSValue - but until we have this requirement,
+ // block this).
+ UString build()
+ {
+ ASSERT_NOT_REACHED();
+ return StringBuilder::build();
+ }
+};
+
+template<typename StringType1, typename StringType2>
+inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2)
+{
+ PassRefPtr<UStringImpl> result = tryMakeString(string1, string2);
+ if (!result)
+ return throwOutOfMemoryError(exec);
+ return jsNontrivialString(exec, result);
+}
+
+template<typename StringType1, typename StringType2, typename StringType3>
+inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3)
+{
+ PassRefPtr<UStringImpl> result = tryMakeString(string1, string2, string3);
+ if (!result)
+ return throwOutOfMemoryError(exec);
+ return jsNontrivialString(exec, result);
+}
+
+template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
+inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
+{
+ PassRefPtr<UStringImpl> result = tryMakeString(string1, string2, string3, string4);
+ if (!result)
+ return throwOutOfMemoryError(exec);
+ return jsNontrivialString(exec, result);
+}
+
+template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
+inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
+{
+ PassRefPtr<UStringImpl> result = tryMakeString(string1, string2, string3, string4, string5);
+ if (!result)
+ return throwOutOfMemoryError(exec);
+ return jsNontrivialString(exec, result);
+}
+
+template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
+inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
+{
+ PassRefPtr<UStringImpl> result = tryMakeString(string1, string2, string3, string4, string5, string6);
+ if (!result)
+ return throwOutOfMemoryError(exec);
+ return jsNontrivialString(exec, result);
+}
+
+}
+
+#endif
diff --git a/JavaScriptCore/runtime/JSValue.cpp b/JavaScriptCore/runtime/JSValue.cpp
index 699c1cd..502312c 100644
--- a/JavaScriptCore/runtime/JSValue.cpp
+++ b/JavaScriptCore/runtime/JSValue.cpp
@@ -174,7 +174,11 @@ uint32_t toUInt32SlowCase(double d, bool& ok)
NEVER_INLINE double nonInlineNaN()
{
+#if OS(SYMBIAN)
+ return nanval();
+#else
return std::numeric_limits<double>::quiet_NaN();
+#endif
}
} // namespace JSC
diff --git a/JavaScriptCore/runtime/LiteralParser.cpp b/JavaScriptCore/runtime/LiteralParser.cpp
index aa1e5ed..cc33bae 100644
--- a/JavaScriptCore/runtime/LiteralParser.cpp
+++ b/JavaScriptCore/runtime/LiteralParser.cpp
@@ -200,7 +200,7 @@ template <LiteralParser::ParserMode mode> inline LiteralParser::TokenType Litera
if (m_ptr >= m_end || *m_ptr != '"')
return TokError;
- token.stringToken = builder.release();
+ token.stringToken = builder.build();
token.type = TokString;
token.end = ++m_ptr;
return TokString;
diff --git a/JavaScriptCore/runtime/NumberPrototype.cpp b/JavaScriptCore/runtime/NumberPrototype.cpp
index 67210fa..fa32b86 100644
--- a/JavaScriptCore/runtime/NumberPrototype.cpp
+++ b/JavaScriptCore/runtime/NumberPrototype.cpp
@@ -25,6 +25,7 @@
#include "Error.h"
#include "JSFunction.h"
#include "JSString.h"
+#include "JSStringBuilder.h"
#include "Operations.h"
#include "PrototypeFunction.h"
#include "StringBuilder.h"
@@ -94,7 +95,7 @@ static UString integerPartNoExp(double d)
builder.append((const char*)(buf.data()));
}
- return builder.release();
+ return builder.build();
}
static UString charSequence(char c, int count)
@@ -262,7 +263,7 @@ JSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState* exec, JSObject*, JSValue
for (int i = 0; i < f + 1 - k; i++)
z.append('0');
z.append(m);
- m = z.release();
+ m = z.build();
k = f + 1;
ASSERT(k == m.size());
}
@@ -432,8 +433,8 @@ JSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec, JSObject*, JSV
if (m.size() > 1)
m = makeString(m.substr(0, 1), ".", m.substr(1));
if (e >= 0)
- return jsNontrivialString(exec, makeString(s, m, "e+", UString::from(e)));
- return jsNontrivialString(exec, makeString(s, m, "e-", UString::from(-e)));
+ return jsMakeNontrivialString(exec, s, m, "e+", UString::from(e));
+ return jsMakeNontrivialString(exec, s, m, "e-", UString::from(-e));
}
} else {
m = charSequence('0', precision);
@@ -447,7 +448,7 @@ JSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec, JSObject*, JSV
return jsString(exec, makeString(s, m.substr(0, e + 1), ".", m.substr(e + 1)));
return jsString(exec, makeString(s, m));
}
- return jsNontrivialString(exec, makeString(s, "0.", charSequence('0', -(e + 1)), m));
+ return jsMakeNontrivialString(exec, s, "0.", charSequence('0', -(e + 1)), m);
}
} // namespace JSC
diff --git a/JavaScriptCore/runtime/ObjectPrototype.cpp b/JavaScriptCore/runtime/ObjectPrototype.cpp
index 3065c6d..c32a007 100644
--- a/JavaScriptCore/runtime/ObjectPrototype.cpp
+++ b/JavaScriptCore/runtime/ObjectPrototype.cpp
@@ -24,6 +24,7 @@
#include "Error.h"
#include "JSFunction.h"
#include "JSString.h"
+#include "JSStringBuilder.h"
#include "PrototypeFunction.h"
namespace JSC {
@@ -148,7 +149,7 @@ JSValue JSC_HOST_CALL objectProtoFuncToLocaleString(ExecState* exec, JSObject*,
JSValue JSC_HOST_CALL objectProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
- return jsNontrivialString(exec, makeString("[object ", thisValue.toThisObject(exec)->className(), "]"));
+ return jsMakeNontrivialString(exec, "[object ", thisValue.toThisObject(exec)->className(), "]");
}
} // namespace JSC
diff --git a/JavaScriptCore/runtime/Operations.cpp b/JavaScriptCore/runtime/Operations.cpp
index 0e1887c..cf236bf 100644
--- a/JavaScriptCore/runtime/Operations.cpp
+++ b/JavaScriptCore/runtime/Operations.cpp
@@ -41,13 +41,6 @@ bool JSValue::strictEqualSlowCase(ExecState* exec, JSValue v1, JSValue v2)
return strictEqualSlowCaseInline(exec, v1, v2);
}
-NEVER_INLINE JSValue throwOutOfMemoryError(ExecState* exec)
-{
- JSObject* error = Error::create(exec, GeneralError, "Out of memory");
- exec->setException(error);
- return error;
-}
-
NEVER_INLINE JSValue jsAddSlowCase(CallFrame* callFrame, JSValue v1, JSValue v2)
{
// exception for the Date exception in defaultValue()
diff --git a/JavaScriptCore/runtime/Operations.h b/JavaScriptCore/runtime/Operations.h
index c3aa0fa..9b27074 100644
--- a/JavaScriptCore/runtime/Operations.h
+++ b/JavaScriptCore/runtime/Operations.h
@@ -22,6 +22,7 @@
#ifndef Operations_h
#define Operations_h
+#include "ExceptionHelpers.h"
#include "Interpreter.h"
#include "JSImmediate.h"
#include "JSNumberCell.h"
@@ -29,7 +30,6 @@
namespace JSC {
- NEVER_INLINE JSValue throwOutOfMemoryError(ExecState*);
NEVER_INLINE JSValue jsAddSlowCase(CallFrame*, JSValue, JSValue);
JSValue jsTypeStringForValue(CallFrame*, JSValue);
bool jsIsObjectType(JSValue);
diff --git a/JavaScriptCore/runtime/PropertyNameArray.cpp b/JavaScriptCore/runtime/PropertyNameArray.cpp
index 5108272..4937b7c 100644
--- a/JavaScriptCore/runtime/PropertyNameArray.cpp
+++ b/JavaScriptCore/runtime/PropertyNameArray.cpp
@@ -30,7 +30,7 @@ static const size_t setThreshold = 20;
void PropertyNameArray::add(UString::Rep* identifier)
{
- ASSERT(identifier == &UString::Rep::null() || identifier == &UString::Rep::empty() || identifier->isIdentifier());
+ ASSERT(identifier == &UString::Rep::empty() || identifier->isIdentifier());
size_t size = m_data->propertyNameVector().size();
if (size < setThreshold) {
diff --git a/JavaScriptCore/runtime/RegExpPrototype.cpp b/JavaScriptCore/runtime/RegExpPrototype.cpp
index 5f9d357..dd5fe02 100644
--- a/JavaScriptCore/runtime/RegExpPrototype.cpp
+++ b/JavaScriptCore/runtime/RegExpPrototype.cpp
@@ -27,6 +27,7 @@
#include "JSFunction.h"
#include "JSObject.h"
#include "JSString.h"
+#include "JSStringBuilder.h"
#include "JSValue.h"
#include "ObjectPrototype.h"
#include "PrototypeFunction.h"
@@ -116,7 +117,7 @@ JSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState* exec, JSObject*, JSValu
postfix[index] = 'm';
UString source = asRegExpObject(thisValue)->get(exec, exec->propertyNames().source).toString(exec);
// If source is empty, use "/(?:)/" to avoid colliding with comment syntax
- return jsNontrivialString(exec, makeString("/", source.size() ? source : UString("(?:)"), postfix));
+ return jsMakeNontrivialString(exec, "/", source.size() ? source : UString("(?:)"), postfix);
}
} // namespace JSC
diff --git a/JavaScriptCore/runtime/SmallStrings.cpp b/JavaScriptCore/runtime/SmallStrings.cpp
index ac71735..d9d4377 100644
--- a/JavaScriptCore/runtime/SmallStrings.cpp
+++ b/JavaScriptCore/runtime/SmallStrings.cpp
@@ -34,6 +34,11 @@
namespace JSC {
static const unsigned numCharactersToStore = 0x100;
+static inline bool isMarked(JSString* string)
+{
+ return string && Heap::isCellMarked(string);
+}
+
class SmallStringsStorage : public Noncopyable {
public:
SmallStringsStorage();
@@ -55,13 +60,9 @@ SmallStringsStorage::SmallStringsStorage()
}
SmallStrings::SmallStrings()
- : m_emptyString(0)
- , m_storage(0)
{
COMPILE_ASSERT(numCharactersToStore == sizeof(m_singleCharacterStrings) / sizeof(m_singleCharacterStrings[0]), IsNumCharactersConstInSyncWithClassUsage);
-
- for (unsigned i = 0; i < numCharactersToStore; ++i)
- m_singleCharacterStrings[i] = 0;
+ clear();
}
SmallStrings::~SmallStrings()
@@ -70,6 +71,25 @@ SmallStrings::~SmallStrings()
void SmallStrings::markChildren(MarkStack& markStack)
{
+ /*
+ Our hypothesis is that small strings are very common. So, we cache them
+ to avoid GC churn. However, in cases where this hypothesis turns out to
+ be false -- including the degenerate case where all JavaScript execution
+ has terminated -- we don't want to waste memory.
+
+ To test our hypothesis, we check if any small string has been marked. If
+ so, it's probably reasonable to mark the rest. If not, we clear the cache.
+ */
+
+ bool isAnyStringMarked = isMarked(m_emptyString);
+ for (unsigned i = 0; i < numCharactersToStore && !isAnyStringMarked; ++i)
+ isAnyStringMarked |= isMarked(m_singleCharacterStrings[i]);
+
+ if (!isAnyStringMarked) {
+ clear();
+ return;
+ }
+
if (m_emptyString)
markStack.append(m_emptyString);
for (unsigned i = 0; i < numCharactersToStore; ++i) {
@@ -78,6 +98,13 @@ void SmallStrings::markChildren(MarkStack& markStack)
}
}
+void SmallStrings::clear()
+{
+ m_emptyString = 0;
+ for (unsigned i = 0; i < numCharactersToStore; ++i)
+ m_singleCharacterStrings[i] = 0;
+}
+
unsigned SmallStrings::count() const
{
unsigned count = 0;
diff --git a/JavaScriptCore/runtime/SmallStrings.h b/JavaScriptCore/runtime/SmallStrings.h
index efecbb0..cc11d0a 100644
--- a/JavaScriptCore/runtime/SmallStrings.h
+++ b/JavaScriptCore/runtime/SmallStrings.h
@@ -57,6 +57,7 @@ namespace JSC {
UString::Rep* singleCharacterStringRep(unsigned char character);
void markChildren(MarkStack&);
+ void clear();
unsigned count() const;
diff --git a/JavaScriptCore/runtime/StringBuilder.h b/JavaScriptCore/runtime/StringBuilder.h
index 8e18d37..27dbbd7 100644
--- a/JavaScriptCore/runtime/StringBuilder.h
+++ b/JavaScriptCore/runtime/StringBuilder.h
@@ -39,7 +39,7 @@ public:
void append(const char* str)
{
- buffer.append(str, strlen(str));
+ append(str, strlen(str));
}
void append(const char* str, size_t len)
@@ -66,13 +66,15 @@ public:
UChar operator[](size_t i) const { return buffer.at(i); }
- UString release()
+ UString build()
{
buffer.shrinkToFit();
+ if (buffer.size() && !buffer.data())
+ CRASH();
return UString::adopt(buffer);
}
-private:
+protected:
Vector<UChar, 64> buffer;
};
diff --git a/JavaScriptCore/runtime/StringPrototype.cpp b/JavaScriptCore/runtime/StringPrototype.cpp
index d002e07..8c014ec 100644
--- a/JavaScriptCore/runtime/StringPrototype.cpp
+++ b/JavaScriptCore/runtime/StringPrototype.cpp
@@ -28,6 +28,7 @@
#include "JSGlobalObjectFunctions.h"
#include "JSArray.h"
#include "JSFunction.h"
+#include "JSStringBuilder.h"
#include "ObjectPrototype.h"
#include "Operations.h"
#include "PropertyNameArray.h"
@@ -227,6 +228,86 @@ static inline int localeCompare(const UString& a, const UString& b)
return Collator::userDefault()->collate(reinterpret_cast<const ::UChar*>(a.data()), a.size(), reinterpret_cast<const ::UChar*>(b.data()), b.size());
}
+struct StringRange {
+public:
+ StringRange(int pos, int len)
+ : position(pos)
+ , length(len)
+ {
+ }
+
+ StringRange()
+ {
+ }
+
+ int position;
+ int length;
+};
+
+JSValue jsSpliceSubstringsWithSeparators(ExecState* exec, JSString* sourceVal, const UString& source, const StringRange* substringRanges, int rangeCount, const UString* separators, int separatorCount);
+JSValue jsSpliceSubstringsWithSeparators(ExecState* exec, JSString* sourceVal, const UString& source, const StringRange* substringRanges, int rangeCount, const UString* separators, int separatorCount)
+{
+ if (rangeCount == 1 && separatorCount == 0) {
+ int sourceSize = source.size();
+ int position = substringRanges[0].position;
+ int length = substringRanges[0].length;
+ if (position <= 0 && length >= sourceSize)
+ return sourceVal;
+ // We could call UString::substr, but this would result in redundant checks
+ return jsString(exec, UStringImpl::create(source.rep(), max(0, position), min(sourceSize, length)));
+ }
+
+ int totalLength = 0;
+ for (int i = 0; i < rangeCount; i++)
+ totalLength += substringRanges[i].length;
+ for (int i = 0; i < separatorCount; i++)
+ totalLength += separators[i].size();
+
+ if (totalLength == 0)
+ return jsString(exec, "");
+
+ UChar* buffer;
+ PassRefPtr<UStringImpl> impl = UStringImpl::tryCreateUninitialized(totalLength, buffer);
+ if (!impl)
+ return throwOutOfMemoryError(exec);
+
+ int maxCount = max(rangeCount, separatorCount);
+ int bufferPos = 0;
+ for (int i = 0; i < maxCount; i++) {
+ if (i < rangeCount) {
+ UStringImpl::copyChars(buffer + bufferPos, source.data() + substringRanges[i].position, substringRanges[i].length);
+ bufferPos += substringRanges[i].length;
+ }
+ if (i < separatorCount) {
+ UStringImpl::copyChars(buffer + bufferPos, separators[i].data(), separators[i].size());
+ bufferPos += separators[i].size();
+ }
+ }
+
+ return jsString(exec, impl);
+}
+
+JSValue jsReplaceRange(ExecState* exec, const UString& source, int rangeStart, int rangeLength, const UString& replacement);
+JSValue jsReplaceRange(ExecState* exec, const UString& source, int rangeStart, int rangeLength, const UString& replacement)
+{
+ int replacementLength = replacement.size();
+ int totalLength = source.size() - rangeLength + replacementLength;
+ if (totalLength == 0)
+ return jsString(exec, "");
+
+ UChar* buffer;
+ PassRefPtr<UStringImpl> impl = UStringImpl::tryCreateUninitialized(totalLength, buffer);
+ if (!impl)
+ return throwOutOfMemoryError(exec);
+
+ UStringImpl::copyChars(buffer, source.data(), rangeStart);
+ UStringImpl::copyChars(buffer + rangeStart, replacement.data(), replacementLength);
+ int rangeEnd = rangeStart + rangeLength;
+ UStringImpl::copyChars(buffer + rangeStart + replacementLength, source.data() + rangeEnd, source.size() - rangeEnd);
+
+ return jsString(exec, impl);
+}
+
JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
JSString* sourceVal = thisValue.toThisJSString(exec);
@@ -250,7 +331,7 @@ JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue
int lastIndex = 0;
int startPosition = 0;
- Vector<UString::Range, 16> sourceRanges;
+ Vector<StringRange, 16> sourceRanges;
Vector<UString, 16> replacements;
// This is either a loop (if global is set) or a one-way (if not).
@@ -269,7 +350,7 @@ JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue
if (matchIndex < 0)
break;
- sourceRanges.append(UString::Range(lastIndex, matchIndex - lastIndex));
+ sourceRanges.append(StringRange(lastIndex, matchIndex - lastIndex));
int completeMatchStart = ovector[0];
unsigned i = 0;
@@ -311,7 +392,7 @@ JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue
if (matchIndex < 0)
break;
- sourceRanges.append(UString::Range(lastIndex, matchIndex - lastIndex));
+ sourceRanges.append(StringRange(lastIndex, matchIndex - lastIndex));
if (callType != CallTypeNone) {
int completeMatchStart = ovector[0];
@@ -352,10 +433,9 @@ JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue
return sourceVal;
if (lastIndex < source.size())
- sourceRanges.append(UString::Range(lastIndex, source.size() - lastIndex));
+ sourceRanges.append(StringRange(lastIndex, source.size() - lastIndex));
- return jsString(exec, source.spliceSubstringsWithSeparators(sourceRanges.data(), sourceRanges.size(),
- replacements.data(), replacements.size()));
+ return jsSpliceSubstringsWithSeparators(exec, sourceVal, source, sourceRanges.data(), sourceRanges.size(), replacements.data(), replacements.size());
}
// Not a regular expression, so treat the pattern as a string.
@@ -377,7 +457,7 @@ JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue
}
int ovector[2] = { matchPos, matchPos + matchLen };
- return jsString(exec, source.replaceRange(matchPos, matchLen, substituteBackreferences(replacementString, source, ovector, 0)));
+ return jsReplaceRange(exec, source, matchPos, matchLen, substituteBackreferences(replacementString, source, ovector, 0));
}
JSValue JSC_HOST_CALL stringProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -789,62 +869,62 @@ JSValue JSC_HOST_CALL stringProtoFuncLocaleCompare(ExecState* exec, JSObject*, J
JSValue JSC_HOST_CALL stringProtoFuncBig(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
UString s = thisValue.toThisString(exec);
- return jsNontrivialString(exec, makeString("<big>", s, "</big>"));
+ return jsMakeNontrivialString(exec, "<big>", s, "</big>");
}
JSValue JSC_HOST_CALL stringProtoFuncSmall(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
UString s = thisValue.toThisString(exec);
- return jsNontrivialString(exec, makeString("<small>", s, "</small>"));
+ return jsMakeNontrivialString(exec, "<small>", s, "</small>");
}
JSValue JSC_HOST_CALL stringProtoFuncBlink(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
UString s = thisValue.toThisString(exec);
- return jsNontrivialString(exec, makeString("<blink>", s, "</blink>"));
+ return jsMakeNontrivialString(exec, "<blink>", s, "</blink>");
}
JSValue JSC_HOST_CALL stringProtoFuncBold(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
UString s = thisValue.toThisString(exec);
- return jsNontrivialString(exec, makeString("<b>", s, "</b>"));
+ return jsMakeNontrivialString(exec, "<b>", s, "</b>");
}
JSValue JSC_HOST_CALL stringProtoFuncFixed(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
UString s = thisValue.toThisString(exec);
- return jsString(exec, makeString("<tt>", s, "</tt>"));
+ return jsMakeNontrivialString(exec, "<tt>", s, "</tt>");
}
JSValue JSC_HOST_CALL stringProtoFuncItalics(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
UString s = thisValue.toThisString(exec);
- return jsNontrivialString(exec, makeString("<i>", s, "</i>"));
+ return jsMakeNontrivialString(exec, "<i>", s, "</i>");
}
JSValue JSC_HOST_CALL stringProtoFuncStrike(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
UString s = thisValue.toThisString(exec);
- return jsNontrivialString(exec, makeString("<strike>", s, "</strike>"));
+ return jsMakeNontrivialString(exec, "<strike>", s, "</strike>");
}
JSValue JSC_HOST_CALL stringProtoFuncSub(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
UString s = thisValue.toThisString(exec);
- return jsNontrivialString(exec, makeString("<sub>", s, "</sub>"));
+ return jsMakeNontrivialString(exec, "<sub>", s, "</sub>");
}
JSValue JSC_HOST_CALL stringProtoFuncSup(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
UString s = thisValue.toThisString(exec);
- return jsNontrivialString(exec, makeString("<sup>", s, "</sup>"));
+ return jsMakeNontrivialString(exec, "<sup>", s, "</sup>");
}
JSValue JSC_HOST_CALL stringProtoFuncFontcolor(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
UString s = thisValue.toThisString(exec);
JSValue a0 = args.at(0);
- return jsNontrivialString(exec, makeString("<font color=\"", a0.toString(exec), "\">", s, "</font>"));
+ return jsMakeNontrivialString(exec, "<font color=\"", a0.toString(exec), "\">", s, "</font>");
}
JSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
@@ -886,14 +966,14 @@ JSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValu
return jsNontrivialString(exec, impl);
}
- return jsNontrivialString(exec, makeString("<font size=\"", a0.toString(exec), "\">", s, "</font>"));
+ return jsMakeNontrivialString(exec, "<font size=\"", a0.toString(exec), "\">", s, "</font>");
}
JSValue JSC_HOST_CALL stringProtoFuncAnchor(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
UString s = thisValue.toThisString(exec);
JSValue a0 = args.at(0);
- return jsNontrivialString(exec, makeString("<a name=\"", a0.toString(exec), "\">", s, "</a>"));
+ return jsMakeNontrivialString(exec, "<a name=\"", a0.toString(exec), "\">", s, "</a>");
}
JSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
diff --git a/JavaScriptCore/runtime/Structure.h b/JavaScriptCore/runtime/Structure.h
index 1353a5a..95cf94c 100644
--- a/JavaScriptCore/runtime/Structure.h
+++ b/JavaScriptCore/runtime/Structure.h
@@ -36,6 +36,7 @@
#include "StructureTransitionTable.h"
#include "JSTypeInfo.h"
#include "UString.h"
+#include "WeakGCPtr.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
@@ -101,7 +102,7 @@ namespace JSC {
void growPropertyStorageCapacity();
unsigned propertyStorageCapacity() const { return m_propertyStorageCapacity; }
- unsigned propertyStorageSize() const { return m_anonymousSlotCount + (m_propertyTable ? m_propertyTable->keyCount + (m_propertyTable->deletedOffsets ? m_propertyTable->deletedOffsets->size() : 0) : m_offset + 1); }
+ unsigned propertyStorageSize() const { return m_anonymousSlotCount + (m_propertyTable ? m_propertyTable->keyCount + (m_propertyTable->deletedOffsets ? m_propertyTable->deletedOffsets->size() : 0) : static_cast<unsigned>(m_offset + 1)); }
bool isUsingInlineStorage() const;
size_t get(const Identifier& propertyName);
@@ -135,7 +136,8 @@ namespace JSC {
void disableSpecificFunctionTracking() { m_specificFunctionThrashCount = maxSpecificFunctionThrashCount; }
void setEnumerationCache(JSPropertyNameIterator* enumerationCache); // Defined in JSPropertyNameIterator.h.
- JSPropertyNameIterator* enumerationCache() { return m_enumerationCache.get(); }
+ void clearEnumerationCache(JSPropertyNameIterator* enumerationCache); // Defined in JSPropertyNameIterator.h.
+ JSPropertyNameIterator* enumerationCache(); // Defined in JSPropertyNameIterator.h.
void getPropertyNames(PropertyNameArray&, EnumerationMode mode);
private:
@@ -199,7 +201,7 @@ namespace JSC {
StructureTransitionTable table;
- ProtectedPtr<JSPropertyNameIterator> m_enumerationCache;
+ WeakGCPtr<JSPropertyNameIterator> m_enumerationCache;
PropertyMapHashTable* m_propertyTable;
diff --git a/JavaScriptCore/runtime/UString.cpp b/JavaScriptCore/runtime/UString.cpp
index e75a05c..4a89a23 100644
--- a/JavaScriptCore/runtime/UString.cpp
+++ b/JavaScriptCore/runtime/UString.cpp
@@ -53,7 +53,7 @@ using namespace WTF::Unicode;
using namespace std;
namespace JSC {
-
+
extern const double NaN;
extern const double Inf;
@@ -146,95 +146,46 @@ bool operator==(const CString& c1, const CString& c2)
return len == c2.size() && (len == 0 || memcmp(c1.c_str(), c2.c_str(), len) == 0);
}
-// These static strings are immutable, except for rc, whose initial value is chosen to
+// These static strings are immutable, except for rc, whose initial value is chosen to
// reduce the possibility of it becoming zero due to ref/deref not being thread-safe.
static UChar sharedEmptyChar;
-UStringImpl* UStringImpl::s_null;
UStringImpl* UStringImpl::s_empty;
-UString* UString::nullUString;
+
+UString::Rep* UString::s_nullRep;
+UString* UString::s_nullUString;
void initializeUString()
{
- UStringImpl::s_null = new UStringImpl(0, 0, UStringImpl::ConstructStaticString);
UStringImpl::s_empty = new UStringImpl(&sharedEmptyChar, 0, UStringImpl::ConstructStaticString);
- UString::nullUString = new UString;
-}
-
-static PassRefPtr<UString::Rep> createRep(const char* c)
-{
- if (!c)
- return &UString::Rep::null();
-
- if (!c[0])
- return &UString::Rep::empty();
- size_t length = strlen(c);
- UChar* d;
- PassRefPtr<UStringImpl> result = UStringImpl::tryCreateUninitialized(length, d);
- if (!result)
- return &UString::Rep::null();
-
- for (size_t i = 0; i < length; i++)
- d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend
- return result;
-}
-
-static inline PassRefPtr<UString::Rep> createRep(const char* c, int length)
-{
- if (!c)
- return &UString::Rep::null();
-
- if (!length)
- return &UString::Rep::empty();
-
- UChar* d;
- PassRefPtr<UStringImpl> result = UStringImpl::tryCreateUninitialized(length, d);
- if (!result)
- return &UString::Rep::null();
-
- for (int i = 0; i < length; i++)
- d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend
- return result;
+ UString::s_nullRep = new UStringImpl(0, 0, UStringImpl::ConstructStaticString);
+ UString::s_nullUString = new UString;
}
UString::UString(const char* c)
- : m_rep(createRep(c))
+ : m_rep(Rep::create(c))
{
}
UString::UString(const char* c, int length)
- : m_rep(createRep(c, length))
+ : m_rep(Rep::create(c, length))
{
}
UString::UString(const UChar* c, int length)
{
- if (length == 0)
+ if (length == 0)
m_rep = &Rep::empty();
else
m_rep = Rep::create(c, length);
}
-UString UString::createFromUTF8(const char* string)
-{
- if (!string)
- return null();
-
- size_t length = strlen(string);
- Vector<UChar, 1024> buffer(length);
- UChar* p = buffer.data();
- if (conversionOK != convertUTF8ToUTF16(&string, string + length, &p, p + length))
- return null();
-
- return UString(buffer.data(), p - buffer.data());
-}
-
UString UString::from(int i)
{
UChar buf[1 + sizeof(i) * 3];
UChar* end = buf + sizeof(buf) / sizeof(UChar);
UChar* p = end;
-
+
if (i == 0)
*--p = '0';
else if (i == INT_MIN) {
@@ -296,7 +247,7 @@ UString UString::from(unsigned int u)
UChar buf[sizeof(u) * 3];
UChar* end = buf + sizeof(buf) / sizeof(UChar);
UChar* p = end;
-
+
if (u == 0)
*--p = '0';
else {
@@ -305,7 +256,7 @@ UString UString::from(unsigned int u)
u /= 10;
}
}
-
+
return UString(p, static_cast<int>(end - p));
}
@@ -346,71 +297,6 @@ UString UString::from(double d)
return UString(buffer, length);
}
-UString UString::spliceSubstringsWithSeparators(const Range* substringRanges, int rangeCount, const UString* separators, int separatorCount) const
-{
- m_rep->checkConsistency();
-
- if (rangeCount == 1 && separatorCount == 0) {
- int thisSize = size();
- int position = substringRanges[0].position;
- int length = substringRanges[0].length;
- if (position <= 0 && length >= thisSize)
- return *this;
- return UString::Rep::create(m_rep, max(0, position), min(thisSize, length));
- }
-
- int totalLength = 0;
- for (int i = 0; i < rangeCount; i++)
- totalLength += substringRanges[i].length;
- for (int i = 0; i < separatorCount; i++)
- totalLength += separators[i].size();
-
- if (totalLength == 0)
- return "";
-
- UChar* buffer;
- PassRefPtr<Rep> rep = Rep::tryCreateUninitialized(totalLength, buffer);
- if (!rep)
- return null();
-
- int maxCount = max(rangeCount, separatorCount);
- int bufferPos = 0;
- for (int i = 0; i < maxCount; i++) {
- if (i < rangeCount) {
- UStringImpl::copyChars(buffer + bufferPos, data() + substringRanges[i].position, substringRanges[i].length);
- bufferPos += substringRanges[i].length;
- }
- if (i < separatorCount) {
- UStringImpl::copyChars(buffer + bufferPos, separators[i].data(), separators[i].size());
- bufferPos += separators[i].size();
- }
- }
-
- return rep;
-}
-
-UString UString::replaceRange(int rangeStart, int rangeLength, const UString& replacement) const
-{
- m_rep->checkConsistency();
-
- int replacementLength = replacement.size();
- int totalLength = size() - rangeLength + replacementLength;
- if (totalLength == 0)
- return "";
-
- UChar* buffer;
- PassRefPtr<Rep> rep = Rep::tryCreateUninitialized(totalLength, buffer);
- if (!rep)
- return null();
-
- UStringImpl::copyChars(buffer, data(), rangeStart);
- UStringImpl::copyChars(buffer + rangeStart, replacement.data(), replacementLength);
- int rangeEnd = rangeStart + rangeLength;
- UStringImpl::copyChars(buffer + rangeStart + replacementLength, data() + rangeEnd, size() - rangeEnd);
-
- return rep;
-}
-
bool UString::getCString(CStringBuffer& buffer) const
{
int length = size();
@@ -456,30 +342,6 @@ char* UString::ascii() const
return asciiBuffer;
}
-UString& UString::operator=(const char* c)
-{
- if (!c) {
- m_rep = &Rep::null();
- return *this;
- }
-
- if (!c[0]) {
- m_rep = &Rep::empty();
- return *this;
- }
-
- int l = static_cast<int>(strlen(c));
- UChar* d = 0;
- m_rep = Rep::tryCreateUninitialized(l, d);
- if (m_rep) {
- for (int i = 0; i < l; i++)
- d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend
- } else
- makeNull();
-
- return *this;
-}
-
bool UString::is8Bit() const
{
const UChar* u = data();
@@ -721,7 +583,7 @@ int UString::find(UChar ch, int pos) const
if (*c == ch)
return static_cast<int>(c - data());
}
-
+
return -1;
}
@@ -888,16 +750,4 @@ CString UString::UTF8String(bool strict) const
return CString(buffer.data(), p - buffer.data());
}
-// For use in error handling code paths -- having this not be inlined helps avoid PIC branches to fetch the global on Mac OS X.
-NEVER_INLINE void UString::makeNull()
-{
- m_rep = &Rep::null();
-}
-
-// For use in error handling code paths -- having this not be inlined helps avoid PIC branches to fetch the global on Mac OS X.
-NEVER_INLINE UString::Rep* UString::nullRep()
-{
- return &Rep::null();
-}
-
} // namespace JSC
diff --git a/JavaScriptCore/runtime/UString.h b/JavaScriptCore/runtime/UString.h
index 0c13689..7d9ec49 100644
--- a/JavaScriptCore/runtime/UString.h
+++ b/JavaScriptCore/runtime/UString.h
@@ -81,7 +81,6 @@ namespace JSC {
typedef UStringImpl Rep;
public:
- // UString constructors passed char*s assume ISO Latin-1 encoding; for UTF8 use 'createFromUTF8', below.
UString();
UString(const char*); // Constructor for null-terminated string.
UString(const char*, int length);
@@ -109,34 +108,12 @@ namespace JSC {
return Rep::adopt(vector);
}
- static UString createFromUTF8(const char*);
-
static UString from(int);
static UString from(long long);
static UString from(unsigned int);
static UString from(long);
static UString from(double);
- struct Range {
- public:
- Range(int pos, int len)
- : position(pos)
- , length(len)
- {
- }
-
- Range()
- {
- }
-
- int position;
- int length;
- };
-
- UString spliceSubstringsWithSeparators(const Range* substringRanges, int rangeCount, const UString* separators, int separatorCount) const;
-
- UString replaceRange(int rangeStart, int RangeEnd, const UString& replacement) const;
-
bool getCString(CStringBuffer&) const;
// NOTE: This method should only be used for *debugging* purposes as it
@@ -153,11 +130,9 @@ namespace JSC {
*/
CString UTF8String(bool strict = false) const;
- UString& operator=(const char*c);
-
const UChar* data() const { return m_rep->data(); }
- bool isNull() const { return m_rep == &Rep::null(); }
+ bool isNull() const { return m_rep == s_nullRep; }
bool isEmpty() const { return !m_rep->size(); }
bool is8Bit() const;
@@ -183,10 +158,9 @@ namespace JSC {
UString substr(int pos = 0, int len = -1) const;
- static const UString& null() { return *nullUString; }
+ static const UString& null() { return *s_nullUString; }
Rep* rep() const { return m_rep.get(); }
- static Rep* nullRep();
UString(PassRefPtr<Rep> r)
: m_rep(r)
@@ -197,10 +171,10 @@ namespace JSC {
size_t cost() const { return m_rep->cost(); }
private:
- void makeNull();
-
RefPtr<Rep> m_rep;
- static UString* nullUString;
+
+ JS_EXPORTDATA static Rep* s_nullRep;
+ static UString* s_nullUString;
friend void initializeUString();
friend bool operator==(const UString&, const UString&);
@@ -255,7 +229,7 @@ namespace JSC {
int compare(const UString&, const UString&);
inline UString::UString()
- : m_rep(&Rep::null())
+ : m_rep(s_nullRep)
{
}
@@ -354,7 +328,7 @@ namespace JSC {
};
template<typename StringType1, typename StringType2>
- UString makeString(StringType1 string1, StringType2 string2)
+ PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2)
{
StringTypeAdapter<StringType1> adapter1(string1);
StringTypeAdapter<StringType2> adapter2(string2);
@@ -363,7 +337,7 @@ namespace JSC {
unsigned length = adapter1.length() + adapter2.length();
PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
if (!resultImpl)
- return UString();
+ return 0;
UChar* result = buffer;
adapter1.writeTo(result);
@@ -374,7 +348,7 @@ namespace JSC {
}
template<typename StringType1, typename StringType2, typename StringType3>
- UString makeString(StringType1 string1, StringType2 string2, StringType3 string3)
+ PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3)
{
StringTypeAdapter<StringType1> adapter1(string1);
StringTypeAdapter<StringType2> adapter2(string2);
@@ -384,7 +358,7 @@ namespace JSC {
unsigned length = adapter1.length() + adapter2.length() + adapter3.length();
PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
if (!resultImpl)
- return UString();
+ return 0;
UChar* result = buffer;
adapter1.writeTo(result);
@@ -397,7 +371,7 @@ namespace JSC {
}
template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
- UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
+ PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
{
StringTypeAdapter<StringType1> adapter1(string1);
StringTypeAdapter<StringType2> adapter2(string2);
@@ -408,7 +382,7 @@ namespace JSC {
unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length();
PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
if (!resultImpl)
- return UString();
+ return 0;
UChar* result = buffer;
adapter1.writeTo(result);
@@ -423,7 +397,7 @@ namespace JSC {
}
template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
- UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
+ PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
{
StringTypeAdapter<StringType1> adapter1(string1);
StringTypeAdapter<StringType2> adapter2(string2);
@@ -435,7 +409,7 @@ namespace JSC {
unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length();
PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
if (!resultImpl)
- return UString();
+ return 0;
UChar* result = buffer;
adapter1.writeTo(result);
@@ -452,7 +426,7 @@ namespace JSC {
}
template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
- UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
+ PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
{
StringTypeAdapter<StringType1> adapter1(string1);
StringTypeAdapter<StringType2> adapter2(string2);
@@ -465,7 +439,7 @@ namespace JSC {
unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length() + adapter6.length();
PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
if (!resultImpl)
- return UString();
+ return 0;
UChar* result = buffer;
adapter1.writeTo(result);
@@ -484,7 +458,7 @@ namespace JSC {
}
template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7>
- UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)
+ PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)
{
StringTypeAdapter<StringType1> adapter1(string1);
StringTypeAdapter<StringType2> adapter2(string2);
@@ -498,7 +472,7 @@ namespace JSC {
unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length() + adapter6.length() + adapter7.length();
PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
if (!resultImpl)
- return UString();
+ return 0;
UChar* result = buffer;
adapter1.writeTo(result);
@@ -519,7 +493,7 @@ namespace JSC {
}
template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8>
- UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)
+ PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)
{
StringTypeAdapter<StringType1> adapter1(string1);
StringTypeAdapter<StringType2> adapter2(string2);
@@ -534,7 +508,7 @@ namespace JSC {
unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length() + adapter6.length() + adapter7.length() + adapter8.length();
PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
if (!resultImpl)
- return UString();
+ return 0;
UChar* result = buffer;
adapter1.writeTo(result);
@@ -556,6 +530,69 @@ namespace JSC {
return resultImpl;
}
+ template<typename StringType1, typename StringType2>
+ UString makeString(StringType1 string1, StringType2 string2)
+ {
+ PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2);
+ if (!resultImpl)
+ CRASH();
+ return resultImpl;
+ }
+
+ template<typename StringType1, typename StringType2, typename StringType3>
+ UString makeString(StringType1 string1, StringType2 string2, StringType3 string3)
+ {
+ PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2, string3);
+ if (!resultImpl)
+ CRASH();
+ return resultImpl;
+ }
+
+ template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
+ UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
+ {
+ PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2, string3, string4);
+ if (!resultImpl)
+ CRASH();
+ return resultImpl;
+ }
+
+ template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
+ UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
+ {
+ PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5);
+ if (!resultImpl)
+ CRASH();
+ return resultImpl;
+ }
+
+ template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
+ UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
+ {
+ PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6);
+ if (!resultImpl)
+ CRASH();
+ return resultImpl;
+ }
+
+ template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7>
+ UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)
+ {
+ PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7);
+ if (!resultImpl)
+ CRASH();
+ return resultImpl;
+ }
+
+ template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8>
+ UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)
+ {
+ PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8);
+ if (!resultImpl)
+ CRASH();
+ return resultImpl;
+ }
+
} // namespace JSC
namespace WTF {
diff --git a/JavaScriptCore/runtime/UStringImpl.cpp b/JavaScriptCore/runtime/UStringImpl.cpp
index 4b0d1c9..9882007 100644
--- a/JavaScriptCore/runtime/UStringImpl.cpp
+++ b/JavaScriptCore/runtime/UStringImpl.cpp
@@ -34,7 +34,44 @@ using namespace WTF::Unicode;
using namespace std;
namespace JSC {
-
+
+PassRefPtr<UStringImpl> UStringImpl::create(const char* c)
+{
+ ASSERT(c);
+
+ if (!c[0])
+ return &UStringImpl::empty();
+
+ size_t length = strlen(c);
+ UChar* d;
+ PassRefPtr<UStringImpl> result = UStringImpl::createUninitialized(length, d);
+ for (size_t i = 0; i < length; i++)
+ d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend
+ return result;
+}
+
+PassRefPtr<UStringImpl> UStringImpl::create(const char* c, int length)
+{
+ ASSERT(c);
+
+ if (!length)
+ return &UStringImpl::empty();
+
+ UChar* d;
+ PassRefPtr<UStringImpl> result = UStringImpl::createUninitialized(length, d);
+ for (int i = 0; i < length; i++)
+ d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend
+ return result;
+}
+
+PassRefPtr<UStringImpl> UStringImpl::create(const UChar* buffer, int length)
+{
+ UChar* newBuffer;
+ PassRefPtr<UStringImpl> impl = createUninitialized(length, newBuffer);
+ copyChars(newBuffer, buffer, length);
+ return impl;
+}
+
SharedUChar* UStringImpl::baseSharedBuffer()
{
ASSERT((bufferOwnership() == BufferShared)
diff --git a/JavaScriptCore/runtime/UStringImpl.h b/JavaScriptCore/runtime/UStringImpl.h
index abed637..bbea0aa 100644
--- a/JavaScriptCore/runtime/UStringImpl.h
+++ b/JavaScriptCore/runtime/UStringImpl.h
@@ -87,20 +87,16 @@ public:
template<size_t inlineCapacity>
static PassRefPtr<UStringImpl> adopt(Vector<UChar, inlineCapacity>& vector)
{
- if (unsigned length = vector.size())
+ if (unsigned length = vector.size()) {
+ ASSERT(vector.data());
return adoptRef(new UStringImpl(vector.releaseBuffer(), length, BufferOwned));
+ }
return &empty();
}
- static PassRefPtr<UStringImpl> create(const UChar* buffer, int length)
- {
- UChar* newBuffer;
- if (PassRefPtr<UStringImpl> impl = tryCreateUninitialized(length, newBuffer)) {
- copyChars(newBuffer, buffer, length);
- return impl;
- }
- return &null();
- }
+ static PassRefPtr<UStringImpl> create(const char* c);
+ static PassRefPtr<UStringImpl> create(const char* c, int length);
+ static PassRefPtr<UStringImpl> create(const UChar* buffer, int length);
static PassRefPtr<UStringImpl> create(PassRefPtr<UStringImpl> rep, int offset, int length)
{
@@ -180,7 +176,6 @@ public:
static unsigned computeHash(const char* s, int length) { ASSERT(length >= 0); return WTF::stringHash(s, length); }
static unsigned computeHash(const char* s) { return WTF::stringHash(s); }
- static UStringImpl& null() { return *s_null; }
static UStringImpl& empty() { return *s_empty; }
ALWAYS_INLINE void checkConsistency() const
@@ -288,7 +283,6 @@ private:
mutable unsigned m_isIdentifier : 1;
UntypedPtrAndBitfield m_dataBuffer;
- JS_EXPORTDATA static UStringImpl* s_null;
JS_EXPORTDATA static UStringImpl* s_empty;
friend class JIT;
diff --git a/JavaScriptCore/runtime/WeakGCPtr.h b/JavaScriptCore/runtime/WeakGCPtr.h
index 8653721..3ed4645 100644
--- a/JavaScriptCore/runtime/WeakGCPtr.h
+++ b/JavaScriptCore/runtime/WeakGCPtr.h
@@ -44,7 +44,11 @@ public:
return m_ptr;
}
- void clear() { m_ptr = 0; }
+ void clear(JSCell* ptr)
+ {
+ if (ptr == m_ptr)
+ m_ptr = 0;
+ }
T& operator*() const { return *get(); }
T* operator->() const { return get(); }
diff --git a/JavaScriptCore/wscript b/JavaScriptCore/wscript
index f5a041f..7caf8b4 100644
--- a/JavaScriptCore/wscript
+++ b/JavaScriptCore/wscript
@@ -72,6 +72,8 @@ def build(bld):
full_dirs = get_dirs_for_features(jscore_dir, features=[build_port], dirs=jscore_dirs)
includes = common_includes + full_dirs
+ if sys.platform.startswith('darwin'):
+ includes.append(os.path.join(jscore_dir, 'icu'))
# 1. A simple program
jscore = bld.new_task_gen(
diff --git a/JavaScriptCore/wtf/Complex.h b/JavaScriptCore/wtf/Complex.h
new file mode 100644
index 0000000..cfd1d20
--- /dev/null
+++ b/JavaScriptCore/wtf/Complex.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2010 Google 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Complex_h
+#define Complex_h
+
+#include <complex>
+#include <wtf/MathExtras.h>
+
+namespace WebCore {
+
+typedef std::complex<double> Complex;
+
+inline Complex complexFromMagnitudePhase(double magnitude, double phase)
+{
+ return Complex(magnitude * cos(phase), magnitude * sin(phase));
+}
+
+} // namespace WebCore
+
+#endif // Complex_h
diff --git a/JavaScriptCore/wtf/FastMalloc.cpp b/JavaScriptCore/wtf/FastMalloc.cpp
index 7b14809..79d2bfb 100644
--- a/JavaScriptCore/wtf/FastMalloc.cpp
+++ b/JavaScriptCore/wtf/FastMalloc.cpp
@@ -239,8 +239,16 @@ void* fastMalloc(size_t n)
void* result = malloc(n);
#endif
- if (!result)
+ if (!result) {
+#if PLATFORM(BREWMP)
+ // The behavior of malloc(0) is implementation defined.
+ // To make sure that fastMalloc never returns 0, retry with fastMalloc(1).
+ if (!n)
+ return fastMalloc(1);
+#endif
CRASH();
+ }
+
return result;
}
@@ -279,8 +287,16 @@ void* fastCalloc(size_t n_elements, size_t element_size)
void* result = calloc(n_elements, element_size);
#endif
- if (!result)
+ if (!result) {
+#if PLATFORM(BREWMP)
+ // If either n_elements or element_size is 0, the behavior of calloc is implementation defined.
+ // To make sure that fastCalloc never returns 0, retry with fastCalloc(1, 1).
+ if (!n_elements || !element_size)
+ return fastCalloc(1, 1);
+#endif
CRASH();
+ }
+
return result;
}
diff --git a/JavaScriptCore/wtf/HashTable.h b/JavaScriptCore/wtf/HashTable.h
index f1473e3..ceb8963 100644
--- a/JavaScriptCore/wtf/HashTable.h
+++ b/JavaScriptCore/wtf/HashTable.h
@@ -24,6 +24,7 @@
#include "FastMalloc.h"
#include "HashTraits.h"
+#include "ValueCheck.h"
#include <wtf/Assertions.h>
#include <wtf/Threading.h>
@@ -1021,7 +1022,7 @@ namespace WTF {
ASSERT(entry == it.m_position);
++count;
- KeyTraits::checkValueConsistency(it->first);
+ ValueCheck<Key>::checkConsistency(it->first);
}
ASSERT(count == m_keyCount);
diff --git a/JavaScriptCore/wtf/HashTraits.h b/JavaScriptCore/wtf/HashTraits.h
index 96ecac9..c8d40f7 100644
--- a/JavaScriptCore/wtf/HashTraits.h
+++ b/JavaScriptCore/wtf/HashTraits.h
@@ -26,13 +26,6 @@
#include <utility>
#include <limits>
-// For malloc_size and _msize.
-#if OS(DARWIN)
-#include <malloc/malloc.h>
-#elif COMPILER(MSVC)
-#include <malloc.h>
-#endif
-
namespace WTF {
using std::pair;
@@ -58,7 +51,6 @@ namespace WTF {
template<typename T> struct GenericHashTraits : GenericHashTraitsBase<IsInteger<T>::value, T> {
typedef T TraitType;
static T emptyValue() { return T(); }
- static void checkValueConsistency(const T&) { }
};
template<typename T> struct HashTraits : GenericHashTraits<T> { };
@@ -87,19 +79,6 @@ namespace WTF {
static const bool needsDestruction = false;
static void constructDeletedValue(P*& slot) { slot = reinterpret_cast<P*>(-1); }
static bool isDeletedValue(P* value) { return value == reinterpret_cast<P*>(-1); }
-#if !ASSERT_DISABLED
- static void checkValueConsistency(const P* p)
- {
-#if (defined(USE_SYSTEM_MALLOC) && USE_SYSTEM_MALLOC) || !defined(NDEBUG)
-#if OS(DARWIN)
- ASSERT(malloc_size(p));
-#elif COMPILER(MSVC)
- ASSERT(_msize(const_cast<P*>(p)));
-#endif
-#endif
- HashTraits<P>::checkValueConsistency(*p);
- }
-#endif
};
template<typename P> struct HashTraits<RefPtr<P> > : GenericHashTraits<RefPtr<P> > {
diff --git a/JavaScriptCore/wtf/MathExtras.h b/JavaScriptCore/wtf/MathExtras.h
index a18949e..8666724 100644
--- a/JavaScriptCore/wtf/MathExtras.h
+++ b/JavaScriptCore/wtf/MathExtras.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 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
@@ -26,8 +26,8 @@
#ifndef WTF_MathExtras_h
#define WTF_MathExtras_h
+#include <cmath>
#include <float.h>
-#include <math.h>
#include <stdlib.h>
#if OS(SOLARIS)
@@ -186,4 +186,11 @@ inline float deg2turn(float d) { return d / 360.0f; }
inline float rad2grad(float r) { return r * 200.0f / piFloat; }
inline float grad2rad(float g) { return g * piFloat / 200.0f; }
+#if !COMPILER(MSVC) && !COMPILER(RVCT) && !OS(ANDROID) && !COMPILER(WINSCW)
+using std::isfinite;
+using std::isinf;
+using std::isnan;
+using std::signbit;
+#endif
+
#endif // #ifndef WTF_MathExtras_h
diff --git a/JavaScriptCore/wtf/PassRefPtr.h b/JavaScriptCore/wtf/PassRefPtr.h
index 36ba78e..9c6e44f 100644
--- a/JavaScriptCore/wtf/PassRefPtr.h
+++ b/JavaScriptCore/wtf/PassRefPtr.h
@@ -28,10 +28,21 @@ namespace WTF {
template<typename T> class RefPtr;
template<typename T> class PassRefPtr;
template <typename T> PassRefPtr<T> adoptRef(T*);
-
- // Remove inline for winscw compiler to prevent the compiler agressively resolving
- // T::deref(), which will fail compiling when PassRefPtr<T> is used as class member
- // or function arguments before T is defined.
+
+
+ // Remove inline for WINSCW compiler to prevent the compiler agressively resolving
+ // T::ref() and T::deref(), which will fail compiling when PassRefPtr<T> is used as
+ // a class member or function arguments before T is defined.
+ template<typename T>
+#if !COMPILER(WINSCW)
+ inline
+#endif
+ void refIfNotNull(T* ptr)
+ {
+ if (UNLIKELY(ptr != 0))
+ ptr->ref();
+ }
+
template<typename T>
#if !COMPILER(WINSCW)
inline
@@ -45,7 +56,7 @@ namespace WTF {
template<typename T> class PassRefPtr {
public:
PassRefPtr() : m_ptr(0) {}
- PassRefPtr(T* ptr) : m_ptr(ptr) { if (ptr) ptr->ref(); }
+ PassRefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); }
// It somewhat breaks the type system to allow transfer of ownership out of
// a const PassRefPtr. However, it makes it much easier to work with PassRefPtr
// temporaries, and we don't really have a need to use real const PassRefPtrs
@@ -53,14 +64,14 @@ namespace WTF {
PassRefPtr(const PassRefPtr& o) : m_ptr(o.releaseRef()) {}
template <typename U> PassRefPtr(const PassRefPtr<U>& o) : m_ptr(o.releaseRef()) { }
- ALWAYS_INLINE ~PassRefPtr() { derefIfNotNull<T>(m_ptr); }
+ ALWAYS_INLINE ~PassRefPtr() { derefIfNotNull(m_ptr); }
template <class U>
- PassRefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { if (T* ptr = m_ptr) ptr->ref(); }
+ PassRefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { T* ptr = m_ptr; refIfNotNull(ptr); }
T* get() const { return m_ptr; }
- void clear() { if (T* ptr = m_ptr) ptr->deref(); m_ptr = 0; }
+ void clear() { T* ptr = m_ptr; derefIfNotNull(ptr); m_ptr = 0; }
T* releaseRef() const { T* tmp = m_ptr; m_ptr = 0; return tmp; }
T& operator*() const { return *m_ptr; }
@@ -143,23 +154,19 @@ namespace WTF {
template <typename T> template <typename U> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const RefPtr<U>& o)
{
T* optr = o.get();
- if (optr)
- optr->ref();
+ refIfNotNull(optr);
T* ptr = m_ptr;
m_ptr = optr;
- if (ptr)
- ptr->deref();
+ derefIfNotNull(ptr);
return *this;
}
template <typename T> inline PassRefPtr<T>& PassRefPtr<T>::operator=(T* optr)
{
- if (optr)
- optr->ref();
+ refIfNotNull(optr);
T* ptr = m_ptr;
m_ptr = optr;
- if (ptr)
- ptr->deref();
+ derefIfNotNull(ptr);
return *this;
}
@@ -167,8 +174,7 @@ namespace WTF {
{
T* ptr = m_ptr;
m_ptr = ref.releaseRef();
- if (ptr)
- ptr->deref();
+ derefIfNotNull(ptr);
return *this;
}
@@ -176,8 +182,7 @@ namespace WTF {
{
T* ptr = m_ptr;
m_ptr = ref.releaseRef();
- if (ptr)
- ptr->deref();
+ derefIfNotNull(ptr);
return *this;
}
diff --git a/JavaScriptCore/wtf/Platform.h b/JavaScriptCore/wtf/Platform.h
index d61d596..b113e79 100644
--- a/JavaScriptCore/wtf/Platform.h
+++ b/JavaScriptCore/wtf/Platform.h
@@ -422,6 +422,8 @@
#else
#define WTF_PLATFORM_BREWMP_SIMULATOR 0
#endif
+#undef WTF_OS_WINDOWS
+#undef WTF_PLATFORM_WIN
#elif OS(DARWIN)
#define WTF_PLATFORM_MAC 1
#elif OS(WINDOWS)
@@ -627,6 +629,10 @@
#define ENABLE_NETSCAPE_PLUGIN_API 0
#endif
+#if PLATFORM(BREWMP)
+#define USE_SYSTEM_MALLOC 1
+#endif
+
#if !defined(HAVE_ACCESSIBILITY)
#if PLATFORM(IPHONE) || PLATFORM(MAC) || PLATFORM(WIN) || PLATFORM(GTK) || PLATFORM(CHROMIUM)
#define HAVE_ACCESSIBILITY 1
@@ -889,6 +895,13 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
#endif /* !defined(ENABLE_JIT) */
+/* CPU architecture specific optimizations */
+#if CPU(ARM_TRADITIONAL)
+#if ENABLE(JIT) && !defined(ENABLE_JIT_OPTIMIZE_MOD) && WTF_ARM_ARCH_AT_LEAST(5)
+#define ENABLE_JIT_OPTIMIZE_MOD 1
+#endif
+#endif
+
#if ENABLE(JIT)
#ifndef ENABLE_JIT_OPTIMIZE_CALL
#define ENABLE_JIT_OPTIMIZE_CALL 1
@@ -902,6 +915,9 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
#ifndef ENABLE_JIT_OPTIMIZE_METHOD_CALLS
#define ENABLE_JIT_OPTIMIZE_METHOD_CALLS 1
#endif
+#ifndef ENABLE_JIT_OPTIMIZE_MOD
+#define ENABLE_JIT_OPTIMIZE_MOD 0
+#endif
#endif
#if CPU(X86) && COMPILER(MSVC)
diff --git a/JavaScriptCore/wtf/RefPtr.h b/JavaScriptCore/wtf/RefPtr.h
index e6d1047..84e841c 100644
--- a/JavaScriptCore/wtf/RefPtr.h
+++ b/JavaScriptCore/wtf/RefPtr.h
@@ -24,6 +24,7 @@
#include <algorithm>
#include "AlwaysInline.h"
#include "FastAllocBase.h"
+#include "PassRefPtr.h"
namespace WTF {
@@ -37,8 +38,8 @@ namespace WTF {
template <typename T> class RefPtr : public FastAllocBase {
public:
RefPtr() : m_ptr(0) { }
- RefPtr(T* ptr) : m_ptr(ptr) { if (ptr) ptr->ref(); }
- RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { if (T* ptr = m_ptr) ptr->ref(); }
+ RefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); }
+ RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { T* ptr = m_ptr; refIfNotNull(ptr); }
// see comment in PassRefPtr.h for why this takes const reference
template <typename U> RefPtr(const PassRefPtr<U>&);
template <typename U> RefPtr(const NonNullPassRefPtr<U>&);
@@ -50,13 +51,13 @@ namespace WTF {
RefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); }
- ~RefPtr() { if (T* ptr = m_ptr) ptr->deref(); }
+ ~RefPtr() { derefIfNotNull(m_ptr); }
- template <typename U> RefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { if (T* ptr = m_ptr) ptr->ref(); }
+ template <typename U> RefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { T* ptr = m_ptr; refIfNotNull(ptr); }
T* get() const { return m_ptr; }
- void clear() { if (T* ptr = m_ptr) ptr->deref(); m_ptr = 0; }
+ void clear() { derefIfNotNull(m_ptr); m_ptr = 0; }
PassRefPtr<T> release() { PassRefPtr<T> tmp = adoptRef(m_ptr); m_ptr = 0; return tmp; }
T& operator*() const { return *m_ptr; }
@@ -65,12 +66,8 @@ namespace WTF {
bool operator!() const { return !m_ptr; }
// This conversion operator allows implicit conversion to bool but not to other integer types.
-#if COMPILER(WINSCW)
- operator bool() const { return m_ptr; }
-#else
- typedef T* RefPtr::*UnspecifiedBoolType;
+ typedef T* (RefPtr::*UnspecifiedBoolType);
operator UnspecifiedBoolType() const { return m_ptr ? &RefPtr::m_ptr : 0; }
-#endif
RefPtr& operator=(const RefPtr&);
RefPtr& operator=(T*);
@@ -101,35 +98,29 @@ namespace WTF {
template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<T>& o)
{
T* optr = o.get();
- if (optr)
- optr->ref();
+ refIfNotNull(optr);
T* ptr = m_ptr;
m_ptr = optr;
- if (ptr)
- ptr->deref();
+ derefIfNotNull(ptr);
return *this;
}
template <typename T> template <typename U> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<U>& o)
{
T* optr = o.get();
- if (optr)
- optr->ref();
+ refIfNotNull(optr);
T* ptr = m_ptr;
m_ptr = optr;
- if (ptr)
- ptr->deref();
+ derefIfNotNull(ptr);
return *this;
}
template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(T* optr)
{
- if (optr)
- optr->ref();
+ refIfNotNull(optr);
T* ptr = m_ptr;
m_ptr = optr;
- if (ptr)
- ptr->deref();
+ derefIfNotNull(ptr);
return *this;
}
@@ -137,8 +128,7 @@ namespace WTF {
{
T* ptr = m_ptr;
m_ptr = o.releaseRef();
- if (ptr)
- ptr->deref();
+ derefIfNotNull(ptr);
return *this;
}
@@ -146,8 +136,7 @@ namespace WTF {
{
T* ptr = m_ptr;
m_ptr = o.releaseRef();
- if (ptr)
- ptr->deref();
+ derefIfNotNull(ptr);
return *this;
}
@@ -155,8 +144,7 @@ namespace WTF {
{
T* ptr = m_ptr;
m_ptr = o.releaseRef();
- if (ptr)
- ptr->deref();
+ derefIfNotNull(ptr);
return *this;
}
@@ -164,8 +152,7 @@ namespace WTF {
{
T* ptr = m_ptr;
m_ptr = o.releaseRef();
- if (ptr)
- ptr->deref();
+ derefIfNotNull(ptr);
return *this;
}
diff --git a/JavaScriptCore/wtf/ValueCheck.h b/JavaScriptCore/wtf/ValueCheck.h
new file mode 100644
index 0000000..cd321b8
--- /dev/null
+++ b/JavaScriptCore/wtf/ValueCheck.h
@@ -0,0 +1,64 @@
+/*
+ * 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 ValueCheck_h
+#define ValueCheck_h
+
+// For malloc_size and _msize.
+#if OS(DARWIN)
+#include <malloc/malloc.h>
+#elif COMPILER(MSVC)
+#include <malloc.h>
+#endif
+
+namespace WTF {
+
+template<typename T> struct ValueCheck {
+ typedef T TraitType;
+ static void checkConsistency(const T&) { }
+};
+
+#if !ASSERT_DISABLED
+template<typename P> struct ValueCheck<P*> {
+ typedef P* TraitType;
+ static void checkConsistency(const P* p)
+ {
+ if (!p)
+ return;
+#if (defined(USE_SYSTEM_MALLOC) && USE_SYSTEM_MALLOC) || !defined(NDEBUG)
+#if OS(DARWIN)
+ ASSERT(malloc_size(p));
+#elif COMPILER(MSVC)
+ ASSERT(_msize(const_cast<P*>(p)));
+#endif
+#endif
+ ValueCheck<P>::checkConsistency(*p);
+ }
+};
+#endif
+
+}
+
+#endif // ValueCheck_h
diff --git a/JavaScriptCore/wtf/Vector.h b/JavaScriptCore/wtf/Vector.h
index decc9c9..81ea321 100644
--- a/JavaScriptCore/wtf/Vector.h
+++ b/JavaScriptCore/wtf/Vector.h
@@ -24,6 +24,7 @@
#include "FastAllocBase.h"
#include "Noncopyable.h"
#include "NotFound.h"
+#include "ValueCheck.h"
#include "VectorTraits.h"
#include <limits>
#include <utility>
@@ -586,6 +587,8 @@ namespace WTF {
m_buffer.swap(other.m_buffer);
}
+ void checkConsistency();
+
private:
void expandCapacity(size_t newMinCapacity);
const T* expandCapacity(size_t newMinCapacity, const T*);
@@ -987,6 +990,15 @@ namespace WTF {
}
template<typename T, size_t inlineCapacity>
+ inline void Vector<T, inlineCapacity>::checkConsistency()
+ {
+#if !ASSERT_DISABLED
+ for (size_t i = 0; i < size(); ++i)
+ ValueCheck<T>::checkConsistency(at(i));
+#endif
+ }
+
+ template<typename T, size_t inlineCapacity>
void deleteAllValues(const Vector<T, inlineCapacity>& collection)
{
typedef typename Vector<T, inlineCapacity>::const_iterator iterator;
@@ -1016,6 +1028,15 @@ namespace WTF {
return !(a == b);
}
+#if !ASSERT_DISABLED
+ template<typename T> struct ValueCheck<Vector<T> > {
+ typedef Vector<T> TraitType;
+ static void checkConsistency(const Vector<T>& v)
+ {
+ v.checkConsistency();
+ }
+ };
+#endif
} // namespace WTF
diff --git a/JavaScriptCore/wtf/Vector3.h b/JavaScriptCore/wtf/Vector3.h
new file mode 100644
index 0000000..3c40b61
--- /dev/null
+++ b/JavaScriptCore/wtf/Vector3.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2010 Google 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef Vector3_h
+#define Vector3_h
+
+#include <math.h>
+
+namespace WebCore {
+
+class Vector3 {
+public:
+ Vector3()
+ : m_x(0.0)
+ , m_y(0.0)
+ , m_z(0.0)
+ {
+ }
+
+ Vector3(double x, double y, double z)
+ : m_x(x)
+ , m_y(y)
+ , m_z(z)
+ {
+ }
+
+ Vector3(const float p[3])
+ : m_x(p[0])
+ , m_y(p[1])
+ , m_z(p[2])
+ {
+ }
+
+ Vector3(const double p[3])
+ : m_x(p[0])
+ , m_y(p[1])
+ , m_z(p[2])
+ {
+ }
+
+ double abs() const
+ {
+ return sqrt(m_x * m_x + m_y * m_y + m_z * m_z);
+ }
+
+ bool isZero() const
+ {
+ return !m_x && !m_y && !m_z;
+ }
+
+ void normalize()
+ {
+ double absValue = abs();
+ if (!absValue)
+ return;
+
+ double k = 1.0 / absValue;
+ m_x *= k;
+ m_y *= k;
+ m_z *= k;
+ }
+
+ double x() const { return m_x; }
+ double y() const { return m_y; }
+ double z() const { return m_z; }
+
+private:
+ double m_x;
+ double m_y;
+ double m_z;
+};
+
+inline Vector3 operator+(const Vector3& v1, const Vector3& v2)
+{
+ return Vector3(v1.x() + v2.x(), v1.y() + v2.y(), v1.z() + v2.z());
+}
+
+inline Vector3 operator-(const Vector3& v1, const Vector3& v2)
+{
+ return Vector3(v1.x() - v2.x(), v1.y() - v2.y(), v1.z() - v2.z());
+}
+
+inline Vector3 operator*(double k, const Vector3& v)
+{
+ return Vector3(k * v.x(), k * v.y(), k * v.z());
+}
+
+inline Vector3 operator*(const Vector3& v, double k)
+{
+ return Vector3(k * v.x(), k * v.y(), k * v.z());
+}
+
+inline double dot(const Vector3& v1, const Vector3& v2)
+{
+ return v1.x() * v2.x() + v1.y() * v2.y() + v1.z() * v2.z();
+}
+
+inline Vector3 cross(const Vector3& v1, const Vector3& v2)
+{
+ double x3 = v1.y() * v2.z() - v1.z() * v2.y();
+ double y3 = v1.z() * v2.x() - v1.x() * v2.z();
+ double z3 = v1.x() * v2.y() - v1.y() * v2.x();
+ return Vector3(x3, y3, z3);
+}
+
+inline double distance(const Vector3& v1, const Vector3& v2)
+{
+ return (v1 - v2).abs();
+}
+
+} // WebCore
+
+#endif // Vector3_h
diff --git a/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h b/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h
index cfd482d..9b1754a 100644
--- a/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h
+++ b/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h
@@ -56,7 +56,7 @@ namespace QUnicodeTables {
QT_END_NAMESPACE
// ugly hack to make UChar compatible with JSChar in API/JSStringRef.h
-#if defined(Q_OS_WIN) || COMPILER(WINSCW)
+#if defined(Q_OS_WIN) || COMPILER(WINSCW) || COMPILER(RVCT)
typedef wchar_t UChar;
#else
typedef uint16_t UChar;