Reviewed by Eric.
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 20 Dec 2007 17:42:50 +0000 (17:42 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 20 Dec 2007 17:42:50 +0000 (17:42 +0000)
        - http://bugs.webkit.org/show_bug.cgi?id=16471
          Completions need to be smaller (or not exist at all)

        SuSpider shows 2.4% speedup.

        Stop using completions in the execution engine.
        Instead, the completion type and label target are both
        stored in the ExecState.

        * API/JSContextRef.cpp: Removed unneeded include of "completion.h".
        * bindings/runtime_method.cpp: Removed unused execute function.
        * bindings/runtime_method.h: Ditto.

        * kjs/ExecState.h: Added completionType, breakOrContinueTarget,
        setCompletionType, setNormalCompletion, setBreakCompletion,
        setContinueCompletion, setReturnValueCompletion, setThrowCompletion,
        setInterruptedCompletion, m_completionType, and m_breakOrContinueTarget.

        * kjs/completion.h: Removed constructor and getter for target
        for break and continue from Completion. This class is now only
        used for the public API to Interpreter and such.

        * kjs/date_object.h: Removed unused execute function.

        * kjs/function.cpp:
        (KJS::FunctionImp::callAsFunction): Removed some unneeded
        exception processing. Updated to call the new execute function
        and to get the completion type from the ExecState. Merged in
        the execute function, which repeated some of the same logic and
        was called only from here.
        (KJS::GlobalFuncImp::callAsFunction): More of the same for eval.
        * kjs/function.h: Removed execute.

        * kjs/interpreter.cpp:
        (KJS::Interpreter::evaluate): Added code to convert the result of
        execut into a Completion.

        * kjs/nodes.cpp:
        (KJS::Node::setErrorCompletion): Renamed from createErrorCompletion.
        Now sets the completion type in the ExecState.
        (KJS::Node::rethrowException): Now sets the completion type in the
        ExecState.
        (KJS::StatementNode::hitStatement): Now sets the completion type in
        the ExecState.
        (KJS::VarStatementNode::execute): Updated to put completion type in
        the ExecState instead of a Completion object.
        (KJS::statementListExecute): Ditto. Also changed the for loop to use
        indices instead of iterators.
        (KJS::BlockNode::execute): Updated return type.
        (KJS::EmptyStatementNode::execute): Updated to put completion type in
        the ExecState instead of a Completion object.
        (KJS::ExprStatementNode::execute): Ditto.
        (KJS::IfNode::execute): Ditto.
        (KJS::DoWhileNode::execute): Ditto. Also streamlined the logic a little
        to make the normal case a little faster and moved the end outside the
        loop so that "break" can do a break.
        (KJS::WhileNode::execute): Ditto.
        (KJS::ForNode::execute): Ditto.
        (KJS::ForInNode::execute): Ditto.
        (KJS::ContinueNode::execute): Updated to put completion type in
        the ExecState instead of a Completion object.
        (KJS::BreakNode::execute): Ditto.
        (KJS::ReturnNode::execute): Ditto.
        (KJS::WithNode::execute): Ditto.
        (KJS::CaseClauseNode::executeStatements): Ditto. Also renamed to have
        execute in its name to reflect the fact that it's a member of the same
        family of functions.
        (KJS::CaseBlockNode::executeBlock): Ditto.
        (KJS::SwitchNode::execute): Ditto.
        (KJS::LabelNode::execute): Ditto.
        (KJS::ThrowNode::execute): Ditto.
        (KJS::TryNode::execute): Ditto.
        (KJS::ProgramNode::execute): Ditto.
        (KJS::EvalNode::execute): Ditto.
        (KJS::FunctionBodyNode::execute): Ditto.
        (KJS::FuncDeclNode::execute): Ditto.

        * kjs/nodes.h: Renamed setErrorCompletion to createErrorCompletion, made
        hitStatement protected, changed return value of execute to a JSValue,
        renamed evalStatements to executeStatements, and evalBlock to executeBlock.

        * kjs/number_object.h: Removed unused execute function.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@28887 268f45cc-cd09-0410-ab3c-d52691b4dbfc

13 files changed:
JavaScriptCore/API/JSContextRef.cpp
JavaScriptCore/ChangeLog
JavaScriptCore/bindings/runtime_method.cpp
JavaScriptCore/bindings/runtime_method.h
JavaScriptCore/kjs/ExecState.h
JavaScriptCore/kjs/completion.h
JavaScriptCore/kjs/date_object.h
JavaScriptCore/kjs/function.cpp
JavaScriptCore/kjs/function.h
JavaScriptCore/kjs/interpreter.cpp
JavaScriptCore/kjs/nodes.cpp
JavaScriptCore/kjs/nodes.h
JavaScriptCore/kjs/number_object.h

index 4fa1c8cbe1368c034d43d599c0a83e04c20028c5..203326e251f64e51f5364495abc115796e31970b 100644 (file)
@@ -31,7 +31,6 @@
 #include "JSCallbackObject.h"
 #include "JSClassRef.h"
 #include "JSGlobalObject.h"
-#include "completion.h"
 #include "object.h"
 #include <wtf/Platform.h>
 
index a059d21b743e424abb9aa73af45d6d5324bbeed4..74546a5b18cd7cf4df66cf0f899e5cf49184d4e2 100644 (file)
@@ -1,3 +1,90 @@
+2007-12-20  Darin Adler  <darin@apple.com>
+
+        Reviewed by Eric.
+
+        - http://bugs.webkit.org/show_bug.cgi?id=16471
+          Completions need to be smaller (or not exist at all)
+
+        SuSpider shows 2.4% speedup.
+
+        Stop using completions in the execution engine.
+        Instead, the completion type and label target are both
+        stored in the ExecState.
+
+        * API/JSContextRef.cpp: Removed unneeded include of "completion.h".
+        * bindings/runtime_method.cpp: Removed unused execute function.
+        * bindings/runtime_method.h: Ditto.
+
+        * kjs/ExecState.h: Added completionType, breakOrContinueTarget,
+        setCompletionType, setNormalCompletion, setBreakCompletion,
+        setContinueCompletion, setReturnValueCompletion, setThrowCompletion,
+        setInterruptedCompletion, m_completionType, and m_breakOrContinueTarget.
+
+        * kjs/completion.h: Removed constructor and getter for target
+        for break and continue from Completion. This class is now only
+        used for the public API to Interpreter and such.
+
+        * kjs/date_object.h: Removed unused execute function.
+
+        * kjs/function.cpp:
+        (KJS::FunctionImp::callAsFunction): Removed some unneeded
+        exception processing. Updated to call the new execute function
+        and to get the completion type from the ExecState. Merged in
+        the execute function, which repeated some of the same logic and
+        was called only from here.
+        (KJS::GlobalFuncImp::callAsFunction): More of the same for eval.
+        * kjs/function.h: Removed execute.
+
+        * kjs/interpreter.cpp:
+        (KJS::Interpreter::evaluate): Added code to convert the result of
+        execut into a Completion.
+
+        * kjs/nodes.cpp:
+        (KJS::Node::setErrorCompletion): Renamed from createErrorCompletion.
+        Now sets the completion type in the ExecState.
+        (KJS::Node::rethrowException): Now sets the completion type in the
+        ExecState.
+        (KJS::StatementNode::hitStatement): Now sets the completion type in
+        the ExecState.
+        (KJS::VarStatementNode::execute): Updated to put completion type in
+        the ExecState instead of a Completion object.
+        (KJS::statementListExecute): Ditto. Also changed the for loop to use
+        indices instead of iterators.
+        (KJS::BlockNode::execute): Updated return type.
+        (KJS::EmptyStatementNode::execute): Updated to put completion type in
+        the ExecState instead of a Completion object.
+        (KJS::ExprStatementNode::execute): Ditto.
+        (KJS::IfNode::execute): Ditto.
+        (KJS::DoWhileNode::execute): Ditto. Also streamlined the logic a little
+        to make the normal case a little faster and moved the end outside the
+        loop so that "break" can do a break.
+        (KJS::WhileNode::execute): Ditto.
+        (KJS::ForNode::execute): Ditto.
+        (KJS::ForInNode::execute): Ditto.
+        (KJS::ContinueNode::execute): Updated to put completion type in
+        the ExecState instead of a Completion object.
+        (KJS::BreakNode::execute): Ditto.
+        (KJS::ReturnNode::execute): Ditto.
+        (KJS::WithNode::execute): Ditto.
+        (KJS::CaseClauseNode::executeStatements): Ditto. Also renamed to have
+        execute in its name to reflect the fact that it's a member of the same
+        family of functions.
+        (KJS::CaseBlockNode::executeBlock): Ditto.
+        (KJS::SwitchNode::execute): Ditto.
+        (KJS::LabelNode::execute): Ditto.
+        (KJS::ThrowNode::execute): Ditto.
+        (KJS::TryNode::execute): Ditto.
+        (KJS::ProgramNode::execute): Ditto.
+        (KJS::EvalNode::execute): Ditto.
+        (KJS::FunctionBodyNode::execute): Ditto.
+        (KJS::FuncDeclNode::execute): Ditto.
+
+        * kjs/nodes.h: Renamed setErrorCompletion to createErrorCompletion, made
+        hitStatement protected, changed return value of execute to a JSValue,
+        renamed evalStatements to executeStatements, and evalBlock to executeBlock.
+
+        * kjs/number_object.h: Removed unused execute function.
+
 2007-12-20  Geoffrey Garen  <ggaren@apple.com>
 
         Added Radar number.
index 50ae64e7c7a89ccc5a2d4abf7a0da878018adc16..c3c69001174cb9603c4e05a7e5a1f29151e41c5f 100644 (file)
@@ -92,8 +92,3 @@ JSValue *RuntimeMethod::callAsFunction(ExecState *exec, JSObject *thisObj, const
     instance->end();
     return aValue;
 }
-
-Completion RuntimeMethod::execute(ExecState*)
-{
-    return Completion(Normal, jsUndefined());
-}
index 3fda886665efbf321eee40115b44d2010ebf2ad9..7fbe32a5a3b99cfee47dd0b3b15ea8f4f7caea1e 100644 (file)
@@ -32,9 +32,7 @@
 
 namespace KJS {
 
-
-class RuntimeMethod : public InternalFunctionImp 
-{
+class RuntimeMethod : public InternalFunctionImp {
 public:
     RuntimeMethod(ExecState *exec, const Identifier &n, Bindings::MethodList &methodList);
     
@@ -42,8 +40,6 @@ public:
 
     virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args);
 
-    virtual Completion execute(ExecState *exec);
-
 private:
     static JSValue *lengthGetter(ExecState *, JSObject *, const Identifier&, const PropertySlot&);
 
index 277e5d0f1fa26f02106c2a32579a1d1b06333647..c92c598cfff7f5704d2d46ec8c8bfa3a79e6c30a 100644 (file)
@@ -108,7 +108,69 @@ namespace KJS  {
         const CommonIdentifiers& propertyNames() const { return *m_propertyNames; }
 
         LocalStorage& localStorage() { return *m_localStorage; }
-    
+
+        // These are only valid right after calling execute().
+        ComplType completionType() const { return m_completionType; }
+        const Identifier& breakOrContinueTarget() const
+        {
+            ASSERT(m_completionType == Break || m_completionType == Continue);
+            return *m_breakOrContinueTarget;
+        }
+
+        // Only for use in the implementation of execute().
+        void setCompletionType(ComplType type)
+        {
+            ASSERT(type != Break);
+            ASSERT(type != Continue);
+            m_completionType = type;
+        }
+        JSValue* setNormalCompletion()
+        {
+            ASSERT(!hadException());
+            m_completionType = Normal;
+            return 0;
+        }
+        JSValue* setNormalCompletion(JSValue* value)
+        {
+            ASSERT(!hadException());
+            m_completionType = Normal;
+            return value;
+        }
+        JSValue* setBreakCompletion(const Identifier* target)
+        {
+            ASSERT(!hadException());
+            m_completionType = Break;
+            m_breakOrContinueTarget = target;
+            return 0;
+        }
+        JSValue* setContinueCompletion(const Identifier* target)
+        {
+            ASSERT(!hadException());
+            m_completionType = Continue;
+            m_breakOrContinueTarget = target;
+            return 0;
+        }
+        JSValue* setReturnValueCompletion(JSValue* returnValue)
+        {
+            ASSERT(!hadException());
+            ASSERT(returnValue);
+            m_completionType = ReturnValue;
+            return returnValue;
+        }
+        JSValue* setThrowCompletion(JSValue* exception)
+        {
+            ASSERT(!hadException());
+            ASSERT(exception);
+            m_completionType = Throw;
+            return exception;
+        }
+        JSValue* setInterruptedCompletion()
+        {
+            ASSERT(!hadException());
+            m_completionType = Interrupted;
+            return 0;
+        }
+
     public:
         ExecState(JSGlobalObject* glob, JSObject* thisV,
                   ScopeNode* scopeNode, CodeType type = GlobalCode,
@@ -141,6 +203,9 @@ namespace KJS  {
         int m_iterationDepth;
         int m_switchDepth;
         CodeType m_codeType;
+
+        ComplType m_completionType;
+        const Identifier* m_breakOrContinueTarget;
     };
 
 } // namespace KJS
index dd647d0ce229c12a611199c9661ba532b0a2c7c5..09f3db79bb3e7157ce28ebf556f16714a02f40c2 100644 (file)
@@ -26,7 +26,6 @@
 
 namespace KJS {
 
-  class Identifier;
   class JSValue;
 
   enum ComplType { Normal, Break, Continue, ReturnValue, Throw, Interrupted };
@@ -44,20 +43,16 @@ namespace KJS {
   class Completion {
   public:
     Completion(ComplType type = Normal, JSValue* value = 0)
-        : m_type(type), m_value(value), m_target(0) { }
-    Completion(ComplType type, const Identifier* target)
-        : m_type(type), m_value(0), m_target(target) { }
+        : m_type(type), m_value(value) { }
 
     ComplType complType() const { return m_type; }
     JSValue* value() const { return m_value; }
     void setValue(JSValue* v) { m_value = v; }
-    const Identifier& target() const { return *m_target; }
     bool isValueCompletion() const { return !!m_value; }
 
   private:
     ComplType m_type;
     JSValue* m_value;
-    const Identifier* m_target;
   };
 
 }
index 6c38e921b51b54ded85e235d53b18d53e14b1773..bac3a3c8d8355ceca6dc9851ecdfc10bef9aa8d1 100644 (file)
@@ -132,7 +132,6 @@ FOR_EACH_CLASS(KJS_IMPLEMENT_PROTOTYPE_FUNCTION_WITH_CREATE)
         virtual JSObject *construct(ExecState *, const List &args);
         virtual JSValue *callAsFunction(ExecState *, JSObject *thisObj, const List &args);
 
-        Completion execute(const List &);
         JSObject *construct(const List &);
     };
 
index 04b9afaa496494bd4a4315496413c9de17ed9fc5..627dd3c230d7437fbe3cd995b5ce82acd717d30c 100644 (file)
@@ -70,24 +70,14 @@ void FunctionImp::mark()
 
 JSValue* FunctionImp::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
 {
-  // enter a new execution context
-  ExecState newExec(exec->dynamicGlobalObject(), thisObj, body.get(), FunctionCode, exec, exec->dynamicGlobalObject()->currentExec(), this, &args);
-  if (exec->hadException())
-    newExec.setException(exec->exception());
-
-  Completion comp = execute(&newExec);
-
-  // if an exception occured, propogate it back to the previous execution object
-  if (newExec.hadException())
-    comp = Completion(Throw, newExec.exception());
-
-  if (comp.complType() == Throw) {
-    exec->setException(comp.value());
-    return comp.value();
-  }
-  else if (comp.complType() == ReturnValue)
-    return comp.value();
-  else
+    ExecState newExec(exec->dynamicGlobalObject(), thisObj, body.get(), FunctionCode, exec, exec->dynamicGlobalObject()->currentExec(), this, &args);
+    JSValue* result = body->execute(&newExec);
+    if (newExec.completionType() == Throw) {
+        exec->setException(result);
+        return result;
+    }
+    if (newExec.completionType() == ReturnValue)
+        return result;
     return jsUndefined();
 }
 
@@ -214,15 +204,6 @@ JSObject* FunctionImp::construct(ExecState* exec, const List& args)
     return obj;
 }
 
-Completion FunctionImp::execute(ExecState* exec)
-{
-  Completion result = body->execute(exec);
-
-  if (result.complType() == Throw || result.complType() == ReturnValue)
-      return result;
-  return Completion(Normal, jsUndefined()); // TODO: or ReturnValue ?
-}
-
 // ------------------------------ IndexToNameMap ---------------------------------
 
 // We map indexes in the arguments array to their corresponding argument names. 
@@ -718,30 +699,21 @@ JSValue* GlobalFuncImp::callAsFunction(ExecState* exec, JSObject* thisObj, const
         JSGlobalObject* globalObject = switchGlobal ? static_cast<JSGlobalObject*>(thisObj) : exec->dynamicGlobalObject();
         JSObject* thisVal = static_cast<JSObject*>(exec->thisValue());
         ExecState newExec(globalObject, thisVal, evalNode.get(), EvalCode, exec, globalObject->currentExec());
-        if (exec->hadException())
-            newExec.setException(exec->exception());
           
         if (switchGlobal) {
             newExec.pushScope(thisObj);
             newExec.setVariableObject(static_cast<JSGlobalObject*>(thisObj));
         }
-        
-        Completion c = evalNode->execute(&newExec);
-          
+        JSValue* value = evalNode->execute(&newExec);
         if (switchGlobal)
             newExec.popScope();
 
-        // if an exception occured, propogate it back to the previous execution object
-        if (newExec.hadException())
-          exec->setException(newExec.exception());
-
-        res = jsUndefined();
-        if (c.complType() == Throw)
-          exec->setException(c.value());
-        else if (c.isValueCompletion())
-            res = c.value();
+        if (exec->completionType() == Throw) {
+            exec->setException(value);
+            return value;
+        }
+        return value ? value : jsUndefined();
       }
-      break;
     }
   case ParseInt:
     res = jsNumber(parseInt(args[0]->toString(exec), args[1]->toInt32(exec)));
index 6757088f6725cdb2e0f6a20c6ff1ffbb7de0ea7c..cc8e716c47fb7da16ea8ee0c10c5dfab8bacdf2a 100644 (file)
@@ -82,7 +82,6 @@ namespace KJS {
     virtual JSObject* construct(ExecState*, const List& args);
     
     virtual JSValue* callAsFunction(ExecState*, JSObject* thisObj, const List& args);
-    Completion execute(ExecState*);
 
     // Note: unlike body->paramName, this returns Identifier::null for parameters 
     // that will never get set, due to later param having the same name
index 51a06b2b3e8d0b672b01b8d558c9d971beaa8517..4e922523354bf9e05bd1f011f4667613c65c984b 100644 (file)
@@ -120,7 +120,8 @@ Completion Interpreter::evaluate(ExecState* exec, const UString& sourceURL, int
     else {
         // execute the code
         ExecState newExec(globalObject, thisObj, progNode.get());
-        res = progNode->execute(&newExec);
+        JSValue* value = progNode->execute(&newExec);
+        res = Completion(newExec.completionType(), value);
     }
     
     globalObject->decRecursion();
index 88e33e258e004a85d306d8406a1891e13dbc4918..671f49be30381fa98f17a366d1c8dc8c91456c70 100644 (file)
@@ -46,7 +46,7 @@ namespace KJS {
 
 #define KJS_BREAKPOINT \
   if (Debugger::debuggersPresent > 0 && !hitStatement(exec)) \
-    return Completion(Normal);
+    return 0;
 
 #define KJS_CHECKEXCEPTION \
   if (exec->hadException()) \
@@ -271,16 +271,16 @@ static inline const UString& currentSourceURL(ExecState* exec)
     return exec->scopeNode()->sourceURL();
 }
 
-Completion Node::createErrorCompletion(ExecState* exec, ErrorType e, const char *msg)
+JSValue* Node::setErrorCompletion(ExecState* exec, ErrorType e, const char* msg)
 {
-    return Completion(Throw, Error::create(exec, e, msg, lineNo(), currentSourceId(exec), currentSourceURL(exec)));
+    return exec->setThrowCompletion(Error::create(exec, e, msg, lineNo(), currentSourceId(exec), currentSourceURL(exec)));
 }
 
-Completion Node::createErrorCompletion(ExecState *exec, ErrorType e, const char *msg, const Identifier &ident)
+JSValue* Node::setErrorCompletion(ExecState* exec, ErrorType e, const char* msg, const Identifier& ident)
 {
     UString message = msg;
     substitute(message, ident.ustring());
-    return Completion(Throw, Error::create(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec)));
+    return exec->setThrowCompletion(Error::create(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec)));
 }
 
 JSValue *Node::throwError(ExecState* exec, ErrorType e, const char *msg)
@@ -364,12 +364,12 @@ void Node::handleException(ExecState* exec, JSValue* exceptionValue)
     }
 }
 
