[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
barraclough at apple.com
barraclough at apple.com
Wed Dec 22 11:09:26 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit 40b4ad33b46e1f8c8a361cec0262e76aaac7e13e
Author: barraclough at apple.com <barraclough at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Wed Jul 14 00:27:13 2010 +0000
Bug 42207 - Clean up interface to compile executables, always check for exceptions
Reviewed by Oliver Hunt.
Presently interface to compile executable is inconsistent between eval/program and
function code, and is error prone in allowing a caller to byte compile without JIT
compiling an executable (we rely on all executables with codeblocks having JIT code).
Unify on an interface where all compilation is performed by a single compile (with
ForCall|ForConstruct variants) method, and make all clients check for errors.
* interpreter/Interpreter.cpp:
(JSC::Interpreter::unwindCallFrame):
(JSC::Interpreter::execute):
(JSC::Interpreter::executeCall):
(JSC::Interpreter::executeConstruct):
(JSC::Interpreter::prepareForRepeatCall):
(JSC::Interpreter::privateExecute):
* jit/JITStubs.cpp:
(JSC::DEFINE_STUB_FUNCTION):
* parser/Parser.h:
(JSC::Parser::isFunctionBodyNode):
(JSC::Parser::parse):
* runtime/ArrayPrototype.cpp:
(JSC::isNumericCompareFunction):
* runtime/ExceptionHelpers.cpp:
(JSC::createStackOverflowError):
* runtime/ExceptionHelpers.h:
* runtime/Executable.cpp:
(JSC::EvalExecutable::compileInternal):
(JSC::ProgramExecutable::checkSyntax):
(JSC::ProgramExecutable::compileInternal):
(JSC::FunctionExecutable::compileForCallInternal):
(JSC::FunctionExecutable::compileForConstructInternal):
(JSC::FunctionExecutable::reparseExceptionInfo):
(JSC::EvalExecutable::reparseExceptionInfo):
(JSC::FunctionExecutable::fromGlobalCode):
* runtime/Executable.h:
(JSC::EvalExecutable::compile):
(JSC::EvalExecutable::generatedBytecode):
(JSC::EvalExecutable::generatedJITCode):
(JSC::ProgramExecutable::compile):
(JSC::ProgramExecutable::generatedBytecode):
(JSC::ProgramExecutable::generatedJITCode):
(JSC::FunctionExecutable::generatedBytecode):
(JSC::FunctionExecutable::compileForCall):
(JSC::FunctionExecutable::compileForConstruct):
(JSC::FunctionExecutable::generatedJITCodeForConstructWithArityCheck):
* runtime/FunctionConstructor.cpp:
(JSC::constructFunction):
* runtime/JSActivation.cpp:
(JSC::JSActivation::argumentsGetter):
* runtime/JSGlobalData.h:
(JSC::JSGlobalData::canUseJIT):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@63267 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 2d9abc4..3321e78 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,59 @@
+2010-07-13 Gavin Barraclough <barraclough at apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 42207 - Clean up interface to compile executables, always check for exceptions
+
+ Presently interface to compile executable is inconsistent between eval/program and
+ function code, and is error prone in allowing a caller to byte compile without JIT
+ compiling an executable (we rely on all executables with codeblocks having JIT code).
+ Unify on an interface where all compilation is performed by a single compile (with
+ ForCall|ForConstruct variants) method, and make all clients check for errors.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::unwindCallFrame):
+ (JSC::Interpreter::execute):
+ (JSC::Interpreter::executeCall):
+ (JSC::Interpreter::executeConstruct):
+ (JSC::Interpreter::prepareForRepeatCall):
+ (JSC::Interpreter::privateExecute):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * parser/Parser.h:
+ (JSC::Parser::isFunctionBodyNode):
+ (JSC::Parser::parse):
+ * runtime/ArrayPrototype.cpp:
+ (JSC::isNumericCompareFunction):
+ * runtime/ExceptionHelpers.cpp:
+ (JSC::createStackOverflowError):
+ * runtime/ExceptionHelpers.h:
+ * runtime/Executable.cpp:
+ (JSC::EvalExecutable::compileInternal):
+ (JSC::ProgramExecutable::checkSyntax):
+ (JSC::ProgramExecutable::compileInternal):
+ (JSC::FunctionExecutable::compileForCallInternal):
+ (JSC::FunctionExecutable::compileForConstructInternal):
+ (JSC::FunctionExecutable::reparseExceptionInfo):
+ (JSC::EvalExecutable::reparseExceptionInfo):
+ (JSC::FunctionExecutable::fromGlobalCode):
+ * runtime/Executable.h:
+ (JSC::EvalExecutable::compile):
+ (JSC::EvalExecutable::generatedBytecode):
+ (JSC::EvalExecutable::generatedJITCode):
+ (JSC::ProgramExecutable::compile):
+ (JSC::ProgramExecutable::generatedBytecode):
+ (JSC::ProgramExecutable::generatedJITCode):
+ (JSC::FunctionExecutable::generatedBytecode):
+ (JSC::FunctionExecutable::compileForCall):
+ (JSC::FunctionExecutable::compileForConstruct):
+ (JSC::FunctionExecutable::generatedJITCodeForConstructWithArityCheck):
+ * runtime/FunctionConstructor.cpp:
+ (JSC::constructFunction):
+ * runtime/JSActivation.cpp:
+ (JSC::JSActivation::argumentsGetter):
+ * runtime/JSGlobalData.h:
+ (JSC::JSGlobalData::canUseJIT):
+
2010-07-13 Caio Marcelo de Oliveira Filho <caio.oliveira at openbossa.org>
Reviewed by Oliver Hunt.
diff --git a/JavaScriptCore/interpreter/Interpreter.cpp b/JavaScriptCore/interpreter/Interpreter.cpp
index 26f7a6b..2342ed6 100644
--- a/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/JavaScriptCore/interpreter/Interpreter.cpp
@@ -547,18 +547,17 @@ NEVER_INLINE bool Interpreter::unwindCallFrame(CallFrame*& callFrame, JSValue ex
return false;
codeBlock = callerFrame->codeBlock();
-#if ENABLE(JIT)
-#if ENABLE(INTERPRETER)
+#if ENABLE(JIT) && ENABLE(INTERPRETER)
if (callerFrame->globalData().canUseJIT())
-#endif
bytecodeOffset = codeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
-#if ENABLE(INTERPRETER)
else
bytecodeOffset = codeBlock->bytecodeOffset(callerFrame, callFrame->returnVPC());
-#endif
+#elif ENABLE(JIT)
+ bytecodeOffset = codeBlock->bytecodeOffset(callerFrame, callFrame->returnPC());
#else
bytecodeOffset = codeBlock->bytecodeOffset(callerFrame, callFrame->returnVPC());
#endif
+
callFrame = callerFrame;
return true;
}
@@ -660,11 +659,12 @@ JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, S
}
}
- CodeBlock* codeBlock = &program->bytecode(callFrame, scopeChain);
- if (!codeBlock) {
- *exception = createStackOverflowError(callFrame);
+ JSObject* error = program->compile(callFrame, scopeChain);
+ if (error) {
+ *exception = error;
return jsNull();
}
+ CodeBlock* codeBlock = &program->generatedBytecode();
Register* oldEnd = m_registerFile.end();
Register* newEnd = oldEnd + codeBlock->m_numParameters + RegisterFile::CallFrameHeaderSize + codeBlock->m_numCalleeRegisters;
@@ -697,17 +697,11 @@ JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, S
m_reentryDepth++;
#if ENABLE(JIT)
-#if ENABLE(INTERPRETER)
if (callFrame->globalData().canUseJIT())
-#endif
- result = program->jitCode(newCallFrame, scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
-#if ENABLE(INTERPRETER)
+ result = program->generatedJITCode().execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
else
#endif
-#endif
-#if ENABLE(INTERPRETER)
result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
-#endif
m_reentryDepth--;
}
@@ -752,12 +746,16 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
if (callType == CallTypeJS) {
ScopeChainNode* callDataScopeChain = callData.js.scopeChain;
- CodeBlock* newCodeBlock = callData.js.functionExecutable->bytecodeForCall(callFrame, callDataScopeChain);
- if (newCodeBlock)
- newCallFrame = slideRegisterWindowForCall(newCodeBlock, &m_registerFile, newCallFrame, registerOffset, argCount);
- else
- newCallFrame = 0;
+ JSObject* compileError = callData.js.functionExecutable->compileForCall(callFrame, callDataScopeChain);
+ if (UNLIKELY(!!compileError)) {
+ *exception = compileError;
+ m_registerFile.shrink(oldEnd);
+ return jsNull();
+ }
+
+ CodeBlock* newCodeBlock = &callData.js.functionExecutable->generatedBytecodeForCall();
+ newCallFrame = slideRegisterWindowForCall(newCodeBlock, &m_registerFile, newCallFrame, registerOffset, argCount);
if (UNLIKELY(!newCallFrame)) {
*exception = createStackOverflowError(callFrame);
m_registerFile.shrink(oldEnd);
@@ -778,17 +776,11 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
m_reentryDepth++;
#if ENABLE(JIT)
-#if ENABLE(INTERPRETER)
if (callFrame->globalData().canUseJIT())
-#endif
- result = callData.js.functionExecutable->jitCodeForCall(newCallFrame, callDataScopeChain).execute(&m_registerFile, newCallFrame, callDataScopeChain->globalData, exception);
-#if ENABLE(INTERPRETER)
+ result = callData.js.functionExecutable->generatedJITCodeForCall().execute(&m_registerFile, newCallFrame, callDataScopeChain->globalData, exception);
else
#endif
-#endif
-#if ENABLE(INTERPRETER)
result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
-#endif
m_reentryDepth--;
}
@@ -851,12 +843,16 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
if (constructType == ConstructTypeJS) {
ScopeChainNode* constructDataScopeChain = constructData.js.scopeChain;
- CodeBlock* newCodeBlock = constructData.js.functionExecutable->bytecodeForConstruct(callFrame, constructDataScopeChain);
- if (newCodeBlock)
- newCallFrame = slideRegisterWindowForCall(newCodeBlock, &m_registerFile, newCallFrame, registerOffset, argCount);
- else
- newCallFrame = 0;
+ JSObject* compileError = constructData.js.functionExecutable->compileForConstruct(callFrame, constructDataScopeChain);
+ if (UNLIKELY(!!compileError)) {
+ *exception = compileError;
+ m_registerFile.shrink(oldEnd);
+ return 0;
+ }
+
+ CodeBlock* newCodeBlock = &constructData.js.functionExecutable->generatedBytecodeForConstruct();
+ newCallFrame = slideRegisterWindowForCall(newCodeBlock, &m_registerFile, newCallFrame, registerOffset, argCount);
if (UNLIKELY(!newCallFrame)) {
*exception = createStackOverflowError(callFrame);
m_registerFile.shrink(oldEnd);
@@ -877,17 +873,11 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
m_reentryDepth++;
#if ENABLE(JIT)
-#if ENABLE(INTERPRETER)
if (callFrame->globalData().canUseJIT())
-#endif
- result = constructData.js.functionExecutable->jitCodeForConstruct(newCallFrame, constructDataScopeChain).execute(&m_registerFile, newCallFrame, constructDataScopeChain->globalData, exception);
-#if ENABLE(INTERPRETER)
+ result = constructData.js.functionExecutable->generatedJITCodeForConstruct().execute(&m_registerFile, newCallFrame, constructDataScopeChain->globalData, exception);
else
#endif
-#endif
-#if ENABLE(INTERPRETER)
result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
-#endif
m_reentryDepth--;
}
@@ -952,11 +942,15 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* FunctionE
for (int i = 0; i < argc; ++i)
newCallFrame->r(++dst) = jsUndefined();
- CodeBlock* codeBlock = FunctionExecutable->bytecodeForCall(callFrame, scopeChain);
- if (codeBlock)
- newCallFrame = slideRegisterWindowForCall(codeBlock, &m_registerFile, newCallFrame, argc + RegisterFile::CallFrameHeaderSize, argc);
- else
- newCallFrame = 0;
+ JSObject* error = FunctionExecutable->compileForCall(callFrame, scopeChain);
+ if (error) {
+ *exception = error;
+ m_registerFile.shrink(oldEnd);
+ return CallFrameClosure();
+ }
+ CodeBlock* codeBlock = &FunctionExecutable->generatedBytecodeForCall();
+
+ newCallFrame = slideRegisterWindowForCall(codeBlock, &m_registerFile, newCallFrame, argc + RegisterFile::CallFrameHeaderSize, argc);
if (UNLIKELY(!newCallFrame)) {
*exception = createStackOverflowError(callFrame);
m_registerFile.shrink(oldEnd);
@@ -964,12 +958,6 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* FunctionE
}
// a 0 codeBlock indicates a built-in caller
newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), argc, function);
-#if ENABLE(JIT)
-#if ENABLE(INTERPRETER)
- if (callFrame->globalData().canUseJIT())
-#endif
- FunctionExecutable->jitCodeForCall(newCallFrame, scopeChain);
-#endif
CallFrameClosure result = { callFrame, newCallFrame, function, FunctionExecutable, scopeChain->globalData, oldEnd, scopeChain, codeBlock->m_numParameters, argc };
return result;
}
@@ -1013,7 +1001,12 @@ void Interpreter::endRepeatCall(CallFrameClosure& closure)
JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObject* thisObj, ScopeChainNode* scopeChain, JSValue* exception)
{
- return execute(eval, callFrame, thisObj, m_registerFile.size() + eval->bytecode(callFrame, scopeChain).m_numParameters + RegisterFile::CallFrameHeaderSize, scopeChain, exception);
+ JSObject* compileError = eval->compile(callFrame, scopeChain);
+ if (UNLIKELY(!!compileError)) {
+ *exception = compileError;
+ return jsNull();
+ }
+ return execute(eval, callFrame, thisObj, m_registerFile.size() + eval->generatedBytecode().m_numParameters + RegisterFile::CallFrameHeaderSize, scopeChain, exception);
}
JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObject* thisObj, int globalRegisterOffset, ScopeChainNode* scopeChain, JSValue* exception)
@@ -1029,11 +1022,12 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObjec
DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject);
- EvalCodeBlock* codeBlock = &eval->bytecode(callFrame, scopeChain);
- if (!codeBlock) {
- *exception = createStackOverflowError(callFrame);
+ JSObject* compileError = eval->compile(callFrame, scopeChain);
+ if (UNLIKELY(!!compileError)) {
+ *exception = compileError;
return jsNull();
}
+ EvalCodeBlock* codeBlock = &eval->generatedBytecode();
JSVariableObject* variableObject;
for (ScopeChainNode* node = scopeChain; ; node = node->next) {
@@ -1096,7 +1090,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObjec
#if ENABLE(INTERPRETER)
if (callFrame->globalData().canUseJIT())
#endif
- result = eval->jitCode(newCallFrame, scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
+ result = eval->generatedJITCode().execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
#if ENABLE(INTERPRETER)
else
#endif
@@ -3712,13 +3706,16 @@ skip_id_custom_self:
if (callType == CallTypeJS) {
ScopeChainNode* callDataScopeChain = callData.js.scopeChain;
- CodeBlock* newCodeBlock = callData.js.functionExecutable->bytecodeForCall(callFrame, callDataScopeChain);
+
+ JSObject* error = callData.js.functionExecutable->compileForCall(callFrame, callDataScopeChain);
+ if (UNLIKELY(!!error)) {
+ exceptionValue = error;
+ goto vm_throw;
+ }
CallFrame* previousCallFrame = callFrame;
- if (newCodeBlock)
- callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount);
- else
- callFrame = 0;
+ CodeBlock* newCodeBlock = &callData.js.functionExecutable->generatedBytecodeForCall();
+ callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount);
if (UNLIKELY(!callFrame)) {
callFrame = previousCallFrame;
exceptionValue = createStackOverflowError(callFrame);
@@ -3870,19 +3867,22 @@ skip_id_custom_self:
if (callType == CallTypeJS) {
ScopeChainNode* callDataScopeChain = callData.js.scopeChain;
- CodeBlock* newCodeBlock = callData.js.functionExecutable->bytecodeForCall(callFrame, callDataScopeChain);
-
+
+ JSObject* error = callData.js.functionExecutable->compileForCall(callFrame, callDataScopeChain);
+ if (UNLIKELY(!!error)) {
+ exceptionValue = error;
+ goto vm_throw;
+ }
+
CallFrame* previousCallFrame = callFrame;
- if (newCodeBlock)
- callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount);
- else
- callFrame = 0;
+ CodeBlock* newCodeBlock = &callData.js.functionExecutable->generatedBytecodeForCall();
+ callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount);
if (UNLIKELY(!callFrame)) {
callFrame = previousCallFrame;
exceptionValue = createStackOverflowError(callFrame);
goto vm_throw;
}
-
+
callFrame->init(newCodeBlock, vPC + OPCODE_LENGTH(op_call_varargs), callDataScopeChain, previousCallFrame, argCount, asFunction(v));
codeBlock = newCodeBlock;
ASSERT(codeBlock == callFrame->codeBlock());
@@ -4195,15 +4195,16 @@ skip_id_custom_self:
if (constructType == ConstructTypeJS) {
ScopeChainNode* callDataScopeChain = constructData.js.scopeChain;
- CodeBlock* newCodeBlock = constructData.js.functionExecutable->bytecodeForConstruct(callFrame, callDataScopeChain);
-
- CallFrame* previousCallFrame = callFrame;
- if (newCodeBlock)
- callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount);
- else
- callFrame = 0;
+ JSObject* error = constructData.js.functionExecutable->compileForConstruct(callFrame, callDataScopeChain);
+ if (UNLIKELY(!!error)) {
+ exceptionValue = error;
+ goto vm_throw;
+ }
+ CallFrame* previousCallFrame = callFrame;
+ CodeBlock* newCodeBlock = &constructData.js.functionExecutable->generatedBytecodeForConstruct();
+ callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount);
if (UNLIKELY(!callFrame)) {
callFrame = previousCallFrame;
exceptionValue = createStackOverflowError(callFrame);
diff --git a/JavaScriptCore/jit/JITStubs.cpp b/JavaScriptCore/jit/JITStubs.cpp
index cab30ca..a70804c 100644
--- a/JavaScriptCore/jit/JITStubs.cpp
+++ b/JavaScriptCore/jit/JITStubs.cpp
@@ -1858,8 +1858,9 @@ DEFINE_STUB_FUNCTION(void*, op_call_jitCompile)
ASSERT(!function->isHostFunction());
FunctionExecutable* executable = function->jsExecutable();
ScopeChainNode* callDataScopeChain = function->scope().node();
- if (!executable->tryJitCodeForCall(stackFrame.callFrame, callDataScopeChain)) {
- stackFrame.callFrame->globalData().exception = createStackOverflowError(stackFrame.callFrame);
+ JSObject* error = executable->compileForCall(stackFrame.callFrame, callDataScopeChain);
+ if (error) {
+ stackFrame.callFrame->globalData().exception = error;
return 0;
}
return function;
@@ -1878,8 +1879,9 @@ DEFINE_STUB_FUNCTION(void*, op_construct_jitCompile)
ASSERT(!function->isHostFunction());
FunctionExecutable* executable = function->jsExecutable();
ScopeChainNode* callDataScopeChain = function->scope().node();
- if (!executable->tryJitCodeForConstruct(stackFrame.callFrame, callDataScopeChain)) {
- stackFrame.callFrame->globalData().exception = createStackOverflowError(stackFrame.callFrame);
+ JSObject* error = executable->compileForConstruct(stackFrame.callFrame, callDataScopeChain);
+ if (error) {
+ stackFrame.callFrame->globalData().exception = error;
return 0;
}
return function;
@@ -2017,12 +2019,12 @@ DEFINE_STUB_FUNCTION(void*, vm_lazyLinkCall)
codePtr = executable->generatedJITCodeForCall().addressForCall();
else {
FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
- codeBlock = functionExecutable->bytecodeForCall(stackFrame.callFrame, callee->scope().node());
- if (!codeBlock) {
- stackFrame.callFrame->globalData().exception = createStackOverflowError(callFrame);
+ JSObject* error = functionExecutable->compileForCall(callFrame, callee->scope().node());
+ if (error) {
+ callFrame->globalData().exception = createStackOverflowError(callFrame);
return 0;
}
- functionExecutable->jitCodeForCall(callFrame, callee->scope().node());
+ codeBlock = &functionExecutable->generatedBytecodeForCall();
if (callFrame->argumentCountIncludingThis() == static_cast<size_t>(codeBlock->m_numParameters))
codePtr = functionExecutable->generatedJITCodeForCall().addressForCall();
else
@@ -2051,12 +2053,12 @@ DEFINE_STUB_FUNCTION(void*, vm_lazyLinkConstruct)
codePtr = executable->generatedJITCodeForConstruct().addressForCall();
else {
FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
- codeBlock = functionExecutable->bytecodeForConstruct(stackFrame.callFrame, callee->scope().node());
- if (!codeBlock) {
+ JSObject* error = functionExecutable->compileForConstruct(callFrame, callee->scope().node());
+ if (error) {
throwStackOverflowError(callFrame, stackFrame.globalData, ReturnAddressPtr(callFrame->returnPC()), STUB_RETURN_ADDRESS);
return 0;
}
- functionExecutable->jitCodeForConstruct(callFrame, callee->scope().node());
+ codeBlock = &functionExecutable->generatedBytecodeForConstruct();
if (callFrame->argumentCountIncludingThis() == static_cast<size_t>(codeBlock->m_numParameters))
codePtr = functionExecutable->generatedJITCodeForConstruct().addressForCall();
else
diff --git a/JavaScriptCore/parser/Parser.h b/JavaScriptCore/parser/Parser.h
index 894f709..c167980 100644
--- a/JavaScriptCore/parser/Parser.h
+++ b/JavaScriptCore/parser/Parser.h
@@ -24,6 +24,7 @@
#define Parser_h
#include "Debugger.h"
+#include "ExceptionHelpers.h"
#include "Executable.h"
#include "JSGlobalObject.h"
#include "Lexer.h"
@@ -38,6 +39,7 @@
namespace JSC {
class FunctionBodyNode;
+
class ProgramNode;
class UString;
@@ -46,7 +48,7 @@ namespace JSC {
class Parser : public Noncopyable {
public:
template <class ParsedNode>
- PassRefPtr<ParsedNode> parse(JSGlobalData* globalData, Debugger*, ExecState*, const SourceCode& source, int* errLine = 0, UString* errMsg = 0);
+ PassRefPtr<ParsedNode> parse(JSGlobalData* globalData, JSGlobalObject* lexicalGlobalObject, Debugger*, ExecState*, const SourceCode& source, JSObject** exception);
void didFinishParsing(SourceElements*, ParserArenaData<DeclarationStacks::VarStack>*,
ParserArenaData<DeclarationStacks::FunctionStack>*, CodeFeatures features, int lastLine, int numConstants);
@@ -56,6 +58,10 @@ namespace JSC {
private:
void parse(JSGlobalData*, int* errLine, UString* errMsg);
+ // Used to determine type of error to report.
+ bool isFunctionBodyNode(ScopeNode*) { return false; }
+ bool isFunctionBodyNode(FunctionBodyNode*) { return true; }
+
ParserArena m_arena;
const SourceCode* m_source;
SourceElements* m_sourceElements;
@@ -67,12 +73,16 @@ namespace JSC {
};
template <class ParsedNode>
- PassRefPtr<ParsedNode> Parser::parse(JSGlobalData* globalData, Debugger* debugger, ExecState* debuggerExecState, const SourceCode& source, int* errLine, UString* errMsg)
+ PassRefPtr<ParsedNode> Parser::parse(JSGlobalData* globalData, JSGlobalObject* lexicalGlobalObject, Debugger* debugger, ExecState* debuggerExecState, const SourceCode& source, JSObject** exception)
{
+ ASSERT(exception && !*exception);
+ int errLine;
+ UString errMsg;
+
m_source = &source;
if (ParsedNode::scopeIsFunction)
globalData->lexer->setIsReparsing();
- parse(globalData, errLine, errMsg);
+ parse(globalData, &errLine, &errMsg);
RefPtr<ParsedNode> result;
if (m_sourceElements) {
@@ -84,6 +94,17 @@ namespace JSC {
m_features,
m_numConstants);
result->setLoc(m_source->firstLine(), m_lastLine);
+ } else if (lexicalGlobalObject) {
+ // We can never see a syntax error when reparsing a function, since we should have
+ // reported the error when parsing the containing program or eval code. So if we're
+ // parsing a function body node, we assume that what actually happened here is that
+ // we ran out of stack while parsing. If we see an error while parsing eval or program
+ // code we assume that it was a syntax error since running out of stack is much less
+ // likely, and we are currently unable to distinguish between the two cases.
+ if (isFunctionBodyNode(static_cast<ParsedNode*>(0)))
+ *exception = createStackOverflowError(lexicalGlobalObject);
+ else
+ *exception = addErrorInfo(globalData, createSyntaxError(lexicalGlobalObject, errMsg), errLine, source);
}
m_arena.reset();
@@ -94,7 +115,7 @@ namespace JSC {
m_funcDeclarations = 0;
if (debugger && !ParsedNode::scopeIsFunction)
- debugger->sourceParsed(debuggerExecState, source, *errLine, *errMsg);
+ debugger->sourceParsed(debuggerExecState, source, errLine, errMsg);
return result.release();
}
diff --git a/JavaScriptCore/runtime/ArrayPrototype.cpp b/JavaScriptCore/runtime/ArrayPrototype.cpp
index 2cb04ff..f6d48da 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 ----------------------------
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..4c2e6bb 100644
--- a/JavaScriptCore/runtime/Executable.cpp
+++ b/JavaScriptCore/runtime/Executable.cpp
@@ -61,15 +61,16 @@ FunctionExecutable::~FunctionExecutable()
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);
@@ -81,50 +82,77 @@ JSObject* EvalExecutable::compile(ExecState* exec, ScopeChainNode* scopeChainNod
generator->generate();
evalNode->destroyData();
+
+#if ENABLE(JIT)
+ if (exec->globalData().canUseJIT()) {
+ m_jitCodeForCall = JIT::compile(scopeChainNode->globalData, m_evalCodeBlock);
+#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)));
generator->generate();
programNode->destroyData();
- return 0;
+
+#if ENABLE(JIT)
+ if (exec->globalData().canUseJIT()) {
+ m_jitCodeForCall = JIT::compile(scopeChainNode->globalData, m_programCodeBlock);
+#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);
@@ -143,15 +171,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, &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);
@@ -170,69 +212,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 (exec->globalData().canUseJIT()) {
+ m_jitCodeForConstruct = JIT::compile(scopeChainNode->globalData, m_codeBlockForConstruct, &m_jitCodeForConstructWithArityCheck);
#if !ENABLE(OPCODE_SAMPLING)
- if (!BytecodeGenerator::dumpsGeneratedCode())
- codeBlock->discardBytecode();
+ if (!BytecodeGenerator::dumpsGeneratedCode())
+ m_codeBlockForConstruct->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 !ENABLE(OPCODE_SAMPLING)
- if (!BytecodeGenerator::dumpsGeneratedCode())
- codeBlock->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 +236,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 +257,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 +270,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 +287,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());
}
@@ -321,26 +310,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 ba5fae7..bc30741 100644
--- a/JavaScriptCore/runtime/Executable.h
+++ b/JavaScriptCore/runtime/Executable.h
@@ -193,19 +193,30 @@ 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*);
+ EvalCodeBlock& generatedBytecode()
+ {
+ ASSERT(m_evalCodeBlock);
+ return *m_evalCodeBlock;
+ }
static PassRefPtr<EvalExecutable> create(ExecState* exec, const SourceCode& source) { return adoptRef(new EvalExecutable(exec, source)); }
+#if ENABLE(JIT)
+ JITCode& generatedJITCode()
+ {
+ return generatedJITCodeForCall();
+ }
+#endif
+
private:
EvalExecutable(ExecState* exec, const SourceCode& source)
: ScriptExecutable(exec, source)
@@ -213,22 +224,11 @@ namespace JSC {
{
}
+ JSObject* compileInternal(ExecState*, ScopeChainNode*);
+
virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
EvalCodeBlock* m_evalCodeBlock;
-
-#if ENABLE(JIT)
- public:
- JITCode& jitCode(ExecState* exec, ScopeChainNode* scopeChainNode)
- {
- if (!m_jitCodeForCall)
- generateJITCode(exec, scopeChainNode);
- return m_jitCodeForCall;
- }
-
- private:
- void generateJITCode(ExecState*, ScopeChainNode*);
-#endif
};
class ProgramExecutable : public ScriptExecutable {
@@ -240,17 +240,29 @@ namespace JSC {
~ProgramExecutable();
- ProgramCodeBlock& bytecode(ExecState* exec, ScopeChainNode* scopeChainNode)
+ JSObject* compile(ExecState* exec, ScopeChainNode* scopeChainNode)
+ {
+ JSObject* error = 0;
+ if (!m_programCodeBlock)
+ error = compileInternal(exec, scopeChainNode);
+ ASSERT(!error == !!m_programCodeBlock);
+ return error;
+ }
+
+ ProgramCodeBlock& generatedBytecode()
{
- if (!m_programCodeBlock) {
- JSObject* error = compile(exec, scopeChainNode);
- ASSERT_UNUSED(!error, error);
- }
+ ASSERT(m_programCodeBlock);
return *m_programCodeBlock;
}
JSObject* checkSyntax(ExecState*);
- JSObject* compile(ExecState*, ScopeChainNode*);
+
+#if ENABLE(JIT)
+ JITCode& generatedJITCode()
+ {
+ return generatedJITCodeForCall();
+ }
+#endif
private:
ProgramExecutable(ExecState* exec, const SourceCode& source)
@@ -259,22 +271,11 @@ namespace JSC {
{
}
+ JSObject* compileInternal(ExecState*, ScopeChainNode*);
+
virtual PassOwnPtr<ExceptionInfo> reparseExceptionInfo(JSGlobalData*, ScopeChainNode*, CodeBlock*);
ProgramCodeBlock* m_programCodeBlock;
-
-#if ENABLE(JIT)
- public:
- JITCode& jitCode(ExecState* exec, ScopeChainNode* scopeChainNode)
- {
- if (!m_jitCodeForCall)
- generateJITCode(exec, scopeChainNode);
- return m_jitCodeForCall;
- }
-
- private:
- void generateJITCode(ExecState*, ScopeChainNode*);
-#endif
};
class FunctionExecutable : public ScriptExecutable {
@@ -300,7 +301,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 +309,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 +329,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
@@ -354,7 +357,7 @@ namespace JSC {
void recompile(ExecState*);
void markAggregate(MarkStack& markStack);
- static PassRefPtr<FunctionExecutable> fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, int* errLine = 0, UString* errMsg = 0);
+ 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)
@@ -385,8 +388,8 @@ namespace JSC {
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*);
@@ -401,40 +404,6 @@ namespace JSC {
#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;
- }
-
- bool tryJitCodeForCall(ExecState* exec, ScopeChainNode* scopeChainNode)
- {
- FunctionCodeBlock* codeBlock = bytecodeForCall(exec, scopeChainNode);
- if (!codeBlock)
- return false;
- if (!m_jitCodeForCall)
- generateJITCodeForCall(exec, scopeChainNode);
- return true;
- }
-
- bool tryJitCodeForConstruct(ExecState* exec, ScopeChainNode* scopeChainNode)
- {
- FunctionCodeBlock* codeBlock = bytecodeForConstruct(exec, scopeChainNode);
- if (!codeBlock)
- return false;
- if (!m_jitCodeForConstruct)
- generateJITCodeForConstruct(exec, scopeChainNode);
- return true;
- }
-
MacroAssemblerCodePtr generatedJITCodeForCallWithArityCheck()
{
ASSERT(m_jitCodeForCall);
@@ -448,10 +417,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/JSGlobalData.h b/JavaScriptCore/runtime/JSGlobalData.h
index bbb1e31..fc36650 100644
--- a/JavaScriptCore/runtime/JSGlobalData.h
+++ b/JavaScriptCore/runtime/JSGlobalData.h
@@ -167,12 +167,12 @@ 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;
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list