[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