-Completion Node::rethrowException(ExecState* exec)
+JSValue* Node::rethrowException(ExecState* exec)
 {
     JSValue* exception = exec->exception();
     exec->clearException();
     handleException(exec, exception);
-    return Completion(Throw, exception);
+    return exec->setThrowCompletion(exception);
 }
 
 // ------------------------------ StatementNode --------------------------------
@@ -386,14 +386,15 @@ void StatementNode::setLoc(int firstLine, int lastLine)
     m_lastLine = lastLine;
 }
 
-// return true if the debugger wants us to stop at this point
+// Set normal completion and return false if the debugger wants us to stop at this point.
+// FIXME: This seems like poor naming and strange design. Why false to stop? Why "hit statement"?
 bool StatementNode::hitStatement(ExecState* exec)
 {
-  Debugger *dbg = exec->dynamicGlobalObject()->debugger();
-  if (dbg)
-    return dbg->atStatement(exec, currentSourceId(exec), firstLine(), lastLine());
-  else
-    return true; // continue
+    Debugger* debugger = exec->dynamicGlobalObject()->debugger();
+    if (!debugger || debugger->atStatement(exec, currentSourceId(exec), firstLine(), lastLine()))
+        return true;
+    exec->setCompletionType(Normal);
+    return false;
 }
 
 // ------------------------------ NullNode -------------------------------------
