summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'JavaScriptCore/runtime')
-rw-r--r--JavaScriptCore/runtime/Arguments.cpp66
-rw-r--r--JavaScriptCore/runtime/Arguments.h12
-rw-r--r--JavaScriptCore/runtime/ArrayPrototype.cpp7
-rw-r--r--JavaScriptCore/runtime/Collector.cpp18
-rw-r--r--JavaScriptCore/runtime/Collector.h2
-rw-r--r--JavaScriptCore/runtime/CommonIdentifiers.cpp1
-rw-r--r--JavaScriptCore/runtime/CommonIdentifiers.h1
-rw-r--r--JavaScriptCore/runtime/DateConversion.cpp4
-rw-r--r--JavaScriptCore/runtime/Error.cpp43
-rw-r--r--JavaScriptCore/runtime/Error.h2
-rw-r--r--JavaScriptCore/runtime/ExceptionHelpers.cpp17
-rw-r--r--JavaScriptCore/runtime/ExceptionHelpers.h1
-rw-r--r--JavaScriptCore/runtime/Executable.cpp48
-rw-r--r--JavaScriptCore/runtime/Executable.h33
-rw-r--r--JavaScriptCore/runtime/FunctionConstructor.cpp10
-rw-r--r--JavaScriptCore/runtime/FunctionPrototype.cpp2
-rw-r--r--JavaScriptCore/runtime/JSActivation.cpp5
-rw-r--r--JavaScriptCore/runtime/JSActivation.h1
-rw-r--r--JavaScriptCore/runtime/JSCell.h14
-rw-r--r--JavaScriptCore/runtime/JSFunction.cpp86
-rw-r--r--JavaScriptCore/runtime/JSGlobalData.cpp5
-rw-r--r--JavaScriptCore/runtime/JSGlobalData.h5
-rw-r--r--JavaScriptCore/runtime/JSGlobalObject.cpp1
-rw-r--r--JavaScriptCore/runtime/JSGlobalObject.h10
-rw-r--r--JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp8
-rw-r--r--JavaScriptCore/runtime/JSImmediate.h65
-rw-r--r--JavaScriptCore/runtime/JSNumberCell.cpp70
-rw-r--r--JavaScriptCore/runtime/JSNumberCell.h165
-rw-r--r--JavaScriptCore/runtime/JSONObject.cpp32
-rw-r--r--JavaScriptCore/runtime/JSObject.cpp23
-rw-r--r--JavaScriptCore/runtime/JSObject.h60
-rw-r--r--JavaScriptCore/runtime/JSStaticScopeObject.cpp5
-rw-r--r--JavaScriptCore/runtime/JSStaticScopeObject.h1
-rw-r--r--JavaScriptCore/runtime/JSStringBuilder.h12
-rw-r--r--JavaScriptCore/runtime/JSValue.h3
-rw-r--r--JavaScriptCore/runtime/JSZombie.h1
-rw-r--r--JavaScriptCore/runtime/LiteralParser.cpp6
-rw-r--r--JavaScriptCore/runtime/NumberObject.h4
-rw-r--r--JavaScriptCore/runtime/NumberPrototype.cpp12
-rw-r--r--JavaScriptCore/runtime/Operations.h6
-rw-r--r--JavaScriptCore/runtime/PutPropertySlot.h5
-rw-r--r--JavaScriptCore/runtime/RegExpConstructor.cpp4
-rw-r--r--JavaScriptCore/runtime/RegExpObject.cpp4
-rw-r--r--JavaScriptCore/runtime/RegExpPrototype.cpp3
-rw-r--r--JavaScriptCore/runtime/StrictEvalActivation.cpp51
-rw-r--r--JavaScriptCore/runtime/StrictEvalActivation.h43
-rw-r--r--JavaScriptCore/runtime/StringConcatenate.h428
-rw-r--r--JavaScriptCore/runtime/StringPrototype.cpp49
-rw-r--r--JavaScriptCore/runtime/UStringBuilder.h (renamed from JavaScriptCore/runtime/StringBuilder.h)62
-rw-r--r--JavaScriptCore/runtime/UStringConcatenate.h125
50 files changed, 639 insertions, 1002 deletions
diff --git a/JavaScriptCore/runtime/Arguments.cpp b/JavaScriptCore/runtime/Arguments.cpp
index 450dc7d..5c5e522 100644
--- a/JavaScriptCore/runtime/Arguments.cpp
+++ b/JavaScriptCore/runtime/Arguments.cpp
@@ -153,6 +153,30 @@ bool Arguments::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& sl
return JSObject::getOwnPropertySlot(exec, Identifier(exec, UString::number(i)), slot);
}
+
+void Arguments::createStrictModeCallerIfNecessary(ExecState* exec)
+{
+ if (d->overrodeCaller)
+ return;
+
+ d->overrodeCaller = true;
+ PropertyDescriptor descriptor;
+ JSValue thrower = createTypeErrorFunction(exec, "Unable to access caller of strict mode function");
+ descriptor.setAccessorDescriptor(thrower, thrower, DontEnum | DontDelete | Getter | Setter);
+ defineOwnProperty(exec, exec->propertyNames().caller, descriptor, false);
+}
+
+void Arguments::createStrictModeCalleeIfNecessary(ExecState* exec)
+{
+ if (d->overrodeCallee)
+ return;
+
+ d->overrodeCallee = true;
+ PropertyDescriptor descriptor;
+ JSValue thrower = createTypeErrorFunction(exec, "Unable to access callee of strict mode function");
+ descriptor.setAccessorDescriptor(thrower, thrower, DontEnum | DontDelete | Getter | Setter);
+ defineOwnProperty(exec, exec->propertyNames().callee, descriptor, false);
+}
bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
@@ -172,10 +196,16 @@ bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyNa
}
if (propertyName == exec->propertyNames().callee && LIKELY(!d->overrodeCallee)) {
- slot.setValue(d->callee);
- return true;
+ if (!d->isStrictMode) {
+ slot.setValue(d->callee);
+ return true;
+ }
+ createStrictModeCalleeIfNecessary(exec);
}
+ if (propertyName == exec->propertyNames().caller && d->isStrictMode)
+ createStrictModeCallerIfNecessary(exec);
+
return JSObject::getOwnPropertySlot(exec, propertyName, slot);
}
@@ -197,9 +227,15 @@ bool Arguments::getOwnPropertyDescriptor(ExecState* exec, const Identifier& prop
}
if (propertyName == exec->propertyNames().callee && LIKELY(!d->overrodeCallee)) {
- descriptor.setDescriptor(d->callee, DontEnum);
- return true;
+ if (!d->isStrictMode) {
+ descriptor.setDescriptor(d->callee, DontEnum);
+ return true;
+ }
+ createStrictModeCalleeIfNecessary(exec);
}
+
+ if (propertyName == exec->propertyNames().caller && d->isStrictMode)
+ createStrictModeCallerIfNecessary(exec);
return JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor);
}
@@ -249,11 +285,17 @@ void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValue val
}
if (propertyName == exec->propertyNames().callee && !d->overrodeCallee) {
- d->overrodeCallee = true;
- putDirect(propertyName, value, DontEnum);
- return;
+ if (!d->isStrictMode) {
+ d->overrodeCallee = true;
+ putDirect(propertyName, value, DontEnum);
+ return;
+ }
+ createStrictModeCalleeIfNecessary(exec);
}
+ if (propertyName == exec->propertyNames().caller && d->isStrictMode)
+ createStrictModeCallerIfNecessary(exec);
+
JSObject::put(exec, propertyName, value, slot);
}
@@ -294,9 +336,15 @@ bool Arguments::deleteProperty(ExecState* exec, const Identifier& propertyName)
}
if (propertyName == exec->propertyNames().callee && !d->overrodeCallee) {
- d->overrodeCallee = true;
- return true;
+ if (!d->isStrictMode) {
+ d->overrodeCallee = true;
+ return true;
+ }
+ createStrictModeCalleeIfNecessary(exec);
}
+
+ if (propertyName == exec->propertyNames().caller && !d->isStrictMode)
+ createStrictModeCallerIfNecessary(exec);
return JSObject::deleteProperty(exec, propertyName);
}
diff --git a/JavaScriptCore/runtime/Arguments.h b/JavaScriptCore/runtime/Arguments.h
index 49c8b3b..715a2ac 100644
--- a/JavaScriptCore/runtime/Arguments.h
+++ b/JavaScriptCore/runtime/Arguments.h
@@ -50,6 +50,8 @@ namespace JSC {
JSFunction* callee;
bool overrodeLength : 1;
bool overrodeCallee : 1;
+ bool overrodeCaller : 1;
+ bool isStrictMode : 1;
};
@@ -105,6 +107,8 @@ namespace JSC {
virtual void put(ExecState*, unsigned propertyName, JSValue, PutPropertySlot&);
virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
virtual bool deleteProperty(ExecState*, unsigned propertyName);
+ void createStrictModeCallerIfNecessary(ExecState*);
+ void createStrictModeCalleeIfNecessary(ExecState*);
virtual const ClassInfo* classInfo() const { return &info; }
@@ -172,6 +176,10 @@ namespace JSC {
d->callee = callee;
d->overrodeLength = false;
d->overrodeCallee = false;
+ d->overrodeCaller = false;
+ d->isStrictMode = callFrame->codeBlock()->isStrictMode();
+ if (d->isStrictMode)
+ copyRegisters();
}
inline Arguments::Arguments(CallFrame* callFrame, NoParametersType)
@@ -201,6 +209,10 @@ namespace JSC {
d->callee = asFunction(callFrame->callee());
d->overrodeLength = false;
d->overrodeCallee = false;
+ d->overrodeCaller = false;
+ d->isStrictMode = callFrame->codeBlock()->isStrictMode();
+ if (d->isStrictMode)
+ copyRegisters();
}
inline void Arguments::copyRegisters()
diff --git a/JavaScriptCore/runtime/ArrayPrototype.cpp b/JavaScriptCore/runtime/ArrayPrototype.cpp
index 28269ff..6002ebb 100644
--- a/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -180,7 +180,14 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec)
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
unsigned totalSize = length ? length - 1 : 0;
+#if OS(SYMBIAN)
+ // Symbian has very limited stack size available.
+ // This function could be called recursively and allocating 1K on stack here cause
+ // stack overflow on Symbian devices.
+ Vector<RefPtr<StringImpl> > strBuffer(length);
+#else
Vector<RefPtr<StringImpl>, 256> strBuffer(length);
+#endif
for (unsigned k = 0; k < length; k++) {
JSValue element;
if (isRealArray && thisObj->canGetIndex(k))
diff --git a/JavaScriptCore/runtime/Collector.cpp b/JavaScriptCore/runtime/Collector.cpp
index 93b91bb..f341646 100644
--- a/JavaScriptCore/runtime/Collector.cpp
+++ b/JavaScriptCore/runtime/Collector.cpp
@@ -642,19 +642,6 @@ inline bool isPointerAligned(void* p)
// Cell size needs to be a power of two for isPossibleCell to be valid.
COMPILE_ASSERT(sizeof(CollectorCell) % 2 == 0, Collector_cell_size_is_power_of_two);
-#if USE(JSVALUE32)
-static bool isHalfCellAligned(void *p)
-{
- return (((intptr_t)(p) & (CELL_MASK >> 1)) == 0);
-}
-
-static inline bool isPossibleCell(void* p)
-{
- return isHalfCellAligned(p) && p;
-}
-
-#else
-
static inline bool isCellAligned(void *p)
{
return (((intptr_t)(p) & CELL_MASK) == 0);
@@ -664,7 +651,6 @@ static inline bool isPossibleCell(void* p)
{
return isCellAligned(p) && p;
}
-#endif // USE(JSVALUE32)
void Heap::markConservatively(MarkStack& markStack, void* start, void* end)
{
@@ -1145,10 +1131,6 @@ static const char* typeName(JSCell* cell)
{
if (cell->isString())
return "string";
-#if USE(JSVALUE32)
- if (cell->isNumber())
- return "number";
-#endif
if (cell->isGetterSetter())
return "Getter-Setter";
if (cell->isAPIValueWrapper())
diff --git a/JavaScriptCore/runtime/Collector.h b/JavaScriptCore/runtime/Collector.h
index 05d5c10..237c139 100644
--- a/JavaScriptCore/runtime/Collector.h
+++ b/JavaScriptCore/runtime/Collector.h
@@ -57,7 +57,7 @@ namespace JSC {
class LiveObjectIterator;
-#if OS(WINCE) || OS(SYMBIAN)
+#if OS(WINCE) || OS(SYMBIAN) || PLATFORM(BREWMP)
const size_t BLOCK_SIZE = 64 * 1024; // 64k
#else
const size_t BLOCK_SIZE = 256 * 1024; // 256k
diff --git a/JavaScriptCore/runtime/CommonIdentifiers.cpp b/JavaScriptCore/runtime/CommonIdentifiers.cpp
index 3837817..1561102 100644
--- a/JavaScriptCore/runtime/CommonIdentifiers.cpp
+++ b/JavaScriptCore/runtime/CommonIdentifiers.cpp
@@ -32,6 +32,7 @@ CommonIdentifiers::CommonIdentifiers(JSGlobalData* globalData)
, emptyIdentifier(globalData, "")
, underscoreProto(globalData, "__proto__")
, thisIdentifier(globalData, "this")
+ , useStrictIdentifier(globalData, "use strict")
JSC_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(INITIALIZE_PROPERTY_NAME)
{
}
diff --git a/JavaScriptCore/runtime/CommonIdentifiers.h b/JavaScriptCore/runtime/CommonIdentifiers.h
index de24f4a..1e22b6a 100644
--- a/JavaScriptCore/runtime/CommonIdentifiers.h
+++ b/JavaScriptCore/runtime/CommonIdentifiers.h
@@ -94,6 +94,7 @@ namespace JSC {
const Identifier emptyIdentifier;
const Identifier underscoreProto;
const Identifier thisIdentifier;
+ const Identifier useStrictIdentifier;
#define JSC_IDENTIFIER_DECLARE_PROPERTY_NAME_GLOBAL(name) const Identifier name;
JSC_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(JSC_IDENTIFIER_DECLARE_PROPERTY_NAME_GLOBAL)
diff --git a/JavaScriptCore/runtime/DateConversion.cpp b/JavaScriptCore/runtime/DateConversion.cpp
index 7eb82e4..d4b8232 100644
--- a/JavaScriptCore/runtime/DateConversion.cpp
+++ b/JavaScriptCore/runtime/DateConversion.cpp
@@ -57,7 +57,9 @@ double parseDate(ExecState* exec, const UString &date)
{
if (date == exec->globalData().cachedDateString)
return exec->globalData().cachedDateStringValue;
- double value = parseDateFromNullTerminatedCharacters(exec, date.utf8().data());
+ double value = parseES5DateFromNullTerminatedCharacters(date.utf8().data());
+ if (isnan(value))
+ value = parseDateFromNullTerminatedCharacters(exec, date.utf8().data());
exec->globalData().cachedDateString = date;
exec->globalData().cachedDateStringValue = value;
return value;
diff --git a/JavaScriptCore/runtime/Error.cpp b/JavaScriptCore/runtime/Error.cpp
index a2be473..e35424b 100644
--- a/JavaScriptCore/runtime/Error.cpp
+++ b/JavaScriptCore/runtime/Error.cpp
@@ -195,4 +195,47 @@ JSObject* throwSyntaxError(ExecState* exec)
return throwError(exec, createSyntaxError(exec, "Syntax error"));
}
+class StrictModeTypeErrorFunction : public InternalFunction {
+public:
+ StrictModeTypeErrorFunction(ExecState* exec, JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, const UString& message)
+ : InternalFunction(&exec->globalData(), globalObject, structure, exec->globalData().propertyNames->emptyIdentifier)
+ , m_message(message)
+ {
+ }
+
+ static EncodedJSValue JSC_HOST_CALL constructThrowTypeError(ExecState* exec)
+ {
+ throwTypeError(exec, static_cast<StrictModeTypeErrorFunction*>(exec->callee())->m_message);
+ return JSValue::encode(jsNull());
+ }
+
+ ConstructType getConstructData(ConstructData& constructData)
+ {
+ constructData.native.function = constructThrowTypeError;
+ return ConstructTypeHost;
+ }
+
+ static EncodedJSValue JSC_HOST_CALL callThrowTypeError(ExecState* exec)
+ {
+ throwTypeError(exec, static_cast<StrictModeTypeErrorFunction*>(exec->callee())->m_message);
+ return JSValue::encode(jsNull());
+ }
+
+ CallType getCallData(CallData& callData)
+ {
+ callData.native.function = callThrowTypeError;
+ return CallTypeHost;
+ }
+
+private:
+ UString m_message;
+};
+
+COMPILE_ASSERT(sizeof(StrictModeTypeErrorFunction) <= sizeof(CollectorCell), sizeof_StrictModeTypeErrorFunction_must_be_less_than_CollectorCell);
+
+JSValue createTypeErrorFunction(ExecState* exec, const UString& message)
+{
+ return new (exec) StrictModeTypeErrorFunction(exec, exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->internalFunctionStructure(), message);
+}
+
} // namespace JSC
diff --git a/JavaScriptCore/runtime/Error.h b/JavaScriptCore/runtime/Error.h
index 1a0ece5..bfde7dc 100644
--- a/JavaScriptCore/runtime/Error.h
+++ b/JavaScriptCore/runtime/Error.h
@@ -73,6 +73,8 @@ namespace JSC {
inline EncodedJSValue throwVMError(ExecState* exec, JSValue error) { return JSValue::encode(throwError(exec, error)); }
inline EncodedJSValue throwVMTypeError(ExecState* exec) { return JSValue::encode(throwTypeError(exec)); }
+ JSValue createTypeErrorFunction(ExecState* exec, const UString& message);
+
} // namespace JSC
#endif // Error_h
diff --git a/JavaScriptCore/runtime/ExceptionHelpers.cpp b/JavaScriptCore/runtime/ExceptionHelpers.cpp
index 9a6fe5e..a1e28d1 100644
--- a/JavaScriptCore/runtime/ExceptionHelpers.cpp
+++ b/JavaScriptCore/runtime/ExceptionHelpers.cpp
@@ -36,7 +36,7 @@
#include "JSNotAnObject.h"
#include "Interpreter.h"
#include "Nodes.h"
-#include "StringConcatenate.h"
+#include "UStringConcatenate.h"
namespace JSC {
@@ -90,7 +90,7 @@ JSValue createUndefinedVariableError(ExecState* exec, const Identifier& ident, u
int endOffset = 0;
int divotPoint = 0;
int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
- UString message(makeString("Can't find variable: ", ident.ustring()));
+ UString message(makeUString("Can't find variable: ", ident.ustring()));
JSObject* exception = addErrorInfo(exec, createReferenceError(exec, message), line, codeBlock->ownerExecutable()->source(), divotPoint, startOffset, endOffset);
return exception;
}
@@ -98,9 +98,9 @@ JSValue createUndefinedVariableError(ExecState* exec, const Identifier& ident, u
static UString createErrorMessage(ExecState* exec, CodeBlock* codeBlock, int, int expressionStart, int expressionStop, JSValue value, UString error)
{
if (!expressionStop || expressionStart > codeBlock->source()->length())
- return makeString(value.toString(exec), " is ", error);
+ return makeUString(value.toString(exec), " is ", error);
if (expressionStart < expressionStop)
- return makeString("Result of expression '", codeBlock->source()->getRange(expressionStart, expressionStop), "' [", value.toString(exec), "] is ", error, ".");
+ return makeUString("Result of expression '", codeBlock->source()->getRange(expressionStart, expressionStop), "' [", value.toString(exec), "] is ", error, ".");
// No range information, so give a few characters of context
const UChar* data = codeBlock->source()->data();
@@ -117,7 +117,7 @@ static UString createErrorMessage(ExecState* exec, CodeBlock* codeBlock, int, in
stop++;
while (stop > expressionStart && isStrWhiteSpace(data[stop]))
stop--;
- return makeString("Result of expression near '...", codeBlock->source()->getRange(start, stop), "...' [", value.toString(exec), "] is ", error, ".");
+ return makeUString("Result of expression near '...", codeBlock->source()->getRange(start, stop), "...' [", value.toString(exec), "] is ", error, ".");
}
JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValue value, unsigned bytecodeOffset, CodeBlock* codeBlock)
@@ -126,7 +126,7 @@ JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValue value
int endOffset = 0;
int divotPoint = 0;
int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
- UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint, divotPoint + endOffset, value, makeString("not a valid argument for '", op, "'"));
+ UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint, divotPoint + endOffset, value, makeUString("not a valid argument for '", op, "'"));
JSObject* exception = addErrorInfo(exec, createTypeError(exec, errorMessage), line, codeBlock->ownerExecutable()->source(), divotPoint, startOffset, endOffset);
return exception;
}
@@ -192,4 +192,9 @@ JSValue throwOutOfMemoryError(ExecState* exec)
return throwError(exec, createError(exec, "Out of memory"));
}
+JSObject* createErrorForInvalidGlobalAssignment(ExecState* exec, const UString& propertyName)
+{
+ return createReferenceError(exec, makeUString("Strict mode forbids implicit creation of global property '", propertyName, "'"));
+}
+
} // namespace JSC
diff --git a/JavaScriptCore/runtime/ExceptionHelpers.h b/JavaScriptCore/runtime/ExceptionHelpers.h
index 3e6de86..9b6f1f2 100644
--- a/JavaScriptCore/runtime/ExceptionHelpers.h
+++ b/JavaScriptCore/runtime/ExceptionHelpers.h
@@ -54,6 +54,7 @@ namespace JSC {
JSValue createNotAFunctionError(ExecState*, JSValue, unsigned bytecodeOffset, CodeBlock*);
JSObject* createNotAnObjectError(ExecState*, JSNotAnObjectErrorStub*, unsigned bytecodeOffset, CodeBlock*);
JSValue throwOutOfMemoryError(ExecState*);
+ JSObject* createErrorForInvalidGlobalAssignment(ExecState*, const UString&);
} // namespace JSC
diff --git a/JavaScriptCore/runtime/Executable.cpp b/JavaScriptCore/runtime/Executable.cpp
index 871f3e2..2ad4b2d 100644
--- a/JavaScriptCore/runtime/Executable.cpp
+++ b/JavaScriptCore/runtime/Executable.cpp
@@ -30,7 +30,7 @@
#include "CodeBlock.h"
#include "JIT.h"
#include "Parser.h"
-#include "StringBuilder.h"
+#include "UStringBuilder.h"
#include "Vector.h"
namespace JSC {
@@ -45,8 +45,8 @@ VPtrHackExecutable::~VPtrHackExecutable()
{
}
-EvalExecutable::EvalExecutable(ExecState* exec, const SourceCode& source)
- : ScriptExecutable(exec, source)
+EvalExecutable::EvalExecutable(ExecState* exec, const SourceCode& source, bool inStrictContext)
+ : ScriptExecutable(exec, source, inStrictContext)
{
}
@@ -55,7 +55,7 @@ EvalExecutable::~EvalExecutable()
}
ProgramExecutable::ProgramExecutable(ExecState* exec, const SourceCode& source)
- : ScriptExecutable(exec, source)
+ : ScriptExecutable(exec, source, false)
{
}
@@ -63,8 +63,8 @@ ProgramExecutable::~ProgramExecutable()
{
}
-FunctionExecutable::FunctionExecutable(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
- : ScriptExecutable(globalData, source)
+FunctionExecutable::FunctionExecutable(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext, int firstLine, int lastLine)
+ : ScriptExecutable(globalData, source, inStrictContext)
, m_numCapturedVariables(0)
, m_forceUsesArguments(forceUsesArguments)
, m_parameters(parameters)
@@ -75,8 +75,8 @@ FunctionExecutable::FunctionExecutable(JSGlobalData* globalData, const Identifie
m_lastLine = lastLine;
}
-FunctionExecutable::FunctionExecutable(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
- : ScriptExecutable(exec, source)
+FunctionExecutable::FunctionExecutable(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext, int firstLine, int lastLine)
+ : ScriptExecutable(exec, source, inStrictContext)
, m_numCapturedVariables(0)
, m_forceUsesArguments(forceUsesArguments)
, m_parameters(parameters)
@@ -96,7 +96,7 @@ JSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scope
JSObject* exception = 0;
JSGlobalData* globalData = &exec->globalData();
JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
- RefPtr<EvalNode> evalNode = globalData->parser->parse<EvalNode>(globalData, lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, &exception);
+ RefPtr<EvalNode> evalNode = globalData->parser->parse<EvalNode>(lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, &exception);
if (!evalNode) {
ASSERT(exception);
return exception;
@@ -131,7 +131,7 @@ JSObject* ProgramExecutable::checkSyntax(ExecState* exec)
JSObject* exception = 0;
JSGlobalData* globalData = &exec->globalData();
JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
- RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>(globalData, lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, &exception);
+ RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>(lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, JSParseNormal, &exception);
if (programNode)
return 0;
ASSERT(exception);
@@ -145,7 +145,7 @@ JSObject* ProgramExecutable::compileInternal(ExecState* exec, ScopeChainNode* sc
JSObject* exception = 0;
JSGlobalData* globalData = &exec->globalData();
JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
- RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>(globalData, lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, &exception);
+ RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>(lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, &exception);
if (!programNode) {
ASSERT(exception);
return exception;
@@ -178,7 +178,7 @@ JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChain
{
JSObject* exception = 0;
JSGlobalData* globalData = scopeChainNode->globalData;
- RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(globalData, exec->lexicalGlobalObject(), 0, 0, m_source, m_parameters.get(), &exception);
+ RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(exec->lexicalGlobalObject(), 0, 0, m_source, m_parameters.get(), isStrictMode() ? JSParseStrict : JSParseNormal, &exception);
if (!body) {
ASSERT(exception);
return exception;
@@ -219,7 +219,7 @@ JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, Scope
{
JSObject* exception = 0;
JSGlobalData* globalData = scopeChainNode->globalData;
- RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(globalData, exec->lexicalGlobalObject(), 0, 0, m_source, m_parameters.get(), &exception);
+ RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(exec->lexicalGlobalObject(), 0, 0, m_source, m_parameters.get(), isStrictMode() ? JSParseStrict : JSParseNormal, &exception);
if (!body) {
ASSERT(exception);
return exception;
@@ -264,12 +264,14 @@ void FunctionExecutable::markAggregate(MarkStack& markStack)
m_codeBlockForConstruct->markAggregate(markStack);
}
-PassOwnPtr<ExceptionInfo> FunctionExecutable::reparseExceptionInfo(JSGlobalData* globalData, ScopeChainNode* scopeChainNode, CodeBlock* codeBlock)
+PassOwnPtr<ExceptionInfo> FunctionExecutable::reparseExceptionInfo(ScopeChainNode* scopeChainNode, CodeBlock* codeBlock)
{
JSObject* exception = 0;
- RefPtr<FunctionBodyNode> newFunctionBody = globalData->parser->parse<FunctionBodyNode>(globalData, 0, 0, 0, m_source, m_parameters.get(), &exception);
+ JSGlobalData* globalData = scopeChainNode->globalData;
+ RefPtr<FunctionBodyNode> newFunctionBody = globalData->parser->parse<FunctionBodyNode>(scopeChainNode->globalObject, 0, 0, m_source, m_parameters.get(), isStrictMode() ? JSParseStrict : JSParseNormal, &exception);
if (!newFunctionBody)
return PassOwnPtr<ExceptionInfo>();
+ ASSERT(newFunctionBody->isStrictMode() == isStrictMode());
if (m_forceUsesArguments)
newFunctionBody->setUsesArguments();
newFunctionBody->finishParsing(m_parameters, m_name);
@@ -298,10 +300,12 @@ PassOwnPtr<ExceptionInfo> FunctionExecutable::reparseExceptionInfo(JSGlobalData*
return newCodeBlock->extractExceptionInfo();
}
-PassOwnPtr<ExceptionInfo> EvalExecutable::reparseExceptionInfo(JSGlobalData* globalData, ScopeChainNode* scopeChainNode, CodeBlock* codeBlock)
+PassOwnPtr<ExceptionInfo> EvalExecutable::reparseExceptionInfo(ScopeChainNode* scopeChainNode, CodeBlock* codeBlock)
{
JSObject* exception = 0;
- RefPtr<EvalNode> newEvalBody = globalData->parser->parse<EvalNode>(globalData, 0, 0, 0, m_source, 0, &exception);
+ JSGlobalData* globalData = scopeChainNode->globalData;
+ RefPtr<EvalNode> newEvalBody = globalData->parser->parse<EvalNode>(scopeChainNode->globalObject, 0, 0, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, &exception);
+ ASSERT(newEvalBody->isStrictMode() == isStrictMode());
if (!newEvalBody)
return PassOwnPtr<ExceptionInfo>();
@@ -341,7 +345,7 @@ void FunctionExecutable::recompile(ExecState*)
PassRefPtr<FunctionExecutable> FunctionExecutable::fromGlobalCode(const Identifier& functionName, ExecState* exec, Debugger* debugger, const SourceCode& source, JSObject** exception)
{
JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
- RefPtr<ProgramNode> program = exec->globalData().parser->parse<ProgramNode>(&exec->globalData(), lexicalGlobalObject, debugger, exec, source, 0, exception);
+ RefPtr<ProgramNode> program = exec->globalData().parser->parse<ProgramNode>(lexicalGlobalObject, debugger, exec, source, 0, JSParseNormal, exception);
if (!program) {
ASSERT(*exception);
return 0;
@@ -357,22 +361,22 @@ PassRefPtr<FunctionExecutable> FunctionExecutable::fromGlobalCode(const Identifi
FunctionBodyNode* body = static_cast<FuncExprNode*>(funcExpr)->body();
ASSERT(body);
- return FunctionExecutable::create(&exec->globalData(), functionName, body->source(), body->usesArguments(), body->parameters(), body->lineNo(), body->lastLine());
+ return FunctionExecutable::create(&exec->globalData(), functionName, body->source(), body->usesArguments(), body->parameters(), body->isStrictMode(), body->lineNo(), body->lastLine());
}
UString FunctionExecutable::paramString() const
{
FunctionParameters& parameters = *m_parameters;
- StringBuilder builder;
+ UStringBuilder builder;
for (size_t pos = 0; pos < parameters.size(); ++pos) {
if (!builder.isEmpty())
builder.append(", ");
builder.append(parameters[pos].ustring());
}
- return builder.build();
+ return builder.toUString();
}
-PassOwnPtr<ExceptionInfo> ProgramExecutable::reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*)
+PassOwnPtr<ExceptionInfo> ProgramExecutable::reparseExceptionInfo(ScopeChainNode*, CodeBlock*)
{
// CodeBlocks for program code are transient and therefore do not gain from from throwing out their exception information.
return PassOwnPtr<ExceptionInfo>();
diff --git a/JavaScriptCore/runtime/Executable.h b/JavaScriptCore/runtime/Executable.h
index feab7ef..4c4ca56 100644
--- a/JavaScriptCore/runtime/Executable.h
+++ b/JavaScriptCore/runtime/Executable.h
@@ -138,10 +138,10 @@ namespace JSC {
class ScriptExecutable : public ExecutableBase {
public:
- ScriptExecutable(JSGlobalData* globalData, const SourceCode& source)
+ ScriptExecutable(JSGlobalData* globalData, const SourceCode& source, bool isInStrictContext)
: ExecutableBase(NUM_PARAMETERS_NOT_COMPILED)
, m_source(source)
- , m_features(0)
+ , m_features(isInStrictContext ? StrictModeFeature : 0)
{
#if ENABLE(CODEBLOCK_SAMPLING)
relaxAdoptionRequirement();
@@ -152,10 +152,10 @@ namespace JSC {
#endif
}
- ScriptExecutable(ExecState* exec, const SourceCode& source)
+ ScriptExecutable(ExecState* exec, const SourceCode& source, bool isInStrictContext)
: ExecutableBase(NUM_PARAMETERS_NOT_COMPILED)
, m_source(source)
- , m_features(0)
+ , m_features(isInStrictContext ? StrictModeFeature : 0)
{
#if ENABLE(CODEBLOCK_SAMPLING)
relaxAdoptionRequirement();
@@ -175,8 +175,9 @@ namespace JSC {
bool usesEval() const { return m_features & EvalFeature; }
bool usesArguments() const { return m_features & ArgumentsFeature; }
bool needsActivation() const { return m_hasCapturedVariables || m_features & (EvalFeature | WithFeature | CatchFeature); }
+ bool isStrictMode() const { return m_features & StrictModeFeature; }
- virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*) = 0;
+ virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(ScopeChainNode*, CodeBlock*) = 0;
protected:
void recordParse(CodeFeatures features, bool hasCapturedVariables, int firstLine, int lastLine)
@@ -214,7 +215,7 @@ namespace JSC {
return *m_evalCodeBlock;
}
- static PassRefPtr<EvalExecutable> create(ExecState* exec, const SourceCode& source) { return adoptRef(new EvalExecutable(exec, source)); }
+ static PassRefPtr<EvalExecutable> create(ExecState* exec, const SourceCode& source, bool isInStrictContext) { return adoptRef(new EvalExecutable(exec, source, isInStrictContext)); }
#if ENABLE(JIT)
JITCode& generatedJITCode()
@@ -224,11 +225,11 @@ namespace JSC {
#endif
private:
- EvalExecutable(ExecState*, const SourceCode&);
+ EvalExecutable(ExecState*, const SourceCode&, bool);
JSObject* compileInternal(ExecState*, ScopeChainNode*);
- virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
+ virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(ScopeChainNode*, CodeBlock*);
OwnPtr<EvalCodeBlock> m_evalCodeBlock;
};
@@ -271,7 +272,7 @@ namespace JSC {
JSObject* compileInternal(ExecState*, ScopeChainNode*);
- virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
+ virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(ScopeChainNode*, CodeBlock*);
OwnPtr<ProgramCodeBlock> m_programCodeBlock;
};
@@ -279,14 +280,14 @@ namespace JSC {
class FunctionExecutable : public ScriptExecutable {
friend class JIT;
public:
- static PassRefPtr<FunctionExecutable> create(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
+ static PassRefPtr<FunctionExecutable> create(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine)
{
- return adoptRef(new FunctionExecutable(exec, name, source, forceUsesArguments, parameters, firstLine, lastLine));
+ return adoptRef(new FunctionExecutable(exec, name, source, forceUsesArguments, parameters, isInStrictContext, firstLine, lastLine));
}
- static PassRefPtr<FunctionExecutable> create(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
+ static PassRefPtr<FunctionExecutable> create(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool isInStrictContext, int firstLine, int lastLine)
{
- return adoptRef(new FunctionExecutable(globalData, name, source, forceUsesArguments, parameters, firstLine, lastLine));
+ return adoptRef(new FunctionExecutable(globalData, name, source, forceUsesArguments, parameters, isInStrictContext, firstLine, lastLine));
}
~FunctionExecutable();
@@ -358,13 +359,13 @@ namespace JSC {
static PassRefPtr<FunctionExecutable> fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
private:
- FunctionExecutable(JSGlobalData*, const Identifier& name, const SourceCode&, bool forceUsesArguments, FunctionParameters*, int firstLine, int lastLine);
- FunctionExecutable(ExecState*, const Identifier& name, const SourceCode&, bool forceUsesArguments, FunctionParameters*, int firstLine, int lastLine);
+ FunctionExecutable(JSGlobalData*, const Identifier& name, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool, int firstLine, int lastLine);
+ FunctionExecutable(ExecState*, const Identifier& name, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool, int firstLine, int lastLine);
JSObject* compileForCallInternal(ExecState*, ScopeChainNode*);
JSObject* compileForConstructInternal(ExecState*, ScopeChainNode*);
- virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
+ virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(ScopeChainNode*, CodeBlock*);
unsigned m_numCapturedVariables : 31;
bool m_forceUsesArguments : 1;
diff --git a/JavaScriptCore/runtime/FunctionConstructor.cpp b/JavaScriptCore/runtime/FunctionConstructor.cpp
index f72a273..9b59720 100644
--- a/JavaScriptCore/runtime/FunctionConstructor.cpp
+++ b/JavaScriptCore/runtime/FunctionConstructor.cpp
@@ -30,8 +30,8 @@
#include "Lexer.h"
#include "Nodes.h"
#include "Parser.h"
-#include "StringBuilder.h"
-#include "StringConcatenate.h"
+#include "UStringBuilder.h"
+#include "UStringConcatenate.h"
namespace JSC {
@@ -81,9 +81,9 @@ JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifi
if (args.isEmpty())
program = "(function() { \n})";
else if (args.size() == 1)
- program = makeString("(function() { ", args.at(0).toString(exec), "\n})");
+ program = makeUString("(function() { ", args.at(0).toString(exec), "\n})");
else {
- StringBuilder builder;
+ UStringBuilder builder;
builder.append("(function(");
builder.append(args.at(0).toString(exec));
for (size_t i = 1; i < args.size() - 1; i++) {
@@ -93,7 +93,7 @@ JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifi
builder.append(") { ");
builder.append(args.at(args.size() - 1).toString(exec));
builder.append("\n})");
- program = builder.build();
+ program = builder.toUString();
}
JSGlobalObject* globalObject = exec->lexicalGlobalObject();
diff --git a/JavaScriptCore/runtime/FunctionPrototype.cpp b/JavaScriptCore/runtime/FunctionPrototype.cpp
index c740624..ef42cdc 100644
--- a/JavaScriptCore/runtime/FunctionPrototype.cpp
+++ b/JavaScriptCore/runtime/FunctionPrototype.cpp
@@ -77,7 +77,7 @@ static inline void insertSemicolonIfNeeded(UString& functionBody)
UChar ch = functionBody[i];
if (!Lexer::isWhiteSpace(ch) && !Lexer::isLineTerminator(ch)) {
if (ch != ';' && ch != '}')
- functionBody = makeString(functionBody.substringSharingImpl(0, i + 1), ";", functionBody.substringSharingImpl(i + 1, functionBody.length() - (i + 1)));
+ functionBody = makeUString(functionBody.substringSharingImpl(0, i + 1), ";", functionBody.substringSharingImpl(i + 1, functionBody.length() - (i + 1)));
return;
}
}
diff --git a/JavaScriptCore/runtime/JSActivation.cpp b/JavaScriptCore/runtime/JSActivation.cpp
index d121518..795ad1f 100644
--- a/JavaScriptCore/runtime/JSActivation.cpp
+++ b/JavaScriptCore/runtime/JSActivation.cpp
@@ -186,6 +186,11 @@ JSObject* JSActivation::toThisObject(ExecState* exec) const
return exec->globalThisValue();
}
+JSValue JSActivation::toStrictThisObject(ExecState*) const
+{
+ return jsNull();
+}
+
bool JSActivation::isDynamicScope(bool& requiresDynamicChecks) const
{
requiresDynamicChecks = d()->functionExecutable->usesEval();
diff --git a/JavaScriptCore/runtime/JSActivation.h b/JavaScriptCore/runtime/JSActivation.h
index 9ff9168..6dd6d70 100644
--- a/JavaScriptCore/runtime/JSActivation.h
+++ b/JavaScriptCore/runtime/JSActivation.h
@@ -60,6 +60,7 @@ namespace JSC {
virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
virtual JSObject* toThisObject(ExecState*) const;
+ virtual JSValue toStrictThisObject(ExecState*) const;
void copyRegisters();
diff --git a/JavaScriptCore/runtime/JSCell.h b/JavaScriptCore/runtime/JSCell.h
index cfa1454..1a7f8b2 100644
--- a/JavaScriptCore/runtime/JSCell.h
+++ b/JavaScriptCore/runtime/JSCell.h
@@ -75,9 +75,6 @@ namespace JSC {
}
// Querying the type.
-#if USE(JSVALUE32)
- bool isNumber() const;
-#endif
bool isString() const;
bool isObject() const;
virtual bool isGetterSetter() const;
@@ -156,13 +153,6 @@ namespace JSC {
{
}
-#if USE(JSVALUE32)
- inline bool JSCell::isNumber() const
- {
- return m_structure->typeInfo().type() == NumberType;
- }
-#endif
-
inline bool JSCell::isObject() const
{
return m_structure->typeInfo().type() == ObjectType;
@@ -253,13 +243,13 @@ namespace JSC {
return false;
}
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
ALWAYS_INLINE JSCell* JSValue::asCell() const
{
ASSERT(isCell());
return m_ptr;
}
-#endif // !USE(JSVALUE32_64)
+#endif // USE(JSVALUE64)
inline JSValue JSValue::toPrimitive(ExecState* exec, PreferredPrimitiveType preferredType) const
{
diff --git a/JavaScriptCore/runtime/JSFunction.cpp b/JavaScriptCore/runtime/JSFunction.cpp
index 7eb9ba5..fdaa509 100644
--- a/JavaScriptCore/runtime/JSFunction.cpp
+++ b/JavaScriptCore/runtime/JSFunction.cpp
@@ -122,6 +122,15 @@ JSFunction::~JSFunction()
}
}
+static const char* StrictModeCallerAccessError = "Cannot access caller property of a strict mode function";
+static const char* StrictModeArgumentsAccessError = "Cannot access arguments property of a strict mode function";
+
+static void createDescriptorForThrowingProperty(ExecState* exec, PropertyDescriptor& descriptor, const char* message)
+{
+ JSValue thrower = createTypeErrorFunction(exec, message);
+ descriptor.setAccessorDescriptor(thrower, thrower, DontEnum | DontDelete | Getter | Setter);
+}
+
const UString& JSFunction::name(ExecState* exec)
{
return asString(getDirect(exec->globalData().propertyNames->name))->tryGetValue();
@@ -209,6 +218,12 @@ bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyN
}
if (propertyName == exec->propertyNames().arguments) {
+ if (jsExecutable()->isStrictMode()) {
+ throwTypeError(exec, "Can't access arguments object of a strict mode function");
+ slot.setValue(jsNull());
+ return true;
+ }
+
slot.setCacheableCustom(this, argumentsGetter);
return true;
}
@@ -219,6 +234,11 @@ bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyN
}
if (propertyName == exec->propertyNames().caller) {
+ if (jsExecutable()->isStrictMode()) {
+ throwTypeError(exec, StrictModeCallerAccessError);
+ slot.setValue(jsNull());
+ return true;
+ }
slot.setCacheableCustom(this, callerGetter);
return true;
}
@@ -226,35 +246,41 @@ bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyN
return Base::getOwnPropertySlot(exec, propertyName, slot);
}
- bool JSFunction::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
- {
- if (isHostFunction())
- return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
-
- if (propertyName == exec->propertyNames().prototype) {
- PropertySlot slot;
- getOwnPropertySlot(exec, propertyName, slot);
- return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
- }
-
- if (propertyName == exec->propertyNames().arguments) {
+bool JSFunction::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
+{
+ if (isHostFunction())
+ return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
+
+ if (propertyName == exec->propertyNames().prototype) {
+ PropertySlot slot;
+ getOwnPropertySlot(exec, propertyName, slot);
+ return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
+ }
+
+ if (propertyName == exec->propertyNames().arguments) {
+ if (jsExecutable()->isStrictMode())
+ createDescriptorForThrowingProperty(exec, descriptor, StrictModeArgumentsAccessError);
+ else
descriptor.setDescriptor(exec->interpreter()->retrieveArguments(exec, this), ReadOnly | DontEnum | DontDelete);
- return true;
- }
-
- if (propertyName == exec->propertyNames().length) {
- descriptor.setDescriptor(jsNumber(exec, jsExecutable()->parameterCount()), ReadOnly | DontEnum | DontDelete);
- return true;
- }
-
- if (propertyName == exec->propertyNames().caller) {
+ return true;
+ }
+
+ if (propertyName == exec->propertyNames().length) {
+ descriptor.setDescriptor(jsNumber(exec, jsExecutable()->parameterCount()), ReadOnly | DontEnum | DontDelete);
+ return true;
+ }
+
+ if (propertyName == exec->propertyNames().caller) {
+ if (jsExecutable()->isStrictMode())
+ createDescriptorForThrowingProperty(exec, descriptor, StrictModeCallerAccessError);
+ else
descriptor.setDescriptor(exec->interpreter()->retrieveCaller(exec, this), ReadOnly | DontEnum | DontDelete);
- return true;
- }
-
- return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
+ return true;
}
+ return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor);
+}
+
void JSFunction::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
{
if (!isHostFunction() && (mode == IncludeDontEnumProperties)) {
@@ -272,6 +298,16 @@ void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValue va
Base::put(exec, propertyName, value, slot);
return;
}
+ if (jsExecutable()->isStrictMode()) {
+ if (propertyName == exec->propertyNames().arguments) {
+ throwTypeError(exec, StrictModeArgumentsAccessError);
+ return;
+ }
+ if (propertyName == exec->propertyNames().caller) {
+ throwTypeError(exec, StrictModeCallerAccessError);
+ return;
+ }
+ }
if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
return;
Base::put(exec, propertyName, value, slot);
diff --git a/JavaScriptCore/runtime/JSGlobalData.cpp b/JavaScriptCore/runtime/JSGlobalData.cpp
index 5eaa59b..1404ddf 100644
--- a/JavaScriptCore/runtime/JSGlobalData.cpp
+++ b/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -50,6 +50,7 @@
#include "Nodes.h"
#include "Parser.h"
#include "RegExpCache.h"
+#include "StrictEvalActivation.h"
#include <wtf/WTFThreadData.h>
#if ENABLE(REGEXP_TRACING)
#include "RegExp.h"
@@ -124,6 +125,7 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
, interruptedExecutionErrorStructure(JSObject::createStructure(jsNull()))
, terminatedExecutionErrorStructure(JSObject::createStructure(jsNull()))
, staticScopeStructure(JSStaticScopeObject::createStructure(jsNull()))
+ , strictEvalActivationStructure(StrictEvalActivation::createStructure(jsNull()))
, stringStructure(JSString::createStructure(jsNull()))
, notAnObjectErrorStubStructure(JSNotAnObjectErrorStub::createStructure(jsNull()))
, notAnObjectStructure(JSNotAnObject::createStructure(jsNull()))
@@ -131,9 +133,6 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
, getterSetterStructure(GetterSetter::createStructure(jsNull()))
, apiWrapperStructure(JSAPIValueWrapper::createStructure(jsNull()))
, dummyMarkableCellStructure(JSCell::createDummyStructure())
-#if USE(JSVALUE32)
- , numberStructure(JSNumberCell::createStructure(jsNull()))
-#endif
, identifierTable(globalDataType == Default ? wtfThreadData().currentIdentifierTable() : createIdentifierTable())
, propertyNames(new CommonIdentifiers(this))
, emptyList(new MarkedArgumentBuffer)
diff --git a/JavaScriptCore/runtime/JSGlobalData.h b/JavaScriptCore/runtime/JSGlobalData.h
index 8e2ed61..775d026 100644
--- a/JavaScriptCore/runtime/JSGlobalData.h
+++ b/JavaScriptCore/runtime/JSGlobalData.h
@@ -145,6 +145,7 @@ namespace JSC {
RefPtr<Structure> interruptedExecutionErrorStructure;
RefPtr<Structure> terminatedExecutionErrorStructure;
RefPtr<Structure> staticScopeStructure;
+ RefPtr<Structure> strictEvalActivationStructure;
RefPtr<Structure> stringStructure;
RefPtr<Structure> notAnObjectErrorStubStructure;
RefPtr<Structure> notAnObjectStructure;
@@ -153,10 +154,6 @@ namespace JSC {
RefPtr<Structure> apiWrapperStructure;
RefPtr<Structure> dummyMarkableCellStructure;
-#if USE(JSVALUE32)
- RefPtr<Structure> numberStructure;
-#endif
-
static void storeVPtrs();
static JS_EXPORTDATA void* jsArrayVPtr;
static JS_EXPORTDATA void* jsByteArrayVPtr;
diff --git a/JavaScriptCore/runtime/JSGlobalObject.cpp b/JavaScriptCore/runtime/JSGlobalObject.cpp
index 89c042a..903e573 100644
--- a/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -204,6 +204,7 @@ void JSGlobalObject::reset(JSValue prototype)
d()->functionPrototype = new (exec) FunctionPrototype(exec, this, FunctionPrototype::createStructure(jsNull())); // The real prototype will be set once ObjectPrototype is created.
d()->prototypeFunctionStructure = PrototypeFunction::createStructure(d()->functionPrototype);
+ d()->internalFunctionStructure = InternalFunction::createStructure(d()->functionPrototype);
NativeFunctionWrapper* callFunction = 0;
NativeFunctionWrapper* applyFunction = 0;
d()->functionPrototype->addFunctionProperties(exec, this, d()->prototypeFunctionStructure.get(), &callFunction, &applyFunction);
diff --git a/JavaScriptCore/runtime/JSGlobalObject.h b/JavaScriptCore/runtime/JSGlobalObject.h
index f5d2fb0..36fa70b 100644
--- a/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/JavaScriptCore/runtime/JSGlobalObject.h
@@ -148,6 +148,7 @@ namespace JSC {
RefPtr<Structure> regExpMatchesArrayStructure;
RefPtr<Structure> regExpStructure;
RefPtr<Structure> stringObjectStructure;
+ RefPtr<Structure> internalFunctionStructure;
SymbolTable symbolTable;
unsigned profileGroup;
@@ -243,6 +244,7 @@ namespace JSC {
Structure* functionStructure() const { return d()->functionStructure.get(); }
Structure* numberObjectStructure() const { return d()->numberObjectStructure.get(); }
Structure* prototypeFunctionStructure() const { return d()->prototypeFunctionStructure.get(); }
+ Structure* internalFunctionStructure() const { return d()->internalFunctionStructure.get(); }
Structure* regExpMatchesArrayStructure() const { return d()->regExpMatchesArrayStructure.get(); }
Structure* regExpStructure() const { return d()->regExpStructure.get(); }
Structure* stringObjectStructure() const { return d()->stringObjectStructure.get(); }
@@ -384,16 +386,8 @@ namespace JSC {
if (typeInfo().type() == ObjectType)
return m_prototype;
-#if USE(JSVALUE32)
- if (typeInfo().type() == StringType)
- return exec->lexicalGlobalObject()->stringPrototype();
-
- ASSERT(typeInfo().type() == NumberType);
- return exec->lexicalGlobalObject()->numberPrototype();
-#else
ASSERT(typeInfo().type() == StringType);
return exec->lexicalGlobalObject()->stringPrototype();
-#endif
}
inline StructureChain* Structure::prototypeChain(ExecState* exec) const
diff --git a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
index 1e20f7f..ed06fa5 100644
--- a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
+++ b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
@@ -35,7 +35,7 @@
#include "LiteralParser.h"
#include "Nodes.h"
#include "Parser.h"
-#include "StringBuilder.h"
+#include "UStringBuilder.h"
#include "dtoa.h"
#include <stdio.h>
#include <stdlib.h>
@@ -450,7 +450,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncEval(ExecState* exec)
if (JSValue parsedObject = preparser.tryLiteralParse())
return JSValue::encode(parsedObject);
- RefPtr<EvalExecutable> eval = EvalExecutable::create(exec, makeSource(s));
+ RefPtr<EvalExecutable> eval = EvalExecutable::create(exec, makeSource(s), false);
JSObject* error = eval->compile(exec, static_cast<JSGlobalObject*>(unwrappedObject)->globalScopeChain().node());
if (error)
return throwVMError(exec, error);
@@ -563,7 +563,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec)
EncodedJSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec)
{
- StringBuilder builder;
+ UStringBuilder builder;
UString str = exec->argument(0).toString(exec);
int k = 0;
int len = str.length();
@@ -585,7 +585,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec)
builder.append(*c);
}
- return JSValue::encode(jsString(exec, builder.build()));
+ return JSValue::encode(jsString(exec, builder.toUString()));
}
#ifndef NDEBUG
diff --git a/JavaScriptCore/runtime/JSImmediate.h b/JavaScriptCore/runtime/JSImmediate.h
index 9127b6a..ffa446e 100644
--- a/JavaScriptCore/runtime/JSImmediate.h
+++ b/JavaScriptCore/runtime/JSImmediate.h
@@ -22,7 +22,7 @@
#ifndef JSImmediate_h
#define JSImmediate_h
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
#include <wtf/Assertions.h>
#include <wtf/AlwaysInline.h>
@@ -44,7 +44,6 @@ namespace JSC {
class JSObject;
class UString;
-#if USE(JSVALUE64)
inline intptr_t reinterpretDoubleToIntptr(double value)
{
return WTF::bitwise_cast<intptr_t>(value);
@@ -54,7 +53,6 @@ namespace JSC {
{
return WTF::bitwise_cast<double>(value);
}
-#endif
/*
* A JSValue* is either a pointer to a cell (a heap-allocated object) or an immediate (a type-tagged
@@ -159,16 +157,12 @@ namespace JSC {
friend JSValue jsNumber(JSGlobalData* globalData, long long i);
friend JSValue jsNumber(JSGlobalData* globalData, unsigned long long i);
-#if USE(JSVALUE64)
// If all bits in the mask are set, this indicates an integer number,
// if any but not all are set this value is a double precision number.
static const intptr_t TagTypeNumber = 0xffff000000000000ll;
// This value is 2^48, used to encode doubles such that the encoded value will begin
// with a 16-bit pattern within the range 0x0001..0xFFFE.
static const intptr_t DoubleEncodeOffset = 0x1000000000000ll;
-#elif USE(JSVALUE32)
- static const intptr_t TagTypeNumber = 0x1; // bottom bit set indicates integer, this dominates the following bit
-#endif
static const intptr_t TagBitTypeOther = 0x2; // second bit set indicates immediate other than an integer
static const intptr_t TagMask = TagTypeNumber | TagBitTypeOther;
@@ -181,11 +175,7 @@ namespace JSC {
static const intptr_t FullTagTypeUndefined = TagBitTypeOther | ExtendedTagBitUndefined;
static const intptr_t FullTagTypeNull = TagBitTypeOther;
-#if USE(JSVALUE64)
static const int32_t IntegerPayloadShift = 0;
-#else
- static const int32_t IntegerPayloadShift = 1;
-#endif
static const int32_t ExtendedPayloadShift = 4;
static const intptr_t ExtendedPayloadBitBoolValue = 1 << ExtendedPayloadShift;
@@ -204,19 +194,13 @@ namespace JSC {
static ALWAYS_INLINE bool isIntegerNumber(JSValue v)
{
-#if USE(JSVALUE64)
return (rawValue(v) & TagTypeNumber) == TagTypeNumber;
-#else
- return isNumber(v);
-#endif
}
-#if USE(JSVALUE64)
static ALWAYS_INLINE bool isDouble(JSValue v)
{
return isNumber(v) && !isIntegerNumber(v);
}
-#endif
static ALWAYS_INLINE bool isPositiveIntegerNumber(JSValue v)
{
@@ -260,11 +244,7 @@ namespace JSC {
static ALWAYS_INLINE bool areBothImmediateIntegerNumbers(JSValue v1, JSValue v2)
{
-#if USE(JSVALUE64)
return (rawValue(v1) & rawValue(v2) & TagTypeNumber) == TagTypeNumber;
-#else
- return rawValue(v1) & rawValue(v2) & TagTypeNumber;
-#endif
}
static double toDouble(JSValue);
@@ -285,13 +265,8 @@ namespace JSC {
static JSValue oneImmediate();
private:
-#if USE(JSVALUE64)
static const int minImmediateInt = ((-INT_MAX) - 1);
static const int maxImmediateInt = INT_MAX;
-#else
- static const int minImmediateInt = ((-INT_MAX) - 1) >> IntegerPayloadShift;
- static const int maxImmediateInt = INT_MAX >> IntegerPayloadShift;
-#endif
static const unsigned maxImmediateUInt = maxImmediateInt;
static ALWAYS_INLINE JSValue makeValue(intptr_t integer)
@@ -302,21 +277,15 @@ namespace JSC {
// With USE(JSVALUE64) we want the argument to be zero extended, so the
// integer doesn't interfere with the tag bits in the upper word. In the default encoding,
// if intptr_t id larger then int32_t we sign extend the value through the upper word.
-#if USE(JSVALUE64)
static ALWAYS_INLINE JSValue makeInt(uint32_t value)
-#else
- static ALWAYS_INLINE JSValue makeInt(int32_t value)
-#endif
{
return makeValue((static_cast<intptr_t>(value) << IntegerPayloadShift) | TagTypeNumber);
}
-#if USE(JSVALUE64)
static ALWAYS_INLINE JSValue makeDouble(double value)
{
return makeValue(reinterpretDoubleToIntptr(value) + DoubleEncodeOffset);
}
-#endif
static ALWAYS_INLINE JSValue makeBool(bool b)
{
@@ -336,12 +305,10 @@ namespace JSC {
template<typename T>
static JSValue fromNumberOutsideIntegerRange(T);
-#if USE(JSVALUE64)
static ALWAYS_INLINE double doubleValue(JSValue v)
{
return reinterpretIntptrToDouble(rawValue(v) - DoubleEncodeOffset);
}
-#endif
static ALWAYS_INLINE int32_t intValue(JSValue v)
{
@@ -371,7 +338,6 @@ namespace JSC {
ALWAYS_INLINE JSValue JSImmediate::zeroImmediate() { return makeInt(0); }
ALWAYS_INLINE JSValue JSImmediate::oneImmediate() { return makeInt(1); }
-#if USE(JSVALUE64)
inline bool doubleToBoolean(double value)
{
return value < 0.0 || value > 0.0;
@@ -383,13 +349,6 @@ namespace JSC {
return isNumber(v) ? isIntegerNumber(v) ? v != zeroImmediate()
: doubleToBoolean(doubleValue(v)) : v == trueImmediate();
}
-#else
- ALWAYS_INLINE bool JSImmediate::toBoolean(JSValue v)
- {
- ASSERT(isImmediate(v));
- return isIntegerNumber(v) ? v != zeroImmediate() : v == trueImmediate();
- }
-#endif
ALWAYS_INLINE uint32_t JSImmediate::getTruncatedUInt32(JSValue v)
{
@@ -398,19 +357,11 @@ namespace JSC {
return intValue(v);
}
-#if USE(JSVALUE64)
template<typename T>
inline JSValue JSImmediate::fromNumberOutsideIntegerRange(T value)
{
return makeDouble(static_cast<double>(value));
}
-#else
- template<typename T>
- inline JSValue JSImmediate::fromNumberOutsideIntegerRange(T)
- {
- return JSValue();
- }
-#endif
ALWAYS_INLINE JSValue JSImmediate::from(char i)
{
@@ -439,10 +390,6 @@ namespace JSC {
ALWAYS_INLINE JSValue JSImmediate::from(int i)
{
-#if !USE(JSVALUE64)
- if ((i < minImmediateInt) | (i > maxImmediateInt))
- return fromNumberOutsideIntegerRange(i);
-#endif
return makeInt(i);
}
@@ -505,14 +452,10 @@ namespace JSC {
if (isIntegerNumber(v))
return intValue(v);
-#if USE(JSVALUE64)
if (isNumber(v)) {
ASSERT(isDouble(v));
return doubleValue(v);
}
-#else
- ASSERT(!isNumber(v));
-#endif
if (rawValue(v) == FullTagTypeUndefined)
return nonInlineNaN();
@@ -670,11 +613,7 @@ namespace JSC {
static ALWAYS_INLINE JSValue rightShiftImmediateNumbers(JSValue val, JSValue shift)
{
ASSERT(canDoFastRshift(val, shift) || canDoFastUrshift(val, shift));
-#if USE(JSVALUE64)
return JSImmediate::makeValue(static_cast<intptr_t>(static_cast<uint32_t>(static_cast<int32_t>(JSImmediate::rawValue(val)) >> ((JSImmediate::rawValue(shift) >> JSImmediate::IntegerPayloadShift) & 0x1f))) | JSImmediate::TagTypeNumber);
-#else
- return JSImmediate::makeValue((JSImmediate::rawValue(val) >> ((JSImmediate::rawValue(shift) >> JSImmediate::IntegerPayloadShift) & 0x1f)) | JSImmediate::TagTypeNumber);
-#endif
}
static ALWAYS_INLINE bool canDoFastAdditiveOperations(JSValue v)
@@ -718,6 +657,6 @@ namespace JSC {
} // namespace JSC
-#endif // !USE(JSVALUE32_64)
+#endif // USE(JSVALUE64)
#endif // JSImmediate_h
diff --git a/JavaScriptCore/runtime/JSNumberCell.cpp b/JavaScriptCore/runtime/JSNumberCell.cpp
index 77388e0..6fa6b2a 100644
--- a/JavaScriptCore/runtime/JSNumberCell.cpp
+++ b/JavaScriptCore/runtime/JSNumberCell.cpp
@@ -23,75 +23,6 @@
#include "config.h"
#include "JSNumberCell.h"
-#if USE(JSVALUE32)
-
-#include "NumberObject.h"
-#include "UString.h"
-
-namespace JSC {
-
-JSValue JSNumberCell::toPrimitive(ExecState*, PreferredPrimitiveType) const
-{
- return const_cast<JSNumberCell*>(this);
-}
-
-bool JSNumberCell::getPrimitiveNumber(ExecState*, double& number, JSValue& value)
-{
- number = m_value;
- value = this;
- return true;
-}
-
-bool JSNumberCell::toBoolean(ExecState*) const
-{
- return m_value < 0.0 || m_value > 0.0; // false for NaN
-}
-
-double JSNumberCell::toNumber(ExecState*) const
-{
- return m_value;
-}
-
-UString JSNumberCell::toString(ExecState*) const
-{
- return UString::number(m_value);
-}
-
-JSObject* JSNumberCell::toObject(ExecState* exec) const
-{
- return constructNumber(exec, const_cast<JSNumberCell*>(this));
-}
-
-JSObject* JSNumberCell::toThisObject(ExecState* exec) const
-{
- return constructNumber(exec, const_cast<JSNumberCell*>(this));
-}
-
-bool JSNumberCell::getUInt32(uint32_t& uint32) const
-{
- uint32 = static_cast<uint32_t>(m_value);
- return uint32 == m_value;
-}
-
-JSValue JSNumberCell::getJSNumber()
-{
- return this;
-}
-
-JSValue jsNumberCell(ExecState* exec, double d)
-{
- return new (exec) JSNumberCell(exec, d);
-}
-
-JSValue jsNumberCell(JSGlobalData* globalData, double d)
-{
- return new (globalData) JSNumberCell(globalData, d);
-}
-
-} // namespace JSC
-
-#else // USE(JSVALUE32)
-
// Keep our exported symbols lists happy.
namespace JSC {
@@ -105,4 +36,3 @@ JSValue jsNumberCell(ExecState*, double)
} // namespace JSC
-#endif // USE(JSVALUE32)
diff --git a/JavaScriptCore/runtime/JSNumberCell.h b/JavaScriptCore/runtime/JSNumberCell.h
index cdd2d8c..a25c531 100644
--- a/JavaScriptCore/runtime/JSNumberCell.h
+++ b/JavaScriptCore/runtime/JSNumberCell.h
@@ -35,167 +35,6 @@ namespace JSC {
extern const double NaN;
extern const double Inf;
-#if USE(JSVALUE32)
- JSValue jsNumberCell(ExecState*, double);
-
- class Identifier;
- class JSCell;
- class JSObject;
- class JSString;
- class PropertySlot;
-
- struct ClassInfo;
- struct Instruction;
-
- class JSNumberCell : public JSCell {
- friend class JIT;
- friend JSValue jsNumberCell(JSGlobalData*, double);
- friend JSValue jsNumberCell(ExecState*, double);
-
- public:
- double value() const { return m_value; }
-
- virtual JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
- virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue& value);
- virtual bool toBoolean(ExecState*) const;
- virtual double toNumber(ExecState*) const;
- virtual UString toString(ExecState*) const;
- virtual JSObject* toObject(ExecState*) const;
-
- virtual JSObject* toThisObject(ExecState*) const;
- virtual JSValue getJSNumber();
-
- void* operator new(size_t size, ExecState* exec)
- {
- return exec->heap()->allocateNumber(size);
- }
-
- void* operator new(size_t size, JSGlobalData* globalData)
- {
- return globalData->heap.allocateNumber(size);
- }
-
- static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(NumberType, OverridesGetOwnPropertySlot | NeedsThisConversion), AnonymousSlotCount); }
-
- private:
- JSNumberCell(JSGlobalData* globalData, double value)
- : JSCell(globalData->numberStructure.get())
- , m_value(value)
- {
- }
-
- JSNumberCell(ExecState* exec, double value)
- : JSCell(exec->globalData().numberStructure.get())
- , m_value(value)
- {
- }
-
- virtual bool getUInt32(uint32_t&) const;
-
- double m_value;
- };
-
- JSValue jsNumberCell(JSGlobalData*, double);
-
- inline bool isNumberCell(JSValue v)
- {
- return v.isCell() && v.asCell()->isNumber();
- }
-
- inline JSNumberCell* asNumberCell(JSValue v)
- {
- ASSERT(isNumberCell(v));
- return static_cast<JSNumberCell*>(v.asCell());
- }
-
- ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, ExecState* exec, double d)
- {
- *this = jsNumberCell(exec, d);
- }
-
- inline JSValue::JSValue(ExecState* exec, double d)
- {
- JSValue v = JSImmediate::from(d);
- *this = v ? v : jsNumberCell(exec, d);
- }
-
- inline JSValue::JSValue(ExecState* exec, int i)
- {
- JSValue v = JSImmediate::from(i);
- *this = v ? v : jsNumberCell(exec, i);
- }
-
- inline JSValue::JSValue(ExecState* exec, unsigned i)
- {
- JSValue v = JSImmediate::from(i);
- *this = v ? v : jsNumberCell(exec, i);
- }
-
- inline JSValue::JSValue(ExecState* exec, long i)
- {
- JSValue v = JSImmediate::from(i);
- *this = v ? v : jsNumberCell(exec, i);
- }
-
- inline JSValue::JSValue(ExecState* exec, unsigned long i)
- {
- JSValue v = JSImmediate::from(i);
- *this = v ? v : jsNumberCell(exec, i);
- }
-
- inline JSValue::JSValue(ExecState* exec, long long i)
- {
- JSValue v = JSImmediate::from(i);
- *this = v ? v : jsNumberCell(exec, static_cast<double>(i));
- }
-
- inline JSValue::JSValue(ExecState* exec, unsigned long long i)
- {
- JSValue v = JSImmediate::from(i);
- *this = v ? v : jsNumberCell(exec, static_cast<double>(i));
- }
-
- inline JSValue::JSValue(JSGlobalData* globalData, double d)
- {
- JSValue v = JSImmediate::from(d);
- *this = v ? v : jsNumberCell(globalData, d);
- }
-
- inline JSValue::JSValue(JSGlobalData* globalData, int i)
- {
- JSValue v = JSImmediate::from(i);
- *this = v ? v : jsNumberCell(globalData, i);
- }
-
- inline JSValue::JSValue(JSGlobalData* globalData, unsigned i)
- {
- JSValue v = JSImmediate::from(i);
- *this = v ? v : jsNumberCell(globalData, i);
- }
-
- inline bool JSValue::isDouble() const
- {
- return isNumberCell(asValue());
- }
-
- inline double JSValue::asDouble() const
- {
- return asNumberCell(asValue())->value();
- }
-
- inline bool JSValue::isNumber() const
- {
- return JSImmediate::isNumber(asValue()) || isDouble();
- }
-
- inline double JSValue::uncheckedGetNumber() const
- {
- ASSERT(isNumber());
- return JSImmediate::isImmediate(asValue()) ? JSImmediate::toDouble(asValue()) : asDouble();
- }
-
-#endif // USE(JSVALUE32)
-
#if USE(JSVALUE64)
ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, ExecState*, double d)
{
@@ -295,7 +134,7 @@ namespace JSC {
#endif // USE(JSVALUE64)
-#if USE(JSVALUE32) || USE(JSVALUE64)
+#if USE(JSVALUE64)
inline JSValue::JSValue(ExecState*, char i)
{
@@ -351,7 +190,7 @@ namespace JSC {
return true;
}
-#endif // USE(JSVALUE32) || USE(JSVALUE64)
+#endif // USE(JSVALUE64)
} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSONObject.cpp b/JavaScriptCore/runtime/JSONObject.cpp
index ba50721..0794189 100644
--- a/JavaScriptCore/runtime/JSONObject.cpp
+++ b/JavaScriptCore/runtime/JSONObject.cpp
@@ -34,8 +34,8 @@
#include "LiteralParser.h"
#include "Lookup.h"
#include "PropertyNameArray.h"
-#include "StringBuilder.h"
-#include "StringConcatenate.h"
+#include "UStringBuilder.h"
+#include "UStringConcatenate.h"
#include <wtf/MathExtras.h>
namespace JSC {
@@ -85,7 +85,7 @@ private:
JSObject* object() const { return m_object; }
- bool appendNextProperty(Stringifier&, StringBuilder&);
+ bool appendNextProperty(Stringifier&, UStringBuilder&);
private:
JSObject* const m_object;
@@ -98,17 +98,17 @@ private:
friend class Holder;
- static void appendQuotedString(StringBuilder&, const UString&);
+ static void appendQuotedString(UStringBuilder&, const UString&);
JSValue toJSON(JSValue, const PropertyNameForFunctionCall&);
enum StringifyResult { StringifyFailed, StringifySucceeded, StringifyFailedDueToUndefinedValue };
- StringifyResult appendStringifiedValue(StringBuilder&, JSValue, JSObject* holder, const PropertyNameForFunctionCall&);
+ StringifyResult appendStringifiedValue(UStringBuilder&, JSValue, JSObject* holder, const PropertyNameForFunctionCall&);
bool willIndent() const;
void indent();
void unindent();
- void startNewLine(StringBuilder&) const;
+ void startNewLine(UStringBuilder&) const;
Stringifier* const m_nextStringifierToMark;
ExecState* const m_exec;
@@ -270,21 +270,21 @@ JSValue Stringifier::stringify(JSValue value)
PropertyNameForFunctionCall emptyPropertyName(m_exec->globalData().propertyNames->emptyIdentifier);
object->putDirect(m_exec->globalData().propertyNames->emptyIdentifier, value);
- StringBuilder result;
+ UStringBuilder result;
if (appendStringifiedValue(result, value, object, emptyPropertyName) != StringifySucceeded)
return jsUndefined();
if (m_exec->hadException())
return jsNull();
- return jsString(m_exec, result.build());
+ return jsString(m_exec, result.toUString());
}
-void Stringifier::appendQuotedString(StringBuilder& builder, const UString& value)
+void Stringifier::appendQuotedString(UStringBuilder& builder, const UString& value)
{
int length = value.length();
// String length plus 2 for quote marks plus 8 so we can accomodate a few escaped characters.
- builder.reserveCapacity(builder.size() + length + 2 + 8);
+ builder.reserveCapacity(builder.length() + length + 2 + 8);
builder.append('"');
@@ -361,7 +361,7 @@ inline JSValue Stringifier::toJSON(JSValue value, const PropertyNameForFunctionC
return call(m_exec, object, callType, callData, value, args);
}
-Stringifier::StringifyResult Stringifier::appendStringifiedValue(StringBuilder& builder, JSValue value, JSObject* holder, const PropertyNameForFunctionCall& propertyName)
+Stringifier::StringifyResult Stringifier::appendStringifiedValue(UStringBuilder& builder, JSValue value, JSObject* holder, const PropertyNameForFunctionCall& propertyName)
{
// Call the toJSON function.
value = toJSON(value, propertyName);
@@ -466,7 +466,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 = makeString(m_repeatedGap, m_gap);
+ m_repeatedGap = makeUString(m_repeatedGap, m_gap);
ASSERT(newSize <= m_repeatedGap.length());
m_indent = m_repeatedGap.substringSharingImpl(0, newSize);
}
@@ -477,7 +477,7 @@ inline void Stringifier::unindent()
m_indent = m_repeatedGap.substringSharingImpl(0, m_indent.length() - m_gap.length());
}
-inline void Stringifier::startNewLine(StringBuilder& builder) const
+inline void Stringifier::startNewLine(UStringBuilder& builder) const
{
if (m_gap.isEmpty())
return;
@@ -492,7 +492,7 @@ inline Stringifier::Holder::Holder(JSObject* object)
{
}
-bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, StringBuilder& builder)
+bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, UStringBuilder& builder)
{
ASSERT(m_index <= m_size);
@@ -521,7 +521,7 @@ bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, StringBui
// Last time through, finish up and return false.
if (m_index == m_size) {
stringifier.unindent();
- if (m_size && builder[builder.size() - 1] != '{')
+ if (m_size && builder[builder.length() - 1] != '{')
stringifier.startNewLine(builder);
builder.append(m_isArray ? ']' : '}');
return false;
@@ -562,7 +562,7 @@ bool Stringifier::Holder::appendNextProperty(Stringifier& stringifier, StringBui
if (exec->hadException())
return false;
- rollBackPoint = builder.size();
+ rollBackPoint = builder.length();
// Append the separator string.
if (builder[rollBackPoint - 1] != '{')
diff --git a/JavaScriptCore/runtime/JSObject.cpp b/JavaScriptCore/runtime/JSObject.cpp
index cabc428..30e40e4 100644
--- a/JavaScriptCore/runtime/JSObject.cpp
+++ b/JavaScriptCore/runtime/JSObject.cpp
@@ -43,6 +43,8 @@ namespace JSC {
ASSERT_CLASS_FITS_IN_CELL(JSObject);
+const char* StrictModeReadonlyPropertyWriteError = "Attempted to assign to readonly property.";
+
static inline void getClassPropertyNames(ExecState* exec, const ClassInfo* classInfo, PropertyNameArray& propertyNames, EnumerationMode mode)
{
// Add properties from the static hashtables of properties
@@ -114,15 +116,19 @@ void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValue valu
for (JSObject* obj = this; !obj->structure()->hasGetterSetterProperties(); obj = asObject(prototype)) {
prototype = obj->prototype();
if (prototype.isNull()) {
- putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot);
+ if (!putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot) && slot.isStrictMode())
+ throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
return;
}
}
unsigned attributes;
JSCell* specificValue;
- if ((m_structure->get(propertyName, attributes, specificValue) != WTF::notFound) && attributes & ReadOnly)
+ if ((m_structure->get(propertyName, attributes, specificValue) != WTF::notFound) && attributes & ReadOnly) {
+ if (slot.isStrictMode())
+ throwError(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError));
return;
+ }
for (JSObject* obj = this; ; obj = asObject(prototype)) {
if (JSValue gs = obj->getDirect(propertyName)) {
@@ -151,7 +157,8 @@ void JSObject::put(ExecState* exec, const Identifier& propertyName, JSValue valu
break;
}
- putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot);
+ if (!putDirectInternal(exec->globalData(), propertyName, value, 0, true, slot) && slot.isStrictMode())
+ throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
return;
}
@@ -489,6 +496,11 @@ JSObject* JSObject::toThisObject(ExecState*) const
return const_cast<JSObject*>(this);
}
+JSValue JSObject::toStrictThisObject(ExecState*) const
+{
+ return const_cast<JSObject*>(this);
+}
+
JSObject* JSObject::unwrappedObject()
{
return this;
@@ -702,4 +714,9 @@ bool JSObject::defineOwnProperty(ExecState* exec, const Identifier& propertyName
return true;
}
+JSObject* throwTypeError(ExecState* exec, const UString& message)
+{
+ return throwError(exec, createTypeError(exec, message));
+}
+
} // namespace JSC
diff --git a/JavaScriptCore/runtime/JSObject.h b/JavaScriptCore/runtime/JSObject.h
index 4201703..8981469 100644
--- a/JavaScriptCore/runtime/JSObject.h
+++ b/JavaScriptCore/runtime/JSObject.h
@@ -55,6 +55,9 @@ namespace JSC {
class Structure;
struct HashTable;
+ JSObject* throwTypeError(ExecState*, const UString&);
+ extern const char* StrictModeReadonlyPropertyWriteError;
+
// ECMA 262-3 8.6.1
// Property attributes
enum Attribute {
@@ -140,6 +143,7 @@ namespace JSC {
virtual JSObject* toObject(ExecState*) const;
virtual JSObject* toThisObject(ExecState*) const;
+ virtual JSValue toStrictThisObject(ExecState*) const;
virtual JSObject* unwrappedObject();
bool getPropertySpecificValue(ExecState* exec, const Identifier& propertyName, JSCell*& specificFunction) const;
@@ -175,9 +179,9 @@ namespace JSC {
bool hasCustomProperties() { return !m_structure->isEmpty(); }
bool hasGetterSetterProperties() { return m_structure->hasGetterSetterProperties(); }
- void putDirect(const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
+ bool putDirect(const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
void putDirect(const Identifier& propertyName, JSValue value, unsigned attr = 0);
- void putDirect(const Identifier& propertyName, JSValue value, PutPropertySlot&);
+ bool putDirect(const Identifier& propertyName, JSValue value, PutPropertySlot&);
void putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attr = 0);
void putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
@@ -205,6 +209,7 @@ namespace JSC {
virtual bool isVariableObject() const { return false; }
virtual bool isActivationObject() const { return false; }
virtual bool isNotAnObjectErrorStub() const { return false; }
+ virtual bool isStrictModeFunction() const { return false; }
virtual ComplType exceptionType() const { return Throw; }
@@ -248,9 +253,6 @@ namespace JSC {
void getString(ExecState* exec);
void isObject();
void isString();
-#if USE(JSVALUE32)
- void isNumber();
-#endif
ConstPropertyStorage propertyStorage() const { return (isUsingInlineStorage() ? m_inlineStorage : m_externalStorage); }
PropertyStorage propertyStorage() { return (isUsingInlineStorage() ? m_inlineStorage : m_externalStorage); }
@@ -265,8 +267,8 @@ namespace JSC {
return reinterpret_cast<JSValue*>(&propertyStorage()[offset]);
}
- void putDirectInternal(const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot, JSCell*);
- void putDirectInternal(JSGlobalData&, const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
+ bool putDirectInternal(const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot, JSCell*);
+ bool putDirectInternal(JSGlobalData&, const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
void putDirectInternal(JSGlobalData&, const Identifier& propertyName, JSValue value, unsigned attr = 0);
bool inlineGetOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
@@ -299,9 +301,7 @@ inline JSObject::JSObject(NonNullPassRefPtr<Structure> structure)
ASSERT(m_structure->propertyStorageCapacity() == inlineStorageCapacity);
ASSERT(m_structure->isEmpty());
ASSERT(prototype().isNull() || Heap::heap(this) == Heap::heap(prototype()));
-#if USE(JSVALUE64) || USE(JSVALUE32_64)
ASSERT(OBJECT_OFFSETOF(JSObject, m_inlineStorage) % sizeof(double) == 0);
-#endif
}
inline JSObject::~JSObject()
@@ -450,7 +450,7 @@ inline JSValue JSObject::get(ExecState* exec, unsigned propertyName) const
return jsUndefined();
}
-inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot, JSCell* specificFunction)
+inline bool JSObject::putDirectInternal(const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot, JSCell* specificFunction)
{
ASSERT(value);
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
@@ -465,7 +465,8 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue
if (currentSpecificFunction && (specificFunction != currentSpecificFunction))
m_structure->despecifyDictionaryFunction(propertyName);
if (checkReadOnly && currentAttributes & ReadOnly)
- return;
+ return false;
+
putDirectOffset(offset, value);
// At this point, the objects structure only has a specific value set if previously there
// had been one set, and if the new value being specified is the same (otherwise we would
@@ -475,7 +476,7 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue
// If there was previously a value, and the new value is the same, then we cannot cache.
if (!currentSpecificFunction || (specificFunction != currentSpecificFunction))
slot.setExistingProperty(this, offset);
- return;
+ return true;
}
size_t currentCapacity = m_structure->propertyStorageCapacity();
@@ -488,7 +489,7 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue
// See comment on setNewProperty call below.
if (!specificFunction)
slot.setNewProperty(this, offset);
- return;
+ return true;
}
size_t offset;
@@ -504,7 +505,7 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue
// so leave the slot in an uncachable state.
if (!specificFunction)
slot.setNewProperty(this, offset);
- return;
+ return true;
}
unsigned currentAttributes;
@@ -512,7 +513,7 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue
offset = m_structure->get(propertyName, currentAttributes, currentSpecificFunction);
if (offset != WTF::notFound) {
if (checkReadOnly && currentAttributes & ReadOnly)
- return;
+ return false;
// There are three possibilities here:
// (1) There is an existing specific value set, and we're overwriting with *the same value*.
@@ -527,7 +528,7 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue
// case (1) Do the put, then return leaving the slot uncachable.
if (specificFunction == currentSpecificFunction) {
putDirectOffset(offset, value);
- return;
+ return true;
}
// case (2) Despecify, fall through to (3).
setStructure(Structure::despecifyFunctionTransition(m_structure, propertyName));
@@ -536,7 +537,7 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue
// case (3) set the slot, do the put, return.
slot.setExistingProperty(this, offset);
putDirectOffset(offset, value);
- return;
+ return true;
}
// If we have a specific function, we may have got to this point if there is
@@ -561,14 +562,15 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue
// so leave the slot in an uncachable state.
if (!specificFunction)
slot.setNewProperty(this, offset);
+ return true;
}
-inline void JSObject::putDirectInternal(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
+inline bool JSObject::putDirectInternal(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
{
ASSERT(value);
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
- putDirectInternal(propertyName, value, attributes, checkReadOnly, slot, getJSFunction(globalData, value));
+ return putDirectInternal(propertyName, value, attributes, checkReadOnly, slot, getJSFunction(globalData, value));
}
inline void JSObject::putDirectInternal(JSGlobalData& globalData, const Identifier& propertyName, JSValue value, unsigned attributes)
@@ -577,12 +579,12 @@ inline void JSObject::putDirectInternal(JSGlobalData& globalData, const Identifi
putDirectInternal(propertyName, value, attributes, false, slot, getJSFunction(globalData, value));
}
-inline void JSObject::putDirect(const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
+inline bool JSObject::putDirect(const Identifier& propertyName, JSValue value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
{
ASSERT(value);
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
- putDirectInternal(propertyName, value, attributes, checkReadOnly, slot, 0);
+ return putDirectInternal(propertyName, value, attributes, checkReadOnly, slot, 0);
}
inline void JSObject::putDirect(const Identifier& propertyName, JSValue value, unsigned attributes)
@@ -591,9 +593,9 @@ inline void JSObject::putDirect(const Identifier& propertyName, JSValue value, u
putDirectInternal(propertyName, value, attributes, false, slot, 0);
}
-inline void JSObject::putDirect(const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
+inline bool JSObject::putDirect(const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
- putDirectInternal(propertyName, value, 0, false, slot, 0);
+ return putDirectInternal(propertyName, value, 0, false, slot, 0);
}
inline void JSObject::putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attributes, bool checkReadOnly, PutPropertySlot& slot)
@@ -698,10 +700,11 @@ inline void JSValue::put(ExecState* exec, const Identifier& propertyName, JSValu
asCell()->put(exec, propertyName, value, slot);
}
-inline void JSValue::putDirect(ExecState*, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
+inline void JSValue::putDirect(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
{
ASSERT(isCell() && isObject());
- asObject(asCell())->putDirect(propertyName, value, slot);
+ if (!asObject(asCell())->putDirect(propertyName, value, slot) && slot.isStrictMode())
+ throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
}
inline void JSValue::put(ExecState* exec, unsigned propertyName, JSValue value)
@@ -756,6 +759,13 @@ inline JSString* JSValue::toThisJSString(ExecState* exec) const
return isString() ? static_cast<JSString*>(asCell()) : jsString(exec, toThisObject(exec)->toString(exec));
}
+inline JSValue JSValue::toStrictThisObject(ExecState* exec) const
+{
+ if (!isObject())
+ return *this;
+ return asObject(asCell())->toStrictThisObject(exec);
+}
+
} // namespace JSC
#endif // JSObject_h
diff --git a/JavaScriptCore/runtime/JSStaticScopeObject.cpp b/JavaScriptCore/runtime/JSStaticScopeObject.cpp
index ad10218..7ab1d1c 100644
--- a/JavaScriptCore/runtime/JSStaticScopeObject.cpp
+++ b/JavaScriptCore/runtime/JSStaticScopeObject.cpp
@@ -42,6 +42,11 @@ JSObject* JSStaticScopeObject::toThisObject(ExecState* exec) const
return exec->globalThisValue();
}
+JSValue JSStaticScopeObject::toStrictThisObject(ExecState*) const
+{
+ return jsNull();
+}
+
void JSStaticScopeObject::put(ExecState*, const Identifier& propertyName, JSValue value, PutPropertySlot&)
{
if (symbolTablePut(propertyName, value))
diff --git a/JavaScriptCore/runtime/JSStaticScopeObject.h b/JavaScriptCore/runtime/JSStaticScopeObject.h
index c0519c1..e69356a 100644
--- a/JavaScriptCore/runtime/JSStaticScopeObject.h
+++ b/JavaScriptCore/runtime/JSStaticScopeObject.h
@@ -53,6 +53,7 @@ namespace JSC{
virtual void markChildren(MarkStack&);
bool isDynamicScope(bool& requiresDynamicChecks) const;
virtual JSObject* toThisObject(ExecState*) const;
+ virtual JSValue toStrictThisObject(ExecState*) const;
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&);
void putWithAttributes(ExecState*, const Identifier&, JSValue, unsigned attributes);
diff --git a/JavaScriptCore/runtime/JSStringBuilder.h b/JavaScriptCore/runtime/JSStringBuilder.h
index 25fe685..49d4a63 100644
--- a/JavaScriptCore/runtime/JSStringBuilder.h
+++ b/JavaScriptCore/runtime/JSStringBuilder.h
@@ -28,7 +28,7 @@
#include "ExceptionHelpers.h"
#include "JSString.h"
-#include "StringConcatenate.h"
+#include "UStringConcatenate.h"
#include "Vector.h"
namespace JSC {
@@ -87,7 +87,7 @@ protected:
template<typename StringType1, typename StringType2>
inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2)
{
- PassRefPtr<StringImpl> result = tryMakeString(string1, string2);
+ PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2);
if (!result)
return throwOutOfMemoryError(exec);
return jsNontrivialString(exec, result);
@@ -96,7 +96,7 @@ inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, Stri
template<typename StringType1, typename StringType2, typename StringType3>
inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3)
{
- PassRefPtr<StringImpl> result = tryMakeString(string1, string2, string3);
+ PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3);
if (!result)
return throwOutOfMemoryError(exec);
return jsNontrivialString(exec, result);
@@ -105,7 +105,7 @@ inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, Stri
template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
{
- PassRefPtr<StringImpl> result = tryMakeString(string1, string2, string3, string4);
+ PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3, string4);
if (!result)
return throwOutOfMemoryError(exec);
return jsNontrivialString(exec, result);
@@ -114,7 +114,7 @@ inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, Stri
template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
{
- PassRefPtr<StringImpl> result = tryMakeString(string1, string2, string3, string4, string5);
+ PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3, string4, string5);
if (!result)
return throwOutOfMemoryError(exec);
return jsNontrivialString(exec, result);
@@ -123,7 +123,7 @@ inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, Stri
template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
{
- PassRefPtr<StringImpl> result = tryMakeString(string1, string2, string3, string4, string5, string6);
+ PassRefPtr<StringImpl> result = WTF::tryMakeString(string1, string2, string3, string4, string5, string6);
if (!result)
return throwOutOfMemoryError(exec);
return jsNontrivialString(exec, result);
diff --git a/JavaScriptCore/runtime/JSValue.h b/JavaScriptCore/runtime/JSValue.h
index b5834c1..b5dcbec 100644
--- a/JavaScriptCore/runtime/JSValue.h
+++ b/JavaScriptCore/runtime/JSValue.h
@@ -80,7 +80,7 @@ namespace JSC {
public:
static EncodedJSValue encode(JSValue value);
static JSValue decode(EncodedJSValue ptr);
-#if !USE(JSVALUE32_64)
+#if USE(JSVALUE64)
private:
static JSValue makeImmediate(intptr_t value);
intptr_t immediateValue();
@@ -193,6 +193,7 @@ namespace JSC {
bool needsThisConversion() const;
JSObject* toThisObject(ExecState*) const;
+ JSValue toStrictThisObject(ExecState*) const;
UString toThisString(ExecState*) const;
JSString* toThisJSString(ExecState*) const;
diff --git a/JavaScriptCore/runtime/JSZombie.h b/JavaScriptCore/runtime/JSZombie.h
index 711f673..da45699 100644
--- a/JavaScriptCore/runtime/JSZombie.h
+++ b/JavaScriptCore/runtime/JSZombie.h
@@ -60,6 +60,7 @@ public:
virtual bool deleteProperty(ExecState*, const Identifier&) { ASSERT_NOT_REACHED(); return false; }
virtual bool deleteProperty(ExecState*, unsigned) { ASSERT_NOT_REACHED(); return false; }
virtual JSObject* toThisObject(ExecState*) const { ASSERT_NOT_REACHED(); return 0; }
+ virtual JSValue toStrictThisObject(ExecState*) const { ASSERT_NOT_REACHED(); return JSValue(); }
virtual JSValue getJSNumber() { ASSERT_NOT_REACHED(); return jsNull(); }
virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&) { ASSERT_NOT_REACHED(); return false; }
virtual bool getOwnPropertySlot(ExecState*, unsigned, PropertySlot&) { ASSERT_NOT_REACHED(); return false; }
diff --git a/JavaScriptCore/runtime/LiteralParser.cpp b/JavaScriptCore/runtime/LiteralParser.cpp
index cc33bae..f1df15f 100644
--- a/JavaScriptCore/runtime/LiteralParser.cpp
+++ b/JavaScriptCore/runtime/LiteralParser.cpp
@@ -29,7 +29,7 @@
#include "JSArray.h"
#include "JSString.h"
#include "Lexer.h"
-#include "StringBuilder.h"
+#include "UStringBuilder.h"
#include <wtf/ASCIICType.h>
#include <wtf/dtoa.h>
@@ -135,7 +135,7 @@ template <LiteralParser::ParserMode mode> inline LiteralParser::TokenType Litera
{
++m_ptr;
const UChar* runStart;
- StringBuilder builder;
+ UStringBuilder builder;
do {
runStart = m_ptr;
while (m_ptr < m_end && isSafeStringCharacter<mode>(*m_ptr))
@@ -200,7 +200,7 @@ template <LiteralParser::ParserMode mode> inline LiteralParser::TokenType Litera
if (m_ptr >= m_end || *m_ptr != '"')
return TokError;
- token.stringToken = builder.build();
+ token.stringToken = builder.toUString();
token.type = TokString;
token.end = ++m_ptr;
return TokString;
diff --git a/JavaScriptCore/runtime/NumberObject.h b/JavaScriptCore/runtime/NumberObject.h
index 6c18cdd..e82b593 100644
--- a/JavaScriptCore/runtime/NumberObject.h
+++ b/JavaScriptCore/runtime/NumberObject.h
@@ -37,11 +37,7 @@ namespace JSC {
}
protected:
-#if USE(JSVALUE32)
- static const unsigned StructureFlags = OverridesMarkChildren | JSWrapperObject::StructureFlags;
-#else
static const unsigned StructureFlags = JSWrapperObject::StructureFlags;
-#endif
private:
virtual const ClassInfo* classInfo() const { return &info; }
diff --git a/JavaScriptCore/runtime/NumberPrototype.cpp b/JavaScriptCore/runtime/NumberPrototype.cpp
index e18553b..4a2ca74 100644
--- a/JavaScriptCore/runtime/NumberPrototype.cpp
+++ b/JavaScriptCore/runtime/NumberPrototype.cpp
@@ -25,10 +25,8 @@
#include "Error.h"
#include "JSFunction.h"
#include "JSString.h"
-#include "JSStringBuilder.h"
#include "Operations.h"
#include "PrototypeFunction.h"
-#include "StringBuilder.h"
#include "dtoa.h"
#include <wtf/Assertions.h>
#include <wtf/DecimalNumber.h>
@@ -119,8 +117,8 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToExponential(ExecState* exec)
// Round if the argument is not undefined, always format as exponential.
NumberToStringBuffer buffer;
unsigned length = isUndefined
- ? DecimalNumber(x).toStringExponential(buffer)
- : DecimalNumber(x, RoundingSignificantFigures, decimalPlacesInExponent + 1).toStringExponential(buffer);
+ ? DecimalNumber(x).toStringExponential(buffer, WTF::NumberToStringBufferLength)
+ : DecimalNumber(x, RoundingSignificantFigures, decimalPlacesInExponent + 1).toStringExponential(buffer, WTF::NumberToStringBufferLength);
return JSValue::encode(jsString(exec, UString(buffer, length)));
}
@@ -156,7 +154,7 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState* exec)
// Convert to decimal with rounding, and format as decimal.
NumberToStringBuffer buffer;
- unsigned length = DecimalNumber(x, RoundingDecimalPlaces, decimalPlaces).toStringDecimal(buffer);
+ unsigned length = DecimalNumber(x, RoundingDecimalPlaces, decimalPlaces).toStringDecimal(buffer, WTF::NumberToStringBufferLength);
return JSValue::encode(jsString(exec, UString(buffer, length)));
}
@@ -198,8 +196,8 @@ EncodedJSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec)
// 1234 (1.234e+3) requires 4 digits. (See ECMA-262 15.7.4.7.10.c)
NumberToStringBuffer buffer;
unsigned length = number.exponent() >= -6 && number.exponent() < significantFigures
- ? number.toStringDecimal(buffer)
- : number.toStringExponential(buffer);
+ ? number.toStringDecimal(buffer, WTF::NumberToStringBufferLength)
+ : number.toStringExponential(buffer, WTF::NumberToStringBufferLength);
return JSValue::encode(jsString(exec, UString(buffer, length)));
}
diff --git a/JavaScriptCore/runtime/Operations.h b/JavaScriptCore/runtime/Operations.h
index eed1f16..9226953 100644
--- a/JavaScriptCore/runtime/Operations.h
+++ b/JavaScriptCore/runtime/Operations.h
@@ -460,7 +460,7 @@ namespace JSC {
}
}
- ALWAYS_INLINE JSValue resolveBase(CallFrame* callFrame, Identifier& property, ScopeChainNode* scopeChain)
+ ALWAYS_INLINE JSValue resolveBase(CallFrame* callFrame, Identifier& property, ScopeChainNode* scopeChain, bool isStrictPut)
{
ScopeChainIterator iter = scopeChain->begin();
ScopeChainIterator next = iter;
@@ -472,7 +472,9 @@ namespace JSC {
JSObject* base;
while (true) {
base = *iter;
- if (next == end || base->getPropertySlot(callFrame, property, slot))
+ if (next == end)
+ return isStrictPut ? JSValue() : base;
+ if (base->getPropertySlot(callFrame, property, slot))
return base;
iter = next;
diff --git a/JavaScriptCore/runtime/PutPropertySlot.h b/JavaScriptCore/runtime/PutPropertySlot.h
index eb8ea8a..4b0b394 100644
--- a/JavaScriptCore/runtime/PutPropertySlot.h
+++ b/JavaScriptCore/runtime/PutPropertySlot.h
@@ -38,9 +38,10 @@ namespace JSC {
public:
enum Type { Uncachable, ExistingProperty, NewProperty };
- PutPropertySlot()
+ PutPropertySlot(bool isStrictMode = false)
: m_type(Uncachable)
, m_base(0)
+ , m_isStrictMode(isStrictMode)
{
}
@@ -61,6 +62,7 @@ namespace JSC {
Type type() const { return m_type; }
JSObject* base() const { return m_base; }
+ bool isStrictMode() const { return m_isStrictMode; }
bool isCacheable() const { return m_type != Uncachable; }
size_t cachedOffset() const {
ASSERT(isCacheable());
@@ -70,6 +72,7 @@ namespace JSC {
Type m_type;
JSObject* m_base;
size_t m_offset;
+ bool m_isStrictMode;
};
} // namespace JSC
diff --git a/JavaScriptCore/runtime/RegExpConstructor.cpp b/JavaScriptCore/runtime/RegExpConstructor.cpp
index 214e528..b9aa587 100644
--- a/JavaScriptCore/runtime/RegExpConstructor.cpp
+++ b/JavaScriptCore/runtime/RegExpConstructor.cpp
@@ -35,7 +35,7 @@
#include "RegExpPrototype.h"
#include "RegExp.h"
#include "RegExpCache.h"
-#include "StringConcatenate.h"
+#include "UStringConcatenate.h"
#include <wtf/PassOwnPtr.h>
namespace JSC {
@@ -307,7 +307,7 @@ JSObject* constructRegExp(ExecState* exec, const ArgList& args)
RefPtr<RegExp> regExp = exec->globalData().regExpCache()->lookupOrCreate(pattern, flags);
if (!regExp->isValid())
- return throwError(exec, createSyntaxError(exec, makeString("Invalid regular expression: ", regExp->errorMessage())));
+ return throwError(exec, createSyntaxError(exec, makeUString("Invalid regular expression: ", regExp->errorMessage())));
return new (exec) RegExpObject(exec->lexicalGlobalObject(), exec->lexicalGlobalObject()->regExpStructure(), regExp.release());
}
diff --git a/JavaScriptCore/runtime/RegExpObject.cpp b/JavaScriptCore/runtime/RegExpObject.cpp
index 4462879..7d14814 100644
--- a/JavaScriptCore/runtime/RegExpObject.cpp
+++ b/JavaScriptCore/runtime/RegExpObject.cpp
@@ -29,7 +29,7 @@
#include "Lookup.h"
#include "RegExpConstructor.h"
#include "RegExpPrototype.h"
-#include "StringConcatenate.h"
+#include "UStringConcatenate.h"
#include <wtf/PassOwnPtr.h>
namespace JSC {
@@ -146,7 +146,7 @@ bool RegExpObject::match(ExecState* exec)
UString input = !exec->argumentCount() ? regExpConstructor->input() : exec->argument(0).toString(exec);
if (input.isNull()) {
- throwError(exec, createError(exec, makeString("No input to ", toString(exec), ".")));
+ throwError(exec, createError(exec, makeUString("No input to ", toString(exec), ".")));
return false;
}
diff --git a/JavaScriptCore/runtime/RegExpPrototype.cpp b/JavaScriptCore/runtime/RegExpPrototype.cpp
index d66f5d7..0a4c8bf 100644
--- a/JavaScriptCore/runtime/RegExpPrototype.cpp
+++ b/JavaScriptCore/runtime/RegExpPrototype.cpp
@@ -34,6 +34,7 @@
#include "RegExpObject.h"
#include "RegExp.h"
#include "RegExpCache.h"
+#include "UStringConcatenate.h"
namespace JSC {
@@ -94,7 +95,7 @@ EncodedJSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState* exec)
}
if (!regExp->isValid())
- return throwVMError(exec, createSyntaxError(exec, makeString("Invalid regular expression: ", regExp->errorMessage())));
+ return throwVMError(exec, createSyntaxError(exec, makeUString("Invalid regular expression: ", regExp->errorMessage())));
asRegExpObject(thisValue)->setRegExp(regExp.release());
asRegExpObject(thisValue)->setLastIndex(0);
diff --git a/JavaScriptCore/runtime/StrictEvalActivation.cpp b/JavaScriptCore/runtime/StrictEvalActivation.cpp
new file mode 100644
index 0000000..5bb013b
--- /dev/null
+++ b/JavaScriptCore/runtime/StrictEvalActivation.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "StrictEvalActivation.h"
+
+namespace JSC {
+
+StrictEvalActivation::StrictEvalActivation(ExecState* exec)
+ : JSObject(exec->globalData().strictEvalActivationStructure)
+{
+}
+
+bool StrictEvalActivation::deleteProperty(ExecState*, const Identifier&)
+{
+ return false;
+}
+
+JSObject* StrictEvalActivation::toThisObject(ExecState* exec) const
+{
+ return exec->globalThisValue();
+}
+
+JSValue StrictEvalActivation::toStrictThisObject(ExecState*) const
+{
+ return jsNull();
+}
+
+}
diff --git a/JavaScriptCore/runtime/StrictEvalActivation.h b/JavaScriptCore/runtime/StrictEvalActivation.h
new file mode 100644
index 0000000..1385eec
--- /dev/null
+++ b/JavaScriptCore/runtime/StrictEvalActivation.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef StrictEvalActivation_h
+#define StrictEvalActivation_h
+
+#include "JSObject.h"
+
+namespace JSC {
+
+class StrictEvalActivation : public JSObject {
+public:
+ StrictEvalActivation(ExecState*);
+ virtual bool deleteProperty(ExecState*, const Identifier&);
+ virtual JSObject* toThisObject(ExecState*) const;
+ virtual JSValue toStrictThisObject(ExecState*) const;
+};
+
+} // namespace JSC
+
+#endif // StrictEvalActivation_h
diff --git a/JavaScriptCore/runtime/StringConcatenate.h b/JavaScriptCore/runtime/StringConcatenate.h
deleted file mode 100644
index 18a52ef..0000000
--- a/JavaScriptCore/runtime/StringConcatenate.h
+++ /dev/null
@@ -1,428 +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 StringConcatenate_h
-#define StringConcatenate_h
-
-#include "UString.h"
-
-namespace JSC {
-
-template<typename StringType>
-class StringTypeAdapter {
-};
-
-template<>
-class StringTypeAdapter<char*> {
-public:
- StringTypeAdapter<char*>(char* buffer)
- : m_buffer((unsigned char*)buffer)
- , m_length(strlen(buffer))
- {
- }
-
- unsigned length() { return m_length; }
-
- void writeTo(UChar* destination)
- {
- for (unsigned i = 0; i < m_length; ++i)
- destination[i] = m_buffer[i];
- }
-
-private:
- const unsigned char* m_buffer;
- unsigned m_length;
-};
-
-template<>
-class StringTypeAdapter<const char*> {
-public:
- StringTypeAdapter<const char*>(const char* buffer)
- : m_buffer((unsigned char*)buffer)
- , m_length(strlen(buffer))
- {
- }
-
- unsigned length() { return m_length; }
-
- void writeTo(UChar* destination)
- {
- for (unsigned i = 0; i < m_length; ++i)
- destination[i] = m_buffer[i];
- }
-
-private:
- const unsigned char* m_buffer;
- unsigned m_length;
-};
-
-template<>
-class StringTypeAdapter<UString> {
-public:
- StringTypeAdapter<UString>(UString& string)
- : m_data(string.characters())
- , m_length(string.length())
- {
- }
-
- unsigned length() { return m_length; }
-
- void writeTo(UChar* destination)
- {
- for (unsigned i = 0; i < m_length; ++i)
- destination[i] = m_data[i];
- }
-
-private:
- const UChar* m_data;
- unsigned m_length;
-};
-
-inline void sumWithOverflow(unsigned& total, unsigned addend, bool& overflow)
-{
- unsigned oldTotal = total;
- total = oldTotal + addend;
- if (total < oldTotal)
- overflow = true;
-}
-
-template<typename StringType1, typename StringType2>
-PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2)
-{
- StringTypeAdapter<StringType1> adapter1(string1);
- StringTypeAdapter<StringType2> adapter2(string2);
-
- UChar* buffer;
- bool overflow = false;
- unsigned length = adapter1.length();
- sumWithOverflow(length, adapter2.length(), overflow);
- if (overflow)
- return 0;
- PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
- if (!resultImpl)
- return 0;
-
- UChar* result = buffer;
- adapter1.writeTo(result);
- result += adapter1.length();
- adapter2.writeTo(result);
-
- return resultImpl;
-}
-
-template<typename StringType1, typename StringType2, typename StringType3>
-PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3)
-{
- StringTypeAdapter<StringType1> adapter1(string1);
- StringTypeAdapter<StringType2> adapter2(string2);
- StringTypeAdapter<StringType3> adapter3(string3);
-
- UChar* buffer = 0;
- bool overflow = false;
- unsigned length = adapter1.length();
- sumWithOverflow(length, adapter2.length(), overflow);
- sumWithOverflow(length, adapter3.length(), overflow);
- if (overflow)
- return 0;
- PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
- if (!resultImpl)
- return 0;
-
- UChar* result = buffer;
- adapter1.writeTo(result);
- result += adapter1.length();
- adapter2.writeTo(result);
- result += adapter2.length();
- adapter3.writeTo(result);
-
- return resultImpl;
-}
-
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
-PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
-{
- StringTypeAdapter<StringType1> adapter1(string1);
- StringTypeAdapter<StringType2> adapter2(string2);
- StringTypeAdapter<StringType3> adapter3(string3);
- StringTypeAdapter<StringType4> adapter4(string4);
-
- UChar* buffer;
- bool overflow = false;
- unsigned length = adapter1.length();
- sumWithOverflow(length, adapter2.length(), overflow);
- sumWithOverflow(length, adapter3.length(), overflow);
- sumWithOverflow(length, adapter4.length(), overflow);
- if (overflow)
- return 0;
- PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
- if (!resultImpl)
- return 0;
-
- UChar* result = buffer;
- adapter1.writeTo(result);
- result += adapter1.length();
- adapter2.writeTo(result);
- result += adapter2.length();
- adapter3.writeTo(result);
- result += adapter3.length();
- adapter4.writeTo(result);
-
- return resultImpl;
-}
-
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
-PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
-{
- StringTypeAdapter<StringType1> adapter1(string1);
- StringTypeAdapter<StringType2> adapter2(string2);
- StringTypeAdapter<StringType3> adapter3(string3);
- StringTypeAdapter<StringType4> adapter4(string4);
- StringTypeAdapter<StringType5> adapter5(string5);
-
- UChar* buffer;
- bool overflow = false;
- unsigned length = adapter1.length();
- sumWithOverflow(length, adapter2.length(), overflow);
- sumWithOverflow(length, adapter3.length(), overflow);
- sumWithOverflow(length, adapter4.length(), overflow);
- sumWithOverflow(length, adapter5.length(), overflow);
- if (overflow)
- return 0;
- PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
- if (!resultImpl)
- return 0;
-
- UChar* result = buffer;
- adapter1.writeTo(result);
- result += adapter1.length();
- adapter2.writeTo(result);
- result += adapter2.length();
- adapter3.writeTo(result);
- result += adapter3.length();
- adapter4.writeTo(result);
- result += adapter4.length();
- adapter5.writeTo(result);
-
- return resultImpl;
-}
-
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
-PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
-{
- StringTypeAdapter<StringType1> adapter1(string1);
- StringTypeAdapter<StringType2> adapter2(string2);
- StringTypeAdapter<StringType3> adapter3(string3);
- StringTypeAdapter<StringType4> adapter4(string4);
- StringTypeAdapter<StringType5> adapter5(string5);
- StringTypeAdapter<StringType6> adapter6(string6);
-
- UChar* buffer;
- bool overflow = false;
- unsigned length = adapter1.length();
- sumWithOverflow(length, adapter2.length(), overflow);
- sumWithOverflow(length, adapter3.length(), overflow);
- sumWithOverflow(length, adapter4.length(), overflow);
- sumWithOverflow(length, adapter5.length(), overflow);
- sumWithOverflow(length, adapter6.length(), overflow);
- if (overflow)
- return 0;
- PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
- if (!resultImpl)
- return 0;
-
- UChar* result = buffer;
- adapter1.writeTo(result);
- result += adapter1.length();
- adapter2.writeTo(result);
- result += adapter2.length();
- adapter3.writeTo(result);
- result += adapter3.length();
- adapter4.writeTo(result);
- result += adapter4.length();
- adapter5.writeTo(result);
- result += adapter5.length();
- adapter6.writeTo(result);
-
- return resultImpl;
-}
-
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7>
-PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)
-{
- StringTypeAdapter<StringType1> adapter1(string1);
- StringTypeAdapter<StringType2> adapter2(string2);
- StringTypeAdapter<StringType3> adapter3(string3);
- StringTypeAdapter<StringType4> adapter4(string4);
- StringTypeAdapter<StringType5> adapter5(string5);
- StringTypeAdapter<StringType6> adapter6(string6);
- StringTypeAdapter<StringType7> adapter7(string7);
-
- UChar* buffer;
- bool overflow = false;
- unsigned length = adapter1.length();
- sumWithOverflow(length, adapter2.length(), overflow);
- sumWithOverflow(length, adapter3.length(), overflow);
- sumWithOverflow(length, adapter4.length(), overflow);
- sumWithOverflow(length, adapter5.length(), overflow);
- sumWithOverflow(length, adapter6.length(), overflow);
- sumWithOverflow(length, adapter7.length(), overflow);
- if (overflow)
- return 0;
- PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
- if (!resultImpl)
- return 0;
-
- UChar* result = buffer;
- adapter1.writeTo(result);
- result += adapter1.length();
- adapter2.writeTo(result);
- result += adapter2.length();
- adapter3.writeTo(result);
- result += adapter3.length();
- adapter4.writeTo(result);
- result += adapter4.length();
- adapter5.writeTo(result);
- result += adapter5.length();
- adapter6.writeTo(result);
- result += adapter6.length();
- adapter7.writeTo(result);
-
- return resultImpl;
-}
-
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8>
-PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)
-{
- StringTypeAdapter<StringType1> adapter1(string1);
- StringTypeAdapter<StringType2> adapter2(string2);
- StringTypeAdapter<StringType3> adapter3(string3);
- StringTypeAdapter<StringType4> adapter4(string4);
- StringTypeAdapter<StringType5> adapter5(string5);
- StringTypeAdapter<StringType6> adapter6(string6);
- StringTypeAdapter<StringType7> adapter7(string7);
- StringTypeAdapter<StringType8> adapter8(string8);
-
- UChar* buffer;
- bool overflow = false;
- unsigned length = adapter1.length();
- sumWithOverflow(length, adapter2.length(), overflow);
- sumWithOverflow(length, adapter3.length(), overflow);
- sumWithOverflow(length, adapter4.length(), overflow);
- sumWithOverflow(length, adapter5.length(), overflow);
- sumWithOverflow(length, adapter6.length(), overflow);
- sumWithOverflow(length, adapter7.length(), overflow);
- sumWithOverflow(length, adapter8.length(), overflow);
- if (overflow)
- return 0;
- PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer);
- if (!resultImpl)
- return 0;
-
- UChar* result = buffer;
- adapter1.writeTo(result);
- result += adapter1.length();
- adapter2.writeTo(result);
- result += adapter2.length();
- adapter3.writeTo(result);
- result += adapter3.length();
- adapter4.writeTo(result);
- result += adapter4.length();
- adapter5.writeTo(result);
- result += adapter5.length();
- adapter6.writeTo(result);
- result += adapter6.length();
- adapter7.writeTo(result);
- result += adapter7.length();
- adapter8.writeTo(result);
-
- return resultImpl;
-}
-
-template<typename StringType1, typename StringType2>
-UString makeString(StringType1 string1, StringType2 string2)
-{
- PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2);
- if (!resultImpl)
- CRASH();
- return resultImpl;
-}
-
-template<typename StringType1, typename StringType2, typename StringType3>
-UString makeString(StringType1 string1, StringType2 string2, StringType3 string3)
-{
- PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3);
- if (!resultImpl)
- CRASH();
- return resultImpl;
-}
-
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
-UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
-{
- PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4);
- if (!resultImpl)
- CRASH();
- return resultImpl;
-}
-
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
-UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
-{
- PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5);
- if (!resultImpl)
- CRASH();
- return resultImpl;
-}
-
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
-UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
-{
- PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6);
- if (!resultImpl)
- CRASH();
- return resultImpl;
-}
-
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7>
-UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)
-{
- PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7);
- if (!resultImpl)
- CRASH();
- return resultImpl;
-}
-
-template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8>
-UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)
-{
- PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8);
- if (!resultImpl)
- CRASH();
- return resultImpl;
-}
-
-} // namespace JSC
-
-#endif
diff --git a/JavaScriptCore/runtime/StringPrototype.cpp b/JavaScriptCore/runtime/StringPrototype.cpp
index 91e9b06..37436f9 100644
--- a/JavaScriptCore/runtime/StringPrototype.cpp
+++ b/JavaScriptCore/runtime/StringPrototype.cpp
@@ -206,7 +206,8 @@ static NEVER_INLINE UString substituteBackreferencesSlow(const UString& replacem
substitutedReplacement.append(replacement.characters() + offset, i - offset);
i += 1 + advance;
offset = i + 1;
- substitutedReplacement.append(source.characters() + backrefStart, backrefLength);
+ if (backrefStart >= 0)
+ substitutedReplacement.append(source.characters() + backrefStart, backrefLength);
} while ((i = replacement.find('$', i + 1)) != notFound);
if (replacement.length() - offset)
@@ -275,12 +276,16 @@ static ALWAYS_INLINE JSValue jsSpliceSubstringsWithSeparators(ExecState* exec, J
int bufferPos = 0;
for (int i = 0; i < maxCount; i++) {
if (i < rangeCount) {
- StringImpl::copyChars(buffer + bufferPos, source.characters() + substringRanges[i].position, substringRanges[i].length);
- bufferPos += substringRanges[i].length;
+ if (int srcLen = substringRanges[i].length) {
+ StringImpl::copyChars(buffer + bufferPos, source.characters() + substringRanges[i].position, srcLen);
+ bufferPos += srcLen;
+ }
}
if (i < separatorCount) {
- StringImpl::copyChars(buffer + bufferPos, separators[i].characters(), separators[i].length());
- bufferPos += separators[i].length();
+ if (int sepLen = separators[i].length()) {
+ StringImpl::copyChars(buffer + bufferPos, separators[i].characters(), sepLen);
+ bufferPos += sepLen;
+ }
}
}
@@ -302,6 +307,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec)
if (pattern.inherits(&RegExpObject::info)) {
const UString& source = sourceVal->value(exec);
+ unsigned sourceLen = source.length();
if (exec->hadException())
return JSValue::encode(JSValue());
RegExp* reg = asRegExpObject(pattern)->regExp();
@@ -330,7 +336,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec)
regExpConstructor->performMatch(reg, source, startPosition, matchIndex, matchLen, &ovector);
if (matchIndex < 0)
break;
-
+
sourceRanges.append(StringRange(lastIndex, matchIndex - lastIndex));
int completeMatchStart = ovector[0];
@@ -347,7 +353,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec)
cachedCall.setArgument(i++, jsNumber(exec, completeMatchStart));
cachedCall.setArgument(i++, sourceVal);
-
+
cachedCall.setThis(exec->globalThisValue());
JSValue result = cachedCall.call();
if (LIKELY(result.isString()))
@@ -363,10 +369,10 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec)
// special case of empty match
if (matchLen == 0) {
startPosition++;
- if (startPosition > source.length())
+ if (startPosition > sourceLen)
break;
}
- }
+ }
} else {
do {
int matchIndex;
@@ -376,16 +382,16 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec)
if (matchIndex < 0)
break;
- sourceRanges.append(StringRange(lastIndex, matchIndex - lastIndex));
-
if (callType != CallTypeNone) {
+ sourceRanges.append(StringRange(lastIndex, matchIndex - lastIndex));
+
int completeMatchStart = ovector[0];
MarkedArgumentBuffer args;
for (unsigned i = 0; i < reg->numSubpatterns() + 1; ++i) {
int matchStart = ovector[i * 2];
int matchLen = ovector[i * 2 + 1] - matchStart;
-
+
if (matchStart < 0)
args.append(jsUndefined());
else
@@ -398,8 +404,17 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec)
replacements.append(call(exec, replacement, callType, callData, exec->globalThisValue(), args).toString(exec));
if (exec->hadException())
break;
- } else
- replacements.append(substituteBackreferences(replacementString, source, ovector, reg));
+ } else {
+ int replLen = replacementString.length();
+ if (lastIndex < matchIndex || replLen) {
+ sourceRanges.append(StringRange(lastIndex, matchIndex - lastIndex));
+
+ if (replLen)
+ replacements.append(substituteBackreferences(replacementString, source, ovector, reg));
+ else
+ replacements.append(UString());
+ }
+ }
lastIndex = matchIndex + matchLen;
startPosition = lastIndex;
@@ -407,7 +422,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec)
// special case of empty match
if (matchLen == 0) {
startPosition++;
- if (startPosition > source.length())
+ if (startPosition > sourceLen)
break;
}
} while (global);
@@ -416,8 +431,8 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec)
if (!lastIndex && replacements.isEmpty())
return JSValue::encode(sourceVal);
- if (static_cast<unsigned>(lastIndex) < source.length())
- sourceRanges.append(StringRange(lastIndex, source.length() - lastIndex));
+ if (static_cast<unsigned>(lastIndex) < sourceLen)
+ sourceRanges.append(StringRange(lastIndex, sourceLen - lastIndex));
return JSValue::encode(jsSpliceSubstringsWithSeparators(exec, sourceVal, source, sourceRanges.data(), sourceRanges.size(), replacements.data(), replacements.size()));
}
diff --git a/JavaScriptCore/runtime/StringBuilder.h b/JavaScriptCore/runtime/UStringBuilder.h
index 27aa57f..31ccf38 100644
--- a/JavaScriptCore/runtime/StringBuilder.h
+++ b/JavaScriptCore/runtime/UStringBuilder.h
@@ -23,65 +23,21 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef StringBuilder_h
-#define StringBuilder_h
+#ifndef UStringBuilder_h
+#define UStringBuilder_h
-#include <wtf/Vector.h>
+#include <wtf/text/StringBuilder.h>
namespace JSC {
-class StringBuilder {
+class UStringBuilder : public StringBuilder {
public:
- void append(const UChar u)
- {
- buffer.append(u);
- }
+ using StringBuilder::append;
+ void append(const UString& str) { append(String(str.impl())); }
- void append(const char* str)
- {
- append(str, strlen(str));
- }
-
- void append(const char* str, size_t len)
- {
- reserveCapacity(buffer.size() + len);
- for (size_t i = 0; i < len; i++)
- buffer.append(static_cast<unsigned char>(str[i]));
- }
-
- void append(const UChar* str, size_t len)
- {
- buffer.append(str, len);
- }
-
- void append(const UString& str)
- {
- buffer.append(str.characters(), str.length());
- }
-
- bool isEmpty() { return buffer.isEmpty(); }
- void reserveCapacity(size_t newCapacity)
- {
- if (newCapacity < buffer.capacity())
- return;
- buffer.reserveCapacity(std::max(newCapacity, buffer.capacity() + buffer.capacity() / 4 + 1));
- }
- void resize(size_t size) { buffer.resize(size); }
- size_t size() const { return buffer.size(); }
-
- UChar operator[](size_t i) const { return buffer.at(i); }
-
- UString build()
- {
- buffer.shrinkToFit();
- ASSERT(buffer.data() || !buffer.size());
- return UString::adopt(buffer);
- }
-
-protected:
- Vector<UChar, 64> buffer;
+ UString toUString() { return toString().impl(); }
};
-}
+} // namespace JSC
-#endif
+#endif // UStringBuilder_h
diff --git a/JavaScriptCore/runtime/UStringConcatenate.h b/JavaScriptCore/runtime/UStringConcatenate.h
new file mode 100644
index 0000000..0990c72
--- /dev/null
+++ b/JavaScriptCore/runtime/UStringConcatenate.h
@@ -0,0 +1,125 @@
+/*
+ * 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_data(string.characters())
+ , m_length(string.length())
+ {
+ }
+
+ unsigned length() { return m_length; }
+
+ void writeTo(UChar* destination)
+ {
+ for (unsigned i = 0; i < m_length; ++i)
+ destination[i] = m_data[i];
+ }
+
+private:
+ const UChar* m_data;
+ 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