summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'JavaScriptCore/runtime')
-rw-r--r--JavaScriptCore/runtime/ArrayConstructor.cpp2
-rw-r--r--JavaScriptCore/runtime/ArrayPrototype.cpp35
-rw-r--r--JavaScriptCore/runtime/ExceptionHelpers.cpp5
-rw-r--r--JavaScriptCore/runtime/ExceptionHelpers.h2
-rw-r--r--JavaScriptCore/runtime/Executable.cpp254
-rw-r--r--JavaScriptCore/runtime/Executable.h168
-rw-r--r--JavaScriptCore/runtime/FunctionConstructor.cpp11
-rw-r--r--JavaScriptCore/runtime/JSActivation.cpp2
-rw-r--r--JavaScriptCore/runtime/JSArray.cpp45
-rw-r--r--JavaScriptCore/runtime/JSArray.h26
-rw-r--r--JavaScriptCore/runtime/JSGlobalData.cpp39
-rw-r--r--JavaScriptCore/runtime/JSGlobalData.h18
-rw-r--r--JavaScriptCore/runtime/JSGlobalObject.h2
-rw-r--r--JavaScriptCore/runtime/RegExpConstructor.cpp2
-rw-r--r--JavaScriptCore/runtime/RegExpKey.h13
15 files changed, 312 insertions, 312 deletions
diff --git a/JavaScriptCore/runtime/ArrayConstructor.cpp b/JavaScriptCore/runtime/ArrayConstructor.cpp
index 589739a..e5d0dac 100644
--- a/JavaScriptCore/runtime/ArrayConstructor.cpp
+++ b/JavaScriptCore/runtime/ArrayConstructor.cpp
@@ -58,7 +58,7 @@ static inline JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgLi
uint32_t n = args.at(0).toUInt32(exec);
if (n != args.at(0).toNumber(exec))
return throwError(exec, createRangeError(exec, "Array size is not a small enough positive integer."));
- return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), n);
+ return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), n, CreateInitialized);
}
// otherwise the array is constructed with the arguments in it
diff --git a/JavaScriptCore/runtime/ArrayPrototype.cpp b/JavaScriptCore/runtime/ArrayPrototype.cpp
index 2cb04ff..e79c46d 100644
--- a/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -73,26 +73,13 @@ static inline bool isNumericCompareFunction(ExecState* exec, CallType callType,
if (callType != CallTypeJS)
return false;
-#if ENABLE(JIT)
- // If the JIT is enabled then we need to preserve the invariant that every
- // function with a CodeBlock also has JIT code.
- CodeBlock* codeBlock = 0;
-#if ENABLE(INTERPRETER)
- if (!exec->globalData().canUseJIT())
- codeBlock = callData.js.functionExecutable->bytecodeForCall(exec, callData.js.scopeChain);
- else
-#endif
- {
- callData.js.functionExecutable->jitCodeForCall(exec, callData.js.scopeChain);
- codeBlock = &callData.js.functionExecutable->generatedBytecodeForCall();
- }
-#else
- CodeBlock* codeBlock = callData.js.functionExecutable->bytecodeForCall(exec, callData.js.scopeChain);
-#endif
- if (!codeBlock)
+ FunctionExecutable* executable = callData.js.functionExecutable;
+
+ JSObject* error = executable->compileForCall(exec, callData.js.scopeChain);
+ if (error)
return false;
- return codeBlock->isNumericCompareFunction();
+ return executable->generatedBytecodeForCall().isNumericCompareFunction();
}
// ------------------------------ ArrayPrototype ----------------------------
@@ -560,8 +547,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
JSObject* thisObj = thisValue.toThisObject(exec);
// 15.4.4.12
- JSArray* resObj = constructEmptyArray(exec);
- JSValue result = resObj;
// FIXME: Firefox returns an empty array.
if (!exec->argumentCount())
@@ -582,10 +567,12 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
else
deleteCount = length - begin;
- for (unsigned k = 0; k < deleteCount; k++) {
- if (JSValue v = getProperty(exec, thisObj, k + begin))
- resObj->put(exec, k, v);
- }
+ JSArray* resObj = new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), deleteCount, CreateCompact);
+ JSValue result = resObj;
+
+ for (unsigned k = 0; k < deleteCount; k++)
+ resObj->uncheckedSetIndex(k, getProperty(exec, thisObj, k + begin));
+
resObj->setLength(deleteCount);
unsigned additionalArgs = std::max<int>(exec->argumentCount() - 2, 0);
diff --git a/JavaScriptCore/runtime/ExceptionHelpers.cpp b/JavaScriptCore/runtime/ExceptionHelpers.cpp
index 0647e81..ebde320 100644
--- a/JavaScriptCore/runtime/ExceptionHelpers.cpp
+++ b/JavaScriptCore/runtime/ExceptionHelpers.cpp
@@ -78,6 +78,11 @@ JSObject* createStackOverflowError(ExecState* exec)
return createRangeError(exec, "Maximum call stack size exceeded.");
}
+JSObject* createStackOverflowError(JSGlobalObject* globalObject)
+{
+ return createRangeError(globalObject, "Maximum call stack size exceeded.");
+}
+
JSValue createUndefinedVariableError(ExecState* exec, const Identifier& ident, unsigned bytecodeOffset, CodeBlock* codeBlock)
{
int startOffset = 0;
diff --git a/JavaScriptCore/runtime/ExceptionHelpers.h b/JavaScriptCore/runtime/ExceptionHelpers.h
index 906465f..3e6de86 100644
--- a/JavaScriptCore/runtime/ExceptionHelpers.h
+++ b/JavaScriptCore/runtime/ExceptionHelpers.h
@@ -37,6 +37,7 @@ namespace JSC {
class ExecState;
class Identifier;
class JSGlobalData;
+ class JSGlobalObject;
class JSNotAnObjectErrorStub;
class JSObject;
class Node;
@@ -45,6 +46,7 @@ namespace JSC {
JSValue createInterruptedExecutionException(JSGlobalData*);
JSValue createTerminatedExecutionException(JSGlobalData*);
JSObject* createStackOverflowError(ExecState*);
+ JSObject* createStackOverflowError(JSGlobalObject*);
JSValue createUndefinedVariableError(ExecState*, const Identifier&, unsigned bytecodeOffset, CodeBlock*);
JSNotAnObjectErrorStub* createNotAnObjectErrorStub(ExecState*, bool isNull);
JSObject* createInvalidParamError(ExecState*, const char* op, JSValue, unsigned bytecodeOffset, CodeBlock*);
diff --git a/JavaScriptCore/runtime/Executable.cpp b/JavaScriptCore/runtime/Executable.cpp
index 355ee86..229588b 100644
--- a/JavaScriptCore/runtime/Executable.cpp
+++ b/JavaScriptCore/runtime/Executable.cpp
@@ -45,86 +45,144 @@ VPtrHackExecutable::~VPtrHackExecutable()
{
}
+EvalExecutable::EvalExecutable(ExecState* exec, const SourceCode& source)
+ : ScriptExecutable(exec, source)
+{
+}
+
EvalExecutable::~EvalExecutable()
{
- delete m_evalCodeBlock;
+}
+
+ProgramExecutable::ProgramExecutable(ExecState* exec, const SourceCode& source)
+ : ScriptExecutable(exec, source)
+{
}
ProgramExecutable::~ProgramExecutable()
{
- delete m_programCodeBlock;
+}
+
+FunctionExecutable::FunctionExecutable(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
+ : ScriptExecutable(globalData, source)
+ , m_numVariables(0)
+ , m_forceUsesArguments(forceUsesArguments)
+ , m_parameters(parameters)
+ , m_name(name)
+ , m_symbolTable(0)
+{
+ m_firstLine = firstLine;
+ m_lastLine = lastLine;
+}
+
+FunctionExecutable::FunctionExecutable(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
+ : ScriptExecutable(exec, source)
+ , m_numVariables(0)
+ , m_forceUsesArguments(forceUsesArguments)
+ , m_parameters(parameters)
+ , m_name(name)
+ , m_symbolTable(0)
+{
+ m_firstLine = firstLine;
+ m_lastLine = lastLine;
}
FunctionExecutable::~FunctionExecutable()
{
- delete m_codeBlockForCall;
- delete m_codeBlockForConstruct;
}
-JSObject* EvalExecutable::compile(ExecState* exec, ScopeChainNode* scopeChainNode)
+JSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode)
{
- int errLine;
- UString errMsg;
+ JSObject* exception = 0;
JSGlobalData* globalData = &exec->globalData();
JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
- RefPtr<EvalNode> evalNode = globalData->parser->parse<EvalNode>(globalData, lexicalGlobalObject->debugger(), exec, m_source, &errLine, &errMsg);
- if (!evalNode)
- return addErrorInfo(globalData, createSyntaxError(lexicalGlobalObject, errMsg), errLine, m_source);
+ RefPtr<EvalNode> evalNode = globalData->parser->parse<EvalNode>(globalData, lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, &exception);
+ if (!evalNode) {
+ ASSERT(exception);
+ return exception;
+ }
recordParse(evalNode->features(), evalNode->lineNo(), evalNode->lastLine());
ScopeChain scopeChain(scopeChainNode);
JSGlobalObject* globalObject = scopeChain.globalObject();
ASSERT(!m_evalCodeBlock);
- m_evalCodeBlock = new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth());
- OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(evalNode.get(), globalObject->debugger(), scopeChain, m_evalCodeBlock->symbolTable(), m_evalCodeBlock)));
+ m_evalCodeBlock = adoptPtr(new EvalCodeBlock(this, globalObject, source().provider(), scopeChain.localDepth()));
+ OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(evalNode.get(), globalObject->debugger(), scopeChain, m_evalCodeBlock->symbolTable(), m_evalCodeBlock.get())));
generator->generate();
evalNode->destroyData();
+
+#if ENABLE(JIT)
+ if (exec->globalData().canUseJIT()) {
+ m_jitCodeForCall = JIT::compile(scopeChainNode->globalData, m_evalCodeBlock.get());
+#if !ENABLE(OPCODE_SAMPLING)
+ if (!BytecodeGenerator::dumpsGeneratedCode())
+ m_evalCodeBlock->discardBytecode();
+#endif
+ }
+#endif
+
return 0;
}
JSObject* ProgramExecutable::checkSyntax(ExecState* exec)
{
- int errLine;
- UString errMsg;
+ JSObject* exception = 0;
JSGlobalData* globalData = &exec->globalData();
JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
- RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>(globalData, lexicalGlobalObject->debugger(), exec, m_source, &errLine, &errMsg);
- if (!programNode)
- return addErrorInfo(globalData, createSyntaxError(lexicalGlobalObject, errMsg), errLine, m_source);
- return 0;
+ RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>(globalData, lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, &exception);
+ if (programNode)
+ return 0;
+ ASSERT(exception);
+ return exception;
}
-JSObject* ProgramExecutable::compile(ExecState* exec, ScopeChainNode* scopeChainNode)
+JSObject* ProgramExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode)
{
- int errLine;
- UString errMsg;
+ ASSERT(!m_programCodeBlock);
+
+ JSObject* exception = 0;
JSGlobalData* globalData = &exec->globalData();
JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
- RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>(globalData, lexicalGlobalObject->debugger(), exec, m_source, &errLine, &errMsg);
- if (!programNode)
- return addErrorInfo(globalData, createSyntaxError(lexicalGlobalObject, errMsg), errLine, m_source);
+ RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>(globalData, lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, &exception);
+ if (!programNode) {
+ ASSERT(exception);
+ return exception;
+ }
recordParse(programNode->features(), programNode->lineNo(), programNode->lastLine());
ScopeChain scopeChain(scopeChainNode);
JSGlobalObject* globalObject = scopeChain.globalObject();
- ASSERT(!m_programCodeBlock);
- m_programCodeBlock = new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider());
- OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(programNode.get(), globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_programCodeBlock)));
+ m_programCodeBlock = adoptPtr(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider()));
+ OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(programNode.get(), globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_programCodeBlock.get())));
generator->generate();
programNode->destroyData();
- return 0;
+
+#if ENABLE(JIT)
+ if (exec->globalData().canUseJIT()) {
+ m_jitCodeForCall = JIT::compile(scopeChainNode->globalData, m_programCodeBlock.get());
+#if !ENABLE(OPCODE_SAMPLING)
+ if (!BytecodeGenerator::dumpsGeneratedCode())
+ m_programCodeBlock->discardBytecode();
+#endif
+ }
+#endif
+
+ return 0;
}
-bool FunctionExecutable::compileForCall(ExecState*, ScopeChainNode* scopeChainNode)
+JSObject* FunctionExecutable::compileForCallInternal(ExecState* exec, ScopeChainNode* scopeChainNode)
{
+ JSObject* exception = 0;
JSGlobalData* globalData = scopeChainNode->globalData;
- RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(globalData, 0, 0, m_source);
- if (!body)
- return false;
+ RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(globalData, exec->lexicalGlobalObject(), 0, 0, m_source, &exception);
+ if (!body) {
+ ASSERT(exception);
+ return exception;
+ }
if (m_forceUsesArguments)
body->setUsesArguments();
body->finishParsing(m_parameters, m_name);
@@ -134,8 +192,8 @@ bool FunctionExecutable::compileForCall(ExecState*, ScopeChainNode* scopeChainNo
JSGlobalObject* globalObject = scopeChain.globalObject();
ASSERT(!m_codeBlockForCall);
- m_codeBlockForCall = new FunctionCodeBlock(this, FunctionCode, source().provider(), source().startOffset(), false);
- OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(body.get(), globalObject->debugger(), scopeChain, m_codeBlockForCall->symbolTable(), m_codeBlockForCall)));
+ m_codeBlockForCall = adoptPtr(new FunctionCodeBlock(this, FunctionCode, source().provider(), source().startOffset(), false));
+ OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(body.get(), globalObject->debugger(), scopeChain, m_codeBlockForCall->symbolTable(), m_codeBlockForCall.get())));
generator->generate();
m_numParametersForCall = m_codeBlockForCall->m_numParameters;
ASSERT(m_numParametersForCall);
@@ -143,15 +201,29 @@ bool FunctionExecutable::compileForCall(ExecState*, ScopeChainNode* scopeChainNo
m_symbolTable = m_codeBlockForCall->sharedSymbolTable();
body->destroyData();
- return true;
+
+#if ENABLE(JIT)
+ if (exec->globalData().canUseJIT()) {
+ m_jitCodeForCall = JIT::compile(scopeChainNode->globalData, m_codeBlockForCall.get(), &m_jitCodeForCallWithArityCheck);
+#if !ENABLE(OPCODE_SAMPLING)
+ if (!BytecodeGenerator::dumpsGeneratedCode())
+ m_codeBlockForCall->discardBytecode();
+#endif
+ }
+#endif
+
+ return 0;
}
-bool FunctionExecutable::compileForConstruct(ExecState*, ScopeChainNode* scopeChainNode)
+JSObject* FunctionExecutable::compileForConstructInternal(ExecState* exec, ScopeChainNode* scopeChainNode)
{
+ JSObject* exception = 0;
JSGlobalData* globalData = scopeChainNode->globalData;
- RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(globalData, 0, 0, m_source);
- if (!body)
- return false;
+ RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(globalData, exec->lexicalGlobalObject(), 0, 0, m_source, &exception);
+ if (!body) {
+ ASSERT(exception);
+ return exception;
+ }
if (m_forceUsesArguments)
body->setUsesArguments();
body->finishParsing(m_parameters, m_name);
@@ -161,8 +233,8 @@ bool FunctionExecutable::compileForConstruct(ExecState*, ScopeChainNode* scopeCh
JSGlobalObject* globalObject = scopeChain.globalObject();
ASSERT(!m_codeBlockForConstruct);
- m_codeBlockForConstruct = new FunctionCodeBlock(this, FunctionCode, source().provider(), source().startOffset(), true);
- OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(body.get(), globalObject->debugger(), scopeChain, m_codeBlockForConstruct->symbolTable(), m_codeBlockForConstruct)));
+ m_codeBlockForConstruct = adoptPtr(new FunctionCodeBlock(this, FunctionCode, source().provider(), source().startOffset(), true));
+ OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(body.get(), globalObject->debugger(), scopeChain, m_codeBlockForConstruct->symbolTable(), m_codeBlockForConstruct.get())));
generator->generate();
m_numParametersForConstruct = m_codeBlockForConstruct->m_numParameters;
ASSERT(m_numParametersForConstruct);
@@ -170,69 +242,20 @@ bool FunctionExecutable::compileForConstruct(ExecState*, ScopeChainNode* scopeCh
m_symbolTable = m_codeBlockForConstruct->sharedSymbolTable();
body->destroyData();
- return true;
-}
#if ENABLE(JIT)
-
-void EvalExecutable::generateJITCode(ExecState* exec, ScopeChainNode* scopeChainNode)
-{
-#if ENABLE(INTERPRETER)
- ASSERT(exec->globalData().canUseJIT());
-#endif
- CodeBlock* codeBlock = &bytecode(exec, scopeChainNode);
- m_jitCodeForCall = JIT::compile(scopeChainNode->globalData, codeBlock);
-
-#if !ENABLE(OPCODE_SAMPLING)
- if (!BytecodeGenerator::dumpsGeneratedCode())
- codeBlock->discardBytecode();
-#endif
-}
-
-void ProgramExecutable::generateJITCode(ExecState* exec, ScopeChainNode* scopeChainNode)
-{
-#if ENABLE(INTERPRETER)
- ASSERT(exec->globalData().canUseJIT());
-#endif
- CodeBlock* codeBlock = &bytecode(exec, scopeChainNode);
- m_jitCodeForCall = JIT::compile(scopeChainNode->globalData, codeBlock);
-
-#if !ENABLE(OPCODE_SAMPLING)
- if (!BytecodeGenerator::dumpsGeneratedCode())
- codeBlock->discardBytecode();
-#endif
-}
-
-void FunctionExecutable::generateJITCodeForCall(ExecState* exec, ScopeChainNode* scopeChainNode)
-{
-#if ENABLE(INTERPRETER)
- ASSERT(exec->globalData().canUseJIT());
-#endif
- CodeBlock* codeBlock = bytecodeForCall(exec, scopeChainNode);
- m_jitCodeForCall = JIT::compile(scopeChainNode->globalData, codeBlock, &m_jitCodeForCallWithArityCheck);
-
+ if (exec->globalData().canUseJIT()) {
+ m_jitCodeForConstruct = JIT::compile(scopeChainNode->globalData, m_codeBlockForConstruct.get(), &m_jitCodeForConstructWithArityCheck);
#if !ENABLE(OPCODE_SAMPLING)
- if (!BytecodeGenerator::dumpsGeneratedCode())
- codeBlock->discardBytecode();
+ if (!BytecodeGenerator::dumpsGeneratedCode())
+ m_codeBlockForConstruct->discardBytecode();
#endif
-}
-
-void FunctionExecutable::generateJITCodeForConstruct(ExecState* exec, ScopeChainNode* scopeChainNode)
-{
-#if ENABLE(INTERPRETER)
- ASSERT(exec->globalData().canUseJIT());
+ }
#endif
- CodeBlock* codeBlock = bytecodeForConstruct(exec, scopeChainNode);
- m_jitCodeForConstruct = JIT::compile(scopeChainNode->globalData, codeBlock, &m_jitCodeForConstructWithArityCheck);
-#if !ENABLE(OPCODE_SAMPLING)
- if (!BytecodeGenerator::dumpsGeneratedCode())
- codeBlock->discardBytecode();
-#endif
+ return 0;
}
-#endif
-
void FunctionExecutable::markAggregate(MarkStack& markStack)
{
if (m_codeBlockForCall)
@@ -243,7 +266,8 @@ void FunctionExecutable::markAggregate(MarkStack& markStack)
PassOwnPtr<ExceptionInfo> FunctionExecutable::reparseExceptionInfo(JSGlobalData* globalData, ScopeChainNode* scopeChainNode, CodeBlock* codeBlock)
{
- RefPtr<FunctionBodyNode> newFunctionBody = globalData->parser->parse<FunctionBodyNode>(globalData, 0, 0, m_source);
+ JSObject* exception = 0;
+ RefPtr<FunctionBodyNode> newFunctionBody = globalData->parser->parse<FunctionBodyNode>(globalData, 0, 0, 0, m_source, &exception);
if (!newFunctionBody)
return PassOwnPtr<ExceptionInfo>();
if (m_forceUsesArguments)
@@ -263,10 +287,7 @@ PassOwnPtr<ExceptionInfo> FunctionExecutable::reparseExceptionInfo(JSGlobalData*
ASSERT(newCodeBlock->instructionCount() == codeBlock->instructionCount());
#if ENABLE(JIT)
-#if ENABLE(INTERPRETER)
- if (globalData->canUseJIT())
-#endif
- {
+ if (globalData->canUseJIT()) {
JITCode newJITCode = JIT::compile(globalData, newCodeBlock.get());
ASSERT(codeBlock->m_isConstructor ? newJITCode.size() == generatedJITCodeForConstruct().size() : newJITCode.size() == generatedJITCodeForCall().size());
}
@@ -279,7 +300,8 @@ PassOwnPtr<ExceptionInfo> FunctionExecutable::reparseExceptionInfo(JSGlobalData*
PassOwnPtr<ExceptionInfo> EvalExecutable::reparseExceptionInfo(JSGlobalData* globalData, ScopeChainNode* scopeChainNode, CodeBlock* codeBlock)
{
- RefPtr<EvalNode> newEvalBody = globalData->parser->parse<EvalNode>(globalData, 0, 0, m_source);
+ JSObject* exception = 0;
+ RefPtr<EvalNode> newEvalBody = globalData->parser->parse<EvalNode>(globalData, 0, 0, 0, m_source, &exception);
if (!newEvalBody)
return PassOwnPtr<ExceptionInfo>();
@@ -295,10 +317,7 @@ PassOwnPtr<ExceptionInfo> EvalExecutable::reparseExceptionInfo(JSGlobalData* glo
ASSERT(newCodeBlock->instructionCount() == codeBlock->instructionCount());
#if ENABLE(JIT)
-#if ENABLE(INTERPRETER)
- if (globalData->canUseJIT())
-#endif
- {
+ if (globalData->canUseJIT()) {
JITCode newJITCode = JIT::compile(globalData, newCodeBlock.get());
ASSERT(newJITCode.size() == generatedJITCodeForCall().size());
}
@@ -309,10 +328,8 @@ PassOwnPtr<ExceptionInfo> EvalExecutable::reparseExceptionInfo(JSGlobalData* glo
void FunctionExecutable::recompile(ExecState*)
{
- delete m_codeBlockForCall;
- m_codeBlockForCall = 0;
- delete m_codeBlockForConstruct;
- m_codeBlockForConstruct = 0;
+ m_codeBlockForCall.clear();
+ m_codeBlockForConstruct.clear();
m_numParametersForCall = NUM_PARAMETERS_NOT_COMPILED;
m_numParametersForConstruct = NUM_PARAMETERS_NOT_COMPILED;
#if ENABLE(JIT)
@@ -321,26 +338,25 @@ void FunctionExecutable::recompile(ExecState*)
#endif
}
-PassRefPtr<FunctionExecutable> FunctionExecutable::fromGlobalCode(const Identifier& functionName, ExecState* exec, Debugger* debugger, const SourceCode& source, int* errLine, UString* errMsg)
+PassRefPtr<FunctionExecutable> FunctionExecutable::fromGlobalCode(const Identifier& functionName, ExecState* exec, Debugger* debugger, const SourceCode& source, JSObject** exception)
{
- RefPtr<ProgramNode> program = exec->globalData().parser->parse<ProgramNode>(&exec->globalData(), debugger, exec, source, errLine, errMsg);
- if (!program)
+ JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
+ RefPtr<ProgramNode> program = exec->globalData().parser->parse<ProgramNode>(&exec->globalData(), lexicalGlobalObject, debugger, exec, source, exception);
+ if (!program) {
+ ASSERT(*exception);
return 0;
+ }
+ // Uses of this function that would not result in a single function expression are invalid.
StatementNode* exprStatement = program->singleStatement();
ASSERT(exprStatement);
ASSERT(exprStatement->isExprStatement());
- if (!exprStatement || !exprStatement->isExprStatement())
- return 0;
-
ExpressionNode* funcExpr = static_cast<ExprStatementNode*>(exprStatement)->expr();
ASSERT(funcExpr);
ASSERT(funcExpr->isFuncExprNode());
- if (!funcExpr || !funcExpr->isFuncExprNode())
- return 0;
-
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());
}
diff --git a/JavaScriptCore/runtime/Executable.h b/JavaScriptCore/runtime/Executable.h
index 516d6ce..10dfb34 100644
--- a/JavaScriptCore/runtime/Executable.h
+++ b/JavaScriptCore/runtime/Executable.h
@@ -98,6 +98,8 @@ namespace JSC {
public:
static PassRefPtr<NativeExecutable> create(MacroAssemblerCodePtr callThunk, NativeFunction function, MacroAssemblerCodePtr constructThunk, NativeFunction constructor)
{
+ if (!callThunk)
+ return adoptRef(new NativeExecutable(JITCode(), function, JITCode(), constructor));
return adoptRef(new NativeExecutable(JITCode::HostFunction(callThunk), function, JITCode::HostFunction(constructThunk), constructor));
}
@@ -193,42 +195,38 @@ namespace JSC {
~EvalExecutable();
- EvalCodeBlock& bytecode(ExecState* exec, ScopeChainNode* scopeChainNode)
+ JSObject* compile(ExecState* exec, ScopeChainNode* scopeChainNode)
{
- if (!m_evalCodeBlock) {
- JSObject* error = compile(exec, scopeChainNode);
- ASSERT_UNUSED(!error, error);
- }
- return *m_evalCodeBlock;
+ JSObject* error = 0;
+ if (!m_evalCodeBlock)
+ error = compileInternal(exec, scopeChainNode);
+ ASSERT(!error == !!m_evalCodeBlock);
+ return error;
}
- JSObject* compile(ExecState*, ScopeChainNode*);
-
- static PassRefPtr<EvalExecutable> create(ExecState* exec, const SourceCode& source) { return adoptRef(new EvalExecutable(exec, source)); }
-
- private:
- EvalExecutable(ExecState* exec, const SourceCode& source)
- : ScriptExecutable(exec, source)
- , m_evalCodeBlock(0)
+ EvalCodeBlock& generatedBytecode()
{
+ ASSERT(m_evalCodeBlock);
+ return *m_evalCodeBlock;
}
- virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
-
- EvalCodeBlock* m_evalCodeBlock;
+ static PassRefPtr<EvalExecutable> create(ExecState* exec, const SourceCode& source) { return adoptRef(new EvalExecutable(exec, source)); }
#if ENABLE(JIT)
- public:
- JITCode& jitCode(ExecState* exec, ScopeChainNode* scopeChainNode)
+ JITCode& generatedJITCode()
{
- if (!m_jitCodeForCall)
- generateJITCode(exec, scopeChainNode);
- return m_jitCodeForCall;
+ return generatedJITCodeForCall();
}
+#endif
private:
- void generateJITCode(ExecState*, ScopeChainNode*);
-#endif
+ EvalExecutable(ExecState*, const SourceCode&);
+
+ JSObject* compileInternal(ExecState*, ScopeChainNode*);
+
+ virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
+
+ OwnPtr<EvalCodeBlock> m_evalCodeBlock;
};
class ProgramExecutable : public ScriptExecutable {
@@ -240,41 +238,38 @@ namespace JSC {
~ProgramExecutable();
- ProgramCodeBlock& bytecode(ExecState* exec, ScopeChainNode* scopeChainNode)
+ JSObject* compile(ExecState* exec, ScopeChainNode* scopeChainNode)
{
- if (!m_programCodeBlock) {
- JSObject* error = compile(exec, scopeChainNode);
- ASSERT_UNUSED(!error, error);
- }
- return *m_programCodeBlock;
+ JSObject* error = 0;
+ if (!m_programCodeBlock)
+ error = compileInternal(exec, scopeChainNode);
+ ASSERT(!error == !!m_programCodeBlock);
+ return error;
}
- JSObject* checkSyntax(ExecState*);
- JSObject* compile(ExecState*, ScopeChainNode*);
-
- private:
- ProgramExecutable(ExecState* exec, const SourceCode& source)
- : ScriptExecutable(exec, source)
- , m_programCodeBlock(0)
+ ProgramCodeBlock& generatedBytecode()
{
+ ASSERT(m_programCodeBlock);
+ return *m_programCodeBlock;
}
- virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
-
- ProgramCodeBlock* m_programCodeBlock;
+ JSObject* checkSyntax(ExecState*);
#if ENABLE(JIT)
- public:
- JITCode& jitCode(ExecState* exec, ScopeChainNode* scopeChainNode)
+ JITCode& generatedJITCode()
{
- if (!m_jitCodeForCall)
- generateJITCode(exec, scopeChainNode);
- return m_jitCodeForCall;
+ return generatedJITCodeForCall();
}
+#endif
private:
- void generateJITCode(ExecState*, ScopeChainNode*);
-#endif
+ ProgramExecutable(ExecState*, const SourceCode&);
+
+ JSObject* compileInternal(ExecState*, ScopeChainNode*);
+
+ virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
+
+ OwnPtr<ProgramCodeBlock> m_programCodeBlock;
};
class FunctionExecutable : public ScriptExecutable {
@@ -300,7 +295,7 @@ namespace JSC {
// Returns either call or construct bytecode. This can be appropriate
// for answering questions that that don't vary between call and construct --
// for example, argumentsRegister().
- FunctionCodeBlock& generatedByteCode()
+ FunctionCodeBlock& generatedBytecode()
{
if (m_codeBlockForCall)
return *m_codeBlockForCall;
@@ -308,12 +303,13 @@ namespace JSC {
return *m_codeBlockForConstruct;
}
- FunctionCodeBlock* bytecodeForCall(ExecState* exec, ScopeChainNode* scopeChainNode)
+ JSObject* compileForCall(ExecState* exec, ScopeChainNode* scopeChainNode)
{
- ASSERT(scopeChainNode);
+ JSObject* error = 0;
if (!m_codeBlockForCall)
- compileForCall(exec, scopeChainNode);
- return m_codeBlockForCall;
+ error = compileForCallInternal(exec, scopeChainNode);
+ ASSERT(!error == !!m_codeBlockForCall);
+ return error;
}
bool isGeneratedForCall() const
@@ -327,12 +323,13 @@ namespace JSC {
return *m_codeBlockForCall;
}
- FunctionCodeBlock* bytecodeForConstruct(ExecState* exec, ScopeChainNode* scopeChainNode)
+ JSObject* compileForConstruct(ExecState* exec, ScopeChainNode* scopeChainNode)
{
- ASSERT(scopeChainNode);
+ JSObject* error = 0;
if (!m_codeBlockForConstruct)
- compileForConstruct(exec, scopeChainNode);
- return m_codeBlockForConstruct;
+ error = compileForConstructInternal(exec, scopeChainNode);
+ ASSERT(!error == !!m_codeBlockForConstruct);
+ return error;
}
bool isGeneratedForConstruct() const
@@ -353,40 +350,15 @@ namespace JSC {
SharedSymbolTable* symbolTable() const { return m_symbolTable; }
void recompile(ExecState*);
- void markAggregate(MarkStack& markStack);
- static PassRefPtr<FunctionExecutable> fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, int* errLine = 0, UString* errMsg = 0);
+ void markAggregate(MarkStack&);
+ static PassRefPtr<FunctionExecutable> fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
private:
- FunctionExecutable(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
- : ScriptExecutable(globalData, source)
- , m_numVariables(0)
- , m_forceUsesArguments(forceUsesArguments)
- , m_parameters(parameters)
- , m_codeBlockForCall(0)
- , m_codeBlockForConstruct(0)
- , m_name(name)
- , m_symbolTable(0)
- {
- m_firstLine = firstLine;
- m_lastLine = lastLine;
- }
+ 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(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
- : ScriptExecutable(exec, source)
- , m_numVariables(0)
- , m_forceUsesArguments(forceUsesArguments)
- , m_parameters(parameters)
- , m_codeBlockForCall(0)
- , m_codeBlockForConstruct(0)
- , m_name(name)
- , m_symbolTable(0)
- {
- m_firstLine = firstLine;
- m_lastLine = lastLine;
- }
-
- bool compileForCall(ExecState*, ScopeChainNode*);
- bool compileForConstruct(ExecState*, ScopeChainNode*);
+ JSObject* compileForCallInternal(ExecState*, ScopeChainNode*);
+ JSObject* compileForConstructInternal(ExecState*, ScopeChainNode*);
virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
@@ -394,27 +366,13 @@ namespace JSC {
bool m_forceUsesArguments : 1;
RefPtr<FunctionParameters> m_parameters;
- FunctionCodeBlock* m_codeBlockForCall;
- FunctionCodeBlock* m_codeBlockForConstruct;
+ OwnPtr<FunctionCodeBlock> m_codeBlockForCall;
+ OwnPtr<FunctionCodeBlock> m_codeBlockForConstruct;
Identifier m_name;
SharedSymbolTable* m_symbolTable;
#if ENABLE(JIT)
public:
- JITCode& jitCodeForCall(ExecState* exec, ScopeChainNode* scopeChainNode)
- {
- if (!m_jitCodeForCall)
- generateJITCodeForCall(exec, scopeChainNode);
- return m_jitCodeForCall;
- }
-
- JITCode& jitCodeForConstruct(ExecState* exec, ScopeChainNode* scopeChainNode)
- {
- if (!m_jitCodeForConstruct)
- generateJITCodeForConstruct(exec, scopeChainNode);
- return m_jitCodeForConstruct;
- }
-
MacroAssemblerCodePtr generatedJITCodeForCallWithArityCheck()
{
ASSERT(m_jitCodeForCall);
@@ -428,10 +386,6 @@ namespace JSC {
ASSERT(m_jitCodeForConstructWithArityCheck);
return m_jitCodeForConstructWithArityCheck;
}
-
- private:
- void generateJITCodeForCall(ExecState*, ScopeChainNode*);
- void generateJITCodeForConstruct(ExecState*, ScopeChainNode*);
#endif
};
diff --git a/JavaScriptCore/runtime/FunctionConstructor.cpp b/JavaScriptCore/runtime/FunctionConstructor.cpp
index a5ff28c..a036eef 100644
--- a/JavaScriptCore/runtime/FunctionConstructor.cpp
+++ b/JavaScriptCore/runtime/FunctionConstructor.cpp
@@ -95,14 +95,15 @@ JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifi
program = builder.build();
}
- int errLine;
- UString errMsg;
JSGlobalObject* globalObject = exec->lexicalGlobalObject();
JSGlobalData* globalData = globalObject->globalData();
SourceCode source = makeSource(program, sourceURL, lineNumber);
- RefPtr<FunctionExecutable> function = FunctionExecutable::fromGlobalCode(functionName, exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg);
- if (!function)
- return throwError(exec, addErrorInfo(globalData, createSyntaxError(globalObject, errMsg), errLine, source));
+ JSObject* exception = 0;
+ RefPtr<FunctionExecutable> function = FunctionExecutable::fromGlobalCode(functionName, exec, exec->dynamicGlobalObject()->debugger(), source, &exception);
+ if (!function) {
+ ASSERT(exception);
+ return throwError(exec, exception);
+ }
ScopeChain scopeChain(globalObject, globalData, globalObject, exec->globalThisValue());
return new (exec) JSFunction(exec, function, scopeChain.node());
diff --git a/JavaScriptCore/runtime/JSActivation.cpp b/JavaScriptCore/runtime/JSActivation.cpp
index fd415ce..8cf71d0 100644
--- a/JavaScriptCore/runtime/JSActivation.cpp
+++ b/JavaScriptCore/runtime/JSActivation.cpp
@@ -143,7 +143,7 @@ JSValue JSActivation::argumentsGetter(ExecState*, JSValue slotBase, const Identi
{
JSActivation* activation = asActivation(slotBase);
CallFrame* callFrame = CallFrame::create(activation->d()->registers);
- int argumentsRegister = activation->d()->functionExecutable->generatedByteCode().argumentsRegister();
+ int argumentsRegister = activation->d()->functionExecutable->generatedBytecode().argumentsRegister();
if (!callFrame->r(argumentsRegister).jsValue()) {
JSValue arguments = JSValue(new (callFrame) Arguments(callFrame));
callFrame->r(argumentsRegister) = arguments;
diff --git a/JavaScriptCore/runtime/JSArray.cpp b/JavaScriptCore/runtime/JSArray.cpp
index 362f89b..56603a3 100644
--- a/JavaScriptCore/runtime/JSArray.cpp
+++ b/JavaScriptCore/runtime/JSArray.cpp
@@ -33,8 +33,6 @@
#include <wtf/OwnPtr.h>
#include <Operations.h>
-#define CHECK_ARRAY_CONSISTENCY 0
-
using namespace std;
using namespace WTF;
@@ -141,22 +139,37 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure)
checkConsistency();
}
-JSArray::JSArray(NonNullPassRefPtr<Structure> structure, unsigned initialLength)
+JSArray::JSArray(NonNullPassRefPtr<Structure> structure, unsigned initialLength, ArrayCreationMode creationMode)
: JSObject(structure)
{
- unsigned initialCapacity = min(initialLength, MIN_SPARSE_ARRAY_INDEX);
+ unsigned initialCapacity;
+ if (creationMode == CreateCompact)
+ initialCapacity = initialLength;
+ else
+ initialCapacity = min(initialLength, MIN_SPARSE_ARRAY_INDEX);
m_storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(initialCapacity)));
- m_storage->m_length = initialLength;
m_vectorLength = initialCapacity;
- m_storage->m_numValuesInVector = 0;
m_storage->m_sparseValueMap = 0;
m_storage->subclassData = 0;
m_storage->reportedMapCapacity = 0;
- JSValue* vector = m_storage->m_vector;
- for (size_t i = 0; i < initialCapacity; ++i)
- vector[i] = JSValue();
+ if (creationMode == CreateCompact) {
+#if CHECK_ARRAY_CONSISTENCY
+ m_storage->m_inCompactInitialization = !!initialCapacity;
+#endif
+ m_storage->m_length = 0;
+ m_storage->m_numValuesInVector = initialCapacity;
+ } else {
+#if CHECK_ARRAY_CONSISTENCY
+ m_storage->m_inCompactInitialization = false;
+#endif
+ m_storage->m_length = initialLength;
+ m_storage->m_numValuesInVector = 0;
+ JSValue* vector = m_storage->m_vector;
+ for (size_t i = 0; i < initialCapacity; ++i)
+ vector[i] = JSValue();
+ }
checkConsistency();
@@ -175,6 +188,9 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, const ArgList& list)
m_storage->m_sparseValueMap = 0;
m_storage->subclassData = 0;
m_storage->reportedMapCapacity = 0;
+#if CHECK_ARRAY_CONSISTENCY
+ m_storage->m_inCompactInitialization = false;
+#endif
size_t i = 0;
ArgList::const_iterator end = list.end();
@@ -524,7 +540,12 @@ bool JSArray::increaseVectorLength(unsigned newLength)
void JSArray::setLength(unsigned newLength)
{
- checkConsistency();
+#if CHECK_ARRAY_CONSISTENCY
+ if (!m_storage->m_inCompactInitialization)
+ checkConsistency();
+ else
+ m_storage->m_inCompactInitialization = false;
+#endif
ArrayStorage* storage = m_storage;
@@ -1045,7 +1066,7 @@ void JSArray::checkConsistency(ConsistencyCheckType type)
if (JSValue value = m_storage->m_vector[i]) {
ASSERT(i < m_storage->m_length);
if (type != DestructorConsistencyCheck)
- value->type(); // Likely to crash if the object was deallocated.
+ value.isUndefined(); // Likely to crash if the object was deallocated.
++numValuesInVector;
} else {
if (type == SortConsistencyCheck)
@@ -1064,7 +1085,7 @@ void JSArray::checkConsistency(ConsistencyCheckType type)
ASSERT(index <= MAX_ARRAY_INDEX);
ASSERT(it->second);
if (type != DestructorConsistencyCheck)
- it->second->type(); // Likely to crash if the object was deallocated.
+ it->second.isUndefined(); // Likely to crash if the object was deallocated.
}
}
}
diff --git a/JavaScriptCore/runtime/JSArray.h b/JavaScriptCore/runtime/JSArray.h
index f65f2bc..b6dd7cc 100644
--- a/JavaScriptCore/runtime/JSArray.h
+++ b/JavaScriptCore/runtime/JSArray.h
@@ -23,6 +23,8 @@
#include "JSObject.h"
+#define CHECK_ARRAY_CONSISTENCY 0
+
namespace JSC {
typedef HashMap<unsigned, JSValue> SparseArrayValueMap;
@@ -33,16 +35,29 @@ namespace JSC {
SparseArrayValueMap* m_sparseValueMap;
void* subclassData; // A JSArray subclass can use this to fill the vector lazily.
size_t reportedMapCapacity;
+#if CHECK_ARRAY_CONSISTENCY
+ bool m_inCompactInitialization;
+#endif
JSValue m_vector[1];
};
+ // The CreateCompact creation mode is used for fast construction of arrays
+ // whose size and contents are known at time of creation.
+ //
+ // There are two obligations when using this mode:
+ //
+ // - uncheckedSetIndex() must be used when initializing the array.
+ // - setLength() must be called after initialization.
+
+ enum ArrayCreationMode { CreateCompact, CreateInitialized };
+
class JSArray : public JSObject {
friend class JIT;
friend class Walker;
public:
explicit JSArray(NonNullPassRefPtr<Structure>);
- JSArray(NonNullPassRefPtr<Structure>, unsigned initialLength);
+ JSArray(NonNullPassRefPtr<Structure>, unsigned initialLength, ArrayCreationMode);
JSArray(NonNullPassRefPtr<Structure>, const ArgList& initialValues);
virtual ~JSArray();
@@ -83,6 +98,15 @@ namespace JSC {
x = v;
}
+ void uncheckedSetIndex(unsigned i, JSValue v)
+ {
+ ASSERT(canSetIndex(i));
+#if CHECK_ARRAY_CONSISTENCY
+ ASSERT(m_storage->m_inCompactInitialization);
+#endif
+ m_storage->m_vector[i] = v;
+ }
+
void fillArgList(ExecState*, MarkedArgumentBuffer&);
void copyToRegisters(ExecState*, Register*, uint32_t);
diff --git a/JavaScriptCore/runtime/JSGlobalData.cpp b/JavaScriptCore/runtime/JSGlobalData.cpp
index 1508750..065cbe1 100644
--- a/JavaScriptCore/runtime/JSGlobalData.cpp
+++ b/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -136,11 +136,7 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
, lexer(new Lexer(this))
, parser(new Parser)
, interpreter(new Interpreter)
-#if ENABLE(JIT)
- , jitStubs(this)
-#endif
, heap(this)
- , initializingLazyNumericCompareFunction(false)
, head(0)
, dynamicGlobalObject(0)
, functionCodeBlockBeingReparsed(0)
@@ -158,18 +154,28 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType thread
startProfilerServerIfNeeded();
#endif
#if ENABLE(JIT) && ENABLE(INTERPRETER)
-#if PLATFORM(MAC)
+#if PLATFORM(CF)
CFStringRef canUseJITKey = CFStringCreateWithCString(0 , "JavaScriptCoreUseJIT", kCFStringEncodingMacRoman);
CFBooleanRef canUseJIT = (CFBooleanRef)CFPreferencesCopyAppValue(canUseJITKey, kCFPreferencesCurrentApplication);
- m_canUseJIT = kCFBooleanTrue == canUseJIT;
- CFRelease(canUseJIT);
+ if (canUseJIT) {
+ m_canUseJIT = kCFBooleanTrue == canUseJIT;
+ CFRelease(canUseJIT);
+ } else
+ m_canUseJIT = !getenv("JavaScriptCoreUseJIT");
CFRelease(canUseJITKey);
#elif OS(UNIX)
- m_canUseJIT = !getenv("JSC_FORCE_INTERPRETER");
+ m_canUseJIT = !getenv("JavaScriptCoreUseJIT");
#else
m_canUseJIT = true;
#endif
#endif
+#if ENABLE(JIT)
+#if ENABLE(INTERPRETER)
+ if (m_canUseJIT)
+ m_canUseJIT = executableAllocator.isValid();
+#endif
+ jitStubs = new JITThunks(this);
+#endif
}
JSGlobalData::~JSGlobalData()
@@ -257,27 +263,14 @@ JSGlobalData*& JSGlobalData::sharedInstanceInternal()
return sharedInstance;
}
-// FIXME: We can also detect forms like v1 < v2 ? -1 : 0, reverse comparison, etc.
-const Vector<Instruction>& JSGlobalData::numericCompareFunction(ExecState* exec)
-{
- if (!lazyNumericCompareFunction.size() && !initializingLazyNumericCompareFunction) {
- initializingLazyNumericCompareFunction = true;
- RefPtr<FunctionExecutable> function = FunctionExecutable::fromGlobalCode(Identifier(exec, "numericCompare"), exec, 0, makeSource(UString("(function (v1, v2) { return v1 - v2; })")), 0, 0);
- lazyNumericCompareFunction = function->bytecodeForCall(exec, exec->scopeChain())->instructions();
- initializingLazyNumericCompareFunction = false;
- }
-
- return lazyNumericCompareFunction;
-}
-
#if ENABLE(JIT)
PassRefPtr<NativeExecutable> JSGlobalData::getHostFunction(NativeFunction function)
{
- return jitStubs.hostFunctionStub(this, function);
+ return jitStubs->hostFunctionStub(this, function);
}
PassRefPtr<NativeExecutable> JSGlobalData::getHostFunction(NativeFunction function, ThunkGenerator generator)
{
- return jitStubs.hostFunctionStub(this, function, generator);
+ return jitStubs->hostFunctionStub(this, function, generator);
}
#endif
diff --git a/JavaScriptCore/runtime/JSGlobalData.h b/JavaScriptCore/runtime/JSGlobalData.h
index f3f6cba..23b6b21 100644
--- a/JavaScriptCore/runtime/JSGlobalData.h
+++ b/JavaScriptCore/runtime/JSGlobalData.h
@@ -167,21 +167,21 @@ namespace JSC {
ExecutableAllocator executableAllocator;
#endif
-#if ENABLE(JIT)
-#if ENABLE(INTERPRETER)
- bool canUseJIT() { return m_canUseJIT; }
-#endif
+#if !ENABLE(JIT)
+ bool canUseJIT() { return false; } // interpreter only
+#elif !ENABLE(INTERPRETER)
+ bool canUseJIT() { return true; } // jit only
#else
- bool canUseJIT() { return false; }
+ bool canUseJIT() { return m_canUseJIT; }
#endif
Lexer* lexer;
Parser* parser;
Interpreter* interpreter;
#if ENABLE(JIT)
- JITThunks jitStubs;
+ OwnPtr<JITThunks> jitStubs;
MacroAssemblerCodePtr getCTIStub(ThunkGenerator generator)
{
- return jitStubs.ctiStub(this, generator);
+ return jitStubs->ctiStub(this, generator);
}
PassRefPtr<NativeExecutable> getHostFunction(NativeFunction function);
PassRefPtr<NativeExecutable> getHostFunction(NativeFunction function, ThunkGenerator generator);
@@ -195,10 +195,6 @@ namespace JSC {
ReturnAddressPtr exceptionLocation;
#endif
- const Vector<Instruction>& numericCompareFunction(ExecState*);
- Vector<Instruction> lazyNumericCompareFunction;
- bool initializingLazyNumericCompareFunction;
-
HashMap<OpaqueJSClass*, OpaqueJSClassContextData*> opaqueJSClassData;
JSGlobalObject* head;
diff --git a/JavaScriptCore/runtime/JSGlobalObject.h b/JavaScriptCore/runtime/JSGlobalObject.h
index 09a92a1..115af87 100644
--- a/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/JavaScriptCore/runtime/JSGlobalObject.h
@@ -457,7 +457,7 @@ namespace JSC {
inline JSArray* constructEmptyArray(ExecState* exec, unsigned initialLength)
{
- return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), initialLength);
+ return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), initialLength, CreateInitialized);
}
inline JSArray* constructArray(ExecState* exec, JSValue singleItemValue)
diff --git a/JavaScriptCore/runtime/RegExpConstructor.cpp b/JavaScriptCore/runtime/RegExpConstructor.cpp
index fa2a1e2..aff83e7 100644
--- a/JavaScriptCore/runtime/RegExpConstructor.cpp
+++ b/JavaScriptCore/runtime/RegExpConstructor.cpp
@@ -106,7 +106,7 @@ RegExpConstructor::RegExpConstructor(ExecState* exec, JSGlobalObject* globalObje
}
RegExpMatchesArray::RegExpMatchesArray(ExecState* exec, RegExpConstructorPrivate* data)
- : JSArray(exec->lexicalGlobalObject()->regExpMatchesArrayStructure(), data->lastNumSubPatterns + 1)
+ : JSArray(exec->lexicalGlobalObject()->regExpMatchesArrayStructure(), data->lastNumSubPatterns + 1, CreateInitialized)
{
RegExpConstructorPrivate* d = new RegExpConstructorPrivate;
d->input = data->lastInput;
diff --git a/JavaScriptCore/runtime/RegExpKey.h b/JavaScriptCore/runtime/RegExpKey.h
index e5ab438..2bbdb07 100644
--- a/JavaScriptCore/runtime/RegExpKey.h
+++ b/JavaScriptCore/runtime/RegExpKey.h
@@ -76,13 +76,8 @@ struct RegExpKey {
return flagsValue;
}
};
-} // namespace JSC
-
-namespace WTF {
-template<typename T> struct DefaultHash;
-template<typename T> struct RegExpHash;
-inline bool operator==(const JSC::RegExpKey& a, const JSC::RegExpKey& b)
+inline bool operator==(const RegExpKey& a, const RegExpKey& b)
{
if (a.flagsValue != b.flagsValue)
return false;
@@ -93,6 +88,12 @@ inline bool operator==(const JSC::RegExpKey& a, const JSC::RegExpKey& b)
return equal(a.pattern.get(), b.pattern.get());
}
+} // namespace JSC
+
+namespace WTF {
+template<typename T> struct DefaultHash;
+template<typename T> struct RegExpHash;
+
template<> struct RegExpHash<JSC::RegExpKey> {
static unsigned hash(const JSC::RegExpKey& key) { return key.pattern->hash(); }
static bool equal(const JSC::RegExpKey& a, const JSC::RegExpKey& b) { return a == b; }