@@ -3548,14 +3549,14 @@ void VarStatementNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::N
 }
 
 // ECMA 12.2
-Completion VarStatementNode::execute(ExecState *exec)
+JSValue* VarStatementNode::execute(ExecState* exec)
 {
-    KJS_BREAKPOINT;
+    KJS_BREAKPOINT
 
     next->evaluate(exec);
     KJS_CHECKEXCEPTION
 
-    return Completion(Normal);
+    return exec->setNormalCompletion();
 }
 
 // ------------------------------ Helper functions for handling Vectors of StatementNode -------------------------------
@@ -3587,24 +3588,20 @@ static inline Node* statementListInitializeVariableAccessStack(SourceElements& s
     return (*begin).get();
 }
 
-static inline Completion statementListExecute(SourceElements& statements, ExecState* exec)
+static inline JSValue* statementListExecute(SourceElements& statements, ExecState* exec)
 {
-    JSValue* v = 0;
-    Completion c(Normal);
-    const SourceElements::iterator end = statements.end();
-    for (SourceElements::iterator ptr = statements.begin(); ptr != end; ++ptr) {
-        c = (*ptr)->execute(exec);
-        
-        if (JSValue* v2 = c.value())
-            v = v2;
-        c.setValue(v);
-        
-        if (c.complType() != Normal)
-            return c;
+    JSValue* value = 0;
+    size_t size = statements.size();
+    for (size_t i = 0; i != size; ++i) {
+        JSValue* statementValue = statements[i]->execute(exec);
+        if (exec->completionType() != Normal)
+            return statementValue;
+        if (statementValue)
+            value = statementValue;
     }
-    return c;
+    return exec->setNormalCompletion(value);
 }
-    
+
 // ------------------------------ BlockNode ------------------------------------
 
 BlockNode::BlockNode(SourceElements* children)
@@ -3619,7 +3616,7 @@ void BlockNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStac
 }
 
 // ECMA 12.1
