diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-09-10 19:10:20 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-09-10 19:10:20 +0200 |
commit | 284837daa07b29d6a63a748544a90b1f5842ac5c (patch) | |
tree | ecd258180bde91fe741e0cfd2638beb3c6da7e8e /Source/JavaScriptCore/runtime | |
parent | 2e2ba8ff45915f40ed3e014101269c175f2a89a0 (diff) | |
download | qtwebkit-284837daa07b29d6a63a748544a90b1f5842ac5c.tar.gz |
Imported WebKit commit 68645295d2e3e09af2c942f092556f06aa5f8b0d (http://svn.webkit.org/repository/webkit/trunk@128073)
New snapshot
Diffstat (limited to 'Source/JavaScriptCore/runtime')
136 files changed, 2039 insertions, 2673 deletions
diff --git a/Source/JavaScriptCore/runtime/ArgList.cpp b/Source/JavaScriptCore/runtime/ArgList.cpp index 873ddc2da..301abd530 100644 --- a/Source/JavaScriptCore/runtime/ArgList.cpp +++ b/Source/JavaScriptCore/runtime/ArgList.cpp @@ -24,7 +24,7 @@ #include "HeapRootVisitor.h" #include "JSValue.h" #include "JSObject.h" -#include "ScopeChain.h" + using std::min; diff --git a/Source/JavaScriptCore/runtime/ArgList.h b/Source/JavaScriptCore/runtime/ArgList.h index 1512a0fa1..29010b1ee 100644 --- a/Source/JavaScriptCore/runtime/ArgList.h +++ b/Source/JavaScriptCore/runtime/ArgList.h @@ -24,7 +24,6 @@ #include "CallFrame.h" #include "Register.h" -#include "WriteBarrier.h" #include <wtf/HashSet.h> #include <wtf/Vector.h> diff --git a/Source/JavaScriptCore/runtime/Arguments.cpp b/Source/JavaScriptCore/runtime/Arguments.cpp index 96791c326..fe79f740e 100644 --- a/Source/JavaScriptCore/runtime/Arguments.cpp +++ b/Source/JavaScriptCore/runtime/Arguments.cpp @@ -48,8 +48,7 @@ void Arguments::visitChildren(JSCell* cell, SlotVisitor& visitor) if (thisObject->d->registerArray) visitor.appendValues(thisObject->d->registerArray.get(), thisObject->d->numArguments); visitor.append(&thisObject->d->callee); - if (thisObject->d->activation) - visitor.append(&thisObject->d->activation); + visitor.append(&thisObject->d->activation); } void Arguments::destroy(JSCell* cell) @@ -99,7 +98,7 @@ bool Arguments::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigne return true; } - return JSObject::getOwnPropertySlot(thisObject, exec, Identifier(exec, UString::number(i)), slot); + return JSObject::getOwnPropertySlot(thisObject, exec, Identifier(exec, String::number(i)), slot); } void Arguments::createStrictModeCallerIfNecessary(ExecState* exec) @@ -187,7 +186,7 @@ void Arguments::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyN Arguments* thisObject = jsCast<Arguments*>(object); for (unsigned i = 0; i < thisObject->d->numArguments; ++i) { if (!thisObject->d->deletedArguments || !thisObject->d->deletedArguments[i]) - propertyNames.add(Identifier(exec, UString::number(i))); + propertyNames.add(Identifier(exec, String::number(i))); } if (mode == IncludeDontEnumProperties) { propertyNames.add(exec->propertyNames().callee); @@ -205,7 +204,7 @@ void Arguments::putByIndex(JSCell* cell, ExecState* exec, unsigned i, JSValue va } PutPropertySlot slot(shouldThrow); - JSObject::put(thisObject, exec, Identifier(exec, UString::number(i)), value, slot); + JSObject::put(thisObject, exec, Identifier(exec, String::number(i)), value, slot); } void Arguments::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot) @@ -256,7 +255,7 @@ bool Arguments::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned i) } } - return JSObject::deleteProperty(thisObject, exec, Identifier(exec, UString::number(i))); + return JSObject::deleteProperty(thisObject, exec, Identifier(exec, String::number(i))); } bool Arguments::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName) diff --git a/Source/JavaScriptCore/runtime/Arguments.h b/Source/JavaScriptCore/runtime/Arguments.h index 90eed25fa..1d0bffd6b 100644 --- a/Source/JavaScriptCore/runtime/Arguments.h +++ b/Source/JavaScriptCore/runtime/Arguments.h @@ -49,7 +49,7 @@ namespace JSC { bool overrodeCaller; bool isStrictMode; - WriteBarrier<Unknown>* registers; + WriteBarrierBase<Unknown>* registers; OwnArrayPtr<WriteBarrier<Unknown> > registerArray; OwnArrayPtr<bool> deletedArguments; @@ -110,6 +110,7 @@ namespace JSC { d->activation.set(globalData, this, activation); d->registers = &activation->registerAt(0); } + void setRegisters(WriteBarrierBase<Unknown>* registers) { d->registers = registers; } static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype) { @@ -138,7 +139,7 @@ namespace JSC { void createStrictModeCallerIfNecessary(ExecState*); void createStrictModeCalleeIfNecessary(ExecState*); - WriteBarrier<Unknown>& argument(size_t); + WriteBarrierBase<Unknown>& argument(size_t); void init(CallFrame*); @@ -165,7 +166,7 @@ namespace JSC { { } - inline WriteBarrier<Unknown>& Arguments::argument(size_t i) + inline WriteBarrierBase<Unknown>& Arguments::argument(size_t i) { return d->registers[CallFrame::argumentOffset(i)]; } @@ -177,7 +178,7 @@ namespace JSC { JSFunction* callee = jsCast<JSFunction*>(callFrame->callee()); d->numArguments = callFrame->argumentCount(); - d->registers = reinterpret_cast<WriteBarrier<Unknown>*>(callFrame->registers()); + d->registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers()); d->callee.set(callFrame->globalData(), this, callee); d->overrodeLength = false; d->overrodeCallee = false; @@ -197,7 +198,7 @@ namespace JSC { JSFunction* callee = inlineCallFrame->callee.get(); d->numArguments = inlineCallFrame->arguments.size() - 1; - d->registers = reinterpret_cast<WriteBarrier<Unknown>*>(callFrame->registers()) + inlineCallFrame->stackOffset; + d->registers = reinterpret_cast<WriteBarrierBase<Unknown>*>(callFrame->registers()) + inlineCallFrame->stackOffset; d->callee.set(callFrame->globalData(), this, callee); d->overrodeLength = false; d->overrodeCallee = false; diff --git a/Source/JavaScriptCore/runtime/ArrayConstructor.cpp b/Source/JavaScriptCore/runtime/ArrayConstructor.cpp index 83e48ca1b..c9a6dc600 100644 --- a/Source/JavaScriptCore/runtime/ArrayConstructor.cpp +++ b/Source/JavaScriptCore/runtime/ArrayConstructor.cpp @@ -85,7 +85,7 @@ static inline JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgLi if (args.size() == 1 && args.at(0).isNumber()) { uint32_t n = args.at(0).toUInt32(exec); if (n != args.at(0).toNumber(exec)) - return throwError(exec, createRangeError(exec, "Array size is not a small enough positive integer.")); + return throwError(exec, createRangeError(exec, ASCIILiteral("Array size is not a small enough positive integer."))); return constructEmptyArray(exec, globalObject, n); } diff --git a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp index a97cf82de..4b13f993c 100644 --- a/Source/JavaScriptCore/runtime/ArrayPrototype.cpp +++ b/Source/JavaScriptCore/runtime/ArrayPrototype.cpp @@ -77,7 +77,7 @@ static inline bool isNumericCompareFunction(ExecState* exec, CallType callType, FunctionExecutable* executable = callData.js.functionExecutable; - JSObject* error = executable->compileForCall(exec, callData.js.scopeChain); + JSObject* error = executable->compileForCall(exec, callData.js.scope); if (error) return false; @@ -205,13 +205,13 @@ static inline void shift(ExecState* exec, JSObject* thisObj, unsigned header, un if (exec->hadException()) return; } else if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, to)) { - throwTypeError(exec, "Unable to delete property."); + throwTypeError(exec, ASCIILiteral("Unable to delete property.")); return; } } for (unsigned k = length; k > length - count; --k) { if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, k - 1)) { - throwTypeError(exec, "Unable to delete property."); + throwTypeError(exec, ASCIILiteral("Unable to delete property.")); return; } } @@ -243,7 +243,7 @@ static inline void unshift(ExecState* exec, JSObject* thisObj, unsigned header, return; thisObj->methodTable()->putByIndex(thisObj, exec, to, value, true); } else if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, to)) { - throwTypeError(exec, "Unable to delete property."); + throwTypeError(exec, ASCIILiteral("Unable to delete property.")); return; } if (exec->hadException()) @@ -300,7 +300,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec) if (element.isUndefinedOrNull()) continue; - UString str = element.toUString(exec); + String str = element.toWTFString(exec); strBuffer[k] = str.impl(); totalSize += str.length(); allStrings8Bit = allStrings8Bit && str.is8Bit(); @@ -328,7 +328,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec) buffer.append(rep->characters8(), rep->length()); } ASSERT(buffer.size() == totalSize); - return JSValue::encode(jsString(exec, UString::adopt(buffer))); + return JSValue::encode(jsString(exec, String::adopt(buffer))); } Vector<UChar> buffer; @@ -343,7 +343,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec) buffer.append(rep->characters(), rep->length()); } ASSERT(buffer.size() == totalSize); - return JSValue::encode(jsString(exec, UString::adopt(buffer))); + return JSValue::encode(jsString(exec, String::adopt(buffer))); } EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec) @@ -362,7 +362,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec) if (JSValue earlyReturnValue = checker.earlyReturnValue()) return JSValue::encode(earlyReturnValue); - UString separator(","); + String separator(",", String::ConstructFromLiteral); JSStringJoiner stringJoiner(separator, length); for (unsigned k = 0; k < length; k++) { JSValue element = thisObj->get(exec, k); @@ -373,13 +373,13 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec) JSValue conversionFunction = o->get(exec, exec->propertyNames().toLocaleString); if (exec->hadException()) return JSValue::encode(jsUndefined()); - UString str; + String str; CallData callData; CallType callType = getCallData(conversionFunction, callData); if (callType != CallTypeNone) - str = call(exec, conversionFunction, callType, callData, element, exec->emptyList()).toUString(exec); + str = call(exec, conversionFunction, callType, callData, element, exec->emptyList()).toWTFString(exec); else - str = element.toUString(exec); + str = element.toWTFString(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); stringJoiner.append(str); @@ -400,11 +400,11 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec) if (JSValue earlyReturnValue = checker.earlyReturnValue()) return JSValue::encode(earlyReturnValue); - UString separator; + String separator; if (!exec->argument(0).isUndefined()) - separator = exec->argument(0).toUString(exec); + separator = exec->argument(0).toWTFString(exec); if (separator.isNull()) - separator = UString(","); + separator = String(",", String::ConstructFromLiteral); JSStringJoiner stringJoiner(separator, length); @@ -418,18 +418,18 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec) JSValue element = array->getIndex(k); if (!element.isUndefinedOrNull()) - stringJoiner.append(element.toUStringInline(exec)); + stringJoiner.append(element.toWTFStringInline(exec)); else - stringJoiner.append(UString()); + stringJoiner.append(String()); } } for (; k < length; k++) { JSValue element = thisObj->get(exec, k); if (!element.isUndefinedOrNull()) - stringJoiner.append(element.toUStringInline(exec)); + stringJoiner.append(element.toWTFStringInline(exec)); else - stringJoiner.append(UString()); + stringJoiner.append(String()); } return JSValue::encode(stringJoiner.build(exec)); @@ -491,7 +491,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncPop(ExecState* exec) if (exec->hadException()) return JSValue::encode(jsUndefined()); if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, length - 1)) { - throwTypeError(exec, "Unable to delete property."); + throwTypeError(exec, ASCIILiteral("Unable to delete property.")); return JSValue::encode(jsUndefined()); } putProperty(exec, thisObj, exec->propertyNames().length, jsNumber(length - 1)); @@ -520,7 +520,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec) thisObj->methodTable()->putByIndex(thisObj, exec, length + n, exec->argument(n), true); else { PutPropertySlot slot; - Identifier propertyName(exec, JSValue(static_cast<int64_t>(length) + static_cast<int64_t>(n)).toUString(exec)); + Identifier propertyName(exec, JSValue(static_cast<int64_t>(length) + static_cast<int64_t>(n)).toWTFString(exec)); thisObj->methodTable()->put(thisObj, exec, propertyName, exec->argument(n), slot); } if (exec->hadException()) @@ -553,7 +553,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncReverse(ExecState* exec) if (exec->hadException()) return JSValue::encode(jsUndefined()); } else if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, k)) { - throwTypeError(exec, "Unable to delete property."); + throwTypeError(exec, ASCIILiteral("Unable to delete property.")); return JSValue::encode(jsUndefined()); } @@ -562,7 +562,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncReverse(ExecState* exec) if (exec->hadException()) return JSValue::encode(jsUndefined()); } else if (!thisObj->methodTable()->deletePropertyByIndex(thisObj, exec, lk1)) { - throwTypeError(exec, "Unable to delete property."); + throwTypeError(exec, ASCIILiteral("Unable to delete property.")); return JSValue::encode(jsUndefined()); } } @@ -661,7 +661,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSort(ExecState* exec) l.append(minObj); compareResult = call(exec, function, callType, callData, jsUndefined(), l).toNumber(exec); } else - compareResult = (jObj.toUStringInline(exec) < minObj.toUStringInline(exec)) ? -1 : 1; + compareResult = codePointCompareLessThan(jObj.toWTFStringInline(exec), minObj.toWTFStringInline(exec)) ? -1 : 1; if (compareResult < 0) { themin = j; diff --git a/Source/JavaScriptCore/runtime/BooleanObject.cpp b/Source/JavaScriptCore/runtime/BooleanObject.cpp index 37c6eab0d..bf2655bbb 100644 --- a/Source/JavaScriptCore/runtime/BooleanObject.cpp +++ b/Source/JavaScriptCore/runtime/BooleanObject.cpp @@ -21,6 +21,8 @@ #include "config.h" #include "BooleanObject.h" +#include "JSScope.h" + namespace JSC { ASSERT_CLASS_FITS_IN_CELL(BooleanObject); diff --git a/Source/JavaScriptCore/runtime/BooleanPrototype.cpp b/Source/JavaScriptCore/runtime/BooleanPrototype.cpp index 1551eabf2..c8c77220a 100644 --- a/Source/JavaScriptCore/runtime/BooleanPrototype.cpp +++ b/Source/JavaScriptCore/runtime/BooleanPrototype.cpp @@ -77,21 +77,22 @@ bool BooleanPrototype::getOwnPropertyDescriptor(JSObject* object, ExecState* exe EncodedJSValue JSC_HOST_CALL booleanProtoFuncToString(ExecState* exec) { + JSGlobalData* globalData = &exec->globalData(); JSValue thisValue = exec->hostThisValue(); if (thisValue == jsBoolean(false)) - return JSValue::encode(jsNontrivialString(exec, "false")); + return JSValue::encode(globalData->smallStrings.falseString(globalData)); if (thisValue == jsBoolean(true)) - return JSValue::encode(jsNontrivialString(exec, "true")); + return JSValue::encode(globalData->smallStrings.trueString(globalData)); if (!thisValue.inherits(&BooleanObject::s_info)) return throwVMTypeError(exec); if (asBooleanObject(thisValue)->internalValue() == jsBoolean(false)) - return JSValue::encode(jsNontrivialString(exec, "false")); + return JSValue::encode(globalData->smallStrings.falseString(globalData)); ASSERT(asBooleanObject(thisValue)->internalValue() == jsBoolean(true)); - return JSValue::encode(jsNontrivialString(exec, "true")); + return JSValue::encode(globalData->smallStrings.trueString(globalData)); } EncodedJSValue JSC_HOST_CALL booleanProtoFuncValueOf(ExecState* exec) diff --git a/Source/JavaScriptCore/runtime/CallData.h b/Source/JavaScriptCore/runtime/CallData.h index 15a6a0a48..77478304c 100644 --- a/Source/JavaScriptCore/runtime/CallData.h +++ b/Source/JavaScriptCore/runtime/CallData.h @@ -37,7 +37,7 @@ namespace JSC { class ExecState; class FunctionExecutable; class JSObject; - class ScopeChainNode; + class JSScope; enum CallType { CallTypeNone, @@ -53,7 +53,7 @@ namespace JSC { } native; struct { FunctionExecutable* functionExecutable; - ScopeChainNode* scopeChain; + JSScope* scope; } js; }; diff --git a/Source/JavaScriptCore/runtime/ClassInfo.h b/Source/JavaScriptCore/runtime/ClassInfo.h index b0adab32c..4c72f3ed1 100644 --- a/Source/JavaScriptCore/runtime/ClassInfo.h +++ b/Source/JavaScriptCore/runtime/ClassInfo.h @@ -75,7 +75,7 @@ namespace JSC { typedef void (*GetPropertyNamesFunctionPtr)(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); GetPropertyNamesFunctionPtr getPropertyNames; - typedef UString (*ClassNameFunctionPtr)(const JSObject*); + typedef String (*ClassNameFunctionPtr)(const JSObject*); ClassNameFunctionPtr className; typedef bool (*HasInstanceFunctionPtr)(JSObject*, ExecState*, JSValue, JSValue); diff --git a/Source/JavaScriptCore/runtime/CommonSlowPaths.h b/Source/JavaScriptCore/runtime/CommonSlowPaths.h index 0d3480104..e4c76ad16 100644 --- a/Source/JavaScriptCore/runtime/CommonSlowPaths.h +++ b/Source/JavaScriptCore/runtime/CommonSlowPaths.h @@ -119,123 +119,6 @@ inline bool opIn(ExecState* exec, JSValue propName, JSValue baseVal) return baseObj->hasProperty(exec, property); } -ALWAYS_INLINE JSValue opResolve(ExecState* exec, Identifier& ident) -{ - ScopeChainNode* scopeChain = exec->scopeChain(); - - ScopeChainIterator iter = scopeChain->begin(); - ScopeChainIterator end = scopeChain->end(); - ASSERT(iter != end); - - do { - JSObject* o = iter->get(); - PropertySlot slot(o); - if (o->getPropertySlot(exec, ident, slot)) - return slot.getValue(exec, ident); - } while (++iter != end); - - exec->globalData().exception = createUndefinedVariableError(exec, ident); - return JSValue(); -} - -ALWAYS_INLINE JSValue opResolveSkip(ExecState* exec, Identifier& ident, int skip) -{ - ScopeChainNode* scopeChain = exec->scopeChain(); - - ScopeChainIterator iter = scopeChain->begin(); - ScopeChainIterator end = scopeChain->end(); - ASSERT(iter != end); - CodeBlock* codeBlock = exec->codeBlock(); - bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain(); - ASSERT(skip || !checkTopLevel); - if (checkTopLevel && skip--) { - if (exec->uncheckedR(codeBlock->activationRegister()).jsValue()) - ++iter; - } - while (skip--) { - ++iter; - ASSERT(iter != end); - } - do { - JSObject* o = iter->get(); - PropertySlot slot(o); - if (o->getPropertySlot(exec, ident, slot)) - return slot.getValue(exec, ident); - } while (++iter != end); - - exec->globalData().exception = createUndefinedVariableError(exec, ident); - return JSValue(); -} - -ALWAYS_INLINE JSValue opResolveWithBase(ExecState* exec, Identifier& ident, Register& baseSlot) -{ - ScopeChainNode* scopeChain = exec->scopeChain(); - - ScopeChainIterator iter = scopeChain->begin(); - ScopeChainIterator end = scopeChain->end(); - - // FIXME: add scopeDepthIsZero optimization - - ASSERT(iter != end); - - JSObject* base; - do { - base = iter->get(); - PropertySlot slot(base); - if (base->getPropertySlot(exec, ident, slot)) { - JSValue result = slot.getValue(exec, ident); - if (exec->globalData().exception) - return JSValue(); - - baseSlot = JSValue(base); - return result; - } - ++iter; - } while (iter != end); - - exec->globalData().exception = createUndefinedVariableError(exec, ident); - return JSValue(); -} - -ALWAYS_INLINE JSValue opResolveWithThis(ExecState* exec, Identifier& ident, Register& baseSlot) -{ - ScopeChainNode* scopeChain = exec->scopeChain(); - - ScopeChainIterator iter = scopeChain->begin(); - ScopeChainIterator end = scopeChain->end(); - - // FIXME: add scopeDepthIsZero optimization - - ASSERT(iter != end); - - JSObject* base; - do { - base = iter->get(); - ++iter; - PropertySlot slot(base); - if (base->getPropertySlot(exec, ident, slot)) { - JSValue result = slot.getValue(exec, ident); - if (exec->globalData().exception) - return JSValue(); - - // All entries on the scope chain should be EnvironmentRecords (activations etc), - // other then 'with' object, which are directly referenced from the scope chain, - // and the global object. If we hit either an EnvironmentRecord or a global - // object at the end of the scope chain, this is undefined. If we hit a non- - // EnvironmentRecord within the scope chain, pass the base as the this value. - if (iter == end || base->structure()->typeInfo().isEnvironmentRecord()) - baseSlot = jsUndefined(); - else - baseSlot = JSValue(base); - return result; - } - } while (iter != end); - - exec->globalData().exception = createUndefinedVariableError(exec, ident); - return JSValue(); -} - } } // namespace JSC::CommonSlowPaths #endif // CommonSlowPaths_h - diff --git a/Source/JavaScriptCore/runtime/Completion.cpp b/Source/JavaScriptCore/runtime/Completion.cpp index 1c35b9626..3de8d4841 100644 --- a/Source/JavaScriptCore/runtime/Completion.cpp +++ b/Source/JavaScriptCore/runtime/Completion.cpp @@ -51,7 +51,7 @@ bool checkSyntax(ExecState* exec, const SourceCode& source, JSValue* returnedExc return true; } -JSValue evaluate(ExecState* exec, ScopeChainNode* scopeChain, const SourceCode& source, JSValue thisValue, JSValue* returnedException) +JSValue evaluate(ExecState* exec, const SourceCode& source, JSValue thisValue, JSValue* returnedException) { JSLockHolder lock(exec); ASSERT(exec->globalData().identifierTable == wtfThreadData().currentIdentifierTable()); @@ -72,7 +72,7 @@ JSValue evaluate(ExecState* exec, ScopeChainNode* scopeChain, const SourceCode& if (!thisValue || thisValue.isUndefinedOrNull()) thisValue = exec->dynamicGlobalObject(); JSObject* thisObj = thisValue.toThisObject(exec); - JSValue result = exec->interpreter()->execute(program, exec, scopeChain, thisObj); + JSValue result = exec->interpreter()->execute(program, exec, thisObj); if (exec->hadException()) { if (returnedException) diff --git a/Source/JavaScriptCore/runtime/Completion.h b/Source/JavaScriptCore/runtime/Completion.h index 3d3b86fe4..d150fcea2 100644 --- a/Source/JavaScriptCore/runtime/Completion.h +++ b/Source/JavaScriptCore/runtime/Completion.h @@ -28,11 +28,11 @@ namespace JSC { class ExecState; - class ScopeChainNode; + class JSScope; class SourceCode; JS_EXPORT_PRIVATE bool checkSyntax(ExecState*, const SourceCode&, JSValue* exception = 0); - JS_EXPORT_PRIVATE JSValue evaluate(ExecState*, ScopeChainNode*, const SourceCode&, JSValue thisValue = JSValue(), JSValue* exception = 0); + JS_EXPORT_PRIVATE JSValue evaluate(ExecState*, const SourceCode&, JSValue thisValue = JSValue(), JSValue* exception = 0); } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/ConstructData.h b/Source/JavaScriptCore/runtime/ConstructData.h index d7a3c73d3..6426b044e 100644 --- a/Source/JavaScriptCore/runtime/ConstructData.h +++ b/Source/JavaScriptCore/runtime/ConstructData.h @@ -38,7 +38,7 @@ namespace JSC { class ExecState; class FunctionExecutable; class JSObject; - class ScopeChainNode; + class JSScope; enum ConstructType { ConstructTypeNone, @@ -52,7 +52,7 @@ namespace JSC { } native; struct { FunctionExecutable* functionExecutable; - ScopeChainNode* scopeChain; + JSScope* scope; } js; }; diff --git a/Source/JavaScriptCore/runtime/DateConversion.cpp b/Source/JavaScriptCore/runtime/DateConversion.cpp index 47839817f..0b57f012d 100644 --- a/Source/JavaScriptCore/runtime/DateConversion.cpp +++ b/Source/JavaScriptCore/runtime/DateConversion.cpp @@ -25,10 +25,10 @@ #include "config.h" #include "DateConversion.h" -#include "UString.h" #include <wtf/Assertions.h> #include <wtf/DateMath.h> #include <wtf/text/StringBuilder.h> +#include <wtf/text/WTFString.h> #if OS(WINDOWS) #include <windows.h> @@ -62,7 +62,7 @@ void appendNumber<2>(StringBuilder& builder, int value) builder.append(static_cast<char>('0' + value % 10)); } -UString formatDateTime(const GregorianDateTime& t, DateTimeFormat format, bool asUTCVariant) +String formatDateTime(const GregorianDateTime& t, DateTimeFormat format, bool asUTCVariant) { bool appendDate = format & DateTimeFormatDate; bool appendTime = format & DateTimeFormatTime; @@ -73,7 +73,7 @@ UString formatDateTime(const GregorianDateTime& t, DateTimeFormat format, bool a builder.append(weekdayName[(t.weekDay() + 6) % 7]); if (asUTCVariant) { - builder.append(", "); + builder.appendLiteral(", "); appendNumber<2>(builder, t.monthDay()); builder.append(' '); builder.append(monthName[t.month()]); @@ -96,7 +96,7 @@ UString formatDateTime(const GregorianDateTime& t, DateTimeFormat format, bool a appendNumber<2>(builder, t.minute()); builder.append(':'); appendNumber<2>(builder, t.second()); - builder.append(" GMT"); + builder.appendLiteral(" GMT"); if (!asUTCVariant) { int offset = abs(t.utcOffset()) / 60; @@ -114,7 +114,7 @@ UString formatDateTime(const GregorianDateTime& t, DateTimeFormat format, bool a strftime(timeZoneName, sizeof(timeZoneName), "%Z", >m); #endif if (timeZoneName[0]) { - builder.append(" ("); + builder.appendLiteral(" ("); builder.append(timeZoneName); builder.append(')'); } diff --git a/Source/JavaScriptCore/runtime/DateConversion.h b/Source/JavaScriptCore/runtime/DateConversion.h index fd1a7eb35..8ea4c17ad 100644 --- a/Source/JavaScriptCore/runtime/DateConversion.h +++ b/Source/JavaScriptCore/runtime/DateConversion.h @@ -27,9 +27,11 @@ #include <wtf/GregorianDateTime.h> -namespace JSC { +namespace WTF { +class String; +} // namespace WTF -class UString; +namespace JSC { enum DateTimeFormat { DateTimeFormatDate = 1, @@ -37,7 +39,7 @@ enum DateTimeFormat { DateTimeFormatDateAndTime = DateTimeFormatDate | DateTimeFormatTime }; -UString formatDateTime(const GregorianDateTime&, DateTimeFormat, bool asUTCVariant); +WTF::String formatDateTime(const GregorianDateTime&, DateTimeFormat, bool asUTCVariant); } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/DatePrototype.cpp b/Source/JavaScriptCore/runtime/DatePrototype.cpp index 363eec03a..62211d302 100644 --- a/Source/JavaScriptCore/runtime/DatePrototype.cpp +++ b/Source/JavaScriptCore/runtime/DatePrototype.cpp @@ -131,7 +131,7 @@ enum LocaleDateTimeFormat { LocaleDateAndTime, LocaleDate, LocaleTime }; // FIXME: Since this is superior to the strftime-based version, why limit this to PLATFORM(MAC)? // Instead we should consider using this whenever USE(CF) is true. -static CFDateFormatterStyle styleFromArgString(const UString& string, CFDateFormatterStyle defaultStyle) +static CFDateFormatterStyle styleFromArgString(const String& string, CFDateFormatterStyle defaultStyle) { if (string == "short") return kCFDateFormatterShortStyle; @@ -150,9 +150,9 @@ static JSCell* formatLocaleDate(ExecState* exec, DateInstance*, double timeInMil CFDateFormatterStyle timeStyle = (format != LocaleDate ? kCFDateFormatterLongStyle : kCFDateFormatterNoStyle); bool useCustomFormat = false; - UString customFormatString; + String customFormatString; - UString arg0String = exec->argument(0).toString(exec)->value(exec); + String arg0String = exec->argument(0).toString(exec)->value(exec); if (arg0String == "custom" && !exec->argument(1).isUndefined()) { useCustomFormat = true; customFormatString = exec->argument(1).toString(exec)->value(exec); @@ -190,7 +190,7 @@ static JSCell* formatLocaleDate(ExecState* exec, DateInstance*, double timeInMil CFRelease(string); - return jsNontrivialString(exec, UString(buffer, length)); + return jsNontrivialString(exec, String(buffer, length)); } #elif USE(ICU_UNICODE) && !UCONFIG_NO_FORMATTING @@ -212,7 +212,7 @@ static JSCell* formatLocaleDate(ExecState* exec, DateInstance* dateObject, doubl if (status != U_ZERO_ERROR) return jsEmptyString(exec); - return jsNontrivialString(exec, UString(buffer, length)); + return jsNontrivialString(exec, String(buffer, length)); } #else @@ -253,7 +253,7 @@ static JSCell* formatLocaleDate(ExecState* exec, const GregorianDateTime& gdt, L if (length) length--; - return jsNontrivialString(exec, UString(buffer.data(), length)); + return jsNontrivialString(exec, String(buffer.data(), length)); #else // OS(WINDOWS) @@ -322,7 +322,7 @@ static JSCell* formatLocaleDate(ExecState* exec, const GregorianDateTime& gdt, L if (length != static_cast<size_t>(-1)) { for (size_t i = 0; i < length; ++i) buffer[i] = static_cast<UChar>(tempbuffer[i]); - return jsNontrivialString(exec, UString(buffer, length)); + return jsNontrivialString(exec, String(buffer, length)); } #endif @@ -334,7 +334,7 @@ static JSCell* formatLocaleDate(ExecState* exec, DateInstance* dateObject, doubl { const GregorianDateTime* gregorianDateTime = dateObject->gregorianDateTime(exec); if (!gregorianDateTime) - return jsNontrivialString(exec, "Invalid Date"); + return jsNontrivialString(exec, ASCIILiteral("Invalid Date")); return formatLocaleDate(exec, *gregorianDateTime, format); } @@ -352,7 +352,7 @@ static EncodedJSValue formateDateInstance(ExecState* exec, DateTimeFormat format ? thisDateObj->gregorianDateTimeUTC(exec) : thisDateObj->gregorianDateTime(exec); if (!gregorianDateTime) - return JSValue::encode(jsNontrivialString(exec, "Invalid Date")); + return JSValue::encode(jsNontrivialString(exec, String(ASCIILiteral("Invalid Date")))); return JSValue::encode(jsNontrivialString(exec, formatDateTime(*gregorianDateTime, format, asUTCVariant))); } @@ -548,24 +548,30 @@ EncodedJSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState* exec) DateInstance* thisDateObj = asDateInstance(thisValue); if (!isfinite(thisDateObj->internalNumber())) - return throwVMError(exec, createRangeError(exec, "Invalid Date")); + return throwVMError(exec, createRangeError(exec, ASCIILiteral("Invalid Date"))); const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec); if (!gregorianDateTime) - return JSValue::encode(jsNontrivialString(exec, "Invalid Date")); + return JSValue::encode(jsNontrivialString(exec, String(ASCIILiteral("Invalid Date")))); // Maximum amount of space we need in buffer: 7 (max. digits in year) + 2 * 5 (2 characters each for month, day, hour, minute, second) + 4 (. + 3 digits for milliseconds) // 6 for formatting and one for null termination = 28. We add one extra character to allow us to force null termination. - char buffer[29]; + char buffer[28]; // If the year is outside the bounds of 0 and 9999 inclusive we want to use the extended year format (ES 15.9.1.15.1). int ms = static_cast<int>(fmod(thisDateObj->internalNumber(), msPerSecond)); if (ms < 0) ms += msPerSecond; + + int charactersWritten; if (gregorianDateTime->year() > 9999 || gregorianDateTime->year() < 0) - snprintf(buffer, sizeof(buffer) - 1, "%+07d-%02d-%02dT%02d:%02d:%02d.%03dZ", gregorianDateTime->year(), gregorianDateTime->month() + 1, gregorianDateTime->monthDay(), gregorianDateTime->hour(), gregorianDateTime->minute(), gregorianDateTime->second(), ms); + charactersWritten = snprintf(buffer, sizeof(buffer), "%+07d-%02d-%02dT%02d:%02d:%02d.%03dZ", gregorianDateTime->year(), gregorianDateTime->month() + 1, gregorianDateTime->monthDay(), gregorianDateTime->hour(), gregorianDateTime->minute(), gregorianDateTime->second(), ms); else - snprintf(buffer, sizeof(buffer) - 1, "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", gregorianDateTime->year(), gregorianDateTime->month() + 1, gregorianDateTime->monthDay(), gregorianDateTime->hour(), gregorianDateTime->minute(), gregorianDateTime->second(), ms); - buffer[sizeof(buffer) - 1] = 0; - return JSValue::encode(jsNontrivialString(exec, buffer)); + charactersWritten = snprintf(buffer, sizeof(buffer), "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", gregorianDateTime->year(), gregorianDateTime->month() + 1, gregorianDateTime->monthDay(), gregorianDateTime->hour(), gregorianDateTime->minute(), gregorianDateTime->second(), ms); + + ASSERT(charactersWritten > 0 && static_cast<unsigned>(charactersWritten) < sizeof(buffer)); + if (static_cast<unsigned>(charactersWritten) >= sizeof(buffer)) + return JSValue::encode(jsEmptyString(exec)); + + return JSValue::encode(jsNontrivialString(exec, String(buffer, charactersWritten))); } EncodedJSValue JSC_HOST_CALL dateProtoFuncToDateString(ExecState* exec) @@ -1113,13 +1119,13 @@ EncodedJSValue JSC_HOST_CALL dateProtoFuncToJSON(ExecState* exec) CallData callData; CallType callType = getCallData(toISOValue, callData); if (callType == CallTypeNone) - return throwVMError(exec, createTypeError(exec, "toISOString is not a function")); + return throwVMError(exec, createTypeError(exec, ASCIILiteral("toISOString is not a function"))); JSValue result = call(exec, asObject(toISOValue), callType, callData, object, exec->emptyList()); if (exec->hadException()) return JSValue::encode(jsNull()); if (result.isObject()) - return throwVMError(exec, createTypeError(exec, "toISOString did not return a primitive value")); + return throwVMError(exec, createTypeError(exec, ASCIILiteral("toISOString did not return a primitive value"))); return JSValue::encode(result); } diff --git a/Source/JavaScriptCore/runtime/Error.cpp b/Source/JavaScriptCore/runtime/Error.cpp index a3a990d59..27a729d0a 100644 --- a/Source/JavaScriptCore/runtime/Error.cpp +++ b/Source/JavaScriptCore/runtime/Error.cpp @@ -43,37 +43,37 @@ namespace JSC { static const char* linePropertyName = "line"; static const char* sourceURLPropertyName = "sourceURL"; -JSObject* createError(JSGlobalObject* globalObject, const UString& message) +JSObject* createError(JSGlobalObject* globalObject, const String& message) { ASSERT(!message.isEmpty()); return ErrorInstance::create(globalObject->globalData(), globalObject->errorStructure(), message); } -JSObject* createEvalError(JSGlobalObject* globalObject, const UString& message) +JSObject* createEvalError(JSGlobalObject* globalObject, const String& message) { ASSERT(!message.isEmpty()); return ErrorInstance::create(globalObject->globalData(), globalObject->evalErrorConstructor()->errorStructure(), message); } -JSObject* createRangeError(JSGlobalObject* globalObject, const UString& message) +JSObject* createRangeError(JSGlobalObject* globalObject, const String& message) { ASSERT(!message.isEmpty()); return ErrorInstance::create(globalObject->globalData(), globalObject->rangeErrorConstructor()->errorStructure(), message); } -JSObject* createReferenceError(JSGlobalObject* globalObject, const UString& message) +JSObject* createReferenceError(JSGlobalObject* globalObject, const String& message) { ASSERT(!message.isEmpty()); return ErrorInstance::create(globalObject->globalData(), globalObject->referenceErrorConstructor()->errorStructure(), message); } -JSObject* createSyntaxError(JSGlobalObject* globalObject, const UString& message) +JSObject* createSyntaxError(JSGlobalObject* globalObject, const String& message) { ASSERT(!message.isEmpty()); return ErrorInstance::create(globalObject->globalData(), globalObject->syntaxErrorConstructor()->errorStructure(), message); } -JSObject* createTypeError(JSGlobalObject* globalObject, const UString& message) +JSObject* createTypeError(JSGlobalObject* globalObject, const String& message) { ASSERT(!message.isEmpty()); return ErrorInstance::create(globalObject->globalData(), globalObject->typeErrorConstructor()->errorStructure(), message); @@ -81,41 +81,41 @@ JSObject* createTypeError(JSGlobalObject* globalObject, const UString& message) JSObject* createNotEnoughArgumentsError(JSGlobalObject* globalObject) { - return createTypeError(globalObject, "Not enough arguments"); + return createTypeError(globalObject, ASCIILiteral("Not enough arguments")); } -JSObject* createURIError(JSGlobalObject* globalObject, const UString& message) +JSObject* createURIError(JSGlobalObject* globalObject, const String& message) { ASSERT(!message.isEmpty()); return ErrorInstance::create(globalObject->globalData(), globalObject->URIErrorConstructor()->errorStructure(), message); } -JSObject* createError(ExecState* exec, const UString& message) +JSObject* createError(ExecState* exec, const String& message) { return createError(exec->lexicalGlobalObject(), message); } -JSObject* createEvalError(ExecState* exec, const UString& message) +JSObject* createEvalError(ExecState* exec, const String& message) { return createEvalError(exec->lexicalGlobalObject(), message); } -JSObject* createRangeError(ExecState* exec, const UString& message) +JSObject* createRangeError(ExecState* exec, const String& message) { return createRangeError(exec->lexicalGlobalObject(), message); } -JSObject* createReferenceError(ExecState* exec, const UString& message) +JSObject* createReferenceError(ExecState* exec, const String& message) { return createReferenceError(exec->lexicalGlobalObject(), message); } -JSObject* createSyntaxError(ExecState* exec, const UString& message) +JSObject* createSyntaxError(ExecState* exec, const String& message) { return createSyntaxError(exec->lexicalGlobalObject(), message); } -JSObject* createTypeError(ExecState* exec, const UString& message) +JSObject* createTypeError(ExecState* exec, const String& message) { return createTypeError(exec->lexicalGlobalObject(), message); } @@ -125,7 +125,7 @@ JSObject* createNotEnoughArgumentsError(ExecState* exec) return createNotEnoughArgumentsError(exec->lexicalGlobalObject()); } -JSObject* createURIError(ExecState* exec, const UString& message) +JSObject* createURIError(ExecState* exec, const String& message) { return createURIError(exec->lexicalGlobalObject(), message); } @@ -133,7 +133,7 @@ JSObject* createURIError(ExecState* exec, const UString& message) JSObject* addErrorInfo(CallFrame* callFrame, JSObject* error, int line, const SourceCode& source) { JSGlobalData* globalData = &callFrame->globalData(); - const UString& sourceURL = source.provider()->url(); + const String& sourceURL = source.provider()->url(); if (line != -1) error->putDirect(*globalData, Identifier(globalData, linePropertyName), jsNumber(line), ReadOnly | DontDelete); @@ -169,12 +169,12 @@ JSObject* throwError(ExecState* exec, JSObject* error) JSObject* throwTypeError(ExecState* exec) { - return throwError(exec, createTypeError(exec, "Type error")); + return throwError(exec, createTypeError(exec, ASCIILiteral("Type error"))); } JSObject* throwSyntaxError(ExecState* exec) { - return throwError(exec, createSyntaxError(exec, "Syntax error")); + return throwError(exec, createSyntaxError(exec, ASCIILiteral("Syntax error"))); } ASSERT_CLASS_FITS_IN_CELL(StrictModeTypeErrorFunction); diff --git a/Source/JavaScriptCore/runtime/Error.h b/Source/JavaScriptCore/runtime/Error.h index 65aea3edc..9c34a0574 100644 --- a/Source/JavaScriptCore/runtime/Error.h +++ b/Source/JavaScriptCore/runtime/Error.h @@ -36,26 +36,25 @@ namespace JSC { class JSObject; class SourceCode; class Structure; - class UString; // Methods to create a range of internal errors. - JSObject* createError(JSGlobalObject*, const UString&); - JSObject* createEvalError(JSGlobalObject*, const UString&); - JSObject* createRangeError(JSGlobalObject*, const UString&); - JSObject* createReferenceError(JSGlobalObject*, const UString&); - JSObject* createSyntaxError(JSGlobalObject*, const UString&); - JSObject* createTypeError(JSGlobalObject*, const UString&); + JSObject* createError(JSGlobalObject*, const String&); + JSObject* createEvalError(JSGlobalObject*, const String&); + JSObject* createRangeError(JSGlobalObject*, const String&); + JSObject* createReferenceError(JSGlobalObject*, const String&); + JSObject* createSyntaxError(JSGlobalObject*, const String&); + JSObject* createTypeError(JSGlobalObject*, const String&); JSObject* createNotEnoughArgumentsError(JSGlobalObject*); - JSObject* createURIError(JSGlobalObject*, const UString&); + JSObject* createURIError(JSGlobalObject*, const String&); // ExecState wrappers. - JS_EXPORT_PRIVATE JSObject* createError(ExecState*, const UString&); - JSObject* createEvalError(ExecState*, const UString&); - JS_EXPORT_PRIVATE JSObject* createRangeError(ExecState*, const UString&); - JS_EXPORT_PRIVATE JSObject* createReferenceError(ExecState*, const UString&); - JS_EXPORT_PRIVATE JSObject* createSyntaxError(ExecState*, const UString&); - JS_EXPORT_PRIVATE JSObject* createTypeError(ExecState*, const UString&); + JS_EXPORT_PRIVATE JSObject* createError(ExecState*, const String&); + JSObject* createEvalError(ExecState*, const String&); + JS_EXPORT_PRIVATE JSObject* createRangeError(ExecState*, const String&); + JS_EXPORT_PRIVATE JSObject* createReferenceError(ExecState*, const String&); + JS_EXPORT_PRIVATE JSObject* createSyntaxError(ExecState*, const String&); + JS_EXPORT_PRIVATE JSObject* createTypeError(ExecState*, const String&); JS_EXPORT_PRIVATE JSObject* createNotEnoughArgumentsError(ExecState*); - JSObject* createURIError(ExecState*, const UString&); + JSObject* createURIError(ExecState*, const String&); // Methods to add bool hasErrorInfo(ExecState*, JSObject* error); @@ -76,7 +75,7 @@ namespace JSC { class StrictModeTypeErrorFunction : public InternalFunction { private: - StrictModeTypeErrorFunction(JSGlobalObject* globalObject, Structure* structure, const UString& message) + StrictModeTypeErrorFunction(JSGlobalObject* globalObject, Structure* structure, const String& message) : InternalFunction(globalObject, structure) , m_message(message) { @@ -87,10 +86,10 @@ namespace JSC { public: typedef InternalFunction Base; - static StrictModeTypeErrorFunction* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, const UString& message) + static StrictModeTypeErrorFunction* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, const String& message) { StrictModeTypeErrorFunction* function = new (NotNull, allocateCell<StrictModeTypeErrorFunction>(*exec->heap())) StrictModeTypeErrorFunction(globalObject, structure, message); - function->finishCreation(exec->globalData(), ""); + function->finishCreation(exec->globalData(), String()); return function; } @@ -126,7 +125,7 @@ namespace JSC { } private: - UString m_message; + String m_message; }; } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/ErrorInstance.cpp b/Source/JavaScriptCore/runtime/ErrorInstance.cpp index 91a6fc40e..9c0fe3e8b 100644 --- a/Source/JavaScriptCore/runtime/ErrorInstance.cpp +++ b/Source/JavaScriptCore/runtime/ErrorInstance.cpp @@ -21,6 +21,8 @@ #include "config.h" #include "ErrorInstance.h" +#include "JSScope.h" + namespace JSC { ASSERT_HAS_TRIVIAL_DESTRUCTOR(ErrorInstance); diff --git a/Source/JavaScriptCore/runtime/ErrorInstance.h b/Source/JavaScriptCore/runtime/ErrorInstance.h index d6fa32f99..894676361 100644 --- a/Source/JavaScriptCore/runtime/ErrorInstance.h +++ b/Source/JavaScriptCore/runtime/ErrorInstance.h @@ -36,7 +36,7 @@ namespace JSC { return Structure::create(globalData, globalObject, prototype, TypeInfo(ErrorInstanceType, StructureFlags), &s_info); } - static ErrorInstance* create(JSGlobalData& globalData, Structure* structure, const UString& message) + static ErrorInstance* create(JSGlobalData& globalData, Structure* structure, const String& message) { ErrorInstance* instance = new (NotNull, allocateCell<ErrorInstance>(globalData.heap)) ErrorInstance(globalData, structure); instance->finishCreation(globalData, message); @@ -45,7 +45,7 @@ namespace JSC { static ErrorInstance* create(ExecState* exec, Structure* structure, JSValue message) { - return create(exec->globalData(), structure, message.isUndefined() ? UString() : message.toString(exec)->value(exec)); + return create(exec->globalData(), structure, message.isUndefined() ? String() : message.toString(exec)->value(exec)); } bool appendSourceToMessage() { return m_appendSourceToMessage; } @@ -55,7 +55,7 @@ namespace JSC { protected: explicit ErrorInstance(JSGlobalData&, Structure*); - void finishCreation(JSGlobalData& globalData, const UString& message) + void finishCreation(JSGlobalData& globalData, const String& message) { Base::finishCreation(globalData); ASSERT(inherits(&s_info)); diff --git a/Source/JavaScriptCore/runtime/ErrorPrototype.cpp b/Source/JavaScriptCore/runtime/ErrorPrototype.cpp index 5dd3e85e2..6c9d6df04 100644 --- a/Source/JavaScriptCore/runtime/ErrorPrototype.cpp +++ b/Source/JavaScriptCore/runtime/ErrorPrototype.cpp @@ -27,7 +27,6 @@ #include "JSStringBuilder.h" #include "ObjectPrototype.h" #include "StringRecursionChecker.h" -#include "UString.h" namespace JSC { @@ -60,7 +59,7 @@ void ErrorPrototype::finishCreation(ExecState* exec, JSGlobalObject*) { Base::finishCreation(exec->globalData(), ""); ASSERT(inherits(&s_info)); - putDirect(exec->globalData(), exec->propertyNames().name, jsNontrivialString(exec, "Error"), DontEnum); + putDirect(exec->globalData(), exec->propertyNames().name, jsNontrivialString(exec, String(ASCIILiteral("Error"))), DontEnum); } bool ErrorPrototype::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot &slot) @@ -97,9 +96,9 @@ EncodedJSValue JSC_HOST_CALL errorProtoFuncToString(ExecState* exec) return JSValue::encode(jsUndefined()); // 4. If name is undefined, then let name be "Error"; else let name be ToString(name). - UString nameString; + String nameString; if (name.isUndefined()) - nameString = "Error"; + nameString = ASCIILiteral("Error"); else { nameString = name.toString(exec)->value(exec); if (exec->hadException()) @@ -114,9 +113,9 @@ EncodedJSValue JSC_HOST_CALL errorProtoFuncToString(ExecState* exec) // (sic) // 6. If msg is undefined, then let msg be the empty String; else let msg be ToString(msg). // 7. If msg is undefined, then let msg be the empty String; else let msg be ToString(msg). - UString messageString; + String messageString; if (message.isUndefined()) - messageString = ""; + messageString = String(); else { messageString = message.toString(exec)->value(exec); if (exec->hadException()) diff --git a/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp b/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp index ce63ae9af..38c525268 100644 --- a/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp +++ b/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp @@ -37,7 +37,6 @@ #include "JSNotAnObject.h" #include "Interpreter.h" #include "Nodes.h" -#include "UStringConcatenate.h" namespace JSC { @@ -48,7 +47,7 @@ const ClassInfo InterruptedExecutionError::s_info = { "InterruptedExecutionError JSValue InterruptedExecutionError::defaultValue(const JSObject*, ExecState* exec, PreferredPrimitiveType hint) { if (hint == PreferString) - return jsNontrivialString(exec, "JavaScript execution exceeded timeout."); + return jsNontrivialString(exec, String(ASCIILiteral("JavaScript execution exceeded timeout."))); return JSValue(std::numeric_limits<double>::quiet_NaN()); } @@ -75,7 +74,7 @@ const ClassInfo TerminatedExecutionError::s_info = { "TerminatedExecutionError", JSValue TerminatedExecutionError::defaultValue(const JSObject*, ExecState* exec, PreferredPrimitiveType hint) { if (hint == PreferString) - return jsNontrivialString(exec, "JavaScript execution terminated."); + return jsNontrivialString(exec, String(ASCIILiteral("JavaScript execution terminated."))); return JSValue(std::numeric_limits<double>::quiet_NaN()); } @@ -97,23 +96,23 @@ bool isTerminatedExecutionException(JSValue value) JSObject* createStackOverflowError(ExecState* exec) { - return createRangeError(exec, "Maximum call stack size exceeded."); + return createRangeError(exec, ASCIILiteral("Maximum call stack size exceeded.")); } JSObject* createStackOverflowError(JSGlobalObject* globalObject) { - return createRangeError(globalObject, "Maximum call stack size exceeded."); + return createRangeError(globalObject, ASCIILiteral("Maximum call stack size exceeded.")); } JSObject* createUndefinedVariableError(ExecState* exec, const Identifier& ident) { - UString message(makeUString("Can't find variable: ", ident.ustring())); + String message(makeString("Can't find variable: ", ident.string())); return createReferenceError(exec, message); } JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValue value) { - UString errorMessage = makeUString("'", value.toString(exec)->value(exec), "' is not a valid argument for '", op, "'"); + String errorMessage = makeString("'", value.toString(exec)->value(exec), "' is not a valid argument for '", op, "'"); JSObject* exception = createTypeError(exec, errorMessage); ASSERT(exception->isErrorInstance()); static_cast<ErrorInstance*>(exception)->setAppendSourceToMessage(); @@ -122,7 +121,7 @@ JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValue value JSObject* createNotAConstructorError(ExecState* exec, JSValue value) { - UString errorMessage = makeUString("'", value.toString(exec)->value(exec), "' is not a constructor"); + String errorMessage = makeString("'", value.toString(exec)->value(exec), "' is not a constructor"); JSObject* exception = createTypeError(exec, errorMessage); ASSERT(exception->isErrorInstance()); static_cast<ErrorInstance*>(exception)->setAppendSourceToMessage(); @@ -131,7 +130,7 @@ JSObject* createNotAConstructorError(ExecState* exec, JSValue value) JSObject* createNotAFunctionError(ExecState* exec, JSValue value) { - UString errorMessage = makeUString("'", value.toString(exec)->value(exec), "' is not a function"); + String errorMessage = makeString("'", value.toString(exec)->value(exec), "' is not a function"); JSObject* exception = createTypeError(exec, errorMessage); ASSERT(exception->isErrorInstance()); static_cast<ErrorInstance*>(exception)->setAppendSourceToMessage(); @@ -140,21 +139,21 @@ JSObject* createNotAFunctionError(ExecState* exec, JSValue value) JSObject* createNotAnObjectError(ExecState* exec, JSValue value) { - UString errorMessage = makeUString("'", value.toString(exec)->value(exec), "' is not an object"); + String errorMessage = makeString("'", value.toString(exec)->value(exec), "' is not an object"); JSObject* exception = createTypeError(exec, errorMessage); ASSERT(exception->isErrorInstance()); static_cast<ErrorInstance*>(exception)->setAppendSourceToMessage(); return exception; } -JSObject* createErrorForInvalidGlobalAssignment(ExecState* exec, const UString& propertyName) +JSObject* createErrorForInvalidGlobalAssignment(ExecState* exec, const String& propertyName) { - return createReferenceError(exec, makeUString("Strict mode forbids implicit creation of global property '", propertyName, "'")); + return createReferenceError(exec, makeString("Strict mode forbids implicit creation of global property '", propertyName, "'")); } JSObject* createOutOfMemoryError(JSGlobalObject* globalObject) { - return createError(globalObject, "Out of memory"); + return createError(globalObject, ASCIILiteral("Out of memory")); } JSObject* throwOutOfMemoryError(ExecState* exec) diff --git a/Source/JavaScriptCore/runtime/ExceptionHelpers.h b/Source/JavaScriptCore/runtime/ExceptionHelpers.h index 7bffd294b..d2daaa044 100644 --- a/Source/JavaScriptCore/runtime/ExceptionHelpers.h +++ b/Source/JavaScriptCore/runtime/ExceptionHelpers.h @@ -49,7 +49,7 @@ JSObject* createNotAnObjectError(ExecState*, JSValue); JSObject* createInvalidParamError(ExecState*, const char* op, JSValue); JSObject* createNotAConstructorError(ExecState*, JSValue); JSObject* createNotAFunctionError(ExecState*, JSValue); -JSObject* createErrorForInvalidGlobalAssignment(ExecState*, const UString&); +JSObject* createErrorForInvalidGlobalAssignment(ExecState*, const String&); JSObject* throwOutOfMemoryError(ExecState*); JSObject* throwStackOverflowError(ExecState*); diff --git a/Source/JavaScriptCore/runtime/Executable.cpp b/Source/JavaScriptCore/runtime/Executable.cpp index 50bb5ffae..b11220bea 100644 --- a/Source/JavaScriptCore/runtime/Executable.cpp +++ b/Source/JavaScriptCore/runtime/Executable.cpp @@ -33,8 +33,8 @@ #include "JIT.h" #include "JITDriver.h" #include "Parser.h" -#include "UStringBuilder.h" #include <wtf/Vector.h> +#include <wtf/text/StringBuilder.h> namespace JSC { @@ -133,26 +133,17 @@ void ProgramExecutable::destroy(JSCell* cell) const ClassInfo FunctionExecutable::s_info = { "FunctionExecutable", &ScriptExecutable::s_info, 0, 0, CREATE_METHOD_TABLE(FunctionExecutable) }; -FunctionExecutable::FunctionExecutable(JSGlobalData& globalData, const Identifier& name, const Identifier& inferredName, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext) - : ScriptExecutable(globalData.functionExecutableStructure.get(), globalData, source, inStrictContext) +FunctionExecutable::FunctionExecutable(JSGlobalData& globalData, FunctionBodyNode* node) + : ScriptExecutable(globalData.functionExecutableStructure.get(), globalData, node->source(), node->isStrictMode()) , m_numCapturedVariables(0) - , m_forceUsesArguments(forceUsesArguments) - , m_parameters(parameters) - , m_name(name) - , m_inferredName(inferredName.isNull() ? globalData.propertyNames->emptyIdentifier : inferredName) - , m_symbolTable(0) -{ -} - -FunctionExecutable::FunctionExecutable(ExecState* exec, const Identifier& name, const Identifier& inferredName, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext) - : ScriptExecutable(exec->globalData().functionExecutableStructure.get(), exec, source, inStrictContext) - , m_numCapturedVariables(0) - , m_forceUsesArguments(forceUsesArguments) - , m_parameters(parameters) - , m_name(name) - , m_inferredName(inferredName.isNull() ? exec->globalData().propertyNames->emptyIdentifier : inferredName) - , m_symbolTable(0) + , m_forceUsesArguments(node->usesArguments()) + , m_parameters(node->parameters()) + , m_name(node->ident()) + , m_inferredName(node->inferredName().isNull() ? globalData.propertyNames->emptyIdentifier : node->inferredName()) + , m_functionNameIsInScopeToggle(node->functionNameIsInScopeToggle()) { + m_firstLine = node->lineNo(); + m_lastLine = node->lastLine(); } void FunctionExecutable::destroy(JSCell* cell) @@ -160,13 +151,13 @@ void FunctionExecutable::destroy(JSCell* cell) static_cast<FunctionExecutable*>(cell)->FunctionExecutable::~FunctionExecutable(); } -JSObject* EvalExecutable::compileOptimized(ExecState* exec, ScopeChainNode* scopeChainNode, unsigned bytecodeIndex) +JSObject* EvalExecutable::compileOptimized(ExecState* exec, JSScope* scope, unsigned bytecodeIndex) { ASSERT(exec->globalData().dynamicGlobalObject); ASSERT(!!m_evalCodeBlock); JSObject* error = 0; if (m_evalCodeBlock->getJITType() != JITCode::topTierJIT()) - error = compileInternal(exec, scopeChainNode, JITCode::nextTierJIT(m_evalCodeBlock->getJITType()), bytecodeIndex); + error = compileInternal(exec, scope, JITCode::nextTierJIT(m_evalCodeBlock->getJITType()), bytecodeIndex); ASSERT(!!m_evalCodeBlock); return error; } @@ -193,7 +184,7 @@ inline const char* samplingDescription(JITCode::JITType jitType) } } -JSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType, unsigned bytecodeIndex) +JSObject* EvalExecutable::compileInternal(ExecState* exec, JSScope* scope, JITCode::JITType jitType, unsigned bytecodeIndex) { SamplingRegion samplingRegion(samplingDescription(jitType)); @@ -211,20 +202,20 @@ JSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scope m_evalCodeBlock = newCodeBlock.release(); } else { if (!lexicalGlobalObject->evalEnabled()) - return throwError(exec, createEvalError(exec, "Eval is disabled")); - RefPtr<EvalNode> evalNode = parse<EvalNode>(globalData, lexicalGlobalObject, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, EvalNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception); + return throwError(exec, createEvalError(exec, ASCIILiteral("Eval is disabled"))); + RefPtr<EvalNode> evalNode = parse<EvalNode>(globalData, lexicalGlobalObject, m_source, 0, Identifier(), isStrictMode() ? JSParseStrict : JSParseNormal, EvalNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception); if (!evalNode) { ASSERT(exception); return exception; } recordParse(evalNode->features(), evalNode->hasCapturedVariables(), evalNode->lineNo(), evalNode->lastLine()); - JSGlobalObject* globalObject = scopeChainNode->globalObject.get(); + JSGlobalObject* globalObject = scope->globalObject(); OwnPtr<CodeBlock> previousCodeBlock = m_evalCodeBlock.release(); ASSERT((jitType == JITCode::bottomTierJIT()) == !previousCodeBlock); - m_evalCodeBlock = adoptPtr(new EvalCodeBlock(this, globalObject, source().provider(), scopeChainNode->localDepth(), previousCodeBlock.release())); - OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(evalNode.get(), scopeChainNode, m_evalCodeBlock->symbolTable(), m_evalCodeBlock.get(), !!m_evalCodeBlock->alternative() ? OptimizingCompilation : FirstCompilation))); + m_evalCodeBlock = adoptPtr(new EvalCodeBlock(this, globalObject, source().provider(), scope->localDepth(), previousCodeBlock.release())); + OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(evalNode.get(), scope, m_evalCodeBlock->symbolTable(), m_evalCodeBlock.get(), !!m_evalCodeBlock->alternative() ? OptimizingCompilation : FirstCompilation))); if ((exception = generator->generate())) { m_evalCodeBlock = static_pointer_cast<EvalCodeBlock>(m_evalCodeBlock->releaseAlternative()); evalNode->destroyData(); @@ -295,20 +286,20 @@ JSObject* ProgramExecutable::checkSyntax(ExecState* exec) JSObject* exception = 0; JSGlobalData* globalData = &exec->globalData(); JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); - RefPtr<ProgramNode> programNode = parse<ProgramNode>(globalData, lexicalGlobalObject, m_source, 0, JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception); + RefPtr<ProgramNode> programNode = parse<ProgramNode>(globalData, lexicalGlobalObject, m_source, 0, Identifier(), JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception); if (programNode) return 0; ASSERT(exception); return exception; } -JSObject* ProgramExecutable::compileOptimized(ExecState* exec, ScopeChainNode* scopeChainNode, unsigned bytecodeIndex) +JSObject* ProgramExecutable::compileOptimized(ExecState* exec, JSScope* scope, unsigned bytecodeIndex) { ASSERT(exec->globalData().dynamicGlobalObject); ASSERT(!!m_programCodeBlock); JSObject* error = 0; if (m_programCodeBlock->getJITType() != JITCode::topTierJIT()) - error = compileInternal(exec, scopeChainNode, JITCode::nextTierJIT(m_programCodeBlock->getJITType()), bytecodeIndex); + error = compileInternal(exec, scope, JITCode::nextTierJIT(m_programCodeBlock->getJITType()), bytecodeIndex); ASSERT(!!m_programCodeBlock); return error; } @@ -320,7 +311,7 @@ bool ProgramExecutable::jitCompile(ExecState* exec) } #endif -JSObject* ProgramExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType, unsigned bytecodeIndex) +JSObject* ProgramExecutable::compileInternal(ExecState* exec, JSScope* scope, JITCode::JITType jitType, unsigned bytecodeIndex) { SamplingRegion samplingRegion(samplingDescription(jitType)); @@ -337,19 +328,19 @@ JSObject* ProgramExecutable::compileInternal(ExecState* exec, ScopeChainNode* sc newCodeBlock->setAlternative(static_pointer_cast<CodeBlock>(m_programCodeBlock.release())); m_programCodeBlock = newCodeBlock.release(); } else { - RefPtr<ProgramNode> programNode = parse<ProgramNode>(globalData, lexicalGlobalObject, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception); + RefPtr<ProgramNode> programNode = parse<ProgramNode>(globalData, lexicalGlobalObject, m_source, 0, Identifier(), isStrictMode() ? JSParseStrict : JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception); if (!programNode) { ASSERT(exception); return exception; } recordParse(programNode->features(), programNode->hasCapturedVariables(), programNode->lineNo(), programNode->lastLine()); - JSGlobalObject* globalObject = scopeChainNode->globalObject.get(); + JSGlobalObject* globalObject = scope->globalObject(); OwnPtr<CodeBlock> previousCodeBlock = m_programCodeBlock.release(); ASSERT((jitType == JITCode::bottomTierJIT()) == !previousCodeBlock); m_programCodeBlock = adoptPtr(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider(), previousCodeBlock.release())); - OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(programNode.get(), scopeChainNode, &globalObject->symbolTable(), m_programCodeBlock.get(), !!m_programCodeBlock->alternative() ? OptimizingCompilation : FirstCompilation))); + OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(programNode.get(), scope, globalObject->symbolTable(), m_programCodeBlock.get(), !!m_programCodeBlock->alternative() ? OptimizingCompilation : FirstCompilation))); if ((exception = generator->generate())) { m_programCodeBlock = static_pointer_cast<ProgramCodeBlock>(m_programCodeBlock->releaseAlternative()); programNode->destroyData(); @@ -433,24 +424,24 @@ FunctionCodeBlock* FunctionExecutable::baselineCodeBlockFor(CodeSpecializationKi return result; } -JSObject* FunctionExecutable::compileOptimizedForCall(ExecState* exec, ScopeChainNode* scopeChainNode, unsigned bytecodeIndex) +JSObject* FunctionExecutable::compileOptimizedForCall(ExecState* exec, JSScope* scope, unsigned bytecodeIndex) { ASSERT(exec->globalData().dynamicGlobalObject); ASSERT(!!m_codeBlockForCall); JSObject* error = 0; if (m_codeBlockForCall->getJITType() != JITCode::topTierJIT()) - error = compileForCallInternal(exec, scopeChainNode, JITCode::nextTierJIT(m_codeBlockForCall->getJITType()), bytecodeIndex); + error = compileForCallInternal(exec, scope, JITCode::nextTierJIT(m_codeBlockForCall->getJITType()), bytecodeIndex); ASSERT(!!m_codeBlockForCall); return error; } -JSObject* FunctionExecutable::compileOptimizedForConstruct(ExecState* exec, ScopeChainNode* scopeChainNode, unsigned bytecodeIndex) +JSObject* FunctionExecutable::compileOptimizedForConstruct(ExecState* exec, JSScope* scope, unsigned bytecodeIndex) { ASSERT(exec->globalData().dynamicGlobalObject); ASSERT(!!m_codeBlockForConstruct); JSObject* error = 0; if (m_codeBlockForConstruct->getJITType() != JITCode::topTierJIT()) - error = compileForConstructInternal(exec, scopeChainNode, JITCode::nextTierJIT(m_codeBlockForConstruct->getJITType()), bytecodeIndex); + error = compileForConstructInternal(exec, scope, JITCode::nextTierJIT(m_codeBlockForConstruct->getJITType()), bytecodeIndex); ASSERT(!!m_codeBlockForConstruct); return error; } @@ -472,15 +463,26 @@ FunctionCodeBlock* FunctionExecutable::codeBlockWithBytecodeFor(CodeSpecializati return baselineCodeBlockFor(kind); } -PassOwnPtr<FunctionCodeBlock> FunctionExecutable::produceCodeBlockFor(ScopeChainNode* scopeChainNode, CompilationKind compilationKind, CodeSpecializationKind specializationKind, JSObject*& exception) +PassOwnPtr<FunctionCodeBlock> FunctionExecutable::produceCodeBlockFor(JSScope* scope, CompilationKind compilationKind, CodeSpecializationKind specializationKind, JSObject*& exception) { if (!!codeBlockFor(specializationKind)) return adoptPtr(new FunctionCodeBlock(CodeBlock::CopyParsedBlock, *codeBlockFor(specializationKind))); exception = 0; - JSGlobalData* globalData = scopeChainNode->globalData; - JSGlobalObject* globalObject = scopeChainNode->globalObject.get(); - RefPtr<FunctionBodyNode> body = parse<FunctionBodyNode>(globalData, globalObject, m_source, m_parameters.get(), isStrictMode() ? JSParseStrict : JSParseNormal, FunctionBodyNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, 0, 0, &exception); + JSGlobalData* globalData = scope->globalData(); + JSGlobalObject* globalObject = scope->globalObject(); + RefPtr<FunctionBodyNode> body = parse<FunctionBodyNode>( + globalData, + globalObject, + m_source, + m_parameters.get(), + name(), + isStrictMode() ? JSParseStrict : JSParseNormal, + FunctionBodyNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, + 0, + 0, + &exception + ); if (!body) { ASSERT(exception); @@ -488,13 +490,13 @@ PassOwnPtr<FunctionCodeBlock> FunctionExecutable::produceCodeBlockFor(ScopeChain } if (m_forceUsesArguments) body->setUsesArguments(); - body->finishParsing(m_parameters, m_name); + body->finishParsing(m_parameters, m_name, m_functionNameIsInScopeToggle); recordParse(body->features(), body->hasCapturedVariables(), body->lineNo(), body->lastLine()); OwnPtr<FunctionCodeBlock> result; ASSERT((compilationKind == FirstCompilation) == !codeBlockFor(specializationKind)); result = adoptPtr(new FunctionCodeBlock(this, FunctionCode, globalObject, source().provider(), source().startOffset(), specializationKind == CodeForConstruct)); - OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(body.get(), scopeChainNode, result->symbolTable(), result.get(), compilationKind))); + OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(body.get(), scope, result->symbolTable(), result.get(), compilationKind))); exception = generator->generate(); body->destroyData(); if (exception) @@ -504,7 +506,7 @@ PassOwnPtr<FunctionCodeBlock> FunctionExecutable::produceCodeBlockFor(ScopeChain return result.release(); } -JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType, unsigned bytecodeIndex) +JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, JSScope* scope, JITCode::JITType jitType, unsigned bytecodeIndex) { SamplingRegion samplingRegion(samplingDescription(jitType)); @@ -516,7 +518,7 @@ JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChain #endif ASSERT((jitType == JITCode::bottomTierJIT()) == !m_codeBlockForCall); JSObject* exception; - OwnPtr<FunctionCodeBlock> newCodeBlock = produceCodeBlockFor(scopeChainNode, !!m_codeBlockForCall ? OptimizingCompilation : FirstCompilation, CodeForCall, exception); + OwnPtr<FunctionCodeBlock> newCodeBlock = produceCodeBlockFor(scope, !!m_codeBlockForCall ? OptimizingCompilation : FirstCompilation, CodeForCall, exception); if (!newCodeBlock) return exception; @@ -526,7 +528,7 @@ JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChain m_numParametersForCall = m_codeBlockForCall->numParameters(); ASSERT(m_numParametersForCall); m_numCapturedVariables = m_codeBlockForCall->m_numCapturedVars; - m_symbolTable = m_codeBlockForCall->sharedSymbolTable(); + m_symbolTable.set(exec->globalData(), this, m_codeBlockForCall->symbolTable()); #if ENABLE(JIT) if (!prepareFunctionForExecution(exec, m_codeBlockForCall, m_jitCodeForCall, m_jitCodeForCallWithArityCheck, m_symbolTable, jitType, bytecodeIndex, CodeForCall)) @@ -547,7 +549,7 @@ JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChain return 0; } -JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType, unsigned bytecodeIndex) +JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, JSScope* scope, JITCode::JITType jitType, unsigned bytecodeIndex) { SamplingRegion samplingRegion(samplingDescription(jitType)); @@ -559,7 +561,7 @@ JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, Scope ASSERT((jitType == JITCode::bottomTierJIT()) == !m_codeBlockForConstruct); JSObject* exception; - OwnPtr<FunctionCodeBlock> newCodeBlock = produceCodeBlockFor(scopeChainNode, !!m_codeBlockForConstruct ? OptimizingCompilation : FirstCompilation, CodeForConstruct, exception); + OwnPtr<FunctionCodeBlock> newCodeBlock = produceCodeBlockFor(scope, !!m_codeBlockForConstruct ? OptimizingCompilation : FirstCompilation, CodeForConstruct, exception); if (!newCodeBlock) return exception; @@ -569,7 +571,7 @@ JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, Scope m_numParametersForConstruct = m_codeBlockForConstruct->numParameters(); ASSERT(m_numParametersForConstruct); m_numCapturedVariables = m_codeBlockForConstruct->m_numCapturedVars; - m_symbolTable = m_codeBlockForConstruct->sharedSymbolTable(); + m_symbolTable.set(exec->globalData(), this, m_codeBlockForConstruct->symbolTable()); #if ENABLE(JIT) if (!prepareFunctionForExecution(exec, m_codeBlockForConstruct, m_jitCodeForConstruct, m_jitCodeForConstructWithArityCheck, m_symbolTable, jitType, bytecodeIndex, CodeForConstruct)) @@ -613,8 +615,8 @@ void FunctionExecutable::visitChildren(JSCell* cell, SlotVisitor& visitor) COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); ScriptExecutable::visitChildren(thisObject, visitor); - if (thisObject->m_nameValue) - visitor.append(&thisObject->m_nameValue); + visitor.append(&thisObject->m_nameValue); + visitor.append(&thisObject->m_symbolTable); if (thisObject->m_codeBlockForCall) thisObject->m_codeBlockForCall->visitAggregate(visitor); if (thisObject->m_codeBlockForConstruct) @@ -649,16 +651,16 @@ void FunctionExecutable::unlinkCalls() #endif } -FunctionExecutable* FunctionExecutable::fromGlobalCode(const Identifier& functionName, ExecState* exec, Debugger* debugger, const SourceCode& source, JSObject** exception) +FunctionExecutable* FunctionExecutable::fromGlobalCode(const Identifier& name, ExecState* exec, Debugger* debugger, const SourceCode& source, JSObject** exception) { JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject(); - RefPtr<ProgramNode> program = parse<ProgramNode>(&exec->globalData(), lexicalGlobalObject, source, 0, JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, debugger, exec, exception); + RefPtr<ProgramNode> program = parse<ProgramNode>(&exec->globalData(), lexicalGlobalObject, source, 0, Identifier(), JSParseNormal, ProgramNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, debugger, exec, exception); if (!program) { ASSERT(*exception); return 0; } - // Uses of this function that would not result in a single function expression are invalid. + // This function assumes an input string that would result in a single anonymous function expression. StatementNode* exprStatement = program->singleStatement(); ASSERT(exprStatement); ASSERT(exprStatement->isExprStatement()); @@ -667,20 +669,23 @@ FunctionExecutable* FunctionExecutable::fromGlobalCode(const Identifier& functio ASSERT(funcExpr->isFuncExprNode()); FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body(); ASSERT(body); + ASSERT(body->ident().isNull()); - return FunctionExecutable::create(exec->globalData(), functionName, functionName, body->source(), body->usesArguments(), body->parameters(), body->isStrictMode(), body->lineNo(), body->lastLine()); + FunctionExecutable* functionExecutable = FunctionExecutable::create(exec->globalData(), body); + functionExecutable->m_nameValue.set(exec->globalData(), functionExecutable, jsString(&exec->globalData(), name.string())); + return functionExecutable; } -UString FunctionExecutable::paramString() const +String FunctionExecutable::paramString() const { FunctionParameters& parameters = *m_parameters; - UStringBuilder builder; + StringBuilder builder; for (size_t pos = 0; pos < parameters.size(); ++pos) { if (!builder.isEmpty()) - builder.append(", "); - builder.append(parameters[pos].ustring()); + builder.appendLiteral(", "); + builder.append(parameters[pos].string()); } - return builder.toUString(); + return builder.toString(); } } diff --git a/Source/JavaScriptCore/runtime/Executable.h b/Source/JavaScriptCore/runtime/Executable.h index 2e5ba28ca..f63cc7f99 100644 --- a/Source/JavaScriptCore/runtime/Executable.h +++ b/Source/JavaScriptCore/runtime/Executable.h @@ -28,8 +28,10 @@ #include "CallData.h" #include "CodeSpecializationKind.h" +#include "HandlerInfo.h" #include "JSFunction.h" #include "Interpreter.h" +#include "LLIntCLoop.h" #include "Nodes.h" #include "SamplingTool.h" #include <wtf/PassOwnPtr.h> @@ -42,7 +44,7 @@ namespace JSC { class FunctionCodeBlock; class LLIntOffsetsExtractor; class ProgramCodeBlock; - class ScopeChainNode; + class JSScope; enum CompilationKind { FirstCompilation, OptimizingCompilation }; @@ -200,7 +202,47 @@ namespace JSC { ASSERT(kind == CodeForConstruct); return OBJECT_OFFSETOF(ExecutableBase, m_numParametersForConstruct); } -#endif +#endif // ENABLE(JIT) + +#if ENABLE(JIT) || ENABLE(LLINT_C_LOOP) + MacroAssemblerCodePtr hostCodeEntryFor(CodeSpecializationKind kind) + { + #if ENABLE(JIT) + return generatedJITCodeFor(kind).addressForCall(); + #else + return LLInt::CLoop::hostCodeEntryFor(kind); + #endif + } + + MacroAssemblerCodePtr jsCodeEntryFor(CodeSpecializationKind kind) + { + #if ENABLE(JIT) + return generatedJITCodeFor(kind).addressForCall(); + #else + return LLInt::CLoop::jsCodeEntryFor(kind); + #endif + } + + MacroAssemblerCodePtr jsCodeWithArityCheckEntryFor(CodeSpecializationKind kind) + { + #if ENABLE(JIT) + return generatedJITCodeWithArityCheckFor(kind); + #else + return LLInt::CLoop::jsCodeEntryWithArityCheckFor(kind); + #endif + } + + static void* catchRoutineFor(HandlerInfo* handler, Instruction* catchPCForInterpreter) + { + #if ENABLE(JIT) + UNUSED_PARAM(catchPCForInterpreter); + return handler->nativeCode.executableAddress(); + #else + UNUSED_PARAM(handler); + return LLInt::CLoop::catchRoutineFor(catchPCForInterpreter); + #endif + } +#endif // ENABLE(JIT || ENABLE(LLINT_C_LOOP) protected: ExecutableBase* m_prev; @@ -236,7 +278,7 @@ namespace JSC { } #endif -#if ENABLE(CLASSIC_INTERPRETER) +#if ENABLE(CLASSIC_INTERPRETER) || ENABLE(LLINT_C_LOOP) static NativeExecutable* create(JSGlobalData& globalData, NativeFunction function, NativeFunction constructor) { ASSERT(!globalData.canUseJIT()); @@ -320,7 +362,7 @@ namespace JSC { const SourceCode& source() { return m_source; } intptr_t sourceID() const { return m_source.providerID(); } - const UString& sourceURL() const { return m_source.provider()->url(); } + const String& sourceURL() const { return m_source.provider()->url(); } int lineNo() const { return m_firstLine; } int lastLine() const { return m_lastLine; } @@ -367,17 +409,17 @@ namespace JSC { static void destroy(JSCell*); - JSObject* compile(ExecState* exec, ScopeChainNode* scopeChainNode) + JSObject* compile(ExecState* exec, JSScope* scope) { ASSERT(exec->globalData().dynamicGlobalObject); JSObject* error = 0; if (!m_evalCodeBlock) - error = compileInternal(exec, scopeChainNode, JITCode::bottomTierJIT()); + error = compileInternal(exec, scope, JITCode::bottomTierJIT()); ASSERT(!error == !!m_evalCodeBlock); return error; } - JSObject* compileOptimized(ExecState*, ScopeChainNode*, unsigned bytecodeIndex); + JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex); #if ENABLE(JIT) void jettisonOptimizedCode(JSGlobalData&); @@ -418,7 +460,7 @@ namespace JSC { static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags; EvalExecutable(ExecState*, const SourceCode&, bool); - JSObject* compileInternal(ExecState*, ScopeChainNode*, JITCode::JITType, unsigned bytecodeIndex = UINT_MAX); + JSObject* compileInternal(ExecState*, JSScope*, JITCode::JITType, unsigned bytecodeIndex = UINT_MAX); static void visitChildren(JSCell*, SlotVisitor&); OwnPtr<EvalCodeBlock> m_evalCodeBlock; @@ -438,17 +480,17 @@ namespace JSC { static void destroy(JSCell*); - JSObject* compile(ExecState* exec, ScopeChainNode* scopeChainNode) + JSObject* compile(ExecState* exec, JSScope* scope) { ASSERT(exec->globalData().dynamicGlobalObject); JSObject* error = 0; if (!m_programCodeBlock) - error = compileInternal(exec, scopeChainNode, JITCode::bottomTierJIT()); + error = compileInternal(exec, scope, JITCode::bottomTierJIT()); ASSERT(!error == !!m_programCodeBlock); return error; } - JSObject* compileOptimized(ExecState*, ScopeChainNode*, unsigned bytecodeIndex); + JSObject* compileOptimized(ExecState*, JSScope*, unsigned bytecodeIndex); #if ENABLE(JIT) void jettisonOptimizedCode(JSGlobalData&); @@ -485,7 +527,7 @@ namespace JSC { static const unsigned StructureFlags = OverridesVisitChildren | ScriptExecutable::StructureFlags; ProgramExecutable(ExecState*, const SourceCode&); - JSObject* compileInternal(ExecState*, ScopeChainNode*, JITCode::JITType, unsigned bytecodeIndex = UINT_MAX); + JSObject* compileInternal(ExecState*, JSScope*, JITCode::JITType, unsigned bytecodeIndex = UINT_MAX); static void visitChildren(JSCell*, SlotVisitor&); OwnPtr<ProgramCodeBlock> m_programCodeBlock; @@ -497,27 +539,16 @@ namespace JSC { public: typedef ScriptExecutable Base; - static FunctionExecutable* create(ExecState* exec, const Identifier& name, const Identifier& inferredName, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine) - { - FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(*exec->heap())) FunctionExecutable(exec, name, inferredName, source, forceUsesArguments, parameters, isInStrictContext); - executable->finishCreation(exec->globalData(), name, firstLine, lastLine); - return executable; - } - - static FunctionExecutable* create(JSGlobalData& globalData, const Identifier& name, const Identifier& inferredName, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine) + static FunctionExecutable* create(JSGlobalData& globalData, FunctionBodyNode* node) { - FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(globalData.heap)) FunctionExecutable(globalData, name, inferredName, source, forceUsesArguments, parameters, isInStrictContext); - executable->finishCreation(globalData, name, firstLine, lastLine); + FunctionExecutable* executable = new (NotNull, allocateCell<FunctionExecutable>(globalData.heap)) FunctionExecutable(globalData, node); + executable->finishCreation(globalData); return executable; } + static FunctionExecutable* fromGlobalCode(const Identifier& name, ExecState*, Debugger*, const SourceCode&, JSObject** exception); static void destroy(JSCell*); - JSFunction* make(ExecState* exec, ScopeChainNode* scopeChain) - { - return JSFunction::create(exec, this, scopeChain); - } - // Returns either call or construct bytecode. This can be appropriate // for answering questions that that don't vary between call and construct -- // for example, argumentsRegister(). @@ -531,19 +562,19 @@ namespace JSC { FunctionCodeBlock* codeBlockWithBytecodeFor(CodeSpecializationKind); - PassOwnPtr<FunctionCodeBlock> produceCodeBlockFor(ScopeChainNode*, CompilationKind, CodeSpecializationKind, JSObject*& exception); + PassOwnPtr<FunctionCodeBlock> produceCodeBlockFor(JSScope*, CompilationKind, CodeSpecializationKind, JSObject*& exception); - JSObject* compileForCall(ExecState* exec, ScopeChainNode* scopeChainNode) + JSObject* compileForCall(ExecState* exec, JSScope* scope) { ASSERT(exec->globalData().dynamicGlobalObject); JSObject* error = 0; if (!m_codeBlockForCall) - error = compileForCallInternal(exec, scopeChainNode, JITCode::bottomTierJIT()); + error = compileForCallInternal(exec, scope, JITCode::bottomTierJIT()); ASSERT(!error == !!m_codeBlockForCall); return error; } - JSObject* compileOptimizedForCall(ExecState*, ScopeChainNode*, unsigned bytecodeIndex); + JSObject* compileOptimizedForCall(ExecState*, JSScope*, unsigned bytecodeIndex); #if ENABLE(JIT) void jettisonOptimizedCodeForCall(JSGlobalData&); @@ -561,17 +592,17 @@ namespace JSC { return *m_codeBlockForCall; } - JSObject* compileForConstruct(ExecState* exec, ScopeChainNode* scopeChainNode) + JSObject* compileForConstruct(ExecState* exec, JSScope* scope) { ASSERT(exec->globalData().dynamicGlobalObject); JSObject* error = 0; if (!m_codeBlockForConstruct) - error = compileForConstructInternal(exec, scopeChainNode, JITCode::bottomTierJIT()); + error = compileForConstructInternal(exec, scope, JITCode::bottomTierJIT()); ASSERT(!error == !!m_codeBlockForConstruct); return error; } - JSObject* compileOptimizedForConstruct(ExecState*, ScopeChainNode*, unsigned bytecodeIndex); + JSObject* compileOptimizedForConstruct(ExecState*, JSScope*, unsigned bytecodeIndex); #if ENABLE(JIT) void jettisonOptimizedCodeForConstruct(JSGlobalData&); @@ -589,28 +620,28 @@ namespace JSC { return *m_codeBlockForConstruct; } - JSObject* compileFor(ExecState* exec, ScopeChainNode* scopeChainNode, CodeSpecializationKind kind) + JSObject* compileFor(ExecState* exec, JSScope* scope, CodeSpecializationKind kind) { ASSERT(exec->callee()); ASSERT(exec->callee()->inherits(&JSFunction::s_info)); ASSERT(jsCast<JSFunction*>(exec->callee())->jsExecutable() == this); if (kind == CodeForCall) - return compileForCall(exec, scopeChainNode); + return compileForCall(exec, scope); ASSERT(kind == CodeForConstruct); - return compileForConstruct(exec, scopeChainNode); + return compileForConstruct(exec, scope); } - JSObject* compileOptimizedFor(ExecState* exec, ScopeChainNode* scopeChainNode, unsigned bytecodeIndex, CodeSpecializationKind kind) + JSObject* compileOptimizedFor(ExecState* exec, JSScope* scope, unsigned bytecodeIndex, CodeSpecializationKind kind) { ASSERT(exec->callee()); ASSERT(exec->callee()->inherits(&JSFunction::s_info)); ASSERT(jsCast<JSFunction*>(exec->callee())->jsExecutable() == this); if (kind == CodeForCall) - return compileOptimizedForCall(exec, scopeChainNode, bytecodeIndex); + return compileOptimizedForCall(exec, scope, bytecodeIndex); ASSERT(kind == CodeForConstruct); - return compileOptimizedForConstruct(exec, scopeChainNode, bytecodeIndex); + return compileOptimizedForConstruct(exec, scope, bytecodeIndex); } #if ENABLE(JIT) @@ -661,12 +692,11 @@ namespace JSC { JSString* nameValue() const { return m_nameValue.get(); } size_t parameterCount() const { return m_parameters->size(); } // Excluding 'this'! unsigned capturedVariableCount() const { return m_numCapturedVariables; } - UString paramString() const; - SharedSymbolTable* symbolTable() const { return m_symbolTable; } + String paramString() const; + SharedSymbolTable* symbolTable() const { return m_symbolTable.get(); } void clearCodeIfNotCompiling(); static void visitChildren(JSCell*, SlotVisitor&); - static FunctionExecutable* fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, JSObject** exception); static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(globalData, globalObject, proto, TypeInfo(FunctionExecutableType, StructureFlags), &s_info); @@ -679,20 +709,17 @@ namespace JSC { void clearCode(); protected: - void finishCreation(JSGlobalData& globalData, const Identifier& name, int firstLine, int lastLine) + void finishCreation(JSGlobalData& globalData) { Base::finishCreation(globalData); - m_firstLine = firstLine; - m_lastLine = lastLine; - m_nameValue.set(globalData, this, jsString(&globalData, name.ustring())); + m_nameValue.set(globalData, this, jsString(&globalData, name().string())); } private: - FunctionExecutable(JSGlobalData&, const Identifier& name, const Identifier& inferredName, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool); - FunctionExecutable(ExecState*, const Identifier& name, const Identifier& inferredName, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool); + FunctionExecutable(JSGlobalData&, FunctionBodyNode*); - JSObject* compileForCallInternal(ExecState*, ScopeChainNode*, JITCode::JITType, unsigned bytecodeIndex = UINT_MAX); - JSObject* compileForConstructInternal(ExecState*, ScopeChainNode*, JITCode::JITType, unsigned bytecodeIndex = UINT_MAX); + JSObject* compileForCallInternal(ExecState*, JSScope*, JITCode::JITType, unsigned bytecodeIndex = UINT_MAX); + JSObject* compileForConstructInternal(ExecState*, JSScope*, JITCode::JITType, unsigned bytecodeIndex = UINT_MAX); OwnPtr<FunctionCodeBlock>& codeBlockFor(CodeSpecializationKind kind) { @@ -722,8 +749,9 @@ namespace JSC { OwnPtr<FunctionCodeBlock> m_codeBlockForConstruct; Identifier m_name; Identifier m_inferredName; + FunctionNameIsInScopeToggle m_functionNameIsInScopeToggle; WriteBarrier<JSString> m_nameValue; - SharedSymbolTable* m_symbolTable; + WriteBarrier<SharedSymbolTable> m_symbolTable; }; inline FunctionExecutable* JSFunction::jsExecutable() const diff --git a/Source/JavaScriptCore/runtime/ExecutionHarness.h b/Source/JavaScriptCore/runtime/ExecutionHarness.h index 3a876402e..065788aee 100644 --- a/Source/JavaScriptCore/runtime/ExecutionHarness.h +++ b/Source/JavaScriptCore/runtime/ExecutionHarness.h @@ -49,7 +49,7 @@ inline bool prepareForExecution(ExecState* exec, OwnPtr<CodeBlockType>& codeBloc return jitCompileIfAppropriate(exec, codeBlock, jitCode, jitType, bytecodeIndex, JITCode::isBaselineCode(jitType) ? JITCompilationMustSucceed : JITCompilationCanFail); } -inline bool prepareFunctionForExecution(ExecState* exec, OwnPtr<FunctionCodeBlock>& codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, SharedSymbolTable*& symbolTable, JITCode::JITType jitType, unsigned bytecodeIndex, CodeSpecializationKind kind) +inline bool prepareFunctionForExecution(ExecState* exec, OwnPtr<FunctionCodeBlock>& codeBlock, JITCode& jitCode, MacroAssemblerCodePtr& jitCodeWithArityCheck, WriteBarrier<SharedSymbolTable>& symbolTable, JITCode::JITType jitType, unsigned bytecodeIndex, CodeSpecializationKind kind) { #if ENABLE(LLINT) if (JITCode::isBaselineCode(jitType)) { diff --git a/Source/JavaScriptCore/runtime/FunctionConstructor.cpp b/Source/JavaScriptCore/runtime/FunctionConstructor.cpp index 7f82a74ce..40507dae1 100644 --- a/Source/JavaScriptCore/runtime/FunctionConstructor.cpp +++ b/Source/JavaScriptCore/runtime/FunctionConstructor.cpp @@ -30,8 +30,7 @@ #include "Lexer.h" #include "Nodes.h" #include "Parser.h" -#include "UStringBuilder.h" -#include "UStringConcatenate.h" +#include <wtf/text/StringBuilder.h> namespace JSC { @@ -80,38 +79,37 @@ CallType FunctionConstructor::getCallData(JSCell*, CallData& callData) } // ECMA 15.3.2 The Function Constructor -JSObject* constructFunction(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args, const Identifier& functionName, const UString& sourceURL, const TextPosition& position) +JSObject* constructFunction(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args, const Identifier& functionName, const String& sourceURL, const TextPosition& position) { if (!globalObject->evalEnabled()) - return throwError(exec, createEvalError(exec, "Function constructor is disabled")); + return throwError(exec, createEvalError(exec, ASCIILiteral("Function constructor is disabled"))); return constructFunctionSkippingEvalEnabledCheck(exec, globalObject, args, functionName, sourceURL, position); } -JSObject* constructFunctionSkippingEvalEnabledCheck(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args, const Identifier& functionName, const UString& sourceURL, const TextPosition& position) +JSObject* constructFunctionSkippingEvalEnabledCheck(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args, const Identifier& functionName, const String& sourceURL, const TextPosition& position) { // Functions need to have a space following the opening { due to for web compatibility // see https://bugs.webkit.org/show_bug.cgi?id=24350 // We also need \n before the closing } to handle // comments at the end of the last line - UString program; + String program; if (args.isEmpty()) - program = "(function() { \n})"; + program = ASCIILiteral("(function() { \n})"); else if (args.size() == 1) - program = makeUString("(function() { ", args.at(0).toString(exec)->value(exec), "\n})"); + program = makeString("(function() { ", args.at(0).toString(exec)->value(exec), "\n})"); else { - UStringBuilder builder; - builder.append("(function("); + StringBuilder builder; + builder.appendLiteral("(function("); builder.append(args.at(0).toString(exec)->value(exec)); for (size_t i = 1; i < args.size() - 1; i++) { - builder.append(","); + builder.append(','); builder.append(args.at(i).toString(exec)->value(exec)); } - builder.append(") { "); + builder.appendLiteral(") { "); builder.append(args.at(args.size() - 1).toString(exec)->value(exec)); - builder.append("\n})"); - program = builder.toUString(); + builder.appendLiteral("\n})"); + program = builder.toString(); } - JSGlobalData& globalData = globalObject->globalData(); SourceCode source = makeSource(program, sourceURL, position); JSObject* exception = 0; FunctionExecutable* function = FunctionExecutable::fromGlobalCode(functionName, exec, exec->dynamicGlobalObject()->debugger(), source, &exception); @@ -120,14 +118,13 @@ JSObject* constructFunctionSkippingEvalEnabledCheck(ExecState* exec, JSGlobalObj return throwError(exec, exception); } - ScopeChainNode* scopeChain = ScopeChainNode::create(exec, 0, globalObject, &globalData, globalObject, exec->globalThisValue()); - return JSFunction::create(exec, function, scopeChain); + return JSFunction::create(exec, function, globalObject); } // ECMA 15.3.2 The Function Constructor JSObject* constructFunction(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args) { - return constructFunction(exec, globalObject, args, Identifier(exec, "anonymous"), UString(), TextPosition::minimumPosition()); + return constructFunction(exec, globalObject, args, Identifier(exec, "anonymous"), String(), TextPosition::minimumPosition()); } } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/FunctionConstructor.h b/Source/JavaScriptCore/runtime/FunctionConstructor.h index 31986b70a..99eafee80 100644 --- a/Source/JavaScriptCore/runtime/FunctionConstructor.h +++ b/Source/JavaScriptCore/runtime/FunctionConstructor.h @@ -56,10 +56,10 @@ namespace JSC { static CallType getCallData(JSCell*, CallData&); }; - JSObject* constructFunction(ExecState*, JSGlobalObject*, const ArgList&, const Identifier& functionName, const UString& sourceURL, const WTF::TextPosition&); + JSObject* constructFunction(ExecState*, JSGlobalObject*, const ArgList&, const Identifier& functionName, const String& sourceURL, const WTF::TextPosition&); JSObject* constructFunction(ExecState*, JSGlobalObject*, const ArgList&); - JS_EXPORT_PRIVATE JSObject* constructFunctionSkippingEvalEnabledCheck(ExecState*, JSGlobalObject*, const ArgList&, const Identifier&, const UString&, const WTF::TextPosition&); + JS_EXPORT_PRIVATE JSObject* constructFunctionSkippingEvalEnabledCheck(ExecState*, JSGlobalObject*, const ArgList&, const Identifier&, const String&, const WTF::TextPosition&); } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/FunctionPrototype.cpp b/Source/JavaScriptCore/runtime/FunctionPrototype.cpp index 4206cf2b0..455a21877 100644 --- a/Source/JavaScriptCore/runtime/FunctionPrototype.cpp +++ b/Source/JavaScriptCore/runtime/FunctionPrototype.cpp @@ -47,7 +47,7 @@ FunctionPrototype::FunctionPrototype(JSGlobalObject* globalObject, Structure* st { } -void FunctionPrototype::finishCreation(ExecState* exec, const UString& name) +void FunctionPrototype::finishCreation(ExecState* exec, const String& name) { Base::finishCreation(exec->globalData(), name); putDirectWithoutTransition(exec->globalData(), exec->propertyNames().length, jsNumber(0), DontDelete | ReadOnly | DontEnum); @@ -55,16 +55,16 @@ void FunctionPrototype::finishCreation(ExecState* exec, const UString& name) void FunctionPrototype::addFunctionProperties(ExecState* exec, JSGlobalObject* globalObject, JSFunction** callFunction, JSFunction** applyFunction) { - JSFunction* toStringFunction = JSFunction::create(exec, globalObject, 0, exec->propertyNames().toString.ustring(), functionProtoFuncToString); + JSFunction* toStringFunction = JSFunction::create(exec, globalObject, 0, exec->propertyNames().toString.string(), functionProtoFuncToString); putDirectWithoutTransition(exec->globalData(), exec->propertyNames().toString, toStringFunction, DontEnum); - *applyFunction = JSFunction::create(exec, globalObject, 2, exec->propertyNames().apply.ustring(), functionProtoFuncApply); + *applyFunction = JSFunction::create(exec, globalObject, 2, exec->propertyNames().apply.string(), functionProtoFuncApply); putDirectWithoutTransition(exec->globalData(), exec->propertyNames().apply, *applyFunction, DontEnum); - *callFunction = JSFunction::create(exec, globalObject, 1, exec->propertyNames().call.ustring(), functionProtoFuncCall); + *callFunction = JSFunction::create(exec, globalObject, 1, exec->propertyNames().call.string(), functionProtoFuncCall); putDirectWithoutTransition(exec->globalData(), exec->propertyNames().call, *callFunction, DontEnum); - JSFunction* bindFunction = JSFunction::create(exec, globalObject, 1, exec->propertyNames().bind.ustring(), functionProtoFuncBind); + JSFunction* bindFunction = JSFunction::create(exec, globalObject, 1, exec->propertyNames().bind.string(), functionProtoFuncBind); putDirectWithoutTransition(exec->globalData(), exec->propertyNames().bind, bindFunction, DontEnum); } @@ -83,7 +83,7 @@ CallType FunctionPrototype::getCallData(JSCell*, CallData& callData) // Functions // Compatibility hack for the Optimost JavaScript library. (See <rdar://problem/6595040>.) -static inline void insertSemicolonIfNeeded(UString& functionBody) +static inline void insertSemicolonIfNeeded(String& functionBody) { ASSERT(functionBody[0] == '{'); ASSERT(functionBody[functionBody.length() - 1] == '}'); @@ -92,7 +92,7 @@ static inline void insertSemicolonIfNeeded(UString& functionBody) UChar ch = functionBody[i]; if (!Lexer<UChar>::isWhiteSpace(ch) && !Lexer<UChar>::isLineTerminator(ch)) { if (ch != ';' && ch != '}') - functionBody = makeUString(functionBody.substringSharingImpl(0, i + 1), ";", functionBody.substringSharingImpl(i + 1, functionBody.length() - (i + 1))); + functionBody = makeString(functionBody.substringSharingImpl(0, i + 1), ";", functionBody.substringSharingImpl(i + 1, functionBody.length() - (i + 1))); return; } } @@ -106,7 +106,7 @@ EncodedJSValue JSC_HOST_CALL functionProtoFuncToString(ExecState* exec) if (function->isHostFunction()) return JSValue::encode(jsMakeNontrivialString(exec, "function ", function->name(exec), "() {\n [native code]\n}")); FunctionExecutable* executable = function->jsExecutable(); - UString sourceString = executable->source().toString(); + String sourceString = executable->source().toString(); insertSemicolonIfNeeded(sourceString); return JSValue::encode(jsMakeNontrivialString(exec, "function ", function->name(exec), "(", executable->paramString(), ") ", sourceString)); } diff --git a/Source/JavaScriptCore/runtime/FunctionPrototype.h b/Source/JavaScriptCore/runtime/FunctionPrototype.h index 59427912b..07f381306 100644 --- a/Source/JavaScriptCore/runtime/FunctionPrototype.h +++ b/Source/JavaScriptCore/runtime/FunctionPrototype.h @@ -32,7 +32,7 @@ namespace JSC { static FunctionPrototype* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure) { FunctionPrototype* prototype = new (NotNull, allocateCell<FunctionPrototype>(*exec->heap())) FunctionPrototype(globalObject, structure); - prototype->finishCreation(exec, ""); + prototype->finishCreation(exec, String()); return prototype; } @@ -46,7 +46,7 @@ namespace JSC { static const ClassInfo s_info; protected: - void finishCreation(ExecState*, const UString& name); + void finishCreation(ExecState*, const String& name); private: FunctionPrototype(JSGlobalObject*, Structure*); diff --git a/Source/JavaScriptCore/runtime/GCActivityCallback.cpp b/Source/JavaScriptCore/runtime/GCActivityCallback.cpp index c2fca8c01..74cbdbaef 100644 --- a/Source/JavaScriptCore/runtime/GCActivityCallback.cpp +++ b/Source/JavaScriptCore/runtime/GCActivityCallback.cpp @@ -34,7 +34,7 @@ #include "JSGlobalData.h" #include "JSLock.h" #include "JSObject.h" -#include "ScopeChain.h" + #include <wtf/RetainPtr.h> #include <wtf/WTFThreadData.h> diff --git a/Source/JavaScriptCore/runtime/GCActivityCallback.h b/Source/JavaScriptCore/runtime/GCActivityCallback.h index 67ee17420..c112a7120 100644 --- a/Source/JavaScriptCore/runtime/GCActivityCallback.h +++ b/Source/JavaScriptCore/runtime/GCActivityCallback.h @@ -42,6 +42,7 @@ namespace JSC { class Heap; class GCActivityCallback : public HeapTimer { + WTF_MAKE_FAST_ALLOCATED; public: virtual void didAllocate(size_t) { } virtual void willCollect() { } diff --git a/Source/JavaScriptCore/runtime/GetterSetter.cpp b/Source/JavaScriptCore/runtime/GetterSetter.cpp index 920399dda..8ed582548 100644 --- a/Source/JavaScriptCore/runtime/GetterSetter.cpp +++ b/Source/JavaScriptCore/runtime/GetterSetter.cpp @@ -39,10 +39,8 @@ void GetterSetter::visitChildren(JSCell* cell, SlotVisitor& visitor) ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); JSCell::visitChildren(thisObject, visitor); - if (thisObject->m_getter) - visitor.append(&thisObject->m_getter); - if (thisObject->m_setter) - visitor.append(&thisObject->m_setter); + visitor.append(&thisObject->m_getter); + visitor.append(&thisObject->m_setter); } } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/Identifier.cpp b/Source/JavaScriptCore/runtime/Identifier.cpp index 0fc54f3c6..a9a2a66bf 100644 --- a/Source/JavaScriptCore/runtime/Identifier.cpp +++ b/Source/JavaScriptCore/runtime/Identifier.cpp @@ -23,10 +23,10 @@ #include "CallFrame.h" #include "JSObject.h" +#include "JSScope.h" #include "NumericStrings.h" -#include "ScopeChain.h" -#include <new> // for placement new -#include <string.h> // for strlen +#include <new> +#include <string.h> #include <wtf/Assertions.h> #include <wtf/FastMalloc.h> #include <wtf/HashSet.h> diff --git a/Source/JavaScriptCore/runtime/Identifier.h b/Source/JavaScriptCore/runtime/Identifier.h index 196fdca23..bdcfbd187 100644 --- a/Source/JavaScriptCore/runtime/Identifier.h +++ b/Source/JavaScriptCore/runtime/Identifier.h @@ -23,9 +23,9 @@ #include "JSGlobalData.h" #include <wtf/ThreadSpecific.h> -#include "UString.h" #include <wtf/WTFThreadData.h> #include <wtf/text/CString.h> +#include <wtf/text/WTFString.h> namespace JSC { @@ -45,14 +45,14 @@ namespace JSC { Identifier(JSGlobalData* globalData, const char (&characters)[charactersCount]) : m_string(add(globalData, characters)) { } Identifier(ExecState* exec, StringImpl* rep) : m_string(add(exec, rep)) { } - Identifier(ExecState* exec, const UString& s) : m_string(add(exec, s.impl())) { } + Identifier(ExecState* exec, const String& s) : m_string(add(exec, s.impl())) { } Identifier(JSGlobalData* globalData, const LChar* s, int length) : m_string(add(globalData, s, length)) { } Identifier(JSGlobalData* globalData, const UChar* s, int length) : m_string(add(globalData, s, length)) { } Identifier(JSGlobalData* globalData, StringImpl* rep) : m_string(add(globalData, rep)) { } - Identifier(JSGlobalData* globalData, const UString& s) : m_string(add(globalData, s.impl())) { } + Identifier(JSGlobalData* globalData, const String& s) : m_string(add(globalData, s.impl())) { } - const UString& ustring() const { return m_string; } + const String& string() const { return m_string; } StringImpl* impl() const { return m_string.impl(); } const UChar* characters() const { return m_string.characters(); } @@ -91,7 +91,7 @@ namespace JSC { JS_EXPORT_PRIVATE static PassRefPtr<StringImpl> add(ExecState*, const char*); private: - UString m_string; + String m_string; template <typename CharType> ALWAYS_INLINE static uint32_t toUInt32FromCharacters(const CharType* characters, unsigned length, bool& ok); diff --git a/Source/JavaScriptCore/runtime/InitializeThreading.cpp b/Source/JavaScriptCore/runtime/InitializeThreading.cpp index c7fbd332e..6e7eddbf1 100644 --- a/Source/JavaScriptCore/runtime/InitializeThreading.cpp +++ b/Source/JavaScriptCore/runtime/InitializeThreading.cpp @@ -35,7 +35,7 @@ #include "Identifier.h" #include "JSDateMath.h" #include "JSGlobalObject.h" -#include "UString.h" +#include "LLIntData.h" #include "WriteBarrier.h" #include <wtf/dtoa.h> #include <wtf/Threading.h> @@ -61,6 +61,9 @@ static void initializeThreadingOnce() ExecutableAllocator::initializeAllocator(); #endif RegisterFile::initializeThreading(); +#if ENABLE(LLINT) + LLInt::initialize(); +#endif } void initializeThreading() diff --git a/Source/JavaScriptCore/runtime/InternalFunction.cpp b/Source/JavaScriptCore/runtime/InternalFunction.cpp index 985ab73b0..e2de03d92 100644 --- a/Source/JavaScriptCore/runtime/InternalFunction.cpp +++ b/Source/JavaScriptCore/runtime/InternalFunction.cpp @@ -39,27 +39,27 @@ InternalFunction::InternalFunction(JSGlobalObject* globalObject, Structure* stru { } -void InternalFunction::finishCreation(JSGlobalData& globalData, const UString& name) +void InternalFunction::finishCreation(JSGlobalData& globalData, const String& name) { Base::finishCreation(globalData); ASSERT(inherits(&s_info)); ASSERT(methodTable()->getCallData != InternalFunction::s_info.methodTable.getCallData); - putDirect(globalData, globalData.propertyNames->name, jsString(&globalData, name.isNull() ? "" : name), DontDelete | ReadOnly | DontEnum); + putDirect(globalData, globalData.propertyNames->name, jsString(&globalData, name), DontDelete | ReadOnly | DontEnum); } -const UString& InternalFunction::name(ExecState* exec) +const String& InternalFunction::name(ExecState* exec) { return asString(getDirect(exec->globalData(), exec->globalData().propertyNames->name))->tryGetValue(); } -const UString InternalFunction::displayName(ExecState* exec) +const String InternalFunction::displayName(ExecState* exec) { JSValue displayName = getDirect(exec->globalData(), exec->globalData().propertyNames->displayName); if (displayName && isJSString(displayName)) return asString(displayName)->tryGetValue(); - return UString(); + return String(); } CallType InternalFunction::getCallData(JSCell*, CallData&) @@ -68,9 +68,9 @@ CallType InternalFunction::getCallData(JSCell*, CallData&) return CallTypeNone; } -const UString InternalFunction::calculatedDisplayName(ExecState* exec) +const String InternalFunction::calculatedDisplayName(ExecState* exec) { - const UString explicitName = displayName(exec); + const String explicitName = displayName(exec); if (!explicitName.isEmpty()) return explicitName; diff --git a/Source/JavaScriptCore/runtime/InternalFunction.h b/Source/JavaScriptCore/runtime/InternalFunction.h index 150fb759e..e26b9f953 100644 --- a/Source/JavaScriptCore/runtime/InternalFunction.h +++ b/Source/JavaScriptCore/runtime/InternalFunction.h @@ -37,9 +37,9 @@ namespace JSC { static JS_EXPORTDATA const ClassInfo s_info; - JS_EXPORT_PRIVATE const UString& name(ExecState*); - const UString displayName(ExecState*); - const UString calculatedDisplayName(ExecState*); + JS_EXPORT_PRIVATE const String& name(ExecState*); + const String displayName(ExecState*); + const String calculatedDisplayName(ExecState*); static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { @@ -51,7 +51,7 @@ namespace JSC { JS_EXPORT_PRIVATE InternalFunction(JSGlobalObject*, Structure*); - JS_EXPORT_PRIVATE void finishCreation(JSGlobalData&, const UString& name); + JS_EXPORT_PRIVATE void finishCreation(JSGlobalData&, const String& name); static CallType getCallData(JSCell*, CallData&); }; diff --git a/Source/JavaScriptCore/runtime/JSAPIValueWrapper.cpp b/Source/JavaScriptCore/runtime/JSAPIValueWrapper.cpp index 8517085df..cd1d830fe 100644 --- a/Source/JavaScriptCore/runtime/JSAPIValueWrapper.cpp +++ b/Source/JavaScriptCore/runtime/JSAPIValueWrapper.cpp @@ -24,7 +24,6 @@ #include "JSAPIValueWrapper.h" #include "NumberObject.h" -#include "UString.h" namespace JSC { diff --git a/Source/JavaScriptCore/runtime/JSActivation.cpp b/Source/JavaScriptCore/runtime/JSActivation.cpp index 5417b0023..ae403ce46 100644 --- a/Source/JavaScriptCore/runtime/JSActivation.cpp +++ b/Source/JavaScriptCore/runtime/JSActivation.cpp @@ -42,7 +42,13 @@ ASSERT_CLASS_FITS_IN_CELL(JSActivation); const ClassInfo JSActivation::s_info = { "JSActivation", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSActivation) }; JSActivation::JSActivation(CallFrame* callFrame, FunctionExecutable* functionExecutable) - : Base(callFrame->globalData(), callFrame->globalData().activationStructure.get(), functionExecutable->symbolTable(), callFrame->registers()) + : Base( + callFrame->globalData(), + callFrame->lexicalGlobalObject()->activationStructure(), + callFrame->registers(), + callFrame->scope() + ) + , m_registerArray(callFrame->globalData(), this, 0) , m_numCapturedArgs(max(callFrame->argumentCount(), functionExecutable->parameterCount())) , m_numCapturedVars(functionExecutable->capturedVariableCount()) , m_isTornOff(false) @@ -51,20 +57,10 @@ JSActivation::JSActivation(CallFrame* callFrame, FunctionExecutable* functionExe { } -void JSActivation::finishCreation(CallFrame* callFrame) +void JSActivation::finishCreation(CallFrame* callFrame, FunctionExecutable* functionExecutable) { - Base::finishCreation(callFrame->globalData()); + Base::finishCreation(callFrame->globalData(), functionExecutable->symbolTable()); ASSERT(inherits(&s_info)); - - // We have to manually ref and deref the symbol table as JSVariableObject - // doesn't know about SharedSymbolTable - static_cast<SharedSymbolTable*>(m_symbolTable)->ref(); - callFrame->globalData().heap.addFinalizer(this, &finalize); -} - -void JSActivation::finalize(JSCell* cell) -{ - static_cast<SharedSymbolTable*>(jsCast<JSActivation*>(cell)->m_symbolTable)->deref(); } void JSActivation::visitChildren(JSCell* cell, SlotVisitor& visitor) @@ -76,25 +72,27 @@ void JSActivation::visitChildren(JSCell* cell, SlotVisitor& visitor) Base::visitChildren(thisObject, visitor); // No need to mark our registers if they're still in the RegisterFile. - WriteBarrier<Unknown>* registerArray = thisObject->m_registerArray.get(); + PropertyStorage registerArray = thisObject->m_registerArray.get(); if (!registerArray) return; - - visitor.appendValues(registerArray, thisObject->m_numCapturedArgs); - // Skip 'this' and call frame, except for callee and scope chain. - int offset = CallFrame::offsetFor(thisObject->m_numCapturedArgs + 1); - visitor.append(registerArray + offset + RegisterFile::ScopeChain); - visitor.append(registerArray + offset + RegisterFile::Callee); - - visitor.appendValues(registerArray + offset, thisObject->m_numCapturedVars); + visitor.copyAndAppend(bitwise_cast<void**>(®isterArray), thisObject->registerArraySizeInBytes(), reinterpret_cast<JSValue*>(registerArray), thisObject->registerArraySize()); + thisObject->m_registerArray.set(registerArray, StorageBarrier::Unchecked); + thisObject->m_registers = registerArray + thisObject->registerOffset(); + + // Update the arguments object, since it points at our buffer. + CallFrame* callFrame = CallFrame::create(reinterpret_cast<Register*>(thisObject->m_registers)); + if (JSValue v = callFrame->uncheckedR(unmodifiedArgumentsRegister(thisObject->m_argumentsRegister)).jsValue()) + jsCast<Arguments*>(v)->setRegisters(thisObject->m_registers); } inline bool JSActivation::symbolTableGet(PropertyName propertyName, PropertySlot& slot) { - SymbolTableEntry entry = symbolTable().inlineGet(propertyName.publicName()); + SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.publicName()); if (entry.isNull()) return false; + + // Defend against the inspector asking for a var after it has been optimized out. if (m_isTornOff && entry.getIndex() >= m_numCapturedVars) return false; @@ -102,12 +100,26 @@ inline bool JSActivation::symbolTableGet(PropertyName propertyName, PropertySlot return true; } +inline bool JSActivation::symbolTableGet(PropertyName propertyName, PropertyDescriptor& descriptor) +{ + SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.publicName()); + if (entry.isNull()) + return false; + + // Defend against the inspector asking for a var after it has been optimized out. + if (m_isTornOff && entry.getIndex() >= m_numCapturedVars) + return false; + + descriptor.setDescriptor(registerAt(entry.getIndex()).get(), entry.getAttributes()); + return true; +} + inline bool JSActivation::symbolTablePut(ExecState* exec, PropertyName propertyName, JSValue value, bool shouldThrow) { JSGlobalData& globalData = exec->globalData(); ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); - SymbolTableEntry entry = symbolTable().inlineGet(propertyName.publicName()); + SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.publicName()); if (entry.isNull()) return false; if (entry.isReadOnly()) { @@ -115,6 +127,8 @@ inline bool JSActivation::symbolTablePut(ExecState* exec, PropertyName propertyN throwTypeError(exec, StrictModeReadonlyPropertyWriteError); return true; } + + // Defend against the inspector asking for a var after it has been optimized out. if (m_isTornOff && entry.getIndex() >= m_numCapturedVars) return false; @@ -125,8 +139,12 @@ inline bool JSActivation::symbolTablePut(ExecState* exec, PropertyName propertyN void JSActivation::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) { JSActivation* thisObject = jsCast<JSActivation*>(object); - SymbolTable::const_iterator end = thisObject->symbolTable().end(); - for (SymbolTable::const_iterator it = thisObject->symbolTable().begin(); it != end; ++it) { + + if (mode == IncludeDontEnumProperties) + propertyNames.add(exec->propertyNames().arguments); + + SymbolTable::const_iterator end = thisObject->symbolTable()->end(); + for (SymbolTable::const_iterator it = thisObject->symbolTable()->begin(); it != end; ++it) { if (it->second.getAttributes() & DontEnum && mode != IncludeDontEnumProperties) continue; if (it->second.getIndex() >= thisObject->m_numCapturedVars) @@ -141,8 +159,8 @@ inline bool JSActivation::symbolTablePutWithAttributes(JSGlobalData& globalData, { ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this)); - SymbolTable::iterator iter = symbolTable().find(propertyName.publicName()); - if (iter == symbolTable().end()) + SymbolTable::iterator iter = symbolTable()->find(propertyName.publicName()); + if (iter == symbolTable()->end()) return false; SymbolTableEntry& entry = iter->second; ASSERT(!entry.isNull()); @@ -157,9 +175,13 @@ inline bool JSActivation::symbolTablePutWithAttributes(JSGlobalData& globalData, bool JSActivation::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot) { JSActivation* thisObject = jsCast<JSActivation*>(cell); + if (propertyName == exec->propertyNames().arguments) { - slot.setCustom(thisObject, thisObject->getArgumentsGetter()); - return true; + // Defend against the inspector asking for the arguments object after it has been optimized out. + if (!thisObject->m_isTornOff) { + slot.setCustom(thisObject, thisObject->getArgumentsGetter()); + return true; + } } if (thisObject->symbolTableGet(propertyName, slot)) @@ -177,6 +199,26 @@ bool JSActivation::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyNam return false; } +bool JSActivation::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor) +{ + JSActivation* thisObject = jsCast<JSActivation*>(object); + + if (propertyName == exec->propertyNames().arguments) { + // Defend against the inspector asking for the arguments object after it has been optimized out. + if (!thisObject->m_isTornOff) { + PropertySlot slot; + JSActivation::getOwnPropertySlot(thisObject, exec, propertyName, slot); + descriptor.setDescriptor(slot.getValue(exec, propertyName), DontEnum); + return true; + } + } + + if (thisObject->symbolTableGet(propertyName, descriptor)) + return true; + + return Base::getOwnPropertyDescriptor(object, exec, propertyName, descriptor); +} + void JSActivation::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot) { JSActivation* thisObject = jsCast<JSActivation*>(cell); diff --git a/Source/JavaScriptCore/runtime/JSActivation.h b/Source/JavaScriptCore/runtime/JSActivation.h index 95639076d..3abe5f54b 100644 --- a/Source/JavaScriptCore/runtime/JSActivation.h +++ b/Source/JavaScriptCore/runtime/JSActivation.h @@ -30,9 +30,10 @@ #define JSActivation_h #include "CodeBlock.h" +#include "CopiedSpaceInlineMethods.h" #include "JSVariableObject.h" -#include "SymbolTable.h" #include "Nodes.h" +#include "SymbolTable.h" namespace JSC { @@ -49,18 +50,17 @@ namespace JSC { static JSActivation* create(JSGlobalData& globalData, CallFrame* callFrame, FunctionExecutable* funcExec) { JSActivation* activation = new (NotNull, allocateCell<JSActivation>(globalData.heap)) JSActivation(callFrame, funcExec); - activation->finishCreation(callFrame); + activation->finishCreation(callFrame, funcExec); return activation; } - static void finalize(JSCell*); - static void visitChildren(JSCell*, SlotVisitor&); bool isDynamicScope(bool& requiresDynamicChecks) const; static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&); static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); + JS_EXPORT_PRIVATE static bool getOwnPropertyDescriptor(JSObject*, ExecState*, PropertyName, PropertyDescriptor&); static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); @@ -78,8 +78,8 @@ namespace JSC { bool isValidScopedLookup(int index) { return index < m_numCapturedVars; } protected: - void finishCreation(CallFrame*); - static const unsigned StructureFlags = IsEnvironmentRecord | OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags; + void finishCreation(CallFrame*, FunctionExecutable*); + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | Base::StructureFlags; private: bool symbolTableGet(PropertyName, PropertySlot&); @@ -91,6 +91,11 @@ namespace JSC { static JSValue argumentsGetter(ExecState*, JSValue, PropertyName); NEVER_INLINE PropertySlot::GetValueFunc getArgumentsGetter(); + size_t registerOffset(); + size_t registerArraySize(); + size_t registerArraySizeInBytes(); + + StorageBarrier m_registerArray; // Independent copy of registers, used when a variable object copies its registers out of the register file. int m_numCapturedArgs; int m_numCapturedVars : 30; bool m_isTornOff : 1; @@ -117,23 +122,50 @@ namespace JSC { return false; } + inline size_t JSActivation::registerOffset() + { + if (!m_numCapturedArgs) + return 0; + + size_t capturedArgumentCountIncludingThis = m_numCapturedArgs + 1; + return CallFrame::offsetFor(capturedArgumentCountIncludingThis); + } + + inline size_t JSActivation::registerArraySize() + { + return registerOffset() + m_numCapturedVars; + } + + inline size_t JSActivation::registerArraySizeInBytes() + { + return registerArraySize() * sizeof(WriteBarrierBase<Unknown>); + } + inline void JSActivation::tearOff(JSGlobalData& globalData) { ASSERT(!m_registerArray); ASSERT(m_numCapturedVars + m_numCapturedArgs); - int registerOffset = CallFrame::offsetFor(m_numCapturedArgs + 1); - size_t registerArraySize = registerOffset + m_numCapturedVars; - - OwnArrayPtr<WriteBarrier<Unknown> > registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[registerArraySize]); - WriteBarrier<Unknown>* registers = registerArray.get() + registerOffset; + void* allocation = 0; + if (!globalData.heap.tryAllocateStorage(registerArraySizeInBytes(), &allocation)) + CRASH(); + PropertyStorage registerArray = static_cast<PropertyStorage>(allocation); + PropertyStorage registers = registerArray + registerOffset(); + // arguments int from = CallFrame::argumentOffset(m_numCapturedArgs - 1); - int to = m_numCapturedVars; + int to = CallFrame::thisArgumentOffset(); // Skip 'this' because it's not lexically accessible. + for (int i = from; i < to; ++i) + registers[i].set(globalData, this, m_registers[i].get()); + + // vars + from = 0; + to = m_numCapturedVars; for (int i = from; i < to; ++i) registers[i].set(globalData, this, m_registers[i].get()); - setRegisters(registers, registerArray.release()); + m_registerArray.set(globalData, this, registerArray); + m_registers = registers; m_isTornOff = true; } diff --git a/Source/JavaScriptCore/runtime/JSArray.cpp b/Source/JavaScriptCore/runtime/JSArray.cpp index 7218604d1..8e1606fd8 100644 --- a/Source/JavaScriptCore/runtime/JSArray.cpp +++ b/Source/JavaScriptCore/runtime/JSArray.cpp @@ -113,7 +113,7 @@ static inline bool isDenseEnoughForVector(unsigned length, unsigned numValues) static bool reject(ExecState* exec, bool throwException, const char* message) { if (throwException) - throwTypeError(exec, message); + throwTypeError(exec, ASCIILiteral(message)); return false; } @@ -212,14 +212,14 @@ inline void SparseArrayValueMap::put(ExecState* exec, JSArray* array, unsigned i if (result.isNewEntry && !array->isExtensible()) { remove(result.iterator); if (shouldThrow) - throwTypeError(exec, StrictModeReadonlyPropertyWriteError); + throwTypeError(exec, ASCIILiteral(StrictModeReadonlyPropertyWriteError)); return; } if (!(entry.attributes & Accessor)) { if (entry.attributes & ReadOnly) { if (shouldThrow) - throwTypeError(exec, StrictModeReadonlyPropertyWriteError); + throwTypeError(exec, ASCIILiteral(StrictModeReadonlyPropertyWriteError)); return; } @@ -233,7 +233,7 @@ inline void SparseArrayValueMap::put(ExecState* exec, JSArray* array, unsigned i if (!setter) { if (shouldThrow) - throwTypeError(exec, StrictModeReadonlyPropertyWriteError); + throwTypeError(exec, ASCIILiteral(StrictModeReadonlyPropertyWriteError)); return; } @@ -244,7 +244,7 @@ inline void SparseArrayValueMap::put(ExecState* exec, JSArray* array, unsigned i call(exec, setter, callType, callData, array, args); } -inline bool SparseArrayValueMap::putDirect(ExecState* exec, JSArray* array, unsigned i, JSValue value, bool shouldThrow) +inline bool SparseArrayValueMap::putDirect(ExecState* exec, JSArray* array, unsigned i, JSValue value, PutDirectIndexMode mode) { AddResult result = add(array, i); SparseArrayEntry& entry = result.iterator->second; @@ -252,9 +252,9 @@ inline bool SparseArrayValueMap::putDirect(ExecState* exec, JSArray* array, unsi // To save a separate find & add, we first always add to the sparse map. // In the uncommon case that this is a new property, and the array is not // extensible, this is not the right thing to have done - so remove again. - if (result.isNewEntry && !array->isExtensible()) { + if (mode != PutDirectIndexLikePutDirect && result.isNewEntry && !array->isExtensible()) { remove(result.iterator); - return reject(exec, shouldThrow, "Attempting to define property on object that is not extensible."); + return reject(exec, mode == PutDirectIndexShouldThrow, "Attempting to define property on object that is not extensible."); } entry.attributes = 0; @@ -414,7 +414,7 @@ bool JSArray::defineOwnNumericProperty(ExecState* exec, unsigned index, Property // state (i.e. defineOwnProperty could be used to set a value without needing to entering 'SparseMode'). if (!descriptor.attributes()) { ASSERT(!descriptor.isAccessorDescriptor()); - return putDirectIndex(exec, index, descriptor.value(), throwException); + return putDirectIndex(exec, index, descriptor.value(), throwException ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow); } enterDictionaryMode(exec->globalData()); @@ -723,7 +723,7 @@ void JSArray::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSVa if (propertyName == exec->propertyNames().length) { unsigned newLength = value.toUInt32(exec); if (value.toNumber(exec) != static_cast<double>(newLength)) { - throwError(exec, createRangeError(exec, "Invalid array length")); + throwError(exec, createRangeError(exec, ASCIILiteral("Invalid array length"))); return; } thisObject->setLength(exec, newLength, slot.isStrictMode()); @@ -811,7 +811,7 @@ void JSArray::putByIndexBeyondVectorLength(ExecState* exec, unsigned i, JSValue // Prohibit growing the array if length is not writable. if (map->lengthIsReadOnly() || !isExtensible()) { if (shouldThrow) - throwTypeError(exec, StrictModeReadonlyPropertyWriteError); + throwTypeError(exec, ASCIILiteral(StrictModeReadonlyPropertyWriteError)); return; } length = i + 1; @@ -844,7 +844,7 @@ void JSArray::putByIndexBeyondVectorLength(ExecState* exec, unsigned i, JSValue valueSlot.set(globalData, this, value); } -bool JSArray::putDirectIndexBeyondVectorLength(ExecState* exec, unsigned i, JSValue value, bool shouldThrow) +bool JSArray::putDirectIndexBeyondVectorLength(ExecState* exec, unsigned i, JSValue value, PutDirectIndexMode mode) { JSGlobalData& globalData = exec->globalData(); @@ -875,17 +875,19 @@ bool JSArray::putDirectIndexBeyondVectorLength(ExecState* exec, unsigned i, JSVa // We don't want to, or can't use a vector to hold this property - allocate a sparse map & add the value. allocateSparseMap(exec->globalData()); map = m_sparseValueMap; - return map->putDirect(exec, this, i, value, shouldThrow); + return map->putDirect(exec, this, i, value, mode); } // Update m_length if necessary. unsigned length = storage->m_length; if (i >= length) { // Prohibit growing the array if length is not writable. - if (map->lengthIsReadOnly()) - return reject(exec, shouldThrow, StrictModeReadonlyPropertyWriteError); - if (!isExtensible()) - return reject(exec, shouldThrow, "Attempting to define property on object that is not extensible."); + if (mode != PutDirectIndexLikePutDirect) { + if (map->lengthIsReadOnly()) + return reject(exec, mode == PutDirectIndexShouldThrow, StrictModeReadonlyPropertyWriteError); + if (!isExtensible()) + return reject(exec, mode == PutDirectIndexShouldThrow, "Attempting to define property on object that is not extensible."); + } length = i + 1; storage->m_length = length; } @@ -894,7 +896,7 @@ bool JSArray::putDirectIndexBeyondVectorLength(ExecState* exec, unsigned i, JSVa // We will continue to use a sparse map if SparseMode is set, a vector would be too sparse, or if allocation fails. unsigned numValuesInArray = storage->m_numValuesInVector + map->size(); if (map->sparseMode() || !isDenseEnoughForVector(length, numValuesInArray) || !increaseVectorLength(exec->globalData(), length)) - return map->putDirect(exec, this, i, value, shouldThrow); + return map->putDirect(exec, this, i, value, mode); // Reread m_storage afterincreaseVectorLength, update m_numValuesInVector. storage = m_storage; @@ -1234,7 +1236,7 @@ JSValue JSArray::pop(ExecState* exec) unsigned length = storage->m_length; if (!length) { if (!isLengthWritable()) - throwTypeError(exec, StrictModeReadonlyPropertyWriteError); + throwTypeError(exec, ASCIILiteral(StrictModeReadonlyPropertyWriteError)); return jsUndefined(); } @@ -1259,7 +1261,7 @@ JSValue JSArray::pop(ExecState* exec) return jsUndefined(); // Call the [[Delete]] internal method of O with arguments indx and true. if (!deletePropertyByIndex(this, exec, index)) { - throwTypeError(exec, "Unable to delete property."); + throwTypeError(exec, ASCIILiteral("Unable to delete property.")); return jsUndefined(); } // Call the [[Put]] internal method of O with arguments "length", indx, and true. @@ -1292,7 +1294,7 @@ void JSArray::push(ExecState* exec, JSValue value) methodTable()->putByIndex(this, exec, storage->m_length, value, true); // Per ES5.1 15.4.4.7 step 6 & 15.4.5.1 step 3.d. if (!exec->hadException()) - throwError(exec, createRangeError(exec, "Invalid array length")); + throwError(exec, createRangeError(exec, ASCIILiteral("Invalid array length"))); return; } @@ -1479,7 +1481,7 @@ void JSArray::sort(ExecState* exec) // a toString call raises an exception. for (size_t i = 0; i < lengthNotIncludingUndefined; i++) - values[i].second = values[i].first.toUStringInline(exec); + values[i].second = values[i].first.toWTFStringInline(exec); if (exec->hadException()) { Heap::heap(this)->popTempSortVector(&values); diff --git a/Source/JavaScriptCore/runtime/JSArray.h b/Source/JavaScriptCore/runtime/JSArray.h index c0b9916d1..2aab8c683 100644 --- a/Source/JavaScriptCore/runtime/JSArray.h +++ b/Source/JavaScriptCore/runtime/JSArray.h @@ -30,6 +30,8 @@ namespace JSC { class JSArray; class LLIntOffsetsExtractor; + enum PutDirectIndexMode { PutDirectIndexLikePutDirect, PutDirectIndexShouldNotThrow, PutDirectIndexShouldThrow }; + struct SparseArrayEntry : public WriteBarrier<Unknown> { typedef WriteBarrier<Unknown> Base; @@ -87,7 +89,7 @@ namespace JSC { // These methods may mutate the contents of the map void put(ExecState*, JSArray*, unsigned, JSValue, bool shouldThrow); - bool putDirect(ExecState*, JSArray*, unsigned, JSValue, bool shouldThrow); + bool putDirect(ExecState*, JSArray*, unsigned, JSValue, PutDirectIndexMode); AddResult add(JSArray*, unsigned); iterator find(unsigned i) { return m_map.find(i); } // This should ASSERT the remove is valid (check the result of the find). @@ -173,14 +175,15 @@ namespace JSC { // This is similar to the JSObject::putDirect* methods: // - the prototype chain is not consulted // - accessors are not called. + // - it will ignore extensibility and read-only properties if PutDirectIndexLikePutDirect is passed as the mode (the default). // This method creates a property with attributes writable, enumerable and configurable all set to true. - bool putDirectIndex(ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow = true) + bool putDirectIndex(ExecState* exec, unsigned propertyName, JSValue value, PutDirectIndexMode mode = PutDirectIndexLikePutDirect) { if (canSetIndex(propertyName)) { setIndex(exec->globalData(), propertyName, value); return true; } - return putDirectIndexBeyondVectorLength(exec, propertyName, value, shouldThrow); + return putDirectIndexBeyondVectorLength(exec, propertyName, value, mode); } static JS_EXPORTDATA const ClassInfo s_info; @@ -302,7 +305,7 @@ namespace JSC { void deallocateSparseMap(); void putByIndexBeyondVectorLength(ExecState*, unsigned propertyName, JSValue, bool shouldThrow); - JS_EXPORT_PRIVATE bool putDirectIndexBeyondVectorLength(ExecState*, unsigned propertyName, JSValue, bool shouldThrow); + JS_EXPORT_PRIVATE bool putDirectIndexBeyondVectorLength(ExecState*, unsigned propertyName, JSValue, PutDirectIndexMode); unsigned getNewVectorLength(unsigned desiredLength); bool increaseVectorLength(JSGlobalData&, unsigned newLength); diff --git a/Source/JavaScriptCore/runtime/JSBoundFunction.cpp b/Source/JavaScriptCore/runtime/JSBoundFunction.cpp index 3f6430871..7540d4394 100644 --- a/Source/JavaScriptCore/runtime/JSBoundFunction.cpp +++ b/Source/JavaScriptCore/runtime/JSBoundFunction.cpp @@ -76,7 +76,7 @@ EncodedJSValue JSC_HOST_CALL boundFunctionConstruct(ExecState* exec) return JSValue::encode(construct(exec, targetFunction, constructType, constructData, args)); } -JSBoundFunction* JSBoundFunction::create(ExecState* exec, JSGlobalObject* globalObject, JSObject* targetFunction, JSValue boundThis, JSValue boundArgs, int length, const UString& name) +JSBoundFunction* JSBoundFunction::create(ExecState* exec, JSGlobalObject* globalObject, JSObject* targetFunction, JSValue boundThis, JSValue boundArgs, int length, const String& name) { ConstructData constructData; ConstructType constructType = JSC::getConstructData(targetFunction, constructData); @@ -107,7 +107,7 @@ JSBoundFunction::JSBoundFunction(ExecState* exec, JSGlobalObject* globalObject, { } -void JSBoundFunction::finishCreation(ExecState* exec, NativeExecutable* executable, int length, const UString& name) +void JSBoundFunction::finishCreation(ExecState* exec, NativeExecutable* executable, int length, const String& name) { Base::finishCreation(exec, executable, length, name); ASSERT(inherits(&s_info)); diff --git a/Source/JavaScriptCore/runtime/JSBoundFunction.h b/Source/JavaScriptCore/runtime/JSBoundFunction.h index dd1229272..5067d194c 100644 --- a/Source/JavaScriptCore/runtime/JSBoundFunction.h +++ b/Source/JavaScriptCore/runtime/JSBoundFunction.h @@ -37,7 +37,7 @@ class JSBoundFunction : public JSFunction { public: typedef JSFunction Base; - static JSBoundFunction* create(ExecState*, JSGlobalObject*, JSObject* targetFunction, JSValue boundThis, JSValue boundArgs, int, const UString&); + static JSBoundFunction* create(ExecState*, JSGlobalObject*, JSObject* targetFunction, JSValue boundThis, JSValue boundArgs, int, const String&); static bool hasInstance(JSObject*, ExecState*, JSValue, JSValue proto); @@ -61,7 +61,7 @@ protected: private: JSBoundFunction(ExecState*, JSGlobalObject*, Structure*, JSObject* targetFunction, JSValue boundThis, JSValue boundArgs); - void finishCreation(ExecState*, NativeExecutable*, int, const UString&); + void finishCreation(ExecState*, NativeExecutable*, int, const String&); WriteBarrier<JSObject> m_targetFunction; WriteBarrier<Unknown> m_boundThis; diff --git a/Source/JavaScriptCore/runtime/JSCell.cpp b/Source/JavaScriptCore/runtime/JSCell.cpp index 61e8549ee..ffb76ff95 100644 --- a/Source/JavaScriptCore/runtime/JSCell.cpp +++ b/Source/JavaScriptCore/runtime/JSCell.cpp @@ -38,7 +38,7 @@ void JSCell::destroy(JSCell* cell) cell->JSCell::~JSCell(); } -bool JSCell::getString(ExecState* exec, UString&stringValue) const +bool JSCell::getString(ExecState* exec, String& stringValue) const { if (!isString()) return false; @@ -46,9 +46,9 @@ bool JSCell::getString(ExecState* exec, UString&stringValue) const return true; } -UString JSCell::getString(ExecState* exec) const +String JSCell::getString(ExecState* exec) const { - return isString() ? static_cast<const JSString*>(this)->value(exec) : UString(); + return isString() ? static_cast<const JSString*>(this)->value(exec) : String(); } JSObject* JSCell::getObject() @@ -178,10 +178,10 @@ void JSCell::getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, Enum ASSERT_NOT_REACHED(); } -UString JSCell::className(const JSObject*) +String JSCell::className(const JSObject*) { ASSERT_NOT_REACHED(); - return UString(); + return String(); } const char* JSCell::className() diff --git a/Source/JavaScriptCore/runtime/JSCell.h b/Source/JavaScriptCore/runtime/JSCell.h index 39f98356f..ef06b1ecf 100644 --- a/Source/JavaScriptCore/runtime/JSCell.h +++ b/Source/JavaScriptCore/runtime/JSCell.h @@ -65,6 +65,8 @@ namespace JSC { template<typename T> friend void* allocateCell(Heap&); public: + static const unsigned StructureFlags = 0; + enum CreatingEarlyCellTag { CreatingEarlyCell }; JSCell(CreatingEarlyCellTag); @@ -87,8 +89,8 @@ namespace JSC { const char* className(); // Extracting the value. - JS_EXPORT_PRIVATE bool getString(ExecState* exec, UString&) const; - JS_EXPORT_PRIVATE UString getString(ExecState* exec) const; // null string if not a string + JS_EXPORT_PRIVATE bool getString(ExecState*, String&) const; + JS_EXPORT_PRIVATE String getString(ExecState*) const; // null string if not a string JS_EXPORT_PRIVATE JSObject* getObject(); // NULL if not an object const JSObject* getObject() const; // NULL if not an object @@ -124,7 +126,7 @@ namespace JSC { // call this function, not its slower virtual counterpart. (For integer // property names, we want a similar interface with appropriate optimizations.) bool fastGetOwnPropertySlot(ExecState*, PropertyName, PropertySlot&); - JSValue fastGetOwnProperty(ExecState*, const UString&); + JSValue fastGetOwnProperty(ExecState*, const String&); static ptrdiff_t structureOffset() { @@ -159,7 +161,7 @@ namespace JSC { static JSValue defaultValue(const JSObject*, ExecState*, PreferredPrimitiveType); static NO_RETURN_DUE_TO_ASSERT void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); static NO_RETURN_DUE_TO_ASSERT void getPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); - static UString className(const JSObject*); + static String className(const JSObject*); static bool hasInstance(JSObject*, ExecState*, JSValue, JSValue prototypeProperty); static NO_RETURN_DUE_TO_ASSERT void putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned attributes); static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, PropertyDescriptor&, bool shouldThrow); @@ -221,17 +223,17 @@ namespace JSC { return isCell() && asCell()->isObject(); } - inline bool JSValue::getString(ExecState* exec, UString& s) const + inline bool JSValue::getString(ExecState* exec, String& s) const { return isCell() && asCell()->getString(exec, s); } - inline UString JSValue::getString(ExecState* exec) const + inline String JSValue::getString(ExecState* exec) const { - return isCell() ? asCell()->getString(exec) : UString(); + return isCell() ? asCell()->getString(exec) : String(); } - template <typename Base> UString HandleConverter<Base, Unknown>::getString(ExecState* exec) const + template <typename Base> String HandleConverter<Base, Unknown>::getString(ExecState* exec) const { return jsValue().getString(exec); } diff --git a/Source/JavaScriptCore/runtime/JSDateMath.cpp b/Source/JavaScriptCore/runtime/JSDateMath.cpp index fcf1c4345..c54147ef2 100644 --- a/Source/JavaScriptCore/runtime/JSDateMath.cpp +++ b/Source/JavaScriptCore/runtime/JSDateMath.cpp @@ -73,7 +73,7 @@ #include "JSDateMath.h" #include "JSObject.h" -#include "ScopeChain.h" +#include "JSScope.h" #include <algorithm> #include <limits.h> @@ -258,7 +258,7 @@ double parseDateFromNullTerminatedCharacters(ExecState* exec, const char* dateSt return ms - (offset * WTF::msPerMinute); } -double parseDate(ExecState* exec, const UString& date) +double parseDate(ExecState* exec, const String& date) { if (date == exec->globalData().cachedDateString) return exec->globalData().cachedDateStringValue; diff --git a/Source/JavaScriptCore/runtime/JSDateMath.h b/Source/JavaScriptCore/runtime/JSDateMath.h index c7fb5a975..a6dd96f99 100644 --- a/Source/JavaScriptCore/runtime/JSDateMath.h +++ b/Source/JavaScriptCore/runtime/JSDateMath.h @@ -49,13 +49,12 @@ namespace JSC { class ExecState; -class UString; void msToGregorianDateTime(ExecState*, double, bool outputIsUTC, GregorianDateTime&); double gregorianDateTimeToMS(ExecState*, const GregorianDateTime&, double, bool inputIsUTC); double getUTCOffset(ExecState*); double parseDateFromNullTerminatedCharacters(ExecState*, const char* dateString); -double parseDate(ExecState*, const UString&); +double parseDate(ExecState*, const WTF::String&); } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/JSFunction.cpp b/Source/JavaScriptCore/runtime/JSFunction.cpp index 0a65deee2..e5cb8cf38 100644 --- a/Source/JavaScriptCore/runtime/JSFunction.cpp +++ b/Source/JavaScriptCore/runtime/JSFunction.cpp @@ -38,7 +38,6 @@ #include "ObjectPrototype.h" #include "Parser.h" #include "PropertyNameArray.h" -#include "ScopeChainMark.h" using namespace WTF; using namespace Unicode; @@ -59,7 +58,7 @@ bool JSFunction::isHostFunctionNonInline() const return isHostFunction(); } -JSFunction* JSFunction::create(ExecState* exec, JSGlobalObject* globalObject, int length, const UString& name, NativeFunction nativeFunction, Intrinsic intrinsic, NativeFunction nativeConstructor) +JSFunction* JSFunction::create(ExecState* exec, JSGlobalObject* globalObject, int length, const String& name, NativeFunction nativeFunction, Intrinsic intrinsic, NativeFunction nativeConstructor) { NativeExecutable* executable; #if !ENABLE(JIT) @@ -81,38 +80,38 @@ JSFunction* JSFunction::create(ExecState* exec, JSGlobalObject* globalObject, in JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, Structure* structure) : Base(exec->globalData(), structure) , m_executable() - , m_scopeChain(exec->globalData(), this, globalObject->globalScopeChain()) + , m_scope(exec->globalData(), this, globalObject) { } -JSFunction::JSFunction(ExecState* exec, FunctionExecutable* executable, ScopeChainNode* scopeChainNode) - : Base(exec->globalData(), scopeChainNode->globalObject->functionStructure()) +JSFunction::JSFunction(ExecState* exec, FunctionExecutable* executable, JSScope* scope) + : Base(exec->globalData(), scope->globalObject()->functionStructure()) , m_executable(exec->globalData(), this, executable) - , m_scopeChain(exec->globalData(), this, scopeChainNode) + , m_scope(exec->globalData(), this, scope) { } -void JSFunction::finishCreation(ExecState* exec, NativeExecutable* executable, int length, const UString& name) +void JSFunction::finishCreation(ExecState* exec, NativeExecutable* executable, int length, const String& name) { Base::finishCreation(exec->globalData()); ASSERT(inherits(&s_info)); m_executable.set(exec->globalData(), this, executable); - putDirect(exec->globalData(), exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name), DontDelete | ReadOnly | DontEnum); + putDirect(exec->globalData(), exec->globalData().propertyNames->name, jsString(exec, name), DontDelete | ReadOnly | DontEnum); putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum); } -void JSFunction::finishCreation(ExecState* exec, FunctionExecutable* executable, ScopeChainNode* scopeChainNode) +void JSFunction::finishCreation(ExecState* exec, FunctionExecutable* executable, JSScope* scope) { JSGlobalData& globalData = exec->globalData(); Base::finishCreation(globalData); ASSERT(inherits(&s_info)); // Switching the structure here is only safe if we currently have the function structure! - ASSERT(structure() == scopeChainNode->globalObject->functionStructure()); + ASSERT(structure() == scope->globalObject()->functionStructure()); setStructureAndReallocateStorageIfNecessary( globalData, - scopeChainNode->globalObject->namedFunctionStructure()); - putDirectOffset(globalData, scopeChainNode->globalObject->functionNameOffset(), executable->nameValue()); + scope->globalObject()->namedFunctionStructure()); + putDirectOffset(globalData, scope->globalObject()->functionNameOffset(), executable->nameValue()); } Structure* JSFunction::cacheInheritorID(ExecState* exec) @@ -125,33 +124,33 @@ Structure* JSFunction::cacheInheritorID(ExecState* exec) return m_cachedInheritorID.get(); } -const UString& JSFunction::name(ExecState* exec) +const String& JSFunction::name(ExecState* exec) { return asString(getDirect(exec->globalData(), exec->globalData().propertyNames->name))->tryGetValue(); } -const UString JSFunction::displayName(ExecState* exec) +const String JSFunction::displayName(ExecState* exec) { JSValue displayName = getDirect(exec->globalData(), exec->globalData().propertyNames->displayName); if (displayName && isJSString(displayName)) return asString(displayName)->tryGetValue(); - return UString(); + return String(); } -const UString JSFunction::calculatedDisplayName(ExecState* exec) +const String JSFunction::calculatedDisplayName(ExecState* exec) { - const UString explicitName = displayName(exec); + const String explicitName = displayName(exec); if (!explicitName.isEmpty()) return explicitName; - const UString actualName = name(exec); + const String actualName = name(exec); if (!actualName.isEmpty() || isHostFunction()) return actualName; - return jsExecutable()->inferredName().ustring(); + return jsExecutable()->inferredName().string(); } const SourceCode* JSFunction::sourceCode() const @@ -169,9 +168,8 @@ void JSFunction::visitChildren(JSCell* cell, SlotVisitor& visitor) ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); Base::visitChildren(thisObject, visitor); - visitor.append(&thisObject->m_scopeChain); - if (thisObject->m_executable) - visitor.append(&thisObject->m_executable); + visitor.append(&thisObject->m_scope); + visitor.append(&thisObject->m_executable); } CallType JSFunction::getCallData(JSCell* cell, CallData& callData) @@ -182,7 +180,7 @@ CallType JSFunction::getCallData(JSCell* cell, CallData& callData) return CallTypeHost; } callData.js.functionExecutable = thisObject->jsExecutable(); - callData.js.scopeChain = thisObject->scope(); + callData.js.scope = thisObject->scope(); return CallTypeJS; } @@ -205,7 +203,7 @@ JSValue JSFunction::callerGetter(ExecState* exec, JSValue slotBase, PropertyName JSFunction* function = jsCast<JSFunction*>(caller); if (function->isHostFunction() || !function->jsExecutable()->isStrictMode()) return caller; - return throwTypeError(exec, "Function.caller used to retrieve strict caller"); + return throwTypeError(exec, ASCIILiteral("Function.caller used to retrieve strict caller")); } JSValue JSFunction::lengthGetter(ExecState*, JSValue slotBase, PropertyName) @@ -416,27 +414,27 @@ bool JSFunction::defineOwnProperty(JSObject* object, ExecState* exec, PropertyNa if (descriptor.configurablePresent() && descriptor.configurable()) { if (throwException) - throwError(exec, createTypeError(exec, "Attempting to configurable attribute of unconfigurable property.")); + throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to configurable attribute of unconfigurable property."))); return false; } if (descriptor.enumerablePresent() && descriptor.enumerable()) { if (throwException) - throwError(exec, createTypeError(exec, "Attempting to change enumerable attribute of unconfigurable property.")); + throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change enumerable attribute of unconfigurable property."))); return false; } if (descriptor.isAccessorDescriptor()) { if (throwException) - throwError(exec, createTypeError(exec, "Attempting to change access mechanism for an unconfigurable property.")); + throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change access mechanism for an unconfigurable property."))); return false; } if (descriptor.writablePresent() && descriptor.writable()) { if (throwException) - throwError(exec, createTypeError(exec, "Attempting to change writable attribute of unconfigurable property.")); + throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change writable attribute of unconfigurable property."))); return false; } if (!valueCheck) { if (throwException) - throwError(exec, createTypeError(exec, "Attempting to change value of a readonly property.")); + throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change value of a readonly property."))); return false; } return true; @@ -451,12 +449,12 @@ ConstructType JSFunction::getConstructData(JSCell* cell, ConstructData& construc return ConstructTypeHost; } constructData.js.functionExecutable = thisObject->jsExecutable(); - constructData.js.scopeChain = thisObject->scope(); + constructData.js.scope = thisObject->scope(); return ConstructTypeJS; } -UString getCalculatedDisplayName(CallFrame* callFrame, JSObject* object) +String getCalculatedDisplayName(CallFrame* callFrame, JSObject* object) { if (JSFunction* function = jsDynamicCast<JSFunction*>(object)) return function->calculatedDisplayName(callFrame); diff --git a/Source/JavaScriptCore/runtime/JSFunction.h b/Source/JavaScriptCore/runtime/JSFunction.h index 56faf00de..4bd5f46fa 100644 --- a/Source/JavaScriptCore/runtime/JSFunction.h +++ b/Source/JavaScriptCore/runtime/JSFunction.h @@ -25,7 +25,7 @@ #define JSFunction_h #include "InternalFunction.h" -#include "JSObject.h" +#include "JSScope.h" namespace JSC { @@ -44,7 +44,7 @@ namespace JSC { JS_EXPORT_PRIVATE EncodedJSValue JSC_HOST_CALL callHostFunctionAsConstructor(ExecState*); - JS_EXPORT_PRIVATE UString getCalculatedDisplayName(CallFrame*, JSObject*); + JS_EXPORT_PRIVATE String getCalculatedDisplayName(CallFrame*, JSObject*); class JSFunction : public JSNonFinalObject { friend class JIT; @@ -55,38 +55,38 @@ namespace JSC { public: typedef JSNonFinalObject Base; - JS_EXPORT_PRIVATE static JSFunction* create(ExecState*, JSGlobalObject*, int length, const UString& name, NativeFunction, Intrinsic = NoIntrinsic, NativeFunction nativeConstructor = callHostFunctionAsConstructor); + JS_EXPORT_PRIVATE static JSFunction* create(ExecState*, JSGlobalObject*, int length, const String& name, NativeFunction, Intrinsic = NoIntrinsic, NativeFunction nativeConstructor = callHostFunctionAsConstructor); - static JSFunction* create(ExecState* exec, FunctionExecutable* executable, ScopeChainNode* scopeChain) + static JSFunction* create(ExecState* exec, FunctionExecutable* executable, JSScope* scope) { - JSFunction* function = new (NotNull, allocateCell<JSFunction>(*exec->heap())) JSFunction(exec, executable, scopeChain); + JSFunction* function = new (NotNull, allocateCell<JSFunction>(*exec->heap())) JSFunction(exec, executable, scope); ASSERT(function->structure()->globalObject()); - function->finishCreation(exec, executable, scopeChain); + function->finishCreation(exec, executable, scope); return function; } - JS_EXPORT_PRIVATE const UString& name(ExecState*); - JS_EXPORT_PRIVATE const UString displayName(ExecState*); - const UString calculatedDisplayName(ExecState*); + JS_EXPORT_PRIVATE const String& name(ExecState*); + JS_EXPORT_PRIVATE const String displayName(ExecState*); + const String calculatedDisplayName(ExecState*); - ScopeChainNode* scope() + JSScope* scope() { ASSERT(!isHostFunctionNonInline()); - return m_scopeChain.get(); + return m_scope.get(); } // This method may be called for host functins, in which case it // will return an arbitrary value. This should only be used for // optimized paths in which the return value does not matter for // host functions, and checking whether the function is a host // function is deemed too expensive. - ScopeChainNode* scopeUnchecked() + JSScope* scopeUnchecked() { - return m_scopeChain.get(); + return m_scope.get(); } - void setScope(JSGlobalData& globalData, ScopeChainNode* scopeChain) + void setScope(JSGlobalData& globalData, JSScope* scope) { ASSERT(!isHostFunctionNonInline()); - m_scopeChain.set(globalData, this, scopeChain); + m_scope.set(globalData, this, scope); } ExecutableBase* executable() const { return m_executable.get(); } @@ -113,7 +113,7 @@ namespace JSC { static inline size_t offsetOfScopeChain() { - return OBJECT_OFFSETOF(JSFunction, m_scopeChain); + return OBJECT_OFFSETOF(JSFunction, m_scope); } static inline size_t offsetOfExecutable() @@ -137,10 +137,10 @@ namespace JSC { const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags; JS_EXPORT_PRIVATE JSFunction(ExecState*, JSGlobalObject*, Structure*); - JSFunction(ExecState*, FunctionExecutable*, ScopeChainNode*); + JSFunction(ExecState*, FunctionExecutable*, JSScope*); - void finishCreation(ExecState*, NativeExecutable*, int length, const UString& name); - void finishCreation(ExecState*, FunctionExecutable*, ScopeChainNode*); + void finishCreation(ExecState*, NativeExecutable*, int length, const String& name); + void finishCreation(ExecState*, FunctionExecutable*, JSScope*); Structure* cacheInheritorID(ExecState*); @@ -165,7 +165,7 @@ namespace JSC { static JSValue lengthGetter(ExecState*, JSValue, PropertyName); WriteBarrier<ExecutableBase> m_executable; - WriteBarrier<ScopeChainNode> m_scopeChain; + WriteBarrier<JSScope> m_scope; WriteBarrier<Structure> m_cachedInheritorID; }; diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.cpp b/Source/JavaScriptCore/runtime/JSGlobalData.cpp index 2d6d1e54f..217526f6a 100644 --- a/Source/JavaScriptCore/runtime/JSGlobalData.cpp +++ b/Source/JavaScriptCore/runtime/JSGlobalData.cpp @@ -30,12 +30,12 @@ #include "JSGlobalData.h" #include "ArgList.h" -#include "Heap.h" #include "CommonIdentifiers.h" #include "DebuggerActivation.h" #include "FunctionConstructor.h" #include "GCActivityCallback.h" #include "GetterSetter.h" +#include "Heap.h" #include "HostCallReturnValue.h" #include "IncrementalSweeper.h" #include "Interpreter.h" @@ -45,9 +45,10 @@ #include "JSClassRef.h" #include "JSFunction.h" #include "JSLock.h" +#include "JSNameScope.h" #include "JSNotAnObject.h" #include "JSPropertyNameIterator.h" -#include "JSStaticScopeObject.h" +#include "JSWithScope.h" #include "Lexer.h" #include "Lookup.h" #include "Nodes.h" @@ -99,12 +100,19 @@ extern const HashTable stringConstructorTable; #if ENABLE(ASSEMBLER) && (ENABLE(CLASSIC_INTERPRETER) || ENABLE(LLINT)) static bool enableAssembler(ExecutableAllocator& executableAllocator) { - if (!executableAllocator.isValid() || !Options::useJIT()) + if (!executableAllocator.isValid() || (!Options::useJIT() && !Options::useRegExpJIT())) return false; #if USE(CF) - RetainPtr<CFStringRef> canUseJITKey(AdoptCF, CFStringCreateWithCString(0 , "JavaScriptCoreUseJIT", kCFStringEncodingMacRoman)); - RetainPtr<CFBooleanRef> canUseJIT(AdoptCF, (CFBooleanRef)CFPreferencesCopyAppValue(canUseJITKey.get(), kCFPreferencesCurrentApplication)); +#if COMPILER(GCC) && !COMPILER(CLANG) + // FIXME: remove this once the EWS have been upgraded to LLVM. + // Work around a bug of GCC with strict-aliasing. + RetainPtr<CFStringRef> canUseJITKeyRetain(AdoptCF, CFStringCreateWithCString(0 , "JavaScriptCoreUseJIT", kCFStringEncodingMacRoman)); + CFStringRef canUseJITKey = canUseJITKeyRetain.get(); +#else + CFStringRef canUseJITKey = CFSTR("JavaScriptCoreUseJIT"); +#endif // COMPILER(GCC) && !COMPILER(CLANG) + RetainPtr<CFBooleanRef> canUseJIT(AdoptCF, (CFBooleanRef)CFPreferencesCopyAppValue(canUseJITKey, kCFPreferencesCurrentApplication)); if (canUseJIT) return kCFBooleanTrue == canUseJIT.get(); #endif @@ -119,7 +127,11 @@ static bool enableAssembler(ExecutableAllocator& executableAllocator) #endif JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType threadStackType, HeapType heapType) - : heap(this, heapType) + : +#if ENABLE(ASSEMBLER) + executableAllocator(*this), +#endif + heap(this, heapType) , globalDataType(globalDataType) , clientData(0) , topCallFrame(CallFrame::noCaller()) @@ -145,9 +157,6 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread , identifierTable(globalDataType == Default ? wtfThreadData().currentIdentifierTable() : createIdentifierTable()) , propertyNames(new CommonIdentifiers(this)) , emptyList(new MarkedArgumentBuffer) -#if ENABLE(ASSEMBLER) - , executableAllocator(*this) -#endif , parserArena(adoptPtr(new ParserArena)) , keywords(adoptPtr(new Keywords(this))) , interpreter(0) @@ -173,6 +182,8 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread , m_newStringsSinceLastHashConst(0) #if ENABLE(ASSEMBLER) && (ENABLE(CLASSIC_INTERPRETER) || ENABLE(LLINT)) , m_canUseAssembler(enableAssembler(executableAllocator)) + , m_canUseJIT(m_canUseAssembler && Options::useJIT()) + , m_canUseRegExpJIT(m_canUseAssembler && Options::useRegExpJIT()) #endif #if ENABLE(GC_VALIDATION) , m_initializingObjectClass(0) @@ -186,23 +197,21 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread IdentifierTable* existingEntryIdentifierTable = wtfThreadData().setCurrentIdentifierTable(identifierTable); structureStructure.set(*this, Structure::createStructure(*this)); debuggerActivationStructure.set(*this, DebuggerActivation::createStructure(*this, 0, jsNull())); - activationStructure.set(*this, JSActivation::createStructure(*this, 0, jsNull())); interruptedExecutionErrorStructure.set(*this, InterruptedExecutionError::createStructure(*this, 0, jsNull())); terminatedExecutionErrorStructure.set(*this, TerminatedExecutionError::createStructure(*this, 0, jsNull())); - staticScopeStructure.set(*this, JSStaticScopeObject::createStructure(*this, 0, jsNull())); - strictEvalActivationStructure.set(*this, StrictEvalActivation::createStructure(*this, 0, jsNull())); stringStructure.set(*this, JSString::createStructure(*this, 0, jsNull())); notAnObjectStructure.set(*this, JSNotAnObject::createStructure(*this, 0, jsNull())); propertyNameIteratorStructure.set(*this, JSPropertyNameIterator::createStructure(*this, 0, jsNull())); getterSetterStructure.set(*this, GetterSetter::createStructure(*this, 0, jsNull())); apiWrapperStructure.set(*this, JSAPIValueWrapper::createStructure(*this, 0, jsNull())); - scopeChainNodeStructure.set(*this, ScopeChainNode::createStructure(*this, 0, jsNull())); + JSScopeStructure.set(*this, JSScope::createStructure(*this, 0, jsNull())); executableStructure.set(*this, ExecutableBase::createStructure(*this, 0, jsNull())); nativeExecutableStructure.set(*this, NativeExecutable::createStructure(*this, 0, jsNull())); evalExecutableStructure.set(*this, EvalExecutable::createStructure(*this, 0, jsNull())); programExecutableStructure.set(*this, ProgramExecutable::createStructure(*this, 0, jsNull())); functionExecutableStructure.set(*this, FunctionExecutable::createStructure(*this, 0, jsNull())); regExpStructure.set(*this, RegExp::createStructure(*this, 0, jsNull())); + sharedSymbolTableStructure.set(*this, SharedSymbolTable::createStructure(*this, 0, jsNull())); structureChainStructure.set(*this, StructureChain::createStructure(*this, 0, jsNull())); wtfThreadData().setCurrentIdentifierTable(existingEntryIdentifierTable); @@ -211,13 +220,13 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread jitStubs = adoptPtr(new JITThunks(this)); #endif - interpreter->initialize(&llintData, this->canUseJIT()); + interpreter->initialize(this->canUseJIT()); initializeHostCallReturnValue(); // This is needed to convince the linker not to drop host call return support. heap.notifyIsSafeToCollect(); - llintData.performAssertions(*this); + LLInt::Data::performAssertions(*this); } JSGlobalData::~JSGlobalData() @@ -371,12 +380,13 @@ NativeExecutable* JSGlobalData::getHostFunction(NativeFunction function, Intrins ASSERT(canUseJIT()); return jitStubs->hostFunctionStub(this, function, intrinsic != NoIntrinsic ? thunkGeneratorForIntrinsic(intrinsic) : 0, intrinsic); } -#else + +#else // !ENABLE(JIT) NativeExecutable* JSGlobalData::getHostFunction(NativeFunction function, NativeFunction constructor) { return NativeExecutable::create(*this, function, constructor); } -#endif +#endif // !ENABLE(JIT) JSGlobalData::ClientData::~ClientData() { @@ -386,7 +396,7 @@ void JSGlobalData::resetDateCache() { cachedUTCOffset = std::numeric_limits<double>::quiet_NaN(); dstOffsetCache.reset(); - cachedDateString = UString(); + cachedDateString = String(); cachedDateStringValue = std::numeric_limits<double>::quiet_NaN(); dateInstanceCache.reset(); } diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.h b/Source/JavaScriptCore/runtime/JSGlobalData.h index 4604737d2..e4e6784da 100644 --- a/Source/JavaScriptCore/runtime/JSGlobalData.h +++ b/Source/JavaScriptCore/runtime/JSGlobalData.h @@ -76,7 +76,6 @@ namespace JSC { class RegExpCache; class Stringifier; class Structure; - class UString; #if ENABLE(REGEXP_TRACING) class RegExp; #endif @@ -193,7 +192,15 @@ namespace JSC { JSLock m_apiLock; public: - Heap heap; // The heap is our first data member to ensure that it's destructed after all the objects that reference it. +#if ENABLE(ASSEMBLER) + // executableAllocator should be destructed after the heap, as the heap can call executableAllocator + // in its destructor. + ExecutableAllocator executableAllocator; +#endif + + // The heap should be just after executableAllocator and before other members to ensure that it's + // destructed after all the objects that reference it. + Heap heap; GlobalDataType globalDataType; ClientData* clientData; @@ -221,23 +228,21 @@ namespace JSC { Strong<Structure> structureStructure; Strong<Structure> debuggerActivationStructure; - Strong<Structure> activationStructure; Strong<Structure> interruptedExecutionErrorStructure; Strong<Structure> terminatedExecutionErrorStructure; - Strong<Structure> staticScopeStructure; - Strong<Structure> strictEvalActivationStructure; Strong<Structure> stringStructure; Strong<Structure> notAnObjectStructure; Strong<Structure> propertyNameIteratorStructure; Strong<Structure> getterSetterStructure; Strong<Structure> apiWrapperStructure; - Strong<Structure> scopeChainNodeStructure; + Strong<Structure> JSScopeStructure; Strong<Structure> executableStructure; Strong<Structure> nativeExecutableStructure; Strong<Structure> evalExecutableStructure; Strong<Structure> programExecutableStructure; Strong<Structure> functionExecutableStructure; Strong<Structure> regExpStructure; + Strong<Structure> sharedSymbolTableStructure; Strong<Structure> structureChainStructure; IdentifierTable* identifierTable; @@ -274,16 +279,12 @@ namespace JSC { return m_enabledProfiler; } -#if ENABLE(ASSEMBLER) - ExecutableAllocator executableAllocator; -#endif - #if !ENABLE(JIT) bool canUseJIT() { return false; } // interpreter only #elif !ENABLE(CLASSIC_INTERPRETER) && !ENABLE(LLINT) bool canUseJIT() { return true; } // jit only #else - bool canUseJIT() { return m_canUseAssembler; } + bool canUseJIT() { return m_canUseJIT; } #endif #if !ENABLE(YARR_JIT) @@ -291,7 +292,7 @@ namespace JSC { #elif !ENABLE(CLASSIC_INTERPRETER) && !ENABLE(LLINT) bool canUseRegExpJIT() { return true; } // jit only #else - bool canUseRegExpJIT() { return m_canUseAssembler; } + bool canUseRegExpJIT() { return m_canUseRegExpJIT; } #endif PrivateName m_inheritorIDKey; @@ -317,8 +318,6 @@ namespace JSC { const ClassInfo* const jsArrayClassInfo; const ClassInfo* const jsFinalObjectClassInfo; - LLInt::Data llintData; - ReturnAddressPtr exceptionLocation; JSValue hostCallReturnValue; CallFrame* callFrameForThrow; @@ -362,7 +361,7 @@ namespace JSC { double cachedUTCOffset; DSTOffsetCache dstOffsetCache; - UString cachedDateString; + String cachedDateString; double cachedDateStringValue; int maxReentryDepth; @@ -417,6 +416,7 @@ namespace JSC { { \ ASSERT(!m_##type##ArrayDescriptor.m_classInfo || m_##type##ArrayDescriptor.m_classInfo == descriptor.m_classInfo); \ m_##type##ArrayDescriptor = descriptor; \ + ASSERT(m_##type##ArrayDescriptor.m_classInfo); \ } \ const TypedArrayDescriptor& type##ArrayDescriptor() const { ASSERT(m_##type##ArrayDescriptor.m_classInfo); return m_##type##ArrayDescriptor; } @@ -441,6 +441,8 @@ namespace JSC { void createNativeThunk(); #if ENABLE(ASSEMBLER) && (ENABLE(CLASSIC_INTERPRETER) || ENABLE(LLINT)) bool m_canUseAssembler; + bool m_canUseJIT; + bool m_canUseRegExpJIT; #endif #if ENABLE(GC_VALIDATION) const ClassInfo* m_initializingObjectClass; @@ -470,6 +472,11 @@ namespace JSC { } #endif + inline Heap* WeakSet::heap() const + { + return &m_globalData->heap; + } + } // namespace JSC #endif // JSGlobalData_h diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp index ff7b1486f..97e9153cb 100644 --- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp +++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp @@ -30,10 +30,6 @@ #include "config.h" #include "JSGlobalObject.h" -#include "JSCallbackConstructor.h" -#include "JSCallbackFunction.h" -#include "JSCallbackObject.h" - #include "Arguments.h" #include "ArrayConstructor.h" #include "ArrayPrototype.h" @@ -42,18 +38,25 @@ #include "CodeBlock.h" #include "DateConstructor.h" #include "DatePrototype.h" +#include "Debugger.h" #include "Error.h" #include "ErrorConstructor.h" #include "ErrorPrototype.h" #include "FunctionConstructor.h" #include "FunctionPrototype.h" #include "GetterSetter.h" +#include "Interpreter.h" +#include "JSActivation.h" #include "JSBoundFunction.h" +#include "JSCallbackConstructor.h" +#include "JSCallbackFunction.h" +#include "JSCallbackObject.h" #include "JSFunction.h" #include "JSGlobalObjectFunctions.h" #include "JSLock.h" +#include "JSNameScope.h" #include "JSONObject.h" -#include "Interpreter.h" +#include "JSWithScope.h" #include "Lookup.h" #include "MathObject.h" #include "NameConstructor.h" @@ -70,16 +73,15 @@ #include "RegExpMatchesArray.h" #include "RegExpObject.h" #include "RegExpPrototype.h" -#include "ScopeChainMark.h" +#include "StrictEvalActivation.h" #include "StringConstructor.h" #include "StringPrototype.h" -#include "Debugger.h" #include "JSGlobalObject.lut.h" namespace JSC { -const ClassInfo JSGlobalObject::s_info = { "GlobalObject", &JSSegmentedVariableObject::s_info, 0, ExecState::globalObjectTable, CREATE_METHOD_TABLE(JSGlobalObject) }; +const ClassInfo JSGlobalObject::s_info = { "GlobalObject", &Base::s_info, 0, ExecState::globalObjectTable, CREATE_METHOD_TABLE(JSGlobalObject) }; const GlobalObjectMethodTable JSGlobalObject::s_globalObjectMethodTable = { &allowsAccessFrom, &supportsProfiling, &supportsRichSourceInfo, &shouldInterruptScript, &javaScriptExperimentsEnabled }; @@ -106,15 +108,8 @@ static const int initialTickCountThreshold = 255; // Preferred number of milliseconds between each timeout check static const int preferredScriptCheckTimeInterval = 1000; -template <typename T> static inline void visitIfNeeded(SlotVisitor& visitor, WriteBarrier<T>* v) -{ - if (*v) - visitor.append(v); -} - JSGlobalObject::JSGlobalObject(JSGlobalData& globalData, Structure* structure, const GlobalObjectMethodTable* globalObjectMethodTable) - : JSSegmentedVariableObject(globalData, structure, &m_symbolTable) - , m_globalScopeChain() + : Base(globalData, structure, 0) , m_masqueradesAsUndefinedWatchpoint(adoptRef(new WatchpointSet(InitializedWatching))) , m_weakRandom(Options::forceWeakRandomSeed() ? Options::forcedWeakRandomSeed() : static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0))) , m_evalEnabled(true) @@ -136,13 +131,17 @@ void JSGlobalObject::destroy(JSCell* cell) static_cast<JSGlobalObject*>(cell)->JSGlobalObject::~JSGlobalObject(); } +void JSGlobalObject::setGlobalThis(JSGlobalData& globalData, JSObject* globalThis) +{ + m_globalThis.set(globalData, this, globalThis); +} + void JSGlobalObject::init(JSObject* thisValue) { ASSERT(globalData().apiLock().currentThreadIsHoldingLock()); - - m_globalScopeChain.set(globalData(), this, ScopeChainNode::create(0, this, &globalData(), this, thisValue)); - JSGlobalObject::globalExec()->init(0, 0, m_globalScopeChain.get(), CallFrame::noCaller(), 0, 0); + setGlobalThis(globalData(), thisValue); + JSGlobalObject::globalExec()->init(0, 0, this, CallFrame::noCaller(), 0, 0); m_debugger = 0; @@ -156,7 +155,7 @@ void JSGlobalObject::put(JSCell* cell, ExecState* exec, PropertyName propertyNam if (symbolTablePut(thisObject, exec, propertyName, value, slot.isStrictMode())) return; - JSSegmentedVariableObject::put(thisObject, exec, propertyName, value, slot); + Base::put(thisObject, exec, propertyName, value, slot); } void JSGlobalObject::putDirectVirtual(JSObject* object, ExecState* exec, PropertyName propertyName, JSValue value, unsigned attributes) @@ -169,7 +168,7 @@ void JSGlobalObject::putDirectVirtual(JSObject* object, ExecState* exec, Propert JSValue valueBefore = thisObject->getDirect(exec->globalData(), propertyName); PutPropertySlot slot; - JSSegmentedVariableObject::put(thisObject, exec, propertyName, value, slot); + Base::put(thisObject, exec, propertyName, value, slot); if (!valueBefore) { JSValue valueAfter = thisObject->getDirect(exec->globalData(), propertyName); if (valueAfter) @@ -212,11 +211,16 @@ void JSGlobalObject::reset(JSValue prototype) m_applyFunction.set(exec->globalData(), this, applyFunction); m_objectPrototype.set(exec->globalData(), this, ObjectPrototype::create(exec, this, ObjectPrototype::createStructure(exec->globalData(), this, jsNull()))); GetterSetter* protoAccessor = GetterSetter::create(exec); - protoAccessor->setGetter(exec->globalData(), JSFunction::create(exec, this, 0, "", globalFuncProtoGetter)); - protoAccessor->setSetter(exec->globalData(), JSFunction::create(exec, this, 0, "", globalFuncProtoSetter)); + protoAccessor->setGetter(exec->globalData(), JSFunction::create(exec, this, 0, String(), globalFuncProtoGetter)); + protoAccessor->setSetter(exec->globalData(), JSFunction::create(exec, this, 0, String(), globalFuncProtoSetter)); m_objectPrototype->putDirectAccessor(exec->globalData(), exec->propertyNames().underscoreProto, protoAccessor, Accessor | DontEnum); m_functionPrototype->structure()->setPrototypeWithoutTransition(exec->globalData(), m_objectPrototype.get()); + m_nameScopeStructure.set(exec->globalData(), this, JSNameScope::createStructure(exec->globalData(), this, jsNull())); + m_activationStructure.set(exec->globalData(), this, JSActivation::createStructure(exec->globalData(), this, jsNull())); + m_strictEvalActivationStructure.set(exec->globalData(), this, StrictEvalActivation::createStructure(exec->globalData(), this, jsNull())); + m_withScopeStructure.set(exec->globalData(), this, JSWithScope::createStructure(exec->globalData(), this, jsNull())); + m_emptyObjectStructure.set(exec->globalData(), this, m_objectPrototype->inheritorID(exec->globalData())); m_nullPrototypeObjectStructure.set(exec->globalData(), this, createEmptyObjectStructure(exec->globalData(), this, jsNull())); @@ -267,12 +271,12 @@ void JSGlobalObject::reset(JSValue prototype) Structure* nativeErrorPrototypeStructure = NativeErrorPrototype::createStructure(exec->globalData(), this, m_errorPrototype.get()); Structure* nativeErrorStructure = NativeErrorConstructor::createStructure(exec->globalData(), this, m_functionPrototype.get()); - m_evalErrorConstructor.set(exec->globalData(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "EvalError")); - m_rangeErrorConstructor.set(exec->globalData(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "RangeError")); - m_referenceErrorConstructor.set(exec->globalData(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "ReferenceError")); - m_syntaxErrorConstructor.set(exec->globalData(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "SyntaxError")); - m_typeErrorConstructor.set(exec->globalData(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "TypeError")); - m_URIErrorConstructor.set(exec->globalData(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, "URIError")); + m_evalErrorConstructor.set(exec->globalData(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("EvalError"))); + m_rangeErrorConstructor.set(exec->globalData(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("RangeError"))); + m_referenceErrorConstructor.set(exec->globalData(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("ReferenceError"))); + m_syntaxErrorConstructor.set(exec->globalData(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("SyntaxError"))); + m_typeErrorConstructor.set(exec->globalData(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("TypeError"))); + m_URIErrorConstructor.set(exec->globalData(), this, NativeErrorConstructor::create(exec, this, nativeErrorStructure, nativeErrorPrototypeStructure, ASCIILiteral("URIError"))); m_objectPrototype->putDirectWithoutTransition(exec->globalData(), exec->propertyNames().constructor, objectConstructor, DontEnum); m_functionPrototype->putDirectWithoutTransition(exec->globalData(), exec->propertyNames().constructor, functionConstructor, DontEnum); @@ -300,7 +304,7 @@ void JSGlobalObject::reset(JSValue prototype) putDirectWithoutTransition(exec->globalData(), Identifier(exec, "TypeError"), m_typeErrorConstructor.get(), DontEnum); putDirectWithoutTransition(exec->globalData(), Identifier(exec, "URIError"), m_URIErrorConstructor.get(), DontEnum); - m_evalFunction.set(exec->globalData(), this, JSFunction::create(exec, this, 1, exec->propertyNames().eval.ustring(), globalFuncEval)); + m_evalFunction.set(exec->globalData(), this, JSFunction::create(exec, this, 1, exec->propertyNames().eval.string(), globalFuncEval)); putDirectWithoutTransition(exec->globalData(), exec->propertyNames().eval, m_evalFunction.get(), DontEnum); putDirectWithoutTransition(exec->globalData(), Identifier(exec, "JSON"), JSONObject::create(exec, this, JSONObject::createStructure(exec->globalData(), this, m_objectPrototype.get())), DontEnum); @@ -327,7 +331,7 @@ void JSGlobalObject::reset(JSValue prototype) void JSGlobalObject::createThrowTypeError(ExecState* exec) { - JSFunction* thrower = JSFunction::create(exec, this, 0, "", globalFuncThrowTypeError); + JSFunction* thrower = JSFunction::create(exec, this, 0, String(), globalFuncThrowTypeError); GetterSetter* getterSetter = GetterSetter::create(exec); getterSetter->setGetter(exec->globalData(), thrower); getterSetter->setSetter(exec->globalData(), thrower); @@ -351,54 +355,58 @@ void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor) ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); - JSSegmentedVariableObject::visitChildren(thisObject, visitor); - - visitIfNeeded(visitor, &thisObject->m_globalScopeChain); - visitIfNeeded(visitor, &thisObject->m_methodCallDummy); - - visitIfNeeded(visitor, &thisObject->m_regExpConstructor); - visitIfNeeded(visitor, &thisObject->m_errorConstructor); - visitIfNeeded(visitor, &thisObject->m_evalErrorConstructor); - visitIfNeeded(visitor, &thisObject->m_rangeErrorConstructor); - visitIfNeeded(visitor, &thisObject->m_referenceErrorConstructor); - visitIfNeeded(visitor, &thisObject->m_syntaxErrorConstructor); - visitIfNeeded(visitor, &thisObject->m_typeErrorConstructor); - visitIfNeeded(visitor, &thisObject->m_URIErrorConstructor); - - visitIfNeeded(visitor, &thisObject->m_evalFunction); - visitIfNeeded(visitor, &thisObject->m_callFunction); - visitIfNeeded(visitor, &thisObject->m_applyFunction); - visitIfNeeded(visitor, &thisObject->m_throwTypeErrorGetterSetter); - - visitIfNeeded(visitor, &thisObject->m_objectPrototype); - visitIfNeeded(visitor, &thisObject->m_functionPrototype); - visitIfNeeded(visitor, &thisObject->m_arrayPrototype); - visitIfNeeded(visitor, &thisObject->m_booleanPrototype); - visitIfNeeded(visitor, &thisObject->m_stringPrototype); - visitIfNeeded(visitor, &thisObject->m_numberPrototype); - visitIfNeeded(visitor, &thisObject->m_datePrototype); - visitIfNeeded(visitor, &thisObject->m_regExpPrototype); - visitIfNeeded(visitor, &thisObject->m_errorPrototype); - - visitIfNeeded(visitor, &thisObject->m_argumentsStructure); - visitIfNeeded(visitor, &thisObject->m_arrayStructure); - visitIfNeeded(visitor, &thisObject->m_booleanObjectStructure); - visitIfNeeded(visitor, &thisObject->m_callbackConstructorStructure); - visitIfNeeded(visitor, &thisObject->m_callbackFunctionStructure); - visitIfNeeded(visitor, &thisObject->m_callbackObjectStructure); - visitIfNeeded(visitor, &thisObject->m_dateStructure); - visitIfNeeded(visitor, &thisObject->m_emptyObjectStructure); - visitIfNeeded(visitor, &thisObject->m_nullPrototypeObjectStructure); - visitIfNeeded(visitor, &thisObject->m_errorStructure); - visitIfNeeded(visitor, &thisObject->m_functionStructure); - visitIfNeeded(visitor, &thisObject->m_boundFunctionStructure); - visitIfNeeded(visitor, &thisObject->m_namedFunctionStructure); - visitIfNeeded(visitor, &thisObject->m_numberObjectStructure); - visitIfNeeded(visitor, &thisObject->m_privateNameStructure); - visitIfNeeded(visitor, &thisObject->m_regExpMatchesArrayStructure); - visitIfNeeded(visitor, &thisObject->m_regExpStructure); - visitIfNeeded(visitor, &thisObject->m_stringObjectStructure); - visitIfNeeded(visitor, &thisObject->m_internalFunctionStructure); + Base::visitChildren(thisObject, visitor); + + visitor.append(&thisObject->m_globalThis); + visitor.append(&thisObject->m_methodCallDummy); + + visitor.append(&thisObject->m_regExpConstructor); + visitor.append(&thisObject->m_errorConstructor); + visitor.append(&thisObject->m_evalErrorConstructor); + visitor.append(&thisObject->m_rangeErrorConstructor); + visitor.append(&thisObject->m_referenceErrorConstructor); + visitor.append(&thisObject->m_syntaxErrorConstructor); + visitor.append(&thisObject->m_typeErrorConstructor); + visitor.append(&thisObject->m_URIErrorConstructor); + + visitor.append(&thisObject->m_evalFunction); + visitor.append(&thisObject->m_callFunction); + visitor.append(&thisObject->m_applyFunction); + visitor.append(&thisObject->m_throwTypeErrorGetterSetter); + + visitor.append(&thisObject->m_objectPrototype); + visitor.append(&thisObject->m_functionPrototype); + visitor.append(&thisObject->m_arrayPrototype); + visitor.append(&thisObject->m_booleanPrototype); + visitor.append(&thisObject->m_stringPrototype); + visitor.append(&thisObject->m_numberPrototype); + visitor.append(&thisObject->m_datePrototype); + visitor.append(&thisObject->m_regExpPrototype); + visitor.append(&thisObject->m_errorPrototype); + + visitor.append(&thisObject->m_withScopeStructure); + visitor.append(&thisObject->m_strictEvalActivationStructure); + visitor.append(&thisObject->m_activationStructure); + visitor.append(&thisObject->m_nameScopeStructure); + visitor.append(&thisObject->m_argumentsStructure); + visitor.append(&thisObject->m_arrayStructure); + visitor.append(&thisObject->m_booleanObjectStructure); + visitor.append(&thisObject->m_callbackConstructorStructure); + visitor.append(&thisObject->m_callbackFunctionStructure); + visitor.append(&thisObject->m_callbackObjectStructure); + visitor.append(&thisObject->m_dateStructure); + visitor.append(&thisObject->m_emptyObjectStructure); + visitor.append(&thisObject->m_nullPrototypeObjectStructure); + visitor.append(&thisObject->m_errorStructure); + visitor.append(&thisObject->m_functionStructure); + visitor.append(&thisObject->m_boundFunctionStructure); + visitor.append(&thisObject->m_namedFunctionStructure); + visitor.append(&thisObject->m_numberObjectStructure); + visitor.append(&thisObject->m_privateNameStructure); + visitor.append(&thisObject->m_regExpMatchesArrayStructure); + visitor.append(&thisObject->m_regExpStructure); + visitor.append(&thisObject->m_stringObjectStructure); + visitor.append(&thisObject->m_internalFunctionStructure); } ExecState* JSGlobalObject::globalExec() @@ -414,9 +422,9 @@ void JSGlobalObject::addStaticGlobals(GlobalPropertyInfo* globals, int count) GlobalPropertyInfo& global = globals[i]; ASSERT(global.attributes & DontDelete); - int index = symbolTable().size(); + int index = symbolTable()->size(); SymbolTableEntry newEntry(index, global.attributes); - symbolTable().add(global.identifier.impl(), newEntry); + symbolTable()->add(global.identifier.impl(), newEntry); registerAt(index).set(globalData(), this, global.value); } } @@ -424,7 +432,7 @@ void JSGlobalObject::addStaticGlobals(GlobalPropertyInfo* globals, int count) bool JSGlobalObject::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot) { JSGlobalObject* thisObject = jsCast<JSGlobalObject*>(cell); - if (getStaticFunctionSlot<JSSegmentedVariableObject>(exec, ExecState::globalObjectTable(exec), thisObject, propertyName, slot)) + if (getStaticFunctionSlot<Base>(exec, ExecState::globalObjectTable(exec), thisObject, propertyName, slot)) return true; return symbolTableGet(thisObject, propertyName, slot); } @@ -432,7 +440,7 @@ bool JSGlobalObject::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyN bool JSGlobalObject::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor) { JSGlobalObject* thisObject = jsCast<JSGlobalObject*>(object); - if (getStaticFunctionDescriptor<JSSegmentedVariableObject>(exec, ExecState::globalObjectTable(exec), thisObject, propertyName, descriptor)) + if (getStaticFunctionDescriptor<Base>(exec, ExecState::globalObjectTable(exec), thisObject, propertyName, descriptor)) return true; return symbolTableGet(thisObject, propertyName, descriptor); } diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.h b/Source/JavaScriptCore/runtime/JSGlobalObject.h index 248004bd5..406a65b51 100644 --- a/Source/JavaScriptCore/runtime/JSGlobalObject.h +++ b/Source/JavaScriptCore/runtime/JSGlobalObject.h @@ -77,6 +77,7 @@ namespace JSC { class JSGlobalObject : public JSSegmentedVariableObject { private: + typedef JSSegmentedVariableObject Base; typedef HashSet<RefPtr<OpaqueJSWeakObjectMap> > WeakMapSet; struct JSGlobalObjectRareData { @@ -93,7 +94,7 @@ namespace JSC { Register m_globalCallFrame[RegisterFile::CallFrameHeaderSize]; - WriteBarrier<ScopeChainNode> m_globalScopeChain; + WriteBarrier<JSObject> m_globalThis; WriteBarrier<JSObject> m_methodCallDummy; WriteBarrier<RegExpConstructor> m_regExpConstructor; @@ -120,6 +121,10 @@ namespace JSC { WriteBarrier<RegExpPrototype> m_regExpPrototype; WriteBarrier<ErrorPrototype> m_errorPrototype; + WriteBarrier<Structure> m_withScopeStructure; + WriteBarrier<Structure> m_strictEvalActivationStructure; + WriteBarrier<Structure> m_activationStructure; + WriteBarrier<Structure> m_nameScopeStructure; WriteBarrier<Structure> m_argumentsStructure; WriteBarrier<Structure> m_arrayStructure; WriteBarrier<Structure> m_booleanObjectStructure; @@ -149,8 +154,6 @@ namespace JSC { WeakRandom m_weakRandom; - SymbolTable m_symbolTable; - bool m_evalEnabled; bool m_experimentsEnabled; @@ -166,8 +169,6 @@ namespace JSC { } public: - typedef JSSegmentedVariableObject Base; - static JSGlobalObject* create(JSGlobalData& globalData, Structure* structure) { JSGlobalObject* globalObject = new (NotNull, allocateCell<JSGlobalObject>(globalData.heap)) JSGlobalObject(globalData, structure); @@ -252,6 +253,10 @@ namespace JSC { JSObject* methodCallDummy() const { return m_methodCallDummy.get(); } + Structure* withScopeStructure() const { return m_withScopeStructure.get(); } + Structure* strictEvalActivationStructure() const { return m_strictEvalActivationStructure.get(); } + Structure* activationStructure() const { return m_activationStructure.get(); } + Structure* nameScopeStructure() const { return m_nameScopeStructure.get(); } Structure* argumentsStructure() const { return m_argumentsStructure.get(); } Structure* arrayStructure() const { return m_arrayStructure.get(); } Structure* booleanObjectStructure() const { return m_booleanObjectStructure.get(); } @@ -292,8 +297,6 @@ namespace JSC { static bool supportsProfiling(const JSGlobalObject*) { return false; } static bool supportsRichSourceInfo(const JSGlobalObject*) { return true; } - ScopeChainNode* globalScopeChain() { return m_globalScopeChain.get(); } - JS_EXPORT_PRIVATE ExecState* globalExec(); static bool shouldInterruptScript(const JSGlobalObject*) { return true; } @@ -307,6 +310,7 @@ namespace JSC { void resetPrototype(JSGlobalData&, JSValue prototype); JSGlobalData& globalData() const { return *Heap::heap(this)->globalData(); } + JSObject* globalThis() const; static Structure* createStructure(JSGlobalData& globalData, JSValue prototype) { @@ -329,7 +333,7 @@ namespace JSC { unsigned weakRandomInteger() { return m_weakRandom.getUint32(); } protected: - static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | JSSegmentedVariableObject::StructureFlags; + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | Base::StructureFlags; struct GlobalPropertyInfo { GlobalPropertyInfo(const Identifier& i, JSValue v, unsigned a) @@ -351,6 +355,7 @@ namespace JSC { // FIXME: Fold reset into init. JS_EXPORT_PRIVATE void init(JSObject* thisValue); void reset(JSValue prototype); + void setGlobalThis(JSGlobalData&, JSObject* globalThis); void createThrowTypeError(ExecState*); @@ -368,7 +373,7 @@ namespace JSC { inline bool JSGlobalObject::hasOwnPropertyForWrite(ExecState* exec, PropertyName propertyName) { PropertySlot slot; - if (JSSegmentedVariableObject::getOwnPropertySlot(this, exec, propertyName, slot)) + if (Base::getOwnPropertySlot(this, exec, propertyName, slot)) return true; bool slotIsWriteable; return symbolTableGet(this, propertyName, slot, slotIsWriteable); @@ -376,7 +381,7 @@ namespace JSC { inline bool JSGlobalObject::symbolTableHasProperty(PropertyName propertyName) { - SymbolTableEntry entry = symbolTable().inlineGet(propertyName.publicName()); + SymbolTableEntry entry = symbolTable()->inlineGet(propertyName.publicName()); return !entry.isNull(); } @@ -491,6 +496,16 @@ namespace JSC { return true; } + inline JSObject* JSScope::globalThis() + { + return globalObject()->globalThis(); + } + + inline JSObject* JSGlobalObject::globalThis() const + { + return m_globalThis.get(); + } + } // namespace JSC #endif // JSGlobalObject_h diff --git a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp index e8017b904..4588ec2d9 100644 --- a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp +++ b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp @@ -34,7 +34,6 @@ #include "LiteralParser.h" #include "Nodes.h" #include "Parser.h" -#include "UStringBuilder.h" #include <wtf/dtoa.h> #include <stdio.h> #include <stdlib.h> @@ -42,6 +41,7 @@ #include <wtf/Assertions.h> #include <wtf/MathExtras.h> #include <wtf/StringExtras.h> +#include <wtf/text/StringBuilder.h> #include <wtf/unicode/UTF8.h> using namespace WTF; @@ -53,7 +53,7 @@ static JSValue encode(ExecState* exec, const char* doNotEscape) { CString cstr = exec->argument(0).toString(exec)->value(exec).utf8(true); if (!cstr.data()) - return throwError(exec, createURIError(exec, "String contained an illegal UTF-16 sequence.")); + return throwError(exec, createURIError(exec, ASCIILiteral("String contained an illegal UTF-16 sequence."))); JSStringBuilder builder; const char* p = cstr.data(); @@ -114,7 +114,7 @@ static JSValue decode(ExecState* exec, const CharType* characters, int length, c } if (charLen == 0) { if (strict) - return throwError(exec, createURIError(exec, "URI error")); + return throwError(exec, createURIError(exec, ASCIILiteral("URI error"))); // The only case where we don't use "strict" mode is the "unescape" function. // For that, it's good to support the wonky "%u" syntax for compatibility with WinIE. if (k <= length - 6 && p[1] == 'u' @@ -142,7 +142,7 @@ static JSValue decode(ExecState* exec, const CharType* characters, int length, c static JSValue decode(ExecState* exec, const char* doNotUnescape, bool strict) { JSStringBuilder builder; - UString str = exec->argument(0).toString(exec)->value(exec); + String str = exec->argument(0).toString(exec)->value(exec); if (str.is8Bit()) return decode(exec, str.characters8(), str.length(), doNotUnescape, strict); @@ -232,7 +232,7 @@ double parseIntOverflow(const UChar* s, int length, int radix) // ES5.1 15.1.2.2 template <typename CharType> ALWAYS_INLINE -static double parseInt(const UString& s, const CharType* data, int radix) +static double parseInt(const String& s, const CharType* data, int radix) { // 1. Let inputString be ToString(string). // 2. Let S be a newly created substring of inputString consisting of the first character that is not a @@ -313,7 +313,7 @@ static double parseInt(const UString& s, const CharType* data, int radix) return sign * number; } -static double parseInt(const UString& s, int radix) +static double parseInt(const String& s, int radix) { if (s.is8Bit()) return parseInt(s, s.characters8(), radix); @@ -432,7 +432,7 @@ static double toDouble(const CharType* characters, unsigned size) } // See ecma-262 9.3.1 -double jsToNumber(const UString& s) +double jsToNumber(const String& s) { unsigned size = s.length(); @@ -450,7 +450,7 @@ double jsToNumber(const UString& s) return toDouble(s.characters16(), size); } -static double parseFloat(const UString& s) +static double parseFloat(const String& s) { unsigned size = s.length(); @@ -499,13 +499,13 @@ EncodedJSValue JSC_HOST_CALL globalFuncEval(ExecState* exec) JSObject* thisObject = exec->hostThisValue().toThisObject(exec); JSObject* unwrappedObject = thisObject->unwrappedObject(); if (!unwrappedObject->isGlobalObject() || jsCast<JSGlobalObject*>(unwrappedObject)->evalFunction() != exec->callee()) - return throwVMError(exec, createEvalError(exec, "The \"this\" value passed to eval must be the global object from which eval originated")); + return throwVMError(exec, createEvalError(exec, ASCIILiteral("The \"this\" value passed to eval must be the global object from which eval originated"))); JSValue x = exec->argument(0); if (!x.isString()) return JSValue::encode(x); - UString s = x.toString(exec)->value(exec); + String s = x.toString(exec)->value(exec); if (s.is8Bit()) { LiteralParser<LChar> preparser(exec, s.characters8(), s.length(), NonStrictJSON); @@ -518,11 +518,11 @@ EncodedJSValue JSC_HOST_CALL globalFuncEval(ExecState* exec) } EvalExecutable* eval = EvalExecutable::create(exec, makeSource(s), false); - JSObject* error = eval->compile(exec, jsCast<JSGlobalObject*>(unwrappedObject)->globalScopeChain()); + JSObject* error = eval->compile(exec, jsCast<JSGlobalObject*>(unwrappedObject)); if (error) return throwVMError(exec, error); - return JSValue::encode(exec->interpreter()->execute(eval, exec, thisObject, jsCast<JSGlobalObject*>(unwrappedObject)->globalScopeChain())); + return JSValue::encode(exec->interpreter()->execute(eval, exec, thisObject, jsCast<JSGlobalObject*>(unwrappedObject))); } EncodedJSValue JSC_HOST_CALL globalFuncParseInt(ExecState* exec) @@ -548,7 +548,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncParseInt(ExecState* exec) } // If ToString throws, we shouldn't call ToInt32. - UString s = value.toString(exec)->value(exec); + String s = value.toString(exec)->value(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); @@ -615,7 +615,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec) "*+-./@_"; JSStringBuilder builder; - UString str = exec->argument(0).toString(exec)->value(exec); + String str = exec->argument(0).toString(exec)->value(exec); if (str.is8Bit()) { const LChar* c = str.characters8(); for (unsigned k = 0; k < str.length(); k++, c++) { @@ -653,8 +653,8 @@ EncodedJSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec) EncodedJSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec) { - UStringBuilder builder; - UString str = exec->argument(0).toString(exec)->value(exec); + StringBuilder builder; + String str = exec->argument(0).toString(exec)->value(exec); int k = 0; int len = str.length(); @@ -699,7 +699,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec) } } - return JSValue::encode(jsString(exec, builder.toUString())); + return JSValue::encode(jsString(exec, builder.toString())); } EncodedJSValue JSC_HOST_CALL globalFuncThrowTypeError(ExecState* exec) diff --git a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h index 8833bf6d0..757c9dcac 100644 --- a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h +++ b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h @@ -56,7 +56,7 @@ namespace JSC { ALWAYS_INLINE double parseIntOverflow(const char* s, int length, int radix) { return parseIntOverflow(reinterpret_cast<const LChar*>(s), length, radix); } double parseIntOverflow(const UChar*, int length, int radix); bool isStrWhiteSpace(UChar); - double jsToNumber(const UString& s); + double jsToNumber(const WTF::String&); } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/JSGlobalThis.cpp b/Source/JavaScriptCore/runtime/JSGlobalThis.cpp index b2bbae5d7..a3f2e7785 100644 --- a/Source/JavaScriptCore/runtime/JSGlobalThis.cpp +++ b/Source/JavaScriptCore/runtime/JSGlobalThis.cpp @@ -44,8 +44,7 @@ void JSGlobalThis::visitChildren(JSCell* cell, SlotVisitor& visitor) ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); Base::visitChildren(thisObject, visitor); - if (thisObject->m_unwrappedObject) - visitor.append(&thisObject->m_unwrappedObject); + visitor.append(&thisObject->m_unwrappedObject); } void JSGlobalThis::setUnwrappedObject(JSGlobalData& globalData, JSGlobalObject* globalObject) diff --git a/Source/JavaScriptCore/runtime/JSLock.cpp b/Source/JavaScriptCore/runtime/JSLock.cpp index be30c0c9c..c57c9cdc5 100644 --- a/Source/JavaScriptCore/runtime/JSLock.cpp +++ b/Source/JavaScriptCore/runtime/JSLock.cpp @@ -25,7 +25,7 @@ #include "CallFrame.h" #include "JSGlobalObject.h" #include "JSObject.h" -#include "ScopeChain.h" + #if USE(PTHREADS) #include <pthread.h> diff --git a/Source/JavaScriptCore/runtime/JSNameScope.cpp b/Source/JavaScriptCore/runtime/JSNameScope.cpp new file mode 100644 index 000000000..5dc665c44 --- /dev/null +++ b/Source/JavaScriptCore/runtime/JSNameScope.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2008, 2009, 2012 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. + */ + +#include "config.h" +#include "JSNameScope.h" + +#include "Error.h" + +namespace JSC { + +ASSERT_CLASS_FITS_IN_CELL(JSNameScope); + +const ClassInfo JSNameScope::s_info = { "NameScope", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSNameScope) }; + +void JSNameScope::visitChildren(JSCell* cell, SlotVisitor& visitor) +{ + JSNameScope* thisObject = jsCast<JSNameScope*>(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); + COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); + ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); + + Base::visitChildren(thisObject, visitor); + visitor.append(&thisObject->m_registerStore); +} + +JSObject* JSNameScope::toThisObject(JSCell*, ExecState* exec) +{ + return exec->globalThisValue(); +} + +void JSNameScope::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot) +{ + JSNameScope* thisObject = jsCast<JSNameScope*>(cell); + if (slot.isStrictMode()) { + // Double lookup in strict mode, but this only occurs when + // a) indirectly writing to an exception slot + // b) writing to a function expression name + // (a) is unlikely, and (b) is an error. + // Also with a single entry the symbol table lookup should simply be + // a pointer compare. + PropertySlot slot; + bool isWritable = true; + symbolTableGet(thisObject, propertyName, slot, isWritable); + if (!isWritable) { + throwError(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError)); + return; + } + } + if (symbolTablePut(thisObject, exec, propertyName, value, slot.isStrictMode())) + return; + + ASSERT_NOT_REACHED(); +} + +bool JSNameScope::getOwnPropertySlot(JSCell* cell, ExecState*, PropertyName propertyName, PropertySlot& slot) +{ + return symbolTableGet(jsCast<JSNameScope*>(cell), propertyName, slot); +} + +} // namespace JSC diff --git a/Source/JavaScriptCore/runtime/JSNameScope.h b/Source/JavaScriptCore/runtime/JSNameScope.h new file mode 100644 index 000000000..e67370d92 --- /dev/null +++ b/Source/JavaScriptCore/runtime/JSNameScope.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2008, 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 JSNameScope_h +#define JSNameScope_h + +#include "JSGlobalObject.h" +#include "JSVariableObject.h" + +namespace JSC { + +// Used for scopes with a single named variable: catch and named function expression. +class JSNameScope : public JSVariableObject { +public: + typedef JSVariableObject Base; + + static JSNameScope* create(ExecState* exec, const Identifier& identifier, JSValue value, unsigned attributes) + { + JSNameScope* scopeObject = new (NotNull, allocateCell<JSNameScope>(*exec->heap())) JSNameScope(exec, exec->scope()); + scopeObject->finishCreation(exec, identifier, value, attributes); + return scopeObject; + } + + static JSNameScope* create(ExecState* exec, const Identifier& identifier, JSValue value, unsigned attributes, JSScope* next) + { + JSNameScope* scopeObject = new (NotNull, allocateCell<JSNameScope>(*exec->heap())) JSNameScope(exec, next); + scopeObject->finishCreation(exec, identifier, value, attributes); + return scopeObject; + } + + static void visitChildren(JSCell*, SlotVisitor&); + bool isDynamicScope(bool& requiresDynamicChecks) const; + static JSObject* toThisObject(JSCell*, ExecState*); + static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&); + static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); + + static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(globalData, globalObject, proto, TypeInfo(NameScopeObjectType, StructureFlags), &s_info); } + + static const ClassInfo s_info; + +protected: + void finishCreation(ExecState* exec, const Identifier& identifier, JSValue value, unsigned attributes) + { + Base::finishCreation(exec->globalData()); + m_registerStore.set(exec->globalData(), this, value); + symbolTable()->add(identifier.impl(), SymbolTableEntry(-1, attributes)); + } + + static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | Base::StructureFlags; + +private: + JSNameScope(ExecState* exec, JSScope* next) + : Base( + exec->globalData(), + exec->lexicalGlobalObject()->nameScopeStructure(), + reinterpret_cast<Register*>(&m_registerStore + 1), + next + ) + { + } + + WriteBarrier<Unknown> m_registerStore; +}; + +inline bool JSNameScope::isDynamicScope(bool&) const +{ + return false; +} + +} + +#endif // JSNameScope_h diff --git a/Source/JavaScriptCore/runtime/JSONObject.cpp b/Source/JavaScriptCore/runtime/JSONObject.cpp index 065ae3828..45854dcea 100644 --- a/Source/JavaScriptCore/runtime/JSONObject.cpp +++ b/Source/JavaScriptCore/runtime/JSONObject.cpp @@ -36,9 +36,8 @@ #include "LocalScope.h" #include "Lookup.h" #include "PropertyNameArray.h" -#include "UStringBuilder.h" -#include "UStringConcatenate.h" #include <wtf/MathExtras.h> +#include <wtf/text/StringBuilder.h> namespace JSC { @@ -94,7 +93,7 @@ private: JSObject* object() const { return m_object.get(); } - bool appendNextProperty(Stringifier&, UStringBuilder&); + bool appendNextProperty(Stringifier&, StringBuilder&); private: Local<JSObject> m_object; @@ -107,17 +106,17 @@ private: friend class Holder; - static void appendQuotedString(UStringBuilder&, const UString&); + static void appendQuotedString(StringBuilder&, const String&); JSValue toJSON(JSValue, const PropertyNameForFunctionCall&); enum StringifyResult { StringifyFailed, StringifySucceeded, StringifyFailedDueToUndefinedValue }; - StringifyResult appendStringifiedValue(UStringBuilder&, JSValue, JSObject* holder, const PropertyNameForFunctionCall&); + StringifyResult appendStringifiedValue(StringBuilder&, JSValue, JSObject* holder, const PropertyNameForFunctionCall&); bool willIndent() const; void indent(); void unindent(); - void startNewLine(UStringBuilder&) const; + void startNewLine(StringBuilder&) const; ExecState* const m_exec; const Local<Unknown> m_replacer; @@ -125,11 +124,11 @@ private: PropertyNameArray m_arrayReplacerPropertyNames; CallType m_replacerCallType; CallData m_replacerCallData; - const UString m_gap; + const String m_gap; Vector<Holder, 16> m_holderStack; - UString m_repeatedGap; - UString m_indent; + String m_repeatedGap; + String m_indent; }; // ------------------------------ helper functions -------------------------------- @@ -148,7 +147,7 @@ static inline JSValue unwrapBoxedPrimitive(ExecState* exec, JSValue value) return value; } -static inline UString gap(ExecState* exec, JSValue space) +static inline String gap(ExecState* exec, JSValue space) { const unsigned maxGapLength = 10; space = unwrapBoxedPrimitive(exec, space); @@ -166,11 +165,11 @@ static inline UString gap(ExecState* exec, JSValue space) UChar spaces[maxGapLength]; for (int i = 0; i < count; ++i) spaces[i] = ' '; - return UString(spaces, count); + return String(spaces, count); } // If the space value is a string, use it as the gap string, otherwise use no gap string. - UString spaces = space.getString(exec); + String spaces = space.getString(exec); if (spaces.length() > maxGapLength) { spaces = spaces.substringSharingImpl(0, maxGapLength); } @@ -194,7 +193,7 @@ JSValue PropertyNameForFunctionCall::value(ExecState* exec) const { if (!m_value) { if (m_identifier) - m_value = jsString(exec, m_identifier->ustring()); + m_value = jsString(exec, m_identifier->string()); else m_value = jsNumber(m_number); } @@ -245,17 +244,17 @@ Local<Unknown> Stringifier::stringify(Handle<Unknown> value) PropertyNameForFunctionCall emptyPropertyName(m_exec->globalData().propertyNames->emptyIdentifier); object->putDirect(m_exec->globalData(), m_exec->globalData().propertyNames->emptyIdentifier, value.get()); - UStringBuilder result; + StringBuilder result; if (appendStringifiedValue(result, value.get(), object, emptyPropertyName) != StringifySucceeded) return Local<Unknown>(m_exec->globalData(), jsUndefined()); if (m_exec->hadException()) return Local<Unknown>(m_exec->globalData(), jsNull()); - return Local<Unknown>(m_exec->globalData(), jsString(m_exec, result.toUString())); + return Local<Unknown>(m_exec->globalData(), jsString(m_exec, result.toString())); } template <typename CharType> -static void appendStringToUStringBuilder(UStringBuilder& builder, const CharType* data, int length) +static void appendStringToStringBuilder(StringBuilder& builder, const CharType* data, int length) { for (int i = 0; i < length; ++i) { int start = i; @@ -303,16 +302,16 @@ static void appendStringToUStringBuilder(UStringBuilder& builder, const CharType } } -void Stringifier::appendQuotedString(UStringBuilder& builder, const UString& value) +void Stringifier::appendQuotedString(StringBuilder& builder, const String& value) { int length = value.length(); builder.append('"'); if (value.is8Bit()) - appendStringToUStringBuilder<LChar>(builder, value.characters8(), length); + appendStringToStringBuilder<LChar>(builder, value.characters8(), length); else - appendStringToUStringBuilder<UChar>(builder, value.characters16(), length); + appendStringToStringBuilder<UChar>(builder, value.characters16(), length); builder.append('"'); } @@ -341,7 +340,7 @@ inline JSValue Stringifier::toJSON(JSValue value, const PropertyNameForFunctionC return call(m_exec, object, callType, callData, value, args); } -Stringifier::StringifyResult Stringifier::appendStringifiedValue(UStringBuilder& builder, JSValue value, JSObject* holder, const PropertyNameForFunctionCall& propertyName) +Stringifier::StringifyResult Stringifier::appendStringifiedValue(StringBuilder& builder, JSValue value, JSObject* holder, const PropertyNameForFunctionCall& propertyName) { // Call the toJSON function. value = toJSON(value, propertyName); @@ -362,7 +361,7 @@ Stringifier::StringifyResult Stringifier::appendStringifiedValue(UStringBuilder& return StringifyFailedDueToUndefinedValue; if (value.isNull()) { - builder.append("null"); + builder.appendLiteral("null"); return StringifySucceeded; } @@ -372,11 +371,14 @@ Stringifier::StringifyResult Stringifier::appendStringifiedValue(UStringBuilder& return StringifyFailed; if (value.isBoolean()) { - builder.append(value.isTrue() ? "true" : "false"); + if (value.isTrue()) + builder.appendLiteral("true"); + else + builder.appendLiteral("false"); return StringifySucceeded; } - UString stringValue; + String stringValue; if (value.getString(m_exec, stringValue)) { appendQuotedString(builder, stringValue); return StringifySucceeded; @@ -385,9 +387,9 @@ Stringifier::StringifyResult Stringifier::appendStringifiedValue(UStringBuilder& if (value.isNumber()) { double number = value.asNumber(); if (!isfinite(number)) - builder.append("null"); + builder.appendLiteral("null"); else - builder.append(UString::number(number)); + builder.append(String::numberToStringECMAScript(number)); return StringifySucceeded; } @@ -399,7 +401,7 @@ Stringifier::StringifyResult Stringifier::appendStringifiedValue(UStringBuilder& CallData callData; if (object->methodTable()->getCallData(object, callData) != CallTypeNone) { if (holder->inherits(&JSArray::s_info)) { - builder.append("null"); + builder.appendLiteral("null"); return StringifySucceeded; } return StringifyFailedDueToUndefinedValue; @@ -408,7 +410,7 @@ Stringifier::StringifyResult Stringifier::appendStringifiedValue(UStringBuilder& // Handle cycle detection, and put the holder on the stack. for (unsigned i = 0; i < m_holderStack.size(); i++) { if (m_holderStack[i].object() == object) { - throwError(m_exec, createTypeError(m_exec, "JSON.stringify cannot serialize cyclic structures.")); + throwError(m_exec, createTypeError(m_exec, ASCIILiteral("JSON.stringify cannot serialize cyclic structures."))); return StringifyFailed; } } @@ -448,7 +450,7 @@ inline void Stringifier::indent() // Use a single shared string, m_repeatedGap, so we don't keep allocating new ones as we indent and unindent. unsigned newSize = m_indent.length() + m_gap.length(); if (newSize > m_repeatedGap.length()) - m_repeatedGap = makeUString(m_repeatedGap, m_gap); + m_repeatedGap = makeString(m_repeatedGap, m_gap); ASSERT(newSize <= m_repeatedGap.length()); m_indent = m_repeatedGap.substringSharingImpl(0, newSize); } @@ -459,7 +461,7 @@ inline void Stringifier::unindent() m_indent = m_repeatedGap.substringSharingImpl(0, m_indent.length() - m_gap.length()); } -inline void Stringifier::startNewLine(UStringBuilder& builder) const +inline void Stringifier::startNewLine(StringBuilder& builder) const { if (m_gap.isEmpty()) return; @@ -477,7 +479,7 @@ inline Stringifier::Holder::Holder(JSGlobalData& globalData, JSObject* object) { } -bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, UStringBuilder& builder) +bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, StringBuilder& builder) { ASSERT(m_index <= m_size); @@ -555,7 +557,7 @@ bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, UStringBu stringifier.startNewLine(builder); // Append the property name. - appendQuotedString(builder, propertyName.ustring()); + appendQuotedString(builder, propertyName.string()); builder.append(':'); if (stringifier.willIndent()) builder.append(' '); @@ -570,7 +572,7 @@ bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, UStringBu switch (stringifyResult) { case StringifyFailed: - builder.append("null"); + builder.appendLiteral("null"); break; case StringifySucceeded: break; @@ -704,11 +706,11 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered) } case ArrayEndVisitMember: { JSArray* array = arrayStack.peek(); - JSValue filteredValue = callReviver(array, jsString(m_exec, UString::number(indexStack.last())), outValue); + JSValue filteredValue = callReviver(array, jsString(m_exec, String::number(indexStack.last())), outValue); if (filteredValue.isUndefined()) array->methodTable()->deletePropertyByIndex(array, m_exec, indexStack.last()); else - array->putDirectIndex(m_exec, indexStack.last(), filteredValue, false); + array->putDirectIndex(m_exec, indexStack.last(), filteredValue); if (m_exec->hadException()) return jsNull(); indexStack.last()++; @@ -767,7 +769,7 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered) JSObject* object = objectStack.peek(); Identifier prop = propertyStack.last()[indexStack.last()]; PutPropertySlot slot; - JSValue filteredValue = callReviver(object, jsString(m_exec, prop.ustring()), outValue); + JSValue filteredValue = callReviver(object, jsString(m_exec, prop.string()), outValue); if (filteredValue.isUndefined()) object->methodTable()->deleteProperty(object, m_exec, prop); else @@ -810,8 +812,8 @@ NEVER_INLINE JSValue Walker::walk(JSValue unfiltered) EncodedJSValue JSC_HOST_CALL JSONProtoFuncParse(ExecState* exec) { if (!exec->argumentCount()) - return throwVMError(exec, createError(exec, "JSON.parse requires at least one parameter")); - UString source = exec->argument(0).toString(exec)->value(exec); + return throwVMError(exec, createError(exec, ASCIILiteral("JSON.parse requires at least one parameter"))); + String source = exec->argument(0).toString(exec)->value(exec); if (exec->hadException()) return JSValue::encode(jsNull()); @@ -844,7 +846,7 @@ EncodedJSValue JSC_HOST_CALL JSONProtoFuncParse(ExecState* exec) EncodedJSValue JSC_HOST_CALL JSONProtoFuncStringify(ExecState* exec) { if (!exec->argumentCount()) - return throwVMError(exec, createError(exec, "No input to stringify")); + return throwVMError(exec, createError(exec, ASCIILiteral("No input to stringify"))); LocalScope scope(exec->globalData()); Local<Unknown> value(exec->globalData(), exec->argument(0)); Local<Unknown> replacer(exec->globalData(), exec->argument(1)); @@ -852,12 +854,12 @@ EncodedJSValue JSC_HOST_CALL JSONProtoFuncStringify(ExecState* exec) return JSValue::encode(Stringifier(exec, replacer, space).stringify(value).get()); } -UString JSONStringify(ExecState* exec, JSValue value, unsigned indent) +String JSONStringify(ExecState* exec, JSValue value, unsigned indent) { LocalScope scope(exec->globalData()); Local<Unknown> result = Stringifier(exec, Local<Unknown>(exec->globalData(), jsNull()), Local<Unknown>(exec->globalData(), jsNumber(indent))).stringify(Local<Unknown>(exec->globalData(), value)); if (result.isUndefinedOrNull()) - return UString(); + return String(); return result.getString(exec); } diff --git a/Source/JavaScriptCore/runtime/JSONObject.h b/Source/JavaScriptCore/runtime/JSONObject.h index 3b8647714..b537b9144 100644 --- a/Source/JavaScriptCore/runtime/JSONObject.h +++ b/Source/JavaScriptCore/runtime/JSONObject.h @@ -61,7 +61,7 @@ namespace JSC { }; - UString JSONStringify(ExecState* exec, JSValue value, unsigned indent); + String JSONStringify(ExecState*, JSValue, unsigned indent); } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/JSObject.cpp b/Source/JavaScriptCore/runtime/JSObject.cpp index c40c625e1..812ba3bc8 100644 --- a/Source/JavaScriptCore/runtime/JSObject.cpp +++ b/Source/JavaScriptCore/runtime/JSObject.cpp @@ -154,7 +154,7 @@ void JSFinalObject::visitChildren(JSCell* cell, SlotVisitor& visitor) #endif } -UString JSObject::className(const JSObject* object) +String JSObject::className(const JSObject* object) { const ClassInfo* info = object->classInfo(); ASSERT(info); @@ -182,7 +182,7 @@ void JSObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSV prototype = obj->prototype(); if (prototype.isNull()) { if (!thisObject->putDirectInternal<PutModePut>(globalData, propertyName, value, 0, slot, getCallableObject(value)) && slot.isStrictMode()) - throwTypeError(exec, StrictModeReadonlyPropertyWriteError); + throwTypeError(exec, ASCIILiteral(StrictModeReadonlyPropertyWriteError)); return; } } @@ -195,7 +195,7 @@ void JSObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSV if (offset != invalidOffset) { if (attributes & ReadOnly) { if (slot.isStrictMode()) - throwError(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError)); + throwError(exec, createTypeError(exec, ASCIILiteral(StrictModeReadonlyPropertyWriteError))); return; } @@ -204,7 +204,7 @@ void JSObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSV JSObject* setterFunc = asGetterSetter(gs)->setter(); if (!setterFunc) { if (slot.isStrictMode()) - throwError(exec, createTypeError(exec, "setting a property that has only a getter")); + throwError(exec, createTypeError(exec, ASCIILiteral("setting a property that has only a getter"))); return; } @@ -229,7 +229,7 @@ void JSObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSV } if (!thisObject->putDirectInternal<PutModePut>(globalData, propertyName, value, 0, slot, getCallableObject(value)) && slot.isStrictMode()) - throwTypeError(exec, StrictModeReadonlyPropertyWriteError); + throwTypeError(exec, ASCIILiteral(StrictModeReadonlyPropertyWriteError)); return; } @@ -389,7 +389,7 @@ JSValue JSObject::defaultValue(const JSObject* object, ExecState* exec, Preferre ASSERT(!exec->hadException()); - return throwError(exec, createTypeError(exec, "No default value")); + return throwError(exec, createTypeError(exec, ASCIILiteral("No default value"))); } const HashEntry* JSObject::findPropertyHashEntry(ExecState* exec, PropertyName propertyName) const @@ -409,7 +409,7 @@ bool JSObject::hasInstance(JSObject*, ExecState* exec, JSValue value, JSValue pr return false; if (!proto.isObject()) { - throwError(exec, createTypeError(exec, "instanceof called on an object with an invalid prototype property.")); + throwError(exec, createTypeError(exec, ASCIILiteral("instanceof called on an object with an invalid prototype property."))); return false; } @@ -718,7 +718,7 @@ bool JSObject::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName // unless extensions are prevented! if (!object->isExtensible()) { if (throwException) - throwError(exec, createTypeError(exec, "Attempting to define property on object that is not extensible.")); + throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to define property on object that is not extensible."))); return false; } PropertyDescriptor oldDescriptor; @@ -736,12 +736,12 @@ bool JSObject::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName if (!current.configurable()) { if (descriptor.configurable()) { if (throwException) - throwError(exec, createTypeError(exec, "Attempting to configurable attribute of unconfigurable property.")); + throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to configurable attribute of unconfigurable property."))); return false; } if (descriptor.enumerablePresent() && descriptor.enumerable() != current.enumerable()) { if (throwException) - throwError(exec, createTypeError(exec, "Attempting to change enumerable attribute of unconfigurable property.")); + throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change enumerable attribute of unconfigurable property."))); return false; } } @@ -759,7 +759,7 @@ bool JSObject::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName if (descriptor.isDataDescriptor() != current.isDataDescriptor()) { if (!current.configurable()) { if (throwException) - throwError(exec, createTypeError(exec, "Attempting to change access mechanism for an unconfigurable property.")); + throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change access mechanism for an unconfigurable property."))); return false; } object->methodTable()->deleteProperty(object, exec, propertyName); @@ -771,13 +771,13 @@ bool JSObject::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName if (!current.configurable()) { if (!current.writable() && descriptor.writable()) { if (throwException) - throwError(exec, createTypeError(exec, "Attempting to change writable attribute of unconfigurable property.")); + throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change writable attribute of unconfigurable property."))); return false; } if (!current.writable()) { if (descriptor.value() && !sameValue(exec, current.value(), descriptor.value())) { if (throwException) - throwError(exec, createTypeError(exec, "Attempting to change value of a readonly property.")); + throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change value of a readonly property."))); return false; } } @@ -793,12 +793,12 @@ bool JSObject::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName if (!current.configurable()) { if (descriptor.setterPresent() && !(current.setterPresent() && JSValue::strictEqual(exec, current.setter(), descriptor.setter()))) { if (throwException) - throwError(exec, createTypeError(exec, "Attempting to change the setter of an unconfigurable property.")); + throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change the setter of an unconfigurable property."))); return false; } if (descriptor.getterPresent() && !(current.getterPresent() && JSValue::strictEqual(exec, current.getter(), descriptor.getter()))) { if (throwException) - throwError(exec, createTypeError(exec, "Attempting to change the getter of an unconfigurable property.")); + throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change the getter of an unconfigurable property."))); return false; } } @@ -818,7 +818,7 @@ bool JSObject::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName return true; } -JSObject* throwTypeError(ExecState* exec, const UString& message) +JSObject* throwTypeError(ExecState* exec, const String& message) { return throwError(exec, createTypeError(exec, message)); } diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h index 82da5eef9..f4b847b4c 100644 --- a/Source/JavaScriptCore/runtime/JSObject.h +++ b/Source/JavaScriptCore/runtime/JSObject.h @@ -30,7 +30,7 @@ #include "JSCell.h" #include "PropertySlot.h" #include "PutPropertySlot.h" -#include "ScopeChain.h" + #include "StorageBarrier.h" #include "Structure.h" #include "JSGlobalData.h" @@ -65,7 +65,7 @@ namespace JSC { class Structure; struct HashTable; - JS_EXPORT_PRIVATE JSObject* throwTypeError(ExecState*, const UString&); + JS_EXPORT_PRIVATE JSObject* throwTypeError(ExecState*, const String&); extern JS_EXPORTDATA const char* StrictModeReadonlyPropertyWriteError; // ECMA 262-3 8.6.1 @@ -99,7 +99,7 @@ namespace JSC { JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&); - JS_EXPORT_PRIVATE static UString className(const JSObject*); + JS_EXPORT_PRIVATE static String className(const JSObject*); JSValue prototype() const; void setPrototype(JSGlobalData&, JSValue prototype); @@ -254,7 +254,7 @@ namespace JSC { bool isGlobalObject() const; bool isVariableObject() const; - bool isStaticScopeObject() const; + bool isNameScopeObject() const; bool isActivationObject() const; bool isErrorInstance() const; bool isGlobalThis() const; @@ -314,8 +314,6 @@ namespace JSC { return Structure::create(globalData, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), &s_info); } - static const unsigned StructureFlags = 0; - // To instantiate objects you likely want JSFinalObject, below. // To create derived types you likely want JSNonFinalObject, below. JSObject(JSGlobalData&, Structure*); @@ -473,9 +471,9 @@ inline bool JSObject::isVariableObject() const return structure()->typeInfo().type() >= VariableObjectType; } -inline bool JSObject::isStaticScopeObject() const +inline bool JSObject::isNameScopeObject() const { - return structure()->typeInfo().type() == StaticScopeObjectType; + return structure()->typeInfo().type() == NameScopeObjectType; } inline bool JSObject::isActivationObject() const @@ -622,7 +620,7 @@ ALWAYS_INLINE bool JSCell::fastGetOwnPropertySlot(ExecState* exec, PropertyName // identifier. The first time we perform a property access with a given string, try // performing the property map lookup without forming an identifier. We detect this // case by checking whether the hash has yet been set for this string. -ALWAYS_INLINE JSValue JSCell::fastGetOwnProperty(ExecState* exec, const UString& name) +ALWAYS_INLINE JSValue JSCell::fastGetOwnProperty(ExecState* exec, const String& name) { if (!structure()->typeInfo().overridesGetOwnPropertySlot() && !structure()->hasGetterSetterProperties()) { PropertyOffset offset = name.impl()->hasHash() diff --git a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp index aaf946d3d..b1376c5e8 100644 --- a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp +++ b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.cpp @@ -103,8 +103,7 @@ void JSPropertyNameIterator::visitChildren(JSCell* cell, SlotVisitor& visitor) ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); visitor.appendValues(thisObject->m_jsStrings.get(), thisObject->m_jsStringsSize); - if (thisObject->m_cachedPrototypeChain) - visitor.append(&thisObject->m_cachedPrototypeChain); + visitor.append(&thisObject->m_cachedPrototypeChain); } } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h index 653ee0463..057ffe293 100644 --- a/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h +++ b/Source/JavaScriptCore/runtime/JSPropertyNameIterator.h @@ -87,7 +87,7 @@ namespace JSC { Base::finishCreation(exec->globalData()); PropertyNameArrayData::PropertyNameVector& propertyNameVector = propertyNameArrayData->propertyNameVector(); for (size_t i = 0; i < m_jsStringsSize; ++i) - m_jsStrings[i].set(exec->globalData(), this, jsOwnedString(exec, propertyNameVector[i].ustring())); + m_jsStrings[i].set(exec->globalData(), this, jsOwnedString(exec, propertyNameVector[i].string())); m_offsetBase = object->structure()->firstValidOffset(); } diff --git a/Source/JavaScriptCore/runtime/JSScope.cpp b/Source/JavaScriptCore/runtime/JSScope.cpp new file mode 100644 index 000000000..b22211970 --- /dev/null +++ b/Source/JavaScriptCore/runtime/JSScope.cpp @@ -0,0 +1,262 @@ +/* + * Copyright (C) 2012 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. + */ + +#include "config.h" +#include "JSScope.h" + +#include "JSActivation.h" +#include "JSGlobalObject.h" +#include "JSNameScope.h" +#include "JSWithScope.h" + +namespace JSC { + +ASSERT_CLASS_FITS_IN_CELL(JSScope); + +void JSScope::visitChildren(JSCell* cell, SlotVisitor& visitor) +{ + JSScope* thisObject = jsCast<JSScope*>(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); + COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); + ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); + + Base::visitChildren(thisObject, visitor); + visitor.append(&thisObject->m_next); +} + +bool JSScope::isDynamicScope(bool& requiresDynamicChecks) const +{ + switch (structure()->typeInfo().type()) { + case GlobalObjectType: + return static_cast<const JSGlobalObject*>(this)->isDynamicScope(requiresDynamicChecks); + case ActivationObjectType: + return static_cast<const JSActivation*>(this)->isDynamicScope(requiresDynamicChecks); + case NameScopeObjectType: + return static_cast<const JSNameScope*>(this)->isDynamicScope(requiresDynamicChecks); + default: + ASSERT_NOT_REACHED(); + break; + } + + return false; +} + +JSObject* JSScope::objectAtScope(JSScope* scope) +{ + JSObject* object = scope; + if (object->structure()->typeInfo().type() == WithScopeType) + return jsCast<JSWithScope*>(object)->object(); + + return object; +} + +int JSScope::localDepth() +{ + int scopeDepth = 0; + ScopeChainIterator iter = this->begin(); + ScopeChainIterator end = this->end(); + while (!iter->inherits(&JSActivation::s_info)) { + ++iter; + if (iter == end) + break; + ++scopeDepth; + } + return scopeDepth; +} + +JSValue JSScope::resolve(CallFrame* callFrame, const Identifier& identifier) +{ + JSScope* scope = callFrame->scope(); + ASSERT(scope); + + do { + JSObject* object = JSScope::objectAtScope(scope); + PropertySlot slot(object); + if (object->getPropertySlot(callFrame, identifier, slot)) + return slot.getValue(callFrame, identifier); + } while ((scope = scope->next())); + + return throwError(callFrame, createUndefinedVariableError(callFrame, identifier)); +} + +JSValue JSScope::resolveSkip(CallFrame* callFrame, const Identifier& identifier, int skip) +{ + JSScope* scope = callFrame->scope(); + ASSERT(scope); + + CodeBlock* codeBlock = callFrame->codeBlock(); + + bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain(); + ASSERT(skip || !checkTopLevel); + if (checkTopLevel && skip--) { + if (callFrame->uncheckedR(codeBlock->activationRegister()).jsValue()) + scope = scope->next(); + } + while (skip--) { + scope = scope->next(); + ASSERT(scope); + } + + do { + JSObject* object = JSScope::objectAtScope(scope); + PropertySlot slot(object); + if (object->getPropertySlot(callFrame, identifier, slot)) + return slot.getValue(callFrame, identifier); + } while ((scope = scope->next())); + + return throwError(callFrame, createUndefinedVariableError(callFrame, identifier)); +} + +JSValue JSScope::resolveGlobal( + CallFrame* callFrame, + const Identifier& identifier, + JSGlobalObject* globalObject, + WriteBarrierBase<Structure>* cachedStructure, + PropertyOffset* cachedOffset +) +{ + if (globalObject->structure() == cachedStructure->get()) + return globalObject->getDirectOffset(*cachedOffset); + + PropertySlot slot(globalObject); + if (!globalObject->getPropertySlot(callFrame, identifier, slot)) + return throwError(callFrame, createUndefinedVariableError(callFrame, identifier)); + + JSValue result = slot.getValue(callFrame, identifier); + if (callFrame->globalData().exception) + return JSValue(); + + if (slot.isCacheableValue() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) { + cachedStructure->set(callFrame->globalData(), callFrame->codeBlock()->ownerExecutable(), globalObject->structure()); + *cachedOffset = slot.cachedOffset(); + } + return result; +} + +JSValue JSScope::resolveGlobalDynamic( + CallFrame* callFrame, + const Identifier& identifier, + int skip, + WriteBarrierBase<Structure>* cachedStructure, + PropertyOffset* cachedOffset +) +{ + JSScope* scope = callFrame->scope(); + ASSERT(scope); + + CodeBlock* codeBlock = callFrame->codeBlock(); + + bool checkTopLevel = codeBlock->codeType() == FunctionCode && codeBlock->needsFullScopeChain(); + ASSERT(skip || !checkTopLevel); + if (checkTopLevel && skip--) { + if (callFrame->uncheckedR(codeBlock->activationRegister()).jsValue()) + scope = scope->next(); + } + while (skip--) { + JSObject* object = JSScope::objectAtScope(scope); + if (!object->hasCustomProperties()) + continue; + + PropertySlot slot(object); + if (!object->getPropertySlot(callFrame, identifier, slot)) + continue; + + JSValue result = slot.getValue(callFrame, identifier); + if (callFrame->globalData().exception) + return JSValue(); + return result; + } + + return resolveGlobal(callFrame, identifier, callFrame->lexicalGlobalObject(), cachedStructure, cachedOffset); +} + +JSValue JSScope::resolveBase(CallFrame* callFrame, const Identifier& identifier, bool isStrict) +{ + JSScope* scope = callFrame->scope(); + ASSERT(scope); + + do { + JSObject* object = JSScope::objectAtScope(scope); + + PropertySlot slot(object); + if (!object->getPropertySlot(callFrame, identifier, slot)) + continue; + + return JSValue(object); + } while ((scope = scope->next())); + + if (!isStrict) + return callFrame->lexicalGlobalObject(); + + return throwError(callFrame, createErrorForInvalidGlobalAssignment(callFrame, identifier.string())); +} + +JSValue JSScope::resolveWithBase(CallFrame* callFrame, const Identifier& identifier, Register* base) +{ + JSScope* scope = callFrame->scope(); + ASSERT(scope); + + do { + JSObject* object = JSScope::objectAtScope(scope); + + PropertySlot slot(object); + if (!object->getPropertySlot(callFrame, identifier, slot)) + continue; + + JSValue value = slot.getValue(callFrame, identifier); + if (callFrame->globalData().exception) + return JSValue(); + + *base = JSValue(object); + return value; + } while ((scope = scope->next())); + + return throwError(callFrame, createUndefinedVariableError(callFrame, identifier)); +} + +JSValue JSScope::resolveWithThis(CallFrame* callFrame, const Identifier& identifier, Register* base) +{ + JSScope* scope = callFrame->scope(); + ASSERT(scope); + + do { + JSObject* object = JSScope::objectAtScope(scope); + + PropertySlot slot(object); + if (!object->getPropertySlot(callFrame, identifier, slot)) + continue; + + JSValue value = slot.getValue(callFrame, identifier); + if (callFrame->globalData().exception) + return JSValue(); + + *base = object->structure()->typeInfo().isEnvironmentRecord() ? jsUndefined() : JSValue(object); + return value; + } while ((scope = scope->next())); + + return throwError(callFrame, createUndefinedVariableError(callFrame, identifier)); +} + +} // namespace JSC diff --git a/Source/JavaScriptCore/runtime/JSScope.h b/Source/JavaScriptCore/runtime/JSScope.h new file mode 100644 index 000000000..011aff57e --- /dev/null +++ b/Source/JavaScriptCore/runtime/JSScope.h @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2012 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 JSScope_h +#define JSScope_h + +#include "JSObject.h" + +namespace JSC { + +class ScopeChainIterator; + +class JSScope : public JSNonFinalObject { +public: + typedef JSNonFinalObject Base; + + friend class LLIntOffsetsExtractor; + static size_t offsetOfNext(); + + JS_EXPORT_PRIVATE static JSObject* objectAtScope(JSScope*); + + static JSValue resolve(CallFrame*, const Identifier&); + static JSValue resolveSkip(CallFrame*, const Identifier&, int skip); + static JSValue resolveGlobal( + CallFrame*, + const Identifier&, + JSGlobalObject* globalObject, + WriteBarrierBase<Structure>* cachedStructure, + PropertyOffset* cachedOffset + ); + static JSValue resolveGlobalDynamic( + CallFrame*, + const Identifier&, + int skip, + WriteBarrierBase<Structure>* cachedStructure, + PropertyOffset* cachedOffset + ); + static JSValue resolveBase(CallFrame*, const Identifier&, bool isStrict); + static JSValue resolveWithBase(CallFrame*, const Identifier&, Register* base); + static JSValue resolveWithThis(CallFrame*, const Identifier&, Register* base); + + static void visitChildren(JSCell*, SlotVisitor&); + + bool isDynamicScope(bool& requiresDynamicChecks) const; + + ScopeChainIterator begin(); + ScopeChainIterator end(); + JSScope* next(); + int localDepth(); + + JSGlobalObject* globalObject(); + JSGlobalData* globalData(); + JSObject* globalThis(); + +protected: + JSScope(JSGlobalData&, Structure*, JSScope* next); + static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags; + +private: + WriteBarrier<JSScope> m_next; +}; + +inline JSScope::JSScope(JSGlobalData& globalData, Structure* structure, JSScope* next) + : Base(globalData, structure) + , m_next(globalData, this, next, WriteBarrier<JSScope>::MayBeNull) +{ +} + +class ScopeChainIterator { +public: + ScopeChainIterator(JSScope* node) + : m_node(node) + { + } + + JSObject* get() const { return JSScope::objectAtScope(m_node); } + JSObject* operator->() const { return JSScope::objectAtScope(m_node); } + + ScopeChainIterator& operator++() { m_node = m_node->next(); return *this; } + + // postfix ++ intentionally omitted + + bool operator==(const ScopeChainIterator& other) const { return m_node == other.m_node; } + bool operator!=(const ScopeChainIterator& other) const { return m_node != other.m_node; } + +private: + JSScope* m_node; +}; + +inline ScopeChainIterator JSScope::begin() +{ + return ScopeChainIterator(this); +} + +inline ScopeChainIterator JSScope::end() +{ + return ScopeChainIterator(0); +} + +inline JSScope* JSScope::next() +{ + return m_next.get(); +} + +inline JSGlobalObject* JSScope::globalObject() +{ + return structure()->globalObject(); +} + +inline JSGlobalData* JSScope::globalData() +{ + return Heap::heap(this)->globalData(); +} + +inline Register& Register::operator=(JSScope* scope) +{ + *this = JSValue(scope); + return *this; +} + +inline JSScope* Register::scope() const +{ + return jsCast<JSScope*>(jsValue()); +} + +inline JSGlobalData& ExecState::globalData() const +{ + ASSERT(scope()->globalData()); + return *scope()->globalData(); +} + +inline JSGlobalObject* ExecState::lexicalGlobalObject() const +{ + return scope()->globalObject(); +} + +inline JSObject* ExecState::globalThisValue() const +{ + return scope()->globalThis(); +} + +inline size_t JSScope::offsetOfNext() +{ + return OBJECT_OFFSETOF(JSScope, m_next); +} + +} // namespace JSC + +#endif // JSScope_h diff --git a/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h b/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h index f1fe0483d..1fd96c17a 100644 --- a/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h +++ b/Source/JavaScriptCore/runtime/JSSegmentedVariableObject.h @@ -82,8 +82,8 @@ public: protected: static const unsigned StructureFlags = OverridesVisitChildren | JSSymbolTableObject::StructureFlags; - JSSegmentedVariableObject(JSGlobalData& globalData, Structure* structure, SymbolTable* symbolTable) - : JSSymbolTableObject(globalData, structure, symbolTable) + JSSegmentedVariableObject(JSGlobalData& globalData, Structure* structure, JSScope* scope) + : JSSymbolTableObject(globalData, structure, scope) { } diff --git a/Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp b/Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp index 14187f422..e69de29bb 100644 --- a/Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp +++ b/Source/JavaScriptCore/runtime/JSStaticScopeObject.cpp @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2008, 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. - */ - -#include "config.h" - -#include "JSStaticScopeObject.h" - -#include "Error.h" - -namespace JSC { -ASSERT_CLASS_FITS_IN_CELL(JSStaticScopeObject); - -const ClassInfo JSStaticScopeObject::s_info = { "Object", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSStaticScopeObject) }; - -void JSStaticScopeObject::destroy(JSCell* cell) -{ - static_cast<JSStaticScopeObject*>(cell)->JSStaticScopeObject::~JSStaticScopeObject(); -} - -void JSStaticScopeObject::visitChildren(JSCell* cell, SlotVisitor& visitor) -{ - JSStaticScopeObject* thisObject = jsCast<JSStaticScopeObject*>(cell); - ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); - COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); - ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); - JSVariableObject::visitChildren(thisObject, visitor); - visitor.append(&thisObject->m_registerStore); -} - -JSObject* JSStaticScopeObject::toThisObject(JSCell*, ExecState* exec) -{ - return exec->globalThisValue(); -} - -void JSStaticScopeObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot) -{ - JSStaticScopeObject* thisObject = jsCast<JSStaticScopeObject*>(cell); - if (slot.isStrictMode()) { - // Double lookup in strict mode, but this only occurs when - // a) indirectly writing to an exception slot - // b) writing to a function expression name - // (a) is unlikely, and (b) is an error. - // Also with a single entry the symbol table lookup should simply be - // a pointer compare. - PropertySlot slot; - bool isWritable = true; - symbolTableGet(thisObject, propertyName, slot, isWritable); - if (!isWritable) { - throwError(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError)); - return; - } - } - if (symbolTablePut(thisObject, exec, propertyName, value, slot.isStrictMode())) - return; - - ASSERT_NOT_REACHED(); -} - -void JSStaticScopeObject::putDirectVirtual(JSObject* object, ExecState* exec, PropertyName propertyName, JSValue value, unsigned attributes) -{ - JSStaticScopeObject* thisObject = jsCast<JSStaticScopeObject*>(object); - if (symbolTablePutWithAttributes(thisObject, exec->globalData(), propertyName, value, attributes)) - return; - - ASSERT_NOT_REACHED(); -} - -bool JSStaticScopeObject::getOwnPropertySlot(JSCell* cell, ExecState*, PropertyName propertyName, PropertySlot& slot) -{ - return symbolTableGet(jsCast<JSStaticScopeObject*>(cell), propertyName, slot); -} - -} diff --git a/Source/JavaScriptCore/runtime/JSStaticScopeObject.h b/Source/JavaScriptCore/runtime/JSStaticScopeObject.h index f351349a6..e69de29bb 100644 --- a/Source/JavaScriptCore/runtime/JSStaticScopeObject.h +++ b/Source/JavaScriptCore/runtime/JSStaticScopeObject.h @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2008, 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 JSStaticScopeObject_h -#define JSStaticScopeObject_h - -#include "JSVariableObject.h" - -namespace JSC{ - - class JSStaticScopeObject : public JSVariableObject { - public: - typedef JSVariableObject Base; - - static JSStaticScopeObject* create(ExecState* exec, const Identifier& identifier, JSValue value, unsigned attributes) - { - JSStaticScopeObject* scopeObject = new (NotNull, allocateCell<JSStaticScopeObject>(*exec->heap())) JSStaticScopeObject(exec); - scopeObject->finishCreation(exec, identifier, value, attributes); - return scopeObject; - } - - static void visitChildren(JSCell*, SlotVisitor&); - bool isDynamicScope(bool& requiresDynamicChecks) const; - static JSObject* toThisObject(JSCell*, ExecState*); - static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&); - static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&); - - static void putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned attributes); - - static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(globalData, globalObject, proto, TypeInfo(StaticScopeObjectType, StructureFlags), &s_info); } - - static const ClassInfo s_info; - - protected: - void finishCreation(ExecState* exec, const Identifier& identifier, JSValue value, unsigned attributes) - { - Base::finishCreation(exec->globalData()); - m_registerStore.set(exec->globalData(), this, value); - symbolTable().add(identifier.impl(), SymbolTableEntry(-1, attributes)); - } - static const unsigned StructureFlags = IsEnvironmentRecord | OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags; - - private: - JSStaticScopeObject(ExecState* exec) - : JSVariableObject(exec->globalData(), exec->globalData().staticScopeStructure.get(), &m_symbolTable, reinterpret_cast<Register*>(&m_registerStore + 1)) - { - } - - static void destroy(JSCell*); - - SymbolTable m_symbolTable; - WriteBarrier<Unknown> m_registerStore; - }; - - inline bool JSStaticScopeObject::isDynamicScope(bool&) const - { - return false; - } - -} - -#endif // JSStaticScopeObject_h diff --git a/Source/JavaScriptCore/runtime/JSString.cpp b/Source/JavaScriptCore/runtime/JSString.cpp index 4eb2a5297..f0e796d89 100644 --- a/Source/JavaScriptCore/runtime/JSString.cpp +++ b/Source/JavaScriptCore/runtime/JSString.cpp @@ -130,7 +130,10 @@ void JSRopeString::resolveRope(ExecState* exec) const for (size_t i = 0; i < s_maxInternalRopeLength && m_fibers[i]; ++i) { StringImpl* string = m_fibers[i]->m_value.impl(); unsigned length = string->length(); - StringImpl::copyChars(position, string->characters(), length); + if (string->is8Bit()) + StringImpl::copyChars(position, string->characters8(), length); + else + StringImpl::copyChars(position, string->characters16(), length); position += length; m_fibers[i].clear(); } @@ -139,7 +142,7 @@ void JSRopeString::resolveRope(ExecState* exec) const } // Overview: These functions convert a JSString from holding a string in rope form -// down to a simple UString representation. It does so by building up the string +// down to a simple String representation. It does so by building up the string // backwards, since we want to avoid recursion, we expect that the tree structure // representing the rope is likely imbalanced with more nodes down the left side // (since appending to the string is likely more common) - and as such resolving @@ -202,7 +205,10 @@ void JSRopeString::resolveRopeSlowCase(UChar* buffer) const StringImpl* string = static_cast<StringImpl*>(currentFiber->m_value.impl()); unsigned length = string->length(); position -= length; - StringImpl::copyChars(position, string->characters(), length); + if (string->is8Bit()) + StringImpl::copyChars(position, string->characters8(), length); + else + StringImpl::copyChars(position, string->characters16(), length); } ASSERT(buffer == position); @@ -214,7 +220,7 @@ void JSRopeString::outOfMemory(ExecState* exec) const for (size_t i = 0; i < s_maxInternalRopeLength && m_fibers[i]; ++i) m_fibers[i].clear(); ASSERT(isRope()); - ASSERT(m_value == UString()); + ASSERT(m_value.isNull()); if (exec) throwOutOfMemoryError(exec); } @@ -225,7 +231,7 @@ JSString* JSRopeString::getIndexSlowCase(ExecState* exec, unsigned i) resolveRope(exec); // Return a safe no-value result, this should never be used, since the excetion will be thrown. if (exec->exception()) - return jsString(exec, ""); + return jsEmptyString(exec); ASSERT(!isRope()); ASSERT(i < m_value.length()); return jsSingleCharacterSubstring(exec, m_value, i); diff --git a/Source/JavaScriptCore/runtime/JSString.h b/Source/JavaScriptCore/runtime/JSString.h index e91553aeb..7821b42b8 100644 --- a/Source/JavaScriptCore/runtime/JSString.h +++ b/Source/JavaScriptCore/runtime/JSString.h @@ -37,27 +37,25 @@ namespace JSC { JSString* jsEmptyString(JSGlobalData*); JSString* jsEmptyString(ExecState*); - JSString* jsString(JSGlobalData*, const UString&); // returns empty string if passed null string - JSString* jsString(ExecState*, const UString&); // returns empty string if passed null string + JSString* jsString(JSGlobalData*, const String&); // returns empty string if passed null string + JSString* jsString(ExecState*, const String&); // returns empty string if passed null string JSString* jsSingleCharacterString(JSGlobalData*, UChar); JSString* jsSingleCharacterString(ExecState*, UChar); - JSString* jsSingleCharacterSubstring(ExecState*, const UString&, unsigned offset); - JSString* jsSubstring(JSGlobalData*, const UString&, unsigned offset, unsigned length); - JSString* jsSubstring(ExecState*, const UString&, unsigned offset, unsigned length); + JSString* jsSingleCharacterSubstring(ExecState*, const String&, unsigned offset); + JSString* jsSubstring(JSGlobalData*, const String&, unsigned offset, unsigned length); + JSString* jsSubstring(ExecState*, const String&, unsigned offset, unsigned length); // Non-trivial strings are two or more characters long. // These functions are faster than just calling jsString. - JSString* jsNontrivialString(JSGlobalData*, const UString&); - JSString* jsNontrivialString(ExecState*, const UString&); - JSString* jsNontrivialString(JSGlobalData*, const char*); - JSString* jsNontrivialString(ExecState*, const char*); + JSString* jsNontrivialString(JSGlobalData*, const String&); + JSString* jsNontrivialString(ExecState*, const String&); // Should be used for strings that are owned by an object that will // likely outlive the JSValue this makes, such as the parse tree or a - // DOM object that contains a UString - JSString* jsOwnedString(JSGlobalData*, const UString&); - JSString* jsOwnedString(ExecState*, const UString&); + // DOM object that contains a String + JSString* jsOwnedString(JSGlobalData*, const String&); + JSString* jsOwnedString(ExecState*, const String&); JSRopeString* jsStringBuilder(JSGlobalData*); @@ -136,8 +134,8 @@ namespace JSC { return newString; } - const UString& value(ExecState*) const; - const UString& tryGetValue() const; + const String& value(ExecState*) const; + const String& tryGetValue() const; unsigned length() { return m_length; } JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const; @@ -190,9 +188,9 @@ namespace JSC { Is8Bit = 1u }; - // A string is represented either by a UString or a rope of fibers. + // A string is represented either by a String or a rope of fibers. unsigned m_length; - mutable UString m_value; + mutable String m_value; private: friend class LLIntOffsetsExtractor; @@ -203,7 +201,7 @@ namespace JSC { static bool getOwnPropertySlot(JSCell*, ExecState*, PropertyName, PropertySlot&); static bool getOwnPropertySlotByIndex(JSCell*, ExecState*, unsigned propertyName, PropertySlot&); - UString& string() { ASSERT(!isRope()); return m_value; } + String& string() { ASSERT(!isRope()); return m_value; } friend JSValue jsString(ExecState*, JSString*, JSString*); friend JSString* jsSubstring(ExecState*, JSString*, unsigned offset, unsigned length); @@ -340,41 +338,33 @@ namespace JSC { { if (c <= maxSingleCharacterString) return globalData->smallStrings.singleCharacterString(globalData, c); - return JSString::create(*globalData, UString(&c, 1).impl()); + return JSString::create(*globalData, String(&c, 1).impl()); } - ALWAYS_INLINE JSString* jsSingleCharacterSubstring(ExecState* exec, const UString& s, unsigned offset) + ALWAYS_INLINE JSString* jsSingleCharacterSubstring(ExecState* exec, const String& s, unsigned offset) { JSGlobalData* globalData = &exec->globalData(); ASSERT(offset < static_cast<unsigned>(s.length())); - UChar c = s[offset]; + UChar c = s.characterAt(offset); if (c <= maxSingleCharacterString) return globalData->smallStrings.singleCharacterString(globalData, c); return JSString::create(*globalData, StringImpl::create(s.impl(), offset, 1)); } - inline JSString* jsNontrivialString(JSGlobalData* globalData, const char* s) - { - ASSERT(s); - ASSERT(s[0]); - ASSERT(s[1]); - return JSString::create(*globalData, UString(s).impl()); - } - - inline JSString* jsNontrivialString(JSGlobalData* globalData, const UString& s) + inline JSString* jsNontrivialString(JSGlobalData* globalData, const String& s) { ASSERT(s.length() > 1); return JSString::create(*globalData, s.impl()); } - inline const UString& JSString::value(ExecState* exec) const + inline const String& JSString::value(ExecState* exec) const { if (isRope()) static_cast<const JSRopeString*>(this)->resolveRope(exec); return m_value; } - inline const UString& JSString::tryGetValue() const + inline const String& JSString::tryGetValue() const { if (isRope()) static_cast<const JSRopeString*>(this)->resolveRope(0); @@ -390,13 +380,13 @@ namespace JSC { return jsSingleCharacterSubstring(exec, m_value, i); } - inline JSString* jsString(JSGlobalData* globalData, const UString& s) + inline JSString* jsString(JSGlobalData* globalData, const String& s) { int size = s.length(); if (!size) return globalData->smallStrings.emptyString(globalData); if (size == 1) { - UChar c = s[0]; + UChar c = s.characterAt(0); if (c <= maxSingleCharacterString) return globalData->smallStrings.singleCharacterString(globalData, c); } @@ -414,7 +404,7 @@ namespace JSC { return jsSubstring(globalData, s->value(exec), offset, length); } - inline JSString* jsSubstring8(JSGlobalData* globalData, const UString& s, unsigned offset, unsigned length) + inline JSString* jsSubstring8(JSGlobalData* globalData, const String& s, unsigned offset, unsigned length) { ASSERT(offset <= static_cast<unsigned>(s.length())); ASSERT(length <= static_cast<unsigned>(s.length())); @@ -422,14 +412,14 @@ namespace JSC { if (!length) return globalData->smallStrings.emptyString(globalData); if (length == 1) { - UChar c = s[offset]; + UChar c = s.characterAt(offset); if (c <= maxSingleCharacterString) return globalData->smallStrings.singleCharacterString(globalData, c); } return JSString::createHasOtherOwner(*globalData, StringImpl::create8(s.impl(), offset, length)); } - inline JSString* jsSubstring(JSGlobalData* globalData, const UString& s, unsigned offset, unsigned length) + inline JSString* jsSubstring(JSGlobalData* globalData, const String& s, unsigned offset, unsigned length) { ASSERT(offset <= static_cast<unsigned>(s.length())); ASSERT(length <= static_cast<unsigned>(s.length())); @@ -437,20 +427,20 @@ namespace JSC { if (!length) return globalData->smallStrings.emptyString(globalData); if (length == 1) { - UChar c = s[offset]; + UChar c = s.characterAt(offset); if (c <= maxSingleCharacterString) return globalData->smallStrings.singleCharacterString(globalData, c); } return JSString::createHasOtherOwner(*globalData, StringImpl::create(s.impl(), offset, length)); } - inline JSString* jsOwnedString(JSGlobalData* globalData, const UString& s) + inline JSString* jsOwnedString(JSGlobalData* globalData, const String& s) { int size = s.length(); if (!size) return globalData->smallStrings.emptyString(globalData); if (size == 1) { - UChar c = s[0]; + UChar c = s.characterAt(0); if (c <= maxSingleCharacterString) return globalData->smallStrings.singleCharacterString(globalData, c); } @@ -463,13 +453,12 @@ namespace JSC { } inline JSString* jsEmptyString(ExecState* exec) { return jsEmptyString(&exec->globalData()); } - inline JSString* jsString(ExecState* exec, const UString& s) { return jsString(&exec->globalData(), s); } + inline JSString* jsString(ExecState* exec, const String& s) { return jsString(&exec->globalData(), s); } inline JSString* jsSingleCharacterString(ExecState* exec, UChar c) { return jsSingleCharacterString(&exec->globalData(), c); } - inline JSString* jsSubstring8(ExecState* exec, const UString& s, unsigned offset, unsigned length) { return jsSubstring8(&exec->globalData(), s, offset, length); } - inline JSString* jsSubstring(ExecState* exec, const UString& s, unsigned offset, unsigned length) { return jsSubstring(&exec->globalData(), s, offset, length); } - inline JSString* jsNontrivialString(ExecState* exec, const UString& s) { return jsNontrivialString(&exec->globalData(), s); } - inline JSString* jsNontrivialString(ExecState* exec, const char* s) { return jsNontrivialString(&exec->globalData(), s); } - inline JSString* jsOwnedString(ExecState* exec, const UString& s) { return jsOwnedString(&exec->globalData(), s); } + inline JSString* jsSubstring8(ExecState* exec, const String& s, unsigned offset, unsigned length) { return jsSubstring8(&exec->globalData(), s, offset, length); } + inline JSString* jsSubstring(ExecState* exec, const String& s, unsigned offset, unsigned length) { return jsSubstring(&exec->globalData(), s, offset, length); } + inline JSString* jsNontrivialString(ExecState* exec, const String& s) { return jsNontrivialString(&exec->globalData(), s); } + inline JSString* jsOwnedString(ExecState* exec, const String& s) { return jsOwnedString(&exec->globalData(), s); } ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, PropertyName propertyName, PropertySlot& slot) { @@ -527,14 +516,14 @@ namespace JSC { return toStringSlowCase(exec); } - inline UString JSValue::toUString(ExecState* exec) const + inline String JSValue::toWTFString(ExecState* exec) const { if (isString()) return static_cast<JSString*>(asCell())->value(exec); - return toUStringSlowCase(exec); + return toWTFStringSlowCase(exec); } - ALWAYS_INLINE UString inlineJSValueNotStringtoUString(const JSValue& value, ExecState* exec) + ALWAYS_INLINE String inlineJSValueNotStringtoString(const JSValue& value, ExecState* exec) { JSGlobalData& globalData = exec->globalData(); if (value.isInt32()) @@ -542,22 +531,22 @@ namespace JSC { if (value.isDouble()) return globalData.numericStrings.add(value.asDouble()); if (value.isTrue()) - return globalData.propertyNames->trueKeyword.ustring(); + return globalData.propertyNames->trueKeyword.string(); if (value.isFalse()) - return globalData.propertyNames->falseKeyword.ustring(); + return globalData.propertyNames->falseKeyword.string(); if (value.isNull()) - return globalData.propertyNames->nullKeyword.ustring(); + return globalData.propertyNames->nullKeyword.string(); if (value.isUndefined()) - return globalData.propertyNames->undefinedKeyword.ustring(); + return globalData.propertyNames->undefinedKeyword.string(); return value.toString(exec)->value(exec); } - ALWAYS_INLINE UString JSValue::toUStringInline(ExecState* exec) const + ALWAYS_INLINE String JSValue::toWTFStringInline(ExecState* exec) const { if (isString()) return static_cast<JSString*>(asCell())->value(exec); - return inlineJSValueNotStringtoUString(*this, exec); + return inlineJSValueNotStringtoString(*this, exec); } } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/JSStringBuilder.h b/Source/JavaScriptCore/runtime/JSStringBuilder.h index 1a2b812f0..e7778e4fb 100644 --- a/Source/JavaScriptCore/runtime/JSStringBuilder.h +++ b/Source/JavaScriptCore/runtime/JSStringBuilder.h @@ -28,7 +28,6 @@ #include "ExceptionHelpers.h" #include "JSString.h" -#include "UStringConcatenate.h" #include <wtf/Vector.h> namespace JSC { @@ -92,7 +91,7 @@ public: m_okay &= buffer16.tryAppend(str, len); } - void append(const UString& str) + void append(const String& str) { unsigned length = str.length(); @@ -129,12 +128,12 @@ public: buffer8.shrinkToFit(); if (!buffer8.data()) return throwOutOfMemoryError(exec); - return jsString(exec, UString::adopt(buffer8)); + return jsString(exec, String::adopt(buffer8)); } buffer16.shrinkToFit(); if (!buffer16.data()) return throwOutOfMemoryError(exec); - return jsString(exec, UString::adopt(buffer16)); + return jsString(exec, String::adopt(buffer16)); } protected: diff --git a/Source/JavaScriptCore/runtime/JSStringJoiner.cpp b/Source/JavaScriptCore/runtime/JSStringJoiner.cpp index ea260243b..cbf9ba48b 100644 --- a/Source/JavaScriptCore/runtime/JSStringJoiner.cpp +++ b/Source/JavaScriptCore/runtime/JSStringJoiner.cpp @@ -27,15 +27,15 @@ #include "JSStringJoiner.h" #include "ExceptionHelpers.h" +#include "JSScope.h" #include "JSString.h" -#include "ScopeChain.h" #include <wtf/text/StringImpl.h> namespace JSC { // The destination is 16bits, at least one string is 16 bits. -static inline void appendStringToData(UChar*& data, const UString& string) +static inline void appendStringToData(UChar*& data, const String& string) { if (string.isNull()) return; @@ -57,7 +57,7 @@ static inline void appendStringToData(UChar*& data, const UString& string) } // If the destination is 8bits, we know every string has to be 8bit. -static inline void appendStringToData(LChar*& data, const UString& string) +static inline void appendStringToData(LChar*& data, const String& string) { if (string.isNull()) return; @@ -73,7 +73,7 @@ static inline void appendStringToData(LChar*& data, const UString& string) } template<typename CharacterType> -static inline PassRefPtr<StringImpl> joinStrings(const Vector<UString>& strings, const UString& separator, unsigned outputLength) +static inline PassRefPtr<StringImpl> joinStrings(const Vector<String>& strings, const String& separator, unsigned outputLength) { ASSERT(outputLength); @@ -82,7 +82,7 @@ static inline PassRefPtr<StringImpl> joinStrings(const Vector<UString>& strings, if (!outputStringImpl) return PassRefPtr<StringImpl>(); - const UString firstString = strings.first(); + const String firstString = strings.first(); appendStringToData(data, firstString); for (size_t i = 1; i < strings.size(); ++i) { diff --git a/Source/JavaScriptCore/runtime/JSStringJoiner.h b/Source/JavaScriptCore/runtime/JSStringJoiner.h index 49f846c1f..5cb841a80 100644 --- a/Source/JavaScriptCore/runtime/JSStringJoiner.h +++ b/Source/JavaScriptCore/runtime/JSStringJoiner.h @@ -27,8 +27,8 @@ #define JSStringJoiner_h #include "JSValue.h" -#include "UString.h" #include <wtf/Vector.h> +#include <wtf/text/WTFString.h> namespace JSC { @@ -37,21 +37,21 @@ class ExecState; class JSStringJoiner { public: - JSStringJoiner(const UString& separator, size_t stringCount); + JSStringJoiner(const String& separator, size_t stringCount); - void append(const UString&); + void append(const String&); JSValue build(ExecState*); private: - UString m_separator; - Vector<UString> m_strings; + String m_separator; + Vector<String> m_strings; unsigned m_cumulatedStringsLength; bool m_isValid; bool m_is8Bits; }; -inline JSStringJoiner::JSStringJoiner(const UString& separator, size_t stringCount) +inline JSStringJoiner::JSStringJoiner(const String& separator, size_t stringCount) : m_separator(separator) , m_cumulatedStringsLength(0) , m_isValid(true) @@ -61,7 +61,7 @@ inline JSStringJoiner::JSStringJoiner(const UString& separator, size_t stringCou m_isValid = m_strings.tryReserveCapacity(stringCount); } -inline void JSStringJoiner::append(const UString& str) +inline void JSStringJoiner::append(const String& str) { if (!m_isValid) return; diff --git a/Source/JavaScriptCore/runtime/JSSymbolTableObject.cpp b/Source/JavaScriptCore/runtime/JSSymbolTableObject.cpp index 927ad25cf..72caa33db 100644 --- a/Source/JavaScriptCore/runtime/JSSymbolTableObject.cpp +++ b/Source/JavaScriptCore/runtime/JSSymbolTableObject.cpp @@ -31,20 +31,26 @@ #include "JSActivation.h" #include "JSGlobalObject.h" -#include "JSStaticScopeObject.h" +#include "JSNameScope.h" #include "PropertyNameArray.h" namespace JSC { -void JSSymbolTableObject::destroy(JSCell* cell) +void JSSymbolTableObject::visitChildren(JSCell* cell, SlotVisitor& visitor) { - static_cast<JSSymbolTableObject*>(cell)->JSSymbolTableObject::~JSSymbolTableObject(); + JSSymbolTableObject* thisObject = jsCast<JSSymbolTableObject*>(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); + COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); + ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); + + Base::visitChildren(thisObject, visitor); + visitor.append(&thisObject->m_symbolTable); } bool JSSymbolTableObject::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName) { JSSymbolTableObject* thisObject = jsCast<JSSymbolTableObject*>(cell); - if (thisObject->symbolTable().contains(propertyName.publicName())) + if (thisObject->symbolTable()->contains(propertyName.publicName())) return false; return JSObject::deleteProperty(thisObject, exec, propertyName); @@ -53,8 +59,8 @@ bool JSSymbolTableObject::deleteProperty(JSCell* cell, ExecState* exec, Property void JSSymbolTableObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) { JSSymbolTableObject* thisObject = jsCast<JSSymbolTableObject*>(object); - SymbolTable::const_iterator end = thisObject->symbolTable().end(); - for (SymbolTable::const_iterator it = thisObject->symbolTable().begin(); it != end; ++it) { + SymbolTable::const_iterator end = thisObject->symbolTable()->end(); + for (SymbolTable::const_iterator it = thisObject->symbolTable()->begin(); it != end; ++it) { if (!(it->second.getAttributes() & DontEnum) || (mode == IncludeDontEnumProperties)) propertyNames.add(Identifier(exec, it->first.get())); } @@ -67,22 +73,4 @@ void JSSymbolTableObject::putDirectVirtual(JSObject*, ExecState*, PropertyName, ASSERT_NOT_REACHED(); } -bool JSSymbolTableObject::isDynamicScope(bool& requiresDynamicChecks) const -{ - switch (structure()->typeInfo().type()) { - case GlobalObjectType: - return static_cast<const JSGlobalObject*>(this)->isDynamicScope(requiresDynamicChecks); - case ActivationObjectType: - return static_cast<const JSActivation*>(this)->isDynamicScope(requiresDynamicChecks); - case StaticScopeObjectType: - return static_cast<const JSStaticScopeObject*>(this)->isDynamicScope(requiresDynamicChecks); - default: - ASSERT_NOT_REACHED(); - break; - } - - return false; -} - } // namespace JSC - diff --git a/Source/JavaScriptCore/runtime/JSSymbolTableObject.h b/Source/JavaScriptCore/runtime/JSSymbolTableObject.h index 2bbe21d06..1913d018b 100644 --- a/Source/JavaScriptCore/runtime/JSSymbolTableObject.h +++ b/Source/JavaScriptCore/runtime/JSSymbolTableObject.h @@ -29,50 +29,49 @@ #ifndef JSSymbolTableObject_h #define JSSymbolTableObject_h -#include "JSObject.h" +#include "JSScope.h" #include "PropertyDescriptor.h" #include "SymbolTable.h" namespace JSC { -class JSSymbolTableObject : public JSNonFinalObject { +class JSSymbolTableObject : public JSScope { public: - typedef JSNonFinalObject Base; + typedef JSScope Base; - SymbolTable& symbolTable() const { return *m_symbolTable; } - - JS_EXPORT_PRIVATE static void destroy(JSCell*); + SharedSymbolTable* symbolTable() const { return m_symbolTable.get(); } static NO_RETURN_DUE_TO_ASSERT void putDirectVirtual(JSObject*, ExecState*, PropertyName, JSValue, unsigned attributes); JS_EXPORT_PRIVATE static bool deleteProperty(JSCell*, ExecState*, PropertyName); JS_EXPORT_PRIVATE static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode); - bool isDynamicScope(bool& requiresDynamicChecks) const; - protected: - static const unsigned StructureFlags = OverridesGetPropertyNames | JSNonFinalObject::StructureFlags; + static const unsigned StructureFlags = IsEnvironmentRecord | OverridesVisitChildren | OverridesGetPropertyNames | Base::StructureFlags; - JSSymbolTableObject(JSGlobalData& globalData, Structure* structure, SymbolTable* symbolTable) - : JSNonFinalObject(globalData, structure) - , m_symbolTable(symbolTable) + JSSymbolTableObject(JSGlobalData& globalData, Structure* structure, JSScope* scope) + : Base(globalData, structure, scope) { } - - void finishCreation(JSGlobalData& globalData) + + void finishCreation(JSGlobalData& globalData, SharedSymbolTable* symbolTable = 0) { Base::finishCreation(globalData); - ASSERT(m_symbolTable); + if (!symbolTable) + symbolTable = SharedSymbolTable::create(globalData); + m_symbolTable.set(globalData, this, symbolTable); } - - SymbolTable* m_symbolTable; + + static void visitChildren(JSCell*, SlotVisitor&); + + WriteBarrier<SharedSymbolTable> m_symbolTable; }; template<typename SymbolTableObjectType> inline bool symbolTableGet( SymbolTableObjectType* object, PropertyName propertyName, PropertySlot& slot) { - SymbolTable& symbolTable = object->symbolTable(); + SymbolTable& symbolTable = *object->symbolTable(); SymbolTable::iterator iter = symbolTable.find(propertyName.publicName()); if (iter == symbolTable.end()) return false; @@ -86,7 +85,7 @@ template<typename SymbolTableObjectType> inline bool symbolTableGet( SymbolTableObjectType* object, PropertyName propertyName, PropertyDescriptor& descriptor) { - SymbolTable& symbolTable = object->symbolTable(); + SymbolTable& symbolTable = *object->symbolTable(); SymbolTable::iterator iter = symbolTable.find(propertyName.publicName()); if (iter == symbolTable.end()) return false; @@ -102,7 +101,7 @@ inline bool symbolTableGet( SymbolTableObjectType* object, PropertyName propertyName, PropertySlot& slot, bool& slotIsWriteable) { - SymbolTable& symbolTable = object->symbolTable(); + SymbolTable& symbolTable = *object->symbolTable(); SymbolTable::iterator iter = symbolTable.find(propertyName.publicName()); if (iter == symbolTable.end()) return false; @@ -121,7 +120,7 @@ inline bool symbolTablePut( JSGlobalData& globalData = exec->globalData(); ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(object)); - SymbolTable& symbolTable = object->symbolTable(); + SymbolTable& symbolTable = *object->symbolTable(); SymbolTable::iterator iter = symbolTable.find(propertyName.publicName()); if (iter == symbolTable.end()) return false; @@ -146,8 +145,8 @@ inline bool symbolTablePutWithAttributes( { ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(object)); - SymbolTable::iterator iter = object->symbolTable().find(propertyName.publicName()); - if (iter == object->symbolTable().end()) + SymbolTable::iterator iter = object->symbolTable()->find(propertyName.publicName()); + if (iter == object->symbolTable()->end()) return false; SymbolTableEntry& entry = iter->second; ASSERT(!entry.isNull()); diff --git a/Source/JavaScriptCore/runtime/JSType.h b/Source/JavaScriptCore/runtime/JSType.h index c9603437b..b8ab330f5 100644 --- a/Source/JavaScriptCore/runtime/JSType.h +++ b/Source/JavaScriptCore/runtime/JSType.h @@ -49,10 +49,11 @@ enum JSType { NumberObjectType, ErrorInstanceType, GlobalThisType, + WithScopeType, - StaticScopeObjectType, + NameScopeObjectType, // VariableObjectType must be less than MOST of the types of its subclasses and only its subclasses. - // We use >=VariableObjectType checks to test for Global & Activation objects, but exclude StaticScopes. + // We use >=VariableObjectType checks to test for Global & Activation objects, but exclude NameScopes. VariableObjectType, GlobalObjectType, ActivationObjectType, diff --git a/Source/JavaScriptCore/runtime/JSValue.cpp b/Source/JavaScriptCore/runtime/JSValue.cpp index c34431178..caff9973b 100644 --- a/Source/JavaScriptCore/runtime/JSValue.cpp +++ b/Source/JavaScriptCore/runtime/JSValue.cpp @@ -143,7 +143,7 @@ void JSValue::putToPrimitive(ExecState* exec, PropertyName propertyName, JSValue JSObject* setterFunc = asGetterSetter(gs)->setter(); if (!setterFunc) { if (slot.isStrictMode()) - throwError(exec, createTypeError(exec, "setting a property that has only a getter")); + throwError(exec, createTypeError(exec, ASCIILiteral("setting a property that has only a getter"))); return; } @@ -283,9 +283,9 @@ JSString* JSValue::toStringSlowCase(ExecState* exec) const return value.toString(exec); } -UString JSValue::toUStringSlowCase(ExecState* exec) const +String JSValue::toWTFStringSlowCase(ExecState* exec) const { - return inlineJSValueNotStringtoUString(*this, exec); + return inlineJSValueNotStringtoString(*this, exec); } } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/JSValue.h b/Source/JavaScriptCore/runtime/JSValue.h index 7aa5453e4..ce9405817 100644 --- a/Source/JavaScriptCore/runtime/JSValue.h +++ b/Source/JavaScriptCore/runtime/JSValue.h @@ -44,7 +44,6 @@ namespace JSC { class PropertyName; class PropertySlot; class PutPropertySlot; - class UString; #if ENABLE(DFG_JIT) namespace DFG { class AssemblyHelpers; @@ -55,9 +54,11 @@ namespace JSC { class SpeculativeJIT; } #endif +#if ENABLE(LLINT_C_LOOP) namespace LLInt { - class Data; + class CLoop; } +#endif struct ClassInfo; struct Instruction; @@ -121,7 +122,9 @@ namespace JSC { friend class DFG::OSRExitCompiler; friend class DFG::SpeculativeJIT; #endif - friend class LLInt::Data; +#if ENABLE(LLINT_C_LOOP) + friend class LLInt::CLoop; +#endif public: #if USE(JSVALUE32_64) @@ -198,8 +201,8 @@ namespace JSC { bool inherits(const ClassInfo*) const; // Extracting the value. - bool getString(ExecState* exec, UString&) const; - UString getString(ExecState* exec) const; // null string if not a string + bool getString(ExecState*, WTF::String&) const; + WTF::String getString(ExecState*) const; // null string if not a string JSObject* getObject() const; // 0 if not an object // Extracting integer values. @@ -215,8 +218,8 @@ namespace JSC { // been set in the ExecState already. double toNumber(ExecState*) const; JSString* toString(ExecState*) const; - UString toUString(ExecState*) const; - UString toUStringInline(ExecState*) const; + WTF::String toWTFString(ExecState*) const; + WTF::String toWTFStringInline(ExecState*) const; JSObject* toObject(ExecState*) const; JSObject* toObject(ExecState*, JSGlobalObject*) const; @@ -267,7 +270,7 @@ namespace JSC { inline const JSValue asValue() const { return *this; } JS_EXPORT_PRIVATE double toNumberSlowCase(ExecState*) const; JS_EXPORT_PRIVATE JSString* toStringSlowCase(ExecState*) const; - JS_EXPORT_PRIVATE UString toUStringSlowCase(ExecState*) const; + JS_EXPORT_PRIVATE WTF::String toWTFStringSlowCase(ExecState*) const; JS_EXPORT_PRIVATE JSObject* toObjectSlowCase(ExecState*, JSGlobalObject*) const; JS_EXPORT_PRIVATE JSObject* toThisObjectSlowCase(ExecState*) const; @@ -292,6 +295,14 @@ namespace JSC { */ uint32_t tag() const; int32_t payload() const; + +#if ENABLE(LLINT_C_LOOP) + // This should only be used by the LLInt C Loop interpreter who needs + // synthesize JSValue from its "register"s holding tag and payload + // values. + explicit JSValue(int32_t tag, int32_t payload); +#endif + #elif USE(JSVALUE64) /* * On 64-bit platforms USE(JSVALUE64) should be defined, and we use a NaN-encoded diff --git a/Source/JavaScriptCore/runtime/JSValueInlineMethods.h b/Source/JavaScriptCore/runtime/JSValueInlineMethods.h index 1373558f7..4c582ab2a 100644 --- a/Source/JavaScriptCore/runtime/JSValueInlineMethods.h +++ b/Source/JavaScriptCore/runtime/JSValueInlineMethods.h @@ -307,6 +307,14 @@ namespace JSC { u.asBits.payload = i; } +#if ENABLE(LLINT_C_LOOP) + inline JSValue::JSValue(int32_t tag, int32_t payload) + { + u.asBits.tag = tag; + u.asBits.payload = payload; + } +#endif + inline bool JSValue::isNumber() const { return isInt32() || isDouble(); @@ -323,7 +331,7 @@ namespace JSC { return payload(); } -#else // USE(JSVALUE32_64) +#else // !USE(JSVALUE32_64) i.e. USE(JSVALUE64) // JSValue member functions. inline EncodedJSValue JSValue::encode(JSValue value) diff --git a/Source/JavaScriptCore/runtime/JSVariableObject.cpp b/Source/JavaScriptCore/runtime/JSVariableObject.cpp index 7210c9b90..c815dcd11 100644 --- a/Source/JavaScriptCore/runtime/JSVariableObject.cpp +++ b/Source/JavaScriptCore/runtime/JSVariableObject.cpp @@ -31,9 +31,4 @@ namespace JSC { -void JSVariableObject::destroy(JSCell* cell) -{ - static_cast<JSVariableObject*>(cell)->JSVariableObject::~JSVariableObject(); -} - } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/JSVariableObject.h b/Source/JavaScriptCore/runtime/JSVariableObject.h index 2f0dd42e5..c9f989e68 100644 --- a/Source/JavaScriptCore/runtime/JSVariableObject.h +++ b/Source/JavaScriptCore/runtime/JSVariableObject.h @@ -48,53 +48,34 @@ namespace JSC { public: typedef JSSymbolTableObject Base; - WriteBarrier<Unknown>& registerAt(int index) const { return m_registers[index]; } + WriteBarrierBase<Unknown>& registerAt(int index) const { return m_registers[index]; } - WriteBarrier<Unknown>* const * addressOfRegisters() const { return &m_registers; } + WriteBarrierBase<Unknown>* const * addressOfRegisters() const { return &m_registers; } static size_t offsetOfRegisters() { return OBJECT_OFFSETOF(JSVariableObject, m_registers); } - JS_EXPORT_PRIVATE static void destroy(JSCell*); - protected: - static const unsigned StructureFlags = JSSymbolTableObject::StructureFlags; - - JSVariableObject(JSGlobalData& globalData, Structure* structure, SymbolTable* symbolTable, Register* registers) - : JSSymbolTableObject(globalData, structure, symbolTable) - , m_registers(reinterpret_cast<WriteBarrier<Unknown>*>(registers)) + static const unsigned StructureFlags = Base::StructureFlags; + + JSVariableObject( + JSGlobalData& globalData, + Structure* structure, + Register* registers, + JSScope* scope + ) + : Base(globalData, structure, scope) + , m_registers(reinterpret_cast<WriteBarrierBase<Unknown>*>(registers)) { } - void finishCreation(JSGlobalData& globalData) + void finishCreation(JSGlobalData& globalData, SharedSymbolTable* symbolTable = 0) { - Base::finishCreation(globalData); - COMPILE_ASSERT(sizeof(WriteBarrier<Unknown>) == sizeof(Register), Register_should_be_same_size_as_WriteBarrier); + Base::finishCreation(globalData, symbolTable); + COMPILE_ASSERT(sizeof(WriteBarrierBase<Unknown>) == sizeof(Register), Register_should_be_same_size_as_WriteBarrierBase); } - PassOwnArrayPtr<WriteBarrier<Unknown> > copyRegisterArray(JSGlobalData&, WriteBarrier<Unknown>* src, size_t count, size_t callframeStarts); - void setRegisters(WriteBarrier<Unknown>* registers, PassOwnArrayPtr<WriteBarrier<Unknown> > registerArray); - - WriteBarrier<Unknown>* m_registers; // "r" in the register file. - OwnArrayPtr<WriteBarrier<Unknown> > m_registerArray; // Independent copy of registers, used when a variable object copies its registers out of the register file. + WriteBarrierBase<Unknown>* m_registers; // "r" in the register file. }; - inline PassOwnArrayPtr<WriteBarrier<Unknown> > JSVariableObject::copyRegisterArray(JSGlobalData& globalData, WriteBarrier<Unknown>* src, size_t count, size_t callframeStarts) - { - OwnArrayPtr<WriteBarrier<Unknown> > registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[count]); - for (size_t i = 0; i < callframeStarts; i++) - registerArray[i].set(globalData, this, src[i].get()); - for (size_t i = callframeStarts + RegisterFile::CallFrameHeaderSize; i < count; i++) - registerArray[i].set(globalData, this, src[i].get()); - - return registerArray.release(); - } - - inline void JSVariableObject::setRegisters(WriteBarrier<Unknown>* registers, PassOwnArrayPtr<WriteBarrier<Unknown> > registerArray) - { - ASSERT(registerArray != m_registerArray); - m_registerArray = registerArray; - m_registers = registers; - } - } // namespace JSC #endif // JSVariableObject_h diff --git a/Source/JavaScriptCore/runtime/UStringBuilder.h b/Source/JavaScriptCore/runtime/JSWithScope.cpp index 31ccf382a..0c4b6e2cc 100644 --- a/Source/JavaScriptCore/runtime/UStringBuilder.h +++ b/Source/JavaScriptCore/runtime/JSWithScope.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Apple Inc. All rights reserved. + * Copyright (C) 2012 Apple Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,21 +23,24 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef UStringBuilder_h -#define UStringBuilder_h - -#include <wtf/text/StringBuilder.h> +#include "config.h" +#include "JSWithScope.h" namespace JSC { -class UStringBuilder : public StringBuilder { -public: - using StringBuilder::append; - void append(const UString& str) { append(String(str.impl())); } +ASSERT_CLASS_FITS_IN_CELL(JSWithScope); - UString toUString() { return toString().impl(); } -}; +const ClassInfo JSWithScope::s_info = { "WithScope", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(JSWithScope) }; -} // namespace JSC +void JSWithScope::visitChildren(JSCell* cell, SlotVisitor& visitor) +{ + JSWithScope* thisObject = jsCast<JSWithScope*>(cell); + ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); + COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); + ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); -#endif // UStringBuilder_h + Base::visitChildren(thisObject, visitor); + visitor.append(&thisObject->m_object); +} + +} // namespace JSC diff --git a/Source/JavaScriptCore/runtime/JSWithScope.h b/Source/JavaScriptCore/runtime/JSWithScope.h new file mode 100644 index 000000000..ba2b793a9 --- /dev/null +++ b/Source/JavaScriptCore/runtime/JSWithScope.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2012 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 JSWithScope_h +#define JSWithScope_h + +#include "JSGlobalObject.h" + +namespace JSC { + +class JSWithScope : public JSScope { +public: + typedef JSScope Base; + + static JSWithScope* create(ExecState* exec, JSObject* object) + { + JSWithScope* withScope = new (NotNull, allocateCell<JSWithScope>(*exec->heap())) JSWithScope(exec, object); + withScope->finishCreation(exec->globalData()); + return withScope; + } + + static JSWithScope* create(ExecState* exec, JSObject* object, JSScope* next) + { + JSWithScope* withScope = new (NotNull, allocateCell<JSWithScope>(*exec->heap())) JSWithScope(exec, object, next); + withScope->finishCreation(exec->globalData()); + return withScope; + } + + JSObject* object() { return m_object.get(); } + + static void visitChildren(JSCell*, SlotVisitor&); + + static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) + { + return Structure::create(globalData, globalObject, proto, TypeInfo(WithScopeType, StructureFlags), &s_info); + } + + static JS_EXPORTDATA const ClassInfo s_info; + +protected: + static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags; + +private: + JSWithScope(ExecState* exec, JSObject* object) + : Base( + exec->globalData(), + exec->lexicalGlobalObject()->withScopeStructure(), + exec->scope() + ) + , m_object(exec->globalData(), this, object) + { + } + + JSWithScope(ExecState* exec, JSObject* object, JSScope* next) + : Base( + exec->globalData(), + exec->lexicalGlobalObject()->withScopeStructure(), + next + ) + , m_object(exec->globalData(), this, object) + { + } + + WriteBarrier<JSObject> m_object; +}; + +} // namespace JSC + +#endif // JSWithScope_h diff --git a/Source/JavaScriptCore/runtime/JSWrapperObject.cpp b/Source/JavaScriptCore/runtime/JSWrapperObject.cpp index f8f5727d8..4a46c2c69 100644 --- a/Source/JavaScriptCore/runtime/JSWrapperObject.cpp +++ b/Source/JavaScriptCore/runtime/JSWrapperObject.cpp @@ -33,9 +33,9 @@ void JSWrapperObject::visitChildren(JSCell* cell, SlotVisitor& visitor) ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); + JSObject::visitChildren(thisObject, visitor); - if (thisObject->m_internalValue) - visitor.append(&thisObject->m_internalValue); + visitor.append(&thisObject->m_internalValue); } } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/LiteralParser.cpp b/Source/JavaScriptCore/runtime/LiteralParser.cpp index e1f85cefe..30a478d48 100644 --- a/Source/JavaScriptCore/runtime/LiteralParser.cpp +++ b/Source/JavaScriptCore/runtime/LiteralParser.cpp @@ -31,9 +31,9 @@ #include "JSString.h" #include "Lexer.h" #include "StrongInlines.h" -#include "UStringBuilder.h" #include <wtf/ASCIICType.h> #include <wtf/dtoa.h> +#include <wtf/text/StringBuilder.h> namespace JSC { @@ -269,7 +269,7 @@ template <ParserMode mode> TokenType LiteralParser<CharType>::Lexer::lex(Literal return lexIdentifier(token); if (*m_ptr == '\'') { if (mode == StrictJSON) { - m_lexErrorMessage = "Single quotes (\') are not allowed in JSON"; + m_lexErrorMessage = ASCIILiteral("Single quotes (\') are not allowed in JSON"); return TokError; } return lexString<mode, '\''>(token); @@ -344,7 +344,7 @@ template <ParserMode mode, char terminator> ALWAYS_INLINE TokenType LiteralParse { ++m_ptr; const CharType* runStart = m_ptr; - UStringBuilder builder; + StringBuilder builder; do { runStart = m_ptr; while (m_ptr < m_end && isSafeStringCharacter<mode, CharType, terminator>(*m_ptr)) @@ -356,7 +356,7 @@ template <ParserMode mode, char terminator> ALWAYS_INLINE TokenType LiteralParse builder.append(runStart, m_ptr - runStart); ++m_ptr; if (m_ptr >= m_end) { - m_lexErrorMessage = "Unterminated string"; + m_lexErrorMessage = ASCIILiteral("Unterminated string"); return TokError; } switch (*m_ptr) { @@ -395,12 +395,12 @@ template <ParserMode mode, char terminator> ALWAYS_INLINE TokenType LiteralParse case 'u': if ((m_end - m_ptr) < 5) { - m_lexErrorMessage = "\\u must be followed by 4 hex digits"; + m_lexErrorMessage = ASCIILiteral("\\u must be followed by 4 hex digits"); return TokError; } // uNNNN == 5 characters for (int i = 1; i < 5; i++) { if (!isASCIIHexDigit(m_ptr[i])) { - m_lexErrorMessage = String::format("\"\\%s\" is not a valid unicode escape", UString(m_ptr, 5).ascii().data()).impl(); + m_lexErrorMessage = String::format("\"\\%s\" is not a valid unicode escape", String(m_ptr, 5).ascii().data()).impl(); return TokError; } } @@ -421,16 +421,16 @@ template <ParserMode mode, char terminator> ALWAYS_INLINE TokenType LiteralParse } while ((mode != NonStrictJSON) && m_ptr != runStart && (m_ptr < m_end) && *m_ptr != terminator); if (m_ptr >= m_end || *m_ptr != terminator) { - m_lexErrorMessage = "Unterminated string"; + m_lexErrorMessage = ASCIILiteral("Unterminated string"); return TokError; } if (builder.isEmpty()) { - token.stringBuffer = UString(); + token.stringBuffer = String(); setParserTokenString<CharType>(token, runStart); token.stringLength = m_ptr - runStart; } else { - token.stringBuffer = builder.toUString(); + token.stringBuffer = builder.toString(); if (token.stringBuffer.is8Bit()) { token.stringIs8Bit = 1; token.stringToken8 = token.stringBuffer.characters8(); @@ -474,7 +474,7 @@ TokenType LiteralParser<CharType>::Lexer::lexNumber(LiteralParserToken<CharType> while (m_ptr < m_end && isASCIIDigit(*m_ptr)) ++m_ptr; } else { - m_lexErrorMessage = "Invalid number"; + m_lexErrorMessage = ASCIILiteral("Invalid number"); return TokError; } @@ -483,7 +483,7 @@ TokenType LiteralParser<CharType>::Lexer::lexNumber(LiteralParserToken<CharType> ++m_ptr; // [0-9]+ if (m_ptr >= m_end || !isASCIIDigit(*m_ptr)) { - m_lexErrorMessage = "Invalid digits after decimal point"; + m_lexErrorMessage = ASCIILiteral("Invalid digits after decimal point"); return TokError; } @@ -518,7 +518,7 @@ TokenType LiteralParser<CharType>::Lexer::lexNumber(LiteralParserToken<CharType> // [0-9]+ if (m_ptr >= m_end || !isASCIIDigit(*m_ptr)) { - m_lexErrorMessage = "Exponent symbols should be followed by an optional '+' or '-' and then by at least one number"; + m_lexErrorMessage = ASCIILiteral("Exponent symbols should be followed by an optional '+' or '-' and then by at least one number"); return TokError; } @@ -555,7 +555,7 @@ JSValue LiteralParser<CharType>::parse(ParserState initialState) TokenType lastToken = m_lexer.currentToken().type; if (m_lexer.next() == TokRBracket) { if (lastToken == TokComma) { - m_parseErrorMessage = "Unexpected comma at the end of array expression"; + m_parseErrorMessage = ASCIILiteral("Unexpected comma at the end of array expression"); return JSValue(); } m_lexer.next(); @@ -574,7 +574,7 @@ JSValue LiteralParser<CharType>::parse(ParserState initialState) goto doParseArrayStartExpression; if (m_lexer.currentToken().type != TokRBracket) { - m_parseErrorMessage = "Expected ']'"; + m_parseErrorMessage = ASCIILiteral("Expected ']'"); return JSValue(); } @@ -594,7 +594,7 @@ JSValue LiteralParser<CharType>::parse(ParserState initialState) // Check for colon if (m_lexer.next() != TokColon) { - m_parseErrorMessage = "Expected ':' before value in object property definition"; + m_parseErrorMessage = ASCIILiteral("Expected ':' before value in object property definition"); return JSValue(); } @@ -607,7 +607,7 @@ JSValue LiteralParser<CharType>::parse(ParserState initialState) goto startParseExpression; } if (type != TokRBrace) { - m_parseErrorMessage = "Expected '}'"; + m_parseErrorMessage = ASCIILiteral("Expected '}'"); return JSValue(); } m_lexer.next(); @@ -619,14 +619,14 @@ JSValue LiteralParser<CharType>::parse(ParserState initialState) case DoParseObjectStartExpression: { TokenType type = m_lexer.next(); if (type != TokString && (m_mode == StrictJSON || type != TokIdentifier)) { - m_parseErrorMessage = "Property name must be a string literal"; + m_parseErrorMessage = ASCIILiteral("Property name must be a string literal"); return JSValue(); } LiteralParserToken<CharType> identifierToken = m_lexer.currentToken(); // Check for colon if (m_lexer.next() != TokColon) { - m_parseErrorMessage = "Expected ':'"; + m_parseErrorMessage = ASCIILiteral("Expected ':'"); return JSValue(); } @@ -645,7 +645,7 @@ JSValue LiteralParser<CharType>::parse(ParserState initialState) if (m_lexer.currentToken().type == TokComma) goto doParseObjectStartExpression; if (m_lexer.currentToken().type != TokRBrace) { - m_parseErrorMessage = "Expected '}'"; + m_parseErrorMessage = ASCIILiteral("Expected '}'"); return JSValue(); } m_lexer.next(); @@ -664,9 +664,9 @@ JSValue LiteralParser<CharType>::parse(ParserState initialState) LiteralParserToken<CharType> stringToken = m_lexer.currentToken(); m_lexer.next(); if (stringToken.stringIs8Bit) - lastValue = jsString(m_exec, makeIdentifier(stringToken.stringToken8, stringToken.stringLength).ustring()); + lastValue = jsString(m_exec, makeIdentifier(stringToken.stringToken8, stringToken.stringLength).string()); else - lastValue = jsString(m_exec, makeIdentifier(stringToken.stringToken16, stringToken.stringLength).ustring()); + lastValue = jsString(m_exec, makeIdentifier(stringToken.stringToken16, stringToken.stringLength).string()); break; } case TokNumber: { @@ -690,47 +690,47 @@ JSValue LiteralParser<CharType>::parse(ParserState initialState) lastValue = jsBoolean(false); break; case TokRBracket: - m_parseErrorMessage = "Unexpected token ']'"; + m_parseErrorMessage = ASCIILiteral("Unexpected token ']'"); return JSValue(); case TokRBrace: - m_parseErrorMessage = "Unexpected token '}'"; + m_parseErrorMessage = ASCIILiteral("Unexpected token '}'"); return JSValue(); case TokIdentifier: { const LiteralParserToken<CharType>& token = m_lexer.currentToken(); if (token.stringIs8Bit) - m_parseErrorMessage = String::format("Unexpected identifier \"%s\"", UString(m_lexer.currentToken().stringToken8, m_lexer.currentToken().stringLength).ascii().data()).impl(); + m_parseErrorMessage = String::format("Unexpected identifier \"%s\"", String(m_lexer.currentToken().stringToken8, m_lexer.currentToken().stringLength).ascii().data()).impl(); else - m_parseErrorMessage = String::format("Unexpected identifier \"%s\"", UString(m_lexer.currentToken().stringToken16, m_lexer.currentToken().stringLength).ascii().data()).impl(); + m_parseErrorMessage = String::format("Unexpected identifier \"%s\"", String(m_lexer.currentToken().stringToken16, m_lexer.currentToken().stringLength).ascii().data()).impl(); return JSValue(); } case TokColon: - m_parseErrorMessage = "Unexpected token ':'"; + m_parseErrorMessage = ASCIILiteral("Unexpected token ':'"); return JSValue(); case TokLParen: - m_parseErrorMessage = "Unexpected token '('"; + m_parseErrorMessage = ASCIILiteral("Unexpected token '('"); return JSValue(); case TokRParen: - m_parseErrorMessage = "Unexpected token ')'"; + m_parseErrorMessage = ASCIILiteral("Unexpected token ')'"); return JSValue(); case TokComma: - m_parseErrorMessage = "Unexpected token ','"; + m_parseErrorMessage = ASCIILiteral("Unexpected token ','"); return JSValue(); case TokDot: - m_parseErrorMessage = "Unexpected token '.'"; + m_parseErrorMessage = ASCIILiteral("Unexpected token '.'"); return JSValue(); case TokAssign: - m_parseErrorMessage = "Unexpected token '='"; + m_parseErrorMessage = ASCIILiteral("Unexpected token '='"); return JSValue(); case TokSemi: - m_parseErrorMessage = "Unexpected token ';'"; + m_parseErrorMessage = ASCIILiteral("Unexpected token ';'"); return JSValue(); case TokEnd: - m_parseErrorMessage = "Unexpected EOF"; + m_parseErrorMessage = ASCIILiteral("Unexpected EOF"); return JSValue(); case TokError: default: // Error - m_parseErrorMessage = "Could not parse value expression"; + m_parseErrorMessage = ASCIILiteral("Could not parse value expression"); return JSValue(); } break; @@ -748,50 +748,50 @@ JSValue LiteralParser<CharType>::parse(ParserState initialState) goto startParseExpression; } case TokRBracket: - m_parseErrorMessage = "Unexpected token ']'"; + m_parseErrorMessage = ASCIILiteral("Unexpected token ']'"); return JSValue(); case TokLBrace: - m_parseErrorMessage = "Unexpected token '{'"; + m_parseErrorMessage = ASCIILiteral("Unexpected token '{'"); return JSValue(); case TokRBrace: - m_parseErrorMessage = "Unexpected token '}'"; + m_parseErrorMessage = ASCIILiteral("Unexpected token '}'"); return JSValue(); case TokIdentifier: - m_parseErrorMessage = "Unexpected identifier"; + m_parseErrorMessage = ASCIILiteral("Unexpected identifier"); return JSValue(); case TokColon: - m_parseErrorMessage = "Unexpected token ':'"; + m_parseErrorMessage = ASCIILiteral("Unexpected token ':'"); return JSValue(); case TokRParen: - m_parseErrorMessage = "Unexpected token ')'"; + m_parseErrorMessage = ASCIILiteral("Unexpected token ')'"); return JSValue(); case TokComma: - m_parseErrorMessage = "Unexpected token ','"; + m_parseErrorMessage = ASCIILiteral("Unexpected token ','"); return JSValue(); case TokTrue: - m_parseErrorMessage = "Unexpected token 'true'"; + m_parseErrorMessage = ASCIILiteral("Unexpected token 'true'"); return JSValue(); case TokFalse: - m_parseErrorMessage = "Unexpected token 'false'"; + m_parseErrorMessage = ASCIILiteral("Unexpected token 'false'"); return JSValue(); case TokNull: - m_parseErrorMessage = "Unexpected token 'null'"; + m_parseErrorMessage = ASCIILiteral("Unexpected token 'null'"); return JSValue(); case TokEnd: - m_parseErrorMessage = "Unexpected EOF"; + m_parseErrorMessage = ASCIILiteral("Unexpected EOF"); return JSValue(); case TokDot: - m_parseErrorMessage = "Unexpected token '.'"; + m_parseErrorMessage = ASCIILiteral("Unexpected token '.'"); return JSValue(); case TokAssign: - m_parseErrorMessage = "Unexpected token '='"; + m_parseErrorMessage = ASCIILiteral("Unexpected token '='"); return JSValue(); case TokSemi: - m_parseErrorMessage = "Unexpected token ';'"; + m_parseErrorMessage = ASCIILiteral("Unexpected token ';'"); return JSValue(); case TokError: default: - m_parseErrorMessage = "Could not parse statement"; + m_parseErrorMessage = ASCIILiteral("Could not parse statement"); return JSValue(); } } @@ -801,7 +801,7 @@ JSValue LiteralParser<CharType>::parse(ParserState initialState) return JSValue(); if (m_lexer.next() == TokEnd) return lastValue; - m_parseErrorMessage = "Unexpected content at end of JSON literal"; + m_parseErrorMessage = ASCIILiteral("Unexpected content at end of JSON literal"); return JSValue(); } default: diff --git a/Source/JavaScriptCore/runtime/LiteralParser.h b/Source/JavaScriptCore/runtime/LiteralParser.h index abe3f95b7..c0f308ee5 100644 --- a/Source/JavaScriptCore/runtime/LiteralParser.h +++ b/Source/JavaScriptCore/runtime/LiteralParser.h @@ -29,7 +29,7 @@ #include "Identifier.h" #include "JSGlobalObjectFunctions.h" #include "JSValue.h" -#include "UString.h" +#include <wtf/text/WTFString.h> namespace JSC { @@ -67,7 +67,7 @@ struct LiteralParserToken { TokenType type; const CharType* start; const CharType* end; - UString stringBuffer; + String stringBuffer; union { double numberToken; struct { @@ -94,13 +94,13 @@ public: { } - UString getErrorMessage() + String getErrorMessage() { if (!m_lexer.getErrorMessage().isEmpty()) return String::format("JSON Parse error: %s", m_lexer.getErrorMessage().ascii().data()).impl(); if (!m_parseErrorMessage.isEmpty()) return String::format("JSON Parse error: %s", m_parseErrorMessage.ascii().data()).impl(); - return "JSON Parse error: Unable to parse JSON string"; + return ASCIILiteral("JSON Parse error: Unable to parse JSON string"); } JSValue tryLiteralParse() @@ -133,10 +133,10 @@ private: return m_currentToken; } - UString getErrorMessage() { return m_lexErrorMessage; } + String getErrorMessage() { return m_lexErrorMessage; } private: - UString m_lexErrorMessage; + String m_lexErrorMessage; template <ParserMode mode> TokenType lex(LiteralParserToken<CharType>&); ALWAYS_INLINE TokenType lexIdentifier(LiteralParserToken<CharType>&); template <ParserMode mode, char terminator> ALWAYS_INLINE TokenType lexString(LiteralParserToken<CharType>&); @@ -153,7 +153,7 @@ private: ExecState* m_exec; typename LiteralParser<CharType>::Lexer m_lexer; ParserMode m_mode; - UString m_parseErrorMessage; + String m_parseErrorMessage; static unsigned const MaximumCachableCharacter = 128; FixedArray<Identifier, MaximumCachableCharacter> m_shortIdentifiers; FixedArray<Identifier, MaximumCachableCharacter> m_recentIdentifiers; diff --git a/Source/JavaScriptCore/runtime/MemoryStatistics.cpp b/Source/JavaScriptCore/runtime/MemoryStatistics.cpp index 14b1c7d06..b35e9fbda 100644 --- a/Source/JavaScriptCore/runtime/MemoryStatistics.cpp +++ b/Source/JavaScriptCore/runtime/MemoryStatistics.cpp @@ -37,7 +37,7 @@ GlobalMemoryStatistics globalMemoryStatistics() GlobalMemoryStatistics stats; stats.stackBytes = RegisterFile::committedByteCount(); -#if ENABLE(EXECUTABLE_ALLOCATOR_FIXED) || (PLATFORM(BLACKBERRY) && ENABLE(JIT)) +#if ENABLE(EXECUTABLE_ALLOCATOR_FIXED) || ((PLATFORM(BLACKBERRY) || PLATFORM(EFL)) && ENABLE(JIT)) stats.JITBytes = ExecutableAllocator::committedByteCount(); #else stats.JITBytes = 0; diff --git a/Source/JavaScriptCore/runtime/NameInstance.cpp b/Source/JavaScriptCore/runtime/NameInstance.cpp index 410fe62e7..f257243e8 100644 --- a/Source/JavaScriptCore/runtime/NameInstance.cpp +++ b/Source/JavaScriptCore/runtime/NameInstance.cpp @@ -26,6 +26,8 @@ #include "config.h" #include "NameInstance.h" +#include "JSScope.h" + namespace JSC { const ClassInfo NameInstance::s_info = { "Name", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(NameInstance) }; diff --git a/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp b/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp index b6aff916e..a4ba240fd 100644 --- a/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp +++ b/Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp @@ -44,9 +44,9 @@ void NativeErrorConstructor::visitChildren(JSCell* cell, SlotVisitor& visitor) ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); + InternalFunction::visitChildren(thisObject, visitor); - if (thisObject->m_errorStructure) - visitor.append(&thisObject->m_errorStructure); + visitor.append(&thisObject->m_errorStructure); } static EncodedJSValue JSC_HOST_CALL constructWithNativeErrorConstructor(ExecState* exec) diff --git a/Source/JavaScriptCore/runtime/NativeErrorConstructor.h b/Source/JavaScriptCore/runtime/NativeErrorConstructor.h index 76aea9da8..8db237028 100644 --- a/Source/JavaScriptCore/runtime/NativeErrorConstructor.h +++ b/Source/JavaScriptCore/runtime/NativeErrorConstructor.h @@ -34,7 +34,7 @@ namespace JSC { public: typedef InternalFunction Base; - static NativeErrorConstructor* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, Structure* prototypeStructure, const UString& name) + static NativeErrorConstructor* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, Structure* prototypeStructure, const String& name) { NativeErrorConstructor* constructor = new (NotNull, allocateCell<NativeErrorConstructor>(*exec->heap())) NativeErrorConstructor(globalObject, structure); constructor->finishCreation(exec, globalObject, prototypeStructure, name); @@ -51,7 +51,7 @@ namespace JSC { Structure* errorStructure() { return m_errorStructure.get(); } protected: - void finishCreation(ExecState* exec, JSGlobalObject* globalObject, Structure* prototypeStructure, const UString& name) + void finishCreation(ExecState* exec, JSGlobalObject* globalObject, Structure* prototypeStructure, const String& name) { Base::finishCreation(exec->globalData(), name); ASSERT(inherits(&s_info)); diff --git a/Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp b/Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp index dfdd87f85..7fee213fa 100644 --- a/Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp +++ b/Source/JavaScriptCore/runtime/NativeErrorPrototype.cpp @@ -24,7 +24,6 @@ #include "JSGlobalObject.h" #include "JSString.h" #include "NativeErrorConstructor.h" -#include "UString.h" namespace JSC { @@ -35,7 +34,7 @@ NativeErrorPrototype::NativeErrorPrototype(ExecState* exec, Structure* structure { } -void NativeErrorPrototype::finishCreation(ExecState* exec, JSGlobalObject* globalObject, const UString& nameAndMessage, NativeErrorConstructor* constructor) +void NativeErrorPrototype::finishCreation(ExecState* exec, JSGlobalObject* globalObject, const WTF::String& nameAndMessage, NativeErrorConstructor* constructor) { Base::finishCreation(exec, globalObject); putDirect(exec->globalData(), exec->propertyNames().name, jsString(exec, nameAndMessage), DontEnum); diff --git a/Source/JavaScriptCore/runtime/NativeErrorPrototype.h b/Source/JavaScriptCore/runtime/NativeErrorPrototype.h index 4bceb883a..c94f2b75a 100644 --- a/Source/JavaScriptCore/runtime/NativeErrorPrototype.h +++ b/Source/JavaScriptCore/runtime/NativeErrorPrototype.h @@ -33,7 +33,7 @@ namespace JSC { public: typedef ErrorPrototype Base; - static NativeErrorPrototype* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, const UString& name, NativeErrorConstructor* constructor) + static NativeErrorPrototype* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, const String& name, NativeErrorConstructor* constructor) { NativeErrorPrototype* prototype = new (NotNull, allocateCell<NativeErrorPrototype>(*exec->heap())) NativeErrorPrototype(exec, structure); prototype->finishCreation(exec, globalObject, name, constructor); @@ -41,7 +41,7 @@ namespace JSC { } protected: - void finishCreation(ExecState*, JSGlobalObject*, const UString& nameAndMessage, NativeErrorConstructor*); + void finishCreation(ExecState*, JSGlobalObject*, const String& nameAndMessage, NativeErrorConstructor*); }; } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/NumberPrototype.cpp b/Source/JavaScriptCore/runtime/NumberPrototype.cpp index 1df7b6951..4a10efd6d 100644 --- a/Source/JavaScriptCore/runtime/NumberPrototype.cpp +++ b/Source/JavaScriptCore/runtime/NumberPrototype.cpp @@ -339,7 +339,7 @@ static char* toStringWithRadix(RadixBuffer& buffer, double number, unsigned radi return startOfResultString; } -static UString toUStringWithRadix(int32_t number, unsigned radix) +static String toStringWithRadix(int32_t number, unsigned radix) { LChar buf[1 + 32]; // Worst case is radix == 2, which gives us 32 digits + sign. LChar* end = buf + WTF_ARRAY_LENGTH(buf); @@ -361,7 +361,7 @@ static UString toUStringWithRadix(int32_t number, unsigned radix) if (negative) *--p = '-'; - return UString(p, static_cast<unsigned>(end - p)); + return String(p, static_cast<unsigned>(end - p)); } // toExponential converts a number to a string, always formatting as an expoential. @@ -378,11 +378,11 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToExponential(ExecState* exec) int decimalPlacesInExponent; bool isUndefined; if (!getIntegerArgumentInRange(exec, 0, 20, decimalPlacesInExponent, isUndefined)) - return throwVMError(exec, createRangeError(exec, "toExponential() argument must be between 0 and 20")); + return throwVMError(exec, createRangeError(exec, ASCIILiteral("toExponential() argument must be between 0 and 20"))); // Handle NaN and Infinity. if (!isfinite(x)) - return JSValue::encode(jsString(exec, UString::number(x))); + return JSValue::encode(jsString(exec, String::numberToStringECMAScript(x))); // Round if the argument is not undefined, always format as exponential. char buffer[WTF::NumberToStringBufferLength]; @@ -392,7 +392,7 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToExponential(ExecState* exec) isUndefined ? converter.ToExponential(x, -1, &builder) : converter.ToExponential(x, decimalPlacesInExponent, &builder); - return JSValue::encode(jsString(exec, UString(builder.Finalize()))); + return JSValue::encode(jsString(exec, String(builder.Finalize()))); } // toFixed converts a number to a string, always formatting as an a decimal fraction. @@ -409,20 +409,20 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState* exec) int decimalPlaces; bool isUndefined; // This is ignored; undefined treated as 0. if (!getIntegerArgumentInRange(exec, 0, 20, decimalPlaces, isUndefined)) - return throwVMError(exec, createRangeError(exec, "toFixed() argument must be between 0 and 20")); + return throwVMError(exec, createRangeError(exec, ASCIILiteral("toFixed() argument must be between 0 and 20"))); // 15.7.4.5.7 states "If x >= 10^21, then let m = ToString(x)" // This also covers Ininity, and structure the check so that NaN // values are also handled by numberToString if (!(fabs(x) < 1e+21)) - return JSValue::encode(jsString(exec, UString::number(x))); + return JSValue::encode(jsString(exec, String::numberToStringECMAScript(x))); // The check above will return false for NaN or Infinity, these will be // handled by numberToString. ASSERT(isfinite(x)); NumberToStringBuffer buffer; - return JSValue::encode(jsString(exec, UString(numberToFixedWidthString(x, decimalPlaces, buffer)))); + return JSValue::encode(jsString(exec, String(numberToFixedWidthString(x, decimalPlaces, buffer)))); } // toPrecision converts a number to a string, takeing an argument specifying a @@ -442,18 +442,18 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec) int significantFigures; bool isUndefined; if (!getIntegerArgumentInRange(exec, 1, 21, significantFigures, isUndefined)) - return throwVMError(exec, createRangeError(exec, "toPrecision() argument must be between 1 and 21")); + return throwVMError(exec, createRangeError(exec, ASCIILiteral("toPrecision() argument must be between 1 and 21"))); // To precision called with no argument is treated as ToString. if (isUndefined) - return JSValue::encode(jsString(exec, UString::number(x))); + return JSValue::encode(jsString(exec, String::numberToStringECMAScript(x))); // Handle NaN and Infinity. if (!isfinite(x)) - return JSValue::encode(jsString(exec, UString::number(x))); + return JSValue::encode(jsString(exec, String::numberToStringECMAScript(x))); NumberToStringBuffer buffer; - return JSValue::encode(jsString(exec, UString(numberToFixedPrecisionString(x, significantFigures, buffer)))); + return JSValue::encode(jsString(exec, String(numberToFixedPrecisionString(x, significantFigures, buffer)))); } static inline int32_t extractRadixFromArgs(ExecState* exec) @@ -485,7 +485,7 @@ static inline EncodedJSValue integerValueToString(ExecState* exec, int32_t radix return JSValue::encode(jsString(globalData, globalData->numericStrings.add(value))); } - return JSValue::encode(jsString(exec, toUStringWithRadix(value, radix))); + return JSValue::encode(jsString(exec, toStringWithRadix(value, radix))); } @@ -497,7 +497,7 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToString(ExecState* exec) int32_t radix = extractRadixFromArgs(exec); if (radix < 2 || radix > 36) - return throwVMError(exec, createRangeError(exec, "toString() radix argument must be between 2 and 36")); + return throwVMError(exec, createRangeError(exec, ASCIILiteral("toString() radix argument must be between 2 and 36"))); int32_t integerValue = static_cast<int32_t>(doubleValue); if (integerValue == doubleValue) @@ -509,7 +509,7 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToString(ExecState* exec) } if (!isfinite(doubleValue)) - return JSValue::encode(jsString(exec, UString::number(doubleValue))); + return JSValue::encode(jsString(exec, String::numberToStringECMAScript(doubleValue))); RadixBuffer s; return JSValue::encode(jsString(exec, toStringWithRadix(s, doubleValue, radix))); diff --git a/Source/JavaScriptCore/runtime/NumericStrings.h b/Source/JavaScriptCore/runtime/NumericStrings.h index 7fa20c44d..4cd92fc1f 100644 --- a/Source/JavaScriptCore/runtime/NumericStrings.h +++ b/Source/JavaScriptCore/runtime/NumericStrings.h @@ -26,25 +26,25 @@ #ifndef NumericStrings_h #define NumericStrings_h -#include "UString.h" #include <wtf/FixedArray.h> #include <wtf/HashFunctions.h> +#include <wtf/text/WTFString.h> namespace JSC { class NumericStrings { public: - ALWAYS_INLINE UString add(double d) + ALWAYS_INLINE String add(double d) { CacheEntry<double>& entry = lookup(d); if (d == entry.key && !entry.value.isNull()) return entry.value; entry.key = d; - entry.value = UString::number(d); + entry.value = String::numberToStringECMAScript(d); return entry.value; } - ALWAYS_INLINE UString add(int i) + ALWAYS_INLINE String add(int i) { if (static_cast<unsigned>(i) < cacheSize) return lookupSmallString(static_cast<unsigned>(i)); @@ -52,11 +52,11 @@ namespace JSC { if (i == entry.key && !entry.value.isNull()) return entry.value; entry.key = i; - entry.value = UString::number(i); + entry.value = String::number(i); return entry.value; } - ALWAYS_INLINE UString add(unsigned i) + ALWAYS_INLINE String add(unsigned i) { if (i < cacheSize) return lookupSmallString(static_cast<unsigned>(i)); @@ -64,7 +64,7 @@ namespace JSC { if (i == entry.key && !entry.value.isNull()) return entry.value; entry.key = i; - entry.value = UString::number(i); + entry.value = String::number(i); return entry.value; } private: @@ -73,24 +73,24 @@ namespace JSC { template<typename T> struct CacheEntry { T key; - UString value; + String value; }; CacheEntry<double>& lookup(double d) { return doubleCache[WTF::FloatHash<double>::hash(d) & (cacheSize - 1)]; } CacheEntry<int>& lookup(int i) { return intCache[WTF::IntHash<int>::hash(i) & (cacheSize - 1)]; } CacheEntry<unsigned>& lookup(unsigned i) { return unsignedCache[WTF::IntHash<unsigned>::hash(i) & (cacheSize - 1)]; } - ALWAYS_INLINE const UString& lookupSmallString(unsigned i) + ALWAYS_INLINE const String& lookupSmallString(unsigned i) { ASSERT(i < cacheSize); if (smallIntCache[i].isNull()) - smallIntCache[i] = UString::number(i); + smallIntCache[i] = String::number(i); return smallIntCache[i]; } FixedArray<CacheEntry<double>, cacheSize> doubleCache; FixedArray<CacheEntry<int>, cacheSize> intCache; FixedArray<CacheEntry<unsigned>, cacheSize> unsignedCache; - FixedArray<UString, cacheSize> smallIntCache; + FixedArray<String, cacheSize> smallIntCache; }; } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/ObjectConstructor.cpp b/Source/JavaScriptCore/runtime/ObjectConstructor.cpp index 5a6fcddf0..ed0d0cfc7 100644 --- a/Source/JavaScriptCore/runtime/ObjectConstructor.cpp +++ b/Source/JavaScriptCore/runtime/ObjectConstructor.cpp @@ -84,7 +84,7 @@ ObjectConstructor::ObjectConstructor(JSGlobalObject* globalObject, Structure* st void ObjectConstructor::finishCreation(ExecState* exec, ObjectPrototype* objectPrototype) { - Base::finishCreation(exec->globalData(), Identifier(exec, "Object").ustring()); + Base::finishCreation(exec->globalData(), Identifier(exec, "Object").string()); // ECMA 15.2.3.1 putDirectWithoutTransition(exec->globalData(), exec->propertyNames().prototype, objectPrototype, DontEnum | DontDelete | ReadOnly); // no. of arguments for constructor @@ -137,7 +137,7 @@ CallType ObjectConstructor::getCallData(JSCell*, CallData& callData) EncodedJSValue JSC_HOST_CALL objectConstructorGetPrototypeOf(ExecState* exec) { if (!exec->argument(0).isObject()) - return throwVMError(exec, createTypeError(exec, "Requested prototype of a value that is not an object.")); + return throwVMError(exec, createTypeError(exec, ASCIILiteral("Requested prototype of a value that is not an object."))); JSObject* object = asObject(exec->argument(0)); if (!object->allowsAccessFrom(exec->trueCallerFrame())) return JSValue::encode(jsUndefined()); @@ -147,8 +147,8 @@ EncodedJSValue JSC_HOST_CALL objectConstructorGetPrototypeOf(ExecState* exec) EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState* exec) { if (!exec->argument(0).isObject()) - return throwVMError(exec, createTypeError(exec, "Requested property descriptor of a value that is not an object.")); - UString propertyName = exec->argument(1).toString(exec)->value(exec); + return throwVMError(exec, createTypeError(exec, ASCIILiteral("Requested property descriptor of a value that is not an object."))); + String propertyName = exec->argument(1).toString(exec)->value(exec); if (exec->hadException()) return JSValue::encode(jsNull()); JSObject* object = asObject(exec->argument(0)); @@ -179,13 +179,13 @@ EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(ExecState* exec) { if (!exec->argument(0).isObject()) - return throwVMError(exec, createTypeError(exec, "Requested property names of a value that is not an object.")); + return throwVMError(exec, createTypeError(exec, ASCIILiteral("Requested property names of a value that is not an object."))); PropertyNameArray properties(exec); asObject(exec->argument(0))->methodTable()->getOwnPropertyNames(asObject(exec->argument(0)), exec, properties, IncludeDontEnumProperties); JSArray* names = constructEmptyArray(exec); size_t numProperties = properties.size(); for (size_t i = 0; i < numProperties; i++) - names->push(exec, jsOwnedString(exec, properties[i].ustring())); + names->push(exec, jsOwnedString(exec, properties[i].string())); return JSValue::encode(names); } @@ -193,13 +193,13 @@ EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyNames(ExecState* exe EncodedJSValue JSC_HOST_CALL objectConstructorKeys(ExecState* exec) { if (!exec->argument(0).isObject()) - return throwVMError(exec, createTypeError(exec, "Requested keys of a value that is not an object.")); + return throwVMError(exec, createTypeError(exec, ASCIILiteral("Requested keys of a value that is not an object."))); PropertyNameArray properties(exec); asObject(exec->argument(0))->methodTable()->getOwnPropertyNames(asObject(exec->argument(0)), exec, properties, ExcludeDontEnumProperties); JSArray* keys = constructEmptyArray(exec); size_t numProperties = properties.size(); for (size_t i = 0; i < numProperties; i++) - keys->push(exec, jsOwnedString(exec, properties[i].ustring())); + keys->push(exec, jsOwnedString(exec, properties[i].string())); return JSValue::encode(keys); } @@ -207,7 +207,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorKeys(ExecState* exec) static bool toPropertyDescriptor(ExecState* exec, JSValue in, PropertyDescriptor& desc) { if (!in.isObject()) { - throwError(exec, createTypeError(exec, "Property description must be an object.")); + throwError(exec, createTypeError(exec, ASCIILiteral("Property description must be an object."))); return false; } JSObject* description = asObject(in); @@ -249,7 +249,7 @@ static bool toPropertyDescriptor(ExecState* exec, JSValue in, PropertyDescriptor if (!get.isUndefined()) { CallData callData; if (getCallData(get, callData) == CallTypeNone) { - throwError(exec, createTypeError(exec, "Getter must be a function.")); + throwError(exec, createTypeError(exec, ASCIILiteral("Getter must be a function."))); return false; } } @@ -264,7 +264,7 @@ static bool toPropertyDescriptor(ExecState* exec, JSValue in, PropertyDescriptor if (!set.isUndefined()) { CallData callData; if (getCallData(set, callData) == CallTypeNone) { - throwError(exec, createTypeError(exec, "Setter must be a function.")); + throwError(exec, createTypeError(exec, ASCIILiteral("Setter must be a function."))); return false; } } @@ -275,12 +275,12 @@ static bool toPropertyDescriptor(ExecState* exec, JSValue in, PropertyDescriptor return true; if (desc.value()) { - throwError(exec, createTypeError(exec, "Invalid property. 'value' present on property with getter or setter.")); + throwError(exec, createTypeError(exec, ASCIILiteral("Invalid property. 'value' present on property with getter or setter."))); return false; } if (desc.writablePresent()) { - throwError(exec, createTypeError(exec, "Invalid property. 'writable' present on property with getter or setter.")); + throwError(exec, createTypeError(exec, ASCIILiteral("Invalid property. 'writable' present on property with getter or setter."))); return false; } return true; @@ -289,9 +289,9 @@ static bool toPropertyDescriptor(ExecState* exec, JSValue in, PropertyDescriptor EncodedJSValue JSC_HOST_CALL objectConstructorDefineProperty(ExecState* exec) { if (!exec->argument(0).isObject()) - return throwVMError(exec, createTypeError(exec, "Properties can only be defined on Objects.")); + return throwVMError(exec, createTypeError(exec, ASCIILiteral("Properties can only be defined on Objects."))); JSObject* O = asObject(exec->argument(0)); - UString propertyName = exec->argument(1).toString(exec)->value(exec); + String propertyName = exec->argument(1).toString(exec)->value(exec); if (exec->hadException()) return JSValue::encode(jsNull()); PropertyDescriptor descriptor; @@ -340,20 +340,20 @@ static JSValue defineProperties(ExecState* exec, JSObject* object, JSObject* pro EncodedJSValue JSC_HOST_CALL objectConstructorDefineProperties(ExecState* exec) { if (!exec->argument(0).isObject()) - return throwVMError(exec, createTypeError(exec, "Properties can only be defined on Objects.")); + return throwVMError(exec, createTypeError(exec, ASCIILiteral("Properties can only be defined on Objects."))); return JSValue::encode(defineProperties(exec, asObject(exec->argument(0)), exec->argument(1).toObject(exec))); } EncodedJSValue JSC_HOST_CALL objectConstructorCreate(ExecState* exec) { if (!exec->argument(0).isObject() && !exec->argument(0).isNull()) - return throwVMError(exec, createTypeError(exec, "Object prototype may only be an Object or null.")); + return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object prototype may only be an Object or null."))); JSValue proto = exec->argument(0); JSObject* newObject = proto.isObject() ? constructEmptyObject(exec, asObject(proto)->inheritorID(exec->globalData())) : constructEmptyObject(exec, exec->lexicalGlobalObject()->nullPrototypeObjectStructure()); if (exec->argument(1).isUndefined()) return JSValue::encode(newObject); if (!exec->argument(1).isObject()) - return throwVMError(exec, createTypeError(exec, "Property descriptor list must be an Object.")); + return throwVMError(exec, createTypeError(exec, ASCIILiteral("Property descriptor list must be an Object."))); return JSValue::encode(defineProperties(exec, newObject, asObject(exec->argument(1)))); } @@ -362,7 +362,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorSeal(ExecState* exec) // 1. If Type(O) is not Object throw a TypeError exception. JSValue obj = exec->argument(0); if (!obj.isObject()) - return throwVMError(exec, createTypeError(exec, "Object.seal can only be called on Objects.")); + return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.seal can only be called on Objects."))); JSObject* object = asObject(obj); if (isJSFinalObject(object)) { @@ -399,7 +399,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorFreeze(ExecState* exec) // 1. If Type(O) is not Object throw a TypeError exception. JSValue obj = exec->argument(0); if (!obj.isObject()) - return throwVMError(exec, createTypeError(exec, "Object.freeze can only be called on Objects.")); + return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.freeze can only be called on Objects."))); JSObject* object = asObject(obj); if (isJSFinalObject(object)) { @@ -439,7 +439,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorPreventExtensions(ExecState* exec) { JSValue obj = exec->argument(0); if (!obj.isObject()) - return throwVMError(exec, createTypeError(exec, "Object.preventExtensions can only be called on Objects.")); + return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.preventExtensions can only be called on Objects."))); asObject(obj)->preventExtensions(exec->globalData()); return JSValue::encode(obj); } @@ -449,7 +449,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorIsSealed(ExecState* exec) // 1. If Type(O) is not Object throw a TypeError exception. JSValue obj = exec->argument(0); if (!obj.isObject()) - return throwVMError(exec, createTypeError(exec, "Object.isSealed can only be called on Objects.")); + return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.isSealed can only be called on Objects."))); JSObject* object = asObject(obj); if (isJSFinalObject(object)) @@ -479,7 +479,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorIsFrozen(ExecState* exec) // 1. If Type(O) is not Object throw a TypeError exception. JSValue obj = exec->argument(0); if (!obj.isObject()) - return throwVMError(exec, createTypeError(exec, "Object.isFrozen can only be called on Objects.")); + return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.isFrozen can only be called on Objects."))); JSObject* object = asObject(obj); if (isJSFinalObject(object)) @@ -509,7 +509,7 @@ EncodedJSValue JSC_HOST_CALL objectConstructorIsExtensible(ExecState* exec) { JSValue obj = exec->argument(0); if (!obj.isObject()) - return throwVMError(exec, createTypeError(exec, "Object.isExtensible can only be called on Objects.")); + return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object.isExtensible can only be called on Objects."))); return JSValue::encode(jsBoolean(asObject(obj)->isExtensible())); } diff --git a/Source/JavaScriptCore/runtime/ObjectPrototype.cpp b/Source/JavaScriptCore/runtime/ObjectPrototype.cpp index 6faa16848..800909385 100644 --- a/Source/JavaScriptCore/runtime/ObjectPrototype.cpp +++ b/Source/JavaScriptCore/runtime/ObjectPrototype.cpp @@ -157,7 +157,7 @@ EncodedJSValue JSC_HOST_CALL objectProtoFuncDefineGetter(ExecState* exec) JSValue get = exec->argument(1); CallData callData; if (getCallData(get, callData) == CallTypeNone) - return throwVMError(exec, createSyntaxError(exec, "invalid getter usage")); + return throwVMError(exec, createTypeError(exec, ASCIILiteral("invalid getter usage"))); PropertyDescriptor descriptor; descriptor.setGetter(get); @@ -177,7 +177,7 @@ EncodedJSValue JSC_HOST_CALL objectProtoFuncDefineSetter(ExecState* exec) JSValue set = exec->argument(1); CallData callData; if (getCallData(set, callData) == CallTypeNone) - return throwVMError(exec, createSyntaxError(exec, "invalid setter usage")); + return throwVMError(exec, createTypeError(exec, ASCIILiteral("invalid setter usage"))); PropertyDescriptor descriptor; descriptor.setSetter(set); @@ -247,7 +247,7 @@ EncodedJSValue JSC_HOST_CALL objectProtoFuncToString(ExecState* exec) { JSValue thisValue = exec->hostThisValue(); if (thisValue.isUndefinedOrNull()) - return JSValue::encode(jsNontrivialString(exec, thisValue.isUndefined() ? "[object Undefined]" : "[object Null]")); + return JSValue::encode(jsNontrivialString(exec, String(thisValue.isUndefined() ? ASCIILiteral("[object Undefined]") : ASCIILiteral("[object Null]")))); JSObject* thisObject = thisValue.toObject(exec); JSString* result = thisObject->structure()->objectToStringValue(); diff --git a/Source/JavaScriptCore/runtime/Operations.h b/Source/JavaScriptCore/runtime/Operations.h index 88fffdac4..30ba0b27d 100644 --- a/Source/JavaScriptCore/runtime/Operations.h +++ b/Source/JavaScriptCore/runtime/Operations.h @@ -50,7 +50,7 @@ namespace JSC { return JSRopeString::create(globalData, s1, s2); } - ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, const UString& u2, const UString& u3) + ALWAYS_INLINE JSValue jsString(ExecState* exec, const String& u1, const String& u2, const String& u3) { JSGlobalData* globalData = &exec->globalData(); @@ -221,7 +221,7 @@ namespace JSC { return v1.asNumber() < v2.asNumber(); if (isJSString(v1) && isJSString(v2)) - return asString(v1)->value(callFrame) < asString(v2)->value(callFrame); + return codePointCompareLessThan(asString(v1)->value(callFrame), asString(v2)->value(callFrame)); double n1; double n2; @@ -239,7 +239,7 @@ namespace JSC { if (wasNotString1 | wasNotString2) return n1 < n2; - return asString(p1)->value(callFrame) < asString(p2)->value(callFrame); + return codePointCompareLessThan(asString(p1)->value(callFrame), asString(p2)->value(callFrame)); } // See ES5 11.8.3/11.8.4/11.8.5 for definition of leftFirst, this value ensures correct @@ -255,7 +255,7 @@ namespace JSC { return v1.asNumber() <= v2.asNumber(); if (isJSString(v1) && isJSString(v2)) - return !(asString(v2)->value(callFrame) < asString(v1)->value(callFrame)); + return !codePointCompareLessThan(asString(v2)->value(callFrame), asString(v1)->value(callFrame)); double n1; double n2; @@ -273,7 +273,7 @@ namespace JSC { if (wasNotString1 | wasNotString2) return n1 <= n2; - return !(asString(p2)->value(callFrame) < asString(p1)->value(callFrame)); + return !codePointCompareLessThan(asString(p2)->value(callFrame), asString(p1)->value(callFrame)); } // Fast-path choices here are based on frequency data from SunSpider: @@ -347,33 +347,6 @@ namespace JSC { } } - ALWAYS_INLINE JSValue resolveBase(CallFrame* callFrame, Identifier& property, ScopeChainNode* scopeChain, bool isStrictPut) - { - ScopeChainIterator iter = scopeChain->begin(); - ScopeChainIterator next = iter; - ++next; - ScopeChainIterator end = scopeChain->end(); - ASSERT(iter != end); - - PropertySlot slot; - JSObject* base; - while (true) { - base = iter->get(); - if (next == end) { - if (isStrictPut && !base->getPropertySlot(callFrame, property, slot)) - return JSValue(); - return base; - } - if (base->getPropertySlot(callFrame, property, slot)) - return base; - - iter = next; - ++next; - } - - ASSERT_NOT_REACHED(); - return JSValue(); - } } // namespace JSC #endif // Operations_h diff --git a/Source/JavaScriptCore/runtime/Options.cpp b/Source/JavaScriptCore/runtime/Options.cpp index b5ce39c0d..16c0b5d43 100644 --- a/Source/JavaScriptCore/runtime/Options.cpp +++ b/Source/JavaScriptCore/runtime/Options.cpp @@ -138,6 +138,19 @@ void Options::initialize() ; // Deconfuse editors that do auto indentation #endif +#if !ENABLE(JIT) + useJIT() = false; + useDFGJIT() = false; +#endif +#if !ENABLE(YARR_JIT) + useRegExpJIT() = false; +#endif + +#if USE(CF) || OS(UNIX) + zombiesAreImmortal() = !!getenv("JSImmortalZombieEnabled"); + useZombieMode() = zombiesAreImmortal() || !!getenv("JSZombieEnabled"); +#endif + // Do range checks where needed and make corrections to the options: ASSERT(thresholdForOptimizeAfterLongWarmUp() >= thresholdForOptimizeAfterWarmUp()); ASSERT(thresholdForOptimizeAfterWarmUp() >= thresholdForOptimizeSoon()); diff --git a/Source/JavaScriptCore/runtime/Options.h b/Source/JavaScriptCore/runtime/Options.h index ab3f34bb6..5e53d1cf2 100644 --- a/Source/JavaScriptCore/runtime/Options.h +++ b/Source/JavaScriptCore/runtime/Options.h @@ -65,6 +65,7 @@ namespace JSC { #define JSC_OPTIONS(v) \ v(bool, useJIT, true) \ v(bool, useDFGJIT, true) \ + v(bool, useRegExpJIT, true) \ \ /* showDisassembly implies showDFGDisassembly. */ \ v(bool, showDisassembly, false) \ @@ -117,7 +118,10 @@ namespace JSC { v(unsigned, opaqueRootMergeThreshold, 1000) \ \ v(bool, forceWeakRandomSeed, false) \ - v(unsigned, forcedWeakRandomSeed, 0) + v(unsigned, forcedWeakRandomSeed, 0) \ + \ + v(bool, useZombieMode, false) \ + v(bool, zombiesAreImmortal, false) class Options { diff --git a/Source/JavaScriptCore/runtime/PropertyMapHashTable.h b/Source/JavaScriptCore/runtime/PropertyMapHashTable.h index 5953f5e87..2d0f27a3e 100644 --- a/Source/JavaScriptCore/runtime/PropertyMapHashTable.h +++ b/Source/JavaScriptCore/runtime/PropertyMapHashTable.h @@ -22,11 +22,11 @@ #define PropertyMapHashTable_h #include "PropertyOffset.h" -#include "UString.h" #include "WriteBarrier.h" #include <wtf/HashTable.h> #include <wtf/PassOwnPtr.h> #include <wtf/Vector.h> +#include <wtf/text/StringImpl.h> #ifndef NDEBUG @@ -44,7 +44,7 @@ extern int numRemoves; #endif -#define PROPERTY_MAP_DELETED_ENTRY_KEY ((StringImpl*)1) +#define PROPERTY_MAP_DELETED_ENTRY_KEY ((StringImpl*)1) namespace JSC { diff --git a/Source/JavaScriptCore/runtime/PropertyNameArray.cpp b/Source/JavaScriptCore/runtime/PropertyNameArray.cpp index 9bae94097..08a5296a4 100644 --- a/Source/JavaScriptCore/runtime/PropertyNameArray.cpp +++ b/Source/JavaScriptCore/runtime/PropertyNameArray.cpp @@ -22,7 +22,7 @@ #include "PropertyNameArray.h" #include "JSObject.h" -#include "ScopeChain.h" + #include "Structure.h" #include "StructureChain.h" diff --git a/Source/JavaScriptCore/runtime/RegExp.cpp b/Source/JavaScriptCore/runtime/RegExp.cpp index 64e553be1..7757274f1 100644 --- a/Source/JavaScriptCore/runtime/RegExp.cpp +++ b/Source/JavaScriptCore/runtime/RegExp.cpp @@ -40,7 +40,7 @@ namespace JSC { const ClassInfo RegExp::s_info = { "RegExp", 0, 0, 0, CREATE_METHOD_TABLE(RegExp) }; -RegExpFlags regExpFlags(const UString& string) +RegExpFlags regExpFlags(const String& string) { RegExpFlags flags = NoFlags; @@ -83,7 +83,7 @@ public: ~RegExpFunctionalTestCollector(); - void outputOneTest(RegExp*, UString, int, int*, int); + void outputOneTest(RegExp*, String, int, int*, int); void clearRegExp(RegExp* regExp) { if (regExp == m_lastRegExp) @@ -93,7 +93,7 @@ public: private: RegExpFunctionalTestCollector(); - void outputEscapedUString(const UString&, bool escapeSlash = false); + void outputEscapedString(const String&, bool escapeSlash = false); static RegExpFunctionalTestCollector* s_instance; FILE* m_file; @@ -111,12 +111,12 @@ RegExpFunctionalTestCollector* RegExpFunctionalTestCollector::get() return s_instance; } -void RegExpFunctionalTestCollector::outputOneTest(RegExp* regExp, UString s, int startOffset, int* ovector, int result) +void RegExpFunctionalTestCollector::outputOneTest(RegExp* regExp, String s, int startOffset, int* ovector, int result) { if ((!m_lastRegExp) || (m_lastRegExp != regExp)) { m_lastRegExp = regExp; fputc('/', m_file); - outputEscapedUString(regExp->pattern(), true); + outputEscapedString(regExp->pattern(), true); fputc('/', m_file); if (regExp->global()) fputc('g', m_file); @@ -128,7 +128,7 @@ void RegExpFunctionalTestCollector::outputOneTest(RegExp* regExp, UString s, int } fprintf(m_file, " \""); - outputEscapedUString(s); + outputEscapedString(s); fprintf(m_file, "\", %d, %d, (", startOffset, result); for (unsigned i = 0; i <= regExp->numSubpatterns(); i++) { int subpatternBegin = ovector[i * 2]; @@ -159,7 +159,7 @@ RegExpFunctionalTestCollector::~RegExpFunctionalTestCollector() s_instance = 0; } -void RegExpFunctionalTestCollector::outputEscapedUString(const UString& s, bool escapeSlash) +void RegExpFunctionalTestCollector::outputEscapedString(const String& s, bool escapeSlash) { int len = s.length(); @@ -217,7 +217,7 @@ void RegExpFunctionalTestCollector::outputEscapedUString(const UString& s, bool } #endif -RegExp::RegExp(JSGlobalData& globalData, const UString& patternString, RegExpFlags flags) +RegExp::RegExp(JSGlobalData& globalData, const String& patternString, RegExpFlags flags) : JSCell(globalData, globalData.regExpStructure.get()) , m_state(NotCompiled) , m_patternString(patternString) @@ -250,14 +250,14 @@ void RegExp::destroy(JSCell* cell) thisObject->RegExp::~RegExp(); } -RegExp* RegExp::createWithoutCaching(JSGlobalData& globalData, const UString& patternString, RegExpFlags flags) +RegExp* RegExp::createWithoutCaching(JSGlobalData& globalData, const String& patternString, RegExpFlags flags) { RegExp* regExp = new (NotNull, allocateCell<RegExp>(globalData.heap)) RegExp(globalData, patternString, flags); regExp->finishCreation(globalData); return regExp; } -RegExp* RegExp::create(JSGlobalData& globalData, const UString& patternString, RegExpFlags flags) +RegExp* RegExp::create(JSGlobalData& globalData, const String& patternString, RegExpFlags flags) { return globalData.regExpCache()->lookupOrCreate(patternString, flags); } @@ -318,7 +318,7 @@ void RegExp::compileIfNecessary(JSGlobalData& globalData, Yarr::YarrCharSize cha compile(&globalData, charSize); } -int RegExp::match(JSGlobalData& globalData, const UString& s, unsigned startOffset, Vector<int, 32>& ovector) +int RegExp::match(JSGlobalData& globalData, const String& s, unsigned startOffset, Vector<int, 32>& ovector) { #if ENABLE(REGEXP_TRACING) m_rtMatchCallCount++; @@ -440,7 +440,7 @@ void RegExp::compileIfNecessaryMatchOnly(JSGlobalData& globalData, Yarr::YarrCha compileMatchOnly(&globalData, charSize); } -MatchResult RegExp::match(JSGlobalData& globalData, const UString& s, unsigned startOffset) +MatchResult RegExp::match(JSGlobalData& globalData, const String& s, unsigned startOffset) { #if ENABLE(REGEXP_TRACING) m_rtMatchCallCount++; @@ -494,7 +494,7 @@ void RegExp::invalidateCode() } #if ENABLE(YARR_JIT_DEBUG) -void RegExp::matchCompareWithInterpreter(const UString& s, int startOffset, int* offsetVector, int jitResult) +void RegExp::matchCompareWithInterpreter(const String& s, int startOffset, int* offsetVector, int jitResult) { int offsetVectorSize = (m_numSubpatterns + 1) * 2; Vector<int, 32> interpreterOvector; diff --git a/Source/JavaScriptCore/runtime/RegExp.h b/Source/JavaScriptCore/runtime/RegExp.h index ad1020376..287444b95 100644 --- a/Source/JavaScriptCore/runtime/RegExp.h +++ b/Source/JavaScriptCore/runtime/RegExp.h @@ -26,10 +26,10 @@ #include "MatchResult.h" #include "RegExpKey.h" #include "Structure.h" -#include "UString.h" #include "yarr/Yarr.h" #include <wtf/Forward.h> #include <wtf/RefCounted.h> +#include <wtf/text/WTFString.h> #if ENABLE(YARR_JIT) #include "yarr/YarrJIT.h" @@ -40,26 +40,26 @@ namespace JSC { struct RegExpRepresentation; class JSGlobalData; - JS_EXPORT_PRIVATE RegExpFlags regExpFlags(const UString&); + JS_EXPORT_PRIVATE RegExpFlags regExpFlags(const String&); class RegExp : public JSCell { public: typedef JSCell Base; - JS_EXPORT_PRIVATE static RegExp* create(JSGlobalData&, const UString& pattern, RegExpFlags); + JS_EXPORT_PRIVATE static RegExp* create(JSGlobalData&, const String& pattern, RegExpFlags); static void destroy(JSCell*); bool global() const { return m_flags & FlagGlobal; } bool ignoreCase() const { return m_flags & FlagIgnoreCase; } bool multiline() const { return m_flags & FlagMultiline; } - const UString& pattern() const { return m_patternString; } + const String& pattern() const { return m_patternString; } bool isValid() const { return !m_constructionError && m_flags != InvalidFlags; } const char* errorMessage() const { return m_constructionError; } - JS_EXPORT_PRIVATE int match(JSGlobalData&, const UString&, unsigned startOffset, Vector<int, 32>& ovector); - MatchResult match(JSGlobalData&, const UString&, unsigned startOffset); + JS_EXPORT_PRIVATE int match(JSGlobalData&, const String&, unsigned startOffset, Vector<int, 32>& ovector); + MatchResult match(JSGlobalData&, const String&, unsigned startOffset); unsigned numSubpatterns() const { return m_numSubpatterns; } bool hasCode() @@ -87,9 +87,9 @@ namespace JSC { private: friend class RegExpCache; - RegExp(JSGlobalData&, const UString&, RegExpFlags); + RegExp(JSGlobalData&, const String&, RegExpFlags); - static RegExp* createWithoutCaching(JSGlobalData&, const UString&, RegExpFlags); + static RegExp* createWithoutCaching(JSGlobalData&, const String&, RegExpFlags); enum RegExpState { ParseError, @@ -105,10 +105,10 @@ namespace JSC { void compileIfNecessaryMatchOnly(JSGlobalData&, Yarr::YarrCharSize); #if ENABLE(YARR_JIT_DEBUG) - void matchCompareWithInterpreter(const UString&, int startOffset, int* offsetVector, int jitResult); + void matchCompareWithInterpreter(const String&, int startOffset, int* offsetVector, int jitResult); #endif - UString m_patternString; + String m_patternString; RegExpFlags m_flags; const char* m_constructionError; unsigned m_numSubpatterns; diff --git a/Source/JavaScriptCore/runtime/RegExpCache.cpp b/Source/JavaScriptCore/runtime/RegExpCache.cpp index 53a13a4b5..c67dab8e6 100644 --- a/Source/JavaScriptCore/runtime/RegExpCache.cpp +++ b/Source/JavaScriptCore/runtime/RegExpCache.cpp @@ -33,7 +33,7 @@ namespace JSC { -RegExp* RegExpCache::lookupOrCreate(const UString& patternString, RegExpFlags flags) +RegExp* RegExpCache::lookupOrCreate(const String& patternString, RegExpFlags flags) { RegExpKey key(flags, patternString); if (RegExp* regExp = m_weakCache.get(key)) @@ -63,7 +63,7 @@ void RegExpCache::finalize(Handle<Unknown> handle, void*) void RegExpCache::addToStrongCache(RegExp* regExp) { - UString pattern = regExp->pattern(); + String pattern = regExp->pattern(); if (pattern.length() > maxStrongCacheablePatternLength) return; m_strongCache[m_nextEntryInStrongCache].set(*m_globalData, regExp); diff --git a/Source/JavaScriptCore/runtime/RegExpCache.h b/Source/JavaScriptCore/runtime/RegExpCache.h index 4f3ea1536..c6a4a0aa2 100644 --- a/Source/JavaScriptCore/runtime/RegExpCache.h +++ b/Source/JavaScriptCore/runtime/RegExpCache.h @@ -28,7 +28,6 @@ #include "RegExp.h" #include "RegExpKey.h" #include "Strong.h" -#include "UString.h" #include "Weak.h" #include <wtf/FixedArray.h> #include <wtf/HashMap.h> @@ -54,7 +53,7 @@ private: virtual void finalize(Handle<Unknown>, void* context); - RegExp* lookupOrCreate(const UString& patternString, RegExpFlags); + RegExp* lookupOrCreate(const WTF::String& patternString, RegExpFlags); void addToStrongCache(RegExp*); RegExpCacheMap m_weakCache; // Holds all regular expressions currently live. int m_nextEntryInStrongCache; diff --git a/Source/JavaScriptCore/runtime/RegExpCachedResult.cpp b/Source/JavaScriptCore/runtime/RegExpCachedResult.cpp index 07881451a..47cff15f1 100644 --- a/Source/JavaScriptCore/runtime/RegExpCachedResult.cpp +++ b/Source/JavaScriptCore/runtime/RegExpCachedResult.cpp @@ -32,13 +32,10 @@ namespace JSC { void RegExpCachedResult::visitChildren(SlotVisitor& visitor) { - if (m_result) { - visitor.append(&m_lastInput); - visitor.append(&m_lastRegExp); - } else { - visitor.append(&m_reifiedInput); - visitor.append(&m_reifiedResult); - } + visitor.append(&m_lastInput); + visitor.append(&m_lastRegExp); + visitor.append(&m_reifiedInput); + visitor.append(&m_reifiedResult); } RegExpMatchesArray* RegExpCachedResult::lastResult(ExecState* exec, JSObject* owner) diff --git a/Source/JavaScriptCore/runtime/RegExpCachedResult.h b/Source/JavaScriptCore/runtime/RegExpCachedResult.h index a72244025..812ff4336 100644 --- a/Source/JavaScriptCore/runtime/RegExpCachedResult.h +++ b/Source/JavaScriptCore/runtime/RegExpCachedResult.h @@ -49,8 +49,6 @@ namespace JSC { { m_lastInput.set(globalData, owner, jsEmptyString(&globalData)); m_lastRegExp.set(globalData, owner, emptyRegExp); - m_reifiedResult.clear(); - m_reifiedInput.clear(); } ALWAYS_INLINE void record(JSGlobalData& globalData, JSObject* owner, RegExp* regExp, JSString* input, MatchResult result) diff --git a/Source/JavaScriptCore/runtime/RegExpConstructor.cpp b/Source/JavaScriptCore/runtime/RegExpConstructor.cpp index 0b463474f..b8c4cd0b3 100644 --- a/Source/JavaScriptCore/runtime/RegExpConstructor.cpp +++ b/Source/JavaScriptCore/runtime/RegExpConstructor.cpp @@ -92,7 +92,7 @@ RegExpConstructor::RegExpConstructor(JSGlobalObject* globalObject, Structure* st void RegExpConstructor::finishCreation(ExecState* exec, RegExpPrototype* regExpPrototype) { - Base::finishCreation(exec->globalData(), Identifier(exec, "RegExp").ustring()); + Base::finishCreation(exec->globalData(), Identifier(exec, "RegExp").string()); ASSERT(inherits(&s_info)); // ECMA 15.10.5.1 RegExp.prototype @@ -262,7 +262,7 @@ JSObject* constructRegExp(ExecState* exec, JSGlobalObject* globalObject, const A if (arg0.inherits(&RegExpObject::s_info)) { if (!arg1.isUndefined()) - return throwError(exec, createTypeError(exec, "Cannot supply flags when constructing one RegExp from another.")); + return throwError(exec, createTypeError(exec, ASCIILiteral("Cannot supply flags when constructing one RegExp from another."))); // If called as a function, this just returns the first argument (see 15.10.3.1). if (callAsConstructor) { RegExp* regExp = static_cast<RegExpObject*>(asObject(arg0))->regExp(); @@ -271,7 +271,7 @@ JSObject* constructRegExp(ExecState* exec, JSGlobalObject* globalObject, const A return asObject(arg0); } - UString pattern = arg0.isUndefined() ? UString("") : arg0.toString(exec)->value(exec); + String pattern = arg0.isUndefined() ? String("") : arg0.toString(exec)->value(exec); if (exec->hadException()) return 0; @@ -281,7 +281,7 @@ JSObject* constructRegExp(ExecState* exec, JSGlobalObject* globalObject, const A if (exec->hadException()) return 0; if (flags == InvalidFlags) - return throwError(exec, createSyntaxError(exec, "Invalid flags supplied to RegExp constructor.")); + return throwError(exec, createSyntaxError(exec, ASCIILiteral("Invalid flags supplied to RegExp constructor."))); } RegExp* regExp = RegExp::create(exec->globalData(), pattern, flags); diff --git a/Source/JavaScriptCore/runtime/RegExpConstructor.h b/Source/JavaScriptCore/runtime/RegExpConstructor.h index d714f2167..2cb1c1204 100644 --- a/Source/JavaScriptCore/runtime/RegExpConstructor.h +++ b/Source/JavaScriptCore/runtime/RegExpConstructor.h @@ -55,8 +55,8 @@ namespace JSC { static const ClassInfo s_info; - MatchResult performMatch(JSGlobalData&, RegExp*, JSString*, const UString&, int startOffset, int** ovector); - MatchResult performMatch(JSGlobalData&, RegExp*, JSString*, const UString&, int startOffset); + MatchResult performMatch(JSGlobalData&, RegExp*, JSString*, const String&, int startOffset, int** ovector); + MatchResult performMatch(JSGlobalData&, RegExp*, JSString*, const String&, int startOffset); void setMultiline(bool multiline) { m_multiline = multiline; } bool multiline() const { return m_multiline; } @@ -101,7 +101,7 @@ namespace JSC { expression matching through the performMatch function. We use cached results to calculate, e.g., RegExp.lastMatch and RegExp.leftParen. */ - ALWAYS_INLINE MatchResult RegExpConstructor::performMatch(JSGlobalData& globalData, RegExp* regExp, JSString* string, const UString& input, int startOffset, int** ovector) + ALWAYS_INLINE MatchResult RegExpConstructor::performMatch(JSGlobalData& globalData, RegExp* regExp, JSString* string, const String& input, int startOffset, int** ovector) { int position = regExp->match(globalData, input, startOffset, m_ovector); @@ -120,7 +120,7 @@ namespace JSC { return MatchResult(position, end); } - ALWAYS_INLINE MatchResult RegExpConstructor::performMatch(JSGlobalData& globalData, RegExp* regExp, JSString* string, const UString& input, int startOffset) + ALWAYS_INLINE MatchResult RegExpConstructor::performMatch(JSGlobalData& globalData, RegExp* regExp, JSString* string, const String& input, int startOffset) { MatchResult result = regExp->match(globalData, input, startOffset); if (result) diff --git a/Source/JavaScriptCore/runtime/RegExpKey.h b/Source/JavaScriptCore/runtime/RegExpKey.h index cdaff27f5..f93fbbc1d 100644 --- a/Source/JavaScriptCore/runtime/RegExpKey.h +++ b/Source/JavaScriptCore/runtime/RegExpKey.h @@ -28,8 +28,8 @@ #ifndef RegExpKey_h #define RegExpKey_h -#include "UString.h" #include <wtf/text/StringHash.h> +#include <wtf/text/WTFString.h> namespace JSC { @@ -56,7 +56,7 @@ struct RegExpKey { { } - RegExpKey(RegExpFlags flags, const UString& pattern) + RegExpKey(RegExpFlags flags, const String& pattern) : flagsValue(flags) , pattern(pattern.impl()) { diff --git a/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp b/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp index 80f1068f2..b2c3027b5 100644 --- a/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp +++ b/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp @@ -66,9 +66,9 @@ void RegExpMatchesArray::reifyAllProperties(ExecState* exec) for (unsigned i = 1; i <= numSubpatterns; ++i) { int start = subpatternResults[2 * i]; if (start >= 0) - putDirectIndex(exec, i, jsSubstring(exec, m_input.get(), start, subpatternResults[2 * i + 1] - start), false); + putDirectIndex(exec, i, jsSubstring(exec, m_input.get(), start, subpatternResults[2 * i + 1] - start)); else - putDirectIndex(exec, i, jsUndefined(), false); + putDirectIndex(exec, i, jsUndefined()); } } @@ -83,7 +83,7 @@ void RegExpMatchesArray::reifyMatchProperty(ExecState* exec) { ASSERT(m_state == ReifiedNone); ASSERT(m_result); - putDirectIndex(exec, 0, jsSubstring(exec, m_input.get(), m_result.start, m_result.end - m_result.start), false); + putDirectIndex(exec, 0, jsSubstring(exec, m_input.get(), m_result.start, m_result.end - m_result.start)); m_state = ReifiedMatch; } diff --git a/Source/JavaScriptCore/runtime/RegExpObject.cpp b/Source/JavaScriptCore/runtime/RegExpObject.cpp index 8aeeb9edc..b346c7769 100644 --- a/Source/JavaScriptCore/runtime/RegExpObject.cpp +++ b/Source/JavaScriptCore/runtime/RegExpObject.cpp @@ -31,9 +31,8 @@ #include "RegExpConstructor.h" #include "RegExpMatchesArray.h" #include "RegExpPrototype.h" -#include "UStringBuilder.h" -#include "UStringConcatenate.h" #include <wtf/PassOwnPtr.h> +#include <wtf/text/StringBuilder.h> namespace JSC { @@ -81,11 +80,10 @@ void RegExpObject::visitChildren(JSCell* cell, SlotVisitor& visitor) ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); + Base::visitChildren(thisObject, visitor); - if (thisObject->m_regExp) - visitor.append(&thisObject->m_regExp); - if (UNLIKELY(!thisObject->m_lastIndex.get().isInt32())) - visitor.append(&thisObject->m_lastIndex); + visitor.append(&thisObject->m_regExp); + visitor.append(&thisObject->m_lastIndex); } bool RegExpObject::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot) @@ -132,7 +130,7 @@ void RegExpObject::getPropertyNames(JSObject* object, ExecState* exec, PropertyN static bool reject(ExecState* exec, bool throwException, const char* message) { if (throwException) - throwTypeError(exec, message); + throwTypeError(exec, ASCIILiteral(message)); return false; } @@ -180,7 +178,7 @@ JSValue regExpObjectMultiline(ExecState*, JSValue slotBase, PropertyName) JSValue regExpObjectSource(ExecState* exec, JSValue slotBase, PropertyName) { - UString pattern = asRegExpObject(slotBase)->regExp()->pattern(); + String pattern = asRegExpObject(slotBase)->regExp()->pattern(); unsigned length = pattern.length(); const UChar* characters = pattern.characters(); bool previousCharacterWasBackslash = false; @@ -193,7 +191,7 @@ JSValue regExpObjectSource(ExecState* exec, JSValue slotBase, PropertyName) // source cannot ever validly be "". If the source is empty, return a different Pattern // that would match the same thing. if (!length) - return jsString(exec, "(?:)"); + return jsNontrivialString(exec, ASCIILiteral("(?:)")); // early return for strings that don't contain a forwards slash and LineTerminator for (unsigned i = 0; i < length; ++i) { @@ -228,7 +226,7 @@ JSValue regExpObjectSource(ExecState* exec, JSValue slotBase, PropertyName) previousCharacterWasBackslash = false; inBrackets = false; - UStringBuilder result; + StringBuilder result; for (unsigned i = 0; i < length; ++i) { UChar ch = characters[i]; if (!previousCharacterWasBackslash) { @@ -253,9 +251,9 @@ JSValue regExpObjectSource(ExecState* exec, JSValue slotBase, PropertyName) else if (ch == '\r') result.append('r'); else if (ch == 0x2028) - result.append("u2028"); + result.appendLiteral("u2028"); else - result.append("u2029"); + result.appendLiteral("u2029"); } else result.append(ch); @@ -265,7 +263,7 @@ JSValue regExpObjectSource(ExecState* exec, JSValue slotBase, PropertyName) previousCharacterWasBackslash = ch == '\\'; } - return jsString(exec, result.toUString()); + return jsString(exec, result.toString()); } void RegExpObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot) @@ -289,7 +287,7 @@ MatchResult RegExpObject::match(ExecState* exec, JSString* string) { RegExp* regExp = this->regExp(); RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor(); - UString input = string->value(exec); + String input = string->value(exec); JSGlobalData& globalData = exec->globalData(); if (!regExp->global()) return regExpConstructor->performMatch(globalData, regExp, string, input, 0); diff --git a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp index 24c7c8027..3c742a0d3 100644 --- a/Source/JavaScriptCore/runtime/RegExpPrototype.cpp +++ b/Source/JavaScriptCore/runtime/RegExpPrototype.cpp @@ -34,7 +34,6 @@ #include "RegExp.h" #include "RegExpCache.h" #include "StringRecursionChecker.h" -#include "UStringConcatenate.h" namespace JSC { @@ -107,10 +106,10 @@ EncodedJSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState* exec) if (arg0.inherits(&RegExpObject::s_info)) { if (!arg1.isUndefined()) - return throwVMError(exec, createTypeError(exec, "Cannot supply flags when constructing one RegExp from another.")); + return throwVMError(exec, createTypeError(exec, ASCIILiteral("Cannot supply flags when constructing one RegExp from another."))); regExp = asRegExpObject(arg0)->regExp(); } else { - UString pattern = !exec->argumentCount() ? UString("") : arg0.toString(exec)->value(exec); + String pattern = !exec->argumentCount() ? String("") : arg0.toString(exec)->value(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); @@ -120,7 +119,7 @@ EncodedJSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState* exec) if (exec->hadException()) return JSValue::encode(jsUndefined()); if (flags == InvalidFlags) - return throwVMError(exec, createSyntaxError(exec, "Invalid flags supplied to RegExp constructor.")); + return throwVMError(exec, createSyntaxError(exec, ASCIILiteral("Invalid flags supplied to RegExp constructor."))); } regExp = RegExp::create(exec->globalData(), pattern, flags); } @@ -153,7 +152,7 @@ EncodedJSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState* exec) postfix[index++] = 'i'; if (thisObject->get(exec, exec->propertyNames().multiline).toBoolean(exec)) postfix[index] = 'm'; - UString source = thisObject->get(exec, exec->propertyNames().source).toString(exec)->value(exec); + String source = thisObject->get(exec, exec->propertyNames().source).toString(exec)->value(exec); // If source is empty, use "/(?:)/" to avoid colliding with comment syntax return JSValue::encode(jsMakeNontrivialString(exec, "/", source, postfix)); } diff --git a/Source/JavaScriptCore/runtime/ScopeChain.cpp b/Source/JavaScriptCore/runtime/ScopeChain.cpp deleted file mode 100644 index e7ea07508..000000000 --- a/Source/JavaScriptCore/runtime/ScopeChain.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2003, 2006, 2008 Apple Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "ScopeChain.h" - -#include "JSActivation.h" -#include "JSGlobalObject.h" -#include "JSObject.h" -#include "PropertyNameArray.h" -#include <stdio.h> - -namespace JSC { - -ASSERT_HAS_TRIVIAL_DESTRUCTOR(ScopeChainNode); - -#ifndef NDEBUG - -void ScopeChainNode::print() -{ - ScopeChainIterator scopeEnd = end(); - for (ScopeChainIterator scopeIter = begin(); scopeIter != scopeEnd; ++scopeIter) { - JSObject* o = scopeIter->get(); - PropertyNameArray propertyNames(globalObject->globalExec()); - o->methodTable()->getPropertyNames(o, globalObject->globalExec(), propertyNames, ExcludeDontEnumProperties); - PropertyNameArray::const_iterator propEnd = propertyNames.end(); - - dataLog("----- [scope %p] -----\n", o); - for (PropertyNameArray::const_iterator propIter = propertyNames.begin(); propIter != propEnd; propIter++) { - Identifier name = *propIter; - dataLog("%s, ", name.ustring().utf8().data()); - } - dataLog("\n"); - } -} - -#endif - -const ClassInfo ScopeChainNode::s_info = { "ScopeChainNode", 0, 0, 0, CREATE_METHOD_TABLE(ScopeChainNode) }; - -int ScopeChainNode::localDepth() -{ - int scopeDepth = 0; - ScopeChainIterator iter = this->begin(); - ScopeChainIterator end = this->end(); - while (!(*iter)->inherits(&JSActivation::s_info)) { - ++iter; - if (iter == end) - break; - ++scopeDepth; - } - return scopeDepth; -} - -void ScopeChainNode::visitChildren(JSCell* cell, SlotVisitor& visitor) -{ - ScopeChainNode* thisObject = jsCast<ScopeChainNode*>(cell); - ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); - COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); - ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); - if (thisObject->next) - visitor.append(&thisObject->next); - visitor.append(&thisObject->object); - visitor.append(&thisObject->globalObject); - visitor.append(&thisObject->globalThis); -} - -} // namespace JSC diff --git a/Source/JavaScriptCore/runtime/ScopeChain.h b/Source/JavaScriptCore/runtime/ScopeChain.h deleted file mode 100644 index c382008f1..000000000 --- a/Source/JavaScriptCore/runtime/ScopeChain.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2003, 2008, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef ScopeChain_h -#define ScopeChain_h - -#include "JSCell.h" -#include "Structure.h" -#include <wtf/FastAllocBase.h> - -namespace JSC { - - class JSGlobalData; - class JSGlobalObject; - class JSObject; - class LLIntOffsetsExtractor; - class ScopeChainIterator; - class SlotVisitor; - - class ScopeChainNode : public JSCell { - private: - ScopeChainNode(ScopeChainNode* next, JSObject* object, JSGlobalData* globalData, JSGlobalObject* globalObject, JSObject* globalThis) - : JSCell(*globalData, globalData->scopeChainNodeStructure.get()) - , globalData(globalData) - , next(*globalData, this, next, WriteBarrier<ScopeChainNode>::MayBeNull) - , object(*globalData, this, object) - , globalObject(*globalData, this, globalObject) - , globalThis(*globalData, this, globalThis) - { - } - - protected: - void finishCreation(JSGlobalData* globalData, JSGlobalObject* globalObject) - { - Base::finishCreation(*globalData); - ASSERT_UNUSED(globalObject, globalObject); - } - - public: - typedef JSCell Base; - - static ScopeChainNode* create(ExecState* exec, ScopeChainNode* next, JSObject* object, JSGlobalData* globalData, JSGlobalObject* globalObject, JSObject* globalThis) - { - ScopeChainNode* node = new (NotNull, allocateCell<ScopeChainNode>(*exec->heap())) ScopeChainNode(next, object, globalData, globalObject, globalThis); - node->finishCreation(globalData, globalObject); - return node; - } - static ScopeChainNode* create(ScopeChainNode* next, JSObject* object, JSGlobalData* globalData, JSGlobalObject* globalObject, JSObject* globalThis) - { - ScopeChainNode* node = new (NotNull, allocateCell<ScopeChainNode>(globalData->heap)) ScopeChainNode(next, object, globalData, globalObject, globalThis); - node->finishCreation(globalData, globalObject); - return node; - } - - JSGlobalData* globalData; - WriteBarrier<ScopeChainNode> next; - WriteBarrier<JSObject> object; - WriteBarrier<JSGlobalObject> globalObject; - WriteBarrier<JSObject> globalThis; - - ScopeChainNode* push(JSObject*); - ScopeChainNode* pop(); - - ScopeChainIterator begin(); - ScopeChainIterator end(); - - int localDepth(); - -#ifndef NDEBUG - void print(); -#endif - - static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue proto) { return Structure::create(globalData, globalObject, proto, TypeInfo(CompoundType, StructureFlags), &s_info); } - static void visitChildren(JSCell*, SlotVisitor&); - static JS_EXPORTDATA const ClassInfo s_info; - - private: - friend class LLIntOffsetsExtractor; - - static const unsigned StructureFlags = OverridesVisitChildren; - }; - - inline ScopeChainNode* ScopeChainNode::push(JSObject* o) - { - ASSERT(o); - return ScopeChainNode::create(this, o, globalData, globalObject.get(), globalThis.get()); - } - - inline ScopeChainNode* ScopeChainNode::pop() - { - ASSERT(next); - return next.get(); - } - - class ScopeChainIterator { - public: - ScopeChainIterator(ScopeChainNode* node) - : m_node(node) - { - } - - WriteBarrier<JSObject> const & operator*() const { return m_node->object; } - WriteBarrier<JSObject> const * operator->() const { return &(operator*()); } - - ScopeChainIterator& operator++() { m_node = m_node->next.get(); return *this; } - - // postfix ++ intentionally omitted - - bool operator==(const ScopeChainIterator& other) const { return m_node == other.m_node; } - bool operator!=(const ScopeChainIterator& other) const { return m_node != other.m_node; } - - private: - ScopeChainNode* m_node; - }; - - inline ScopeChainIterator ScopeChainNode::begin() - { - return ScopeChainIterator(this); - } - - inline ScopeChainIterator ScopeChainNode::end() - { - return ScopeChainIterator(0); - } - - ALWAYS_INLINE JSGlobalData& ExecState::globalData() const - { - ASSERT(scopeChain()->globalData); - return *scopeChain()->globalData; - } - - ALWAYS_INLINE JSGlobalObject* ExecState::lexicalGlobalObject() const - { - return scopeChain()->globalObject.get(); - } - - ALWAYS_INLINE JSObject* ExecState::globalThisValue() const - { - return scopeChain()->globalThis.get(); - } - - ALWAYS_INLINE ScopeChainNode* Register::scopeChain() const - { - return static_cast<ScopeChainNode*>(jsValue().asCell()); - } - - ALWAYS_INLINE Register& Register::operator=(ScopeChainNode* scopeChain) - { - *this = JSValue(scopeChain); - return *this; - } - -} // namespace JSC - -#endif // ScopeChain_h diff --git a/Source/JavaScriptCore/runtime/ScopeChainMark.h b/Source/JavaScriptCore/runtime/ScopeChainMark.h deleted file mode 100644 index 35701f11d..000000000 --- a/Source/JavaScriptCore/runtime/ScopeChainMark.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2003, 2006, 2008, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef ScopeChainMark_h -#define ScopeChainMark_h - -#include "ScopeChain.h" - -namespace JSC { - -} // namespace JSC - -#endif // ScopeChainMark_h diff --git a/Source/JavaScriptCore/runtime/SmallStrings.cpp b/Source/JavaScriptCore/runtime/SmallStrings.cpp index f50f73d27..56a359279 100644 --- a/Source/JavaScriptCore/runtime/SmallStrings.cpp +++ b/Source/JavaScriptCore/runtime/SmallStrings.cpp @@ -31,6 +31,7 @@ #include "JSString.h" #include <wtf/Noncopyable.h> #include <wtf/PassOwnPtr.h> +#include <wtf/text/StringImpl.h> namespace JSC { diff --git a/Source/JavaScriptCore/runtime/SmallStrings.h b/Source/JavaScriptCore/runtime/SmallStrings.h index e609c5092..5bc9d2252 100644 --- a/Source/JavaScriptCore/runtime/SmallStrings.h +++ b/Source/JavaScriptCore/runtime/SmallStrings.h @@ -26,8 +26,8 @@ #ifndef SmallStrings_h #define SmallStrings_h -#include "UString.h" #include <wtf/FixedArray.h> +#include <wtf/Noncopyable.h> #include <wtf/OwnPtr.h> #define JSC_COMMON_STRINGS_EACH_NAME(macro) \ @@ -41,6 +41,10 @@ macro(string) \ macro(true) +namespace WTF { +class StringImpl; +} + namespace JSC { class HeapRootVisitor; @@ -71,7 +75,7 @@ namespace JSC { return m_singleCharacterStrings[character]; } - JS_EXPORT_PRIVATE StringImpl* singleCharacterStringRep(unsigned char character); + JS_EXPORT_PRIVATE WTF::StringImpl* singleCharacterStringRep(unsigned char character); void finalizeSmallStrings(); diff --git a/Source/JavaScriptCore/runtime/StorageBarrier.h b/Source/JavaScriptCore/runtime/StorageBarrier.h index 2a0c842ba..1fae82091 100644 --- a/Source/JavaScriptCore/runtime/StorageBarrier.h +++ b/Source/JavaScriptCore/runtime/StorageBarrier.h @@ -66,6 +66,8 @@ public: ConstPropertyStorage get() const { return m_storage; } PropertyStorage get() { return m_storage; } + + bool operator!() { return !m_storage; } private: PropertyStorage m_storage; diff --git a/Source/JavaScriptCore/runtime/StrictEvalActivation.cpp b/Source/JavaScriptCore/runtime/StrictEvalActivation.cpp index 8b47a5d70..b1f28c8aa 100644 --- a/Source/JavaScriptCore/runtime/StrictEvalActivation.cpp +++ b/Source/JavaScriptCore/runtime/StrictEvalActivation.cpp @@ -26,6 +26,8 @@ #include "config.h" #include "StrictEvalActivation.h" +#include "JSGlobalObject.h" + namespace JSC { ASSERT_HAS_TRIVIAL_DESTRUCTOR(StrictEvalActivation); @@ -33,7 +35,11 @@ ASSERT_HAS_TRIVIAL_DESTRUCTOR(StrictEvalActivation); const ClassInfo StrictEvalActivation::s_info = { "Object", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(StrictEvalActivation) }; StrictEvalActivation::StrictEvalActivation(ExecState* exec) - : JSNonFinalObject(exec->globalData(), exec->globalData().strictEvalActivationStructure.get()) + : Base( + exec->globalData(), + exec->lexicalGlobalObject()->strictEvalActivationStructure(), + exec->scope() + ) { } diff --git a/Source/JavaScriptCore/runtime/StrictEvalActivation.h b/Source/JavaScriptCore/runtime/StrictEvalActivation.h index d73eedf5a..9f64feb15 100644 --- a/Source/JavaScriptCore/runtime/StrictEvalActivation.h +++ b/Source/JavaScriptCore/runtime/StrictEvalActivation.h @@ -26,13 +26,13 @@ #ifndef StrictEvalActivation_h #define StrictEvalActivation_h -#include "JSObject.h" +#include "JSScope.h" namespace JSC { -class StrictEvalActivation : public JSNonFinalObject { +class StrictEvalActivation : public JSScope { public: - typedef JSNonFinalObject Base; + typedef JSScope Base; static StrictEvalActivation* create(ExecState* exec) { @@ -52,7 +52,7 @@ public: static const ClassInfo s_info; protected: - static const unsigned StructureFlags = IsEnvironmentRecord | JSNonFinalObject::StructureFlags; + static const unsigned StructureFlags = IsEnvironmentRecord | Base::StructureFlags; private: StrictEvalActivation(ExecState*); diff --git a/Source/JavaScriptCore/runtime/StringObject.cpp b/Source/JavaScriptCore/runtime/StringObject.cpp index 3c037bcd1..113dee165 100644 --- a/Source/JavaScriptCore/runtime/StringObject.cpp +++ b/Source/JavaScriptCore/runtime/StringObject.cpp @@ -85,27 +85,27 @@ bool StringObject::defineOwnProperty(JSObject* object, ExecState* exec, Property if (propertyName == exec->propertyNames().length) { if (!object->isExtensible()) { if (throwException) - throwError(exec, createTypeError(exec, "Attempting to define property on object that is not extensible.")); + throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to define property on object that is not extensible."))); return false; } if (descriptor.configurablePresent() && descriptor.configurable()) { if (throwException) - throwError(exec, createTypeError(exec, "Attempting to configurable attribute of unconfigurable property.")); + throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to configurable attribute of unconfigurable property."))); return false; } if (descriptor.enumerablePresent() && descriptor.enumerable()) { if (throwException) - throwError(exec, createTypeError(exec, "Attempting to change enumerable attribute of unconfigurable property.")); + throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change enumerable attribute of unconfigurable property."))); return false; } if (descriptor.isAccessorDescriptor()) { if (throwException) - throwError(exec, createTypeError(exec, "Attempting to change access mechanism for an unconfigurable property.")); + throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change access mechanism for an unconfigurable property."))); return false; } if (descriptor.writablePresent() && descriptor.writable()) { if (throwException) - throwError(exec, createTypeError(exec, "Attempting to change writable attribute of unconfigurable property.")); + throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change writable attribute of unconfigurable property."))); return false; } if (!descriptor.value()) @@ -113,7 +113,7 @@ bool StringObject::defineOwnProperty(JSObject* object, ExecState* exec, Property if (propertyName == exec->propertyNames().length && sameValue(exec, descriptor.value(), jsNumber(thisObject->internalValue()->length()))) return true; if (throwException) - throwError(exec, createTypeError(exec, "Attempting to change value of a readonly property.")); + throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change value of a readonly property."))); return false; } @@ -138,7 +138,7 @@ void StringObject::getOwnPropertyNames(JSObject* object, ExecState* exec, Proper StringObject* thisObject = jsCast<StringObject*>(object); int size = thisObject->internalValue()->length(); for (int i = 0; i < size; ++i) - propertyNames.add(Identifier(exec, UString::number(i))); + propertyNames.add(Identifier(exec, String::number(i))); if (mode == IncludeDontEnumProperties) propertyNames.add(exec->propertyNames().length); return JSObject::getOwnPropertyNames(thisObject, exec, propertyNames, mode); diff --git a/Source/JavaScriptCore/runtime/StringPrototype.cpp b/Source/JavaScriptCore/runtime/StringPrototype.cpp index 001e5e8b0..73633a60b 100644 --- a/Source/JavaScriptCore/runtime/StringPrototype.cpp +++ b/Source/JavaScriptCore/runtime/StringPrototype.cpp @@ -162,7 +162,7 @@ bool StringPrototype::getOwnPropertyDescriptor(JSObject* object, ExecState* exec // Helper for producing a JSString for 'string', where 'string' was been produced by // calling ToString on 'originalValue'. In cases where 'originalValue' already was a // string primitive we can just use this, otherwise we need to allocate a new JSString. -static inline JSString* jsStringWithReuse(ExecState* exec, JSValue originalValue, const UString& string) +static inline JSString* jsStringWithReuse(ExecState* exec, JSValue originalValue, const String& string) { if (originalValue.isString()) { ASSERT(asString(originalValue)->value(exec) == string); @@ -172,7 +172,7 @@ static inline JSString* jsStringWithReuse(ExecState* exec, JSValue originalValue } template <typename CharType> -static NEVER_INLINE UString substituteBackreferencesSlow(const UString& replacement, const UString& source, const int* ovector, RegExp* reg, size_t i) +static NEVER_INLINE String substituteBackreferencesSlow(const String& replacement, const String& source, const int* ovector, RegExp* reg, size_t i) { Vector<CharType> substitutedReplacement; int offset = 0; @@ -184,7 +184,7 @@ static NEVER_INLINE UString substituteBackreferencesSlow(const UString& replacem if (ref == '$') { // "$$" -> "$" ++i; - substitutedReplacement.append(replacement.getCharacters<CharType>() + offset, i - offset); + substitutedReplacement.append(replacement.getCharactersWithUpconvert<CharType>() + offset, i - offset); offset = i + 1; continue; } @@ -224,21 +224,21 @@ static NEVER_INLINE UString substituteBackreferencesSlow(const UString& replacem continue; if (i - offset) - substitutedReplacement.append(replacement.getCharacters<CharType>() + offset, i - offset); + substitutedReplacement.append(replacement.getCharactersWithUpconvert<CharType>() + offset, i - offset); i += 1 + advance; offset = i + 1; if (backrefStart >= 0) - substitutedReplacement.append(source.getCharacters<CharType>() + backrefStart, backrefLength); + substitutedReplacement.append(source.getCharactersWithUpconvert<CharType>() + backrefStart, backrefLength); } while ((i = replacement.find('$', i + 1)) != notFound); if (replacement.length() - offset) - substitutedReplacement.append(replacement.getCharacters<CharType>() + offset, replacement.length() - offset); + substitutedReplacement.append(replacement.getCharactersWithUpconvert<CharType>() + offset, replacement.length() - offset); substitutedReplacement.shrinkToFit(); - return UString::adopt(substitutedReplacement); + return String::adopt(substitutedReplacement); } -static inline UString substituteBackreferences(const UString& replacement, const UString& source, const int* ovector, RegExp* reg) +static inline String substituteBackreferences(const String& replacement, const String& source, const int* ovector, RegExp* reg) { size_t i = replacement.find('$'); if (UNLIKELY(i != notFound)) { @@ -249,7 +249,7 @@ static inline UString substituteBackreferences(const UString& replacement, const return replacement; } -static inline int localeCompare(const UString& a, const UString& b) +static inline int localeCompare(const String& a, const String& b) { return Collator::userDefault()->collate(reinterpret_cast<const ::UChar*>(a.characters()), a.length(), reinterpret_cast<const ::UChar*>(b.characters()), b.length()); } @@ -270,7 +270,7 @@ public: int length; }; -static ALWAYS_INLINE JSValue jsSpliceSubstrings(ExecState* exec, JSString* sourceVal, const UString& source, const StringRange* substringRanges, int rangeCount) +static ALWAYS_INLINE JSValue jsSpliceSubstrings(ExecState* exec, JSString* sourceVal, const String& source, const StringRange* substringRanges, int rangeCount) { if (rangeCount == 1) { int sourceSize = source.length(); @@ -278,7 +278,7 @@ static ALWAYS_INLINE JSValue jsSpliceSubstrings(ExecState* exec, JSString* sourc int length = substringRanges[0].length; if (position <= 0 && length >= sourceSize) return sourceVal; - // We could call UString::substr, but this would result in redundant checks + // We could call String::substringSharingImpl(), but this would result in redundant checks. return jsString(exec, StringImpl::create(source.impl(), max(0, position), min(sourceSize, length))); } @@ -287,7 +287,7 @@ static ALWAYS_INLINE JSValue jsSpliceSubstrings(ExecState* exec, JSString* sourc totalLength += substringRanges[i].length; if (!totalLength) - return jsString(exec, ""); + return jsEmptyString(exec); if (source.is8Bit()) { LChar* buffer; @@ -325,7 +325,7 @@ static ALWAYS_INLINE JSValue jsSpliceSubstrings(ExecState* exec, JSString* sourc return jsString(exec, impl.release()); } -static ALWAYS_INLINE JSValue jsSpliceSubstringsWithSeparators(ExecState* exec, JSString* sourceVal, const UString& source, const StringRange* substringRanges, int rangeCount, const UString* separators, int separatorCount) +static ALWAYS_INLINE JSValue jsSpliceSubstringsWithSeparators(ExecState* exec, JSString* sourceVal, const String& source, const StringRange* substringRanges, int rangeCount, const String* separators, int separatorCount) { if (rangeCount == 1 && separatorCount == 0) { int sourceSize = source.length(); @@ -333,7 +333,7 @@ static ALWAYS_INLINE JSValue jsSpliceSubstringsWithSeparators(ExecState* exec, J int length = substringRanges[0].length; if (position <= 0 && length >= sourceSize) return sourceVal; - // We could call UString::substr, but this would result in redundant checks + // We could call String::substringSharingImpl(), but this would result in redundant checks. return jsString(exec, StringImpl::create(source.impl(), max(0, position), min(sourceSize, length))); } @@ -348,7 +348,7 @@ static ALWAYS_INLINE JSValue jsSpliceSubstringsWithSeparators(ExecState* exec, J } if (!totalLength) - return jsString(exec, ""); + return jsEmptyString(exec); if (source.is8Bit() && allSeperators8Bit) { LChar* buffer; @@ -403,7 +403,7 @@ static ALWAYS_INLINE JSValue jsSpliceSubstringsWithSeparators(ExecState* exec, J return jsString(exec, impl.release()); } -static NEVER_INLINE EncodedJSValue removeUsingRegExpSearch(ExecState* exec, JSString* string, const UString& source, RegExp* regExp) +static NEVER_INLINE EncodedJSValue removeUsingRegExpSearch(ExecState* exec, JSString* string, const String& source, RegExp* regExp) { size_t lastIndex = 0; unsigned startPosition = 0; @@ -444,13 +444,13 @@ static NEVER_INLINE EncodedJSValue removeUsingRegExpSearch(ExecState* exec, JSSt static NEVER_INLINE EncodedJSValue replaceUsingRegExpSearch(ExecState* exec, JSString* string, JSValue searchValue) { JSValue replaceValue = exec->argument(1); - UString replacementString; + String replacementString; CallData callData; CallType callType = getCallData(replaceValue, callData); if (callType == CallTypeNone) replacementString = replaceValue.toString(exec)->value(exec); - const UString& source = string->value(exec); + const String& source = string->value(exec); unsigned sourceLen = source.length(); if (exec->hadException()) return JSValue::encode(JSValue()); @@ -474,7 +474,7 @@ static NEVER_INLINE EncodedJSValue replaceUsingRegExpSearch(ExecState* exec, JSS unsigned startPosition = 0; Vector<StringRange, 16> sourceRanges; - Vector<UString, 16> replacements; + Vector<String, 16> replacements; // This is either a loop (if global is set) or a one-way (if not). if (global && callType == CallTypeJS) { @@ -601,7 +601,7 @@ static NEVER_INLINE EncodedJSValue replaceUsingRegExpSearch(ExecState* exec, JSS if (replLen) replacements.append(substituteBackreferences(replacementString, source, ovector, regExp)); else - replacements.append(UString()); + replacements.append(String()); } } @@ -628,8 +628,8 @@ static NEVER_INLINE EncodedJSValue replaceUsingRegExpSearch(ExecState* exec, JSS static inline EncodedJSValue replaceUsingStringSearch(ExecState* exec, JSString* jsString, JSValue searchValue) { - const UString& string = jsString->value(exec); - UString searchString = searchValue.toUString(exec); + const String& string = jsString->value(exec); + String searchString = searchValue.toString(exec)->value(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); @@ -651,19 +651,19 @@ static inline EncodedJSValue replaceUsingStringSearch(ExecState* exec, JSString* return JSValue::encode(jsUndefined()); } - UString replaceString = replaceValue.toUString(exec); + String replaceString = replaceValue.toString(exec)->value(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); StringImpl* stringImpl = string.impl(); - UString leftPart(StringImpl::create(stringImpl, 0, matchStart)); + String leftPart(StringImpl::create(stringImpl, 0, matchStart)); size_t matchEnd = matchStart + searchString.impl()->length(); int ovector[2] = { matchStart, matchEnd}; - UString middlePart = substituteBackreferences(replaceString, string, ovector, 0); + String middlePart = substituteBackreferences(replaceString, string, ovector, 0); size_t leftLength = stringImpl->length() - matchEnd; - UString rightPart(StringImpl::create(stringImpl, matchEnd, leftLength)); + String rightPart(StringImpl::create(stringImpl, matchEnd, leftLength)); return JSValue::encode(JSC::jsString(exec, leftPart, middlePart, rightPart)); } @@ -699,7 +699,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncCharAt(ExecState* exec) JSValue thisValue = exec->hostThisValue(); if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); - UString s = thisValue.toString(exec)->value(exec); + String s = thisValue.toString(exec)->value(exec); unsigned len = s.length(); JSValue a0 = exec->argument(0); if (a0.isUInt32()) { @@ -719,7 +719,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncCharCodeAt(ExecState* exec) JSValue thisValue = exec->hostThisValue(); if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); - UString s = thisValue.toString(exec)->value(exec); + String s = thisValue.toString(exec)->value(exec); unsigned len = s.length(); JSValue a0 = exec->argument(0); if (a0.isUInt32()) { @@ -753,11 +753,11 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState* exec) JSValue thisValue = exec->hostThisValue(); if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); - UString s = thisValue.toString(exec)->value(exec); + String s = thisValue.toString(exec)->value(exec); JSValue a0 = exec->argument(0); JSValue a1 = exec->argument(1); - UString u2 = a0.toString(exec)->value(exec); + String u2 = a0.toString(exec)->value(exec); size_t result; if (a1.isUndefined()) @@ -788,13 +788,13 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncLastIndexOf(ExecState* exec) JSValue thisValue = exec->hostThisValue(); if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); - UString s = thisValue.toString(exec)->value(exec); + String s = thisValue.toString(exec)->value(exec); int len = s.length(); JSValue a0 = exec->argument(0); JSValue a1 = exec->argument(1); - UString u2 = a0.toString(exec)->value(exec); + String u2 = a0.toString(exec)->value(exec); double dpos = a1.toIntegerPreserveNaN(exec); if (dpos < 0) dpos = 0; @@ -813,7 +813,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec) if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); JSString* string = thisValue.toString(exec); - UString s = string->value(exec); + String s = string->value(exec); JSGlobalData* globalData = &exec->globalData(); JSValue a0 = exec->argument(0); @@ -836,7 +836,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec) * replaced with the result of the expression new RegExp(regexp). * Per ECMA 15.10.4.1, if a0 is undefined substitute the empty string. */ - regExp = RegExp::create(exec->globalData(), a0.isUndefined() ? UString("") : a0.toString(exec)->value(exec), NoFlags); + regExp = RegExp::create(exec->globalData(), a0.isUndefined() ? String("") : a0.toString(exec)->value(exec), NoFlags); if (!regExp->isValid()) return throwVMError(exec, createSyntaxError(exec, regExp->errorMessage())); } @@ -872,7 +872,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState* exec) if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); JSString* string = thisValue.toString(exec); - UString s = string->value(exec); + String s = string->value(exec); JSGlobalData* globalData = &exec->globalData(); JSValue a0 = exec->argument(0); @@ -887,7 +887,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState* exec) * replaced with the result of the expression new RegExp(regexp). * Per ECMA 15.10.4.1, if a0 is undefined substitute the empty string. */ - reg = RegExp::create(exec->globalData(), a0.isUndefined() ? UString("") : a0.toString(exec)->value(exec), NoFlags); + reg = RegExp::create(exec->globalData(), a0.isUndefined() ? String("") : a0.toString(exec)->value(exec), NoFlags); if (!reg->isValid()) return throwVMError(exec, createSyntaxError(exec, reg->errorMessage())); } @@ -901,7 +901,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSlice(ExecState* exec) JSValue thisValue = exec->hostThisValue(); if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); - UString s = thisValue.toString(exec)->value(exec); + String s = thisValue.toString(exec)->value(exec); int len = s.length(); JSValue a0 = exec->argument(0); @@ -925,7 +925,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSlice(ExecState* exec) // Return true in case of early return (resultLength got to limitLength). template<typename CharacterType> -static ALWAYS_INLINE bool splitStringByOneCharacterImpl(ExecState* exec, JSArray* result, const UString& input, StringImpl* string, UChar separatorCharacter, size_t& position, unsigned& resultLength, unsigned limitLength) +static ALWAYS_INLINE bool splitStringByOneCharacterImpl(ExecState* exec, JSArray* result, const String& input, StringImpl* string, UChar separatorCharacter, size_t& position, unsigned& resultLength, unsigned limitLength) { // 12. Let q = p. size_t matchPosition; @@ -939,7 +939,7 @@ static ALWAYS_INLINE bool splitStringByOneCharacterImpl(ExecState* exec, JSArray // through q (exclusive). // 2. Call the [[DefineOwnProperty]] internal method of A with arguments ToString(lengthA), // Property Descriptor {[[Value]]: T, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false. - result->putDirectIndex(exec, resultLength, jsSubstring(exec, input, position, matchPosition - position), false); + result->putDirectIndex(exec, resultLength, jsSubstring(exec, input, position, matchPosition - position)); // 3. Increment lengthA by 1. // 4. If lengthA == lim, return A. if (++resultLength == limitLength) @@ -962,7 +962,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec) // 2. Let S be the result of calling ToString, giving it the this value as its argument. // 6. Let s be the number of characters in S. - UString input = thisValue.toString(exec)->value(exec); + String input = thisValue.toString(exec)->value(exec); // 3. Let A be a new array created as if by the expression new Array() // where Array is the standard built-in constructor with that name. @@ -993,7 +993,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec) if (separatorValue.isUndefined()) { // a. Call the [[DefineOwnProperty]] internal method of A with arguments "0", // Property Descriptor {[[Value]]: S, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false. - result->putDirectIndex(exec, 0, jsStringWithReuse(exec, thisValue, input), false); + result->putDirectIndex(exec, 0, jsStringWithReuse(exec, thisValue, input)); // b. Return A. return JSValue::encode(result); } @@ -1006,7 +1006,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec) // Property Descriptor {[[Value]]: S, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false. // d. Return A. if (!reg->match(*globalData, input, 0)) - result->putDirectIndex(exec, 0, jsStringWithReuse(exec, thisValue, input), false); + result->putDirectIndex(exec, 0, jsStringWithReuse(exec, thisValue, input)); return JSValue::encode(result); } @@ -1037,7 +1037,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec) // through q (exclusive). // 2. Call the [[DefineOwnProperty]] internal method of A with arguments ToString(lengthA), // Property Descriptor {[[Value]]: T, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false. - result->putDirectIndex(exec, resultLength, jsSubstring(exec, input, position, matchPosition - position), false); + result->putDirectIndex(exec, resultLength, jsSubstring(exec, input, position, matchPosition - position)); // 3. Increment lengthA by 1. // 4. If lengthA == lim, return A. if (++resultLength == limit) @@ -1056,7 +1056,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec) // ToString(lengthA), Property Descriptor {[[Value]]: cap[i], [[Writable]]: // true, [[Enumerable]]: true, [[Configurable]]: true}, and false. int sub = ovector[i * 2]; - result->putDirectIndex(exec, resultLength, sub < 0 ? jsUndefined() : jsSubstring(exec, input, sub, ovector[i * 2 + 1] - sub), false); + result->putDirectIndex(exec, resultLength, sub < 0 ? jsUndefined() : jsSubstring(exec, input, sub, ovector[i * 2 + 1] - sub)); // c Increment lengthA by 1. // d If lengthA == lim, return A. if (++resultLength == limit) @@ -1064,7 +1064,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec) } } } else { - UString separator = separatorValue.toString(exec)->value(exec); + String separator = separatorValue.toString(exec)->value(exec); // 9. If lim == 0, return A. if (!limit) @@ -1075,7 +1075,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec) if (separatorValue.isUndefined()) { // a. Call the [[DefineOwnProperty]] internal method of A with arguments "0", // Property Descriptor {[[Value]]: S, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false. - result->putDirectIndex(exec, 0, jsStringWithReuse(exec, thisValue, input), false); + result->putDirectIndex(exec, 0, jsStringWithReuse(exec, thisValue, input)); // b. Return A. return JSValue::encode(result); } @@ -1088,7 +1088,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec) // Property Descriptor {[[Value]]: S, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false. // d. Return A. if (!separator.isEmpty()) - result->putDirectIndex(exec, 0, jsStringWithReuse(exec, thisValue, input), false); + result->putDirectIndex(exec, 0, jsStringWithReuse(exec, thisValue, input)); return JSValue::encode(result); } @@ -1099,7 +1099,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec) ASSERT(limit); do { - result->putDirectIndex(exec, position, jsSingleCharacterSubstring(exec, input, position), false); + result->putDirectIndex(exec, position, jsSingleCharacterSubstring(exec, input, position)); } while (++position < limit); return JSValue::encode(result); @@ -1139,7 +1139,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec) // through q (exclusive). // 2. Call the [[DefineOwnProperty]] internal method of A with arguments ToString(lengthA), // Property Descriptor {[[Value]]: T, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false. - result->putDirectIndex(exec, resultLength, jsSubstring(exec, input, position, matchPosition - position), false); + result->putDirectIndex(exec, resultLength, jsSubstring(exec, input, position, matchPosition - position)); // 3. Increment lengthA by 1. // 4. If lengthA == lim, return A. if (++resultLength == limit) @@ -1156,7 +1156,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec) // through s (exclusive). // 15. Call the [[DefineOwnProperty]] internal method of A with arguments ToString(lengthA), Property Descriptor // {[[Value]]: T, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false. - result->putDirectIndex(exec, resultLength++, jsSubstring(exec, input, position, input.length() - position), false); + result->putDirectIndex(exec, resultLength++, jsSubstring(exec, input, position, input.length() - position)); // 16. Return A. return JSValue::encode(result); @@ -1167,7 +1167,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSubstr(ExecState* exec) JSValue thisValue = exec->hostThisValue(); unsigned len; JSString* jsString = 0; - UString uString; + String uString; if (thisValue.isString()) { jsString = jsCast<JSString*>(thisValue.asCell()); len = jsString->length(); @@ -1247,7 +1247,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncToLowerCase(ExecState* exec) if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); JSString* sVal = thisValue.toString(exec); - const UString& s = sVal->value(exec); + const String& s = sVal->value(exec); int sSize = s.length(); if (!sSize) @@ -1257,7 +1257,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncToLowerCase(ExecState* exec) RefPtr<StringImpl> lower = ourImpl->lower(); if (ourImpl == lower) return JSValue::encode(sVal); - return JSValue::encode(jsString(exec, UString(lower.release()))); + return JSValue::encode(jsString(exec, String(lower.release()))); } EncodedJSValue JSC_HOST_CALL stringProtoFuncToUpperCase(ExecState* exec) @@ -1266,7 +1266,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncToUpperCase(ExecState* exec) if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); JSString* sVal = thisValue.toString(exec); - const UString& s = sVal->value(exec); + const String& s = sVal->value(exec); int sSize = s.length(); if (!sSize) @@ -1276,7 +1276,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncToUpperCase(ExecState* exec) RefPtr<StringImpl> upper = sImpl->upper(); if (sImpl == upper) return JSValue::encode(sVal); - return JSValue::encode(jsString(exec, UString(upper.release()))); + return JSValue::encode(jsString(exec, String(upper.release()))); } EncodedJSValue JSC_HOST_CALL stringProtoFuncLocaleCompare(ExecState* exec) @@ -1287,7 +1287,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncLocaleCompare(ExecState* exec) JSValue thisValue = exec->hostThisValue(); if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); - UString s = thisValue.toString(exec)->value(exec); + String s = thisValue.toString(exec)->value(exec); JSValue a0 = exec->argument(0); return JSValue::encode(jsNumber(localeCompare(s, a0.toString(exec)->value(exec)))); @@ -1298,7 +1298,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncBig(ExecState* exec) JSValue thisValue = exec->hostThisValue(); if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); - UString s = thisValue.toString(exec)->value(exec); + String s = thisValue.toString(exec)->value(exec); return JSValue::encode(jsMakeNontrivialString(exec, "<big>", s, "</big>")); } @@ -1307,7 +1307,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSmall(ExecState* exec) JSValue thisValue = exec->hostThisValue(); if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); - UString s = thisValue.toString(exec)->value(exec); + String s = thisValue.toString(exec)->value(exec); return JSValue::encode(jsMakeNontrivialString(exec, "<small>", s, "</small>")); } @@ -1316,7 +1316,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncBlink(ExecState* exec) JSValue thisValue = exec->hostThisValue(); if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); - UString s = thisValue.toString(exec)->value(exec); + String s = thisValue.toString(exec)->value(exec); return JSValue::encode(jsMakeNontrivialString(exec, "<blink>", s, "</blink>")); } @@ -1325,7 +1325,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncBold(ExecState* exec) JSValue thisValue = exec->hostThisValue(); if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); - UString s = thisValue.toString(exec)->value(exec); + String s = thisValue.toString(exec)->value(exec); return JSValue::encode(jsMakeNontrivialString(exec, "<b>", s, "</b>")); } @@ -1334,7 +1334,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncFixed(ExecState* exec) JSValue thisValue = exec->hostThisValue(); if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); - UString s = thisValue.toString(exec)->value(exec); + String s = thisValue.toString(exec)->value(exec); return JSValue::encode(jsMakeNontrivialString(exec, "<tt>", s, "</tt>")); } @@ -1343,7 +1343,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncItalics(ExecState* exec) JSValue thisValue = exec->hostThisValue(); if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); - UString s = thisValue.toString(exec)->value(exec); + String s = thisValue.toString(exec)->value(exec); return JSValue::encode(jsMakeNontrivialString(exec, "<i>", s, "</i>")); } @@ -1352,7 +1352,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncStrike(ExecState* exec) JSValue thisValue = exec->hostThisValue(); if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); - UString s = thisValue.toString(exec)->value(exec); + String s = thisValue.toString(exec)->value(exec); return JSValue::encode(jsMakeNontrivialString(exec, "<strike>", s, "</strike>")); } @@ -1361,7 +1361,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSub(ExecState* exec) JSValue thisValue = exec->hostThisValue(); if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); - UString s = thisValue.toString(exec)->value(exec); + String s = thisValue.toString(exec)->value(exec); return JSValue::encode(jsMakeNontrivialString(exec, "<sub>", s, "</sub>")); } @@ -1370,7 +1370,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSup(ExecState* exec) JSValue thisValue = exec->hostThisValue(); if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); - UString s = thisValue.toString(exec)->value(exec); + String s = thisValue.toString(exec)->value(exec); return JSValue::encode(jsMakeNontrivialString(exec, "<sup>", s, "</sup>")); } @@ -1379,7 +1379,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncFontcolor(ExecState* exec) JSValue thisValue = exec->hostThisValue(); if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); - UString s = thisValue.toString(exec)->value(exec); + String s = thisValue.toString(exec)->value(exec); JSValue a0 = exec->argument(0); return JSValue::encode(jsMakeNontrivialString(exec, "<font color=\"", a0.toString(exec)->value(exec), "\">", s, "</font>")); } @@ -1389,7 +1389,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec) JSValue thisValue = exec->hostThisValue(); if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); - UString s = thisValue.toString(exec)->value(exec); + String s = thisValue.toString(exec)->value(exec); JSValue a0 = exec->argument(0); uint32_t smallInteger; @@ -1434,7 +1434,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncAnchor(ExecState* exec) JSValue thisValue = exec->hostThisValue(); if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); - UString s = thisValue.toString(exec)->value(exec); + String s = thisValue.toString(exec)->value(exec); JSValue a0 = exec->argument(0); return JSValue::encode(jsMakeNontrivialString(exec, "<a name=\"", a0.toString(exec)->value(exec), "\">", s, "</a>")); } @@ -1444,9 +1444,9 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec) JSValue thisValue = exec->hostThisValue(); if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwVMTypeError(exec); - UString s = thisValue.toString(exec)->value(exec); + String s = thisValue.toString(exec)->value(exec); JSValue a0 = exec->argument(0); - UString linkText = a0.toString(exec)->value(exec); + String linkText = a0.toString(exec)->value(exec); unsigned linkTextSize = linkText.length(); unsigned stringSize = s.length(); @@ -1489,7 +1489,7 @@ static inline JSValue trimString(ExecState* exec, JSValue thisValue, int trimKin { if (thisValue.isUndefinedOrNull()) // CheckObjectCoercible return throwTypeError(exec); - UString str = thisValue.toString(exec)->value(exec); + String str = thisValue.toString(exec)->value(exec); unsigned left = 0; if (trimKind & TrimLeft) { while (left < str.length() && isTrimWhitespace(str[left])) diff --git a/Source/JavaScriptCore/runtime/Structure.cpp b/Source/JavaScriptCore/runtime/Structure.cpp index e02105826..4c8ee8741 100644 --- a/Source/JavaScriptCore/runtime/Structure.cpp +++ b/Source/JavaScriptCore/runtime/Structure.cpp @@ -762,32 +762,24 @@ void Structure::visitChildren(JSCell* cell, SlotVisitor& visitor) Structure* thisObject = jsCast<Structure*>(cell); ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); + JSCell::visitChildren(thisObject, visitor); - if (thisObject->m_globalObject) - visitor.append(&thisObject->m_globalObject); + visitor.append(&thisObject->m_globalObject); if (!thisObject->isObject()) thisObject->m_cachedPrototypeChain.clear(); else { - if (thisObject->m_prototype) - visitor.append(&thisObject->m_prototype); - if (thisObject->m_cachedPrototypeChain) - visitor.append(&thisObject->m_cachedPrototypeChain); + visitor.append(&thisObject->m_prototype); + visitor.append(&thisObject->m_cachedPrototypeChain); } - if (thisObject->m_previous) - visitor.append(&thisObject->m_previous); - if (thisObject->m_specificValueInPrevious) - visitor.append(&thisObject->m_specificValueInPrevious); - if (thisObject->m_enumerationCache) - visitor.append(&thisObject->m_enumerationCache); + visitor.append(&thisObject->m_previous); + visitor.append(&thisObject->m_specificValueInPrevious); + visitor.append(&thisObject->m_enumerationCache); if (thisObject->m_propertyTable) { PropertyTable::iterator end = thisObject->m_propertyTable->end(); - for (PropertyTable::iterator ptr = thisObject->m_propertyTable->begin(); ptr != end; ++ptr) { - if (ptr->specificValue) - visitor.append(&ptr->specificValue); - } + for (PropertyTable::iterator ptr = thisObject->m_propertyTable->begin(); ptr != end; ++ptr) + visitor.append(&ptr->specificValue); } - if (thisObject->m_objectToStringValue) - visitor.append(&thisObject->m_objectToStringValue); + visitor.append(&thisObject->m_objectToStringValue); } #if DO_PROPERTYMAP_CONSTENCY_CHECK diff --git a/Source/JavaScriptCore/runtime/Structure.h b/Source/JavaScriptCore/runtime/Structure.h index 2bb0107b7..57368bee8 100644 --- a/Source/JavaScriptCore/runtime/Structure.h +++ b/Source/JavaScriptCore/runtime/Structure.h @@ -36,12 +36,12 @@ #include "Protect.h" #include "StructureTransitionTable.h" #include "JSTypeInfo.h" -#include "UString.h" #include "Watchpoint.h" #include "Weak.h" #include <wtf/PassOwnPtr.h> #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> +#include <wtf/text/StringImpl.h> namespace JSC { @@ -259,7 +259,7 @@ namespace JSC { bool masqueradesAsUndefined(JSGlobalObject* lexicalGlobalObject); PropertyOffset get(JSGlobalData&, PropertyName); - PropertyOffset get(JSGlobalData&, const UString& name); + PropertyOffset get(JSGlobalData&, const WTF::String& name); JS_EXPORT_PRIVATE PropertyOffset get(JSGlobalData&, PropertyName, unsigned& attributes, JSCell*& specificValue); bool hasGetterSetterProperties() const { return m_hasGetterSetterProperties; } @@ -501,7 +501,7 @@ namespace JSC { return entry ? entry->offset : invalidOffset; } - inline PropertyOffset Structure::get(JSGlobalData& globalData, const UString& name) + inline PropertyOffset Structure::get(JSGlobalData& globalData, const WTF::String& name) { ASSERT(structure()->classInfo() == &s_info); materializePropertyMapIfNecessary(globalData); @@ -567,6 +567,8 @@ namespace JSC { ALWAYS_INLINE void MarkStack::internalAppend(JSCell* cell) { ASSERT(!m_isCheckingForDefaultMarkViolation); + if (!cell) + return; #if ENABLE(GC_VALIDATION) validate(cell); #endif diff --git a/Source/JavaScriptCore/runtime/StructureTransitionTable.h b/Source/JavaScriptCore/runtime/StructureTransitionTable.h index 2067a8995..7c9d50894 100644 --- a/Source/JavaScriptCore/runtime/StructureTransitionTable.h +++ b/Source/JavaScriptCore/runtime/StructureTransitionTable.h @@ -26,11 +26,11 @@ #ifndef StructureTransitionTable_h #define StructureTransitionTable_h -#include "UString.h" #include "WeakGCMap.h" #include <wtf/HashFunctions.h> #include <wtf/OwnPtr.h> #include <wtf/RefPtr.h> +#include <wtf/text/StringImpl.h> namespace JSC { diff --git a/Source/JavaScriptCore/runtime/SymbolTable.cpp b/Source/JavaScriptCore/runtime/SymbolTable.cpp index 2a9d71629..1b7fd89c5 100644 --- a/Source/JavaScriptCore/runtime/SymbolTable.cpp +++ b/Source/JavaScriptCore/runtime/SymbolTable.cpp @@ -31,6 +31,8 @@ namespace JSC { +const ClassInfo SharedSymbolTable::s_info = { "SharedSymbolTable", 0, 0, 0, CREATE_METHOD_TABLE(SharedSymbolTable) }; + SymbolTableEntry& SymbolTableEntry::copySlow(const SymbolTableEntry& other) { ASSERT(other.isFat()); @@ -40,6 +42,12 @@ SymbolTableEntry& SymbolTableEntry::copySlow(const SymbolTableEntry& other) return *this; } +void SharedSymbolTable::destroy(JSCell* cell) +{ + SharedSymbolTable* thisObject = jsCast<SharedSymbolTable*>(cell); + thisObject->SharedSymbolTable::~SharedSymbolTable(); +} + void SymbolTableEntry::freeFatEntrySlow() { ASSERT(isFat()); diff --git a/Source/JavaScriptCore/runtime/SymbolTable.h b/Source/JavaScriptCore/runtime/SymbolTable.h index 8b017efbc..08ea8c163 100644 --- a/Source/JavaScriptCore/runtime/SymbolTable.h +++ b/Source/JavaScriptCore/runtime/SymbolTable.h @@ -30,10 +30,10 @@ #define SymbolTable_h #include "JSObject.h" -#include "UString.h" #include "Watchpoint.h" #include <wtf/AlwaysInline.h> #include <wtf/HashTraits.h> +#include <wtf/text/StringImpl.h> namespace JSC { @@ -325,12 +325,28 @@ namespace JSC { typedef HashMap<RefPtr<StringImpl>, SymbolTableEntry, IdentifierRepHash, HashTraits<RefPtr<StringImpl> >, SymbolTableIndexHashTraits> SymbolTable; - class SharedSymbolTable : public SymbolTable, public RefCounted<SharedSymbolTable> { - WTF_MAKE_FAST_ALLOCATED; + class SharedSymbolTable : public JSCell, public SymbolTable { public: - static PassRefPtr<SharedSymbolTable> create() { return adoptRef(new SharedSymbolTable); } + static SharedSymbolTable* create(JSGlobalData& globalData) + { + SharedSymbolTable* sharedSymbolTable = new (NotNull, allocateCell<SharedSymbolTable>(globalData.heap)) SharedSymbolTable(globalData); + sharedSymbolTable->finishCreation(globalData); + return sharedSymbolTable; + } + static void destroy(JSCell*); + + static Structure* createStructure(JSGlobalData& globalData, JSGlobalObject* globalObject, JSValue prototype) + { + return Structure::create(globalData, globalObject, prototype, TypeInfo(LeafType, StructureFlags), &s_info); + } + + static JS_EXPORTDATA const ClassInfo s_info; + private: - SharedSymbolTable() { } + SharedSymbolTable(JSGlobalData& globalData) + : JSCell(globalData, globalData.sharedSymbolTableStructure.get()) + { + } }; } // namespace JSC diff --git a/Source/JavaScriptCore/runtime/UString.cpp b/Source/JavaScriptCore/runtime/UString.cpp deleted file mode 100644 index 5b1e9a0e0..000000000 --- a/Source/JavaScriptCore/runtime/UString.cpp +++ /dev/null @@ -1,475 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) - * Copyright (C) 2009 Google Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "UString.h" - -#include "JSGlobalObjectFunctions.h" -#include "Heap.h" -#include "Identifier.h" -#include "Operations.h" -#include <ctype.h> -#include <limits.h> -#include <limits> -#include <stdio.h> -#include <stdlib.h> -#include <wtf/ASCIICType.h> -#include <wtf/Assertions.h> -#include <wtf/MathExtras.h> -#include <wtf/StringExtras.h> -#include <wtf/Vector.h> -#include <wtf/dtoa.h> -#include <wtf/unicode/UTF8.h> - -#if HAVE(STRINGS_H) -#include <strings.h> -#endif - -using namespace WTF; -using namespace WTF::Unicode; -using namespace std; - -namespace JSC { - -COMPILE_ASSERT(sizeof(UString) == sizeof(void*), UString_should_stay_small); - -// Construct a string with UTF-16 data. -UString::UString(const UChar* characters, unsigned length) - : m_impl(characters ? StringImpl::create(characters, length) : 0) -{ -} - -// Construct a string with UTF-16 data, from a null-terminated source. -UString::UString(const UChar* characters) -{ - if (!characters) - return; - - int length = 0; - while (characters[length] != UChar(0)) - ++length; - - m_impl = StringImpl::create(characters, length); -} - -// Construct a string with latin1 data. -UString::UString(const LChar* characters, unsigned length) - : m_impl(characters ? StringImpl::create(characters, length) : 0) -{ -} - -UString::UString(const char* characters, unsigned length) - : m_impl(characters ? StringImpl::create(reinterpret_cast<const LChar*>(characters), length) : 0) -{ -} - -// Construct a string with latin1 data, from a null-terminated source. -UString::UString(const LChar* characters) - : m_impl(characters ? StringImpl::create(characters) : 0) -{ -} - -UString::UString(const char* characters) - : m_impl(characters ? StringImpl::create(reinterpret_cast<const LChar*>(characters)) : 0) -{ -} - -UString UString::number(int i) -{ - LChar buf[1 + sizeof(i) * 3]; - LChar* end = buf + WTF_ARRAY_LENGTH(buf); - LChar* p = end; - - if (i == 0) - *--p = '0'; - else if (i == INT_MIN) { - char minBuf[1 + sizeof(i) * 3]; - snprintf(minBuf, sizeof(minBuf), "%d", INT_MIN); - return UString(minBuf); - } else { - bool negative = false; - if (i < 0) { - negative = true; - i = -i; - } - while (i) { - *--p = static_cast<unsigned short>((i % 10) + '0'); - i /= 10; - } - if (negative) - *--p = '-'; - } - - return UString(p, static_cast<unsigned>(end - p)); -} - -UString UString::number(long long i) -{ - LChar buf[1 + sizeof(i) * 3]; - LChar* end = buf + WTF_ARRAY_LENGTH(buf); - LChar* p = end; - - if (i == 0) - *--p = '0'; - else if (i == std::numeric_limits<long long>::min()) { - char minBuf[1 + sizeof(i) * 3]; -#if OS(WINDOWS) - snprintf(minBuf, sizeof(minBuf), "%I64d", std::numeric_limits<long long>::min()); -#else - snprintf(minBuf, sizeof(minBuf), "%lld", std::numeric_limits<long long>::min()); -#endif - return UString(minBuf); - } else { - bool negative = false; - if (i < 0) { - negative = true; - i = -i; - } - while (i) { - *--p = static_cast<unsigned short>((i % 10) + '0'); - i /= 10; - } - if (negative) - *--p = '-'; - } - - return UString(p, static_cast<unsigned>(end - p)); -} - -UString UString::number(unsigned u) -{ - LChar buf[sizeof(u) * 3]; - LChar* end = buf + WTF_ARRAY_LENGTH(buf); - LChar* p = end; - - if (u == 0) - *--p = '0'; - else { - while (u) { - *--p = static_cast<unsigned short>((u % 10) + '0'); - u /= 10; - } - } - - return UString(p, static_cast<unsigned>(end - p)); -} - -UString UString::number(long l) -{ - LChar buf[1 + sizeof(l) * 3]; - LChar* end = buf + WTF_ARRAY_LENGTH(buf); - LChar* p = end; - - if (l == 0) - *--p = '0'; - else if (l == LONG_MIN) { - char minBuf[1 + sizeof(l) * 3]; - snprintf(minBuf, sizeof(minBuf), "%ld", LONG_MIN); - return UString(minBuf); - } else { - bool negative = false; - if (l < 0) { - negative = true; - l = -l; - } - while (l) { - *--p = static_cast<unsigned short>((l % 10) + '0'); - l /= 10; - } - if (negative) - *--p = '-'; - } - - return UString(p, end - p); -} - -UString UString::number(double d) -{ - NumberToStringBuffer buffer; - return UString(numberToString(d, buffer)); -} - -UString UString::substringSharingImpl(unsigned offset, unsigned length) const -{ - // FIXME: We used to check against a limit of Heap::minExtraCost / sizeof(UChar). - - unsigned stringLength = this->length(); - offset = min(offset, stringLength); - length = min(length, stringLength - offset); - - if (!offset && length == stringLength) - return *this; - return UString(StringImpl::create(m_impl, offset, length)); -} - -bool operator==(const UString& s1, const char *s2) -{ - if (s1.isEmpty()) - return !s2; - - return equal(s1.impl(), s2); -} - -// This method assumes that all simple checks have been performed by -// the inlined operator==() in the header file. -bool equalSlowCase(const UString& s1, const UString& s2) -{ - StringImpl* rep1 = s1.impl(); - StringImpl* rep2 = s2.impl(); - unsigned size1 = rep1->length(); - - // At this point we know - // (a) that the strings are the same length and - // (b) that they are greater than zero length. - bool s1Is8Bit = rep1->is8Bit(); - bool s2Is8Bit = rep2->is8Bit(); - - if (s1Is8Bit) { - const LChar* d1 = rep1->characters8(); - if (s2Is8Bit) { - const LChar* d2 = rep2->characters8(); - - if (d1 == d2) // Check to see if the data pointers are the same. - return true; - - // Do quick checks for sizes 1 and 2. - switch (size1) { - case 1: - return d1[0] == d2[0]; - case 2: - return (d1[0] == d2[0]) & (d1[1] == d2[1]); - default: - return (!memcmp(d1, d2, size1 * sizeof(LChar))); - } - } - - const UChar* d2 = rep2->characters16(); - - for (unsigned i = 0; i < size1; i++) { - if (d1[i] != d2[i]) - return false; - } - return true; - } - - if (s2Is8Bit) { - const UChar* d1 = rep1->characters16(); - const LChar* d2 = rep2->characters8(); - - for (unsigned i = 0; i < size1; i++) { - if (d1[i] != d2[i]) - return false; - } - return true; - - } - - const UChar* d1 = rep1->characters16(); - const UChar* d2 = rep2->characters16(); - - if (d1 == d2) // Check to see if the data pointers are the same. - return true; - - // Do quick checks for sizes 1 and 2. - switch (size1) { - case 1: - return d1[0] == d2[0]; - case 2: - return (d1[0] == d2[0]) & (d1[1] == d2[1]); - default: - return (!memcmp(d1, d2, size1 * sizeof(UChar))); - } -} - -bool operator<(const UString& s1, const UString& s2) -{ - const unsigned l1 = s1.length(); - const unsigned l2 = s2.length(); - const unsigned lmin = l1 < l2 ? l1 : l2; - if (s1.is8Bit() && s2.is8Bit()) { - const LChar* c1 = s1.characters8(); - const LChar* c2 = s2.characters8(); - unsigned length = 0; - while (length < lmin && *c1 == *c2) { - c1++; - c2++; - length++; - } - if (length < lmin) - return (c1[0] < c2[0]); - - return (l1 < l2); - } - const UChar* c1 = s1.characters(); - const UChar* c2 = s2.characters(); - unsigned length = 0; - while (length < lmin && *c1 == *c2) { - c1++; - c2++; - length++; - } - if (length < lmin) - return (c1[0] < c2[0]); - - return (l1 < l2); -} - -bool operator>(const UString& s1, const UString& s2) -{ - const unsigned l1 = s1.length(); - const unsigned l2 = s2.length(); - const unsigned lmin = l1 < l2 ? l1 : l2; - const UChar* c1 = s1.characters(); - const UChar* c2 = s2.characters(); - unsigned l = 0; - while (l < lmin && *c1 == *c2) { - c1++; - c2++; - l++; - } - if (l < lmin) - return (c1[0] > c2[0]); - - return (l1 > l2); -} - -CString UString::ascii() const -{ - // Basic Latin1 (ISO) encoding - Unicode characters 0..255 are - // preserved, characters outside of this range are converted to '?'. - - unsigned length = this->length(); - - if (this->is8Bit()) { - const LChar* characters = this->characters8(); - - char* characterBuffer; - CString result = CString::newUninitialized(length, characterBuffer); - - for (unsigned i = 0; i < length; ++i) { - LChar ch = characters[i]; - characterBuffer[i] = ch && (ch < 0x20 || ch > 0x7f) ? '?' : ch; - } - - return result; - } - - const UChar* characters = this->characters16(); - - char* characterBuffer; - CString result = CString::newUninitialized(length, characterBuffer); - - for (unsigned i = 0; i < length; ++i) { - UChar ch = characters[i]; - characterBuffer[i] = ch && (ch < 0x20 || ch >= 0x7f) ? '?' : ch; - } - - return result; -} - -CString UString::latin1() const -{ - // Basic Latin1 (ISO) encoding - Unicode characters 0..255 are - // preserved, characters outside of this range are converted to '?'. - - unsigned length = this->length(); - const UChar* characters = this->characters(); - - char* characterBuffer; - CString result = CString::newUninitialized(length, characterBuffer); - - for (unsigned i = 0; i < length; ++i) { - UChar ch = characters[i]; - characterBuffer[i] = ch > 0xff ? '?' : ch; - } - - return result; -} - -// Helper to write a three-byte UTF-8 code point to the buffer, caller must check room is available. -static inline void putUTF8Triple(char*& buffer, UChar ch) -{ - ASSERT(ch >= 0x0800); - *buffer++ = static_cast<char>(((ch >> 12) & 0x0F) | 0xE0); - *buffer++ = static_cast<char>(((ch >> 6) & 0x3F) | 0x80); - *buffer++ = static_cast<char>((ch & 0x3F) | 0x80); -} - -CString UString::utf8(bool strict) const -{ - unsigned length = this->length(); - - if (!length) - return CString("", 0); - - // Allocate a buffer big enough to hold all the characters - // (an individual UTF-16 UChar can only expand to 3 UTF-8 bytes). - // Optimization ideas, if we find this function is hot: - // * We could speculatively create a CStringBuffer to contain 'length' - // characters, and resize if necessary (i.e. if the buffer contains - // non-ascii characters). (Alternatively, scan the buffer first for - // ascii characters, so we know this will be sufficient). - // * We could allocate a CStringBuffer with an appropriate size to - // have a good chance of being able to write the string into the - // buffer without reallocing (say, 1.5 x length). - if (length > numeric_limits<unsigned>::max() / 3) - return CString(); - - Vector<char, 1024> bufferVector(length * 3); - char* buffer = bufferVector.data(); - - if (is8Bit()) { - const LChar* characters = this->characters8(); - - ConversionResult result = convertLatin1ToUTF8(&characters, characters + length, &buffer, buffer + bufferVector.size()); - ASSERT_UNUSED(result, result != targetExhausted); // (length * 3) should be sufficient for any conversion - } else { - const UChar* characters = this->characters16(); - - ConversionResult result = convertUTF16ToUTF8(&characters, characters + length, &buffer, buffer + bufferVector.size(), strict); - ASSERT(result != targetExhausted); // (length * 3) should be sufficient for any conversion - - // Only produced from strict conversion. - if (result == sourceIllegal) - return CString(); - - // Check for an unconverted high surrogate. - if (result == sourceExhausted) { - if (strict) - return CString(); - // This should be one unpaired high surrogate. Treat it the same - // was as an unpaired high surrogate would have been handled in - // the middle of a string with non-strict conversion - which is - // to say, simply encode it to UTF-8. - ASSERT((characters + 1) == (this->characters() + length)); - ASSERT((*characters >= 0xD800) && (*characters <= 0xDBFF)); - // There should be room left, since one UChar hasn't been converted. - ASSERT((buffer + 3) <= (buffer + bufferVector.size())); - putUTF8Triple(buffer, *characters); - } - } - - return CString(bufferVector.data(), buffer - bufferVector.data()); -} - -} // namespace JSC diff --git a/Source/JavaScriptCore/runtime/UString.h b/Source/JavaScriptCore/runtime/UString.h deleted file mode 100644 index 7677161a3..000000000 --- a/Source/JavaScriptCore/runtime/UString.h +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2009 Google Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef UString_h -#define UString_h - -#include <wtf/text/StringImpl.h> - -namespace JSC { - -class UString { -public: - // Construct a null string, distinguishable from an empty string. - UString() { } - - // Construct a string with UTF-16 data. - JS_EXPORT_PRIVATE UString(const UChar* characters, unsigned length); - - // Construct a string with UTF-16 data, from a null-terminated source. - JS_EXPORT_PRIVATE UString(const UChar*); - - // Construct a string with latin1 data. - UString(const LChar* characters, unsigned length); - JS_EXPORT_PRIVATE UString(const char* characters, unsigned length); - - // Construct a string with latin1 data, from a null-terminated source. - UString(const LChar* characters); - JS_EXPORT_PRIVATE UString(const char* characters); - - // Construct a string referencing an existing StringImpl. - UString(StringImpl* impl) : m_impl(impl) { } - UString(PassRefPtr<StringImpl> impl) : m_impl(impl) { } - UString(RefPtr<StringImpl> impl) : m_impl(impl) { } - - // Inline the destructor. - ALWAYS_INLINE ~UString() { } - - void swap(UString& o) { m_impl.swap(o.m_impl); } - - template<typename CharType, size_t inlineCapacity> - static UString adopt(Vector<CharType, inlineCapacity>& vector) { return StringImpl::adopt(vector); } - - bool isNull() const { return !m_impl; } - bool isEmpty() const { return !m_impl || !m_impl->length(); } - - StringImpl* impl() const { return m_impl.get(); } - - unsigned length() const - { - if (!m_impl) - return 0; - return m_impl->length(); - } - - const UChar* characters() const - { - if (!m_impl) - return 0; - return m_impl->characters(); - } - - const LChar* characters8() const - { - if (!m_impl) - return 0; - ASSERT(m_impl->is8Bit()); - return m_impl->characters8(); - } - - const UChar* characters16() const - { - if (!m_impl) - return 0; - ASSERT(!m_impl->is8Bit()); - return m_impl->characters16(); - } - - template <typename CharType> - inline const CharType* getCharacters() const; - - bool is8Bit() const { return m_impl->is8Bit(); } - - JS_EXPORT_PRIVATE CString ascii() const; - CString latin1() const; - JS_EXPORT_PRIVATE CString utf8(bool strict = false) const; - - UChar operator[](unsigned index) const - { - if (!m_impl || index >= m_impl->length()) - return 0; - if (is8Bit()) - return m_impl->characters8()[index]; - return m_impl->characters16()[index]; - } - - JS_EXPORT_PRIVATE static UString number(int); - JS_EXPORT_PRIVATE static UString number(unsigned); - JS_EXPORT_PRIVATE static UString number(long); - static UString number(long long); - JS_EXPORT_PRIVATE static UString number(double); - - // Find a single character or string, also with match function & latin1 forms. - size_t find(UChar c, unsigned start = 0) const - { return m_impl ? m_impl->find(c, start) : notFound; } - - size_t find(const UString& str) const - { return m_impl ? m_impl->find(str.impl()) : notFound; } - size_t find(const UString& str, unsigned start) const - { return m_impl ? m_impl->find(str.impl(), start) : notFound; } - - size_t find(const LChar* str, unsigned start = 0) const - { return m_impl ? m_impl->find(str, start) : notFound; } - - // Find the last instance of a single character or string. - size_t reverseFind(UChar c, unsigned start = UINT_MAX) const - { return m_impl ? m_impl->reverseFind(c, start) : notFound; } - size_t reverseFind(const UString& str, unsigned start = UINT_MAX) const - { return m_impl ? m_impl->reverseFind(str.impl(), start) : notFound; } - - JS_EXPORT_PRIVATE UString substringSharingImpl(unsigned pos, unsigned len = UINT_MAX) const; - -private: - RefPtr<StringImpl> m_impl; -}; - -template<> -inline const LChar* UString::getCharacters<LChar>() const { return characters8(); } - -template<> -inline const UChar* UString::getCharacters<UChar>() const { return characters(); } - -NEVER_INLINE bool equalSlowCase(const UString& s1, const UString& s2); - -ALWAYS_INLINE bool operator==(const UString& s1, const UString& s2) -{ - StringImpl* rep1 = s1.impl(); - StringImpl* rep2 = s2.impl(); - - if (rep1 == rep2) // If they're the same rep, they're equal. - return true; - - unsigned size1 = 0; - unsigned size2 = 0; - - if (rep1) - size1 = rep1->length(); - - if (rep2) - size2 = rep2->length(); - - if (size1 != size2) // If the lengths are not the same, we're done. - return false; - - if (!size1) - return true; - - if (size1 == 1) - return (*rep1)[0u] == (*rep2)[0u]; - - return equalSlowCase(s1, s2); -} - - -inline bool operator!=(const UString& s1, const UString& s2) -{ - return !JSC::operator==(s1, s2); -} - -JS_EXPORT_PRIVATE bool operator<(const UString& s1, const UString& s2); -JS_EXPORT_PRIVATE bool operator>(const UString& s1, const UString& s2); - -JS_EXPORT_PRIVATE bool operator==(const UString& s1, const char* s2); - -inline bool operator!=(const UString& s1, const char* s2) -{ - return !JSC::operator==(s1, s2); -} - -inline bool operator==(const char *s1, const UString& s2) -{ - return operator==(s2, s1); -} - -inline bool operator!=(const char *s1, const UString& s2) -{ - return !JSC::operator==(s1, s2); -} - -inline int codePointCompare(const UString& s1, const UString& s2) -{ - return codePointCompare(s1.impl(), s2.impl()); -} - -struct UStringHash { - static unsigned hash(StringImpl* key) { return key->hash(); } - static bool equal(const StringImpl* a, const StringImpl* b) - { - if (a == b) - return true; - if (!a || !b) - return false; - - unsigned aLength = a->length(); - unsigned bLength = b->length(); - if (aLength != bLength) - return false; - - // FIXME: perhaps we should have a more abstract macro that indicates when - // going 4 bytes at a time is unsafe -#if CPU(ARM) || CPU(SH4) || CPU(MIPS) || CPU(SPARC) - const UChar* aChars = a->characters(); - const UChar* bChars = b->characters(); - for (unsigned i = 0; i != aLength; ++i) { - if (*aChars++ != *bChars++) - return false; - } - return true; -#else - /* Do it 4-bytes-at-a-time on architectures where it's safe */ - const uint32_t* aChars = reinterpret_cast<const uint32_t*>(a->characters()); - const uint32_t* bChars = reinterpret_cast<const uint32_t*>(b->characters()); - - unsigned halfLength = aLength >> 1; - for (unsigned i = 0; i != halfLength; ++i) - if (*aChars++ != *bChars++) - return false; - - if (aLength & 1 && *reinterpret_cast<const uint16_t*>(aChars) != *reinterpret_cast<const uint16_t*>(bChars)) - return false; - - return true; -#endif - } - - static unsigned hash(const RefPtr<StringImpl>& key) { return key->hash(); } - static bool equal(const RefPtr<StringImpl>& a, const RefPtr<StringImpl>& b) - { - return equal(a.get(), b.get()); - } - - static unsigned hash(const UString& key) { return key.impl()->hash(); } - static bool equal(const UString& a, const UString& b) - { - return equal(a.impl(), b.impl()); - } - - static const bool safeToCompareToEmptyOrDeleted = false; -}; - -} // namespace JSC - -namespace WTF { - -// UStringHash is the default hash for UString -template<typename T> struct DefaultHash; -template<> struct DefaultHash<JSC::UString> { - typedef JSC::UStringHash Hash; -}; - -template <> struct VectorTraits<JSC::UString> : SimpleClassVectorTraits { }; - -} // namespace WTF - -#endif - diff --git a/Source/JavaScriptCore/runtime/UStringConcatenate.h b/Source/JavaScriptCore/runtime/UStringConcatenate.h deleted file mode 100644 index cbd4e60ca..000000000 --- a/Source/JavaScriptCore/runtime/UStringConcatenate.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 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 UStringConcatenate_h -#define UStringConcatenate_h - -#include "UString.h" -#include <wtf/text/StringConcatenate.h> - -namespace WTF { - -template<> -class StringTypeAdapter<JSC::UString> { -public: - StringTypeAdapter<JSC::UString>(JSC::UString& string) - : m_string(string) - , m_length(string.length()) - { - } - - unsigned length() { return m_length; } - - bool is8Bit() { return m_string.isNull() || m_string.is8Bit(); } - - void writeTo(LChar* destination) - { - const LChar* characters = m_string.characters8(); - for (unsigned i = 0; i < m_length; ++i) - destination[i] = characters[i]; - } - - void writeTo(UChar* destination) - { - if (is8Bit()) { - const LChar* characters = m_string.characters8(); - for (unsigned i = 0; i < m_length; ++i) - destination[i] = characters[i]; - } else { - const UChar* characters = m_string.characters16(); - for (unsigned i = 0; i < m_length; ++i) - destination[i] = characters[i]; - } - } - -private: - const JSC::UString& m_string; - unsigned m_length; -}; - -}; // namespace WTF - -namespace JSC { - -template<typename StringType1, typename StringType2> -UString makeUString(StringType1 string1, StringType2 string2) -{ - PassRefPtr<StringImpl> resultImpl = WTF::tryMakeString(string1, string2); - if (!resultImpl) - CRASH(); - return resultImpl; -} - -template<typename StringType1, typename StringType2, typename StringType3> -UString makeUString(StringType1 string1, StringType2 string2, StringType3 string3) -{ - PassRefPtr<StringImpl> resultImpl = WTF::tryMakeString(string1, string2, string3); - if (!resultImpl) - CRASH(); - return resultImpl; -} - -template<typename StringType1, typename StringType2, typename StringType3, typename StringType4> -UString makeUString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4) -{ - PassRefPtr<StringImpl> resultImpl = WTF::tryMakeString(string1, string2, string3, string4); - if (!resultImpl) - CRASH(); - return resultImpl; -} - -template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5> -UString makeUString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5) -{ - PassRefPtr<StringImpl> resultImpl = WTF::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 makeUString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6) -{ - PassRefPtr<StringImpl> resultImpl = WTF::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 makeUString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7) -{ - PassRefPtr<StringImpl> resultImpl = WTF::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 makeUString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8) -{ - PassRefPtr<StringImpl> resultImpl = WTF::tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8); - if (!resultImpl) - CRASH(); - return resultImpl; -} - -} // namespace JSC - -#endif |