-Completion BlockNode::execute(ExecState *exec)
+JSValue* BlockNode::execute(ExecState* exec)
 {
     return statementListExecute(*m_children, exec);
 }
@@ -3627,9 +3624,9 @@ Completion BlockNode::execute(ExecState *exec)
 // ------------------------------ EmptyStatementNode ---------------------------
 
 // ECMA 12.3
-Completion EmptyStatementNode::execute(ExecState *)
+JSValue* EmptyStatementNode::execute(ExecState* exec)
 {
-  return Completion(Normal);
+    return exec->setNormalCompletion();
 }
 
 // ------------------------------ ExprStatementNode ----------------------------
@@ -3641,14 +3638,14 @@ void ExprStatementNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::
 }
 
 // ECMA 12.4
-Completion ExprStatementNode::execute(ExecState *exec)
+JSValue* ExprStatementNode::execute(ExecState* exec)
 {
-  KJS_BREAKPOINT;
+    KJS_BREAKPOINT
 
-  JSValue *v = expr->evaluate(exec);
-  KJS_CHECKEXCEPTION
+    JSValue* value = expr->evaluate(exec);
+    KJS_CHECKEXCEPTION
 
-  return Completion(Normal, v);
+    return exec->setNormalCompletion(value);
 }
 
 // ------------------------------ IfNode ---------------------------------------
@@ -3664,9 +3661,9 @@ void IfNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&
 }
 
 // ECMA 12.5
-Completion IfNode::execute(ExecState* exec)
+JSValue* IfNode::execute(ExecState* exec)
 {
-    KJS_BREAKPOINT;
+    KJS_BREAKPOINT
 
     bool b = expr->evaluateToBoolean(exec);
     KJS_CHECKEXCEPTION
@@ -3677,7 +3674,7 @@ Completion IfNode::execute(ExecState* exec)
 
     // no else
     if (!statement2)
-        return Completion(Normal);
+        return exec->setNormalCompletion();
 
     // else
     return statement2->execute(exec);
@@ -3692,37 +3689,39 @@ void DoWhileNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeSt
 }
 
 // ECMA 12.6.1
-Completion DoWhileNode::execute(ExecState *exec)
+JSValue* DoWhileNode::execute(ExecState* exec)
 {
-    KJS_BREAKPOINT;
+    KJS_BREAKPOINT
 
     JSValue* value = 0;
 
     while (1) {
         exec->pushIteration();
-        Completion c = statement->execute(exec);
+        JSValue* statementValue = statement->execute(exec);
         exec->popIteration();
 
         if (exec->dynamicGlobalObject()->timedOut())
-            return Completion(Interrupted);
+            exec->setInterruptedCompletion();
 
-        if (c.isValueCompletion())
-            value = c.value();
+        if (statementValue)
+            value = statementValue;
 
-        if (!((c.complType() == Continue) && ls.contains(c.target()))) {
-            if ((c.complType() == Break) && ls.contains(c.target()))
-                return Completion(Normal, value);
-            if (c.complType() != Normal)
-                return c;
+        if (exec->completionType() != Normal) {
+            if (exec->completionType() == Continue && ls.contains(exec->breakOrContinueTarget()))
+                goto continueDoWhileLoop;
+            if (exec->completionType() == Break && ls.contains(exec->breakOrContinueTarget()))
+                break;
+            return statementValue;
         }
 
+continueDoWhileLoop:
         bool b = expr->evaluateToBoolean(exec);
         KJS_CHECKEXCEPTION
         if (!b)
-            return Completion(Normal, value);
+            break;
     }
 
-    return Completion(); // work around gcc 4.0 bug
+    return exec->setNormalCompletion(value);
 }
 
 // ------------------------------ WhileNode ------------------------------------
@@ -3734,9 +3733,9 @@ void WhileNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStac
 }
 
 // ECMA 12.6.2
-Completion WhileNode::execute(ExecState *exec)
+JSValue* WhileNode::execute(ExecState* exec)
 {
-    KJS_BREAKPOINT;
+    KJS_BREAKPOINT
 
     JSValue* value = 0;
 
@@ -3744,27 +3743,28 @@ Completion WhileNode::execute(ExecState *exec)
         bool b = expr->evaluateToBoolean(exec);
         KJS_CHECKEXCEPTION
         if (!b)
-            return Completion(Normal, value);
+            break;
 
         exec->pushIteration();
-        Completion c = statement->execute(exec);
+        JSValue* statementValue = statement->execute(exec);
         exec->popIteration();
 
         if (exec->dynamicGlobalObject()->timedOut())
-            return Completion(Interrupted);
+            return exec->setInterruptedCompletion();
     
-        if (c.isValueCompletion())
-            value = c.value();
+        if (statementValue)
+            value = statementValue;
 
-        if ((c.complType() == Continue) && ls.contains(c.target()))
-            continue;
-        if ((c.complType() == Break) && ls.contains(c.target()))
-            return Completion(Normal, value);
-        if (c.complType() != Normal)
-            return c;
+        if (exec->completionType() != Normal) {
+            if (exec->completionType() == Continue && ls.contains(exec->breakOrContinueTarget()))
+                continue;
+            if (exec->completionType() == Break && ls.contains(exec->breakOrContinueTarget()))
+                break;
+            return statementValue;
+        }
     }
 
-    return Completion(); // work around gcc 4.0 bug
+    return exec->setNormalCompletion(value);
 }
 
 // ------------------------------ ForNode --------------------------------------
@@ -3781,9 +3781,9 @@ void ForNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&
 }
 
 // ECMA 12.6.3
-Completion ForNode::execute(ExecState *exec)
+JSValue* ForNode::execute(ExecState *exec)
 {
-    JSValue* cval = 0;
+    JSValue* value = 0;
 
     if (expr1) {
         expr1->evaluate(exec);
@@ -3795,31 +3795,34 @@ Completion ForNode::execute(ExecState *exec)
             bool b = expr2->evaluateToBoolean(exec);
             KJS_CHECKEXCEPTION
             if (!b)
-                return Completion(Normal, cval);
+                break;
         }
 
         exec->pushIteration();
-        Completion c = statement->execute(exec);
+        JSValue* statementValue = statement->execute(exec);
         exec->popIteration();
-        if (c.isValueCompletion())
-            cval = c.value();
-        if (!((c.complType() == Continue) && ls.contains(c.target()))) {
-            if ((c.complType() == Break) && ls.contains(c.target()))
-                return Completion(Normal, cval);
-            if (c.complType() != Normal)
-                return c;
-        }
+        if (statementValue)
+            value = statementValue;
 
         if (exec->dynamicGlobalObject()->timedOut())
-            return Completion(Interrupted);
+            return exec->setInterruptedCompletion();
+
+        if (exec->completionType() != Normal) {
+            if (exec->completionType() == Continue && ls.contains(exec->breakOrContinueTarget()))
+                goto continueForLoop;
+            if (exec->completionType() == Break && ls.contains(exec->breakOrContinueTarget()))
+                break;
+            return statementValue;
+        }
 
+continueForLoop:
         if (expr3) {
             expr3->evaluate(exec);
             KJS_CHECKEXCEPTION
         }
     }
   
-    return Completion(); // work around gcc 4.0 bug
+    return exec->setNormalCompletion(value);
 }
 
 // ------------------------------ ForInNode ------------------------------------
@@ -3847,35 +3850,30 @@ void ForInNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStac
 }
 
 // ECMA 12.6.4
-Completion ForInNode::execute(ExecState *exec)
+JSValue* ForInNode::execute(ExecState* exec)
 {
-  JSValue *e;
-  JSValue *retval = 0;
-  JSObject *v;
-  Completion c;
-  PropertyNameArray propertyNames;
+  JSValue* value = 0;
 
   if (varDecl) {
     varDecl->evaluate(exec);
     KJS_CHECKEXCEPTION
   }
 
-  e = expr->evaluate(exec);
+  JSValue* e = expr->evaluate(exec);
 
-  // for Null and Undefined, we want to make sure not to go through
-  // the loop at all, because their object wrappers will have a
-  // property list but will throw an exception if you attempt to
-  // access any property.
+  // For Null and Undefined, we want to make sure not to go through
+  // the loop at all, because toObject will throw an exception.
   if (e->isUndefinedOrNull())
-    return Completion(Normal);
+    return exec->setNormalCompletion();
 
   KJS_CHECKEXCEPTION
-  v = e->toObject(exec);
+  JSObject* v = e->toObject(exec);
+  PropertyNameArray propertyNames;
   v->getPropertyNames(exec, propertyNames);
   
   PropertyNameArray::const_iterator end = propertyNames.end();
   for (PropertyNameArray::const_iterator it = propertyNames.begin(); it != end; ++it) {
-      const Identifier &name = *it;
+      const Identifiername = *it;
       if (!v->hasProperty(exec, name))
           continue;
 
@@ -3928,50 +3926,49 @@ Completion ForInNode::execute(ExecState *exec)
     KJS_CHECKEXCEPTION
 
     exec->pushIteration();
-    c = statement->execute(exec);
+    JSValue* statementValue = statement->execute(exec);
     exec->popIteration();
-    if (c.isValueCompletion())
-      retval = c.value();
+    if (statementValue)
+      value = statementValue;
 
-    if (!((c.complType() == Continue) && ls.contains(c.target()))) {
-      if ((c.complType() == Break) && ls.contains(c.target()))
-        break;
-      if (c.complType() != Normal) {
-        return c;
-      }
+    if (exec->completionType() != Normal) {
+        if (exec->completionType() == Continue && ls.contains(exec->breakOrContinueTarget()))
+            continue;
+        if (exec->completionType() == Break && ls.contains(exec->breakOrContinueTarget()))
+            break;
+        return statementValue;
     }
   }
 
-  return Completion(Normal, retval);
+  return exec->setNormalCompletion(value);
 }
 
 // ------------------------------ ContinueNode ---------------------------------
 
 // ECMA 12.7
-Completion ContinueNode::execute(ExecState *exec)
+JSValue* ContinueNode::execute(ExecState* exec)
 {
-  KJS_BREAKPOINT;
+  KJS_BREAKPOINT
 
   if (ident.isEmpty() && !exec->inIteration())
-    return createErrorCompletion(exec, SyntaxError, "Invalid continue statement.");
+    return setErrorCompletion(exec, SyntaxError, "Invalid continue statement.");
   if (!ident.isEmpty() && !exec->seenLabels()->contains(ident))
-    return createErrorCompletion(exec, SyntaxError, "Label %s not found.", ident);
-  return Completion(Continue, &ident);
+    return setErrorCompletion(exec, SyntaxError, "Label %s not found.", ident);
+  return exec->setContinueCompletion(&ident);
 }
 
 // ------------------------------ BreakNode ------------------------------------
 
 // ECMA 12.8
-Completion BreakNode::execute(ExecState *exec)
+JSValue* BreakNode::execute(ExecState *exec)
 {
-  KJS_BREAKPOINT;
+  KJS_BREAKPOINT
 
-  if (ident.isEmpty() && !exec->inIteration() &&
-      !exec->inSwitch())
-    return createErrorCompletion(exec, SyntaxError, "Invalid break statement.");
+  if (ident.isEmpty() && !exec->inIteration() && !exec->inSwitch())
+    return setErrorCompletion(exec, SyntaxError, "Invalid break statement.");
   if (!ident.isEmpty() && !exec->seenLabels()->contains(ident))
-    return createErrorCompletion(exec, SyntaxError, "Label %s not found.");
-  return Completion(Break, &ident);
+    return setErrorCompletion(exec, SyntaxError, "Label %s not found.");
+  return exec->setBreakCompletion(&ident);
 }
 
 // ------------------------------ ReturnNode -----------------------------------
@@ -3983,21 +3980,21 @@ void ReturnNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeSta
 }
 
 // ECMA 12.9
-Completion ReturnNode::execute(ExecState *exec)
+JSValue* ReturnNode::execute(ExecState* exec)
 {
-  KJS_BREAKPOINT;
+  KJS_BREAKPOINT
 
   CodeType codeType = exec->codeType();
   if (codeType != FunctionCode)
-    return createErrorCompletion(exec, SyntaxError, "Invalid return statement.");
+    return setErrorCompletion(exec, SyntaxError, "Invalid return statement.");
 
   if (!value)
-    return Completion(ReturnValue, jsUndefined());
+    return exec->setReturnValueCompletion(jsUndefined());
 
-  JSValue *v = value->evaluate(exec);
+  JSValuev = value->evaluate(exec);
   KJS_CHECKEXCEPTION
 
-  return Completion(ReturnValue, v);
+  return exec->setReturnValueCompletion(v);
 }
 
 // ------------------------------ WithNode -------------------------------------
@@ -4009,19 +4006,19 @@ void WithNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack
 }
 
 // ECMA 12.10
-Completion WithNode::execute(ExecState *exec)
+JSValue* WithNode::execute(ExecState *exec)
 {
-  KJS_BREAKPOINT;
+  KJS_BREAKPOINT
 
   JSValue *v = expr->evaluate(exec);
   KJS_CHECKEXCEPTION
   JSObject *o = v->toObject(exec);
   KJS_CHECKEXCEPTION
   exec->pushScope(o);
-  Completion res = statement->execute(exec);
+  JSValue* value = statement->execute(exec);
   exec->popScope();
 
-  return res;
+  return value;
 }
     
 // ------------------------------ CaseClauseNode -------------------------------
@@ -4044,12 +4041,11 @@ JSValue *CaseClauseNode::evaluate(ExecState *exec)
 }
 
 // ECMA 12.11
-Completion CaseClauseNode::evalStatements(ExecState *exec)
+JSValue* CaseClauseNode::executeStatements(ExecState* exec)
 {
   if (m_children)
     return statementListExecute(*m_children, exec);
-  else
-    return Completion(Normal, jsUndefined());
+  return exec->setNormalCompletion();
 }
 
 // ------------------------------ ClauseListNode -------------------------------
@@ -4081,41 +4077,36 @@ void CaseBlockNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::Node
 }
 
 // ECMA 12.11
-Completion CaseBlockNode::evalBlock(ExecState *exec, JSValue *input)
+JSValue* CaseBlockNode::executeBlock(ExecState* exec, JSValue* input)
 {
-  JSValue *v;
-  Completion res;
-  ClauseListNode *a = list1.get();
-  ClauseListNode *b = list2.get();
-  CaseClauseNode *clause;
-
+  ClauseListNode* a = list1.get();
     while (a) {
-      clause = a->getClause();
+      CaseClauseNode* clause = a->getClause();
       a = a->getNext();
-      v = clause->evaluate(exec);
+      JSValue* v = clause->evaluate(exec);
       KJS_CHECKEXCEPTION
       if (strictEqual(exec, input, v)) {
-        res = clause->evalStatements(exec);
-        if (res.complType() != Normal)
+        JSValue* res = clause->executeStatements(exec);
+        if (exec->completionType() != Normal)
           return res;
-        while (a) {
-          res = a->getClause()->evalStatements(exec);
-          if (res.complType() != Normal)
+        for (; a; a = a->getNext()) {
+          JSValue* res = a->getClause()->executeStatements(exec);
+          if (exec->completionType() != Normal)
             return res;
-          a = a->getNext();
         }
         break;
       }
     }
 
+  ClauseListNode* b = list2.get();
   while (b) {
-    clause = b->getClause();
+    CaseClauseNode* clause = b->getClause();
     b = b->getNext();
-    v = clause->evaluate(exec);
+    JSValue* v = clause->evaluate(exec);
     KJS_CHECKEXCEPTION
     if (strictEqual(exec, input, v)) {
-      res = clause->evalStatements(exec);
-      if (res.complType() != Normal)
+      JSValue* res = clause->executeStatements(exec);
+      if (exec->completionType() != Normal)
         return res;
       goto step18;
     }
@@ -4123,16 +4114,16 @@ Completion CaseBlockNode::evalBlock(ExecState *exec, JSValue *input)
 
   // default clause
   if (def) {
-    res = def->evalStatements(exec);
-    if (res.complType() != Normal)
+    JSValue* res = def->executeStatements(exec);
+    if (exec->completionType() != Normal)
       return res;
   }
   b = list2.get();
  step18:
   while (b) {
-    clause = b->getClause();
-    res = clause->evalStatements(exec);
-    if (res.complType() != Normal)
+    CaseClauseNode* clause = b->getClause();
+    JSValue* res = clause->executeStatements(exec);
+    if (exec->completionType() != Normal)
       return res;
     b = b->getNext();
   }
@@ -4140,7 +4131,7 @@ Completion CaseBlockNode::evalBlock(ExecState *exec, JSValue *input)
   // bail out on error
   KJS_CHECKEXCEPTION
 
-  return Completion(Normal);
+  return exec->setNormalCompletion();
 }
 
 // ------------------------------ SwitchNode -----------------------------------
@@ -4152,20 +4143,20 @@ void SwitchNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeSta
 }
 
 // ECMA 12.11
-Completion SwitchNode::execute(ExecState *exec)
+JSValue* SwitchNode::execute(ExecState* exec)
 {
-  KJS_BREAKPOINT;
+  KJS_BREAKPOINT
 
   JSValue *v = expr->evaluate(exec);
   KJS_CHECKEXCEPTION
 
   exec->pushSwitch();
-  Completion res = block->evalBlock(exec,v);
+  JSValue* result = block->executeBlock(exec, v);
   exec->popSwitch();
 
-  if ((res.complType() == Break) && ls.contains(res.target()))
-    return Completion(Normal, res.value());
-  return res;
+  if (exec->completionType() == Break && ls.contains(exec->breakOrContinueTarget()))
+    exec->setCompletionType(Normal);
+  return result;
 }
 
 // ------------------------------ LabelNode ------------------------------------
@@ -4176,16 +4167,16 @@ void LabelNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStac
 }
 
 // ECMA 12.12
-Completion LabelNode::execute(ExecState *exec)
+JSValue* LabelNode::execute(ExecState *exec)
 {
   if (!exec->seenLabels()->push(label))
-    return createErrorCompletion(exec, SyntaxError, "Duplicated label %s found.", label);
-  Completion e = statement->execute(exec);
+    return setErrorCompletion(exec, SyntaxError, "Duplicated label %s found.", label);
+  JSValue* result = statement->execute(exec);
   exec->seenLabels()->pop();
 
-  if ((e.complType() == Break) && (e.target() == label))
-    return Completion(Normal, e.value());
-  return e;
+  if (exec->completionType() == Break && exec->breakOrContinueTarget() == label)
+    exec->setCompletionType(Normal);
+  return result;
 }
 
 // ------------------------------ ThrowNode ------------------------------------
@@ -4196,15 +4187,15 @@ void ThrowNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStac
 }
 
 // ECMA 12.13
-Completion ThrowNode::execute(ExecState *exec)
+JSValue* ThrowNode::execute(ExecState* exec)
 {
-  KJS_BREAKPOINT;
+  KJS_BREAKPOINT
 
   JSValue *v = expr->evaluate(exec);
   KJS_CHECKEXCEPTION
 
   handleException(exec, v);
-  return Completion(Throw, v);
+  return exec->setThrowCompletion(v);
 }
 
 // ------------------------------ TryNode --------------------------------------
@@ -4218,30 +4209,33 @@ void TryNode::optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&
 }
 
 // ECMA 12.14
-Completion TryNode::execute(ExecState *exec)
+JSValue* TryNode::execute(ExecState *exec)
 {
-  KJS_BREAKPOINT;
+  KJS_BREAKPOINT
 
-  Completion c = tryBlock->execute(exec);
+  JSValue* result = tryBlock->execute(exec);
 
   if (Collector::isOutOfMemory())
-      return c; // don't try to catch an out of memory exception thrown by the collector
+      return result; // don't try to catch an out of memory exception thrown by the collector
   
-  if (catchBlock && c.complType() == Throw) {
-    JSObject *obj = new JSObject;
-    obj->put(exec, exceptionIdent, c.value(), DontDelete);
+  if (catchBlock && exec->completionType() == Throw) {
+    JSObjectobj = new JSObject;
+    obj->put(exec, exceptionIdent, result, DontDelete);
     exec->pushScope(obj);
-    c = catchBlock->execute(exec);
+    result = catchBlock->execute(exec);
     exec->popScope();
   }
 
   if (finallyBlock) {
-    Completion c2 = finallyBlock->execute(exec);
-    if (c2.complType() != Normal)
-      c = c2;
+    ComplType savedCompletionType = exec->completionType();
+    JSValue* finallyResult = finallyBlock->execute(exec);
+    if (exec->completionType() != Normal)
+        result = finallyResult;
+    else
+        exec->setCompletionType(savedCompletionType);
   }
 
-  return c;
+  return result;
 }
 
 // ------------------------------ FunctionBodyNode -----------------------------
@@ -4496,43 +4490,42 @@ UString FunctionBodyNode::paramString() const
   return s;
 }
 
-Completion ProgramNode::execute(ExecState* exec)
+JSValue* ProgramNode::execute(ExecState* exec)
 {
     processDeclarations(exec);
     return ScopeNode::execute(exec);
 }
 
-Completion EvalNode::execute(ExecState* exec)
+JSValue* EvalNode::execute(ExecState* exec)
 {
     processDeclarations(exec);
     return ScopeNode::execute(exec);
 }
 
-Completion FunctionBodyNode::execute(ExecState* exec)
+JSValue* FunctionBodyNode::execute(ExecState* exec)
 {
     processDeclarations(exec);
 
     if (Debugger* dbg = exec->dynamicGlobalObject()->debugger()) {
         if (!dbg->callEvent(exec, sourceId(), lineNo(), exec->function(), *exec->arguments())) {
             dbg->imp()->abort();
-            return Completion(Interrupted, jsUndefined());
+            return exec->setInterruptedCompletion();
         }
     }    
     
-    Completion completion = ScopeNode::execute(exec);
+    JSValue* result = ScopeNode::execute(exec);
     
     if (Debugger* dbg = exec->dynamicGlobalObject()->debugger()) {
-        if (completion.complType() == Throw)
-            exec->setException(completion.value());
-
+        if (exec->completionType() == Throw)
+            exec->setException(result);
         if (!dbg->returnEvent(exec, sourceId(), lineNo(), exec->function())) {
             dbg->imp()->abort();
-            return Completion(Interrupted, jsUndefined());
+            return exec->setInterruptedCompletion();
         }
     }
 
     
-    return completion;
+    return result;
 }
 
 // ------------------------------ FuncDeclNode ---------------------------------
@@ -4555,9 +4548,9 @@ FunctionImp* FuncDeclNode::makeFunction(ExecState* exec)
   return func;
 }
 
-Completion FuncDeclNode::execute(ExecState *)
+JSValue* FuncDeclNode::execute(ExecState* exec)
 {
-    return Completion(Normal);
+    return exec->setNormalCompletion();
 }
 
 // ------------------------------ FuncExprNode ---------------------------------
index fc2e1df88e4ca5de79ba5d87f850ccff499b3c52..b9451f5230bfe4724ebe34b7c90419f4bf5a88f5 100644 (file)
@@ -144,9 +144,12 @@ namespace KJS {
 
   protected:
     Node(JSType) KJS_FAST_CALL; // used by ExpressionNode
-    Completion createErrorCompletion(ExecState *, ErrorType, const char *msg) KJS_FAST_CALL;
-    Completion createErrorCompletion(ExecState *, ErrorType, const char *msg, const Identifier &) KJS_FAST_CALL;
 
+    // for use in execute()
+    JSValue* setErrorCompletion(ExecState*, ErrorType, const char* msg) KJS_FAST_CALL;
+    JSValue* setErrorCompletion(ExecState*, ErrorType, const char* msg, const Identifier&) KJS_FAST_CALL;
+
+    // for use in evaluate()
     JSValue* throwError(ExecState*, ErrorType, const char* msg) KJS_FAST_CALL;
     JSValue* throwError(ExecState*, ErrorType, const char* msg, const char*) KJS_FAST_CALL;
     JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, Node*) KJS_FAST_CALL;
@@ -160,7 +163,8 @@ namespace KJS {
     void handleException(ExecState*) KJS_FAST_CALL;
     void handleException(ExecState*, JSValue*) KJS_FAST_CALL;
 
-    Completion rethrowException(ExecState*) KJS_FAST_CALL;
+    // for use in execute()
+    JSValue* rethrowException(ExecState*) KJS_FAST_CALL;
 
     int m_line : 28;
     unsigned m_expectedReturnType : 3; // JSType
@@ -200,11 +204,11 @@ namespace KJS {
     void setLoc(int line0, int line1) KJS_FAST_CALL;
     int firstLine() const KJS_FAST_CALL { return lineNo(); }
     int lastLine() const KJS_FAST_CALL { return m_lastLine; }
-    bool hitStatement(ExecState*) KJS_FAST_CALL;
-    virtual Completion execute(ExecState *exec) KJS_FAST_CALL = 0;
+    virtual JSValue* execute(ExecState *exec) KJS_FAST_CALL = 0;
     void pushLabel(const Identifier &id) KJS_FAST_CALL { ls.push(id); }
     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
   protected:
+    bool hitStatement(ExecState*) KJS_FAST_CALL;
     LabelStack ls;
   private:
     int m_lastLine;
@@ -1724,7 +1728,7 @@ namespace KJS {
   public:
     VarStatementNode(VarDeclNode* l) KJS_FAST_CALL : next(l) { }
     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
-    virtual Completion execute(ExecState*) KJS_FAST_CALL;
+    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
   private:
     RefPtr<VarDeclNode> next;
@@ -1743,7 +1747,7 @@ namespace KJS {
         return elems;
     }
     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL { ASSERT_NOT_REACHED(); }
-    virtual Completion execute(ExecState*) KJS_FAST_CALL  { ASSERT_NOT_REACHED(); return Completion(); }
+    virtual JSValue* execute(ExecState*) KJS_FAST_CALL  { ASSERT_NOT_REACHED(); return 0; }
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL  { ASSERT_NOT_REACHED(); }
     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
   private:
@@ -1754,7 +1758,7 @@ namespace KJS {
   public:
     BlockNode(SourceElements* children) KJS_FAST_CALL;
     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
-    virtual Completion execute(ExecState*) KJS_FAST_CALL;
+    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
   protected:
     OwnPtr<SourceElements> m_children;
@@ -1763,7 +1767,7 @@ namespace KJS {
   class EmptyStatementNode : public StatementNode {
   public:
     EmptyStatementNode() KJS_FAST_CALL { } // debug
-    virtual Completion execute(ExecState*) KJS_FAST_CALL;
+    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
   };
 
@@ -1771,7 +1775,7 @@ namespace KJS {
   public:
     ExprStatementNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) { }
     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
-    virtual Completion execute(ExecState*) KJS_FAST_CALL;
+    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
   private:
     RefPtr<ExpressionNode> expr;
@@ -1782,7 +1786,7 @@ namespace KJS {
     IfNode(ExpressionNode* e, StatementNode *s1, StatementNode *s2) KJS_FAST_CALL
       : expr(e), statement1(s1), statement2(s2) { }
     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
-    virtual Completion execute(ExecState*) KJS_FAST_CALL;
+    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
   private:
     RefPtr<ExpressionNode> expr;
@@ -1794,7 +1798,7 @@ namespace KJS {
   public:
     DoWhileNode(StatementNode *s, ExpressionNode* e) KJS_FAST_CALL : statement(s), expr(e) { }
     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
-    virtual Completion execute(ExecState*) KJS_FAST_CALL;
+    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
   private:
     RefPtr<StatementNode> statement;
@@ -1805,7 +1809,7 @@ namespace KJS {
   public:
     WhileNode(ExpressionNode* e, StatementNode *s) KJS_FAST_CALL : expr(e), statement(s) { }
     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
-    virtual Completion execute(ExecState*) KJS_FAST_CALL;
+    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
   private:
     RefPtr<ExpressionNode> expr;
@@ -1824,7 +1828,7 @@ namespace KJS {
     }
 
     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
-    virtual Completion execute(ExecState*) KJS_FAST_CALL;
+    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
   private:
     RefPtr<ExpressionNode> expr1;
@@ -1838,7 +1842,7 @@ namespace KJS {
     ForInNode(ExpressionNode*  l, ExpressionNode* e, StatementNode *s) KJS_FAST_CALL;
     ForInNode(const Identifier &i, AssignExprNode *in, ExpressionNode* e, StatementNode *s) KJS_FAST_CALL;
     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
-    virtual Completion execute(ExecState*) KJS_FAST_CALL;
+    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     VarDeclNode* getVarDecl() { return varDecl.get(); }
   private:
@@ -1854,7 +1858,7 @@ namespace KJS {
   public:
     ContinueNode() KJS_FAST_CALL { }
     ContinueNode(const Identifier &i) KJS_FAST_CALL : ident(i) { }
-    virtual Completion execute(ExecState*) KJS_FAST_CALL;
+    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
   private:
     Identifier ident;
@@ -1864,7 +1868,7 @@ namespace KJS {
   public:
     BreakNode() KJS_FAST_CALL { }
     BreakNode(const Identifier &i) KJS_FAST_CALL : ident(i) { }
-    virtual Completion execute(ExecState*) KJS_FAST_CALL;
+    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
   private:
     Identifier ident;
@@ -1874,7 +1878,7 @@ namespace KJS {
   public:
     ReturnNode(ExpressionNode* v) KJS_FAST_CALL : value(v) {}
     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
-    virtual Completion execute(ExecState*) KJS_FAST_CALL;
+    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
   private:
     RefPtr<ExpressionNode> value;
@@ -1884,7 +1888,7 @@ namespace KJS {
   public:
     WithNode(ExpressionNode* e, StatementNode* s) KJS_FAST_CALL : expr(e), statement(s) { }
     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
-    virtual Completion execute(ExecState*) KJS_FAST_CALL;
+    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
   private:
     RefPtr<ExpressionNode> expr;
@@ -1895,7 +1899,7 @@ namespace KJS {
   public:
     LabelNode(const Identifier &l, StatementNode *s) KJS_FAST_CALL : label(l), statement(s) { }
     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
-    virtual Completion execute(ExecState*) KJS_FAST_CALL;
+    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
   private:
     Identifier label;
@@ -1906,7 +1910,7 @@ namespace KJS {
   public:
     ThrowNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) {}
     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
-    virtual Completion execute(ExecState*) KJS_FAST_CALL;
+    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
   private:
     RefPtr<ExpressionNode> expr;
@@ -1917,7 +1921,7 @@ namespace KJS {
     TryNode(StatementNode *b, const Identifier &e, StatementNode *c, StatementNode *f) KJS_FAST_CALL
       : tryBlock(b), exceptionIdent(e), catchBlock(c), finallyBlock(f) { }
     virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
-    virtual Completion execute(ExecState*) KJS_FAST_CALL;
+    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
   private:
     RefPtr<StatementNode> tryBlock;
@@ -1964,7 +1968,7 @@ namespace KJS {
   class ProgramNode : public ScopeNode {
   public:
     ProgramNode(SourceElements*, DeclarationStacks::VarStack*, DeclarationStacks::FunctionStack*) KJS_FAST_CALL;
-    virtual Completion execute(ExecState*) KJS_FAST_CALL;
+    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
     
   private:
     void initializeSymbolTable(ExecState*) KJS_FAST_CALL;
@@ -1977,7 +1981,7 @@ namespace KJS {
   class EvalNode : public ScopeNode {
   public:
     EvalNode(SourceElements*, DeclarationStacks::VarStack*, DeclarationStacks::FunctionStack*) KJS_FAST_CALL;
-    virtual Completion execute(ExecState*) KJS_FAST_CALL;
+    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
     
   private:
     ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL;
@@ -1987,7 +1991,7 @@ namespace KJS {
   public:
     FunctionBodyNode(SourceElements*, DeclarationStacks::VarStack*, DeclarationStacks::FunctionStack*) KJS_FAST_CALL;
 
-    virtual Completion execute(ExecState*) KJS_FAST_CALL;
+    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
 
     SymbolTable& symbolTable() KJS_FAST_CALL { return m_symbolTable; }
 
@@ -2025,7 +2029,7 @@ namespace KJS {
       : ident(i), body(b) { addParams(); }
     FuncDeclNode(const Identifier& i, ParameterNode* p, FunctionBodyNode* b) KJS_FAST_CALL
       : ident(i), param(p), body(b) { addParams(); }
-    virtual Completion execute(ExecState*) KJS_FAST_CALL;
+    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     ALWAYS_INLINE FunctionImp* makeFunction(ExecState*) KJS_FAST_CALL;
     Identifier ident;
@@ -2045,7 +2049,7 @@ namespace KJS {
       virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
 
       JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-      Completion evalStatements(ExecState*) KJS_FAST_CALL;
+      JSValue* executeStatements(ExecState*) KJS_FAST_CALL;
 
   private:
       RefPtr<ExpressionNode> expr;
@@ -2073,7 +2077,7 @@ namespace KJS {
   public:
       CaseBlockNode(ClauseListNode* l1, CaseClauseNode* d, ClauseListNode* l2) KJS_FAST_CALL;
       virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
-      Completion evalBlock(ExecState *exec, JSValue *input) KJS_FAST_CALL;
+      JSValue* executeBlock(ExecState*, JSValue *input) KJS_FAST_CALL;
       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
   private:
@@ -2086,7 +2090,7 @@ namespace KJS {
   public:
       SwitchNode(ExpressionNode* e, CaseBlockNode *b) KJS_FAST_CALL : expr(e), block(b) { }
       virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
-      virtual Completion execute(ExecState*) KJS_FAST_CALL;
+      virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
   private:
       RefPtr<ExpressionNode> expr;
index 8a3e39c9c3e6d2f8827eb4047000a64c7f7545c1..68570d87ac1432ffcb427026042bbb9019006303 100644 (file)
@@ -88,7 +88,6 @@ namespace KJS {
     static const ClassInfo info;
     enum { NaNValue, NegInfinity, PosInfinity, MaxValue, MinValue };
 
-    Completion execute(const List &);
     JSObject *construct(const List &);
   };