Merge squirrelfish branch into trunk.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@33979 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/kjs/Activation.h b/JavaScriptCore/kjs/Activation.h
deleted file mode 100644
index 5cbdf1ab..0000000
--- a/JavaScriptCore/kjs/Activation.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
- *  Copyright (C) 2003, 2006, 2007 Apple Inc. All rights reserved.
- *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
- *  Copyright (C) 2007 Maks Orlovich
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Library General Public
- *  License as published by the Free Software Foundation; either
- *  version 2 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Library General Public License for more details.
- *
- *  You should have received a copy of the GNU Library General Public License
- *  along with this library; see the file COPYING.LIB.  If not, write to
- *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- *  Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef Activation_h
-#define Activation_h
-
-#include "ExecState.h"
-#include "JSVariableObject.h"
-#include "object.h"
-#include "function.h"
-
-namespace KJS {
-
-    class Arguments;
-    class FunctionImp;
-
-    class ActivationImp : public JSVariableObject {
-        friend class JSGlobalObject;
-        friend struct StackActivation;
-    private:
-        struct ActivationData : public JSVariableObjectData {
-            ActivationData() : isOnStack(true), leftRelic(false) { }
-            ActivationData(const ActivationData&);
-
-            ExecState* exec;
-            FunctionImp* function;
-            Arguments* argumentsObject;
-
-            bool isOnStack : 1;
-            bool leftRelic : 1;
-        };
-
-    public:
-        ActivationImp() { }
-        ActivationImp(const ActivationData&, bool);
-
-        virtual ~ActivationImp();
-
-        void init(ExecState*);
-
-        virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
-        virtual void put(ExecState*, const Identifier&, JSValue*);
-        virtual void putWithAttributes(ExecState*, const Identifier&, JSValue*, unsigned attributes);
-        virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
-
-        virtual const ClassInfo* classInfo() const { return &info; }
-        static const ClassInfo info;
-
-        virtual JSObject* toThisObject(ExecState*) const;
-
-        virtual void mark();
-        void markChildren();
-
-        virtual bool isActivationObject() const { return true; }
-    
-        bool isOnStack() const { return d()->isOnStack; }
-        bool needsPop() const { return d()->isOnStack || d()->leftRelic; }
-
-        virtual bool isDynamicScope() const;
-    private:
-        static PropertySlot::GetValueFunc getArgumentsGetter();
-        static JSValue* argumentsGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&);
-        void createArgumentsObject(ExecState*);
-        ActivationData* d() const { return static_cast<ActivationData*>(JSVariableObject::d); }
-    };
-
-    inline void ActivationImp::init(ExecState* exec)
-    {
-        d()->exec = exec;
-        d()->function = exec->function();
-        d()->symbolTable = &exec->function()->body->symbolTable();
-        d()->argumentsObject = 0;
-    }
-
-    const size_t activationStackNodeSize = 32;
-
-    struct StackActivation {
-        StackActivation() { activationStorage.JSVariableObject::d = &activationDataStorage; }
-        StackActivation(const StackActivation&);
-      
-        ActivationImp activationStorage;
-        ActivationImp::ActivationData activationDataStorage;
-    };
-
-    struct ActivationStackNode {
-        ActivationStackNode* prev;
-        StackActivation data[activationStackNodeSize];
-    };
-
-} // namespace
-
-#endif
diff --git a/JavaScriptCore/kjs/AllInOneFile.cpp b/JavaScriptCore/kjs/AllInOneFile.cpp
index 5144521..eb1d2b4 100644
--- a/JavaScriptCore/kjs/AllInOneFile.cpp
+++ b/JavaScriptCore/kjs/AllInOneFile.cpp
@@ -39,7 +39,6 @@
 #include "DateMath.cpp"
 #include "dtoa.cpp"
 #include "error_object.cpp"
-#include "ExecState.cpp"
 #include "function_object.cpp"
 #include "grammar.cpp"
 #include "identifier.cpp"
@@ -70,3 +69,5 @@
 #include "value.cpp"
 #include "wtf/FastMalloc.cpp"
 #include "wtf/TCSystemAlloc.cpp"
+#include "VM/CodeGenerator.cpp"
+#include "VM/RegisterFile.cpp"
diff --git a/JavaScriptCore/kjs/CallData.h b/JavaScriptCore/kjs/CallData.h
new file mode 100644
index 0000000..c701c2b
--- /dev/null
+++ b/JavaScriptCore/kjs/CallData.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+ 
+#ifndef CallData_h
+#define CallData_h
+
+namespace KJS {
+
+    class FunctionBodyNode;
+    class ScopeChainNode;
+
+    enum CallType {
+        CallTypeNone,
+        CallTypeNative,
+        CallTypeJS
+    };
+
+    union CallData {
+        struct {
+            FunctionBodyNode* functionBody;
+            ScopeChainNode* scopeChain;
+        } js;
+    };
+
+} // namespace KJS
+
+#endif // CallData_h
diff --git a/JavaScriptCore/kjs/CommonIdentifiers.cpp b/JavaScriptCore/kjs/CommonIdentifiers.cpp
index 543e6aa..00181fe 100644
--- a/JavaScriptCore/kjs/CommonIdentifiers.cpp
+++ b/JavaScriptCore/kjs/CommonIdentifiers.cpp
@@ -35,6 +35,7 @@
 CommonIdentifiers::CommonIdentifiers()
     : nullIdentifier(nullCString)
     , underscoreProto("__proto__")
+    , thisIdentifier("this")
     KJS_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(INITIALIZE_PROPERTY_NAME)
 {
 }
diff --git a/JavaScriptCore/kjs/CommonIdentifiers.h b/JavaScriptCore/kjs/CommonIdentifiers.h
index f709242..d7507b5 100644
--- a/JavaScriptCore/kjs/CommonIdentifiers.h
+++ b/JavaScriptCore/kjs/CommonIdentifiers.h
@@ -82,6 +82,7 @@
 
         const Identifier nullIdentifier;
         const Identifier underscoreProto;
+        const Identifier thisIdentifier;
 
 #define KJS_IDENTIFIER_DECLARE_PROPERTY_NAME_GLOBAL(name) const Identifier name;
         KJS_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(KJS_IDENTIFIER_DECLARE_PROPERTY_NAME_GLOBAL)
diff --git a/JavaScriptCore/kjs/ConstructData.h b/JavaScriptCore/kjs/ConstructData.h
new file mode 100644
index 0000000..9463503
--- /dev/null
+++ b/JavaScriptCore/kjs/ConstructData.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ConstructData_h
+#define ConstructData_h
+
+namespace KJS {
+
+    class FunctionBodyNode;
+    class ScopeChain;
+
+    enum ConstructType {
+        ConstructTypeNone,
+        ConstructTypeNative,
+        ConstructTypeJS
+    };
+
+    union ConstructData {
+        struct {
+            FunctionBodyNode* functionBody;
+            ScopeChainNode* scopeChain;
+        } js;
+    };
+
+} // namespace KJS
+
+#endif // ConstructData_h
diff --git a/JavaScriptCore/kjs/DebuggerCallFrame.cpp b/JavaScriptCore/kjs/DebuggerCallFrame.cpp
new file mode 100644
index 0000000..81bc193
--- /dev/null
+++ b/JavaScriptCore/kjs/DebuggerCallFrame.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "DebuggerCallFrame.h"
+
+#include "function.h"
+#include "CodeBlock.h"
+#include "Machine.h"
+#include "Parser.h"
+
+namespace KJS {
+
+const UString* DebuggerCallFrame::functionName() const
+{
+    if (!m_codeBlock)
+        return 0;
+
+    int callFrameOffset = m_registerOffset - m_codeBlock->numLocals - Machine::CallFrameHeaderSize;
+    if (callFrameOffset < 0)
+        return 0;
+
+    Register* callFrame = *m_registerBase + callFrameOffset;
+    FunctionImp* function = static_cast<FunctionImp*>(callFrame[Machine::Callee].u.jsValue);
+    if (!function)
+        return 0;
+    return &function->functionName().ustring();
+}
+
+JSObject* DebuggerCallFrame::thisObject() const
+{
+    if (!m_codeBlock)
+        return 0;
+
+    return static_cast<JSObject*>((*m_registerBase + m_registerOffset)[m_codeBlock->thisRegister].u.jsValue);
+}
+
+JSValue* DebuggerCallFrame::evaluate(const UString& script, JSValue*& exception) const
+{
+    if (!m_codeBlock)
+        return 0;
+
+    JSObject* thisObject = this->thisObject();
+
+    ExecState newExec(m_scopeChain->globalObject(), thisObject, m_scopeChain);
+
+    int sourceId;
+    int errLine;
+    UString errMsg;
+
+    RefPtr<EvalNode> evalNode = parser().parse<EvalNode>(&newExec, UString(), 0, UStringSourceProvider::create(script), &sourceId, &errLine, &errMsg);
+
+    if (!evalNode)
+        return Error::create(&newExec, SyntaxError, errMsg, errLine, sourceId, 0);
+
+    JSValue* result = machine().execute(evalNode.get(), &newExec, thisObject, &newExec.dynamicGlobalObject()->registerFileStack(), m_scopeChain, &exception);
+    return result;
+}
+
+} // namespace KJS
diff --git a/JavaScriptCore/kjs/DebuggerCallFrame.h b/JavaScriptCore/kjs/DebuggerCallFrame.h
new file mode 100644
index 0000000..157341b
--- /dev/null
+++ b/JavaScriptCore/kjs/DebuggerCallFrame.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+ 
+#ifndef DebuggerCallFrame_h
+#define DebuggerCallFrame_h
+
+namespace KJS {
+    
+    class CodeBlock;
+    class JSGlobalObject;
+    class JSObject;
+    class JSValue;
+    class Machine;
+    class UString;
+    class Register;
+    class ScopeChainNode;
+    
+    class DebuggerCallFrame {
+    public:
+        DebuggerCallFrame(Machine* machine, JSGlobalObject* dynamicGlobalObject, const CodeBlock* codeBlock, ScopeChainNode* scopeChain, JSValue* exception, Register** registerBase, int registerOffset)
+            : m_machine(machine)
+            , m_dynamicGlobalObject(dynamicGlobalObject)
+            , m_codeBlock(codeBlock)
+            , m_scopeChain(scopeChain)
+            , m_exception(exception)
+            , m_registerBase(registerBase)
+            , m_registerOffset(registerOffset)
+        {
+        }
+
+        JSGlobalObject* dynamicGlobalObject() const { return m_dynamicGlobalObject; }
+        const ScopeChainNode* scopeChain() const { return m_scopeChain; }
+        const UString* functionName() const;
+        JSObject* thisObject() const;
+        JSValue* evaluate(const UString&, JSValue*& exception) const;
+        JSValue* exception() const { return m_exception; }
+
+    private:
+        Machine* m_machine;
+        JSGlobalObject* m_dynamicGlobalObject;
+        const CodeBlock* m_codeBlock;
+        ScopeChainNode* m_scopeChain;
+        JSValue* m_exception;
+        Register** m_registerBase;
+        int m_registerOffset;
+    };
+
+} // namespace KJS
+
+#endif // DebuggerCallFrame_h
diff --git a/JavaScriptCore/kjs/ExecState.cpp b/JavaScriptCore/kjs/ExecState.cpp
index edab7fc..db89422 100644
--- a/JavaScriptCore/kjs/ExecState.cpp
+++ b/JavaScriptCore/kjs/ExecState.cpp
@@ -24,122 +24,43 @@
 #include "config.h"
 #include "ExecState.h"
 
-#include "Activation.h"
 #include "JSGlobalObject.h"
 #include "function.h"
 #include "internal.h"
 #include "scope_chain_mark.h"
-#include "ExecStateInlines.h"
 
 namespace KJS {
 
-// ECMA 10.2
-
-// The constructor for the globalExec pseudo-ExecState
-inline ExecState::ExecState(JSGlobalObject* globalObject, JSObject* thisObject)
+ExecState::ExecState(JSGlobalObject* globalObject, JSObject* globalThisValue, ScopeChainNode* globalScopeChain)
     : m_globalObject(globalObject)
+    , m_globalThisValue(globalThisValue)
     , m_exception(0)
-    , m_callingExec(0)
     , m_perThreadData(globalObject->perThreadData())
-    , m_scopeNode(0)
-    , m_function(0)
-    , m_arguments(0)
-    , m_activation(0)
-    , m_localStorage(&globalObject->localStorage())
-    , m_inlineScopeChainNode(0, 0)
-    , m_variableObject(globalObject)
-    , m_thisValue(thisObject)
-    , m_globalThisValue(thisObject)
-    , m_iterationDepth(0)
-    , m_switchDepth(0) 
-    , m_codeType(GlobalCode)
+    , m_prev(0)
+    , m_machine(0)
+    , m_registerFile(0)
+    , m_scopeChain(globalScopeChain)
+    , m_callFrameOffset(-1)
 {
-    m_scopeChain.push(globalObject);
 }
 
-inline ExecState::ExecState(JSGlobalObject* globalObject, JSObject* thisObject, ProgramNode* programNode)
-    : m_globalObject(globalObject)
+ExecState::ExecState(ExecState* exec, Machine* machine, RegisterFile* registerFile, ScopeChainNode* scopeChain, int callFrameOffset)
+    : m_globalObject(exec->m_globalObject)
+    , m_globalThisValue(exec->m_globalThisValue)
     , m_exception(0)
-    , m_callingExec(0)
-    , m_perThreadData(globalObject->perThreadData())
-    , m_scopeNode(programNode)
-    , m_function(0)
-    , m_arguments(0)
-    , m_activation(0)
-    , m_localStorage(&globalObject->localStorage())
-    , m_inlineScopeChainNode(0, 0)
-    , m_variableObject(globalObject)
-    , m_thisValue(thisObject)
-    , m_globalThisValue(thisObject)
-    , m_iterationDepth(0)
-    , m_switchDepth(0) 
-    , m_codeType(GlobalCode)
-{
-    ASSERT(m_scopeNode);
-    m_scopeChain.push(globalObject);
-}
-
-inline ExecState::ExecState(JSGlobalObject* globalObject, JSObject* thisObject, EvalNode* evalNode, ExecState* callingExec, const ScopeChain& scopeChain, JSVariableObject* variableObject)
-    : m_globalObject(globalObject)
-    , m_exception(0)
-    , m_callingExec(callingExec)
-    , m_perThreadData(callingExec->m_perThreadData)
-    , m_scopeNode(evalNode)
-    , m_function(0)
-    , m_arguments(0)
-    , m_activation(0)
-    , m_localStorage(callingExec->m_localStorage)
+    , m_perThreadData(exec->m_globalObject->perThreadData())
+    , m_prev(exec)
+    , m_machine(machine)
+    , m_registerFile(registerFile)
     , m_scopeChain(scopeChain)
-    , m_inlineScopeChainNode(0, 0)
-    , m_variableObject(variableObject)
-    , m_thisValue(thisObject)
-    , m_globalThisValue(thisObject)
-    , m_iterationDepth(0)
-    , m_switchDepth(0) 
-    , m_codeType(EvalCode)
-{    
-    ASSERT(m_scopeNode);
+    , m_callFrameOffset(callFrameOffset)
+{
+    ASSERT(!exec->m_exception);
 }
 
-JSGlobalObject* ExecState::lexicalGlobalObject() const
+bool ExecState::isGlobalObject(JSObject* o) const
 {
-    JSObject* object = m_scopeChain.bottom();
-    if (object && object->isGlobalObject())
-        return static_cast<JSGlobalObject*>(object);
-    return m_globalObject;
+    return o->isGlobalObject();
 }
 
-GlobalExecState::GlobalExecState(JSGlobalObject* globalObject, JSObject* thisObject)
-    : ExecState(globalObject, thisObject)
-{
-}
-
-GlobalExecState::~GlobalExecState()
-{
-}
-
-InterpreterExecState::InterpreterExecState(JSGlobalObject* globalObject, JSObject* thisObject, ProgramNode* programNode)
-    : ExecState(globalObject, thisObject, programNode)
-{
-    m_globalObject->activeExecStates().append(this);
-}
-
-InterpreterExecState::~InterpreterExecState()
-{
-    ASSERT(m_globalObject->activeExecStates().last() == this);
-    m_globalObject->activeExecStates().removeLast();
-}
-
-EvalExecState::EvalExecState(JSGlobalObject* globalObject, JSObject* thisObj, EvalNode* evalNode, ExecState* callingExec, const ScopeChain& scopeChain, JSVariableObject* variableObject)
-    : ExecState(globalObject, thisObj, evalNode, callingExec, scopeChain, variableObject)
-{
-    m_globalObject->activeExecStates().append(this);
-}
-
-EvalExecState::~EvalExecState()
-{
-    ASSERT(m_globalObject->activeExecStates().last() == this);
-    m_globalObject->activeExecStates().removeLast();
-}
-    
 } // namespace KJS
diff --git a/JavaScriptCore/kjs/ExecState.h b/JavaScriptCore/kjs/ExecState.h
index 0947703..d4012a2 100644
--- a/JavaScriptCore/kjs/ExecState.h
+++ b/JavaScriptCore/kjs/ExecState.h
@@ -32,7 +32,6 @@
 
 namespace KJS  {
 
-    class ActivationImp;
     class CommonIdentifiers;
     class EvalNode;
     class FunctionBodyNode;
@@ -42,11 +41,13 @@
     class Interpreter;
     class JSGlobalObject;
     class JSVariableObject;
+    class Machine;
     class ProgramNode;
+    class RegisterFile;
     class ScopeNode;
-    
-    enum CodeType { GlobalCode, EvalCode, FunctionCode };
 
+    struct Instruction;
+    
     struct PerThreadData {
         const HashTable* arrayTable;
         const HashTable* dateTable;
@@ -63,50 +64,32 @@
     // Represents the current state of script execution.
     // Passed as the first argument to most functions.
     class ExecState : Noncopyable {
-        friend class JSGlobalObject;
+        friend class Machine;
+        friend class DebuggerCallFrame;
+
     public:
-        // Global object that was in scope when the current script started executing.
+        ExecState(JSGlobalObject*, JSObject* globalThisValue, ScopeChainNode* globalScopeChain);
+
+        // Global object in which execution began.
         JSGlobalObject* dynamicGlobalObject() const { return m_globalObject; }
         
-        // Global object that was in scope when the current body of code was defined.
-        JSGlobalObject* lexicalGlobalObject() const;
-                
+        // Global object in which the current script was defined. (Can differ
+        // from dynamicGlobalObject() during function calls across frames.)
+        JSGlobalObject* lexicalGlobalObject() const
+        {
+            return m_scopeChain->globalObject();
+        }
+        
+        JSObject* globalThisValue() const { return m_globalThisValue; }
+        
+        Machine* machine() const { return m_machine; }
+        
+        // Exception propogation.
         void setException(JSValue* exception) { m_exception = exception; }
         void clearException() { m_exception = 0; }
         JSValue* exception() const { return m_exception; }
         JSValue** exceptionSlot() { return &m_exception; }
         bool hadException() const { return !!m_exception; }
-        JSValue* takeException() { JSValue* exception = m_exception; m_exception = 0; return exception; }
-        
-        const ScopeChain& scopeChain() const { return m_scopeChain; }
-        void pushScope(JSObject* s) { m_scopeChain.push(s); }
-        void popScope() { m_scopeChain.pop(); }
-        void replaceScopeChainTop(JSObject* o) { m_scopeChain.replaceTop(o); }
-        
-        JSVariableObject* variableObject() const { return m_variableObject; }
-        void setVariableObject(JSVariableObject* v) { m_variableObject = v; }
-        
-        JSObject* thisValue() const { return m_thisValue; }
-        JSObject* globalThisValue() const { return m_globalThisValue; }
-        
-        ExecState* callingExecState() { return m_callingExec; }
-        
-        ActivationImp* activationObject() { return m_activation; }
-        void setActivationObject(ActivationImp* a) { m_activation = a; }
-        CodeType codeType() { return m_codeType; }
-        ScopeNode* scopeNode() { return m_scopeNode; }
-        FunctionImp* function() const { return m_function; }
-        const List* arguments() const { return m_arguments; }
-        
-        LabelStack& seenLabels() { return m_labelStack; }
-        
-        void pushIteration() { m_iterationDepth++; }
-        void popIteration() { m_iterationDepth--; }
-        bool inIteration() const { return (m_iterationDepth > 0); }
-        
-        void pushSwitch() { m_switchDepth++; }
-        void popSwitch() { m_switchDepth--; }
-        bool inSwitch() const { return (m_switchDepth > 0); }
 
         // These pointers are used to avoid accessing global variables for these,
         // to avoid taking PIC branches in Mach-O binaries.
@@ -120,8 +103,34 @@
         static const HashTable* RegExpObjectImpTable(ExecState* exec) { return exec->m_perThreadData->RegExpObjectImpTable; }
         static const HashTable* stringTable(ExecState* exec) { return exec->m_perThreadData->stringTable; }
 
-        LocalStorage& localStorage() { return *m_localStorage; }
-        void setLocalStorage(LocalStorage* s) { m_localStorage = s; }
+    private:
+        ExecState(ExecState*, Machine*, RegisterFile*, ScopeChainNode*, int callFrameOffset);
+
+        bool isGlobalObject(JSObject*) const;
+
+        JSGlobalObject* m_globalObject;
+        JSObject* m_globalThisValue;
+
+        JSValue* m_exception;
+
+        const PerThreadData* m_perThreadData;
+
+        // These values are controlled by the machine.
+        ExecState* m_prev;
+        Machine* m_machine;
+        RegisterFile* m_registerFile;
+        ScopeChainNode* m_scopeChain;
+        int m_callFrameOffset; // A negative offset indicates a non-function scope.
+    };
+
+    // This code is now defunct:
+
+    enum CodeType { GlobalCode, EvalCode, FunctionCode };
+    class OldInterpreterExecState : public ExecState {
+    public:
+        void pushSwitch() { m_switchDepth++; }
+        void popSwitch() { m_switchDepth--; }
+        bool inSwitch() const { return (m_switchDepth > 0); }
 
         // These are only valid right after calling execute().
         ComplType completionType() const { return m_completionType; }
@@ -184,70 +193,38 @@
             m_completionType = Interrupted;
             return 0;
         }
-
-    protected:
-        ExecState(JSGlobalObject*, JSObject* thisObject);
-        ExecState(JSGlobalObject*, JSObject* thisObject, ProgramNode*);
-        ExecState(JSGlobalObject*, JSObject* thisObject, EvalNode*, ExecState* callingExecState, const ScopeChain&, JSVariableObject*);
-        ExecState(JSGlobalObject*, JSObject* thisObject, JSObject* globalThisValue, FunctionBodyNode*, ExecState* callingExecState, FunctionImp*, const List& args);
-        ~ExecState();
-
-        // ExecStates are always stack-allocated, and the garbage collector
-        // marks the stack, so we don't need to protect the objects below from GC.
-
-        JSGlobalObject* m_globalObject;
-        JSValue* m_exception;
-
-        ExecState* m_callingExec;
-
-        const PerThreadData* m_perThreadData;
-
-        ScopeNode* m_scopeNode;
+        CodeType codeType() { return m_codeType; }
+        void pushIteration() { m_iterationDepth++; }
+        void popIteration() { m_iterationDepth--; }
+        bool inIteration() const { return (m_iterationDepth > 0); }
+        LabelStack& seenLabels() { return m_labelStack; }
+        void pushScope(JSObject* s) { m_scopeChain.push(s); }
+        void popScope() { m_scopeChain.pop(); }
+        JSVariableObject* variableObject() const { ASSERT_NOT_REACHED(); return m_variableObject; }
+        void setVariableObject(JSVariableObject* v) { m_variableObject = v; }
+        ExecState* callingExecState() { return m_callingExec; }
+        ScopeNode* scopeNode() { return m_scopeNode; }
+        const List* arguments() const { return m_arguments; }
+        FunctionImp* function() const { return m_function; }
+        LocalStorage& localStorage() { ASSERT_NOT_REACHED(); return *(LocalStorage*)0; }
+        void setLocalStorage(LocalStorage*) { ASSERT_NOT_REACHED(); }
+        ScopeChain& scopeChain() { return m_scopeChain; }
+        JSObject* thisValue() const { return m_thisValue; }
         
-        FunctionImp* m_function;
-        const List* m_arguments;
-        ActivationImp* m_activation;
-        LocalStorage* m_localStorage;
-
-        ScopeChain m_scopeChain;
-        ScopeChainNode m_inlineScopeChainNode;
-        JSVariableObject* m_variableObject;
-
-        JSObject* m_thisValue;
-        JSObject* m_globalThisValue;
-        
-        LabelStack m_labelStack;
-        int m_iterationDepth;
-        int m_switchDepth;
-        CodeType m_codeType;
-
         ComplType m_completionType;
         const Identifier* m_breakOrContinueTarget;
-    };
-
-    class GlobalExecState : public ExecState {
-    public:
-        GlobalExecState(JSGlobalObject*, JSObject* thisObject);
-        ~GlobalExecState();
-    };
-
-    class InterpreterExecState : public ExecState {
-    public:
-        InterpreterExecState(JSGlobalObject*, JSObject* thisObject, ProgramNode*);
-        ~InterpreterExecState();
-    };
-
-    class EvalExecState : public ExecState {
-    public:
-        EvalExecState(JSGlobalObject*, JSObject* thisObj, EvalNode*, ExecState* callingExec, const ScopeChain&, JSVariableObject*);
-        ~EvalExecState();
-    };
-
-    class FunctionExecState : public ExecState {
-    public:
-        FunctionExecState(JSGlobalObject*, JSObject* thisObject, JSObject* globalThisValue, FunctionBodyNode*,
-            ExecState* callingExecState, FunctionImp*, const List& args);
-        ~FunctionExecState();
+        int m_switchDepth;
+        CodeType m_codeType;
+        int m_iterationDepth;
+        LabelStack m_labelStack;
+        ScopeChainNode m_inlineScopeChainNode;
+        ScopeChain m_scopeChain;
+        JSVariableObject* m_variableObject;
+        ScopeNode* m_scopeNode;
+        const List* m_arguments;
+        FunctionImp* m_function;
+        ExecState* m_callingExec;
+        JSObject* m_thisValue;
     };
 
 } // namespace KJS
diff --git a/JavaScriptCore/kjs/ExecStateInlines.h b/JavaScriptCore/kjs/ExecStateInlines.h
deleted file mode 100644
index c0d29e5..0000000
--- a/JavaScriptCore/kjs/ExecStateInlines.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// -*- mode: c++; c-basic-offset: 4 -*-
-/*
- *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
- *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
- *  Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved.
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Library General Public
- *  License as published by the Free Software Foundation; either
- *  version 2 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Library General Public License for more details.
- *
- *  You should have received a copy of the GNU Library General Public License
- *  along with this library; see the file COPYING.LIB.  If not, write to
- *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- *  Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef ExecStateInlines_h
-#define ExecStateInlines_h
-
-#include "ExecState.h"
-#include "function.h"
-#include "JSGlobalObject.h"
-
-namespace KJS  {
-
-    inline ExecState::ExecState(JSGlobalObject* globalObject, JSObject* thisObject, JSObject* globalThisValue,
-                                FunctionBodyNode* functionBodyNode, ExecState* callingExec,
-                                FunctionImp* func, const List& args)
-        : m_globalObject(globalObject)
-        , m_exception(0)
-        , m_callingExec(callingExec)
-        , m_perThreadData(callingExec->m_perThreadData)
-        , m_scopeNode(functionBodyNode)
-        , m_function(func)
-        , m_arguments(&args)
-        , m_scopeChain(func->scope())
-        , m_inlineScopeChainNode(0, 0)
-        , m_thisValue(thisObject)
-        , m_globalThisValue(globalThisValue)
-        , m_iterationDepth(0)
-        , m_switchDepth(0) 
-        , m_codeType(FunctionCode)
-    {
-        ASSERT(m_scopeNode);
-        
-        ActivationImp* activation = globalObject->pushActivation(this);
-        m_activation = activation;
-        m_localStorage = &activation->localStorage();
-        m_variableObject = activation;
-        if (functionBodyNode->usesEval() || functionBodyNode->needsClosure())
-            m_scopeChain.push(activation);
-        else {
-            m_inlineScopeChainNode.object = activation;
-            // The ScopeChain will ref this node itself, so we don't need to worry about
-            // anything trying to delete our scopenode
-            m_scopeChain.push(&m_inlineScopeChainNode);
-        }
-    }
-
-    inline ExecState::~ExecState()
-    {
-    }
-
-    inline FunctionExecState::FunctionExecState(JSGlobalObject* globalObject, JSObject* thisObject, JSObject* globalThisValue,
-                                                FunctionBodyNode* functionBodyNode, ExecState* callingExec,
-                                                FunctionImp* func, const List& args)
-        : ExecState(globalObject, thisObject, globalThisValue, functionBodyNode, callingExec, func, args)
-    {
-        m_globalObject->activeExecStates().append(this);
-    }
-
-    inline FunctionExecState::~FunctionExecState()
-    {
-        ASSERT(m_globalObject->activeExecStates().last() == this);
-        m_globalObject->activeExecStates().removeLast();
-        
-        if (m_activation->needsPop())
-            m_globalObject->popActivation();
-        
-        if (m_inlineScopeChainNode.next) {
-            m_scopeChain.popInlineScopeNode();
-            m_inlineScopeChainNode.next = 0;
-        }
-    }
-
-} // namespace KJS
-
-#endif // ExecStateInlines_h
diff --git a/JavaScriptCore/kjs/JSActivation.cpp b/JavaScriptCore/kjs/JSActivation.cpp
new file mode 100644
index 0000000..66961fd
--- /dev/null
+++ b/JavaScriptCore/kjs/JSActivation.cpp
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+ 
+#include "config.h"
+#include "JSActivation.h"
+
+#include "CodeBlock.h"
+#include "Machine.h"
+#include "Register.h"
+#include "function.h"
+
+namespace KJS {
+
+const ClassInfo JSActivation::info = { "JSActivation", 0, 0, 0 };
+
+JSActivation::JSActivation(PassRefPtr<FunctionBodyNode> functionBody, Register** registerBase, int registerOffset)
+    : Base(new JSActivationData(functionBody, registerBase, registerOffset))
+{
+}
+
+JSActivation::~JSActivation()
+{
+    delete d()->registerArray;
+    delete d();
+}
+
+void JSActivation::copyRegisters()
+{
+    int numRegisters = d()->functionBody->generatedCode().numLocals;
+    if (!numRegisters)
+        return;
+
+    Register* registerArray = static_cast<Register*>(fastMalloc(numRegisters * sizeof(Register)));
+
+    Register* end = registers();
+    Register* src = end - numRegisters;
+    Register* dst = registerArray;
+    while (src != end)
+        *dst++ = *src++;
+
+    d()->registerArray = registerArray;
+    d()->registerBase = &d()->registerArray;
+    d()->registerOffset = numRegisters;
+}
+
+bool JSActivation::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+{
+    if (symbolTableGet(propertyName, slot))
+        return true;
+
+    if (JSValue** location = getDirectLocation(propertyName)) {
+        slot.setValueSlot(this, location);
+        return true;
+    }
+
+    // Only return the built-in arguments object if it wasn't overridden above.
+    if (propertyName == exec->propertyNames().arguments) {
+        slot.setCustom(this, getArgumentsGetter());
+        return true;
+    }
+
+    // We don't call through to JSObject because there's no way to give an 
+    // activation object getter properties or a prototype.
+    ASSERT(!_prop.hasGetterSetterProperties());
+    ASSERT(prototype() == jsNull());
+    return false;
+}
+
+void JSActivation::put(ExecState*, const Identifier& propertyName, JSValue* value)
+{
+    if (symbolTablePut(propertyName, value))
+        return;
+
+    // We don't call through to JSObject because __proto__ and getter/setter 
+    // properties are non-standard extensions that other implementations do not
+    // expose in the activation object.
+    ASSERT(!_prop.hasGetterSetterProperties());
+    _prop.put(propertyName, value, 0, true);
+}
+
+// FIXME: Make this function honor ReadOnly (const) and DontEnum
+void JSActivation::putWithAttributes(ExecState*, const Identifier& propertyName, JSValue* value, unsigned attributes)
+{
+    if (symbolTablePutWithAttributes(propertyName, value, attributes))
+        return;
+
+    // We don't call through to JSObject because __proto__ and getter/setter 
+    // properties are non-standard extensions that other implementations do not
+    // expose in the activation object.
+    ASSERT(!_prop.hasGetterSetterProperties());
+    _prop.put(propertyName, value, attributes, true);
+}
+
+bool JSActivation::deleteProperty(ExecState* exec, const Identifier& propertyName)
+{
+    if (propertyName == exec->propertyNames().arguments)
+        return false;
+
+    return Base::deleteProperty(exec, propertyName);
+}
+
+JSObject* JSActivation::toThisObject(ExecState* exec) const
+{
+    return exec->globalThisValue();
+}
+
+void JSActivation::mark()
+{
+    Base::mark();
+    
+    if (d()->argumentsObject)
+        d()->argumentsObject->mark();
+    
+    // No need to mark our values if they're still in the regsiter file, since
+    // the register file gets marked independently.
+    if(!d()->registerArray)
+        return;
+    
+    int numRegisters = d()->functionBody->generatedCode().numLocals;
+    Register* end = d()->registerArray + numRegisters;
+    for (Register* it = d()->registerArray; it != end; ++it) {
+        JSValue* v = (*it).u.jsValue;
+        if (!v->marked())
+            v->mark();
+    }
+}
+
+bool JSActivation::isActivationObject() const
+{
+    return true;
+}
+
+bool JSActivation::isDynamicScope() const
+{
+    return d()->functionBody->usesEval();
+}
+
+JSValue* JSActivation::argumentsGetter(ExecState* exec, JSObject*, const Identifier&, const PropertySlot& slot)
+{
+    JSActivation* thisObj = static_cast<JSActivation*>(slot.slotBase());
+    if (!thisObj->d()->argumentsObject)
+        thisObj->d()->argumentsObject = thisObj->createArgumentsObject(exec);
+
+    return thisObj->d()->argumentsObject;
+}
+
+// These two functions serve the purpose of isolating the common case from a
+// PIC branch.
+
+PropertySlot::GetValueFunc JSActivation::getArgumentsGetter()
+{
+    return argumentsGetter;
+}
+
+JSObject* JSActivation::createArgumentsObject(ExecState* exec)
+{
+    Register* callFrame = registers() - d()->functionBody->generatedCode().numLocals - Machine::CallFrameHeaderSize;
+
+    FunctionImp* function;
+    Register* argv;
+    int argc;
+    exec->machine()->getFunctionAndArguments(registerBase(), callFrame, function, argv, argc);
+    List args(&argv->u.jsValue, argc);
+    return new Arguments(exec, function, args, this);
+}
+
+} // namespace KJS
diff --git a/JavaScriptCore/kjs/JSActivation.h b/JavaScriptCore/kjs/JSActivation.h
new file mode 100644
index 0000000..a6a269d
--- /dev/null
+++ b/JavaScriptCore/kjs/JSActivation.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+ 
+#ifndef JSActivation_h
+#define JSActivation_h
+
+#include "JSVariableObject.h"
+#include "SymbolTable.h"
+#include "nodes.h"
+
+namespace KJS {
+
+    class Register;
+    
+    class JSActivation : public JSVariableObject {
+    typedef JSVariableObject Base;
+    public:
+        JSActivation(PassRefPtr<FunctionBodyNode>, Register**, int registerOffset);
+        virtual ~JSActivation();
+        
+        virtual bool isActivationObject() const;
+        virtual bool isDynamicScope() const;
+
+        virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
+
+        virtual void put(ExecState*, const Identifier&, JSValue*);
+        virtual void putWithAttributes(ExecState*, const Identifier&, JSValue*, unsigned attributes);
+        virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
+
+        virtual JSObject* toThisObject(ExecState*) const;
+
+        virtual void mark();
+        
+        void copyRegisters();
+        
+        virtual const ClassInfo* classInfo() const { return &info; }
+        static const ClassInfo info;
+
+    private:
+        struct JSActivationData : public JSVariableObjectData {
+            JSActivationData(PassRefPtr<FunctionBodyNode> functionBody_, Register** registerBase, int registerOffset)
+                : JSVariableObjectData(&functionBody_->symbolTable(), registerBase, registerOffset)
+                , registerArray(0)
+                , functionBody(functionBody_)
+                , argumentsObject(0)
+            {
+            }
+
+            Register* registerArray;
+            RefPtr<FunctionBodyNode> functionBody; // Owns the symbol table and code block
+            JSObject* argumentsObject;
+        };
+        
+        static JSValue* argumentsGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot&);
+        NEVER_INLINE PropertySlot::GetValueFunc getArgumentsGetter();
+        NEVER_INLINE JSObject* createArgumentsObject(ExecState*);
+
+        JSActivationData* d() const { return static_cast<JSActivationData*>(JSVariableObject::d); }
+    };
+    
+} // namespace KJS
+
+#endif // JSActivation_h
diff --git a/JavaScriptCore/kjs/JSGlobalObject.cpp b/JavaScriptCore/kjs/JSGlobalObject.cpp
index 37ebdcd..55ea9de 100644
--- a/JavaScriptCore/kjs/JSGlobalObject.cpp
+++ b/JavaScriptCore/kjs/JSGlobalObject.cpp
@@ -30,7 +30,7 @@
 #include "config.h"
 #include "JSGlobalObject.h"
 
-#include "Activation.h"
+#include "CodeBlock.h"
 #include "array_object.h"
 #include "bool_object.h"
 #include "date_object.h"
@@ -104,15 +104,6 @@
 
 JSGlobalObject* JSGlobalObject::s_head = 0;
 
-void JSGlobalObject::deleteActivationStack()
-{
-    ActivationStackNode* prevNode = 0;
-    for (ActivationStackNode* currentNode = d()->activations; currentNode; currentNode = prevNode) {
-        prevNode = currentNode->prev;
-        delete currentNode;
-    }
-}
-
 JSGlobalObject::~JSGlobalObject()
 {
     ASSERT(JSLock::currentThreadIsHoldingLock());
@@ -125,8 +116,10 @@
     s_head = d()->next;
     if (s_head == this)
         s_head = 0;
-    
-    deleteActivationStack();
+
+    HashSet<ProgramCodeBlock*>::const_iterator end = codeBlocks().end();
+    for (HashSet<ProgramCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it)
+        (*it)->globalObject = 0;
     
     delete d();
 }
@@ -205,11 +198,6 @@
     d()->recursion = 0;
     d()->debugger = 0;
     
-    ActivationStackNode* newStackNode = new ActivationStackNode;
-    newStackNode->prev = 0;    
-    d()->activations = newStackNode;
-    d()->activationCount = 0;
-
     d()->perThreadData.arrayTable = &threadClassInfoHashTables()->arrayTable;
     d()->perThreadData.dateTable = &threadClassInfoHashTables()->dateTable;
     d()->perThreadData.mathTable = &threadClassInfoHashTables()->mathTable;
@@ -219,20 +207,13 @@
     d()->perThreadData.stringTable = &threadClassInfoHashTables()->stringTable;
     d()->perThreadData.propertyNames = CommonIdentifiers::shared();
 
-    d()->globalExec.set(new GlobalExecState(this, thisValue));
+    d()->globalExec.set(new ExecState(this, thisValue, d()->globalScopeChain.node()));
 
     d()->pageGroupIdentifier = 0;
 
     reset(prototype());
 }
 
-bool JSGlobalObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
-{
-    if (symbolTableGet(propertyName, slot))
-        return true;
-    return JSVariableObject::getOwnPropertySlot(exec, propertyName, slot);
-}
-
 void JSGlobalObject::put(ExecState* exec, const Identifier& propertyName, JSValue* value)
 {
     if (symbolTablePut(propertyName, value))
@@ -268,7 +249,8 @@
     // dangerous. (The allocations below may cause a GC.)
 
     _prop.clear();
-    localStorage().clear();
+    registerFileStack().current()->clear();
+    registerFileStack().current()->addGlobalSlots(1);
     symbolTable().clear();
 
     // Prototypes
@@ -389,21 +371,14 @@
     putDirect("URIError", d()->URIErrorConstructor);
 
     // Set global values.
-    Identifier mathIdent = "Math";
-    JSValue* mathObject = new MathObjectImp(exec, d()->objectPrototype);
-    symbolTableInsert(mathIdent, mathObject, DontEnum | DontDelete);
-    
-    Identifier nanIdent = "NaN";
-    JSValue* nanValue = jsNaN();
-    symbolTableInsert(nanIdent, nanValue, DontEnum | DontDelete);
-    
-    Identifier infinityIdent = "Infinity";
-    JSValue* infinityValue = jsNumber(Inf);
-    symbolTableInsert(infinityIdent, infinityValue, DontEnum | DontDelete);
-    
-    Identifier undefinedIdent = "undefined";
-    JSValue* undefinedValue = jsUndefined();
-    symbolTableInsert(undefinedIdent, undefinedValue, DontEnum | DontDelete);
+    GlobalPropertyInfo staticGlobals[] = {
+        GlobalPropertyInfo("Math", new MathObjectImp(exec, d()->objectPrototype), DontEnum | DontDelete),
+        GlobalPropertyInfo("NaN", jsNaN(), DontEnum | DontDelete),
+        GlobalPropertyInfo("Infinity", jsNumber(Inf), DontEnum | DontDelete),
+        GlobalPropertyInfo("undefined", jsUndefined(), DontEnum | DontDelete)
+    };
+
+    addStaticGlobals(staticGlobals, sizeof(staticGlobals) / sizeof(GlobalPropertyInfo));
 
     // Set global functions.
 
@@ -492,10 +467,12 @@
 void JSGlobalObject::mark()
 {
     JSVariableObject::mark();
+    
+    HashSet<ProgramCodeBlock*>::const_iterator end = codeBlocks().end();
+    for (HashSet<ProgramCodeBlock*>::const_iterator it = codeBlocks().begin(); it != end; ++it)
+        (*it)->mark();
 
-    ExecStateStack::const_iterator end = d()->activeExecStates.end();
-    for (ExecStateStack::const_iterator it = d()->activeExecStates.begin(); it != end; ++it)
-        (*it)->m_scopeChain.mark();
+    registerFileStack().mark();
 
     markIfNeeded(d()->globalExec->exception());
 
@@ -544,28 +521,6 @@
     return d()->globalExec.get();
 }
 
-void JSGlobalObject::tearOffActivation(ExecState* exec, bool leaveRelic)
-{
-    ActivationImp* oldActivation = exec->activationObject();
-    if (!oldActivation || !oldActivation->isOnStack())
-        return;
-
-    ASSERT(exec->codeType() == FunctionCode);
-    ActivationImp* newActivation = new ActivationImp(*oldActivation->d(), leaveRelic);
-    
-    if (!leaveRelic) {
-        checkActivationCount();
-        d()->activationCount--;
-    }
-    
-    oldActivation->d()->localStorage.shrink(0);
-    
-    exec->setActivationObject(newActivation);
-    exec->setVariableObject(newActivation);
-    exec->setLocalStorage(&newActivation->localStorage());
-    exec->replaceScopeChainTop(newActivation);
-}
-
 bool JSGlobalObject::isDynamicScope() const
 {
     return true;
diff --git a/JavaScriptCore/kjs/JSGlobalObject.h b/JavaScriptCore/kjs/JSGlobalObject.h
index dbfe3f9..1ce515c 100644
--- a/JavaScriptCore/kjs/JSGlobalObject.h
+++ b/JavaScriptCore/kjs/JSGlobalObject.h
@@ -1,7 +1,7 @@
 // -*- c-basic-offset: 4 -*-
 /*
  *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
- *  Copyright (C) 2007 Apple Inc. All rights reserved.
+ *  Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
@@ -24,11 +24,13 @@
 #define KJS_GlobalObject_h
 
 #include "JSVariableObject.h"
-#include "Activation.h"
+#include "RegisterFile.h"
+#include "RegisterFileStack.h"
+#include <wtf/HashSet.h>
+#include <wtf/OwnPtr.h>
 
 namespace KJS {
 
-    class ActivationImp;
     class ArrayObjectImp;
     class ArrayPrototype;
     class BooleanObjectImp;
@@ -50,6 +52,7 @@
     class NumberPrototype;
     class ObjectObjectImp;
     class ObjectPrototype;
+    class ProgramCodeBlock;
     class PrototypeReflexiveFunction;
     class RangeError;
     class RangeErrorPrototype;
@@ -77,8 +80,10 @@
         using JSVariableObject::JSVariableObjectData;
 
         struct JSGlobalObjectData : public JSVariableObjectData {
-            JSGlobalObjectData()
-                : JSVariableObjectData(&inlineSymbolTable)
+            JSGlobalObjectData(JSGlobalObject* globalObject, JSObject* thisValue)
+                : JSVariableObjectData(&symbolTable, registerFileStack.globalBasePointer(), 0)
+                , globalScopeChain(globalObject)
+                , globalExec(new ExecState(globalObject, thisValue, globalScopeChain.node()))
             {
             }
 
@@ -87,7 +92,10 @@
 
             Debugger* debugger;
             
-            OwnPtr<GlobalExecState> globalExec;
+            RegisterFileStack registerFileStack;
+            ScopeChain globalScopeChain;
+            OwnPtr<ExecState> globalExec;
+
             int recursion;
 
             unsigned timeoutTime;
@@ -131,30 +139,26 @@
             NativeErrorPrototype* typeErrorPrototype;
             NativeErrorPrototype* URIErrorPrototype;
             
-            SymbolTable inlineSymbolTable;
-
-            ExecStateStack activeExecStates;
-
-            ActivationStackNode* activations;
-            size_t activationCount;
-            
+            SymbolTable symbolTable;
             unsigned pageGroupIdentifier;
 
-            OwnPtr<HashSet<JSObject*> > arrayVisitedElements; // Global data shared by array prototype functions.
-
             PerThreadData perThreadData;
+
+            HashSet<ProgramCodeBlock*> codeBlocks;
+
+            OwnPtr<HashSet<JSObject*> > arrayVisitedElements; // Global data shared by array prototype functions.
         };
 
     public:
         JSGlobalObject()
-            : JSVariableObject(new JSGlobalObjectData)
+            : JSVariableObject(new JSGlobalObjectData(this, this))
         {
             init(this);
         }
 
     protected:
         JSGlobalObject(JSValue* proto, JSObject* globalThisValue)
-            : JSVariableObject(proto, new JSGlobalObjectData)
+            : JSVariableObject(proto, new JSGlobalObjectData(this, globalThisValue))
         {
             init(globalThisValue);
         }
@@ -163,6 +167,7 @@
         virtual ~JSGlobalObject();
 
         virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
+        virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&, bool& slotIsWriteable);
         virtual void put(ExecState*, const Identifier&, JSValue*);
         virtual void putWithAttributes(ExecState*, const Identifier& propertyName, JSValue* value, unsigned attributes);
 
@@ -227,6 +232,8 @@
         int recursion() { return d()->recursion; }
         void incRecursion() { ++d()->recursion; }
         void decRecursion() { --d()->recursion; }
+        
+        ScopeChain& globalScopeChain() { return d()->globalScopeChain; }
 
         virtual void mark();
 
@@ -239,16 +246,14 @@
 
         virtual bool allowsAccessFrom(const JSGlobalObject*) const { return true; }
 
-        ActivationImp* pushActivation(ExecState*);
-        void popActivation();
-        void tearOffActivation(ExecState*, bool markAsRelic = false);
-
         virtual bool isDynamicScope() const;
 
-        ExecStateStack& activeExecStates() const { return d()->activeExecStates; }
-
         HashSet<JSObject*>& arrayVisitedElements() { if (!d()->arrayVisitedElements) d()->arrayVisitedElements.set(new HashSet<JSObject*>); return *d()->arrayVisitedElements; }
 
+        HashSet<ProgramCodeBlock*>& codeBlocks() { return d()->codeBlocks; }
+
+        RegisterFileStack& registerFileStack() { return d()->registerFileStack; }
+
         // Per-thread hash tables, cached on the global object for faster access.
         const PerThreadData* perThreadData() const { return &d()->perThreadData; }
 
@@ -260,15 +265,55 @@
         
         JSGlobalObjectData* d() const { return static_cast<JSGlobalObjectData*>(JSVariableObject::d); }
 
+        struct GlobalPropertyInfo {
+            GlobalPropertyInfo(const Identifier& i, JSValue* v, unsigned a)
+                : identifier(i)
+                , value(v)
+                , attributes(a)
+            {
+            }
+
+            const Identifier& identifier;
+            JSValue* value;
+            unsigned attributes;
+        };
+        void addStaticGlobals(GlobalPropertyInfo*, int count);
+
         bool checkTimeout();
         void resetTimeoutCheck();
 
-        void deleteActivationStack();
-        void checkActivationCount();
-
         static JSGlobalObject* s_head;
     };
 
+    inline void JSGlobalObject::addStaticGlobals(GlobalPropertyInfo* globals, int count)
+    {
+        RegisterFile* registerFile = registerFileStack().current();
+        ASSERT(registerFile->safeForReentry() && registerFile->isGlobal() && !registerFile->size());
+        int index = -registerFile->numGlobalSlots() - 1;
+        registerFile->addGlobalSlots(count);
+        for (int i = 0; i < count; ++i) {
+            ASSERT(globals[i].attributes & DontDelete);
+            SymbolTableEntry newEntry(index, globals[i].attributes);
+            symbolTable().add(globals[i].identifier.ustring().rep(), newEntry);
+            valueAt(index) = globals[i].value;
+            --index;
+        }
+    }
+
+    inline bool JSGlobalObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
+    {
+        if (JSVariableObject::getOwnPropertySlot(exec, propertyName, slot))
+            return true;
+        return symbolTableGet(propertyName, slot);
+    }
+
+    inline bool JSGlobalObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot, bool& slotIsWriteable)
+    {
+        if (JSVariableObject::getOwnPropertySlotForWrite(exec, propertyName, slot, slotIsWriteable))
+            return true;
+        return symbolTableGet(propertyName, slot, slotIsWriteable);
+    }
+
     inline bool JSGlobalObject::timedOut()
     {
         d()->tickCount++;
@@ -279,35 +324,11 @@
         return checkTimeout();
     }
 
-    inline ActivationImp* JSGlobalObject::pushActivation(ExecState* exec)
+    inline JSGlobalObject* ScopeChainNode::globalObject() const
     {
-        if (d()->activationCount == activationStackNodeSize) {
-            ActivationStackNode* newNode = new ActivationStackNode;
-            newNode->prev = d()->activations;
-            d()->activations = newNode;
-            d()->activationCount = 0;
-        }
-        
-        StackActivation* stackEntry = &d()->activations->data[d()->activationCount++];
-        stackEntry->activationStorage.init(exec);
-        return &stackEntry->activationStorage;
-    }
-
-    inline void JSGlobalObject::checkActivationCount()
-    {
-        if (!d()->activationCount) {
-            ActivationStackNode* prev = d()->activations->prev;
-            ASSERT(prev);
-            delete d()->activations;
-            d()->activations = prev;
-            d()->activationCount = activationStackNodeSize;
-        }
-    }
-
-    inline void JSGlobalObject::popActivation()
-    {
-        checkActivationCount();
-        d()->activations->data[--d()->activationCount].activationDataStorage.localStorage.shrink(0);    
+        JSGlobalObject* globalObject = static_cast<JSGlobalObject*>(bottom());
+        ASSERT(globalObject->isGlobalObject());
+        return globalObject;
     }
 
 } // namespace KJS
diff --git a/JavaScriptCore/kjs/JSImmediate.cpp b/JavaScriptCore/kjs/JSImmediate.cpp
index 5f4a108..e416729 100644
--- a/JavaScriptCore/kjs/JSImmediate.cpp
+++ b/JavaScriptCore/kjs/JSImmediate.cpp
@@ -23,6 +23,7 @@
 
 #include "JSGlobalObject.h"
 #include "bool_object.h"
+#include "JSNotAnObject.h"
 #include "number_object.h"
 #include "object.h"
 
@@ -32,9 +33,9 @@
 {
     ASSERT(isImmediate(v));
     if (v == jsNull())
-        return throwError(exec, TypeError, "Null value");
+        return new JSNotAnObject(throwError(exec, TypeError, "Null value"));
     else if (v == jsUndefined())
-        return throwError(exec, TypeError, "Undefined value");
+        return new JSNotAnObject(throwError(exec, TypeError, "Undefined value"));
     else if (isBoolean(v)) {
         List args;
         args.append(const_cast<JSValue *>(v));
@@ -62,14 +63,4 @@
     return UString::from(getTruncatedInt32(v));
 }
 
-JSType JSImmediate::type(const JSValue *v)
-{
-    ASSERT(isImmediate(v));
-    
-    uintptr_t tag = getTag(v);
-    if (tag == UndefinedType)
-        return v == jsUndefined() ? UndefinedType : NullType;
-    return static_cast<JSType>(tag);
-}
-
 } // namespace KJS
diff --git a/JavaScriptCore/kjs/JSImmediate.h b/JavaScriptCore/kjs/JSImmediate.h
index bc0cb16..3ab6a20 100644
--- a/JavaScriptCore/kjs/JSImmediate.h
+++ b/JavaScriptCore/kjs/JSImmediate.h
@@ -122,6 +122,8 @@
     static JSValue* falseImmediate();
     static JSValue* undefinedImmediate();
     static JSValue* nullImmediate();
+
+    static JSValue* impossibleValue();
     
 private:
     static const uintptr_t TagMask = 3; // type tags are 2 bits long
@@ -152,6 +154,9 @@
 ALWAYS_INLINE JSValue* JSImmediate::undefinedImmediate() { return tag(1 << 2, UndefinedType); }
 ALWAYS_INLINE JSValue* JSImmediate::nullImmediate() { return tag(0, UndefinedType); }
 
+// This value is impossible because 0x4 is not a valid pointer but a tag of 0 would indicate non-immediate
+ALWAYS_INLINE JSValue* JSImmediate::impossibleValue() { return tag(1 << 2, 0); }
+
 ALWAYS_INLINE bool JSImmediate::toBoolean(const JSValue* v)
 {
     ASSERT(isImmediate(v));
@@ -273,6 +278,16 @@
     return getUInt32(v, i);
 }
 
+ALWAYS_INLINE JSType JSImmediate::type(const JSValue* v)
+{
+    ASSERT(isImmediate(v));
+    
+    uintptr_t tag = getTag(v);
+    if (tag == UndefinedType)
+        return v == undefinedImmediate() ? UndefinedType : NullType;
+    return static_cast<JSType>(tag);
+}
+
 } // namespace KJS
 
 #endif
diff --git a/JavaScriptCore/kjs/JSNotAnObject.cpp b/JavaScriptCore/kjs/JSNotAnObject.cpp
new file mode 100644
index 0000000..4c02c16
--- /dev/null
+++ b/JavaScriptCore/kjs/JSNotAnObject.cpp
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "config.h"
+#include "JSNotAnObject.h"
+
+#include <wtf/UnusedParam.h>
+
+namespace KJS {
+    // JSValue methods
+    JSValue *JSNotAnObject::toPrimitive(ExecState* exec, JSType) const
+    {
+        UNUSED_PARAM(exec);
+        ASSERT(exec->hadException() && exec->exception() == m_exception);
+        return m_exception;
+    }
+    
+    bool JSNotAnObject::getPrimitiveNumber(ExecState* exec, double&, JSValue*&)
+    {
+        UNUSED_PARAM(exec);
+        ASSERT(exec->hadException() && exec->exception() == m_exception);
+        return false;
+    }
+    
+    bool JSNotAnObject::toBoolean(ExecState* exec) const
+    {
+        UNUSED_PARAM(exec);
+        ASSERT(exec->hadException() && exec->exception() == m_exception);
+        return false;
+    }
+    
+    double JSNotAnObject::toNumber(ExecState* exec) const
+    {
+        UNUSED_PARAM(exec);
+        ASSERT(exec->hadException() && exec->exception() == m_exception);
+        return NaN;
+    }
+
+    UString JSNotAnObject::toString(ExecState* exec) const
+    {
+        UNUSED_PARAM(exec);
+        ASSERT(exec->hadException() && exec->exception() == m_exception);
+        return "";
+    }
+    
+    JSObject *JSNotAnObject::toObject(ExecState* exec) const
+    {
+        UNUSED_PARAM(exec);
+        ASSERT(exec->hadException() && exec->exception() == m_exception);
+        return m_exception;
+    }
+    
+    // marking
+    void JSNotAnObject::mark()
+    {
+        JSCell::mark();
+        if (!m_exception->marked())
+            m_exception->mark();
+    }
+    
+    bool JSNotAnObject::getOwnPropertySlot(ExecState* exec, const Identifier&, PropertySlot&)
+    {
+        UNUSED_PARAM(exec);
+        ASSERT(exec->hadException() && exec->exception() == m_exception);
+        return false;
+    }
+    
+    bool JSNotAnObject::getOwnPropertySlot(ExecState* exec, unsigned, PropertySlot&)
+    {
+        UNUSED_PARAM(exec);
+        ASSERT(exec->hadException() && exec->exception() == m_exception);
+        return false;
+    }
+    
+    void JSNotAnObject::put(ExecState* exec, const Identifier& , JSValue*)
+    {
+        UNUSED_PARAM(exec);
+        ASSERT(exec->hadException() && exec->exception() == m_exception);
+    }
+    
+    void JSNotAnObject::put(ExecState* exec, unsigned, JSValue*)
+    {
+        UNUSED_PARAM(exec);
+        ASSERT(exec->hadException() && exec->exception() == m_exception);
+    }
+    
+    bool JSNotAnObject::deleteProperty(ExecState* exec, const Identifier &)
+    {
+        UNUSED_PARAM(exec);
+        ASSERT(exec->hadException() && exec->exception() == m_exception);
+        return false;
+    }
+    
+    bool JSNotAnObject::deleteProperty(ExecState* exec, unsigned)
+    {
+        UNUSED_PARAM(exec);
+        ASSERT(exec->hadException() && exec->exception() == m_exception);
+        return false;
+    }
+    
+    JSValue *JSNotAnObject::defaultValue(ExecState* exec, JSType) const
+    {
+        UNUSED_PARAM(exec);
+        ASSERT(exec->hadException() && exec->exception() == m_exception);
+        return m_exception;
+    }
+    
+    JSObject* JSNotAnObject::construct(ExecState* exec, const List&)
+    {
+        UNUSED_PARAM(exec);
+        ASSERT(exec->hadException() && exec->exception() == m_exception);
+        return m_exception;
+    }
+    
+    JSObject* JSNotAnObject::construct(ExecState* exec, const List&, const Identifier&, const UString&, int)
+    {
+        UNUSED_PARAM(exec);
+        ASSERT(exec->hadException() && exec->exception() == m_exception);
+        return m_exception;
+    }
+    
+    JSValue* JSNotAnObject::callAsFunction(ExecState* exec, JSObject *, const List &)
+    {
+        UNUSED_PARAM(exec);
+        ASSERT(exec->hadException() && exec->exception() == m_exception);
+        return m_exception;
+    }
+    
+    void JSNotAnObject::getPropertyNames(ExecState* exec, PropertyNameArray&)
+    {
+        UNUSED_PARAM(exec);
+        ASSERT(exec->hadException() && exec->exception() == m_exception);        
+    }
+    
+}
diff --git a/JavaScriptCore/kjs/JSNotAnObject.h b/JavaScriptCore/kjs/JSNotAnObject.h
new file mode 100644
index 0000000..c99fd4a
--- /dev/null
+++ b/JavaScriptCore/kjs/JSNotAnObject.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSNotAnObject_h
+#define JSNotAnObject_h
+
+#include "object.h"
+
+namespace KJS {
+    
+    // This unholy class is used to allow us to avoid multiple exception checks
+    // in certain SquirrelFish opcodes -- effectively it just silently consumes
+    // any operations performed on the result of a failed toObject call.
+    class JSNotAnObject : public JSObject {
+    public:
+        JSNotAnObject(JSObject* exception)
+            : m_exception(exception)
+        {
+        }
+
+        // JSValue methods
+        virtual JSValue *toPrimitive(ExecState* exec, JSType preferredType = UnspecifiedType) const;
+        virtual bool getPrimitiveNumber(ExecState* exec, double& number, JSValue*& value);
+        virtual bool toBoolean(ExecState* exec) const;
+        virtual double toNumber(ExecState* exec) const;
+        virtual UString toString(ExecState* exec) const;
+        virtual JSObject *toObject(ExecState* exec) const;
+        
+        // marking
+        virtual void mark();
+
+        virtual bool getOwnPropertySlot(ExecState* , const Identifier&, PropertySlot&);
+        virtual bool getOwnPropertySlot(ExecState* , unsigned index, PropertySlot&);
+
+        virtual void put(ExecState*, const Identifier& propertyName, JSValue* value);
+        virtual void put(ExecState*, unsigned propertyName, JSValue* value);
+
+        virtual bool deleteProperty(ExecState* exec, const Identifier &propertyName);
+        virtual bool deleteProperty(ExecState* exec, unsigned propertyName);
+
+        virtual JSValue *defaultValue(ExecState* exec, JSType hint) const;
+
+        virtual JSObject* construct(ExecState* exec, const List& args);
+        virtual JSObject* construct(ExecState* exec, const List& args, const Identifier& functionName, const UString& sourceURL, int lineNumber);
+        
+        virtual JSValue *callAsFunction(ExecState* exec, JSObject *thisObj, const List &args);
+
+        virtual void getPropertyNames(ExecState*, PropertyNameArray&);
+
+    private:
+        JSObject* m_exception;
+    };
+}
+
+#endif
diff --git a/JavaScriptCore/kjs/JSVariableObject.cpp b/JavaScriptCore/kjs/JSVariableObject.cpp
index 720a7bca..51e396d 100644
--- a/JavaScriptCore/kjs/JSVariableObject.cpp
+++ b/JavaScriptCore/kjs/JSVariableObject.cpp
@@ -46,35 +46,23 @@
 {
     SymbolTable::const_iterator end = symbolTable().end();
     for (SymbolTable::const_iterator it = symbolTable().begin(); it != end; ++it) {
-        if ((localStorage()[it->second].attributes & DontEnum) == 0)
-            propertyNames.add(it->first.get());
+        if (!(it->second.getAttributes() & DontEnum))
+            propertyNames.add(Identifier(it->first.get()));
     }
-
+    
     JSObject::getPropertyNames(exec, propertyNames);
 }
 
 bool JSVariableObject::getPropertyAttributes(ExecState* exec, const Identifier& propertyName, unsigned& attributes) const
 {
-    size_t index = symbolTable().get(propertyName.ustring().rep());
-    if (index != missingSymbolMarker()) {
-        attributes = localStorage()[index].attributes;
+    SymbolTableEntry entry = symbolTable().get(propertyName.ustring().rep());
+    if (!entry.isEmpty()) {
+        attributes = entry.getAttributes() | DontDelete;
         return true;
     }
     return JSObject::getPropertyAttributes(exec, propertyName, attributes);
 }
 
-void JSVariableObject::mark()
-{
-    JSObject::mark();
-
-    size_t size = d->localStorage.size();
-    for (size_t i = 0; i < size; ++i) {
-        JSValue* value = d->localStorage[i].value;
-        if (!value->marked())
-            value->mark();
-    }
-}
-
 bool JSVariableObject::isVariableObject() const
 {
     return true;
diff --git a/JavaScriptCore/kjs/JSVariableObject.h b/JavaScriptCore/kjs/JSVariableObject.h
index ee12221..af873c4 100644
--- a/JavaScriptCore/kjs/JSVariableObject.h
+++ b/JavaScriptCore/kjs/JSVariableObject.h
@@ -29,45 +29,50 @@
 #ifndef JSVariableObject_h
 #define JSVariableObject_h
 
-#include "LocalStorageEntry.h"
+#include "Register.h"
 #include "SymbolTable.h"
+#include "UnusedParam.h"
 #include "object.h"
+#include <wtf/UnusedParam.h>
 
 namespace KJS {
 
+    class Register;
+
     class JSVariableObject : public JSObject {
     public:
         SymbolTable& symbolTable() const { return *d->symbolTable; }
-        LocalStorage& localStorage() const { return d->localStorage; }
 
         virtual void putWithAttributes(ExecState*, const Identifier&, JSValue*, unsigned attributes) = 0;
 
         virtual bool deleteProperty(ExecState*, const Identifier&);
         virtual void getPropertyNames(ExecState*, PropertyNameArray&);
         
-        virtual void mark();
-
         virtual bool isVariableObject() const;
         virtual bool isDynamicScope() const = 0;
 
         virtual bool getPropertyAttributes(ExecState*, const Identifier& propertyName, unsigned& attributes) const;
 
+        JSValue*& valueAt(int index) const { return registers()[index].u.jsValue; }
     protected:
         // Subclasses of JSVariableObject can subclass this struct to add data
         // without increasing their own size (since there's a hard limit on the
         // size of a JSCell).
         struct JSVariableObjectData {
-            JSVariableObjectData() { }
-            JSVariableObjectData(SymbolTable* s)
-                : symbolTable(s) // Subclass owns this pointer.
+            JSVariableObjectData(SymbolTable* symbolTable_, Register** registerBase_, int registerOffset_)
+                : symbolTable(symbolTable_)
+                , registerBase(registerBase_)
+                , registerOffset(registerOffset_)
             {
+                ASSERT(symbolTable_);
+                ASSERT(registerBase_);
             }
 
-            LocalStorage localStorage; // Storage for variables in the symbol table.
-            SymbolTable* symbolTable; // Maps name -> index in localStorage.
-        };
+            SymbolTable* symbolTable; // Maps name -> offset from "r" in register file.
 
-        JSVariableObject() { }
+            Register** registerBase; // Location where a pointer to the base of the register file is stored.
+            int registerOffset; // Offset of "r", the register past the end of local storage.
+        };
 
         JSVariableObject(JSVariableObjectData* data)
             : d(data) // Subclass owns this pointer.
@@ -80,64 +85,58 @@
         {
         }
 
+        Register** registerBase() const { return d->registerBase; }
+        Register* registers() const { return *registerBase() + d->registerOffset; }
+
         bool symbolTableGet(const Identifier&, PropertySlot&);
+        bool symbolTableGet(const Identifier&, PropertySlot&, bool& slotIsWriteable);
         bool symbolTablePut(const Identifier&, JSValue*);
         bool symbolTablePutWithAttributes(const Identifier&, JSValue*, unsigned attributes);
-        bool symbolTableInsert(const Identifier&, JSValue*, unsigned attributes);
 
         JSVariableObjectData* d;
     };
 
     inline bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertySlot& slot)
     {
-        size_t index = symbolTable().inlineGet(propertyName.ustring().rep());
-        if (index == missingSymbolMarker())
-            return false;
-#ifndef NDEBUG
-        // During initialization, the variable object needs to advertise that it has certain
-        // properties, even if they're not ready for access yet. This check verifies that
-        // no one tries to access such a property. In a release build, we optimize this check
-        // away and just return an invalid pointer. There's no harm in an invalid pointer,
-        // since no one dereferences it.
-        if (index >= d->localStorage.size()) {
-            slot.setUngettable(this);
+        SymbolTableEntry entry = symbolTable().inlineGet(propertyName.ustring().rep());
+        if (!entry.isEmpty()) {
+            slot.setValueSlot(this, &valueAt(entry.getIndex()));
             return true;
         }
-#endif
-        slot.setValueSlot(this, &d->localStorage[index].value);
-        return true;
+        return false;
+    }
+
+    inline bool JSVariableObject::symbolTableGet(const Identifier& propertyName, PropertySlot& slot, bool& slotIsWriteable)
+    {
+        SymbolTableEntry entry = symbolTable().inlineGet(propertyName.ustring().rep());
+        if (!entry.isEmpty()) {
+            slot.setValueSlot(this, &valueAt(entry.getIndex()));
+            slotIsWriteable = !entry.isReadOnly();
+            return true;
+        }
+        return false;
     }
 
     inline bool JSVariableObject::symbolTablePut(const Identifier& propertyName, JSValue* value)
     {
-        size_t index = symbolTable().inlineGet(propertyName.ustring().rep());
-        if (index == missingSymbolMarker())
+        SymbolTableEntry entry = symbolTable().inlineGet(propertyName.ustring().rep());
+        if (entry.isEmpty())
             return false;
-        LocalStorageEntry& entry = d->localStorage[index];
-        if (entry.attributes & ReadOnly)
+        if (entry.isReadOnly())
             return true;
-        entry.value = value;
+        valueAt(entry.getIndex()) = value;
         return true;
     }
 
     inline bool JSVariableObject::symbolTablePutWithAttributes(const Identifier& propertyName, JSValue* value, unsigned attributes)
     {
-        size_t index = symbolTable().get(propertyName.ustring().rep());
-        if (index == missingSymbolMarker())
+        SymbolTable::iterator iter = symbolTable().find(propertyName.ustring().rep());
+        if (iter == symbolTable().end())
             return false;
-        LocalStorageEntry& entry = d->localStorage[index];
-        entry.value = value;
-        entry.attributes = attributes;
-        return true;
-    }
-
-    inline bool JSVariableObject::symbolTableInsert(const Identifier& propertyName, JSValue* value, unsigned attributes)
-    {
-        if (symbolTable().get(propertyName.ustring().rep()) != missingSymbolMarker())
-            return false;
-        size_t localStorageIndex = d->localStorage.size();
-        d->localStorage.append(LocalStorageEntry(value, attributes));
-        symbolTable().add(propertyName.ustring().rep(), localStorageIndex);
+        SymbolTableEntry& entry = iter->second;
+        ASSERT(!entry.isEmpty());
+        entry.setAttributes(attributes);
+        valueAt(entry.getIndex()) = value;
         return true;
     }
 
diff --git a/JavaScriptCore/kjs/NodeInfo.h b/JavaScriptCore/kjs/NodeInfo.h
index 442dd97..3101145 100644
--- a/JavaScriptCore/kjs/NodeInfo.h
+++ b/JavaScriptCore/kjs/NodeInfo.h
@@ -30,6 +30,7 @@
     const FeatureInfo NoFeatures = 0;
     const FeatureInfo EvalFeature = 1 << 0;
     const FeatureInfo ClosureFeature = 1 << 1;
+    const FeatureInfo AssignFeature = 1 << 2;
 
     template <typename T> struct NodeFeatureInfo {
         T m_node;
diff --git a/JavaScriptCore/kjs/Parser.cpp b/JavaScriptCore/kjs/Parser.cpp
index 5569801..e2b2563 100644
--- a/JavaScriptCore/kjs/Parser.cpp
+++ b/JavaScriptCore/kjs/Parser.cpp
@@ -24,6 +24,7 @@
 
 #include "config.h"
 #include "Parser.h"
+#include "debugger.h"
 
 #include "lexer.h"
 #include <wtf/HashSet.h>
@@ -42,23 +43,32 @@
 {
 }
 
-void Parser::parse(int startingLineNumber,
-    const UChar* code, unsigned length,
-    int* sourceId, int* errLine, UString* errMsg)
+void Parser::parse(ExecState* exec, const UString& sourceURL, int startingLineNumber,
+                   PassRefPtr<SourceProvider> prpSource,
+                   int* sourceId, int* errLine, UString* errMsg)
 {
     ASSERT(!m_sourceElements);
+    
+    int defaultSourceId;
+    int defaultErrLine;
+    UString defaultErrMsg;
+    
+    RefPtr<SourceProvider> source = prpSource;
 
-    if (errLine)
-        *errLine = -1;
-    if (errMsg)
-        *errMsg = 0;
+    if (!sourceId)
+        sourceId = &defaultSourceId;
+    if (!errLine)
+        errLine = &defaultErrLine;
+    if (!errMsg)
+        errMsg = &defaultErrMsg;
+
+    *errLine = -1;
+    *errMsg = 0;
         
     Lexer& lexer = KJS::lexer();
 
-    lexer.setCode(startingLineNumber, code, length);
-    m_sourceId++;
-    if (sourceId)
-        *sourceId = m_sourceId;
+    lexer.setCode(startingLineNumber, source);
+    *sourceId = ++m_sourceId;
 
     int parseError = kjsyyparse(&lexer);
     bool lexError = lexer.sawError();
@@ -67,18 +77,19 @@
     ParserRefCounted::deleteNewObjects();
 
     if (parseError || lexError) {
-        if (errLine)
-            *errLine = lexer.lineNo();
-        if (errMsg)
-            *errMsg = "Parse error";
+        *errLine = lexer.lineNo();
+        *errMsg = "Parse error";
         m_sourceElements.clear();
     }
+    
+    if (Debugger* debugger = exec->dynamicGlobalObject()->debugger())
+        debugger->sourceParsed(exec, *sourceId, sourceURL, *source, startingLineNumber, *errLine, *errMsg);
 }
 
 void Parser::didFinishParsing(SourceElements* sourceElements, ParserRefCountedData<DeclarationStacks::VarStack>* varStack, 
                               ParserRefCountedData<DeclarationStacks::FunctionStack>* funcStack, bool usesEval, bool needsClosure, int lastLine)
 {
-    m_sourceElements = sourceElements ? sourceElements : new SourceElements;
+    m_sourceElements = sourceElements;
     m_varDeclarations = varStack;
     m_funcDeclarations = funcStack;
     m_usesEval = usesEval;
diff --git a/JavaScriptCore/kjs/Parser.h b/JavaScriptCore/kjs/Parser.h
index f71eb5d8..cbfad36 100644
--- a/JavaScriptCore/kjs/Parser.h
+++ b/JavaScriptCore/kjs/Parser.h
@@ -25,11 +25,12 @@
 #ifndef Parser_h
 #define Parser_h
 
+#include "nodes.h"
+#include "SourceProvider.h"
 #include <wtf/Forward.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/OwnPtr.h>
 #include <wtf/RefPtr.h>
-#include "nodes.h"
 
 namespace WTF {
     template<typename T> class ThreadSpecific;
@@ -48,9 +49,9 @@
     class Parser : Noncopyable {
     public:
         template <class ParsedNode>
-        PassRefPtr<ParsedNode> parse(const UString& sourceURL, int startingLineNumber,
-            const UChar* code, unsigned length,
-            int* sourceId = 0, int* errLine = 0, UString* errMsg = 0);
+        PassRefPtr<ParsedNode> parse(ExecState*, const UString& sourceURL, int startingLineNumber,
+                                     PassRefPtr<SourceProvider> source,
+                                     int* sourceId = 0, int* errLine = 0, UString* errMsg = 0);
 
         UString sourceURL() const { return m_sourceURL; }
         int sourceId() const { return m_sourceId; }
@@ -63,8 +64,8 @@
         friend class WTF::ThreadSpecific<Parser>;
 
         Parser(); // Use parser() instead.
-        void parse(int startingLineNumber, const UChar* code, unsigned length,
-            int* sourceId, int* errLine, UString* errMsg);
+        void parse(ExecState*, const UString& sourceURL, int startingLineNumber, PassRefPtr<SourceProvider> source,
+                   int* sourceId, int* errLine, UString* errMsg);
 
         UString m_sourceURL;
         int m_sourceId;
@@ -79,12 +80,12 @@
     Parser& parser(); // Returns the singleton JavaScript parser.
 
     template <class ParsedNode>
-    PassRefPtr<ParsedNode> Parser::parse(const UString& sourceURL, int startingLineNumber,
-        const UChar* code, unsigned length,
-        int* sourceId, int* errLine, UString* errMsg)
+    PassRefPtr<ParsedNode> Parser::parse(ExecState* exec, const UString& sourceURL, int startingLineNumber,
+                                         PassRefPtr<SourceProvider> source,
+                                         int* sourceId, int* errLine, UString* errMsg)
     {
         m_sourceURL = sourceURL;
-        parse(startingLineNumber, code, length, sourceId, errLine, errMsg);
+        parse(exec, sourceURL, startingLineNumber, source, sourceId, errLine, errMsg);
         if (!m_sourceElements) {
             m_sourceURL = UString();
             return 0;
diff --git a/JavaScriptCore/kjs/PropertyNameArray.h b/JavaScriptCore/kjs/PropertyNameArray.h
index 3b18b25..0d7236d 100644
--- a/JavaScriptCore/kjs/PropertyNameArray.h
+++ b/JavaScriptCore/kjs/PropertyNameArray.h
@@ -43,6 +43,7 @@
         Identifier& operator[](unsigned i) { return m_vector[i]; }
         const Identifier& operator[](unsigned i) const { return m_vector[i]; }
 
+        Identifier* releaseIdentifiers() { return size() ? m_vector.releaseBuffer() : 0; }
     private:
         typedef HashSet<UString::Rep*, PtrHash<UString::Rep*> > IdentifierSet;
 
diff --git a/JavaScriptCore/kjs/SourceProvider.h b/JavaScriptCore/kjs/SourceProvider.h
new file mode 100644
index 0000000..10d0362
--- /dev/null
+++ b/JavaScriptCore/kjs/SourceProvider.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+ 
+#ifndef SourceProvider_h
+#define SourceProvider_h
+
+#include "ustring.h"
+#include <wtf/RefCounted.h>
+
+namespace KJS {
+
+    class SourceProvider : public RefCounted<SourceProvider> {
+    public:
+        virtual ~SourceProvider() {}
+        virtual UString getRange(int start, int end) const = 0;
+        virtual const UChar* data() const = 0;
+        virtual int length() const = 0;
+    };
+
+    class UStringSourceProvider : public SourceProvider {
+    public:
+        static PassRefPtr<UStringSourceProvider> create(const UString& source) { return adoptRef(new UStringSourceProvider(source)); }
+
+        UString getRange(int start, int end) const { return m_source.substr(start, end - start); }
+        const UChar* data() const { return m_source.data(); }
+        int length() const { return m_source.size(); }
+
+    private:
+        UStringSourceProvider(const UString& source) : m_source(source) {}
+        UString m_source;
+    };
+
+}
+
+#endif // SourceProvider_h
diff --git a/JavaScriptCore/kjs/SourceRange.h b/JavaScriptCore/kjs/SourceRange.h
new file mode 100644
index 0000000..20c49fc
--- /dev/null
+++ b/JavaScriptCore/kjs/SourceRange.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+ 
+#ifndef SourceRange_h
+#define SourceRange_h
+
+#include "SourceProvider.h"
+#include <wtf/RefPtr.h>
+
+namespace KJS {
+
+    class SourceRange {
+    public:
+        SourceRange(PassRefPtr<SourceProvider> provider, int start, int end) 
+            : m_sourceProvider(provider)
+            , m_startChar(start)
+            , m_endChar(end)
+        {
+        }
+        SourceRange() {}
+
+        UString toString() const { if (!m_sourceProvider) return UString(); return m_sourceProvider->getRange(m_startChar, m_endChar); }
+
+    private:
+        RefPtr<SourceProvider> m_sourceProvider;
+        int m_startChar;
+        int m_endChar;
+    };
+
+}
+
+#endif // SourceRange_h
diff --git a/JavaScriptCore/kjs/SymbolTable.h b/JavaScriptCore/kjs/SymbolTable.h
index d046a2e..768693b 100644
--- a/JavaScriptCore/kjs/SymbolTable.h
+++ b/JavaScriptCore/kjs/SymbolTable.h
@@ -29,6 +29,7 @@
 #ifndef SymbolTable_h
 #define SymbolTable_h
 
+#include "object.h"
 #include "ustring.h"
 #include <wtf/AlwaysInline.h>
 
@@ -39,14 +40,81 @@
         static unsigned hash(UString::Rep* key) { return key->computedHash(); }
     };
 
-    static ALWAYS_INLINE size_t missingSymbolMarker() { return std::numeric_limits<size_t>::max(); }
+    static ALWAYS_INLINE int missingSymbolMarker() { return std::numeric_limits<int>::max(); }
 
-    struct SymbolTableIndexHashTraits : HashTraits<size_t> {
-        static const bool emptyValueIsZero = false;
-        static size_t emptyValue() { return missingSymbolMarker(); }
+    struct SymbolTableEntry {
+        SymbolTableEntry()
+            : rawValue(0)
+        {
+        }
+        
+        SymbolTableEntry(int index)
+        {
+            rawValue = index & ~0x80000000 & ~0x40000000;
+        }
+        
+        SymbolTableEntry(int index, unsigned attributes)
+        {
+            rawValue = index;
+            
+            if (!(attributes & ReadOnly))
+                rawValue &= ~0x80000000;
+            
+            if (!(attributes & DontEnum))
+                rawValue &= ~0x40000000;
+        }
+
+        bool isEmpty() const
+        {
+            return rawValue == 0;
+        }
+
+        int getIndex() const
+        {
+            // Every register index we store is negative, so this bit twiddling works correctly
+            return rawValue | 0x80000000 | 0x40000000;
+        }
+
+        unsigned getAttributes() const
+        {
+            unsigned attributes = 0;
+            
+            if (rawValue & 0x80000000)
+                attributes |= ReadOnly;
+            
+            if (rawValue & 0x40000000)
+                attributes |= DontEnum;
+            
+            return attributes;
+        }
+
+        void setAttributes(unsigned attributes)
+        {
+            rawValue = getIndex();
+            
+            if (!(attributes & ReadOnly))
+                rawValue &= ~0x80000000;
+            
+            if (!(attributes & DontEnum))
+                rawValue &= ~0x40000000;
+        }
+
+        bool isReadOnly() const
+        {
+            return rawValue & 0x80000000;
+        }
+
+        int rawValue;
     };
 
-    typedef HashMap<RefPtr<UString::Rep>, size_t, IdentifierRepHash, HashTraits<RefPtr<UString::Rep> >, SymbolTableIndexHashTraits> SymbolTable;
+    struct SymbolTableIndexHashTraits {
+        typedef SymbolTableEntry TraitType;
+        static SymbolTableEntry emptyValue() { return SymbolTableEntry(); }
+        static const bool emptyValueIsZero = false;
+        static const bool needsDestruction = false;
+    };
+
+    typedef HashMap<RefPtr<UString::Rep>, SymbolTableEntry, IdentifierRepHash, HashTraits<RefPtr<UString::Rep> >, SymbolTableIndexHashTraits> SymbolTable;
 
 } // namespace KJS
 
diff --git a/JavaScriptCore/kjs/array_object.cpp b/JavaScriptCore/kjs/array_object.cpp
index 26b877d..99b619b 100644
--- a/JavaScriptCore/kjs/array_object.cpp
+++ b/JavaScriptCore/kjs/array_object.cpp
@@ -674,7 +674,7 @@
         JSValue* e = getProperty(exec, thisObj, index);
         if (!e)
             continue;
-        if (strictEqual(exec, searchElement, e))
+        if (strictEqual(searchElement, e))
             return jsNumber(index);
     }
 
@@ -703,7 +703,7 @@
         JSValue* e = getProperty(exec, thisObj, index);
         if (!e)
             continue;
-        if (strictEqual(exec, searchElement, e))
+        if (strictEqual(searchElement, e))
             return jsNumber(index);
     }
 
@@ -722,9 +722,9 @@
     putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly|DontDelete|DontEnum);
 }
 
-bool ArrayObjectImp::implementsConstruct() const
+ConstructType ArrayObjectImp::getConstructData(ConstructData&)
 {
-    return true;
+    return ConstructTypeNative;
 }
 
 // ECMA 15.4.2
diff --git a/JavaScriptCore/kjs/array_object.h b/JavaScriptCore/kjs/array_object.h
index e109c470..965de82 100644
--- a/JavaScriptCore/kjs/array_object.h
+++ b/JavaScriptCore/kjs/array_object.h
@@ -40,8 +40,9 @@
   public:
     ArrayObjectImp(ExecState*, FunctionPrototype*, ArrayPrototype*);
 
-    virtual bool implementsConstruct() const;
+    virtual ConstructType getConstructData(ConstructData&);
     virtual JSObject* construct(ExecState*, const List&);
+
     virtual JSValue* callAsFunction(ExecState*, JSObject*, const List&);
 
   };
diff --git a/JavaScriptCore/kjs/bool_object.cpp b/JavaScriptCore/kjs/bool_object.cpp
index 2d770ee..ba694bb 100644
--- a/JavaScriptCore/kjs/bool_object.cpp
+++ b/JavaScriptCore/kjs/bool_object.cpp
@@ -93,9 +93,9 @@
     putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly | DontDelete | DontEnum);
 }
 
-bool BooleanObjectImp::implementsConstruct() const
+ConstructType BooleanObjectImp::getConstructData(ConstructData&)
 {
-    return true;
+    return ConstructTypeNative;
 }
 
 // ECMA 15.6.2
diff --git a/JavaScriptCore/kjs/bool_object.h b/JavaScriptCore/kjs/bool_object.h
index c3d5a9f..51c2ac4 100644
--- a/JavaScriptCore/kjs/bool_object.h
+++ b/JavaScriptCore/kjs/bool_object.h
@@ -54,7 +54,7 @@
     public:
         BooleanObjectImp(ExecState*, FunctionPrototype*, BooleanPrototype*);
 
-        virtual bool implementsConstruct() const;
+        virtual ConstructType getConstructData(ConstructData&);
         virtual JSObject* construct(ExecState*, const List&);
 
         virtual JSValue* callAsFunction(ExecState*, JSObject*, const List&);
diff --git a/JavaScriptCore/kjs/collector.cpp b/JavaScriptCore/kjs/collector.cpp
index 41a0c27..acab28d 100644
--- a/JavaScriptCore/kjs/collector.cpp
+++ b/JavaScriptCore/kjs/collector.cpp
@@ -291,16 +291,17 @@
 
   return newCell;
 }
-
-void* Collector::allocate(size_t s) 
+#if !PLATFORM(MAC)
+void* Collector::allocate(size_t s)
 {
     return heapAllocate<PrimaryHeap>(s);
 }
 
-void* Collector::allocateNumber(size_t s) 
+void* Collector::allocateNumber(size_t s)
 {
     return heapAllocate<NumberHeap>(s);
 }
+#endif
 
 static inline void* currentThreadStackBase()
 {
@@ -1051,18 +1052,4 @@
     return (primaryHeap.operationInProgress != NoOperation) | (numberHeap.operationInProgress != NoOperation);
 }
 
-void Collector::reportOutOfMemoryToAllExecStates()
-{
-    if (!JSGlobalObject::head())
-        return;
-
-    JSGlobalObject* globalObject = JSGlobalObject::head();
-    do {
-        ExecStateStack::const_iterator end = globalObject->activeExecStates().end();
-        for (ExecStateStack::const_iterator it = globalObject->activeExecStates().begin(); it != end; ++it)
-            (*it)->setException(Error::create(*it, GeneralError, "Out of memory"));
-        globalObject = globalObject->next();
-    } while (globalObject != JSGlobalObject::head());
-}
-
 } // namespace KJS
diff --git a/JavaScriptCore/kjs/collector.h b/JavaScriptCore/kjs/collector.h
index 70db6b5..5aa0576 100644
--- a/JavaScriptCore/kjs/collector.h
+++ b/JavaScriptCore/kjs/collector.h
@@ -35,8 +35,21 @@
 
   class Collector {
   public:
+    class Thread;
+    enum HeapType { PrimaryHeap, NumberHeap };
+
+#if PLATFORM(MAC)
+    // We can inline these functions on Mac because everything is compiled as
+    // one file, so the heapAllocate template definitions are available.
+    // FIXME: This should be enabled for all platforms using AllInOneFile.cpp
+    static void* allocate(size_t s) { return heapAllocate<PrimaryHeap>(s); }
+    static void* allocateNumber(size_t s) { return heapAllocate<NumberHeap>(s); }
+#else
     static void* allocate(size_t s);
+
     static void* allocateNumber(size_t s);
+#endif
+
     static bool collect();
     static bool isBusy(); // true if an allocation or collection is in progress
 
@@ -56,7 +69,6 @@
     static size_t protectedGlobalObjectCount();
     static HashCountedSet<const char*>* protectedObjectTypeCounts();
 
-    class Thread;
     static void registerThread();
     
     static void registerAsMainThread();
@@ -64,7 +76,7 @@
     static bool isCellMarked(const JSCell*);
     static void markCell(JSCell*);
 
-    enum HeapType { PrimaryHeap, NumberHeap };
+    static void markStackObjectsConservatively(void* start, void* end);
 
   private:
     template <Collector::HeapType heapType> static void* heapAllocate(size_t s);
@@ -82,11 +94,9 @@
     static void markCurrentThreadConservativelyInternal();
     static void markOtherThreadConservatively(Thread*);
     static void markStackObjectsConservatively();
-    static void markStackObjectsConservatively(void* start, void* end);
 
     static size_t mainThreadOnlyObjectCount;
     static bool memoryFull;
-    static void reportOutOfMemoryToAllExecStates();
   };
 
   // tunable parameters
diff --git a/JavaScriptCore/kjs/date_object.cpp b/JavaScriptCore/kjs/date_object.cpp
index 5c0ac17..0b079c2 100644
--- a/JavaScriptCore/kjs/date_object.cpp
+++ b/JavaScriptCore/kjs/date_object.cpp
@@ -495,9 +495,9 @@
   putDirect(exec->propertyNames().length, 7, ReadOnly|DontDelete|DontEnum);
 }
 
-bool DateObjectImp::implementsConstruct() const
+ConstructType DateObjectImp::getConstructData(ConstructData&)
 {
-    return true;
+    return ConstructTypeNative;
 }
 
 // ECMA 15.9.3
diff --git a/JavaScriptCore/kjs/date_object.h b/JavaScriptCore/kjs/date_object.h
index d78d308..03dc655 100644
--- a/JavaScriptCore/kjs/date_object.h
+++ b/JavaScriptCore/kjs/date_object.h
@@ -127,13 +127,14 @@
      */
     class DateObjectImp : public InternalFunctionImp {
     public:
-        DateObjectImp(ExecState *, FunctionPrototype *, DatePrototype *);
+        DateObjectImp(ExecState*, FunctionPrototype*, DatePrototype*);
 
-        virtual bool implementsConstruct() const;
-        virtual JSObject *construct(ExecState *, const List &args);
-        virtual JSValue *callAsFunction(ExecState *, JSObject *thisObj, const List &args);
+        virtual ConstructType getConstructData(ConstructData&);
+        virtual JSObject* construct(ExecState*, const List& args);
 
-        JSObject *construct(const List &);
+        virtual JSValue* callAsFunction(ExecState*, JSObject* thisObj, const List& args);
+
+        JSObject* construct(const List&);
     };
 
 } // namespace
diff --git a/JavaScriptCore/kjs/debugger.cpp b/JavaScriptCore/kjs/debugger.cpp
index af9c5fa..4d28630 100644
--- a/JavaScriptCore/kjs/debugger.cpp
+++ b/JavaScriptCore/kjs/debugger.cpp
@@ -1,6 +1,6 @@
 // -*- c-basic-offset: 2 -*-
 /*
- *  This file is part of the KDE libraries
+ *  Copyright (C) 2008 Apple Inc. All rights reserved.
  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
  *
@@ -24,111 +24,32 @@
 #include "debugger.h"
 
 #include "JSGlobalObject.h"
-#include "internal.h"
-#include "ustring.h"
-
-using namespace KJS;
-
-// ------------------------------ Debugger -------------------------------------
 
 namespace KJS {
-  struct AttachedGlobalObject
-  {
-  public:
-    AttachedGlobalObject(JSGlobalObject* o, AttachedGlobalObject* ai) : globalObj(o), next(ai) { ++Debugger::debuggersPresent; }
-    ~AttachedGlobalObject() { --Debugger::debuggersPresent; }
-    JSGlobalObject* globalObj;
-    AttachedGlobalObject* next;
-  };
-
-}
-
-int Debugger::debuggersPresent = 0;
 
 Debugger::Debugger()
 {
-  rep = new DebuggerImp();
 }
 
 Debugger::~Debugger()
 {
-  detach(0);
-  delete rep;
+    HashSet<JSGlobalObject*>::iterator end = m_globalObjects.end();
+    for (HashSet<JSGlobalObject*>::iterator it = m_globalObjects.begin(); it != end; ++it)
+        (*it)->setDebugger(0);
 }
 
 void Debugger::attach(JSGlobalObject* globalObject)
 {
-  Debugger* other = globalObject->debugger();
-  if (other == this)
-    return;
-  if (other)
-    other->detach(globalObject);
-  globalObject->setDebugger(this);
-  rep->globalObjects = new AttachedGlobalObject(globalObject, rep->globalObjects);
+    ASSERT(!globalObject->debugger());
+    globalObject->setDebugger(this);
+    m_globalObjects.add(globalObject);
 }
 
-void Debugger::detach(JSGlobalObject* globalObj)
+void Debugger::detach(JSGlobalObject* globalObject)
 {
-  // iterate the addresses where AttachedGlobalObject pointers are stored
-  // so we can unlink items from the list
-  AttachedGlobalObject **p = &rep->globalObjects;
-  AttachedGlobalObject *q;
-  while ((q = *p)) {
-    if (!globalObj || q->globalObj == globalObj) {
-      *p = q->next;
-      q->globalObj->setDebugger(0);
-      delete q;
-    } else
-      p = &q->next;
-  }
-
-  if (globalObj)
-    latestExceptions.remove(globalObj);
-  else
-    latestExceptions.clear();
+    ASSERT(m_globalObjects.contains(globalObject));
+    m_globalObjects.remove(globalObject);
+    globalObject->setDebugger(0);
 }
 
-bool Debugger::hasHandledException(ExecState *exec, JSValue *exception)
-{
-    if (latestExceptions.get(exec->dynamicGlobalObject()).get() == exception)
-        return true;
-
-    latestExceptions.set(exec->dynamicGlobalObject(), exception);
-    return false;
-}
-
-bool Debugger::sourceParsed(ExecState*, int /*sourceId*/, const UString &/*sourceURL*/, 
-                           const UString &/*source*/, int /*startingLineNumber*/, int /*errorLine*/, const UString & /*errorMsg*/)
-{
-  return true;
-}
-
-bool Debugger::sourceUnused(ExecState*, int /*sourceId*/)
-{
-  return true;
-}
-
-bool Debugger::exception(ExecState*, int /*sourceId*/, int /*lineno*/,
-                         JSValue* /*exception */)
-{
-  return true;
-}
-
-bool Debugger::atStatement(ExecState*, int /*sourceId*/, int /*firstLine*/,
-                           int /*lastLine*/)
-{
-  return true;
-}
-
-bool Debugger::callEvent(ExecState*, int /*sourceId*/, int /*lineno*/,
-                         JSObject* /*function*/, const List &/*args*/)
-{
-  return true;
-}
-
-bool Debugger::returnEvent(ExecState*, int /*sourceId*/, int /*lineno*/,
-                           JSObject* /*function*/)
-{
-  return true;
-}
-
+} // namespace KJS
diff --git a/JavaScriptCore/kjs/debugger.h b/JavaScriptCore/kjs/debugger.h
index 2d5cb6f..f417177 100644
--- a/JavaScriptCore/kjs/debugger.h
+++ b/JavaScriptCore/kjs/debugger.h
@@ -20,34 +20,29 @@
  *
  */
 
-#ifndef _KJSDEBUGGER_H_
-#define _KJSDEBUGGER_H_
+#ifndef Debugger_h
+#define Debugger_h
 
-#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
 #include "protect.h"
 
 namespace KJS {
 
-  class DebuggerImp;
+  class DebuggerCallFrame;
   class ExecState;
   class JSGlobalObject;
   class JSObject;
   class JSValue;
-  class UString;
   class List;
-
+  class SourceProvider;
+  class UString;
+  
   /**
    * @internal
    *
    * Provides an interface which receives notification about various
    * script-execution related events such as statement execution and function
    * calls.
-   *
-   * WARNING: This interface is still a work in progress and is not yet
-   * offically publicly available. It is likely to change in binary incompatible
-   * (and possibly source incompatible) ways in future versions. It is
-   * anticipated that at some stage the interface will be frozen and made
-   * available for general use.
    */
   class Debugger {
   public:
@@ -63,8 +58,6 @@
      */
     virtual ~Debugger();
 
-    DebuggerImp *imp() const { return rep; }
-
     /**
      * Attaches the debugger to specified global object. This will cause this
      * object to receive notification of events during execution.
@@ -76,18 +69,13 @@
      * original debugger to be detached.
      *
      * @param The global object to attach to.
-     *
-     * @see detach()
      */
     void attach(JSGlobalObject*);
 
     /**
      * Detach the debugger from a global object.
      *
-     * @param The global object to detach from. If 0, the debugger will be
-     * detached from all global objects to which it is attached.
-     *
-     * @see attach()
+     * @param The global object to detach from.
      */
     void detach(JSGlobalObject*);
 
@@ -111,27 +99,9 @@
      * error, or -1 if the source code was valid and parsed successfully
      * @param errorMsg The error description, or null if the source code
        was valid and parsed successfully
-     * @return true if execution should be continue, false if it should
-     * be aborted
      */
-    virtual bool sourceParsed(ExecState *exec, int sourceId, const UString &sourceURL,
-                              const UString &source, int startingLineNumber, int errorLine, const UString &errorMsg);
-
-    /**
-     * Called when all functions/programs associated with a particular
-     * sourceId have been deleted. After this function has been called for
-     * a particular sourceId, that sourceId will not be used again.
-     *
-     * The default implementation does nothing. Override this method if
-     * you want to process this event.
-     *
-     * @param exec The current execution state
-     * @param sourceId The ID of the source code (corresponds to the
-     * sourceId supplied in other functions such as atLine()
-     * @return true if execution should be continue, false if it should
-     * be aborted
-     */
-    virtual bool sourceUnused(ExecState *exec, int sourceId);
+    virtual void sourceParsed(ExecState*, int sourceId, const UString& sourceURL,
+                              const SourceProvider& source, int startingLineNumber, int errorLine, const UString& errorMsg) = 0;
 
     /**
      * Called when an exception is thrown during script execution.
@@ -143,13 +113,8 @@
      * @param sourceId The ID of the source code being executed
      * @param lineno The line at which the error occurred
      * @param exceptionObj The exception object
-     * @return true if execution should be continue, false if it should
-     * be aborted
      */
-    virtual bool exception(ExecState *exec, int sourceId, int lineno,
-                           JSValue *exception);
-
-    bool hasHandledException(ExecState *, JSValue *);
+    virtual void exception(const DebuggerCallFrame&, int sourceId, int lineno) = 0;
 
     /**
      * Called when a line of the script is reached (before it is executed)
@@ -163,11 +128,8 @@
      * executed
      * @param lastLine The ending line of the statement  that is about to be
      * executed (usually the same as firstLine)
-     * @return true if execution should be continue, false if it should
-     * be aborted
      */
-    virtual bool atStatement(ExecState *exec, int sourceId, int firstLine,
-                             int lastLine);
+    virtual void atStatement(const DebuggerCallFrame&, int sourceId, int lineno) = 0;
     /**
      * Called on each function call. Use together with @ref #returnEvent
      * if you want to keep track of the call stack.
@@ -182,14 +144,8 @@
      * @param exec The current execution state
      * @param sourceId The ID of the source code being executed
      * @param lineno The line that is about to be executed
-     * @param function The function being called
-     * @param args The arguments that were passed to the function
-     * line is being executed
-     * @return true if execution should be continue, false if it should
-     * be aborted
      */
-    virtual bool callEvent(ExecState *exec, int sourceId, int lineno,
-                           JSObject *function, const List &args);
+    virtual void callEvent(const DebuggerCallFrame&, int sourceId, int lineno) = 0;
 
     /**
      * Called on each function exit. The function being returned from is that
@@ -205,21 +161,13 @@
      * @param exec The current execution state
      * @param sourceId The ID of the source code being executed
      * @param lineno The line that is about to be executed
-     * @param function The function being called
-     * @return true if execution should be continue, false if it should
-     * be aborted
      */
-    virtual bool returnEvent(ExecState *exec, int sourceId, int lineno,
-                             JSObject *function);
+    virtual void returnEvent(const DebuggerCallFrame&, int sourceId, int lineno) = 0;
 
   private:
-    DebuggerImp *rep;
-    HashMap<JSGlobalObject*, ProtectedPtr<JSValue> > latestExceptions;
-
-  public:
-    static int debuggersPresent;
+    HashSet<JSGlobalObject*> m_globalObjects;
   };
 
-}
+} // namespace KJS
 
 #endif
diff --git a/JavaScriptCore/kjs/error_object.cpp b/JavaScriptCore/kjs/error_object.cpp
index ac773b6..73c9026 100644
--- a/JavaScriptCore/kjs/error_object.cpp
+++ b/JavaScriptCore/kjs/error_object.cpp
@@ -78,9 +78,9 @@
     putDirect(exec->propertyNames().length, jsNumber(1), DontDelete|ReadOnly|DontEnum);
 }
 
-bool ErrorObjectImp::implementsConstruct() const
+ConstructType ErrorObjectImp::getConstructData(ConstructData&)
 {
-    return true;
+    return ConstructTypeNative;
 }
 
 // ECMA 15.9.3
@@ -124,9 +124,9 @@
     putDirect(exec->propertyNames().prototype, proto, DontDelete|ReadOnly|DontEnum);
 }
 
-bool NativeErrorImp::implementsConstruct() const
+ConstructType NativeErrorImp::getConstructData(ConstructData&)
 {
-    return true;
+    return ConstructTypeNative;
 }
 
 JSObject* NativeErrorImp::construct(ExecState* exec, const List& args)
diff --git a/JavaScriptCore/kjs/error_object.h b/JavaScriptCore/kjs/error_object.h
index 9734085..57d607c 100644
--- a/JavaScriptCore/kjs/error_object.h
+++ b/JavaScriptCore/kjs/error_object.h
@@ -44,7 +44,7 @@
     public:
         ErrorObjectImp(ExecState*, FunctionPrototype*, ErrorPrototype*);
 
-        virtual bool implementsConstruct() const;
+        virtual ConstructType getConstructData(ConstructData&);
         virtual JSObject* construct(ExecState*, const List&);
 
         virtual JSValue* callAsFunction(ExecState*, JSObject*, const List&);
@@ -59,8 +59,9 @@
     public:
         NativeErrorImp(ExecState*, FunctionPrototype*, NativeErrorPrototype*);
 
-        virtual bool implementsConstruct() const;
+        virtual ConstructType getConstructData(ConstructData&);
         virtual JSObject* construct(ExecState*, const List&);
+
         virtual JSValue* callAsFunction(ExecState*, JSObject*, const List&);
 
         virtual void mark();
diff --git a/JavaScriptCore/kjs/function.cpp b/JavaScriptCore/kjs/function.cpp
index a536b58..8a970e4 100644
--- a/JavaScriptCore/kjs/function.cpp
+++ b/JavaScriptCore/kjs/function.cpp
@@ -26,9 +26,10 @@
 #include "config.h"
 #include "function.h"
 
-#include "Activation.h"
 #include "ExecState.h"
+#include "JSActivation.h"
 #include "JSGlobalObject.h"
+#include "Machine.h"
 #include "Parser.h"
 #include "PropertyNameArray.h"
 #include "debugger.h"
@@ -39,7 +40,6 @@
 #include "nodes.h"
 #include "operations.h"
 #include "scope_chain_mark.h"
-#include "ExecStateInlines.h"
 #include <errno.h>
 #include <profiler/Profiler.h>
 #include <stdio.h>
@@ -59,67 +59,58 @@
 
 const ClassInfo FunctionImp::info = { "Function", &InternalFunctionImp::info, 0, 0 };
 
-FunctionImp::FunctionImp(ExecState* exec, const Identifier& name, FunctionBodyNode* b, const ScopeChain& sc)
+FunctionImp::FunctionImp(ExecState* exec, const Identifier& name, FunctionBodyNode* b, ScopeChainNode* scopeChain)
   : InternalFunctionImp(exec->lexicalGlobalObject()->functionPrototype(), name)
   , body(b)
-  , _scope(sc)
+  , _scope(scopeChain)
 {
 }
 
 void FunctionImp::mark()
 {
     InternalFunctionImp::mark();
+    body->mark();
     _scope.mark();
 }
 
+CallType FunctionImp::getCallData(CallData& callData)
+{
+    callData.js.functionBody = body.get();
+    callData.js.scopeChain = _scope.node();
+    return CallTypeJS;
+}
+
 JSValue* FunctionImp::callAsFunction(ExecState* exec, JSObject* thisObj, const List& args)
 {
-    FunctionExecState newExec(exec->dynamicGlobalObject(), thisObj, exec->globalThisValue(), body.get(), exec, this, args);
-    JSValue* result = body->execute(&newExec);
-    if (newExec.completionType() == ReturnValue)
+    JSValue* exception = 0;
+    RegisterFileStack* stack = &exec->dynamicGlobalObject()->registerFileStack();
+    RegisterFile* current = stack->current();
+    if (!current->safeForReentry()) {
+        stack->pushFunctionRegisterFile();
+        JSValue* result = machine().execute(body.get(), exec, this, thisObj, args, stack, _scope.node(), &exception);
+        stack->popFunctionRegisterFile();
+        exec->setException(exception);
         return result;
-    if (newExec.completionType() == Throw) {
-        exec->setException(result);
+    } else {
+        JSValue* result = machine().execute(body.get(), exec, this, thisObj, args, stack, _scope.node(), &exception);
+        current->setSafeForReentry(true);
+        exec->setException(exception);
         return result;
     }
-    return jsUndefined();
 }
 
-JSValue* FunctionImp::argumentsGetter(ExecState* exec, JSObject*, const Identifier& propertyName, const PropertySlot& slot)
+JSValue* FunctionImp::argumentsGetter(ExecState* exec, JSObject*, const Identifier&, const PropertySlot& slot)
 {
-  FunctionImp* thisObj = static_cast<FunctionImp*>(slot.slotBase());
-  
-  for (ExecState* e = exec; e; e = e->callingExecState())
-    if (e->function() == thisObj) {
-      e->dynamicGlobalObject()->tearOffActivation(e, e != exec);
-      return e->activationObject()->get(exec, propertyName);
-    }
-  
-  return jsNull();
+    FunctionImp* thisObj = static_cast<FunctionImp*>(slot.slotBase());
+    ASSERT(exec->machine());
+    return exec->machine()->retrieveArguments(exec, thisObj);
 }
 
 JSValue* FunctionImp::callerGetter(ExecState* exec, JSObject*, const Identifier&, const PropertySlot& slot)
 {
     FunctionImp* thisObj = static_cast<FunctionImp*>(slot.slotBase());
-    ExecState* e = exec;
-    while (e) {
-        if (e->function() == thisObj)
-            break;
-        e = e->callingExecState();
-    }
-
-    if (!e)
-        return jsNull();
-    
-    ExecState* callingExecState = e->callingExecState();
-    if (!callingExecState)
-        return jsNull();
-    
-    FunctionImp* callingFunction = callingExecState->function();
-    if (!callingFunction)
-        return jsNull();
-
-    return callingFunction;
+    ASSERT(exec->machine());
+    return exec->machine()->retrieveCaller(exec, thisObj);
 }
 
 JSValue* FunctionImp::lengthGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot)
@@ -130,13 +121,11 @@
 
 bool FunctionImp::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
 {
-    // Find the arguments from the closest context.
     if (propertyName == exec->propertyNames().arguments) {
         slot.setCustom(this, argumentsGetter);
         return true;
     }
 
-    // Compute length of parameters.
     if (propertyName == exec->propertyNames().length) {
         slot.setCustom(this, lengthGetter);
         return true;
@@ -190,23 +179,34 @@
 }
 
 // ECMA 13.2.2 [[Construct]]
+ConstructType FunctionImp::getConstructData(ConstructData& constructData)
+{
+    constructData.js.functionBody = body.get();
+    constructData.js.scopeChain = _scope.node();
+    return ConstructTypeJS;
+}
+
 JSObject* FunctionImp::construct(ExecState* exec, const List& args)
 {
-  JSObject* proto;
-  JSValue* p = get(exec, exec->propertyNames().prototype);
-  if (p->isObject())
-    proto = static_cast<JSObject*>(p);
-  else
-    proto = exec->lexicalGlobalObject()->objectPrototype();
+    JSObject* proto;
+    JSValue* p = get(exec, exec->propertyNames().prototype);
+    if (p->isObject())
+        proto = static_cast<JSObject*>(p);
+    else
+        proto = exec->lexicalGlobalObject()->objectPrototype();
 
-  JSObject* obj(new JSObject(proto));
+    JSObject* thisObj = new JSObject(proto);
 
-  JSValue* res = call(exec,obj,args);
+    JSValue* exception = 0;
+    JSValue* result = machine().execute(body.get(), exec, this, thisObj, args, &exec->dynamicGlobalObject()->registerFileStack(), _scope.node(), &exception);
+    if (exception) {
+        exec->setException(exception);
+        return thisObj;
+    }
 
-  if (res->isObject())
-    return static_cast<JSObject*>(res);
-  else
-    return obj;
+    if (result->isObject())
+        return static_cast<JSObject*>(result);
+    return thisObj;
 }
 
 // ------------------------------ IndexToNameMap ---------------------------------
@@ -278,7 +278,7 @@
 const ClassInfo Arguments::info = { "Arguments", 0, 0, 0 };
 
 // ECMA 10.1.8
-Arguments::Arguments(ExecState* exec, FunctionImp* func, const List& args, ActivationImp* act)
+Arguments::Arguments(ExecState* exec, FunctionImp* func, const List& args, JSActivation* act)
     : JSObject(exec->lexicalGlobalObject()->objectPrototype())
     , _activationObject(act)
     , indexToNameMap(func, args)
@@ -336,152 +336,6 @@
   }
 }
 
-// ------------------------------ ActivationImp --------------------------------
-
-const ClassInfo ActivationImp::info = { "Activation", 0, 0, 0 };
-
-ActivationImp::ActivationImp(const ActivationData& oldData, bool leaveRelic)
-{
-    JSVariableObject::d = new ActivationData(oldData);
-    d()->leftRelic = leaveRelic;
-}
-
-ActivationImp::~ActivationImp()
-{
-    if (!d()->isOnStack)
-        delete d();
-}
-
-JSValue* ActivationImp::argumentsGetter(ExecState* exec, JSObject*, const Identifier&, const PropertySlot& slot)
-{
-  ActivationImp* thisObj = static_cast<ActivationImp*>(slot.slotBase());
-  
-  if (!thisObj->d()->argumentsObject)
-    thisObj->createArgumentsObject(exec);
-  
-  return thisObj->d()->argumentsObject;
-}
-
-PropertySlot::GetValueFunc ActivationImp::getArgumentsGetter()
-{
-  return ActivationImp::argumentsGetter;
-}
-
-bool ActivationImp::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
-{
-    if (symbolTableGet(propertyName, slot))
-        return true;
-
-    if (JSValue** location = getDirectLocation(propertyName)) {
-        slot.setValueSlot(this, location);
-        return true;
-    }
-
-    // Only return the built-in arguments object if it wasn't overridden above.
-    if (propertyName == exec->propertyNames().arguments) {
-        for (ExecState* e = exec; e; e = e->callingExecState())
-            if (e->function() == d()->function) {
-                e->dynamicGlobalObject()->tearOffActivation(e, e != exec);
-                ActivationImp* newActivation = e->activationObject();
-                slot.setCustom(newActivation, newActivation->getArgumentsGetter());
-                return true;
-            }
-        
-        slot.setCustom(this, getArgumentsGetter());
-        return true;
-    }
-
-    // We don't call through to JSObject because there's no way to give an 
-    // activation object getter properties or a prototype.
-    ASSERT(!_prop.hasGetterSetterProperties());
-    ASSERT(prototype() == jsNull());
-    return false;
-}
-
-bool ActivationImp::deleteProperty(ExecState* exec, const Identifier& propertyName)
-{
-    if (propertyName == exec->propertyNames().arguments)
-        return false;
-
-    return JSVariableObject::deleteProperty(exec, propertyName);
-}
-
-void ActivationImp::put(ExecState*, const Identifier& propertyName, JSValue* value)
-{
-    if (symbolTablePut(propertyName, value))
-        return;
-
-    // We don't call through to JSObject because __proto__ and getter/setter 
-    // properties are non-standard extensions that other implementations do not
-    // expose in the activation object.
-    ASSERT(!_prop.hasGetterSetterProperties());
-    _prop.put(propertyName, value, 0, true);
-}
-
-void ActivationImp::putWithAttributes(ExecState*, const Identifier& propertyName, JSValue* value, unsigned attributes)
-{
-    if (symbolTablePutWithAttributes(propertyName, value, attributes))
-        return;
-
-    // We don't call through to JSObject because __proto__ and getter/setter 
-    // properties are non-standard extensions that other implementations do not
-    // expose in the activation object.
-    ASSERT(!_prop.hasGetterSetterProperties());
-    _prop.put(propertyName, value, attributes, true);
-}
-
-void ActivationImp::markChildren()
-{
-    LocalStorage& localStorage = d()->localStorage;
-    size_t size = localStorage.size();
-    
-    for (size_t i = 0; i < size; ++i) {
-        JSValue* value = localStorage[i].value;
-        
-        if (!value->marked())
-            value->mark();
-    }
-    
-    if (!d()->function->marked())
-        d()->function->mark();
-    
-    if (d()->argumentsObject && !d()->argumentsObject->marked())
-        d()->argumentsObject->mark();    
-}
-
-void ActivationImp::mark()
-{
-    JSObject::mark();
-    markChildren();
-}
-
-void ActivationImp::createArgumentsObject(ExecState* exec)
-{
-    // Since "arguments" is only accessible while a function is being called,
-    // we can retrieve our argument list from the ExecState for our function 
-    // call instead of storing the list ourselves.
-    d()->argumentsObject = new Arguments(exec, d()->exec->function(), *d()->exec->arguments(), this);
-}
-
-JSObject* ActivationImp::toThisObject(ExecState* exec) const
-{
-    return exec->globalThisValue();
-}
-
-ActivationImp::ActivationData::ActivationData(const ActivationData& old)
-    : JSVariableObjectData(old)
-    , exec(old.exec)
-    , function(old.function)
-    , argumentsObject(old.argumentsObject)
-    , isOnStack(false)
-{
-}
-
-bool ActivationImp::isDynamicScope() const
-{
-    return d()->function->body->usesEval();
-}
-
 // ------------------------------ Global Functions -----------------------------------
 
 static JSValue* encode(ExecState* exec, const List& args, const char* do_not_escape)
@@ -703,14 +557,19 @@
     return s.toDouble( true /*tolerant*/, false /* NaN for empty string */ );
 }
 
-JSValue* eval(ExecState* exec, const ScopeChain& scopeChain, JSVariableObject* variableObject, JSGlobalObject* globalObject, JSObject* thisObj, const List& args)
+JSValue* globalFuncEval(ExecState* exec, PrototypeReflexiveFunction* function, JSObject* thisObj, const List& args)
 {
+    JSGlobalObject* globalObject = thisObj->toGlobalObject(exec);
+
+    if (!globalObject || globalObject->evalFunction() != function)
+        return throwError(exec, EvalError, "The \"this\" value passed to eval must be the global object from which eval originated");
+
     JSValue* x = args[0];
     if (!x->isString())
         return x;
-
+    
     UString s = x->toString(exec);
-
+    
     int sourceId;
     int errLine;
     UString errMsg;
@@ -719,45 +578,26 @@
     Profiler::profiler()->willExecute(exec, UString(), 0);
 #endif
 
-    RefPtr<EvalNode> evalNode = parser().parse<EvalNode>(UString(), 0, s.data(), s.size(), &sourceId, &errLine, &errMsg);
-
-    Debugger* dbg = exec->dynamicGlobalObject()->debugger();
-    if (dbg) {
-        bool cont = dbg->sourceParsed(exec, sourceId, UString(), s, 0, errLine, errMsg);
-        if (!cont)
-            return jsUndefined();
-    }
-
+    RefPtr<EvalNode> evalNode = parser().parse<EvalNode>(exec, UString(), 0, UStringSourceProvider::create(s), &sourceId, &errLine, &errMsg);
+    
     if (!evalNode)
         return throwError(exec, SyntaxError, errMsg, errLine, sourceId, NULL);
 
-    EvalExecState newExec(globalObject, thisObj, evalNode.get(), exec, scopeChain, variableObject);
-
-    JSValue* value = evalNode->execute(&newExec);
+    JSValue* exception = 0;
+    JSValue* value = machine().execute(evalNode.get(), exec, thisObj, &exec->dynamicGlobalObject()->registerFileStack(), globalObject->globalScopeChain().node(), &exception);
 
 #if JAVASCRIPT_PROFILING
     Profiler::profiler()->didExecute(exec, UString(), 0);
 #endif
 
-    if (newExec.completionType() == Throw) {
-        exec->setException(value);
+    if (exception) {
+        exec->setException(exception);
         return value;
     }
-
+    
     return value ? value : jsUndefined();
 }
 
-JSValue* globalFuncEval(ExecState* exec, PrototypeReflexiveFunction* function, JSObject* thisObj, const List& args)
-{
-    JSGlobalObject* globalObject = thisObj->toGlobalObject(exec);
-
-    if (!globalObject || globalObject->evalFunction() != function)
-        return throwError(exec, EvalError, "The \"this\" value passed to eval must be the global object from which eval originated");
-
-    ScopeChain scopeChain(globalObject);
-    return eval(exec, scopeChain, globalObject, globalObject, function->cachedGlobalObject()->toThisObject(exec), args);
-}
-
 JSValue* globalFuncParseInt(ExecState* exec, JSObject*, const List& args)
 {
     return jsNumber(parseInt(args[0]->toString(exec), args[1]->toInt32(exec)));
diff --git a/JavaScriptCore/kjs/function.h b/JavaScriptCore/kjs/function.h
index 7bf71d5..15dd059 100644
--- a/JavaScriptCore/kjs/function.h
+++ b/JavaScriptCore/kjs/function.h
@@ -26,16 +26,15 @@
 #define KJS_FUNCTION_H
 
 #include "JSVariableObject.h"
-#include "LocalStorageEntry.h"
 #include "SymbolTable.h"
 #include "nodes.h"
 #include "object.h"
 
 namespace KJS {
 
-  class ActivationImp;
   class FunctionBodyNode;
   class FunctionPrototype;
+  class JSActivation;
   class JSGlobalObject;
 
   class InternalFunctionImp : public JSObject {
@@ -43,7 +42,8 @@
     InternalFunctionImp();
     InternalFunctionImp(FunctionPrototype*, const Identifier&);
 
-    virtual bool implementsCall() const;
+    virtual CallType getCallData(CallData&);
+
     virtual JSValue* callAsFunction(ExecState*, JSObject* thisObjec, const List& args) = 0;
     virtual bool implementsHasInstance() const;
 
@@ -56,17 +56,17 @@
   };
 
   class FunctionImp : public InternalFunctionImp {
-    friend class ActivationImp;
   public:
-    FunctionImp(ExecState*, const Identifier& name, FunctionBodyNode*, const ScopeChain&);
+    FunctionImp(ExecState*, const Identifier&, FunctionBodyNode*, ScopeChainNode*);
 
     virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
     virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
     virtual bool deleteProperty(ExecState*, const Identifier& propertyName);
 
-    virtual bool implementsConstruct() const { return true; }
+    virtual ConstructType getConstructData(ConstructData&);
     virtual JSObject* construct(ExecState*, const List& args);
-    
+
+    virtual CallType getCallData(CallData&);
     virtual JSValue* callAsFunction(ExecState*, JSObject* thisObj, const List& args);
 
     // Note: unlike body->paramName, this returns Identifier::null for parameters 
@@ -79,7 +79,7 @@
     RefPtr<FunctionBodyNode> body;
 
     void setScope(const ScopeChain& s) { _scope = s; }
-    const ScopeChain& scope() const { return _scope; }
+    ScopeChain& scope() { return _scope; }
 
     virtual void mark();
 
@@ -107,7 +107,7 @@
   
   class Arguments : public JSObject {
   public:
-    Arguments(ExecState*, FunctionImp* func, const List& args, ActivationImp* act);
+    Arguments(ExecState*, FunctionImp* func, const List& args, JSActivation* act);
     virtual void mark();
     virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
     virtual void put(ExecState*, const Identifier& propertyName, JSValue*);
@@ -117,7 +117,7 @@
   private:
     static JSValue* mappedIndexGetter(ExecState*, JSObject*, const Identifier&, const PropertySlot& slot);
 
-    ActivationImp* _activationObject;
+    JSActivation* _activationObject;
     mutable IndexToNameMap indexToNameMap;
   };
 
@@ -168,8 +168,6 @@
     JSValue* globalFuncKJSPrint(ExecState*, JSObject*, const List&);
 #endif
 
-    JSValue* eval(ExecState*, const ScopeChain&, JSVariableObject*, JSGlobalObject*, JSObject* thisObj, const List& args);
-
     static const double mantissaOverflowLowerBound = 9007199254740992.0;
     double parseIntOverflow(const char*, int length, int radix);
 
diff --git a/JavaScriptCore/kjs/function_object.cpp b/JavaScriptCore/kjs/function_object.cpp
index c849b4d..dacbd43 100644
--- a/JavaScriptCore/kjs/function_object.cpp
+++ b/JavaScriptCore/kjs/function_object.cpp
@@ -70,7 +70,7 @@
 
     if (thisObj->inherits(&FunctionImp::info)) {
         FunctionImp* fi = static_cast<FunctionImp*>(thisObj);
-        return jsString("function " + fi->functionName().ustring() + "(" + fi->body->paramString() + ") " + fi->body->toString());
+        return jsString("function " + fi->functionName().ustring() + "(" + fi->body->paramString() + ") " + fi->body->toSourceString());
     }
 
     return jsString("function " + static_cast<InternalFunctionImp*>(thisObj)->functionName().ustring() + "() {\n    [native code]\n}");
@@ -136,9 +136,9 @@
     putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly | DontDelete | DontEnum);
 }
 
-bool FunctionObjectImp::implementsConstruct() const
+ConstructType FunctionObjectImp::getConstructData(ConstructData&)
 {
-    return true;
+    return ConstructTypeNative;
 }
 
 // ECMA 15.3.2 The Function Constructor
@@ -162,24 +162,19 @@
     int sourceId;
     int errLine;
     UString errMsg;
-    RefPtr<FunctionBodyNode> functionBody = parser().parse<FunctionBodyNode>(sourceURL, lineNumber, body.data(), body.size(), &sourceId, &errLine, &errMsg);
-
-    // notify debugger that source has been parsed
-    // send empty sourceURL to indicate constructed code
-    Debugger* dbg = exec->dynamicGlobalObject()->debugger();
-    if (dbg && !dbg->sourceParsed(exec, sourceId, UString(), body, lineNumber, errLine, errMsg))
-        return new JSObject();
+    RefPtr<SourceProvider> source = UStringSourceProvider::create(body);
+    RefPtr<FunctionBodyNode> functionBody = parser().parse<FunctionBodyNode>(exec, sourceURL, lineNumber, source, &sourceId, &errLine, &errMsg);
 
     // No program node == syntax error - throw a syntax error
     if (!functionBody)
         // We can't return a Completion(Throw) here, so just set the exception
         // and return it
         return throwError(exec, SyntaxError, errMsg, errLine, sourceId, sourceURL);
+    
+    functionBody->setSource(SourceRange(source, 0, source->length()));
+    ScopeChain scopeChain(exec->lexicalGlobalObject());
 
-    ScopeChain scopeChain;
-    scopeChain.push(exec->lexicalGlobalObject());
-
-    FunctionImp* fimp = new FunctionImp(exec, functionName, functionBody.get(), scopeChain);
+    FunctionImp* fimp = new FunctionImp(exec, functionName, functionBody.get(), scopeChain.node());
 
     // parse parameter list. throw syntax error on illegal identifiers
     int len = p.size();
@@ -212,8 +207,6 @@
         return throwError(exec, SyntaxError, "Syntax error in parameter list");
     }
   
-    List consArgs;
-
     JSObject* objCons = exec->lexicalGlobalObject()->objectConstructor();
     JSObject* prototype = objCons->construct(exec, exec->emptyList());
     prototype->putDirect(exec->propertyNames().constructor, fimp, DontEnum);
diff --git a/JavaScriptCore/kjs/function_object.h b/JavaScriptCore/kjs/function_object.h
index cd0fe3e..8531070 100644
--- a/JavaScriptCore/kjs/function_object.h
+++ b/JavaScriptCore/kjs/function_object.h
@@ -50,9 +50,10 @@
     public:
         FunctionObjectImp(ExecState*, FunctionPrototype*);
 
-        virtual bool implementsConstruct() const;
+        virtual ConstructType getConstructData(ConstructData&);
         virtual JSObject* construct(ExecState*, const List&);
         virtual JSObject* construct(ExecState*, const List&, const Identifier& functionName, const UString& sourceURL, int lineNumber);
+
         virtual JSValue* callAsFunction(ExecState*, JSObject*, const List&);
     };
 
diff --git a/JavaScriptCore/kjs/grammar.y b/JavaScriptCore/kjs/grammar.y
index f34806a..51bcc03 100644
--- a/JavaScriptCore/kjs/grammar.y
+++ b/JavaScriptCore/kjs/grammar.y
@@ -49,11 +49,13 @@
 #define YYERROR_VERBOSE
 #endif
 
+#define LEXER (static_cast<KJS::Lexer*>(lexer))
+
 int kjsyylex(void* lvalp, void* llocp, void* lexer);
 int kjsyyerror(const char*);
 static inline bool allowAutomaticSemicolon(KJS::Lexer&, int);
 
-#define AUTO_SEMICOLON do { if (!allowAutomaticSemicolon(*static_cast<KJS::Lexer*>(lexer), yychar)) YYABORT; } while (0)
+#define AUTO_SEMICOLON do { if (!allowAutomaticSemicolon(*LEXER, yychar)) YYABORT; } while (0)
 #define DBG(l, s, e) (l)->setLoc((s).first_line, (e).last_line)
 
 using namespace KJS;
@@ -61,10 +63,10 @@
 
 static AddNode* makeAddNode(ExpressionNode*, ExpressionNode*);
 static LessNode* makeLessNode(ExpressionNode*, ExpressionNode*);
-static ExpressionNode* makeAssignNode(ExpressionNode* loc, Operator, ExpressionNode* expr);
+static ExpressionNode* makeAssignNode(ExpressionNode* loc, Operator, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments);
 static ExpressionNode* makePrefixNode(ExpressionNode* expr, Operator);
 static ExpressionNode* makePostfixNode(ExpressionNode* expr, Operator);
-static PropertyNode* makeGetterOrSetterPropertyNode(const Identifier &getOrSet, const Identifier& name, ParameterNode*, FunctionBodyNode*);
+static PropertyNode* makeGetterOrSetterPropertyNode(const Identifier &getOrSet, const Identifier& name, ParameterNode*, FunctionBodyNode*, const SourceRange&);
 static ExpressionNodeInfo makeFunctionCallNode(ExpressionNodeInfo func, ArgumentsNodeInfo);
 static ExpressionNode* makeTypeOfNode(ExpressionNode*);
 static ExpressionNode* makeDeleteNode(ExpressionNode*);
@@ -95,14 +97,14 @@
                                                                        ParserRefCountedData<DeclarationStacks::FunctionStack>* funcDecls,
                                                                        FeatureInfo info) 
 {
-    ASSERT((info & ~(EvalFeature | ClosureFeature)) == 0);
+    ASSERT((info & ~(EvalFeature | ClosureFeature | AssignFeature)) == 0);
     NodeDeclarationInfo<T> result = {node, varDecls, funcDecls, info};
     return result;
 }
 
 template <typename T> NodeFeatureInfo<T> createNodeFeatureInfo(T node, FeatureInfo info) 
 {
-    ASSERT((info & ~(EvalFeature | ClosureFeature)) == 0);
+    ASSERT((info & ~(EvalFeature | ClosureFeature | AssignFeature)) == 0);
     NodeFeatureInfo<T> result = {node, info};
     return result;
 }
@@ -209,6 +211,8 @@
 %token RSHIFTEQUAL URSHIFTEQUAL    /* >>= and >>>= */
 %token ANDEQUAL MODEQUAL           /* &= and %= */
 %token XOREQUAL OREQUAL            /* ^= and |= */
+%token <intValue> OPENBRACE        /* { (with char offset) */
+%token <intValue> CLOSEBRACE        /* { (with char offset) */
 
 /* terminal types */
 %token <doubleValue> NUMBER
@@ -281,13 +285,13 @@
   | NUMBER                              { $$ = createNodeFeatureInfo<ExpressionNode*>(makeNumberNode($1), 0); }
   | STRING                              { $$ = createNodeFeatureInfo<ExpressionNode*>(new StringNode($1), 0); }
   | '/' /* regexp */                    {
-                                            Lexer& l = *static_cast<Lexer*>(lexer);
+                                            Lexer& l = *LEXER;
                                             if (!l.scanRegExp())
                                                 YYABORT;
                                             $$ = createNodeFeatureInfo<ExpressionNode*>(new RegExpNode(l.pattern(), l.flags()), 0);
                                         }
   | DIVEQUAL /* regexp with /= */       {
-                                            Lexer& l = *static_cast<Lexer*>(lexer);
+                                            Lexer& l = *LEXER;
                                             if (!l.scanRegExp())
                                                 YYABORT;
                                             $$ = createNodeFeatureInfo<ExpressionNode*>(new RegExpNode("=" + l.pattern(), l.flags()), 0);
@@ -298,9 +302,9 @@
     IDENT ':' AssignmentExpr            { $$ = createNodeFeatureInfo<PropertyNode*>(new PropertyNode(*$1, $3.m_node, PropertyNode::Constant), $3.m_featureInfo); }
   | STRING ':' AssignmentExpr           { $$ = createNodeFeatureInfo<PropertyNode*>(new PropertyNode(Identifier(*$1), $3.m_node, PropertyNode::Constant), $3.m_featureInfo); }
   | NUMBER ':' AssignmentExpr           { $$ = createNodeFeatureInfo<PropertyNode*>(new PropertyNode(Identifier(UString::from($1)), $3.m_node, PropertyNode::Constant), $3.m_featureInfo); }
-  | IDENT IDENT '(' ')' '{' FunctionBody '}'    { $$ = createNodeFeatureInfo<PropertyNode*>(makeGetterOrSetterPropertyNode(*$1, *$2, 0, $6), ClosureFeature); DBG($6, @5, @7); if (!$$.m_node) YYABORT; }
-  | IDENT IDENT '(' FormalParameterList ')' '{' FunctionBody '}'
-                                        { $$ = createNodeFeatureInfo<PropertyNode*>(makeGetterOrSetterPropertyNode(*$1, *$2, $4.head, $7), ClosureFeature); DBG($7, @6, @8); if (!$$.m_node) YYABORT; }
+  | IDENT IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE    { $$ = createNodeFeatureInfo<PropertyNode*>(makeGetterOrSetterPropertyNode(*$1, *$2, 0, $6, LEXER->sourceRange($5, $7)), ClosureFeature); DBG($6, @5, @7); if (!$$.m_node) YYABORT; }
+  | IDENT IDENT '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE
+                                        { $$ = createNodeFeatureInfo<PropertyNode*>(makeGetterOrSetterPropertyNode(*$1, *$2, $4.head, $7, LEXER->sourceRange($6, $8)), ClosureFeature); DBG($7, @6, @8); if (!$$.m_node) YYABORT; }
 ;
 
 PropertyList:
@@ -314,10 +318,10 @@
 
 PrimaryExpr:
     PrimaryExprNoBrace
-  | '{' '}'                             { $$ = createNodeFeatureInfo<ExpressionNode*>(new ObjectLiteralNode(), 0); }
-  | '{' PropertyList '}'                { $$ = createNodeFeatureInfo<ExpressionNode*>(new ObjectLiteralNode($2.m_node.head), $2.m_featureInfo); }
+  | OPENBRACE CLOSEBRACE                             { $$ = createNodeFeatureInfo<ExpressionNode*>(new ObjectLiteralNode(), 0); }
+  | OPENBRACE PropertyList CLOSEBRACE                { $$ = createNodeFeatureInfo<ExpressionNode*>(new ObjectLiteralNode($2.m_node.head), $2.m_featureInfo); }
   /* allow extra comma, see http://bugs.webkit.org/show_bug.cgi?id=5939 */
-  | '{' PropertyList ',' '}'            { $$ = createNodeFeatureInfo<ExpressionNode*>(new ObjectLiteralNode($2.m_node.head), $2.m_featureInfo); }
+  | OPENBRACE PropertyList ',' CLOSEBRACE            { $$ = createNodeFeatureInfo<ExpressionNode*>(new ObjectLiteralNode($2.m_node.head), $2.m_featureInfo); }
 ;
 
 PrimaryExprNoBrace:
@@ -419,24 +423,24 @@
 
 PostfixExpr:
     LeftHandSideExpr
-  | LeftHandSideExpr PLUSPLUS           { $$ = createNodeFeatureInfo<ExpressionNode*>(makePostfixNode($1.m_node, OpPlusPlus), $1.m_featureInfo); }
-  | LeftHandSideExpr MINUSMINUS         { $$ = createNodeFeatureInfo<ExpressionNode*>(makePostfixNode($1.m_node, OpMinusMinus), $1.m_featureInfo); }
+  | LeftHandSideExpr PLUSPLUS           { $$ = createNodeFeatureInfo<ExpressionNode*>(makePostfixNode($1.m_node, OpPlusPlus), $1.m_featureInfo | AssignFeature); }
+  | LeftHandSideExpr MINUSMINUS         { $$ = createNodeFeatureInfo<ExpressionNode*>(makePostfixNode($1.m_node, OpMinusMinus), $1.m_featureInfo | AssignFeature); }
 ;
 
 PostfixExprNoBF:
     LeftHandSideExprNoBF
-  | LeftHandSideExprNoBF PLUSPLUS       { $$ = createNodeFeatureInfo<ExpressionNode*>(makePostfixNode($1.m_node, OpPlusPlus), $1.m_featureInfo); }
-  | LeftHandSideExprNoBF MINUSMINUS     { $$ = createNodeFeatureInfo<ExpressionNode*>(makePostfixNode($1.m_node, OpMinusMinus), $1.m_featureInfo); }
+  | LeftHandSideExprNoBF PLUSPLUS       { $$ = createNodeFeatureInfo<ExpressionNode*>(makePostfixNode($1.m_node, OpPlusPlus), $1.m_featureInfo | AssignFeature); }
+  | LeftHandSideExprNoBF MINUSMINUS     { $$ = createNodeFeatureInfo<ExpressionNode*>(makePostfixNode($1.m_node, OpMinusMinus), $1.m_featureInfo | AssignFeature); }
 ;
 
 UnaryExprCommon:
     DELETETOKEN UnaryExpr               { $$ = createNodeFeatureInfo<ExpressionNode*>(makeDeleteNode($2.m_node), $2.m_featureInfo); }
   | VOIDTOKEN UnaryExpr                 { $$ = createNodeFeatureInfo<ExpressionNode*>(new VoidNode($2.m_node), $2.m_featureInfo); }
   | TYPEOF UnaryExpr                    { $$ = createNodeFeatureInfo<ExpressionNode*>(makeTypeOfNode($2.m_node), $2.m_featureInfo); }
-  | PLUSPLUS UnaryExpr                  { $$ = createNodeFeatureInfo<ExpressionNode*>(makePrefixNode($2.m_node, OpPlusPlus), $2.m_featureInfo); }
-  | AUTOPLUSPLUS UnaryExpr              { $$ = createNodeFeatureInfo<ExpressionNode*>(makePrefixNode($2.m_node, OpPlusPlus), $2.m_featureInfo); }
-  | MINUSMINUS UnaryExpr                { $$ = createNodeFeatureInfo<ExpressionNode*>(makePrefixNode($2.m_node, OpMinusMinus), $2.m_featureInfo); }
-  | AUTOMINUSMINUS UnaryExpr            { $$ = createNodeFeatureInfo<ExpressionNode*>(makePrefixNode($2.m_node, OpMinusMinus), $2.m_featureInfo); }
+  | PLUSPLUS UnaryExpr                  { $$ = createNodeFeatureInfo<ExpressionNode*>(makePrefixNode($2.m_node, OpPlusPlus), $2.m_featureInfo | AssignFeature); }
+  | AUTOPLUSPLUS UnaryExpr              { $$ = createNodeFeatureInfo<ExpressionNode*>(makePrefixNode($2.m_node, OpPlusPlus), $2.m_featureInfo | AssignFeature); }
+  | MINUSMINUS UnaryExpr                { $$ = createNodeFeatureInfo<ExpressionNode*>(makePrefixNode($2.m_node, OpMinusMinus), $2.m_featureInfo | AssignFeature); }
+  | AUTOMINUSMINUS UnaryExpr            { $$ = createNodeFeatureInfo<ExpressionNode*>(makePrefixNode($2.m_node, OpMinusMinus), $2.m_featureInfo | AssignFeature); }
   | '+' UnaryExpr                       { $$ = createNodeFeatureInfo<ExpressionNode*>(new UnaryPlusNode($2.m_node), $2.m_featureInfo); }
   | '-' UnaryExpr                       { $$ = createNodeFeatureInfo<ExpressionNode*>(makeNegateNode($2.m_node), $2.m_featureInfo); }
   | '~' UnaryExpr                       { $$ = createNodeFeatureInfo<ExpressionNode*>(new BitwiseNotNode($2.m_node), $2.m_featureInfo); }
@@ -663,19 +667,19 @@
 AssignmentExpr:
     ConditionalExpr
   | LeftHandSideExpr AssignmentOperator AssignmentExpr
-                                        { $$ = createNodeFeatureInfo<ExpressionNode*>(makeAssignNode($1.m_node, $2, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
+                                        { $$ = createNodeFeatureInfo<ExpressionNode*>(makeAssignNode($1.m_node, $2, $3.m_node, $1.m_featureInfo & AssignFeature, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo | AssignFeature); }
 ;
 
 AssignmentExprNoIn:
     ConditionalExprNoIn
   | LeftHandSideExpr AssignmentOperator AssignmentExprNoIn
-                                        { $$ = createNodeFeatureInfo<ExpressionNode*>(makeAssignNode($1.m_node, $2, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
+                                        { $$ = createNodeFeatureInfo<ExpressionNode*>(makeAssignNode($1.m_node, $2, $3.m_node, $1.m_featureInfo & AssignFeature, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo | AssignFeature); }
 ;
 
 AssignmentExprNoBF:
     ConditionalExprNoBF
   | LeftHandSideExprNoBF AssignmentOperator AssignmentExpr
-                                        { $$ = createNodeFeatureInfo<ExpressionNode*>(makeAssignNode($1.m_node, $2, $3.m_node), $1.m_featureInfo | $3.m_featureInfo); }
+                                        { $$ = createNodeFeatureInfo<ExpressionNode*>(makeAssignNode($1.m_node, $2, $3.m_node, $1.m_featureInfo & AssignFeature, $3.m_featureInfo & AssignFeature), $1.m_featureInfo | $3.m_featureInfo | AssignFeature); }
 ;
 
 AssignmentOperator:
@@ -728,9 +732,9 @@
 ;
 
 Block:
-    '{' '}'                             { $$ = createNodeDeclarationInfo<StatementNode*>(new BlockNode(0), 0, 0, 0);
+    OPENBRACE CLOSEBRACE                             { $$ = createNodeDeclarationInfo<StatementNode*>(new BlockNode(0), 0, 0, 0);
                                           DBG($$.m_node, @1, @2); }
-  | '{' SourceElements '}'              { $$ = createNodeDeclarationInfo<StatementNode*>(new BlockNode($2.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_featureInfo);
+  | OPENBRACE SourceElements CLOSEBRACE              { $$ = createNodeDeclarationInfo<StatementNode*>(new BlockNode($2.m_node), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_featureInfo);
                                           DBG($$.m_node, @1, @3); }
 ;
 
@@ -749,7 +753,7 @@
                                           $$.m_funcDeclarations = 0;
                                           $$.m_featureInfo = 0;
                                         }
-  | IDENT Initializer                   { $$.m_node = new AssignResolveNode(*$1, $2.m_node);
+  | IDENT Initializer                   { $$.m_node = new AssignResolveNode(*$1, $2.m_node, $2.m_featureInfo & AssignFeature);
                                           $$.m_varDeclarations = new ParserRefCountedData<DeclarationStacks::VarStack>;
                                           appendToVarDeclarationList($$.m_varDeclarations, *$1, DeclarationStacks::HasInitializer);
                                           $$.m_funcDeclarations = 0;
@@ -763,7 +767,7 @@
                                           $$.m_featureInfo = $1.m_featureInfo;
                                         }
   | VariableDeclarationList ',' IDENT Initializer
-                                        { $$.m_node = combineVarInitializers($1.m_node, new AssignResolveNode(*$3, $4.m_node));
+                                        { $$.m_node = combineVarInitializers($1.m_node, new AssignResolveNode(*$3, $4.m_node, $4.m_featureInfo & AssignFeature));
                                           $$.m_varDeclarations = $1.m_varDeclarations;
                                           appendToVarDeclarationList($$.m_varDeclarations, *$3, DeclarationStacks::HasInitializer);
                                           $$.m_funcDeclarations = 0;
@@ -778,7 +782,7 @@
                                           $$.m_funcDeclarations = 0;
                                           $$.m_featureInfo = 0;
                                         }
-  | IDENT InitializerNoIn               { $$.m_node = new AssignResolveNode(*$1, $2.m_node);
+  | IDENT InitializerNoIn               { $$.m_node = new AssignResolveNode(*$1, $2.m_node, $2.m_featureInfo & AssignFeature);
                                           $$.m_varDeclarations = new ParserRefCountedData<DeclarationStacks::VarStack>;
                                           appendToVarDeclarationList($$.m_varDeclarations, *$1, DeclarationStacks::HasInitializer);
                                           $$.m_funcDeclarations = 0;
@@ -792,7 +796,7 @@
                                           $$.m_featureInfo = $1.m_featureInfo;
                                         }
   | VariableDeclarationListNoIn ',' IDENT InitializerNoIn
-                                        { $$.m_node = combineVarInitializers($1.m_node, new AssignResolveNode(*$3, $4.m_node));
+                                        { $$.m_node = combineVarInitializers($1.m_node, new AssignResolveNode(*$3, $4.m_node, $4.m_featureInfo & AssignFeature));
                                           $$.m_varDeclarations = $1.m_varDeclarations;
                                           appendToVarDeclarationList($$.m_varDeclarations, *$3, DeclarationStacks::HasInitializer);
                                           $$.m_funcDeclarations = 0;
@@ -949,8 +953,8 @@
 ;
 
 CaseBlock:
-    '{' CaseClausesOpt '}'              { $$ = createNodeDeclarationInfo<CaseBlockNode*>(new CaseBlockNode($2.m_node.head, 0, 0), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_featureInfo); }
-  | '{' CaseClausesOpt DefaultClause CaseClausesOpt '}'
+    OPENBRACE CaseClausesOpt CLOSEBRACE              { $$ = createNodeDeclarationInfo<CaseBlockNode*>(new CaseBlockNode($2.m_node.head, 0, 0), $2.m_varDeclarations, $2.m_funcDeclarations, $2.m_featureInfo); }
+  | OPENBRACE CaseClausesOpt DefaultClause CaseClausesOpt CLOSEBRACE
                                         { $$ = createNodeDeclarationInfo<CaseBlockNode*>(new CaseBlockNode($2.m_node.head, $3.m_node, $4.m_node.head),
                                                                                          mergeDeclarationLists(mergeDeclarationLists($2.m_varDeclarations, $3.m_varDeclarations), $4.m_varDeclarations),
                                                                                          mergeDeclarationLists(mergeDeclarationLists($2.m_funcDeclarations, $3.m_funcDeclarations), $4.m_funcDeclarations),
@@ -1023,16 +1027,16 @@
 ;
 
 FunctionDeclaration:
-    FUNCTION IDENT '(' ')' '{' FunctionBody '}' { $$ = new FuncDeclNode(*$2, $6); DBG($6, @5, @7); }
-  | FUNCTION IDENT '(' FormalParameterList ')' '{' FunctionBody '}'
-                                        { $$ = new FuncDeclNode(*$2, $4.head, $7); DBG($7, @6, @8); }
+    FUNCTION IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = new FuncDeclNode(*$2, $6, LEXER->sourceRange($5, $7)); DBG($6, @5, @7); }
+  | FUNCTION IDENT '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE
+                                        { $$ = new FuncDeclNode(*$2, $7, LEXER->sourceRange($6, $8), $4.head); DBG($7, @6, @8); }
 ;
 
 FunctionExpr:
-    FUNCTION '(' ')' '{' FunctionBody '}' { $$ = createNodeFeatureInfo(new FuncExprNode(CommonIdentifiers::shared()->nullIdentifier, $5), ClosureFeature); DBG($5, @4, @6); }
-  | FUNCTION '(' FormalParameterList ')' '{' FunctionBody '}' { $$ = createNodeFeatureInfo(new FuncExprNode(CommonIdentifiers::shared()->nullIdentifier, $6, $3.head), ClosureFeature); DBG($6, @5, @7); }
-  | FUNCTION IDENT '(' ')' '{' FunctionBody '}' { $$ = createNodeFeatureInfo(new FuncExprNode(*$2, $6), ClosureFeature); DBG($6, @5, @7); }
-  | FUNCTION IDENT '(' FormalParameterList ')' '{' FunctionBody '}' { $$ = createNodeFeatureInfo(new FuncExprNode(*$2, $7, $4.head), ClosureFeature); DBG($7, @6, @8); }
+    FUNCTION '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeFeatureInfo(new FuncExprNode(CommonIdentifiers::shared()->nullIdentifier, $5, LEXER->sourceRange($4, $6)), ClosureFeature); DBG($5, @4, @6); }
+  | FUNCTION '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeFeatureInfo(new FuncExprNode(CommonIdentifiers::shared()->nullIdentifier, $6, LEXER->sourceRange($5, $7), $3.head), ClosureFeature); DBG($6, @5, @7); }
+  | FUNCTION IDENT '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeFeatureInfo(new FuncExprNode(*$2, $6, LEXER->sourceRange($5, $7)), ClosureFeature); DBG($6, @5, @7); }
+  | FUNCTION IDENT '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeFeatureInfo(new FuncExprNode(*$2, $7, LEXER->sourceRange($6, $8), $4.head), ClosureFeature); DBG($7, @6, @8); }
 ;
 
 FormalParameterList:
@@ -1061,7 +1065,7 @@
 ;
 
 Program:
-    /* not in spec */                   { parser().didFinishParsing(0, 0, 0, false, false, @0.last_line); }
+    /* not in spec */                   { parser().didFinishParsing(new SourceElements, 0, 0, false, false, @0.last_line); }
     | SourceElements                    { parser().didFinishParsing($1.m_node, $1.m_varDeclarations, $1.m_funcDeclarations, 
                                                                     ($1.m_featureInfo & EvalFeature) != 0, ($1.m_featureInfo & ClosureFeature) != 0,
                                                                     @1.last_line); }
@@ -1121,7 +1125,7 @@
     return new LessNode(left, right);
 }
 
-static ExpressionNode* makeAssignNode(ExpressionNode* loc, Operator op, ExpressionNode* expr)
+static ExpressionNode* makeAssignNode(ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments)
 {
     if (!loc->isLocation())
         return new AssignErrorNode(loc, op, expr);
@@ -1129,22 +1133,22 @@
     if (loc->isResolveNode()) {
         ResolveNode* resolve = static_cast<ResolveNode*>(loc);
         if (op == OpEqual)
-            return new AssignResolveNode(resolve->identifier(), expr);
+            return new AssignResolveNode(resolve->identifier(), expr, exprHasAssignments);
         else
-            return new ReadModifyResolveNode(resolve->identifier(), op, expr);
+            return new ReadModifyResolveNode(resolve->identifier(), op, expr, exprHasAssignments);
     }
     if (loc->isBracketAccessorNode()) {
         BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(loc);
         if (op == OpEqual)
-            return new AssignBracketNode(bracket->base(), bracket->subscript(), expr);
+            return new AssignBracketNode(bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments);
         else
-            return new ReadModifyBracketNode(bracket->base(), bracket->subscript(), op, expr);
+            return new ReadModifyBracketNode(bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments);
     }
     ASSERT(loc->isDotAccessorNode());
     DotAccessorNode* dot = static_cast<DotAccessorNode*>(loc);
     if (op == OpEqual)
-        return new AssignDotNode(dot->base(), dot->identifier(), expr);
-    return new ReadModifyDotNode(dot->base(), dot->identifier(), op, expr);
+        return new AssignDotNode(dot->base(), dot->identifier(), expr, exprHasAssignments);
+    return new ReadModifyDotNode(dot->base(), dot->identifier(), op, expr, exprHasAssignments);
 }
 
 static ExpressionNode* makePrefixNode(ExpressionNode* expr, Operator op)
@@ -1247,7 +1251,7 @@
     return new DeleteDotNode(dot->base(), dot->identifier());
 }
 
-static PropertyNode* makeGetterOrSetterPropertyNode(const Identifier& getOrSet, const Identifier& name, ParameterNode* params, FunctionBodyNode* body)
+static PropertyNode* makeGetterOrSetterPropertyNode(const Identifier& getOrSet, const Identifier& name, ParameterNode* params, FunctionBodyNode* body, const SourceRange& source)
 {
     PropertyNode::Type type;
     if (getOrSet == "get")
@@ -1256,7 +1260,7 @@
         type = PropertyNode::Setter;
     else
         return 0;
-    return new PropertyNode(name, new FuncExprNode(CommonIdentifiers::shared()->nullIdentifier, body, params), type);
+    return new PropertyNode(name, new FuncExprNode(CommonIdentifiers::shared()->nullIdentifier, body, source, params), type);
 }
 
 static ExpressionNode* makeNegateNode(ExpressionNode* n)
@@ -1290,7 +1294,7 @@
 /* may we automatically insert a semicolon ? */
 static bool allowAutomaticSemicolon(Lexer& lexer, int yychar)
 {
-    return yychar == '}' || yychar == 0 || lexer.prevTerminator();
+    return yychar == CLOSEBRACE || yychar == 0 || lexer.prevTerminator();
 }
 
 static ExpressionNode* combineVarInitializers(ExpressionNode* list, AssignResolveNode* init)
diff --git a/JavaScriptCore/kjs/internal.cpp b/JavaScriptCore/kjs/internal.cpp
index 4155418..fe23e26 100644
--- a/JavaScriptCore/kjs/internal.cpp
+++ b/JavaScriptCore/kjs/internal.cpp
@@ -85,6 +85,11 @@
 
 // ------------------------------ NumberImp ------------------------------------
 
+JSType NumberImp::type() const
+{
+    return NumberType;
+}
+
 JSValue* NumberImp::toPrimitive(ExecState*, JSType) const
 {
     return const_cast<NumberImp*>(this);
@@ -232,9 +237,9 @@
 {
 }
 
-bool InternalFunctionImp::implementsCall() const
+CallType InternalFunctionImp::getCallData(CallData&)
 {
-  return true;
+    return CallTypeNative;
 }
 
 bool InternalFunctionImp::implementsHasInstance() const
diff --git a/JavaScriptCore/kjs/internal.h b/JavaScriptCore/kjs/internal.h
index f8a2dc6..b41f10e0 100644
--- a/JavaScriptCore/kjs/internal.h
+++ b/JavaScriptCore/kjs/internal.h
@@ -63,51 +63,10 @@
     UString val;
   };
 
-  class NumberImp : public JSCell {
-    friend class ConstantValues;
-    friend JSValue *jsNumberCell(double);
-  public:
-    double value() const { return val; }
-
-    virtual JSType type() const { return NumberType; }
-
-    virtual JSValue* toPrimitive(ExecState*, JSType preferred = UnspecifiedType) const;
-    virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
-    virtual bool toBoolean(ExecState *exec) const;
-    virtual double toNumber(ExecState *exec) const;
-    virtual UString toString(ExecState *exec) const;
-    virtual JSObject *toObject(ExecState *exec) const;
-    
-    void* operator new(size_t size)
-    {
-        return Collector::allocateNumber(size);
-    }
-  private:
-    NumberImp(double v) : val(v) { }
-
-    virtual bool getUInt32(uint32_t&) const;
-    virtual bool getTruncatedInt32(int32_t&) const;
-    virtual bool getTruncatedUInt32(uint32_t&) const;
-
-    double val;
-  };
-
-
   // ---------------------------------------------------------------------------
   //                            Evaluation
   // ---------------------------------------------------------------------------
 
-  struct AttachedGlobalObject;
-  class DebuggerImp {
-  public:
-
-    DebuggerImp() {
-      globalObjects = 0;
-    }
-
-    AttachedGlobalObject* globalObjects;
-  };
-
 } // namespace
 
 #endif //  INTERNAL_H
diff --git a/JavaScriptCore/kjs/interpreter.cpp b/JavaScriptCore/kjs/interpreter.cpp
index e0e1f18..ebf614e 100644
--- a/JavaScriptCore/kjs/interpreter.cpp
+++ b/JavaScriptCore/kjs/interpreter.cpp
@@ -25,6 +25,7 @@
 
 #include "ExecState.h"
 #include "JSGlobalObject.h"
+#include "Machine.h"
 #include "Parser.h"
 #include "debugger.h"
 #include <profiler/Profiler.h>
@@ -38,35 +39,31 @@
 
 Completion Interpreter::checkSyntax(ExecState* exec, const UString& sourceURL, int startingLineNumber, const UString& code)
 {
-    return checkSyntax(exec, sourceURL, startingLineNumber, code.data(), code.size());
+    return checkSyntax(exec, sourceURL, startingLineNumber, UStringSourceProvider::create(code));
 }
 
-Completion Interpreter::checkSyntax(ExecState* exec, const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength)
+Completion Interpreter::checkSyntax(ExecState* exec, const UString& sourceURL, int startingLineNumber, PassRefPtr<SourceProvider> source)
 {
     JSLock lock;
 
     int errLine;
     UString errMsg;
-    RefPtr<ProgramNode> progNode = parser().parse<ProgramNode>(sourceURL, startingLineNumber, code, codeLength, 0, &errLine, &errMsg);
+
+    RefPtr<ProgramNode> progNode = parser().parse<ProgramNode>(exec, sourceURL, startingLineNumber, source, 0, &errLine, &errMsg);
     if (!progNode)
         return Completion(Throw, Error::create(exec, SyntaxError, errMsg, errLine, 0, sourceURL));
     return Completion(Normal);
 }
 
-Completion Interpreter::evaluate(ExecState* exec, const UString& sourceURL, int startingLineNumber, const UString& code, JSValue* thisV)
+Completion Interpreter::evaluate(ExecState* exec, ScopeChain& scopeChain, const UString& sourceURL, int startingLineNumber, const UString& code, JSValue* thisV)
 {
-    return evaluate(exec, sourceURL, startingLineNumber, code.data(), code.size(), thisV);
+    return evaluate(exec, scopeChain, sourceURL, startingLineNumber, UStringSourceProvider::create(code), thisV);
 }
 
-Completion Interpreter::evaluate(ExecState* exec, const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength, JSValue* thisV)
+Completion Interpreter::evaluate(ExecState* exec, ScopeChain& scopeChain, const UString& sourceURL, int startingLineNumber, PassRefPtr<SourceProvider> source, JSValue* thisValue)
 {
     JSLock lock;
     
-    JSGlobalObject* globalObject = exec->dynamicGlobalObject();
-
-    if (globalObject->recursion() >= 20)
-        return Completion(Throw, Error::create(exec, GeneralError, "Recursion too deep"));
-    
     // parse the source code
     int sourceId;
     int errLine;
@@ -76,60 +73,22 @@
     Profiler::profiler()->willExecute(exec, sourceURL, startingLineNumber);
 #endif
 
-    RefPtr<ProgramNode> progNode = parser().parse<ProgramNode>(sourceURL, startingLineNumber, code, codeLength, &sourceId, &errLine, &errMsg);
-    
-    // notify debugger that source has been parsed
-    if (globalObject->debugger()) {
-        bool cont = globalObject->debugger()->sourceParsed(exec, sourceId, sourceURL, UString(code, codeLength), startingLineNumber, errLine, errMsg);
-        if (!cont)
-            return Completion(Break);
-    }
-    
+    RefPtr<ProgramNode> programNode = parser().parse<ProgramNode>(exec, sourceURL, startingLineNumber, source, &sourceId, &errLine, &errMsg);
+
     // no program node means a syntax error occurred
-    if (!progNode)
+    if (!programNode)
         return Completion(Throw, Error::create(exec, SyntaxError, errMsg, errLine, sourceId, sourceURL));
-    
-    exec->clearException();
-    
-    globalObject->incRecursion();
-    
-    JSObject* thisObj = globalObject;
-    
-    // "this" must be an object... use same rules as Function.prototype.apply()
-    if (thisV && !thisV->isUndefinedOrNull())
-        thisObj = thisV->toObject(exec);
-    
-    Completion res;
-    if (exec->hadException())
-        // the thisV->toObject() conversion above might have thrown an exception - if so, propagate it
-        res = Completion(Throw, exec->exception());
-    else {
-        // execute the code
-        InterpreterExecState newExec(globalObject, thisObj, progNode.get());
-        JSValue* value = progNode->execute(&newExec);
-        res = Completion(newExec.completionType(), value);
-    }
+
+    JSObject* thisObj = (!thisValue || thisValue->isUndefinedOrNull()) ? exec->dynamicGlobalObject() : thisValue->toObject(exec);
+
+    JSValue* exception = 0;
+    JSValue* result = machine().execute(programNode.get(), exec, scopeChain.node(), thisObj, &exec->dynamicGlobalObject()->registerFileStack(), &exception);
 
 #if JAVASCRIPT_PROFILING
-        Profiler::profiler()->didExecute(exec, sourceURL, startingLineNumber);
+    Profiler::profiler()->didExecute(exec, sourceURL, startingLineNumber);
 #endif
 
-    globalObject->decRecursion();
-    
-    if (shouldPrintExceptions() && res.complType() == Throw) {
-        JSLock lock;
-        ExecState* exec = globalObject->globalExec();
-        CString f = sourceURL.UTF8String();
-        CString message = res.value()->toObject(exec)->toString(exec).UTF8String();
-        int line = res.value()->toObject(exec)->get(exec, "line")->toUInt32(exec);
-#if PLATFORM(WIN_OS)
-        printf("%s line %d: %s\n", f.c_str(), line, message.c_str());
-#else
-        printf("[%d] %s line %d: %s\n", getpid(), f.c_str(), line, message.c_str());
-#endif
-    }
-
-    return res;
+    return exception ? Completion(Throw, exception) : Completion(Normal, result);
 }
 
 static bool printExceptions = false;
diff --git a/JavaScriptCore/kjs/interpreter.h b/JavaScriptCore/kjs/interpreter.h
index 5b52d8c..a8dbd6e 100644
--- a/JavaScriptCore/kjs/interpreter.h
+++ b/JavaScriptCore/kjs/interpreter.h
@@ -23,6 +23,7 @@
 #ifndef KJS_Interpreter_h
 #define KJS_Interpreter_h
 
+#include <wtf/PassRefPtr.h>
 #include <wtf/unicode/Unicode.h>
 
 namespace KJS {
@@ -30,6 +31,8 @@
   class Completion;
   class ExecState;
   class JSValue;
+  class ScopeChain;
+  class SourceProvider;
   class UString;
   
   class Interpreter {
@@ -42,7 +45,7 @@
      * otherwise a throw completion with the syntax error as its value.
      */
     static Completion checkSyntax(ExecState*, const UString& sourceURL, int startingLineNumber, const UString& code);
-    static Completion checkSyntax(ExecState*, const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength);
+    static Completion checkSyntax(ExecState*, const UString& sourceURL, int startingLineNumber, PassRefPtr<SourceProvider> source);
 
     /**
      * Evaluates the supplied ECMAScript code.
@@ -59,8 +62,8 @@
      * execution. This should either be jsNull() or an Object.
      * @return A completion object representing the result of the execution.
      */
-    static Completion evaluate(ExecState*, const UString& sourceURL, int startingLineNumber, const UString& code, JSValue* thisV = 0);
-    static Completion evaluate(ExecState*, const UString& sourceURL, int startingLineNumber, const UChar* code, int codeLength, JSValue* thisV = 0);
+    static Completion evaluate(ExecState*, ScopeChain&, const UString& sourceURL, int startingLineNumber, const UString& code, JSValue* thisV = 0);
+    static Completion evaluate(ExecState*, ScopeChain&, const UString& sourceURL, int startingLineNumber, PassRefPtr<SourceProvider>, JSValue* thisV = 0);
     
     static bool shouldPrintExceptions();
     static void setShouldPrintExceptions(bool);
diff --git a/JavaScriptCore/kjs/lexer.cpp b/JavaScriptCore/kjs/lexer.cpp
index 090c5dc..05f25f2 100644
--- a/JavaScriptCore/kjs/lexer.cpp
+++ b/JavaScriptCore/kjs/lexer.cpp
@@ -101,7 +101,7 @@
     delete[] mainTable.table;
 }
 
-void Lexer::setCode(int startingLineNumber, const UChar* c, unsigned int len)
+void Lexer::setCode(int startingLineNumber, PassRefPtr<SourceProvider> source)
 {
     yylineno = 1 + startingLineNumber;
     restrKeyword = false;
@@ -109,9 +109,11 @@
     eatNextIdentifier = false;
     stackToken = -1;
     lastToken = -1;
+
     pos = 0;
-    code = c;
-    length = len;
+    m_source = source;
+    code = m_source->data();
+    length = m_source->length();
     skipLF = false;
     skipCR = false;
     error = false;
@@ -132,6 +134,7 @@
         next2 = next3;
         do {
             if (pos >= length) {
+                pos++;
                 next3 = -1;
                 break;
             }
@@ -238,7 +241,7 @@
         shift(2);
         state = InSingleLineComment;
       } else {
-        token = matchPunctuator(current, next1, next2, next3);
+        token = matchPunctuator(lvalp->intValue, current, next1, next2, next3);
         if (token != -1) {
           setDone(Other);
         } else {
@@ -642,7 +645,7 @@
   return (c >= '0' && c <= '7');
 }
 
-int Lexer::matchPunctuator(int c1, int c2, int c3, int c4)
+int Lexer::matchPunctuator(int& charPos, int c1, int c2, int c3, int c4)
 {
   if (c1 == '>' && c2 == '>' && c3 == '>' && c4 == '=') {
     shift(4);
@@ -744,13 +747,19 @@
     case '%':
     case '(':
     case ')':
-    case '{':
-    case '}':
     case '[':
     case ']':
     case ';':
       shift(1);
       return static_cast<int>(c1);
+    case '{':
+      charPos = pos - 4;
+      shift(1);
+      return OPENBRACE;
+    case '}':
+      charPos = pos - 4;
+      shift(1);
+      return CLOSEBRACE;
     default:
       return -1;
   }
diff --git a/JavaScriptCore/kjs/lexer.h b/JavaScriptCore/kjs/lexer.h
index cd3085a..673e787 100644
--- a/JavaScriptCore/kjs/lexer.h
+++ b/JavaScriptCore/kjs/lexer.h
@@ -27,6 +27,7 @@
 #include "lookup.h"
 #include "ustring.h"
 #include <wtf/Vector.h>
+#include "SourceRange.h"
 
 namespace WTF {
     template<typename T> class ThreadSpecific;
@@ -39,7 +40,7 @@
 
   class Lexer : Noncopyable {
   public:
-    void setCode(int startingLineNumber, const UChar *c, unsigned int len);
+    void setCode(int startingLineNumber, PassRefPtr<SourceProvider> source);
     int lex(void* lvalp, void* llocp);
 
     int lineNo() const { return yylineno; }
@@ -90,6 +91,7 @@
     bool sawError() const { return error; }
 
     void clear();
+    SourceRange sourceRange(int openBrace, int closeBrace) { return SourceRange(m_source, openBrace + 1, closeBrace); }
 
   private:
     friend Lexer& lexer();
@@ -122,7 +124,7 @@
     bool isLineTerminator();
     static bool isOctalDigit(int);
 
-    int matchPunctuator(int c1, int c2, int c3, int c4);
+    int matchPunctuator(int& charPos, int c1, int c2, int c3, int c4);
     static unsigned short singleEscape(unsigned short);
     static unsigned short convertOctal(int c1, int c2, int c3);
 
@@ -133,6 +135,7 @@
     KJS::Identifier* makeIdentifier(const Vector<UChar>& buffer);
     UString* makeUString(const Vector<UChar>& buffer);
 
+    RefPtr<SourceProvider> m_source;
     const UChar* code;
     unsigned int length;
     int yycolumn;
diff --git a/JavaScriptCore/kjs/list.cpp b/JavaScriptCore/kjs/list.cpp
index 5cc7cc2..6cc28c3 100644
--- a/JavaScriptCore/kjs/list.cpp
+++ b/JavaScriptCore/kjs/list.cpp
@@ -27,8 +27,12 @@
 
 void List::getSlice(int startIndex, List& result) const
 {
+    ASSERT(!result.m_isReadOnly);
+
     const_iterator start = min(begin() + startIndex, end());
     result.m_vector.appendRange(start, end());
+    result.m_size = result.m_vector.size();
+    result.m_buffer = result.m_vector.data();
 }
 
 List::ListSet& List::markSet()
diff --git a/JavaScriptCore/kjs/list.h b/JavaScriptCore/kjs/list.h
index 6a43e08..2b6d8a9 100644
--- a/JavaScriptCore/kjs/list.h
+++ b/JavaScriptCore/kjs/list.h
@@ -41,8 +41,26 @@
         typedef VectorType::iterator iterator;
         typedef VectorType::const_iterator const_iterator;
 
+        // Constructor for a read-write list, to which you may append values.
+        // FIXME: Remove all clients of this API, then remove this API.
         List()
             : m_isInMarkSet(false)
+#ifndef NDEBUG
+            , m_isReadOnly(false)
+#endif
+        {
+            m_buffer = m_vector.data();
+            m_size = m_vector.size();
+        }
+
+        // Constructor for a read-only list whose data has already been allocated elsewhere.
+        List(JSValue** buffer, size_t size)
+            : m_buffer(buffer)
+            , m_size(size)
+            , m_isInMarkSet(false)
+#ifndef NDEBUG
+            , m_isReadOnly(true)
+#endif
         {
         }
 
@@ -52,38 +70,48 @@
                 markSet().remove(this);
         }
 
-        size_t size() const { return m_vector.size(); }
-        bool isEmpty() const { return m_vector.isEmpty(); }
+        size_t size() const { return m_size; }
+        bool isEmpty() const { return !m_size; }
 
         JSValue* at(size_t i) const
         {
-            if (i < m_vector.size())
-                return m_vector.at(i);
+            if (i < m_size)
+                return m_buffer[i];
             return jsUndefined();
         }
 
         JSValue* operator[](int i) const { return at(i); }
 
-        void clear() { m_vector.clear(); }
+        void clear()
+        {
+            m_vector.clear();
+            m_size = 0;
+        }
 
         void append(JSValue* v)
         {
-            if (m_vector.size() < m_vector.capacity())
+            ASSERT(!m_isReadOnly);
+            
+            if (m_vector.size() < m_vector.capacity()) {
                 m_vector.uncheckedAppend(v);
-            else
+                ++m_size;
+            } else {
                 // Putting the slow "expand and append" case all in one 
                 // function measurably improves the performance of the fast 
                 // "just append" case.
                 expandAndAppend(v);
+                m_buffer = m_vector.data();
+                ++m_size;
+            }
         }
 
         void getSlice(int startIndex, List& result) const;
 
-        iterator begin() { return m_vector.begin(); }
-        iterator end() { return m_vector.end(); }
+        iterator begin() { return m_buffer; }
+        iterator end() { return m_buffer + m_size; }
 
-        const_iterator begin() const { return m_vector.begin(); }
-        const_iterator end() const { return m_vector.end(); }
+        const_iterator begin() const { return m_buffer; }
+        const_iterator end() const { return m_buffer + m_size; }
 
         static void markProtectedLists()
         {
@@ -97,9 +125,15 @@
         static void markProtectedListsSlowCase();
 
         void expandAndAppend(JSValue*);
+        
+        JSValue** m_buffer;
+        size_t m_size;
 
         VectorType m_vector;
         bool m_isInMarkSet;
+#ifndef NDEBUG
+        bool m_isReadOnly;
+#endif
 
     private:
         // Prohibits new / delete, which would break GC.
diff --git a/JavaScriptCore/kjs/nodes.cpp b/JavaScriptCore/kjs/nodes.cpp
index 291223b..3371de6 100644
--- a/JavaScriptCore/kjs/nodes.cpp
+++ b/JavaScriptCore/kjs/nodes.cpp
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "nodes.h"
 
+#include "CodeGenerator.h"
 #include "ExecState.h"
 #include "JSGlobalObject.h"
 #include "Parser.h"
@@ -47,7 +48,7 @@
 class FunctionBodyNodeWithDebuggerHooks : public FunctionBodyNode {
 public:
     FunctionBodyNodeWithDebuggerHooks(SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL;
-    virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
+    virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
 };
 
 #if COMPILER(GCC)
@@ -86,7 +87,7 @@
 }
 
 #if !ASSERT_DISABLED
-static inline bool canSkipLookup(ExecState* exec, const Identifier& ident)
+static inline bool canSkipLookup(OldInterpreterExecState* exec, const Identifier& ident)
 {
     // Static lookup in EvalCode is impossible because variables aren't DontDelete.
     // Static lookup in GlobalCode may be possible, but we haven't implemented support for it yet.
@@ -111,6 +112,11 @@
     return localStorage[index].attributes & ReadOnly;
 }
 
+static inline UString::Rep* rep(const Identifier& ident)
+{
+    return ident.ustring().rep();
+}
+
 // ------------------------------ Node -----------------------------------------
 
 #ifndef NDEBUG
@@ -229,28 +235,28 @@
     m_line = lexer().lineNo();
 }
 
-double ExpressionNode::evaluateToNumber(ExecState* exec)
+double ExpressionNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     JSValue* value = evaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
     return value->toNumber(exec);
 }
 
-bool ExpressionNode::evaluateToBoolean(ExecState* exec)
+bool ExpressionNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     JSValue* value = evaluate(exec);
     KJS_CHECKEXCEPTIONBOOLEAN
     return value->toBoolean(exec);
 }
 
-int32_t ExpressionNode::evaluateToInt32(ExecState* exec)
+int32_t ExpressionNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     JSValue* value = evaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
     return value->toInt32(exec);
 }
 
-uint32_t ExpressionNode::evaluateToUInt32(ExecState* exec)
+uint32_t ExpressionNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     JSValue* value = evaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
@@ -269,42 +275,44 @@
 }
 
 static inline int currentSourceId(ExecState* exec) KJS_FAST_CALL;
-static inline int currentSourceId(ExecState* exec)
+static inline int currentSourceId(ExecState*)
 {
-    return exec->scopeNode()->sourceId();
+    ASSERT_NOT_REACHED();
+    return 0;
 }
 
-static inline const UString& currentSourceURL(ExecState* exec) KJS_FAST_CALL;
-static inline const UString& currentSourceURL(ExecState* exec)
+static inline const UString currentSourceURL(ExecState* exec) KJS_FAST_CALL;
+static inline const UString currentSourceURL(ExecState*)
 {
-    return exec->scopeNode()->sourceURL();
+    ASSERT_NOT_REACHED();
+    return UString();
 }
 
-JSValue* Node::setErrorCompletion(ExecState* exec, ErrorType e, const char* msg)
+JSValue* Node::setErrorCompletion(OldInterpreterExecState* exec, ErrorType e, const char* msg)
 {
     return exec->setThrowCompletion(Error::create(exec, e, msg, lineNo(), currentSourceId(exec), currentSourceURL(exec)));
 }
 
-JSValue* Node::setErrorCompletion(ExecState* exec, ErrorType e, const char* msg, const Identifier& ident)
+JSValue* Node::setErrorCompletion(OldInterpreterExecState* exec, ErrorType e, const char* msg, const Identifier& ident)
 {
     UString message = msg;
     substitute(message, ident.ustring());
     return exec->setThrowCompletion(Error::create(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec)));
 }
 
-JSValue* Node::throwError(ExecState* exec, ErrorType e, const char* msg)
+JSValue* Node::throwError(OldInterpreterExecState* exec, ErrorType e, const char* msg)
 {
     return KJS::throwError(exec, e, msg, lineNo(), currentSourceId(exec), currentSourceURL(exec));
 }
 
-JSValue* Node::throwError(ExecState* exec, ErrorType e, const char* msg, const char* string)
+JSValue* Node::throwError(OldInterpreterExecState* exec, ErrorType e, const char* msg, const char* string)
 {
     UString message = msg;
     substitute(message, string);
     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
 }
 
-JSValue* Node::throwError(ExecState* exec, ErrorType e, const char* msg, JSValue* v, Node* expr)
+JSValue* Node::throwError(OldInterpreterExecState* exec, ErrorType e, const char* msg, JSValue* v, Node* expr)
 {
     UString message = msg;
     substitute(message, v->toString(exec));
@@ -312,14 +320,14 @@
     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
 }
 
-JSValue* Node::throwError(ExecState* exec, ErrorType e, const char* msg, const Identifier& label)
+JSValue* Node::throwError(OldInterpreterExecState* exec, ErrorType e, const char* msg, const Identifier& label)
 {
     UString message = msg;
     substitute(message, label.ustring());
     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
 }
 
-JSValue* Node::throwError(ExecState* exec, ErrorType e, const char* msg, JSValue* v, Node* e1, Node* e2)
+JSValue* Node::throwError(OldInterpreterExecState* exec, ErrorType e, const char* msg, JSValue* v, Node* e1, Node* e2)
 {
     UString message = msg;
     substitute(message, v->toString(exec));
@@ -328,7 +336,7 @@
     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
 }
 
-JSValue* Node::throwError(ExecState* exec, ErrorType e, const char* msg, JSValue* v, Node* expr, const Identifier& label)
+JSValue* Node::throwError(OldInterpreterExecState* exec, ErrorType e, const char* msg, JSValue* v, Node* expr, const Identifier& label)
 {
     UString message = msg;
     substitute(message, v->toString(exec));
@@ -337,7 +345,7 @@
     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
 }
 
-JSValue* Node::throwError(ExecState* exec, ErrorType e, const char* msg, JSValue* v, const Identifier& label)
+JSValue* Node::throwError(OldInterpreterExecState* exec, ErrorType e, const char* msg, JSValue* v, const Identifier& label)
 {
     UString message = msg;
     substitute(message, v->toString(exec));
@@ -345,17 +353,17 @@
     return KJS::throwError(exec, e, message, lineNo(), currentSourceId(exec), currentSourceURL(exec));
 }
 
-JSValue* Node::throwUndefinedVariableError(ExecState* exec, const Identifier& ident)
+JSValue* Node::throwUndefinedVariableError(OldInterpreterExecState* exec, const Identifier& ident)
 {
     return throwError(exec, ReferenceError, "Can't find variable: %s", ident);
 }
 
-void Node::handleException(ExecState* exec)
+void Node::handleException(OldInterpreterExecState* exec)
 {
     handleException(exec, exec->exception());
 }
 
-void Node::handleException(ExecState* exec, JSValue* exceptionValue)
+void Node::handleException(OldInterpreterExecState* exec, JSValue* exceptionValue)
 {
     if (exceptionValue->isObject()) {
         JSObject* exception = static_cast<JSObject*>(exceptionValue);
@@ -364,12 +372,14 @@
             exception->put(exec, "sourceURL", jsString(currentSourceURL(exec)));
         }
     }
+#if 0
     Debugger* dbg = exec->dynamicGlobalObject()->debugger();
     if (dbg && !dbg->hasHandledException(exec, exceptionValue))
         dbg->exception(exec, currentSourceId(exec), m_line, exceptionValue);
+#endif
 }
 
-NEVER_INLINE JSValue* Node::rethrowException(ExecState* exec)
+NEVER_INLINE JSValue* Node::rethrowException(OldInterpreterExecState* exec)
 {
     JSValue* exception = exec->exception();
     exec->clearException();
@@ -377,6 +387,22 @@
     return exec->setThrowCompletion(exception);
 }
 
+RegisterID* Node::emitThrowError(CodeGenerator& generator, ErrorType e, const char* msg)
+{
+    RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(msg));
+    generator.emitThrow(exception);
+    return exception;
+}
+
+RegisterID* Node::emitThrowError(CodeGenerator& generator, ErrorType e, const char* msg, const Identifier& label)
+{
+    UString message = msg;
+    substitute(message, label.ustring());
+    RegisterID* exception = generator.emitNewError(generator.newTemporary(), e, jsString(message));
+    generator.emitThrow(exception);
+    return exception;
+}
+    
 // ------------------------------ StatementNode --------------------------------
 
 StatementNode::StatementNode()
@@ -398,10 +424,7 @@
     if (statement->isEmptyStatement())
         return;
 
-    if (Debugger::debuggersPresent)
-        m_statements.append(new BreakpointCheckStatement(statement));
-    else
-        m_statements.append(statement);
+    m_statements.append(statement);
 }
 
 // ------------------------------ BreakpointCheckStatement --------------------------------
@@ -412,11 +435,8 @@
     ASSERT(m_statement);
 }
 
-JSValue* BreakpointCheckStatement::execute(ExecState* exec)
+JSValue* BreakpointCheckStatement::execute(OldInterpreterExecState* exec)
 {
-    if (Debugger* debugger = exec->dynamicGlobalObject()->debugger())
-        if (!debugger->atStatement(exec, currentSourceId(exec), m_statement->firstLine(), m_statement->lastLine()))
-            return exec->setNormalCompletion();
     return m_statement->execute(exec);
 }
 
@@ -425,73 +445,93 @@
     m_statement->streamTo(stream);
 }
 
-void BreakpointCheckStatement::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+void BreakpointCheckStatement::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_statement.get());
 }
 
 // ------------------------------ NullNode -------------------------------------
 
-JSValue* NullNode::evaluate(ExecState* )
+RegisterID* NullNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    return generator.emitLoad(generator.finalDestination(dst), jsNull());
+}
+
+JSValue* NullNode::evaluate(OldInterpreterExecState* )
 {
     return jsNull();
 }
 
 // ------------------------------ FalseNode ----------------------------------
 
-JSValue* FalseNode::evaluate(ExecState*)
+RegisterID* FalseNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    return generator.emitLoad(generator.finalDestination(dst), false);
+}
+
+JSValue* FalseNode::evaluate(OldInterpreterExecState*)
 {
     return jsBoolean(false);
 }
 
 // ------------------------------ TrueNode ----------------------------------
 
-JSValue* TrueNode::evaluate(ExecState*)
+RegisterID* TrueNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    return generator.emitLoad(generator.finalDestination(dst), true);
+}
+
+JSValue* TrueNode::evaluate(OldInterpreterExecState*)
 {
     return jsBoolean(true);
 }
 
 // ------------------------------ NumberNode -----------------------------------
 
-JSValue* NumberNode::evaluate(ExecState*)
+RegisterID* NumberNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    return generator.emitLoad(generator.finalDestination(dst), m_double);
+}
+
+JSValue* NumberNode::evaluate(OldInterpreterExecState*)
 {
     // Number nodes are only created when the number can't fit in a JSImmediate, so no need to check again.
     return jsNumberCell(m_double);
 }
 
-double NumberNode::evaluateToNumber(ExecState*)
+double NumberNode::evaluateToNumber(OldInterpreterExecState*)
 {
     return m_double;
 }
 
-bool NumberNode::evaluateToBoolean(ExecState*)
+bool NumberNode::evaluateToBoolean(OldInterpreterExecState*)
 {
     return m_double < 0.0 || m_double > 0.0; // false for NaN as well as 0
 }
 
-int32_t NumberNode::evaluateToInt32(ExecState*)
+int32_t NumberNode::evaluateToInt32(OldInterpreterExecState*)
 {
     return JSValue::toInt32(m_double);
 }
 
-uint32_t NumberNode::evaluateToUInt32(ExecState*)
+uint32_t NumberNode::evaluateToUInt32(OldInterpreterExecState*)
 {
     return JSValue::toUInt32(m_double);
 }
 
 // ------------------------------ ImmediateNumberNode -----------------------------------
 
-JSValue* ImmediateNumberNode::evaluate(ExecState*)
+JSValue* ImmediateNumberNode::evaluate(OldInterpreterExecState*)
 {
     return m_value;
 }
 
-int32_t ImmediateNumberNode::evaluateToInt32(ExecState*)
+int32_t ImmediateNumberNode::evaluateToInt32(OldInterpreterExecState*)
 {
     return JSImmediate::getTruncatedInt32(m_value);
 }
 
-uint32_t ImmediateNumberNode::evaluateToUInt32(ExecState*)
+uint32_t ImmediateNumberNode::evaluateToUInt32(OldInterpreterExecState*)
 {
     uint32_t i;
     if (JSImmediate::getTruncatedUInt32(m_value, i))
@@ -502,40 +542,67 @@
 
 // ------------------------------ StringNode -----------------------------------
 
-JSValue* StringNode::evaluate(ExecState*)
+RegisterID* StringNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    // FIXME: should we try to atomize constant strings?
+    return generator.emitLoad(generator.finalDestination(dst), jsOwnedString(m_value));
+}
+
+JSValue* StringNode::evaluate(OldInterpreterExecState*)
 {
     return jsOwnedString(m_value);
 }
 
-double StringNode::evaluateToNumber(ExecState*)
+double StringNode::evaluateToNumber(OldInterpreterExecState*)
 {
     return m_value.toDouble();
 }
 
-bool StringNode::evaluateToBoolean(ExecState*)
+bool StringNode::evaluateToBoolean(OldInterpreterExecState*)
 {
     return !m_value.isEmpty();
 }
 
 // ------------------------------ RegExpNode -----------------------------------
 
-JSValue* RegExpNode::evaluate(ExecState* exec)
+RegisterID* RegExpNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 {
-    return exec->lexicalGlobalObject()->regExpConstructor()->createRegExpImp(exec, m_regExp);
+    if (!m_regExp->isValid())
+        return emitThrowError(generator, SyntaxError, "Invalid regular expression: %s", m_regExp->errorMessage());
+    return generator.emitNewRegExp(generator.finalDestination(dst), m_regExp.get());
+}
+
+JSValue* RegExpNode::evaluate(OldInterpreterExecState*)
+{
+    ASSERT_NOT_REACHED();
+    return 0;
 }
 
 // ------------------------------ ThisNode -------------------------------------
 
+RegisterID* ThisNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    return generator.moveToDestinationIfNeeded(dst, generator.thisRegister());
+}
+
 // ECMA 11.1.1
-JSValue* ThisNode::evaluate(ExecState* exec)
+JSValue* ThisNode::evaluate(OldInterpreterExecState* exec)
 {
     return exec->thisValue();
 }
 
 // ------------------------------ ResolveNode ----------------------------------
 
+RegisterID* ResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    if (RegisterID* local = generator.registerForLocal(m_ident))
+        return generator.moveToDestinationIfNeeded(dst, local);
+
+    return generator.emitResolve(generator.finalDestination(dst), m_ident);
+}
+
 // ECMA 11.1.2 & 10.1.4
-JSValue* ResolveNode::inlineEvaluate(ExecState* exec)
+JSValue* ResolveNode::inlineEvaluate(OldInterpreterExecState* exec)
 {
     // Check for missed optimization opportunity.
     ASSERT(!canSkipLookup(exec, m_ident));
@@ -560,42 +627,42 @@
     return throwUndefinedVariableError(exec, m_ident);
 }
 
-JSValue* ResolveNode::evaluate(ExecState* exec)
+JSValue* ResolveNode::evaluate(OldInterpreterExecState* exec)
 {
     return inlineEvaluate(exec);
 }
 
-double ResolveNode::evaluateToNumber(ExecState* exec)
+double ResolveNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
     return v->toNumber(exec);
 }
 
-bool ResolveNode::evaluateToBoolean(ExecState* exec)
+bool ResolveNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONBOOLEAN
     return v->toBoolean(exec);
 }
 
-int32_t ResolveNode::evaluateToInt32(ExecState* exec)
+int32_t ResolveNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
     return v->toInt32(exec);
 }
 
-uint32_t ResolveNode::evaluateToUInt32(ExecState* exec)
+uint32_t ResolveNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
     return v->toUInt32(exec);
 }
 
-static size_t getSymbolTableEntry(ExecState* exec, const Identifier& ident, const SymbolTable& symbolTable, size_t& stackDepth) 
+static size_t getSymbolTableEntry(OldInterpreterExecState* exec, const Identifier& ident, const SymbolTable& symbolTable, size_t& stackDepth) 
 {
-    size_t index = symbolTable.get(ident.ustring().rep());
+    int index = symbolTable.get(ident.ustring().rep()).getIndex();
     if (index != missingSymbolMarker()) {
         stackDepth = 0;
         return index;
@@ -615,7 +682,7 @@
         if (!currentScope->isVariableObject()) 
             break;
         JSVariableObject* currentVariableObject = static_cast<JSVariableObject*>(currentScope);
-        index = currentVariableObject->symbolTable().get(ident.ustring().rep());
+        index = currentVariableObject->symbolTable().get(ident.ustring().rep()).getIndex();
         if (index != missingSymbolMarker()) {
             stackDepth = depth;
             return index;
@@ -627,10 +694,10 @@
     return missingSymbolMarker();
 }
 
-void ResolveNode::optimizeVariableAccess(ExecState* exec, const SymbolTable& symbolTable, const LocalStorage&, NodeStack&)
+void ResolveNode::optimizeVariableAccess(OldInterpreterExecState* exec, const SymbolTable& symbolTable, const LocalStorage&, NodeStack&)
 {
     size_t depth = 0;
-    size_t index = getSymbolTableEntry(exec, m_ident, symbolTable, depth);
+    int index = getSymbolTableEntry(exec, m_ident, symbolTable, depth);
     if (index != missingSymbolMarker()) {
         if (!depth)
             new (this) LocalVarAccessNode(index);
@@ -645,80 +712,82 @@
     new (this) NonLocalVarAccessNode(depth);
 }
 
-JSValue* LocalVarAccessNode::inlineEvaluate(ExecState* exec)
+JSValue* LocalVarAccessNode::inlineEvaluate(OldInterpreterExecState* exec)
 {
     ASSERT(exec->variableObject() == exec->scopeChain().top());
     return exec->localStorage()[m_index].value;
 }
 
-JSValue* LocalVarAccessNode::evaluate(ExecState* exec)
+JSValue* LocalVarAccessNode::evaluate(OldInterpreterExecState* exec)
 {
     return inlineEvaluate(exec);
 }
 
-double LocalVarAccessNode::evaluateToNumber(ExecState* exec)
+double LocalVarAccessNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     return inlineEvaluate(exec)->toNumber(exec);
 }
 
-bool LocalVarAccessNode::evaluateToBoolean(ExecState* exec)
+bool LocalVarAccessNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     return inlineEvaluate(exec)->toBoolean(exec);
 }
 
-int32_t LocalVarAccessNode::evaluateToInt32(ExecState* exec)
+int32_t LocalVarAccessNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     return inlineEvaluate(exec)->toInt32(exec);
 }
 
-uint32_t LocalVarAccessNode::evaluateToUInt32(ExecState* exec)
+uint32_t LocalVarAccessNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     return inlineEvaluate(exec)->toUInt32(exec);
 }
 
-static inline JSValue* getNonLocalSymbol(ExecState* exec, size_t index, size_t scopeDepth)
+static inline JSValue* getNonLocalSymbol(OldInterpreterExecState* exec, size_t, size_t scopeDepth)
 {
     const ScopeChain& chain = exec->scopeChain();
     ScopeChainIterator iter = chain.begin();
     for (size_t i = 0; i < scopeDepth; ++iter, ++i)
         ASSERT(iter != chain.end());
+#ifndef NDEBUG
     JSObject* scope = *iter;
+#endif
     ASSERT(scope->isVariableObject());
-    JSVariableObject* variableObject = static_cast<JSVariableObject*>(scope);
-    return variableObject->localStorage()[index].value;
+    ASSERT_NOT_REACHED();
+    return 0;
 }
 
-JSValue* ScopedVarAccessNode::inlineEvaluate(ExecState* exec)
+JSValue* ScopedVarAccessNode::inlineEvaluate(OldInterpreterExecState* exec)
 {
     return getNonLocalSymbol(exec, m_index, m_scopeDepth);
 }
 
-JSValue* ScopedVarAccessNode::evaluate(ExecState* exec)
+JSValue* ScopedVarAccessNode::evaluate(OldInterpreterExecState* exec)
 {
     return inlineEvaluate(exec);
 }
 
-double ScopedVarAccessNode::evaluateToNumber(ExecState* exec)
+double ScopedVarAccessNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     return inlineEvaluate(exec)->toNumber(exec);
 }
 
-bool ScopedVarAccessNode::evaluateToBoolean(ExecState* exec)
+bool ScopedVarAccessNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     return inlineEvaluate(exec)->toBoolean(exec);
 }
 
-int32_t ScopedVarAccessNode::evaluateToInt32(ExecState* exec)
+int32_t ScopedVarAccessNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     return inlineEvaluate(exec)->toInt32(exec);
 }
 
-uint32_t ScopedVarAccessNode::evaluateToUInt32(ExecState* exec)
+uint32_t ScopedVarAccessNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     return inlineEvaluate(exec)->toUInt32(exec);
 }
 
-JSValue* NonLocalVarAccessNode::inlineEvaluate(ExecState* exec)
+JSValue* NonLocalVarAccessNode::inlineEvaluate(OldInterpreterExecState* exec)
 {
     // Check for missed optimization opportunity.
     ASSERT(!canSkipLookup(exec, m_ident));
@@ -745,34 +814,34 @@
     return throwUndefinedVariableError(exec, m_ident);
 }
 
-JSValue* NonLocalVarAccessNode::evaluate(ExecState* exec)
+JSValue* NonLocalVarAccessNode::evaluate(OldInterpreterExecState* exec)
 {
     return inlineEvaluate(exec);
 }
 
-double NonLocalVarAccessNode::evaluateToNumber(ExecState* exec)
+double NonLocalVarAccessNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     return inlineEvaluate(exec)->toNumber(exec);
 }
 
-bool NonLocalVarAccessNode::evaluateToBoolean(ExecState* exec)
+bool NonLocalVarAccessNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     return inlineEvaluate(exec)->toBoolean(exec);
 }
 
-int32_t NonLocalVarAccessNode::evaluateToInt32(ExecState* exec)
+int32_t NonLocalVarAccessNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     return inlineEvaluate(exec)->toInt32(exec);
 }
 
-uint32_t NonLocalVarAccessNode::evaluateToUInt32(ExecState* exec)
+uint32_t NonLocalVarAccessNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     return inlineEvaluate(exec)->toUInt32(exec);
 }
 
 // ------------------------------ ElementNode ----------------------------------
 
-void ElementNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+void ElementNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     if (m_next)
         nodeStack.append(m_next.get());
@@ -781,7 +850,7 @@
 }
 
 // ECMA 11.1.4
-JSValue* ElementNode::evaluate(ExecState* exec)
+JSValue* ElementNode::evaluate(OldInterpreterExecState* exec)
 {
     JSObject* array = exec->lexicalGlobalObject()->arrayConstructor()->construct(exec, exec->emptyList());
     int length = 0;
@@ -796,14 +865,33 @@
 
 // ------------------------------ ArrayNode ------------------------------------
 
-void ArrayNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+
+RegisterID* ArrayNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> newArray = generator.emitNewArray(generator.tempDestination(dst));
+    unsigned length = 0;
+
+    RegisterID* value;
+    for (ElementNode* n = m_element.get(); n; n = n->m_next.get()) {
+        value = generator.emitNode(n->m_node.get());
+        length += n->m_elision;
+        generator.emitPutByIndex(newArray.get(), length++, value);
+    }
+
+    value = generator.emitLoad(generator.newTemporary(), jsNumber(m_elision + length));
+    generator.emitPutById(newArray.get(), generator.propertyNames().length, value);
+
+    return generator.moveToDestinationIfNeeded(dst, newArray.get());
+}
+
+void ArrayNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     if (m_element)
         nodeStack.append(m_element.get());
 }
 
 // ECMA 11.1.4
-JSValue* ArrayNode::evaluate(ExecState* exec)
+JSValue* ArrayNode::evaluate(OldInterpreterExecState* exec)
 {
     JSObject* array;
     int length;
@@ -826,14 +914,22 @@
 
 // ------------------------------ ObjectLiteralNode ----------------------------
 
-void ObjectLiteralNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* ObjectLiteralNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    if (m_list)
+        return generator.emitNode(dst, m_list.get());
+    else
+        return generator.emitNewObject(generator.finalDestination(dst));
+}
+
+void ObjectLiteralNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     if (m_list)
         nodeStack.append(m_list.get());
 }
 
 // ECMA 11.1.5
-JSValue* ObjectLiteralNode::evaluate(ExecState* exec)
+JSValue* ObjectLiteralNode::evaluate(OldInterpreterExecState* exec)
 {
     if (m_list)
         return m_list->evaluate(exec);
@@ -843,7 +939,37 @@
 
 // ------------------------------ PropertyListNode -----------------------------
 
-void PropertyListNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* PropertyListNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> newObj = generator.tempDestination(dst);
+    
+    generator.emitNewObject(newObj.get());
+    
+    for (PropertyListNode* p = this; p; p = p->m_next.get()) {
+        RegisterID* value = generator.emitNode(p->m_node->m_assign.get());
+        
+        switch (p->m_node->m_type) {
+            case PropertyNode::Constant: {
+                generator.emitPutById(newObj.get(), p->m_node->name(), value);
+                break;
+            }
+            case PropertyNode::Getter: {
+                generator.emitPutGetter(newObj.get(), p->m_node->name(), value);
+                break;
+            }
+            case PropertyNode::Setter: {
+                generator.emitPutSetter(newObj.get(), p->m_node->name(), value);
+                break;
+            }
+            default:
+                ASSERT_NOT_REACHED();
+        }
+    }
+    
+    return generator.moveToDestinationIfNeeded(dst, newObj.get());
+}
+
+void PropertyListNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     if (m_next)
         nodeStack.append(m_next.get());
@@ -851,7 +977,7 @@
 }
 
 // ECMA 11.1.5
-JSValue* PropertyListNode::evaluate(ExecState* exec)
+JSValue* PropertyListNode::evaluate(OldInterpreterExecState* exec)
 {
     JSObject* obj = exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList());
 
@@ -879,13 +1005,13 @@
 
 // ------------------------------ PropertyNode -----------------------------
 
-void PropertyNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+void PropertyNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_assign.get());
 }
 
 // ECMA 11.1.5
-JSValue* PropertyNode::evaluate(ExecState*)
+JSValue* PropertyNode::evaluate(OldInterpreterExecState*)
 {
     ASSERT(false);
     return jsNull();
@@ -893,14 +1019,22 @@
 
 // ------------------------------ BracketAccessorNode --------------------------------
 
-void BracketAccessorNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* BracketAccessorNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> base = generator.emitNode(m_base.get());
+    RegisterID* property = generator.emitNode(m_subscript.get());
+
+    return generator.emitGetByVal(generator.finalDestination(dst), base.get(), property);
+}
+
+void BracketAccessorNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_subscript.get());
     nodeStack.append(m_base.get());
 }
 
 // ECMA 11.2.1a
-JSValue* BracketAccessorNode::inlineEvaluate(ExecState* exec)
+JSValue* BracketAccessorNode::inlineEvaluate(OldInterpreterExecState* exec)
 {
     JSValue* v1 = m_base->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -913,33 +1047,33 @@
     return o->get(exec, Identifier(v2->toString(exec)));
 }
 
-JSValue* BracketAccessorNode::evaluate(ExecState* exec)
+JSValue* BracketAccessorNode::evaluate(OldInterpreterExecState* exec)
 {
     return inlineEvaluate(exec);
 }
 
-double BracketAccessorNode::evaluateToNumber(ExecState* exec)
+double BracketAccessorNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
     return v->toNumber(exec);
 }
 
-bool BracketAccessorNode::evaluateToBoolean(ExecState* exec)
+bool BracketAccessorNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONBOOLEAN
     return v->toBoolean(exec);
 }
 
-int32_t BracketAccessorNode::evaluateToInt32(ExecState* exec)
+int32_t BracketAccessorNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
     return v->toInt32(exec);
 }
 
-uint32_t BracketAccessorNode::evaluateToUInt32(ExecState* exec)
+uint32_t BracketAccessorNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
@@ -948,46 +1082,52 @@
 
 // ------------------------------ DotAccessorNode --------------------------------
 
-void DotAccessorNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* DotAccessorNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RegisterID* base = generator.emitNode(m_base.get());
+    return generator.emitGetById(generator.finalDestination(dst), base, m_ident);
+}
+
+void DotAccessorNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_base.get());
 }
 
 // ECMA 11.2.1b
-JSValue* DotAccessorNode::inlineEvaluate(ExecState* exec)
+JSValue* DotAccessorNode::inlineEvaluate(OldInterpreterExecState* exec)
 {
     JSValue* v = m_base->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
     return v->toObject(exec)->get(exec, m_ident);
 }
 
-JSValue* DotAccessorNode::evaluate(ExecState* exec)
+JSValue* DotAccessorNode::evaluate(OldInterpreterExecState* exec)
 {
     return inlineEvaluate(exec);
 }
 
-double DotAccessorNode::evaluateToNumber(ExecState* exec)
+double DotAccessorNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
     return v->toNumber(exec);
 }
 
-bool DotAccessorNode::evaluateToBoolean(ExecState* exec)
+bool DotAccessorNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONBOOLEAN
     return v->toBoolean(exec);
 }
 
-int32_t DotAccessorNode::evaluateToInt32(ExecState* exec)
+int32_t DotAccessorNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
     return v->toInt32(exec);
 }
 
-uint32_t DotAccessorNode::evaluateToUInt32(ExecState* exec)
+uint32_t DotAccessorNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
@@ -996,7 +1136,13 @@
 
 // ------------------------------ ArgumentListNode -----------------------------
 
-void ArgumentListNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* ArgumentListNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    ASSERT(m_expr);
+    return generator.emitNode(dst, m_expr.get());
+}
+
+void ArgumentListNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     if (m_next)
         nodeStack.append(m_next.get());
@@ -1005,7 +1151,7 @@
 }
 
 // ECMA 11.2.4
-void ArgumentListNode::evaluateList(ExecState* exec, List& list)
+void ArgumentListNode::evaluateList(OldInterpreterExecState* exec, List& list)
 {
     for (ArgumentListNode* n = this; n; n = n->m_next.get()) {
         JSValue* v = n->m_expr->evaluate(exec);
@@ -1016,7 +1162,7 @@
 
 // ------------------------------ ArgumentsNode --------------------------------
 
-void ArgumentsNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+void ArgumentsNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     if (m_listNode)
         nodeStack.append(m_listNode.get());
@@ -1024,7 +1170,13 @@
 
 // ------------------------------ NewExprNode ----------------------------------
 
-void NewExprNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* NewExprNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
+    return generator.emitConstruct(generator.finalDestination(dst), r0.get(), m_args.get());
+}
+
+void NewExprNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     if (m_args)
         nodeStack.append(m_args.get());
@@ -1033,7 +1185,7 @@
 
 // ECMA 11.2.2
 
-JSValue* NewExprNode::inlineEvaluate(ExecState* exec)
+JSValue* NewExprNode::inlineEvaluate(OldInterpreterExecState* exec)
 {
     JSValue* v = m_expr->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -1047,40 +1199,40 @@
     if (!v->isObject())
         return throwError(exec, TypeError, "Value %s (result of expression %s) is not an object. Cannot be used with new.", v, m_expr.get());
 
-    JSObject* constr = static_cast<JSObject*>(v);
-    if (!constr->implementsConstruct())
+    ConstructData constructData;
+    if (v->getConstructData(constructData) == ConstructTypeNone)
         return throwError(exec, TypeError, "Value %s (result of expression %s) is not a constructor. Cannot be used with new.", v, m_expr.get());
 
-    return constr->construct(exec, argList);
+    return static_cast<JSObject*>(v)->construct(exec, argList);
 }
 
-JSValue* NewExprNode::evaluate(ExecState* exec)
+JSValue* NewExprNode::evaluate(OldInterpreterExecState* exec)
 {
     return inlineEvaluate(exec);
 }
 
-double NewExprNode::evaluateToNumber(ExecState* exec)
+double NewExprNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
     return v->toNumber(exec);
 }
 
-bool NewExprNode::evaluateToBoolean(ExecState* exec)
+bool NewExprNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONBOOLEAN
     return v->toBoolean(exec);
 }
 
-int32_t NewExprNode::evaluateToInt32(ExecState* exec)
+int32_t NewExprNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
     return v->toInt32(exec);
 }
 
-uint32_t NewExprNode::evaluateToUInt32(ExecState* exec)
+uint32_t NewExprNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
@@ -1088,7 +1240,7 @@
 }
 
 template <ExpressionNode::CallerType callerType, bool scopeDepthIsZero> 
-inline JSValue* ExpressionNode::resolveAndCall(ExecState* exec, const Identifier& ident, ArgumentsNode* args, size_t scopeDepth)
+inline JSValue* ExpressionNode::resolveAndCall(OldInterpreterExecState* exec, const Identifier& ident, ArgumentsNode* args, size_t scopeDepth)
 {
     const ScopeChain& chain = exec->scopeChain();
     ScopeChainIterator iter = chain.begin();
@@ -1124,8 +1276,7 @@
 
             if (callerType == EvalOperator) {
                 if (base == exec->lexicalGlobalObject() && func == exec->lexicalGlobalObject()->evalFunction()) {
-                    exec->dynamicGlobalObject()->tearOffActivation(exec);
-                    return eval(exec, exec->scopeChain(), exec->variableObject(), exec->dynamicGlobalObject(), exec->thisValue(), argList);
+                    ASSERT_NOT_REACHED();
                 }
             }
 
@@ -1138,24 +1289,38 @@
     return throwUndefinedVariableError(exec, ident);
 }
 
-void EvalFunctionCallNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* EvalFunctionCallNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> base = generator.tempDestination(dst);
+    RegisterID* func = generator.newTemporary();
+    generator.emitResolveWithBase(base.get(), func, CommonIdentifiers::shared()->eval);
+    return generator.emitCallEval(generator.finalDestination(dst, base.get()), func, base.get(), m_args.get());
+}
+
+void EvalFunctionCallNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_args.get());
 }
 
-JSValue* EvalFunctionCallNode::evaluate(ExecState* exec)
+JSValue* EvalFunctionCallNode::evaluate(OldInterpreterExecState* exec)
 {
     return resolveAndCall<EvalOperator, true>(exec, exec->propertyNames().eval, m_args.get());
 }
 
-void FunctionCallValueNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* FunctionCallValueNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RegisterID* r0 = generator.emitNode(m_expr.get());
+    return generator.emitCall(generator.finalDestination(dst), r0, 0, m_args.get());
+}
+
+void FunctionCallValueNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_args.get());
     nodeStack.append(m_expr.get());
 }
 
 // ECMA 11.2.3
-JSValue* FunctionCallValueNode::evaluate(ExecState* exec)
+JSValue* FunctionCallValueNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* v = m_expr->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -1178,12 +1343,30 @@
     return func->call(exec, thisObj, argList);
 }
 
-void FunctionCallResolveNode::optimizeVariableAccess(ExecState* exec, const SymbolTable& symbolTable, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* FunctionCallResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    if (RegisterID* local = generator.registerForLocal(m_ident))
+        return generator.emitCall(generator.finalDestination(dst), local, 0, m_args.get());
+
+    int index = 0;
+    size_t depth = 0;
+    if (generator.findScopedProperty(m_ident, index, depth) && index != missingSymbolMarker()) {
+        RegisterID* func = generator.emitGetScopedVar(generator.newTemporary(), depth, index);
+        return generator.emitCall(generator.finalDestination(dst), func, 0, m_args.get());
+    }
+
+    RefPtr<RegisterID> base = generator.tempDestination(dst);
+    RegisterID* func = generator.newTemporary();
+    generator.emitResolveFunction(base.get(), func, m_ident);
+    return generator.emitCall(generator.finalDestination(dst, base.get()), func, base.get(), m_args.get());
+}
+
+void FunctionCallResolveNode::optimizeVariableAccess(OldInterpreterExecState* exec, const SymbolTable& symbolTable, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_args.get());
 
     size_t depth = 0;
-    size_t index = getSymbolTableEntry(exec, m_ident, symbolTable, depth);
+    int index = getSymbolTableEntry(exec, m_ident, symbolTable, depth);
     if (index != missingSymbolMarker()) {
         if (!depth)
             new (this) LocalVarFunctionCallNode(index);
@@ -1199,7 +1382,7 @@
 }
 
 // ECMA 11.2.3
-JSValue* FunctionCallResolveNode::inlineEvaluate(ExecState* exec)
+JSValue* FunctionCallResolveNode::inlineEvaluate(OldInterpreterExecState* exec)
 {
     // Check for missed optimization opportunity.
     ASSERT(!canSkipLookup(exec, m_ident));
@@ -1207,40 +1390,40 @@
     return resolveAndCall<FunctionCall, true>(exec, m_ident, m_args.get());
 }
 
-JSValue* FunctionCallResolveNode::evaluate(ExecState* exec)
+JSValue* FunctionCallResolveNode::evaluate(OldInterpreterExecState* exec)
 {
     return inlineEvaluate(exec);
 }
 
-double FunctionCallResolveNode::evaluateToNumber(ExecState* exec)
+double FunctionCallResolveNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
     return v->toNumber(exec);
 }
 
-bool FunctionCallResolveNode::evaluateToBoolean(ExecState* exec)
+bool FunctionCallResolveNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONBOOLEAN
     return v->toBoolean(exec);
 }
 
-int32_t FunctionCallResolveNode::evaluateToInt32(ExecState* exec)
+int32_t FunctionCallResolveNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
     return v->toInt32(exec);
 }
 
-uint32_t FunctionCallResolveNode::evaluateToUInt32(ExecState* exec)
+uint32_t FunctionCallResolveNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
     return v->toUInt32(exec);
 }
 
-JSValue* LocalVarFunctionCallNode::inlineEvaluate(ExecState* exec)
+JSValue* LocalVarFunctionCallNode::inlineEvaluate(OldInterpreterExecState* exec)
 {
     ASSERT(exec->variableObject() == exec->scopeChain().top());
 
@@ -1261,40 +1444,40 @@
     return func->call(exec, thisObj, argList);
 }
 
-JSValue* LocalVarFunctionCallNode::evaluate(ExecState* exec)
+JSValue* LocalVarFunctionCallNode::evaluate(OldInterpreterExecState* exec)
 {
     return inlineEvaluate(exec);
 }
 
-double LocalVarFunctionCallNode::evaluateToNumber(ExecState* exec)
+double LocalVarFunctionCallNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
     return v->toNumber(exec);
 }
 
-bool LocalVarFunctionCallNode::evaluateToBoolean(ExecState* exec)
+bool LocalVarFunctionCallNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONBOOLEAN
     return v->toBoolean(exec);
 }
 
-int32_t LocalVarFunctionCallNode::evaluateToInt32(ExecState* exec)
+int32_t LocalVarFunctionCallNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
     return v->toInt32(exec);
 }
 
-uint32_t LocalVarFunctionCallNode::evaluateToUInt32(ExecState* exec)
+uint32_t LocalVarFunctionCallNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
     return v->toUInt32(exec);
 }
 
-JSValue* ScopedVarFunctionCallNode::inlineEvaluate(ExecState* exec)
+JSValue* ScopedVarFunctionCallNode::inlineEvaluate(OldInterpreterExecState* exec)
 {
     ASSERT(exec->variableObject() == exec->scopeChain().top());
     
@@ -1315,40 +1498,40 @@
     return func->call(exec, thisObj, argList);
 }
 
-JSValue* ScopedVarFunctionCallNode::evaluate(ExecState* exec)
+JSValue* ScopedVarFunctionCallNode::evaluate(OldInterpreterExecState* exec)
 {
     return inlineEvaluate(exec);
 }
 
-double ScopedVarFunctionCallNode::evaluateToNumber(ExecState* exec)
+double ScopedVarFunctionCallNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
     return v->toNumber(exec);
 }
 
-bool ScopedVarFunctionCallNode::evaluateToBoolean(ExecState* exec)
+bool ScopedVarFunctionCallNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONBOOLEAN
     return v->toBoolean(exec);
 }
 
-int32_t ScopedVarFunctionCallNode::evaluateToInt32(ExecState* exec)
+int32_t ScopedVarFunctionCallNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
     return v->toInt32(exec);
 }
 
-uint32_t ScopedVarFunctionCallNode::evaluateToUInt32(ExecState* exec)
+uint32_t ScopedVarFunctionCallNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
     return v->toUInt32(exec);
 }
 
-JSValue* NonLocalVarFunctionCallNode::inlineEvaluate(ExecState* exec)
+JSValue* NonLocalVarFunctionCallNode::inlineEvaluate(OldInterpreterExecState* exec)
 {
     // Check for missed optimization opportunity.
     ASSERT(!canSkipLookup(exec, m_ident));
@@ -1356,40 +1539,48 @@
     return resolveAndCall<FunctionCall, false>(exec, m_ident, m_args.get(), m_scopeDepth);
 }
 
-JSValue* NonLocalVarFunctionCallNode::evaluate(ExecState* exec)
+JSValue* NonLocalVarFunctionCallNode::evaluate(OldInterpreterExecState* exec)
 {
     return inlineEvaluate(exec);
 }
 
-double NonLocalVarFunctionCallNode::evaluateToNumber(ExecState* exec)
+double NonLocalVarFunctionCallNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
     return v->toNumber(exec);
 }
 
-bool NonLocalVarFunctionCallNode::evaluateToBoolean(ExecState* exec)
+bool NonLocalVarFunctionCallNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONBOOLEAN
     return v->toBoolean(exec);
 }
 
-int32_t NonLocalVarFunctionCallNode::evaluateToInt32(ExecState* exec)
+int32_t NonLocalVarFunctionCallNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
     return v->toInt32(exec);
 }
 
-uint32_t NonLocalVarFunctionCallNode::evaluateToUInt32(ExecState* exec)
+uint32_t NonLocalVarFunctionCallNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
     return v->toUInt32(exec);
 }
 
-void FunctionCallBracketNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* FunctionCallBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> base = generator.emitNode(m_base.get());
+    RegisterID* property = generator.emitNode(m_subscript.get());
+    RegisterID* function = generator.emitGetByVal(generator.newTemporary(), base.get(), property);
+    return generator.emitCall(generator.finalDestination(dst, base.get()), function, base.get(), m_args.get());
+}
+
+void FunctionCallBracketNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_args.get());
     nodeStack.append(m_subscript.get());
@@ -1397,7 +1588,7 @@
 }
 
 // ECMA 11.2.3
-JSValue* FunctionCallBracketNode::evaluate(ExecState* exec)
+JSValue* FunctionCallBracketNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* baseVal = m_base->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -1457,14 +1648,21 @@
     return "Object %s (result of expression %s.%s) does not allow calls.";
 }
 
-void FunctionCallDotNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* FunctionCallDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> base = generator.emitNode(m_base.get());
+    RegisterID* function = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
+    return generator.emitCall(generator.finalDestination(dst, base.get()), function, base.get(), m_args.get());
+}
+
+void FunctionCallDotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_args.get());
     nodeStack.append(m_base.get());
 }
 
 // ECMA 11.2.3
-JSValue* FunctionCallDotNode::inlineEvaluate(ExecState* exec)
+JSValue* FunctionCallDotNode::inlineEvaluate(OldInterpreterExecState* exec)
 {
     JSValue* baseVal = m_base->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -1495,33 +1693,33 @@
     return func->call(exec, thisObj, argList);
 }
 
-JSValue* FunctionCallDotNode::evaluate(ExecState* exec)
+JSValue* FunctionCallDotNode::evaluate(OldInterpreterExecState* exec)
 {
     return inlineEvaluate(exec);
 }
 
-double FunctionCallDotNode::evaluateToNumber(ExecState* exec)
+double FunctionCallDotNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
     return v->toNumber(exec);
 }
 
-bool FunctionCallDotNode::evaluateToBoolean(ExecState* exec)
+bool FunctionCallDotNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONBOOLEAN
     return v->toBoolean(exec);
 }
 
-int32_t FunctionCallDotNode::evaluateToInt32(ExecState* exec)
+int32_t FunctionCallDotNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
     return v->toInt32(exec);
 }
 
-uint32_t FunctionCallDotNode::evaluateToUInt32(ExecState* exec)
+uint32_t FunctionCallDotNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     JSValue* v = inlineEvaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
@@ -1532,10 +1730,29 @@
 
 // ------------------------------ PostfixResolveNode ----------------------------------
 
-// Increment
-void PostIncResolveNode::optimizeVariableAccess(ExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
+RegisterID* PostIncResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 {
-    size_t index = symbolTable.get(m_ident.ustring().rep());
+    // FIXME: I think we can detect the absense of dependent expressions here, 
+    // and emit a PreInc instead of a PostInc. A post-pass to eliminate dead
+    // code would work, too.
+    if (RegisterID* local = generator.registerForLocal(m_ident)) {
+        if (generator.isLocalConstant(m_ident))
+            return generator.emitToJSNumber(generator.finalDestination(dst), local);
+        
+        return generator.emitPostInc(generator.finalDestination(dst), local);
+    }
+
+    RefPtr<RegisterID> value = generator.newTemporary();
+    RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), value.get(), m_ident);
+    RegisterID* oldValue = generator.emitPostInc(generator.finalDestination(dst), value.get());
+    generator.emitPutById(base.get(), m_ident, value.get());
+    return oldValue;
+}
+
+// Increment
+void PostIncResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
+{
+    int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
     if (index != missingSymbolMarker()) {
         if (isConstant(localStorage, index))
             new (this) PostIncConstNode(index);
@@ -1544,7 +1761,7 @@
     }
 }
 
-JSValue* PostIncResolveNode::evaluate(ExecState* exec)
+JSValue* PostIncResolveNode::evaluate(OldInterpreterExecState* exec)
 {
     // Check for missed optimization opportunity.
     ASSERT(!canSkipLookup(exec, m_ident));
@@ -1581,7 +1798,7 @@
     new (this) PreIncResolveNode(PlacementNewAdopt);
 }
 
-JSValue* PostIncLocalVarNode::evaluate(ExecState* exec)
+JSValue* PostIncLocalVarNode::evaluate(OldInterpreterExecState* exec)
 {
     ASSERT(exec->variableObject() == exec->scopeChain().top());
 
@@ -1597,9 +1814,28 @@
 }
 
 // Decrement
-void PostDecResolveNode::optimizeVariableAccess(ExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
+RegisterID* PostDecResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 {
-    size_t index = symbolTable.get(m_ident.ustring().rep());
+    // FIXME: I think we can detect the absense of dependent expressions here, 
+    // and emit a PreDec instead of a PostDec. A post-pass to eliminate dead
+    // code would work, too.
+    if (RegisterID* local = generator.registerForLocal(m_ident)) {
+        if (generator.isLocalConstant(m_ident))
+            return generator.emitToJSNumber(generator.finalDestination(dst), local);
+        
+        return generator.emitPostDec(generator.finalDestination(dst), local);
+    }
+
+    RefPtr<RegisterID> value = generator.newTemporary();
+    RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), value.get(), m_ident);
+    RegisterID* oldValue = generator.emitPostDec(generator.finalDestination(dst), value.get());
+    generator.emitPutById(base.get(), m_ident, value.get());
+    return oldValue;
+}
+
+void PostDecResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
+{
+    int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
     if (index != missingSymbolMarker()) {
         if (isConstant(localStorage, index))
             new (this) PostDecConstNode(index);
@@ -1608,7 +1844,7 @@
     }
 }
 
-JSValue* PostDecResolveNode::evaluate(ExecState* exec)
+JSValue* PostDecResolveNode::evaluate(OldInterpreterExecState* exec)
 {
     // Check for missed optimization opportunity.
     ASSERT(!canSkipLookup(exec, m_ident));
@@ -1642,7 +1878,7 @@
     new (this) PreDecResolveNode(PlacementNewAdopt);
 }
 
-JSValue* PostDecLocalVarNode::evaluate(ExecState* exec)
+JSValue* PostDecLocalVarNode::evaluate(OldInterpreterExecState* exec)
 {
     ASSERT(exec->variableObject() == exec->scopeChain().top());
 
@@ -1652,7 +1888,7 @@
     return v;
 }
 
-double PostDecLocalVarNode::inlineEvaluateToNumber(ExecState* exec)
+double PostDecLocalVarNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
 {
     ASSERT(exec->variableObject() == exec->scopeChain().top());
 
@@ -1662,23 +1898,23 @@
     return n;
 }
 
-double PostDecLocalVarNode::evaluateToNumber(ExecState* exec)
+double PostDecLocalVarNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToNumber(exec);
 }
 
-bool PostDecLocalVarNode::evaluateToBoolean(ExecState* exec)
+bool PostDecLocalVarNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     double result = inlineEvaluateToNumber(exec);
     return  result > 0.0 || 0.0 > result; // NaN produces false as well
 }
 
-int32_t PostDecLocalVarNode::evaluateToInt32(ExecState* exec)
+int32_t PostDecLocalVarNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     return JSValue::toInt32(inlineEvaluateToNumber(exec));
 }
 
-uint32_t PostDecLocalVarNode::evaluateToUInt32(ExecState* exec)
+uint32_t PostDecLocalVarNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
 }
@@ -1690,13 +1926,23 @@
 
 // ------------------------------ PostfixBracketNode ----------------------------------
 
-void PostfixBracketNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+void PostfixBracketNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_subscript.get());
     nodeStack.append(m_base.get());
 }
 
-JSValue* PostIncBracketNode::evaluate(ExecState* exec)
+RegisterID* PostIncBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> base = generator.emitNode(m_base.get());
+    RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
+    RefPtr<RegisterID> value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
+    RegisterID* oldValue = generator.emitPostInc(generator.finalDestination(dst), value.get());
+    generator.emitPutByVal(base.get(), property.get(), value.get());
+    return oldValue;
+}
+
+JSValue* PostIncBracketNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* baseValue = m_base->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -1727,7 +1973,17 @@
     return v2;
 }
 
-JSValue* PostDecBracketNode::evaluate(ExecState* exec)
+RegisterID* PostDecBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> base = generator.emitNode(m_base.get());
+    RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
+    RefPtr<RegisterID> value = generator.emitGetByVal(generator.newTemporary(), base.get(), property.get());
+    RegisterID* oldValue = generator.emitPostDec(generator.finalDestination(dst), value.get());
+    generator.emitPutByVal(base.get(), property.get(), value.get());
+    return oldValue;
+}
+
+JSValue* PostDecBracketNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* baseValue = m_base->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -1759,12 +2015,21 @@
 
 // ------------------------------ PostfixDotNode ----------------------------------
 
-void PostfixDotNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+void PostfixDotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_base.get());
 }
 
-JSValue* PostIncDotNode::evaluate(ExecState* exec)
+RegisterID* PostIncDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> base = generator.emitNode(m_base.get());
+    RefPtr<RegisterID> value = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
+    RegisterID* oldValue = generator.emitPostInc(generator.finalDestination(dst), value.get());
+    generator.emitPutById(base.get(), m_ident, value.get());
+    return oldValue;
+}
+
+JSValue* PostIncDotNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* baseValue = m_base->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -1779,7 +2044,16 @@
     return v2;
 }
 
-JSValue* PostDecDotNode::evaluate(ExecState* exec)
+RegisterID* PostDecDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> base = generator.emitNode(m_base.get());
+    RefPtr<RegisterID> value = generator.emitGetById(generator.newTemporary(), base.get(), m_ident);
+    RegisterID* oldValue = generator.emitPostDec(generator.finalDestination(dst), value.get());
+    generator.emitPutById(base.get(), m_ident, value.get());
+    return oldValue;
+}
+
+JSValue* PostDecDotNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* baseValue = m_base->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -1796,7 +2070,12 @@
 
 // ------------------------------ PostfixErrorNode -----------------------------------
 
-JSValue* PostfixErrorNode::evaluate(ExecState* exec)
+RegisterID* PostfixErrorNode::emitCode(CodeGenerator& generator, RegisterID*)
+{
+    return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus ? "Postfix ++ operator applied to value that is not a reference." : "Postfix -- operator applied to value that is not a reference.");
+}
+
+JSValue* PostfixErrorNode::evaluate(OldInterpreterExecState* exec)
 {
     throwError(exec, ReferenceError, "Postfix %s operator applied to value that is not a reference.",
                m_operator == OpPlusPlus ? "++" : "--");
@@ -1806,16 +2085,25 @@
 
 // ------------------------------ DeleteResolveNode -----------------------------------
 
-void DeleteResolveNode::optimizeVariableAccess(ExecState*, const SymbolTable& symbolTable, const LocalStorage&, NodeStack&)
+RegisterID* DeleteResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 {
-    size_t index = symbolTable.get(m_ident.ustring().rep());
+    if (generator.registerForLocal(m_ident))
+        return generator.emitLoad(generator.finalDestination(dst), false);
+
+    RegisterID* base = generator.emitResolveBase(generator.tempDestination(dst), m_ident);
+    return generator.emitDeleteById(generator.finalDestination(dst, base), base, m_ident);
+}
+
+void DeleteResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage&, NodeStack&)
+{
+    int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
     if (index != missingSymbolMarker())
         new (this) LocalVarDeleteNode();
 }
 
 // ECMA 11.4.1
 
-JSValue* DeleteResolveNode::evaluate(ExecState* exec)
+JSValue* DeleteResolveNode::evaluate(OldInterpreterExecState* exec)
 {
     // Check for missed optimization opportunity.
     ASSERT(!canSkipLookup(exec, m_ident));
@@ -1840,20 +2128,27 @@
     return jsBoolean(true);
 }
 
-JSValue* LocalVarDeleteNode::evaluate(ExecState*)
+JSValue* LocalVarDeleteNode::evaluate(OldInterpreterExecState*)
 {
     return jsBoolean(false);
 }
 
 // ------------------------------ DeleteBracketNode -----------------------------------
 
-void DeleteBracketNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* DeleteBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> r0 = generator.emitNode(m_base.get());
+    RefPtr<RegisterID> r1 = generator.emitNode(m_subscript.get());
+    return generator.emitDeleteByVal(generator.finalDestination(dst), r0.get(), r1.get());
+}
+
+void DeleteBracketNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_subscript.get());
     nodeStack.append(m_base.get());
 }
 
-JSValue* DeleteBracketNode::evaluate(ExecState* exec)
+JSValue* DeleteBracketNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* baseValue = m_base->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -1872,12 +2167,18 @@
 
 // ------------------------------ DeleteDotNode -----------------------------------
 
-void DeleteDotNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* DeleteDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RegisterID* r0 = generator.emitNode(m_base.get());
+    return generator.emitDeleteById(generator.finalDestination(dst), r0, m_ident);
+}
+
+void DeleteDotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_base.get());
 }
 
-JSValue* DeleteDotNode::evaluate(ExecState* exec)
+JSValue* DeleteDotNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* baseValue = m_base->evaluate(exec);
     JSObject* base = baseValue->toObject(exec);
@@ -1888,12 +2189,20 @@
 
 // ------------------------------ DeleteValueNode -----------------------------------
 
-void DeleteValueNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* DeleteValueNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    generator.emitNode(m_expr.get());
+
+    // delete on a non-location expression ignores the value and returns true
+    return generator.emitLoad(generator.finalDestination(dst), true);
+}
+
+void DeleteValueNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_expr.get());
 }
 
-JSValue* DeleteValueNode::evaluate(ExecState* exec)
+JSValue* DeleteValueNode::evaluate(OldInterpreterExecState* exec)
 {
     m_expr->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -1904,13 +2213,19 @@
 
 // ------------------------------ VoidNode -------------------------------------
 
-void VoidNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* VoidNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
+    return generator.emitLoad(generator.finalDestination(dst, r0.get()), jsUndefined());
+}
+
+void VoidNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_expr.get());
 }
 
 // ECMA 11.4.2
-JSValue* VoidNode::evaluate(ExecState* exec)
+JSValue* VoidNode::evaluate(OldInterpreterExecState* exec)
 {
     m_expr->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -1922,7 +2237,7 @@
 
 // ------------------------------ TypeOfValueNode -----------------------------------
 
-void TypeOfValueNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+void TypeOfValueNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_expr.get());
 }
@@ -1955,21 +2270,31 @@
     }
 }
 
-void TypeOfResolveNode::optimizeVariableAccess(ExecState*, const SymbolTable& symbolTable, const LocalStorage&, NodeStack&)
+void TypeOfResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage&, NodeStack&)
 {
-    size_t index = symbolTable.get(m_ident.ustring().rep());
+    int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
     if (index != missingSymbolMarker())
         new (this) LocalVarTypeOfNode(index);
 }
 
-JSValue* LocalVarTypeOfNode::evaluate(ExecState* exec)
+JSValue* LocalVarTypeOfNode::evaluate(OldInterpreterExecState* exec)
 {
     ASSERT(exec->variableObject() == exec->scopeChain().top());
 
     return typeStringForValue(exec->localStorage()[m_index].value);
 }
 
-JSValue* TypeOfResolveNode::evaluate(ExecState* exec)
+RegisterID* TypeOfResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    if (RegisterID* local = generator.registerForLocal(m_ident))
+        return generator.emitTypeOf(generator.finalDestination(dst), local);
+
+    RefPtr<RegisterID> scratch = generator.emitResolveBase(generator.tempDestination(dst), m_ident);
+    generator.emitGetById(scratch.get(), scratch.get(), m_ident);
+    return generator.emitTypeOf(generator.finalDestination(dst, scratch.get()), scratch.get());
+}
+
+JSValue* TypeOfResolveNode::evaluate(OldInterpreterExecState* exec)
 {
     const ScopeChain& chain = exec->scopeChain();
     ScopeChainIterator iter = chain.begin();
@@ -1995,7 +2320,13 @@
 
 // ------------------------------ TypeOfValueNode -----------------------------------
 
-JSValue* TypeOfValueNode::evaluate(ExecState* exec)
+RegisterID* TypeOfValueNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> src = generator.emitNode(m_expr.get());
+    return generator.emitTypeOf(generator.finalDestination(dst), src.get());
+}
+
+JSValue* TypeOfValueNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* v = m_expr->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -2007,9 +2338,28 @@
 
 // ------------------------------ PrefixResolveNode ----------------------------------
 
-void PreIncResolveNode::optimizeVariableAccess(ExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
+RegisterID* PreIncResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 {
-    size_t index = symbolTable.get(m_ident.ustring().rep());
+    if (RegisterID* local = generator.registerForLocal(m_ident)) {
+        if (generator.isLocalConstant(m_ident)) {
+            RefPtr<RegisterID> r0 = generator.emitLoad(generator.finalDestination(dst), 1.0);
+            return generator.emitAdd(r0.get(), local, r0.get());
+        }
+        
+        generator.emitPreInc(local);
+        return generator.moveToDestinationIfNeeded(dst, local);
+    }
+    
+    RefPtr<RegisterID> propDst = generator.tempDestination(dst);
+    RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), propDst.get(), m_ident);
+    generator.emitPreInc(propDst.get());
+    generator.emitPutById(base.get(), m_ident, propDst.get());
+    return generator.moveToDestinationIfNeeded(dst, propDst.get());
+}
+
+void PreIncResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
+{
+    int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
     if (index != missingSymbolMarker()) {
         if (isConstant(localStorage, index))
             new (this) PreIncConstNode(index);
@@ -2018,7 +2368,7 @@
     }
 }
 
-JSValue* PreIncLocalVarNode::evaluate(ExecState* exec)
+JSValue* PreIncLocalVarNode::evaluate(OldInterpreterExecState* exec)
 {
     ASSERT(exec->variableObject() == exec->scopeChain().top());
     JSValue** slot = &exec->localStorage()[m_index].value;
@@ -2029,7 +2379,7 @@
     return n2;
 }
 
-JSValue* PreIncResolveNode::evaluate(ExecState* exec)
+JSValue* PreIncResolveNode::evaluate(OldInterpreterExecState* exec)
 {
     const ScopeChain& chain = exec->scopeChain();
     ScopeChainIterator iter = chain.begin();
@@ -2059,9 +2409,28 @@
     return throwUndefinedVariableError(exec, m_ident);
 }
 
-void PreDecResolveNode::optimizeVariableAccess(ExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
+RegisterID* PreDecResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
 {
-    size_t index = symbolTable.get(m_ident.ustring().rep());
+    if (RegisterID* local = generator.registerForLocal(m_ident)) {
+        if (generator.isLocalConstant(m_ident)) {
+            RefPtr<RegisterID> r0 = generator.emitLoad(generator.finalDestination(dst), -1.0);
+            return generator.emitAdd(r0.get(), local, r0.get());
+        }
+        
+        generator.emitPreDec(local);
+        return generator.moveToDestinationIfNeeded(dst, local);
+    }
+
+    RefPtr<RegisterID> propDst = generator.tempDestination(dst);
+    RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), propDst.get(), m_ident);
+    generator.emitPreDec(propDst.get());
+    generator.emitPutById(base.get(), m_ident, propDst.get());
+    return generator.moveToDestinationIfNeeded(dst, propDst.get());
+}
+
+void PreDecResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack&)
+{
+    int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
     if (index != missingSymbolMarker()) {
         if (isConstant(localStorage, index))
             new (this) PreDecConstNode(index);
@@ -2070,7 +2439,7 @@
     }
 }
 
-JSValue* PreDecLocalVarNode::evaluate(ExecState* exec)
+JSValue* PreDecLocalVarNode::evaluate(OldInterpreterExecState* exec)
 {
     ASSERT(exec->variableObject() == exec->scopeChain().top());
     JSValue** slot = &exec->localStorage()[m_index].value;
@@ -2081,7 +2450,7 @@
     return n2;
 }
 
-JSValue* PreDecResolveNode::evaluate(ExecState* exec)
+JSValue* PreDecResolveNode::evaluate(OldInterpreterExecState* exec)
 {
     const ScopeChain& chain = exec->scopeChain();
     ScopeChainIterator iter = chain.begin();
@@ -2113,7 +2482,7 @@
 
 // ------------------------------ PreIncConstNode ----------------------------------
 
-JSValue* PreIncConstNode::evaluate(ExecState* exec)
+JSValue* PreIncConstNode::evaluate(OldInterpreterExecState* exec)
 {
     ASSERT(exec->variableObject() == exec->scopeChain().top());
     return jsNumber(exec->localStorage()[m_index].value->toNumber(exec) + 1);
@@ -2121,7 +2490,7 @@
 
 // ------------------------------ PreDecConstNode ----------------------------------
 
-JSValue* PreDecConstNode::evaluate(ExecState* exec)
+JSValue* PreDecConstNode::evaluate(OldInterpreterExecState* exec)
 {
     ASSERT(exec->variableObject() == exec->scopeChain().top());
     return jsNumber(exec->localStorage()[m_index].value->toNumber(exec) - 1);
@@ -2129,7 +2498,7 @@
 
 // ------------------------------ PostIncConstNode ----------------------------------
 
-JSValue* PostIncConstNode::evaluate(ExecState* exec)
+JSValue* PostIncConstNode::evaluate(OldInterpreterExecState* exec)
 {
     ASSERT(exec->variableObject() == exec->scopeChain().top());
     return jsNumber(exec->localStorage()[m_index].value->toNumber(exec));
@@ -2137,7 +2506,7 @@
 
 // ------------------------------ PostDecConstNode ----------------------------------
 
-JSValue* PostDecConstNode::evaluate(ExecState* exec)
+JSValue* PostDecConstNode::evaluate(OldInterpreterExecState* exec)
 {
     ASSERT(exec->variableObject() == exec->scopeChain().top());
     return jsNumber(exec->localStorage()[m_index].value->toNumber(exec));
@@ -2145,13 +2514,24 @@
 
 // ------------------------------ PrefixBracketNode ----------------------------------
 
-void PrefixBracketNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+void PrefixBracketNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_subscript.get());
     nodeStack.append(m_base.get());
 }
 
-JSValue* PreIncBracketNode::evaluate(ExecState* exec)
+RegisterID* PreIncBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> base = generator.emitNode(m_base.get());
+    RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
+    RefPtr<RegisterID> propDst = generator.tempDestination(dst);
+    RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
+    generator.emitPreInc(value);
+    generator.emitPutByVal(base.get(), property.get(), value);
+    return generator.moveToDestinationIfNeeded(dst, propDst.get());
+}
+
+JSValue* PreIncBracketNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* baseValue = m_base->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -2183,7 +2563,19 @@
     return n2;
 }
 
-JSValue* PreDecBracketNode::evaluate(ExecState* exec)
+RegisterID* PreDecBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    
+    RefPtr<RegisterID> base = generator.emitNode(m_base.get());
+    RefPtr<RegisterID> property = generator.emitNode(m_subscript.get());
+    RefPtr<RegisterID> propDst = generator.tempDestination(dst);
+    RegisterID* value = generator.emitGetByVal(propDst.get(), base.get(), property.get());
+    generator.emitPreDec(value);
+    generator.emitPutByVal(base.get(), property.get(), value);
+    return generator.moveToDestinationIfNeeded(dst, propDst.get());
+}
+
+JSValue* PreDecBracketNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* baseValue = m_base->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -2217,12 +2609,22 @@
 
 // ------------------------------ PrefixDotNode ----------------------------------
 
-void PrefixDotNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+void PrefixDotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_base.get());
 }
 
-JSValue* PreIncDotNode::evaluate(ExecState* exec)
+RegisterID* PreIncDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> base = generator.emitNode(m_base.get());
+    RefPtr<RegisterID> propDst = generator.tempDestination(dst);
+    RegisterID* value = generator.emitGetById(propDst.get(), base.get(), m_ident);
+    generator.emitPreInc(value);
+    generator.emitPutById(base.get(), m_ident, value);
+    return generator.moveToDestinationIfNeeded(dst, propDst.get());
+}
+
+JSValue* PreIncDotNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* baseValue = m_base->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -2239,7 +2641,17 @@
     return n2;
 }
 
-JSValue* PreDecDotNode::evaluate(ExecState* exec)
+RegisterID* PreDecDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> base = generator.emitNode(m_base.get());
+    RefPtr<RegisterID> propDst = generator.tempDestination(dst);
+    RegisterID* value = generator.emitGetById(propDst.get(), base.get(), m_ident);
+    generator.emitPreDec(value);
+    generator.emitPutById(base.get(), m_ident, value);
+    return generator.moveToDestinationIfNeeded(dst, propDst.get());
+}
+
+JSValue* PreDecDotNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* baseValue = m_base->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -2258,7 +2670,12 @@
 
 // ------------------------------ PrefixErrorNode -----------------------------------
 
-JSValue* PrefixErrorNode::evaluate(ExecState* exec)
+RegisterID* PrefixErrorNode::emitCode(CodeGenerator& generator, RegisterID*)
+{
+    return emitThrowError(generator, ReferenceError, m_operator == OpPlusPlus ? "Prefix ++ operator applied to value that is not a reference." : "Prefix -- operator applied to value that is not a reference.");
+}
+
+JSValue* PrefixErrorNode::evaluate(OldInterpreterExecState* exec)
 {
     throwError(exec, ReferenceError, "Prefix %s operator applied to value that is not a reference.",
                m_operator == OpPlusPlus ? "++" : "--");
@@ -2268,54 +2685,66 @@
 
 // ------------------------------ UnaryPlusNode --------------------------------
 
-void UnaryPlusNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* UnaryPlusNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RegisterID* src = generator.emitNode(m_expr.get());
+    return generator.emitToJSNumber(generator.finalDestination(dst), src);
+}
+
+void UnaryPlusNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_expr.get());
 }
 
 // ECMA 11.4.6
-JSValue* UnaryPlusNode::evaluate(ExecState* exec)
+JSValue* UnaryPlusNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* v = m_expr->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
     return v->toJSNumber(exec);
 }
 
-bool UnaryPlusNode::evaluateToBoolean(ExecState* exec)
+bool UnaryPlusNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     return m_expr->evaluateToBoolean(exec);
 }
 
-double UnaryPlusNode::evaluateToNumber(ExecState* exec)
+double UnaryPlusNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     return m_expr->evaluateToNumber(exec);
 }
 
-int32_t UnaryPlusNode::evaluateToInt32(ExecState* exec)
+int32_t UnaryPlusNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     return m_expr->evaluateToInt32(exec);
 }
 
-uint32_t UnaryPlusNode::evaluateToUInt32(ExecState* exec)
+uint32_t UnaryPlusNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     return m_expr->evaluateToInt32(exec);
 }
 
 // ------------------------------ NegateNode -----------------------------------
 
-void NegateNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* NegateNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RegisterID* src = generator.emitNode(m_expr.get());
+    return generator.emitNegate(generator.finalDestination(dst), src);
+}
+
+void NegateNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_expr.get());
 }
 
 // ECMA 11.4.7
-JSValue* NegateNode::evaluate(ExecState* exec)
+JSValue* NegateNode::evaluate(OldInterpreterExecState* exec)
 {
     // No need to check exception, caller will do so right after evaluate()
     return jsNumber(-m_expr->evaluateToNumber(exec));
 }
 
-double NegateNode::evaluateToNumber(ExecState* exec)
+double NegateNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     // No need to check exception, caller will do so right after evaluateToNumber()
     return -m_expr->evaluateToNumber(exec);
@@ -2323,70 +2752,89 @@
 
 // ------------------------------ BitwiseNotNode -------------------------------
 
-void BitwiseNotNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* BitwiseNotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RegisterID* src = generator.emitNode(m_expr.get());
+    return generator.emitBitNot(generator.finalDestination(dst), src);
+}
+
+void BitwiseNotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_expr.get());
 }
 
 // ECMA 11.4.8
-int32_t BitwiseNotNode::inlineEvaluateToInt32(ExecState* exec)
+int32_t BitwiseNotNode::inlineEvaluateToInt32(OldInterpreterExecState* exec)
 {
     return ~m_expr->evaluateToInt32(exec);
 }
 
-JSValue* BitwiseNotNode::evaluate(ExecState* exec)
+JSValue* BitwiseNotNode::evaluate(OldInterpreterExecState* exec)
 {
     return jsNumber(inlineEvaluateToInt32(exec));
 }
 
-double BitwiseNotNode::evaluateToNumber(ExecState* exec)
+double BitwiseNotNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToInt32(exec);
 }
 
-bool BitwiseNotNode::evaluateToBoolean(ExecState* exec)
+bool BitwiseNotNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToInt32(exec);
 }
 
-int32_t BitwiseNotNode::evaluateToInt32(ExecState* exec)
+int32_t BitwiseNotNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToInt32(exec);
 }
 
-uint32_t BitwiseNotNode::evaluateToUInt32(ExecState* exec)
+uint32_t BitwiseNotNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToInt32(exec);
 }
 
 // ------------------------------ LogicalNotNode -------------------------------
 
-void LogicalNotNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* LogicalNotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RegisterID* src = generator.emitNode(m_expr.get());
+    return generator.emitNot(generator.finalDestination(dst), src);
+}
+
+void LogicalNotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_expr.get());
 }
 
 // ECMA 11.4.9
-JSValue* LogicalNotNode::evaluate(ExecState* exec)
+JSValue* LogicalNotNode::evaluate(OldInterpreterExecState* exec)
 {
     return jsBoolean(!m_expr->evaluateToBoolean(exec));
 }
 
-bool LogicalNotNode::evaluateToBoolean(ExecState* exec)
+bool LogicalNotNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     return !m_expr->evaluateToBoolean(exec);
 }
 
 // ------------------------------ Multiplicative Nodes -----------------------------------
 
-void MultNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* MultNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> src1 = generator.emitNode(m_term1.get());
+    RegisterID* src2 = generator.emitNode(m_term2.get());
+    return generator.emitMul(generator.finalDestination(dst, src1.get()), src1.get(), src2);
+}
+
+void MultNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_term1.get());
     nodeStack.append(m_term2.get());
 }
 
 // ECMA 11.5.1
-double MultNode::inlineEvaluateToNumber(ExecState* exec)
+double MultNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
 {
     double n1 = m_term1->evaluateToNumber(exec);
     KJS_CHECKEXCEPTIONNUMBER
@@ -2394,40 +2842,47 @@
     return n1 * n2;
 }
 
-JSValue* MultNode::evaluate(ExecState* exec)
+JSValue* MultNode::evaluate(OldInterpreterExecState* exec)
 {
     return jsNumber(inlineEvaluateToNumber(exec));
 }
 
-double MultNode::evaluateToNumber(ExecState* exec)
+double MultNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToNumber(exec);
 }
 
-bool MultNode::evaluateToBoolean(ExecState* exec)
+bool MultNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     double result = inlineEvaluateToNumber(exec);
     return  result > 0.0 || 0.0 > result; // NaN produces false as well
 }
 
-int32_t MultNode::evaluateToInt32(ExecState* exec)
+int32_t MultNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     return JSValue::toInt32(inlineEvaluateToNumber(exec));
 }
 
-uint32_t MultNode::evaluateToUInt32(ExecState* exec)
+uint32_t MultNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
 }
 
-void DivNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* DivNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> dividend = generator.emitNode(m_term1.get());
+    RegisterID* divisor = generator.emitNode(m_term2.get());
+    return generator.emitDiv(generator.finalDestination(dst, dividend.get()), dividend.get(), divisor);
+}
+
+void DivNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_term1.get());
     nodeStack.append(m_term2.get());
 }
 
 // ECMA 11.5.2
-double DivNode::inlineEvaluateToNumber(ExecState* exec)
+double DivNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
 {
     double n1 = m_term1->evaluateToNumber(exec);
     KJS_CHECKEXCEPTIONNUMBER
@@ -2435,34 +2890,41 @@
     return n1 / n2;
 }
 
-JSValue* DivNode::evaluate(ExecState* exec)
+JSValue* DivNode::evaluate(OldInterpreterExecState* exec)
 {
     return jsNumber(inlineEvaluateToNumber(exec));
 }
 
-double DivNode::evaluateToNumber(ExecState* exec)
+double DivNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToNumber(exec);
 }
 
-int32_t DivNode::evaluateToInt32(ExecState* exec)
+int32_t DivNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     return JSValue::toInt32(inlineEvaluateToNumber(exec));
 }
 
-uint32_t DivNode::evaluateToUInt32(ExecState* exec)
+uint32_t DivNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
 }
 
-void ModNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* ModNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> dividend = generator.emitNode(m_term1.get());
+    RegisterID* divisor = generator.emitNode(m_term2.get());
+    return generator.emitMod(generator.finalDestination(dst, dividend.get()), dividend.get(), divisor);
+}
+
+void ModNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_term1.get());
     nodeStack.append(m_term2.get());
 }
 
 // ECMA 11.5.3
-double ModNode::inlineEvaluateToNumber(ExecState* exec)
+double ModNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
 {
     double n1 = m_term1->evaluateToNumber(exec);
     KJS_CHECKEXCEPTIONNUMBER
@@ -2470,42 +2932,35 @@
     return fmod(n1, n2);
 }
 
-JSValue* ModNode::evaluate(ExecState* exec)
+JSValue* ModNode::evaluate(OldInterpreterExecState* exec)
 {
     return jsNumber(inlineEvaluateToNumber(exec));
 }
 
-double ModNode::evaluateToNumber(ExecState* exec)
+double ModNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToNumber(exec);
 }
 
-bool ModNode::evaluateToBoolean(ExecState* exec)
+bool ModNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     double result = inlineEvaluateToNumber(exec);
     return  result > 0.0 || 0.0 > result; // NaN produces false as well
 }
 
-int32_t ModNode::evaluateToInt32(ExecState* exec)
+int32_t ModNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     return JSValue::toInt32(inlineEvaluateToNumber(exec));
 }
 
-uint32_t ModNode::evaluateToUInt32(ExecState* exec)
+uint32_t ModNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
 }
 
 // ------------------------------ Additive Nodes --------------------------------------
 
-static JSValue* throwOutOfMemoryError(ExecState* exec)
-{
-    JSObject* error = Error::create(exec, GeneralError, "Out of memory");
-    exec->setException(error);
-    return error;
-}
-
-static double throwOutOfMemoryErrorToNumber(ExecState* exec)
+static double throwOutOfMemoryErrorToNumber(OldInterpreterExecState* exec)
 {
     JSObject* error = Error::create(exec, GeneralError, "Out of memory");
     exec->setException(error);
@@ -2513,7 +2968,7 @@
 }
 
 // ECMA 11.6
-static JSValue* addSlowCase(ExecState* exec, JSValue* v1, JSValue* v2)
+static JSValue* addSlowCase(OldInterpreterExecState* exec, JSValue* v1, JSValue* v2)
 {
     // exception for the Date exception in defaultValue()
     JSValue* p1 = v1->toPrimitive(exec, UnspecifiedType);
@@ -2529,7 +2984,7 @@
     return jsNumber(p1->toNumber(exec) + p2->toNumber(exec));
 }
 
-static double addSlowCaseToNumber(ExecState* exec, JSValue* v1, JSValue* v2)
+static double addSlowCaseToNumber(OldInterpreterExecState* exec, JSValue* v1, JSValue* v2)
 {
     // exception for the Date exception in defaultValue()
     JSValue* p1 = v1->toPrimitive(exec, UnspecifiedType);
@@ -2555,7 +3010,7 @@
 //    4000    Add case: 1 5
 //    1       Add case: 3 5
 
-static inline JSValue* add(ExecState* exec, JSValue* v1, JSValue* v2)
+static inline JSValue* add(OldInterpreterExecState* exec, JSValue* v1, JSValue* v2)
 {
     JSType t1 = v1->type();
     JSType t2 = v2->type();
@@ -2574,7 +3029,7 @@
     return addSlowCase(exec, v1, v2);
 }
 
-static inline double addToNumber(ExecState* exec, JSValue* v1, JSValue* v2)
+static inline double addToNumber(OldInterpreterExecState* exec, JSValue* v1, JSValue* v2)
 {
     JSType t1 = v1->type();
     JSType t2 = v2->type();
@@ -2593,14 +3048,21 @@
     return addSlowCaseToNumber(exec, v1, v2);
 }
 
-void AddNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* AddNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> src1 = generator.emitNode(m_term1.get());
+    RegisterID* src2 = generator.emitNode(m_term2.get());
+    return generator.emitAdd(generator.finalDestination(dst, src1.get()), src1.get(), src2);
+}
+
+void AddNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_term1.get());
     nodeStack.append(m_term2.get());
 }
 
 // ECMA 11.6.1
-JSValue* AddNode::evaluate(ExecState* exec)
+JSValue* AddNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* v1 = m_term1->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -2611,7 +3073,7 @@
     return add(exec, v1, v2);
 }
 
-double AddNode::inlineEvaluateToNumber(ExecState* exec)
+double AddNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
 {
     JSValue* v1 = m_term1->evaluate(exec);
     KJS_CHECKEXCEPTIONNUMBER
@@ -2622,22 +3084,22 @@
     return addToNumber(exec, v1, v2);
 }
 
-double AddNode::evaluateToNumber(ExecState* exec)
+double AddNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToNumber(exec);
 }
 
-int32_t AddNode::evaluateToInt32(ExecState* exec)
+int32_t AddNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     return JSValue::toInt32(inlineEvaluateToNumber(exec));
 }
 
-uint32_t AddNode::evaluateToUInt32(ExecState* exec)
+uint32_t AddNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
 }
 
-double AddNumbersNode::inlineEvaluateToNumber(ExecState* exec)
+double AddNumbersNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
 {
     double n1 = m_term1->evaluateToNumber(exec);
     KJS_CHECKEXCEPTIONNUMBER
@@ -2645,27 +3107,27 @@
     return n1 + n2;
 }
 
-JSValue* AddNumbersNode::evaluate(ExecState* exec)
+JSValue* AddNumbersNode::evaluate(OldInterpreterExecState* exec)
 {
     return jsNumber(inlineEvaluateToNumber(exec));
 }
 
-double AddNumbersNode::evaluateToNumber(ExecState* exec)
+double AddNumbersNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToNumber(exec);
 }
 
-int32_t AddNumbersNode::evaluateToInt32(ExecState* exec)
+int32_t AddNumbersNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     return JSValue::toInt32(inlineEvaluateToNumber(exec));
 }
 
-uint32_t AddNumbersNode::evaluateToUInt32(ExecState* exec)
+uint32_t AddNumbersNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
 }
 
-JSValue* AddStringsNode::evaluate(ExecState* exec)
+JSValue* AddStringsNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* v1 = m_term1->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -2676,7 +3138,7 @@
     return jsString(static_cast<StringImp*>(v1)->value() + static_cast<StringImp*>(v2)->value());
 }
 
-JSValue* AddStringLeftNode::evaluate(ExecState* exec)
+JSValue* AddStringLeftNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* v1 = m_term1->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -2688,7 +3150,7 @@
     return jsString(static_cast<StringImp*>(v1)->value() + p2->toString(exec));
 }
 
-JSValue* AddStringRightNode::evaluate(ExecState* exec)
+JSValue* AddStringRightNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* v1 = m_term1->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -2700,14 +3162,21 @@
     return jsString(p1->toString(exec) + static_cast<StringImp*>(v2)->value());
 }
 
-void SubNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* SubNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> src1 = generator.emitNode(m_term1.get());
+    RegisterID* src2 = generator.emitNode(m_term2.get());
+    return generator.emitSub(generator.finalDestination(dst, src1.get()), src1.get(), src2);
+}
+
+void SubNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_term1.get());
     nodeStack.append(m_term2.get());
 }
 
 // ECMA 11.6.2
-double SubNode::inlineEvaluateToNumber(ExecState* exec)
+double SubNode::inlineEvaluateToNumber(OldInterpreterExecState* exec)
 {
     double n1 = m_term1->evaluateToNumber(exec);
     KJS_CHECKEXCEPTIONNUMBER
@@ -2715,36 +3184,43 @@
     return n1 - n2;
 }
 
-JSValue* SubNode::evaluate(ExecState* exec)
+JSValue* SubNode::evaluate(OldInterpreterExecState* exec)
 {
     return jsNumber(inlineEvaluateToNumber(exec));
 }
 
-double SubNode::evaluateToNumber(ExecState* exec)
+double SubNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToNumber(exec);
 }
 
-int32_t SubNode::evaluateToInt32(ExecState* exec)
+int32_t SubNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     return JSValue::toInt32(inlineEvaluateToNumber(exec));
 }
 
-uint32_t SubNode::evaluateToUInt32(ExecState* exec)
+uint32_t SubNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     return JSValue::toUInt32(inlineEvaluateToNumber(exec));
 }
 
 // ------------------------------ Shift Nodes ------------------------------------
 
-void LeftShiftNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* LeftShiftNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> val = generator.emitNode(m_term1.get());
+    RegisterID* shift = generator.emitNode(m_term2.get());
+    return generator.emitLeftShift(generator.finalDestination(dst, val.get()), val.get(), shift);
+}
+
+void LeftShiftNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_term1.get());
     nodeStack.append(m_term2.get());
 }
 
 // ECMA 11.7.1
-int32_t LeftShiftNode::inlineEvaluateToInt32(ExecState* exec)
+int32_t LeftShiftNode::inlineEvaluateToInt32(OldInterpreterExecState* exec)
 {
     int i1 = m_term1->evaluateToInt32(exec);
     KJS_CHECKEXCEPTIONNUMBER
@@ -2752,34 +3228,41 @@
     return (i1 << i2);
 }
 
-JSValue* LeftShiftNode::evaluate(ExecState* exec)
+JSValue* LeftShiftNode::evaluate(OldInterpreterExecState* exec)
 {
     return jsNumber(inlineEvaluateToInt32(exec));
 }
 
-double LeftShiftNode::evaluateToNumber(ExecState* exec)
+double LeftShiftNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToInt32(exec);
 }
 
-int32_t LeftShiftNode::evaluateToInt32(ExecState* exec)
+int32_t LeftShiftNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToInt32(exec);
 }
 
-uint32_t LeftShiftNode::evaluateToUInt32(ExecState* exec)
+uint32_t LeftShiftNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToInt32(exec);
 }
 
-void RightShiftNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* RightShiftNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> val = generator.emitNode(m_term1.get());
+    RegisterID* shift = generator.emitNode(m_term2.get());
+    return generator.emitRightShift(generator.finalDestination(dst, val.get()), val.get(), shift);
+}
+
+void RightShiftNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_term1.get());
     nodeStack.append(m_term2.get());
 }
 
 // ECMA 11.7.2
-int32_t RightShiftNode::inlineEvaluateToInt32(ExecState* exec)
+int32_t RightShiftNode::inlineEvaluateToInt32(OldInterpreterExecState* exec)
 {
     int i1 = m_term1->evaluateToInt32(exec);
     KJS_CHECKEXCEPTIONNUMBER
@@ -2787,34 +3270,41 @@
     return (i1 >> i2);
 }
 
-JSValue* RightShiftNode::evaluate(ExecState* exec)
+JSValue* RightShiftNode::evaluate(OldInterpreterExecState* exec)
 {
     return jsNumber(inlineEvaluateToInt32(exec));
 }
 
-double RightShiftNode::evaluateToNumber(ExecState* exec)
+double RightShiftNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToInt32(exec);
 }
 
-int32_t RightShiftNode::evaluateToInt32(ExecState* exec)
+int32_t RightShiftNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToInt32(exec);
 }
 
-uint32_t RightShiftNode::evaluateToUInt32(ExecState* exec)
+uint32_t RightShiftNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToInt32(exec);
 }
 
-void UnsignedRightShiftNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* UnsignedRightShiftNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> val = generator.emitNode(m_term1.get());
+    RegisterID* shift = generator.emitNode(m_term2.get());
+    return generator.emitUnsignedRightShift(generator.finalDestination(dst, val.get()), val.get(), shift);
+}
+
+void UnsignedRightShiftNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_term1.get());
     nodeStack.append(m_term2.get());
 }
 
 // ECMA 11.7.3
-uint32_t UnsignedRightShiftNode::inlineEvaluateToUInt32(ExecState* exec)
+uint32_t UnsignedRightShiftNode::inlineEvaluateToUInt32(OldInterpreterExecState* exec)
 {
     unsigned int i1 = m_term1->evaluateToUInt32(exec);
     KJS_CHECKEXCEPTIONNUMBER
@@ -2822,29 +3312,29 @@
     return (i1 >> i2);
 }
 
-JSValue* UnsignedRightShiftNode::evaluate(ExecState* exec)
+JSValue* UnsignedRightShiftNode::evaluate(OldInterpreterExecState* exec)
 {
     return jsNumber(inlineEvaluateToUInt32(exec));
 }
 
-double UnsignedRightShiftNode::evaluateToNumber(ExecState* exec)
+double UnsignedRightShiftNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToUInt32(exec);
 }
 
-int32_t UnsignedRightShiftNode::evaluateToInt32(ExecState* exec)
+int32_t UnsignedRightShiftNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToUInt32(exec);
 }
 
-uint32_t UnsignedRightShiftNode::evaluateToUInt32(ExecState* exec)
+uint32_t UnsignedRightShiftNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToUInt32(exec);
 }
 
 // ------------------------------ Relational Nodes -------------------------------
 
-static inline bool lessThan(ExecState* exec, JSValue* v1, JSValue* v2)
+static inline bool lessThan(OldInterpreterExecState* exec, JSValue* v1, JSValue* v2)
 {
     double n1;
     double n2;
@@ -2859,7 +3349,7 @@
     return static_cast<const StringImp*>(p1)->value() < static_cast<const StringImp*>(p2)->value();
 }
 
-static inline bool lessThanEq(ExecState* exec, JSValue* v1, JSValue* v2)
+static inline bool lessThanEq(OldInterpreterExecState* exec, JSValue* v1, JSValue* v2)
 {
     double n1;
     double n2;
@@ -2874,14 +3364,21 @@
     return !(static_cast<const StringImp*>(p2)->value() < static_cast<const StringImp*>(p1)->value());
 }
 
-void LessNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* LessNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
+    RegisterID* src2 = generator.emitNode(m_expr2.get());
+    return generator.emitLess(generator.finalDestination(dst, src1.get()), src1.get(), src2);
+}
+
+void LessNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_expr2.get());
     nodeStack.append(m_expr1.get());
 }
 
 // ECMA 11.8.1
-bool LessNode::inlineEvaluateToBoolean(ExecState* exec)
+bool LessNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
 {
     JSValue* v1 = m_expr1->evaluate(exec);
     KJS_CHECKEXCEPTIONBOOLEAN
@@ -2890,17 +3387,17 @@
     return lessThan(exec, v1, v2);
 }
 
-JSValue* LessNode::evaluate(ExecState* exec)
+JSValue* LessNode::evaluate(OldInterpreterExecState* exec)
 {
     return jsBoolean(inlineEvaluateToBoolean(exec));
 }
 
-bool LessNode::evaluateToBoolean(ExecState* exec)
+bool LessNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToBoolean(exec);
 }
 
-bool LessNumbersNode::inlineEvaluateToBoolean(ExecState* exec)
+bool LessNumbersNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
 {
     double n1 = m_expr1->evaluateToNumber(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -2908,17 +3405,17 @@
     return n1 < n2;
 }
 
-JSValue* LessNumbersNode::evaluate(ExecState* exec)
+JSValue* LessNumbersNode::evaluate(OldInterpreterExecState* exec)
 {
     return jsBoolean(inlineEvaluateToBoolean(exec));
 }
 
-bool LessNumbersNode::evaluateToBoolean(ExecState* exec)
+bool LessNumbersNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToBoolean(exec);
 }
 
-bool LessStringsNode::inlineEvaluateToBoolean(ExecState* exec)
+bool LessStringsNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
 {
     JSValue* v1 = m_expr1->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -2926,24 +3423,31 @@
     return static_cast<StringImp*>(v1)->value() < static_cast<StringImp*>(v2)->value();
 }
 
-JSValue* LessStringsNode::evaluate(ExecState* exec)
+JSValue* LessStringsNode::evaluate(OldInterpreterExecState* exec)
 {
     return jsBoolean(inlineEvaluateToBoolean(exec));
 }
 
-bool LessStringsNode::evaluateToBoolean(ExecState* exec)
+bool LessStringsNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToBoolean(exec);
 }
 
-void GreaterNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* GreaterNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> src1 = generator.emitNode(m_expr2.get());
+    RegisterID* src2 = generator.emitNode(m_expr1.get());
+    return generator.emitLess(generator.finalDestination(dst, src1.get()), src1.get(), src2);
+}
+
+void GreaterNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_expr2.get());
     nodeStack.append(m_expr1.get());
 }
 
 // ECMA 11.8.2
-bool GreaterNode::inlineEvaluateToBoolean(ExecState* exec)
+bool GreaterNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
 {
     JSValue* v1 = m_expr1->evaluate(exec);
     KJS_CHECKEXCEPTIONBOOLEAN
@@ -2952,24 +3456,31 @@
     return lessThan(exec, v2, v1);
 }
 
-JSValue* GreaterNode::evaluate(ExecState* exec)
+JSValue* GreaterNode::evaluate(OldInterpreterExecState* exec)
 {
     return jsBoolean(inlineEvaluateToBoolean(exec));
 }
 
-bool GreaterNode::evaluateToBoolean(ExecState* exec)
+bool GreaterNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToBoolean(exec);
 }
 
-void LessEqNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* LessEqNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
+    RegisterID* src2 = generator.emitNode(m_expr2.get());
+    return generator.emitLessEq(generator.finalDestination(dst, src1.get()), src1.get(), src2);
+}
+
+void LessEqNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_expr2.get());
     nodeStack.append(m_expr1.get());
 }
 
 // ECMA 11.8.3
-bool LessEqNode::inlineEvaluateToBoolean(ExecState* exec)
+bool LessEqNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
 {
     JSValue* v1 = m_expr1->evaluate(exec);
     KJS_CHECKEXCEPTIONBOOLEAN
@@ -2978,24 +3489,31 @@
     return lessThanEq(exec, v1, v2);
 }
 
-JSValue* LessEqNode::evaluate(ExecState* exec)
+JSValue* LessEqNode::evaluate(OldInterpreterExecState* exec)
 {
     return jsBoolean(inlineEvaluateToBoolean(exec));
 }
 
-bool LessEqNode::evaluateToBoolean(ExecState* exec)
+bool LessEqNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToBoolean(exec);
 }
 
-void GreaterEqNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* GreaterEqNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> src1 = generator.emitNode(m_expr2.get());
+    RegisterID* src2 = generator.emitNode(m_expr1.get());
+    return generator.emitLessEq(generator.finalDestination(dst, src1.get()), src1.get(), src2);
+}
+
+void GreaterEqNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_expr2.get());
     nodeStack.append(m_expr1.get());
 }
 
 // ECMA 11.8.4
-bool GreaterEqNode::inlineEvaluateToBoolean(ExecState* exec)
+bool GreaterEqNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
 {
     JSValue* v1 = m_expr1->evaluate(exec);
     KJS_CHECKEXCEPTIONBOOLEAN
@@ -3004,24 +3522,31 @@
     return lessThanEq(exec, v2, v1);
 }
 
-JSValue* GreaterEqNode::evaluate(ExecState* exec)
+JSValue* GreaterEqNode::evaluate(OldInterpreterExecState* exec)
 {
     return jsBoolean(inlineEvaluateToBoolean(exec));
 }
 
-bool GreaterEqNode::evaluateToBoolean(ExecState* exec)
+bool GreaterEqNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToBoolean(exec);
 }
 
-void InstanceOfNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* InstanceOfNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> value = generator.emitNode(m_expr1.get());
+    RegisterID* base = generator.emitNode(m_expr2.get());
+    return generator.emitInstanceOf(generator.finalDestination(dst, value.get()), value.get(), base);
+}
+
+void InstanceOfNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_expr2.get());
     nodeStack.append(m_expr1.get());
 }
 
 // ECMA 11.8.6
-JSValue* InstanceOfNode::evaluate(ExecState* exec)
+JSValue* InstanceOfNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* v1 = m_expr1->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -3043,7 +3568,7 @@
     return jsBoolean(o2->hasInstance(exec, v1));
 }
 
-bool InstanceOfNode::evaluateToBoolean(ExecState* exec)
+bool InstanceOfNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     JSValue* v1 = m_expr1->evaluate(exec);
     KJS_CHECKEXCEPTIONBOOLEAN
@@ -3067,14 +3592,21 @@
     return o2->hasInstance(exec, v1);
 }
 
-void InNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* InNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> property = generator.emitNode(m_expr1.get());
+    RegisterID* base = generator.emitNode(m_expr2.get());
+    return generator.emitIn(generator.finalDestination(dst, property.get()), property.get(), base);
+}
+
+void InNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_expr2.get());
     nodeStack.append(m_expr1.get());
 }
 
 // ECMA 11.8.7
-JSValue* InNode::evaluate(ExecState* exec)
+JSValue* InNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* v1 = m_expr1->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -3087,7 +3619,7 @@
     return jsBoolean(static_cast<JSObject*>(v2)->hasProperty(exec, Identifier(v1->toString(exec))));
 }
 
-bool InNode::evaluateToBoolean(ExecState* exec)
+bool InNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     JSValue* v1 = m_expr1->evaluate(exec);
     KJS_CHECKEXCEPTIONBOOLEAN
@@ -3104,14 +3636,21 @@
 
 // ------------------------------ Equality Nodes ------------------------------------
 
-void EqualNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* EqualNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
+    RegisterID* src2 = generator.emitNode(m_expr2.get());
+    return generator.emitEqual(generator.finalDestination(dst, src1.get()), src1.get(), src2);
+}
+
+void EqualNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_expr2.get());
     nodeStack.append(m_expr1.get());
 }
 
 // ECMA 11.9.1
-bool EqualNode::inlineEvaluateToBoolean(ExecState* exec)
+bool EqualNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
 {
     JSValue* v1 = m_expr1->evaluate(exec);
     KJS_CHECKEXCEPTIONBOOLEAN
@@ -3121,24 +3660,31 @@
     return equal(exec, v1, v2);
 }
 
-JSValue* EqualNode::evaluate(ExecState* exec)
+JSValue* EqualNode::evaluate(OldInterpreterExecState* exec)
 {
     return jsBoolean(inlineEvaluateToBoolean(exec));
 }
 
-bool EqualNode::evaluateToBoolean(ExecState* exec)
+bool EqualNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToBoolean(exec);
 }
 
-void NotEqualNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* NotEqualNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
+    RegisterID* src2 = generator.emitNode(m_expr2.get());
+    return generator.emitNotEqual(generator.finalDestination(dst, src1.get()), src1.get(), src2);
+}
+
+void NotEqualNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_expr2.get());
     nodeStack.append(m_expr1.get());
 }
 
 // ECMA 11.9.2
-bool NotEqualNode::inlineEvaluateToBoolean(ExecState* exec)
+bool NotEqualNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
 {
     JSValue* v1 = m_expr1->evaluate(exec);
     KJS_CHECKEXCEPTIONBOOLEAN
@@ -3148,80 +3694,101 @@
     return !equal(exec,v1, v2);
 }
 
-JSValue* NotEqualNode::evaluate(ExecState* exec)
+JSValue* NotEqualNode::evaluate(OldInterpreterExecState* exec)
 {
     return jsBoolean(inlineEvaluateToBoolean(exec));
 }
 
-bool NotEqualNode::evaluateToBoolean(ExecState* exec)
+bool NotEqualNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToBoolean(exec);
 }
 
-void StrictEqualNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* StrictEqualNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
+    RegisterID* src2 = generator.emitNode(m_expr2.get());
+    return generator.emitStrictEqual(generator.finalDestination(dst, src1.get()), src1.get(), src2);
+}
+
+void StrictEqualNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_expr2.get());
     nodeStack.append(m_expr1.get());
 }
 
 // ECMA 11.9.4
-bool StrictEqualNode::inlineEvaluateToBoolean(ExecState* exec)
+bool StrictEqualNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
 {
     JSValue* v1 = m_expr1->evaluate(exec);
     KJS_CHECKEXCEPTIONBOOLEAN
     JSValue* v2 = m_expr2->evaluate(exec);
     KJS_CHECKEXCEPTIONBOOLEAN
 
-    return strictEqual(exec,v1, v2);
+    return strictEqual(v1, v2);
 }
 
-JSValue* StrictEqualNode::evaluate(ExecState* exec)
+JSValue* StrictEqualNode::evaluate(OldInterpreterExecState* exec)
 {
     return jsBoolean(inlineEvaluateToBoolean(exec));
 }
 
-bool StrictEqualNode::evaluateToBoolean(ExecState* exec)
+bool StrictEqualNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToBoolean(exec);
 }
 
-void NotStrictEqualNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* NotStrictEqualNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
+    RegisterID* src2 = generator.emitNode(m_expr2.get());
+    return generator.emitNotStrictEqual(generator.finalDestination(dst, src1.get()), src1.get(), src2);
+}
+
+void NotStrictEqualNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_expr2.get());
     nodeStack.append(m_expr1.get());
 }
 
 // ECMA 11.9.5
-bool NotStrictEqualNode::inlineEvaluateToBoolean(ExecState* exec)
+bool NotStrictEqualNode::inlineEvaluateToBoolean(OldInterpreterExecState* exec)
 {
     JSValue* v1 = m_expr1->evaluate(exec);
     KJS_CHECKEXCEPTIONBOOLEAN
     JSValue* v2 = m_expr2->evaluate(exec);
     KJS_CHECKEXCEPTIONBOOLEAN
 
-    return !strictEqual(exec,v1, v2);
+    return !strictEqual(v1, v2);
 }
 
-JSValue* NotStrictEqualNode::evaluate(ExecState* exec)
+JSValue* NotStrictEqualNode::evaluate(OldInterpreterExecState* exec)
 {
     return jsBoolean(inlineEvaluateToBoolean(exec));
 }
 
-bool NotStrictEqualNode::evaluateToBoolean(ExecState* exec)
+bool NotStrictEqualNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToBoolean(exec);
 }
 
 // ------------------------------ Bit Operation Nodes ----------------------------------
 
-void BitAndNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* BitAndNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
+    RegisterID* src2 = generator.emitNode(m_expr2.get());
+    return generator.emitBitAnd(generator.finalDestination(dst, src1.get()), src1.get(), src2);
+}
+
+void BitAndNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_expr2.get());
     nodeStack.append(m_expr1.get());
 }
 
 // ECMA 11.10
-JSValue* BitAndNode::evaluate(ExecState* exec)
+JSValue* BitAndNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* v1 = m_expr1->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -3231,7 +3798,7 @@
     return jsNumberFromAnd(exec, v1, v2);
 }
 
-int32_t BitAndNode::inlineEvaluateToInt32(ExecState* exec)
+int32_t BitAndNode::inlineEvaluateToInt32(OldInterpreterExecState* exec)
 {
     int32_t i1 = m_expr1->evaluateToInt32(exec);
     KJS_CHECKEXCEPTIONNUMBER
@@ -3239,33 +3806,40 @@
     return (i1 & i2);
 }
 
-double BitAndNode::evaluateToNumber(ExecState* exec)
+double BitAndNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToInt32(exec);
 }
 
-bool BitAndNode::evaluateToBoolean(ExecState* exec)
+bool BitAndNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToInt32(exec);
 }
 
-int32_t BitAndNode::evaluateToInt32(ExecState* exec)
+int32_t BitAndNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToInt32(exec);
 }
 
-uint32_t BitAndNode::evaluateToUInt32(ExecState* exec)
+uint32_t BitAndNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToInt32(exec);
 }
 
-void BitXOrNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* BitXOrNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
+    RegisterID* src2 = generator.emitNode(m_expr2.get());
+    return generator.emitBitXOr(generator.finalDestination(dst, src1.get()), src1.get(), src2);
+}
+
+void BitXOrNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_expr2.get());
     nodeStack.append(m_expr1.get());
 }
 
-int32_t BitXOrNode::inlineEvaluateToInt32(ExecState* exec)
+int32_t BitXOrNode::inlineEvaluateToInt32(OldInterpreterExecState* exec)
 {
     int i1 = m_expr1->evaluateToInt32(exec);
     KJS_CHECKEXCEPTIONNUMBER
@@ -3273,38 +3847,45 @@
     return (i1 ^ i2);
 }
 
-JSValue* BitXOrNode::evaluate(ExecState* exec)
+JSValue* BitXOrNode::evaluate(OldInterpreterExecState* exec)
 {
     return jsNumber(inlineEvaluateToInt32(exec));
 }
 
-double BitXOrNode::evaluateToNumber(ExecState* exec)
+double BitXOrNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToInt32(exec);
 }
 
-bool BitXOrNode::evaluateToBoolean(ExecState* exec)
+bool BitXOrNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToInt32(exec);
 }
 
-int32_t BitXOrNode::evaluateToInt32(ExecState* exec)
+int32_t BitXOrNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToInt32(exec);
 }
 
-uint32_t BitXOrNode::evaluateToUInt32(ExecState* exec)
+uint32_t BitXOrNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToInt32(exec);
 }
 
-void BitOrNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* BitOrNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> src1 = generator.emitNode(m_expr1.get());
+    RegisterID* src2 = generator.emitNode(m_expr2.get());
+    return generator.emitBitOr(generator.finalDestination(dst, src1.get()), src1.get(), src2);
+}
+
+void BitOrNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_expr2.get());
     nodeStack.append(m_expr1.get());
 }
 
-int32_t BitOrNode::inlineEvaluateToInt32(ExecState* exec)
+int32_t BitOrNode::inlineEvaluateToInt32(OldInterpreterExecState* exec)
 {
     int i1 = m_expr1->evaluateToInt32(exec);
     KJS_CHECKEXCEPTIONNUMBER
@@ -3312,41 +3893,54 @@
     return (i1 | i2);
 }
 
-JSValue* BitOrNode::evaluate(ExecState* exec)
+JSValue* BitOrNode::evaluate(OldInterpreterExecState* exec)
 {
     return jsNumber(inlineEvaluateToInt32(exec));
 }
 
-double BitOrNode::evaluateToNumber(ExecState* exec)
+double BitOrNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToInt32(exec);
 }
 
-bool BitOrNode::evaluateToBoolean(ExecState* exec)
+bool BitOrNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToInt32(exec);
 }
 
-int32_t BitOrNode::evaluateToInt32(ExecState* exec)
+int32_t BitOrNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToInt32(exec);
 }
 
-uint32_t BitOrNode::evaluateToUInt32(ExecState* exec)
+uint32_t BitOrNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     return inlineEvaluateToInt32(exec);
 }
 
 // ------------------------------ Binary Logical Nodes ----------------------------
 
-void LogicalAndNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* LogicalAndNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> temp = generator.tempDestination(dst);
+    RefPtr<LabelID> target = generator.newLabel();
+    
+    generator.emitNode(temp.get(), m_expr1.get());
+    generator.emitJumpIfFalse(temp.get(), target.get());
+    generator.emitNode(temp.get(), m_expr2.get());
+    generator.emitLabel(target.get());
+
+    return generator.moveToDestinationIfNeeded(dst, temp.get());
+}
+
+void LogicalAndNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_expr2.get());
     nodeStack.append(m_expr1.get());
 }
 
 // ECMA 11.11
-JSValue* LogicalAndNode::evaluate(ExecState* exec)
+JSValue* LogicalAndNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* v1 = m_expr1->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -3359,20 +3953,33 @@
     return v2;
 }
 
-bool LogicalAndNode::evaluateToBoolean(ExecState* exec)
+bool LogicalAndNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     bool b = m_expr1->evaluateToBoolean(exec);
     KJS_CHECKEXCEPTIONBOOLEAN
     return b && m_expr2->evaluateToBoolean(exec);
 }
 
-void LogicalOrNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* LogicalOrNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> temp = generator.tempDestination(dst);
+    RefPtr<LabelID> target = generator.newLabel();
+    
+    generator.emitNode(temp.get(), m_expr1.get());
+    generator.emitJumpIfTrue(temp.get(), target.get());
+    generator.emitNode(temp.get(), m_expr2.get());
+    generator.emitLabel(target.get());
+
+    return generator.moveToDestinationIfNeeded(dst, temp.get());
+}
+
+void LogicalOrNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_expr2.get());
     nodeStack.append(m_expr1.get());
 }
 
-JSValue* LogicalOrNode::evaluate(ExecState* exec)
+JSValue* LogicalOrNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* v1 = m_expr1->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -3381,7 +3988,7 @@
     return m_expr2->evaluate(exec);
 }
 
-bool LogicalOrNode::evaluateToBoolean(ExecState* exec)
+bool LogicalOrNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     bool b = m_expr1->evaluateToBoolean(exec);
     KJS_CHECKEXCEPTIONBOOLEAN
@@ -3390,7 +3997,27 @@
 
 // ------------------------------ ConditionalNode ------------------------------
 
-void ConditionalNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* ConditionalNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> newDst = generator.finalDestination(dst);
+    RefPtr<LabelID> beforeElse = generator.newLabel();
+    RefPtr<LabelID> afterElse = generator.newLabel();
+
+    RegisterID* cond = generator.emitNode(m_logical.get());
+    generator.emitJumpIfFalse(cond, beforeElse.get());
+
+    generator.emitNode(newDst.get(), m_expr1.get());
+    generator.emitJump(afterElse.get());
+
+    generator.emitLabel(beforeElse.get());
+    generator.emitNode(newDst.get(), m_expr2.get());
+
+    generator.emitLabel(afterElse.get());
+
+    return newDst.get();
+}
+
+void ConditionalNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_expr2.get());
     nodeStack.append(m_expr1.get());
@@ -3398,35 +4025,35 @@
 }
 
 // ECMA 11.12
-JSValue* ConditionalNode::evaluate(ExecState* exec)
+JSValue* ConditionalNode::evaluate(OldInterpreterExecState* exec)
 {
     bool b = m_logical->evaluateToBoolean(exec);
     KJS_CHECKEXCEPTIONVALUE
     return b ? m_expr1->evaluate(exec) : m_expr2->evaluate(exec);
 }
 
-bool ConditionalNode::evaluateToBoolean(ExecState* exec)
+bool ConditionalNode::evaluateToBoolean(OldInterpreterExecState* exec)
 {
     bool b = m_logical->evaluateToBoolean(exec);
     KJS_CHECKEXCEPTIONBOOLEAN
     return b ? m_expr1->evaluateToBoolean(exec) : m_expr2->evaluateToBoolean(exec);
 }
 
-double ConditionalNode::evaluateToNumber(ExecState* exec)
+double ConditionalNode::evaluateToNumber(OldInterpreterExecState* exec)
 {
     bool b = m_logical->evaluateToBoolean(exec);
     KJS_CHECKEXCEPTIONNUMBER
     return b ? m_expr1->evaluateToNumber(exec) : m_expr2->evaluateToNumber(exec);
 }
 
-int32_t ConditionalNode::evaluateToInt32(ExecState* exec)
+int32_t ConditionalNode::evaluateToInt32(OldInterpreterExecState* exec)
 {
     bool b = m_logical->evaluateToBoolean(exec);
     KJS_CHECKEXCEPTIONNUMBER
     return b ? m_expr1->evaluateToInt32(exec) : m_expr2->evaluateToInt32(exec);
 }
 
-uint32_t ConditionalNode::evaluateToUInt32(ExecState* exec)
+uint32_t ConditionalNode::evaluateToUInt32(OldInterpreterExecState* exec)
 {
     bool b = m_logical->evaluateToBoolean(exec);
     KJS_CHECKEXCEPTIONNUMBER
@@ -3435,8 +4062,8 @@
 
 // ECMA 11.13
 
-static ALWAYS_INLINE JSValue* valueForReadModifyAssignment(ExecState* exec, JSValue* current, ExpressionNode* right, Operator oper) KJS_FAST_CALL;
-static ALWAYS_INLINE JSValue* valueForReadModifyAssignment(ExecState* exec, JSValue* current, ExpressionNode* right, Operator oper)
+static ALWAYS_INLINE JSValue* valueForReadModifyAssignment(OldInterpreterExecState* exec, JSValue* current, ExpressionNode* right, Operator oper) KJS_FAST_CALL;
+static ALWAYS_INLINE JSValue* valueForReadModifyAssignment(OldInterpreterExecState* exec, JSValue* current, ExpressionNode* right, Operator oper)
 {
     JSValue* v;
     int i1;
@@ -3501,10 +4128,72 @@
 
 // ------------------------------ ReadModifyResolveNode -----------------------------------
 
-void ReadModifyResolveNode::optimizeVariableAccess(ExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack& nodeStack)
+// FIXME: should this be moved to be a method on CodeGenerator?
+static ALWAYS_INLINE RegisterID* emitReadModifyAssignment(CodeGenerator& generator, RegisterID* dst, RegisterID* src1, RegisterID* src2, Operator oper)
+{
+    switch (oper) {
+        case OpMultEq:
+            return generator.emitMul(dst, src1, src2);
+        case OpDivEq:
+            return generator.emitDiv(dst, src1, src2);
+        case OpPlusEq:
+            return generator.emitAdd(dst, src1, src2);
+        case OpMinusEq:
+            return generator.emitSub(dst, src1, src2);
+        case OpLShift:
+            return generator.emitLeftShift(dst, src1, src2);
+        case OpRShift:
+            return generator.emitRightShift(dst, src1, src2);
+        case OpURShift:
+            return generator.emitUnsignedRightShift(dst, src1, src2);
+        case OpAndEq:
+            return generator.emitBitAnd(dst, src1, src2);
+        case OpXOrEq:
+            return generator.emitBitXOr(dst, src1, src2);
+        case OpOrEq:
+            return generator.emitBitOr(dst, src1, src2);
+        case OpModEq:
+            return generator.emitMod(dst, src1, src2);
+        default:
+            ASSERT_NOT_REACHED();
+    }
+
+    return dst;
+}
+
+RegisterID* ReadModifyResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    if (RegisterID* local = generator.registerForLocal(m_ident)) {
+        if (generator.isLocalConstant(m_ident)) {
+            RegisterID* src2 = generator.emitNode(m_right.get());
+            return emitReadModifyAssignment(generator, generator.finalDestination(dst), local, src2, m_operator);
+        }
+        
+        if (generator.leftHandSideNeedsCopy(m_rightHasAssignments) && !m_right.get()->isNumber()) {
+            RefPtr<RegisterID> result = generator.newTemporary();
+            generator.emitMove(result.get(), local);
+            RegisterID* src2 = generator.emitNode(m_right.get());
+            emitReadModifyAssignment(generator, result.get(), result.get(), src2, m_operator);
+            generator.emitMove(local, result.get());
+            return generator.moveToDestinationIfNeeded(dst, result.get());
+        }
+        
+        RegisterID* src2 = generator.emitNode(m_right.get());
+        RegisterID* result = emitReadModifyAssignment(generator, local, local, src2, m_operator);
+        return generator.moveToDestinationIfNeeded(dst, result);
+    }
+
+    RefPtr<RegisterID> src1 = generator.tempDestination(dst);
+    RefPtr<RegisterID> base = generator.emitResolveWithBase(generator.newTemporary(), src1.get(), m_ident);
+    RegisterID* src2 = generator.emitNode(m_right.get());
+    RegisterID* result = emitReadModifyAssignment(generator, generator.finalDestination(dst, src1.get()), src1.get(), src2, m_operator);
+    return generator.emitPutById(base.get(), m_ident, result);
+}
+
+void ReadModifyResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack& nodeStack)
 {
     nodeStack.append(m_right.get());
-    size_t index = symbolTable.get(m_ident.ustring().rep());
+    int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
     if (index != missingSymbolMarker()) {
         if (isConstant(localStorage, index))
             new (this) ReadModifyConstNode(index);
@@ -3515,10 +4204,33 @@
 
 // ------------------------------ AssignResolveNode -----------------------------------
 
-void AssignResolveNode::optimizeVariableAccess(ExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack& nodeStack)
+RegisterID* AssignResolveNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    if (RegisterID* local = generator.registerForLocal(m_ident)) {
+        if (generator.isLocalConstant(m_ident))
+            return generator.emitNode(dst, m_right.get());
+        
+        RegisterID* result = generator.emitNode(local, m_right.get());
+        return generator.moveToDestinationIfNeeded(dst, result);
+    }
+
+    int index = 0;
+    size_t depth = 0;
+    if (generator.findScopedProperty(m_ident, index, depth) && index != missingSymbolMarker()) {
+        RegisterID* value = generator.emitNode(dst, m_right.get());
+        generator.emitPutScopedVar(depth, index, value);
+        return value;
+    }
+
+    RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
+    RegisterID* value = generator.emitNode(dst, m_right.get());
+    return generator.emitPutById(base.get(), m_ident, value);
+}
+
+void AssignResolveNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack& nodeStack)
 {
     nodeStack.append(m_right.get());
-    size_t index = symbolTable.get(m_ident.ustring().rep());
+    int index = symbolTable.get(m_ident.ustring().rep()).getIndex();
     if (index != missingSymbolMarker()) {
         if (isConstant(localStorage, index))
             new (this) AssignConstNode;
@@ -3529,7 +4241,7 @@
 
 // ------------------------------ ReadModifyLocalVarNode -----------------------------------
 
-JSValue* ReadModifyLocalVarNode::evaluate(ExecState* exec)
+JSValue* ReadModifyLocalVarNode::evaluate(OldInterpreterExecState* exec)
 {
     ASSERT(exec->variableObject() == exec->scopeChain().top());
 
@@ -3548,7 +4260,7 @@
 
 // ------------------------------ AssignLocalVarNode -----------------------------------
 
-JSValue* AssignLocalVarNode::evaluate(ExecState* exec)
+JSValue* AssignLocalVarNode::evaluate(OldInterpreterExecState* exec)
 {
     ASSERT(exec->variableObject() == exec->scopeChain().top());
     JSValue* v = m_right->evaluate(exec);
@@ -3562,7 +4274,7 @@
 
 // ------------------------------ ReadModifyConstNode -----------------------------------
 
-JSValue* ReadModifyConstNode::evaluate(ExecState* exec)
+JSValue* ReadModifyConstNode::evaluate(OldInterpreterExecState* exec)
 {
     ASSERT(exec->variableObject() == exec->scopeChain().top());
     JSValue* left = exec->localStorage()[m_index].value;
@@ -3574,12 +4286,12 @@
 
 // ------------------------------ AssignConstNode -----------------------------------
 
-JSValue* AssignConstNode::evaluate(ExecState* exec)
+JSValue* AssignConstNode::evaluate(OldInterpreterExecState* exec)
 {
     return m_right->evaluate(exec);
 }
 
-JSValue* ReadModifyResolveNode::evaluate(ExecState* exec)
+JSValue* ReadModifyResolveNode::evaluate(OldInterpreterExecState* exec)
 {
     const ScopeChain& chain = exec->scopeChain();
     ScopeChainIterator iter = chain.begin();
@@ -3622,7 +4334,7 @@
     return v;
 }
 
-JSValue* AssignResolveNode::evaluate(ExecState* exec)
+JSValue* AssignResolveNode::evaluate(OldInterpreterExecState* exec)
 {
     const ScopeChain& chain = exec->scopeChain();
     ScopeChainIterator iter = chain.begin();
@@ -3656,13 +4368,22 @@
 
 // ------------------------------ ReadModifyDotNode -----------------------------------
 
-void AssignDotNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* AssignDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments);
+    RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
+    RegisterID* result = generator.emitNode(value.get(), m_right.get());
+    generator.emitPutById(base.get(), m_ident, result);
+    return generator.moveToDestinationIfNeeded(dst, result);
+}
+
+void AssignDotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_right.get());
     nodeStack.append(m_base.get());
 }
 
-JSValue* AssignDotNode::evaluate(ExecState* exec)
+JSValue* AssignDotNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* baseValue = m_base->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -3676,13 +4397,22 @@
     return v;
 }
 
-void ReadModifyDotNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* ReadModifyDotNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_rightHasAssignments);
+    RefPtr<RegisterID> value = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
+    RegisterID* change = generator.emitNode(m_right.get());
+    RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator);
+    return generator.emitPutById(base.get(), m_ident, updatedValue);
+}
+
+void ReadModifyDotNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_right.get());
     nodeStack.append(m_base.get());
 }
 
-JSValue* ReadModifyDotNode::evaluate(ExecState* exec)
+JSValue* ReadModifyDotNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* baseValue = m_base->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -3704,7 +4434,12 @@
 
 // ------------------------------ AssignErrorNode -----------------------------------
 
-JSValue* AssignErrorNode::evaluate(ExecState* exec)
+RegisterID* AssignErrorNode::emitCode(CodeGenerator& generator, RegisterID*)
+{
+    return emitThrowError(generator, ReferenceError, "Left side of assignment is not a reference.");
+}
+
+JSValue* AssignErrorNode::evaluate(OldInterpreterExecState* exec)
 {
     throwError(exec, ReferenceError, "Left side of assignment is not a reference.");
     handleException(exec);
@@ -3713,14 +4448,24 @@
 
 // ------------------------------ AssignBracketNode -----------------------------------
 
-void AssignBracketNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* AssignBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments);
+    RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments);
+    RefPtr<RegisterID> value = generator.destinationForAssignResult(dst);
+    RegisterID* result = generator.emitNode(value.get(), m_right.get());
+    generator.emitPutByVal(base.get(), property.get(), result);
+    return generator.moveToDestinationIfNeeded(dst, result);
+}
+
+void AssignBracketNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_right.get());
     nodeStack.append(m_subscript.get());
     nodeStack.append(m_base.get());
 }
 
-JSValue* AssignBracketNode::evaluate(ExecState* exec)
+JSValue* AssignBracketNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* baseValue = m_base->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -3745,14 +4490,29 @@
     base->put(exec, propertyName, v);
     return v;
 }
-void ReadModifyBracketNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+
+RegisterID* ReadModifyBracketNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base.get(), m_subscriptHasAssignments || m_rightHasAssignments);
+    RefPtr<RegisterID> property = generator.emitNodeForLeftHandSide(m_subscript.get(), m_rightHasAssignments);
+
+    RefPtr<RegisterID> value = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
+    RegisterID* change = generator.emitNode(m_right.get());
+    RegisterID* updatedValue = emitReadModifyAssignment(generator, generator.finalDestination(dst, value.get()), value.get(), change, m_operator);
+
+    generator.emitPutByVal(base.get(), property.get(), updatedValue);
+
+    return updatedValue;
+}
+
+void ReadModifyBracketNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_right.get());
     nodeStack.append(m_subscript.get());
     nodeStack.append(m_base.get());
 }
 
-JSValue* ReadModifyBracketNode::evaluate(ExecState* exec)
+JSValue* ReadModifyBracketNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* baseValue = m_base->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -3793,14 +4553,20 @@
 
 // ------------------------------ CommaNode ------------------------------------
 
-void CommaNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* CommaNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    generator.emitNode(m_expr1.get());
+    return generator.emitNode(dst, m_expr2.get());
+}
+
+void CommaNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_expr2.get());
     nodeStack.append(m_expr1.get());
 }
 
 // ECMA 11.14
-JSValue* CommaNode::evaluate(ExecState* exec)
+JSValue* CommaNode::evaluate(OldInterpreterExecState* exec)
 {
     m_expr1->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -3815,7 +4581,7 @@
 {
 }
 
-void ConstDeclNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+void ConstDeclNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     if (m_next)
         nodeStack.append(m_next.get());
@@ -3823,7 +4589,7 @@
         nodeStack.append(m_init.get());
 }
 
-void ConstDeclNode::handleSlowCase(ExecState* exec, const ScopeChain& chain, JSValue* val)
+void ConstDeclNode::handleSlowCase(OldInterpreterExecState* exec, const ScopeChain& chain, JSValue* val)
 {
     ScopeChainIterator iter = chain.begin();
     ScopeChainIterator end = chain.end();
@@ -3846,14 +4612,12 @@
 }
 
 // ECMA 12.2
-inline void ConstDeclNode::evaluateSingle(ExecState* exec)
+inline void ConstDeclNode::evaluateSingle(OldInterpreterExecState* exec)
 {
     ASSERT(exec->variableObject()->hasOwnProperty(exec, m_ident) || exec->codeType() == EvalCode); // Guaranteed by processDeclarations.
     const ScopeChain& chain = exec->scopeChain();
     JSVariableObject* variableObject = exec->variableObject();
 
-    ASSERT(!chain.isEmpty());
-
     bool inGlobalScope = ++chain.begin() == chain.end();
 
     if (m_init) {
@@ -3878,7 +4642,28 @@
     }
 }
 
-JSValue* ConstDeclNode::evaluate(ExecState* exec)
+RegisterID* ConstDeclNode::emitCodeSingle(CodeGenerator& generator)
+{
+    if (RegisterID* local = generator.registerForLocalConstInit(m_ident))
+        return generator.emitNode(local, m_init.get());
+
+    // FIXME: While this code should only be hit in eval code, it will potentially
+    // assign to the wrong base if m_ident exists in an intervening dynamic scope.
+    RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
+    RegisterID* value = generator.emitNode(m_init.get());
+    return generator.emitPutById(base.get(), m_ident, value);
+}
+
+RegisterID* ConstDeclNode::emitCode(CodeGenerator& generator, RegisterID*)
+{
+    RegisterID* result = 0;
+    for (ConstDeclNode* n = this; n; n = n->m_next.get())
+        result = n->emitCodeSingle(generator);
+
+    return result;
+}
+
+JSValue* ConstDeclNode::evaluate(OldInterpreterExecState* exec)
 {
     evaluateSingle(exec);
 
@@ -3894,14 +4679,19 @@
 
 // ------------------------------ ConstStatementNode -----------------------------
 
-void ConstStatementNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+void ConstStatementNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     ASSERT(m_next);
     nodeStack.append(m_next.get());
 }
 
+RegisterID* ConstStatementNode::emitCode(CodeGenerator& generator, RegisterID*)
+{
+    return generator.emitNode(m_next.get());
+}
+
 // ECMA 12.2
-JSValue* ConstStatementNode::execute(ExecState* exec)
+JSValue* ConstStatementNode::execute(OldInterpreterExecState* exec)
 {
     m_next->evaluate(exec);
     KJS_CHECKEXCEPTION
@@ -3911,6 +4701,21 @@
 
 // ------------------------------ Helper functions for handling Vectors of StatementNode -------------------------------
 
+static inline RegisterID* statementListEmitCode(StatementVector& statements, CodeGenerator& generator, RegisterID* dst = 0)
+{
+    RefPtr<RegisterID> r0 = dst;
+
+    StatementVector::iterator end = statements.end();
+    for (StatementVector::iterator it = statements.begin(); it != end; ++it) {
+        StatementNode* n = it->get();
+        generator.emitDebugHook(WillExecuteStatement, n->firstLine(), n->lastLine());
+        if (RegisterID* r1 = generator.emitNode(dst, n))
+            r0 = r1;
+    }
+    
+    return r0.get();
+}
+
 static inline void statementListPushFIFO(StatementVector& statements, DeclarationStacks::NodeStack& stack)
 {
     StatementVector::iterator it = statements.end();
@@ -3938,7 +4743,7 @@
     return (*begin).get();
 }
 
-static inline JSValue* statementListExecute(StatementVector& statements, ExecState* exec)
+static inline JSValue* statementListExecute(StatementVector& statements, OldInterpreterExecState* exec)
 {
     JSValue* value = 0;
     size_t size = statements.size();
@@ -3960,35 +4765,51 @@
         children->releaseContentsIntoVector(m_children);
 }
 
-void BlockNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* BlockNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    return statementListEmitCode(m_children, generator, dst);
+}
+
+void BlockNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     statementListPushFIFO(m_children, nodeStack);
 }
 
 // ECMA 12.1
-JSValue* BlockNode::execute(ExecState* exec)
+JSValue* BlockNode::execute(OldInterpreterExecState* exec)
 {
     return statementListExecute(m_children, exec);
 }
 
 // ------------------------------ EmptyStatementNode ---------------------------
 
+RegisterID* EmptyStatementNode::emitCode(CodeGenerator&, RegisterID* dst)
+{
+    return dst;
+}
+
 // ECMA 12.3
-JSValue* EmptyStatementNode::execute(ExecState* exec)
+JSValue* EmptyStatementNode::execute(OldInterpreterExecState* exec)
 {
     return exec->setNormalCompletion();
 }
 
 // ------------------------------ ExprStatementNode ----------------------------
 
-void ExprStatementNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* ExprStatementNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    ASSERT(m_expr);
+    return generator.emitNode(dst, m_expr.get());
+}
+
+void ExprStatementNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     ASSERT(m_expr);
     nodeStack.append(m_expr.get());
 }
 
 // ECMA 12.4
-JSValue* ExprStatementNode::execute(ExecState* exec)
+JSValue* ExprStatementNode::execute(OldInterpreterExecState* exec)
 {
     JSValue* value = m_expr->evaluate(exec);
     KJS_CHECKEXCEPTION
@@ -3998,13 +4819,19 @@
 
 // ------------------------------ VarStatementNode ----------------------------
 
-void VarStatementNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* VarStatementNode::emitCode(CodeGenerator& generator, RegisterID*)
+{
+    ASSERT(m_expr);
+    return generator.emitNode(m_expr.get());
+}
+
+void VarStatementNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     ASSERT(m_expr);
     nodeStack.append(m_expr.get());
 }
 
-JSValue* VarStatementNode::execute(ExecState* exec)
+JSValue* VarStatementNode::execute(OldInterpreterExecState* exec)
 {
     m_expr->evaluate(exec);
     KJS_CHECKEXCEPTION
@@ -4014,14 +4841,28 @@
 
 // ------------------------------ IfNode ---------------------------------------
 
-void IfNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* IfNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<LabelID> afterThen = generator.newLabel();
+
+    RegisterID* cond = generator.emitNode(m_condition.get());
+    generator.emitJumpIfFalse(cond, afterThen.get());
+
+    generator.emitNode(dst, m_ifBlock.get());
+    generator.emitLabel(afterThen.get());
+
+    // FIXME: This should return the last statement exectuted so that it can be returned as a Completion
+    return 0;
+}
+
+void IfNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_ifBlock.get());
     nodeStack.append(m_condition.get());
 }
 
 // ECMA 12.5
-JSValue* IfNode::execute(ExecState* exec)
+JSValue* IfNode::execute(OldInterpreterExecState* exec)
 {
     bool b = m_condition->evaluateToBoolean(exec);
     KJS_CHECKEXCEPTION
@@ -4031,14 +4872,34 @@
     return exec->setNormalCompletion();
 }
 
-void IfElseNode::optimizeVariableAccess(ExecState* exec, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack& nodeStack)
+RegisterID* IfElseNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<LabelID> beforeElse = generator.newLabel();
+    RefPtr<LabelID> afterElse = generator.newLabel();
+
+    RegisterID* cond = generator.emitNode(m_condition.get());
+    generator.emitJumpIfFalse(cond, beforeElse.get());
+
+    generator.emitNode(dst, m_ifBlock.get());
+    generator.emitJump(afterElse.get());
+
+    generator.emitLabel(beforeElse.get());
+    generator.emitNode(dst, m_elseBlock.get());
+
+    generator.emitLabel(afterElse.get());
+
+    // FIXME: This should return the last statement exectuted so that it can be returned as a Completion
+    return 0;
+}
+
+void IfElseNode::optimizeVariableAccess(OldInterpreterExecState* exec, const SymbolTable& symbolTable, const LocalStorage& localStorage, NodeStack& nodeStack)
 {
     nodeStack.append(m_elseBlock.get());
     IfNode::optimizeVariableAccess(exec, symbolTable, localStorage, nodeStack);
 }
 
 // ECMA 12.5
-JSValue* IfElseNode::execute(ExecState* exec)
+JSValue* IfElseNode::execute(OldInterpreterExecState* exec)
 {
     bool b = m_condition->evaluateToBoolean(exec);
     KJS_CHECKEXCEPTION
@@ -4050,14 +4911,33 @@
 
 // ------------------------------ DoWhileNode ----------------------------------
 
-void DoWhileNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* DoWhileNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<LabelID> topOfLoop = generator.newLabel();
+    generator.emitLabel(topOfLoop.get());
+
+    RefPtr<LabelID> continueTarget = generator.newLabel();
+    RefPtr<LabelID> breakTarget = generator.newLabel();
+    
+    generator.pushJumpContext(&m_labelStack, continueTarget.get(), breakTarget.get(), true);
+    RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get());
+    generator.popJumpContext();
+    
+    generator.emitLabel(continueTarget.get());
+    RegisterID* cond = generator.emitNode(m_expr.get());
+    generator.emitJumpIfTrue(cond, topOfLoop.get());
+    generator.emitLabel(breakTarget.get());
+    return result.get();
+}
+
+void DoWhileNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_statement.get());
     nodeStack.append(m_expr.get());
 }
 
 // ECMA 12.6.1
-JSValue* DoWhileNode::execute(ExecState* exec)
+JSValue* DoWhileNode::execute(OldInterpreterExecState* exec)
 {
     JSValue* value = 0;
 
@@ -4092,14 +4972,37 @@
 
 // ------------------------------ WhileNode ------------------------------------
 
-void WhileNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* WhileNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<LabelID> topOfLoop = generator.newLabel();
+    RefPtr<LabelID> continueTarget = generator.newLabel();
+    RefPtr<LabelID> breakTarget = generator.newLabel();
+
+    generator.emitJump(continueTarget.get());
+    generator.emitLabel(topOfLoop.get());
+    
+    generator.pushJumpContext(&m_labelStack, continueTarget.get(), breakTarget.get(), true);
+    generator.emitNode(dst, m_statement.get());
+    generator.popJumpContext();
+
+    generator.emitLabel(continueTarget.get());
+    RegisterID* cond = generator.emitNode(m_expr.get());
+    generator.emitJumpIfTrue(cond, topOfLoop.get());
+
+    generator.emitLabel(breakTarget.get());
+    
+    // FIXME: This should return the last statement executed so that it can be returned as a Completion
+    return 0;
+}
+
+void WhileNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_statement.get());
     nodeStack.append(m_expr.get());
 }
 
 // ECMA 12.6.2
-JSValue* WhileNode::execute(ExecState* exec)
+JSValue* WhileNode::execute(OldInterpreterExecState* exec)
 {
     JSValue* value = 0;
 
@@ -4133,7 +5036,31 @@
 
 // ------------------------------ ForNode --------------------------------------
 
-void ForNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* ForNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    generator.emitNode(m_expr1.get());
+    
+    RefPtr<LabelID> topOfLoop = generator.newLabel();
+    RefPtr<LabelID> beforeCondition = generator.newLabel();
+    RefPtr<LabelID> continueTarget = generator.newLabel(); 
+    RefPtr<LabelID> breakTarget = generator.newLabel(); 
+    generator.emitJump(beforeCondition.get());
+
+    generator.emitLabel(topOfLoop.get());
+    generator.pushJumpContext(&m_labelStack, continueTarget.get(), breakTarget.get(), true);
+    RefPtr<RegisterID> result = generator.emitNode(dst, m_statement.get());
+    generator.popJumpContext();
+    generator.emitLabel(continueTarget.get());  
+    generator.emitNode(m_expr3.get());
+
+    generator.emitLabel(beforeCondition.get());
+    RegisterID* cond = generator.emitNode(m_expr2.get());
+    generator.emitJumpIfTrue(cond, topOfLoop.get());
+    generator.emitLabel(breakTarget.get());
+    return result.get();
+}
+
+void ForNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_statement.get());
     nodeStack.append(m_expr3.get());
@@ -4142,7 +5069,7 @@
 }
 
 // ECMA 12.6.3
-JSValue* ForNode::execute(ExecState* exec)
+JSValue* ForNode::execute(OldInterpreterExecState* exec)
 {
     JSValue* value = 0;
 
@@ -4199,11 +5126,11 @@
     , m_identIsVarDecl(true)
 {
     if (in)
-        m_init = new AssignResolveNode(ident, in);
+        m_init = new AssignResolveNode(ident, in, true);
     // for( var foo = bar in baz )
 }
 
-void ForInNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+void ForInNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_statement.get());
     nodeStack.append(m_expr.get());
@@ -4212,8 +5139,57 @@
         nodeStack.append(m_init.get());
 }
 
+RegisterID* ForInNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<LabelID> loopStart = generator.newLabel();
+    RefPtr<LabelID> continueTarget = generator.newLabel(); 
+    RefPtr<LabelID> breakTarget = generator.newLabel(); 
+
+    if (m_init)
+        generator.emitNode(m_init.get());
+    RegisterID* forInBase = generator.emitNode(m_expr.get());
+    RefPtr<RegisterID> iter = generator.emitGetPropertyNames(generator.newTemporary(), forInBase);
+    generator.emitJump(continueTarget.get());
+    generator.emitLabel(loopStart.get());
+    RegisterID* propertyName;
+    if (m_lexpr->isResolveNode()) {
+        const Identifier& ident = static_cast<ResolveNode*>(m_lexpr.get())->identifier();
+        propertyName = generator.registerForLocal(ident);
+        if (!propertyName) {
+            propertyName = generator.newTemporary();
+            RefPtr<RegisterID> protect = propertyName;
+            RegisterID* base = generator.emitResolveBase(generator.newTemporary(), ident);
+            generator.emitPutById(base, ident, propertyName);
+        }
+    } else if (m_lexpr->isDotAccessorNode()) {
+        DotAccessorNode* assignNode = static_cast<DotAccessorNode*>(m_lexpr.get());
+        const Identifier& ident = assignNode->identifier();
+        propertyName = generator.newTemporary();
+        RefPtr<RegisterID> protect = propertyName;
+        RegisterID* base = generator.emitNode(assignNode->base());
+        generator.emitPutById(base, ident, propertyName);
+    } else {
+        ASSERT(m_lexpr->isBracketAccessorNode());
+        BracketAccessorNode* assignNode = static_cast<BracketAccessorNode*>(m_lexpr.get());
+        propertyName = generator.newTemporary();
+        RefPtr<RegisterID> protect = propertyName;
+        RefPtr<RegisterID> base = generator.emitNode(assignNode->base());
+        RegisterID* subscript = generator.emitNode(assignNode->subscript());
+        generator.emitPutByVal(base.get(), subscript, propertyName);
+    }   
+    
+    generator.pushJumpContext(&m_labelStack, continueTarget.get(), breakTarget.get(), true);
+    generator.emitNode(dst, m_statement.get());
+    generator.popJumpContext();
+
+    generator.emitLabel(continueTarget.get());
+    generator.emitNextPropertyName(propertyName, iter.get(), loopStart.get());
+    generator.emitLabel(breakTarget.get());
+    return dst;
+}
+
 // ECMA 12.6.4
-JSValue* ForInNode::execute(ExecState* exec)
+JSValue* ForInNode::execute(OldInterpreterExecState* exec)
 {
     JSValue* value = 0;
 
@@ -4312,7 +5288,29 @@
 // ------------------------------ ContinueNode ---------------------------------
 
 // ECMA 12.7
-JSValue* ContinueNode::execute(ExecState* exec)
+RegisterID* ContinueNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    if (!generator.inContinueContext())
+        return emitThrowError(generator, SyntaxError, "Invalid continue statement.");
+
+    JumpContext* targetContext = generator.jumpContextForContinue(m_ident);
+
+    if (!targetContext) {
+        if (m_ident.isEmpty())
+            return emitThrowError(generator, SyntaxError, "Invalid continue statement.");
+        else
+            return emitThrowError(generator, SyntaxError, "Label %s not found.", m_ident);
+    }
+
+    if (!targetContext->continueTarget)
+        return emitThrowError(generator, SyntaxError, "Invalid continue statement.");        
+
+    generator.emitJumpScopes(targetContext->continueTarget, targetContext->scopeDepth);
+    
+    return dst;
+}
+
+JSValue* ContinueNode::execute(OldInterpreterExecState* exec)
 {
     if (m_ident.isEmpty() && !exec->inIteration())
         return setErrorCompletion(exec, SyntaxError, "Invalid continue statement.");
@@ -4324,7 +5322,28 @@
 // ------------------------------ BreakNode ------------------------------------
 
 // ECMA 12.8
-JSValue* BreakNode::execute(ExecState* exec)
+RegisterID* BreakNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    if (!generator.inJumpContext())
+        return emitThrowError(generator, SyntaxError, "Invalid break statement.");
+    
+    JumpContext* targetContext = generator.jumpContextForBreak(m_ident);
+    
+    if (!targetContext) {
+        if (m_ident.isEmpty())
+            return emitThrowError(generator, SyntaxError, "Invalid break statement.");
+        else
+            return emitThrowError(generator, SyntaxError, "Label %s not found.", m_ident);
+    }
+
+    ASSERT(targetContext->breakTarget);
+
+    generator.emitJumpScopes(targetContext->breakTarget, targetContext->scopeDepth);
+
+    return dst;
+}
+
+JSValue* BreakNode::execute(OldInterpreterExecState* exec)
 {
     if (m_ident.isEmpty() && !exec->inIteration() && !exec->inSwitch())
         return setErrorCompletion(exec, SyntaxError, "Invalid break statement.");
@@ -4335,14 +5354,29 @@
 
 // ------------------------------ ReturnNode -----------------------------------
 
-void ReturnNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* ReturnNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    if (generator.codeType() != FunctionCode)
+        return emitThrowError(generator, SyntaxError, "Invalid return statement.");
+        
+    RegisterID* r0 = m_value ? generator.emitNode(dst, m_value.get()) : generator.emitLoad(generator.finalDestination(dst), jsUndefined());
+    if (generator.scopeDepth()) {
+        RefPtr<LabelID> l0 = generator.newLabel();
+        generator.emitJumpScopes(l0.get(), 0);
+        generator.emitLabel(l0.get());
+    }
+    generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
+    return generator.emitReturn(r0);
+}
+
+void ReturnNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     if (m_value)
         nodeStack.append(m_value.get());
 }
 
 // ECMA 12.9
-JSValue* ReturnNode::execute(ExecState* exec)
+JSValue* ReturnNode::execute(OldInterpreterExecState* exec)
 {
     CodeType codeType = exec->codeType();
     if (codeType != FunctionCode)
@@ -4359,30 +5393,31 @@
 
 // ------------------------------ WithNode -------------------------------------
 
-void WithNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* WithNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RegisterID* scope = generator.emitNode(m_expr.get());
+    generator.emitPushScope(scope);
+    RegisterID* result = generator.emitNode(dst, m_statement.get());
+    generator.emitPopScope();
+    return result;
+}
+
+void WithNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     // Can't optimize within statement because "with" introduces a dynamic scope.
     nodeStack.append(m_expr.get());
 }
 
 // ECMA 12.10
-JSValue* WithNode::execute(ExecState* exec)
+JSValue* WithNode::execute(OldInterpreterExecState*)
 {
-    JSValue* v = m_expr->evaluate(exec);
-    KJS_CHECKEXCEPTION
-    JSObject* o = v->toObject(exec);
-    KJS_CHECKEXCEPTION
-    exec->dynamicGlobalObject()->tearOffActivation(exec);
-    exec->pushScope(o);
-    JSValue* value = m_statement->execute(exec);
-    exec->popScope();
-
-    return value;
+    ASSERT_NOT_REACHED();
+    return 0;
 }
 
 // ------------------------------ CaseClauseNode -------------------------------
 
-void CaseClauseNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+void CaseClauseNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     if (m_expr)
         nodeStack.append(m_expr.get());
@@ -4390,7 +5425,7 @@
 }
 
 // ECMA 12.11
-JSValue* CaseClauseNode::evaluate(ExecState* exec)
+JSValue* CaseClauseNode::evaluate(OldInterpreterExecState* exec)
 {
     JSValue* v = m_expr->evaluate(exec);
     KJS_CHECKEXCEPTIONVALUE
@@ -4399,14 +5434,14 @@
 }
 
 // ECMA 12.11
-JSValue* CaseClauseNode::executeStatements(ExecState* exec)
+JSValue* CaseClauseNode::executeStatements(OldInterpreterExecState* exec)
 {
     return statementListExecute(m_children, exec);
 }
 
 // ------------------------------ ClauseListNode -------------------------------
 
-void ClauseListNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+void ClauseListNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     if (m_next)
         nodeStack.append(m_next.get());
@@ -4415,14 +5450,55 @@
 
 // ------------------------------ CaseBlockNode --------------------------------
 
-CaseBlockNode::CaseBlockNode(ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2)
-    : m_list1(list1)
-    , m_defaultClause(defaultClause)
-    , m_list2(list2)
+RegisterID* CaseBlockNode::emitCodeForBlock(CodeGenerator& generator, RegisterID* switchExpression, RegisterID* dst)
 {
+    Vector<RefPtr<LabelID>, 8> labelVector;
+
+    // Setup jumps
+    for (ClauseListNode* list = m_list1.get(); list; list = list->getNext()) {
+        RegisterID* clauseVal = generator.emitNode(list->getClause()->expr());
+        generator.emitStrictEqual(clauseVal, clauseVal, switchExpression);
+        labelVector.append(generator.newLabel());
+        generator.emitJumpIfTrue(clauseVal, labelVector[labelVector.size() - 1].get());
+    }
+
+    for (ClauseListNode* list = m_list2.get(); list; list = list->getNext()) {
+        RegisterID* clauseVal = generator.emitNode(list->getClause()->expr());
+        generator.emitStrictEqual(clauseVal, clauseVal, switchExpression);
+        labelVector.append(generator.newLabel());
+        generator.emitJumpIfTrue(clauseVal, labelVector[labelVector.size() - 1].get());
+    }
+
+    RefPtr<LabelID> defaultLabel;
+    defaultLabel = generator.newLabel();
+    generator.emitJump(defaultLabel.get());
+
+    RegisterID* result = 0;
+
+    size_t i = 0;
+    for (ClauseListNode* list = m_list1.get(); list; list = list->getNext()) {
+        generator.emitLabel(labelVector[i++].get());
+        result = statementListEmitCode(list->getClause()->children(), generator, dst);
+    }
+
+    if (m_defaultClause) {
+        generator.emitLabel(defaultLabel.get());
+        result = statementListEmitCode(m_defaultClause->children(), generator, dst);
+    }
+
+    for (ClauseListNode* list = m_list2.get(); list; list = list->getNext()) {
+        generator.emitLabel(labelVector[i++].get());
+        result = statementListEmitCode(list->getClause()->children(), generator, dst);
+    }
+    if (!m_defaultClause)
+        generator.emitLabel(defaultLabel.get());
+
+    ASSERT(i == labelVector.size());
+
+    return result;
 }
 
-void CaseBlockNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+void CaseBlockNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     if (m_list2)
         nodeStack.append(m_list2.get());
@@ -4433,7 +5509,7 @@
 }
 
 // ECMA 12.11
-JSValue* CaseBlockNode::executeBlock(ExecState* exec, JSValue* input)
+JSValue* CaseBlockNode::executeBlock(OldInterpreterExecState* exec, JSValue* input)
 {
     ClauseListNode* a = m_list1.get();
     while (a) {
@@ -4441,7 +5517,7 @@
         a = a->getNext();
         JSValue* v = clause->evaluate(exec);
         KJS_CHECKEXCEPTION
-        if (strictEqual(exec, input, v)) {
+        if (strictEqual(input, v)) {
             JSValue* res = clause->executeStatements(exec);
             if (exec->completionType() != Normal)
                 return res;
@@ -4460,7 +5536,7 @@
         b = b->getNext();
         JSValue* v = clause->evaluate(exec);
         KJS_CHECKEXCEPTION
-        if (strictEqual(exec, input, v)) {
+        if (strictEqual(input, v)) {
             JSValue* res = clause->executeStatements(exec);
             if (exec->completionType() != Normal)
                 return res;
@@ -4492,14 +5568,28 @@
 
 // ------------------------------ SwitchNode -----------------------------------
 
-void SwitchNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* SwitchNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<LabelID> breakTarget = generator.newLabel();
+
+    RefPtr<RegisterID> r0 = generator.emitNode(m_expr.get());
+    generator.pushJumpContext(&m_labelStack, 0, breakTarget.get(), true);
+    RegisterID* r1 = m_block->emitCodeForBlock(generator, r0.get(), dst);
+    generator.popJumpContext();
+
+    generator.emitLabel(breakTarget.get());
+
+    return r1;
+}
+
+void SwitchNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_block.get());
     nodeStack.append(m_expr.get());
 }
 
 // ECMA 12.11
-JSValue* SwitchNode::execute(ExecState* exec)
+JSValue* SwitchNode::execute(OldInterpreterExecState* exec)
 {
     JSValue* v = m_expr->evaluate(exec);
     KJS_CHECKEXCEPTION
@@ -4514,14 +5604,31 @@
 }
 
 // ------------------------------ LabelNode ------------------------------------
+RegisterID* LabelNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    if (generator.jumpContextForBreak(m_label))
+        return emitThrowError(generator, SyntaxError, "Duplicated label %s found.", m_label);
+    
+    RefPtr<LabelID> l0 = generator.newLabel();
+    m_labelStack.push(m_label);
+    generator.pushJumpContext(&m_labelStack, 0, l0.get(), false);
+    
+    RegisterID* r0 = generator.emitNode(dst, m_statement.get());
+    
+    generator.popJumpContext();
+    m_labelStack.pop();
+    
+    generator.emitLabel(l0.get());
+    return r0;
+}
 
-void LabelNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+void LabelNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_statement.get());
 }
 
 // ECMA 12.12
-JSValue* LabelNode::execute(ExecState* exec)
+JSValue* LabelNode::execute(OldInterpreterExecState* exec)
 {
     if (!exec->seenLabels().push(m_label))
         return setErrorCompletion(exec, SyntaxError, "Duplicated label %s found.", m_label);
@@ -4535,13 +5642,19 @@
 
 // ------------------------------ ThrowNode ------------------------------------
 
-void ThrowNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* ThrowNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    generator.emitThrow(generator.emitNode(dst, m_expr.get()));
+    return dst;
+}
+
+void ThrowNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     nodeStack.append(m_expr.get());
 }
 
 // ECMA 12.13
-JSValue* ThrowNode::execute(ExecState* exec)
+JSValue* ThrowNode::execute(OldInterpreterExecState* exec)
 {
     JSValue* v = m_expr->evaluate(exec);
     KJS_CHECKEXCEPTION
@@ -4552,7 +5665,58 @@
 
 // ------------------------------ TryNode --------------------------------------
 
-void TryNode::optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
+RegisterID* TryNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<LabelID> tryStartLabel = generator.newLabel();
+    RefPtr<LabelID> tryEndLabel = generator.newLabel();
+    RefPtr<LabelID> finallyStart;
+    RefPtr<RegisterID> finallyReturnAddr;
+    if (m_finallyBlock) {
+        finallyStart = generator.newLabel();
+        finallyReturnAddr = generator.newTemporary();
+        generator.pushFinallyContext(finallyStart.get(), finallyReturnAddr.get());
+    }
+    generator.emitLabel(tryStartLabel.get());
+    generator.emitNode(dst, m_tryBlock.get());
+    generator.emitLabel(tryEndLabel.get());
+
+    if (m_catchBlock) {
+        RefPtr<LabelID> handlerEndLabel = generator.newLabel();
+        generator.emitJump(handlerEndLabel.get());
+        RefPtr<RegisterID> exceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), tryEndLabel.get());
+        RegisterID* newScope = generator.emitNewObject(generator.newTemporary());
+        generator.emitPutById(newScope, m_exceptionIdent, exceptionRegister.get());
+        exceptionRegister = 0; // Release register used for temporaries
+        generator.emitPushScope(newScope);
+        generator.emitNode(dst, m_catchBlock.get());
+        generator.emitPopScope();
+        generator.emitLabel(handlerEndLabel.get());
+    }
+
+    if (m_finallyBlock) {
+        generator.popFinallyContext();
+        RefPtr<LabelID> finallyEndLabel = generator.newLabel();
+        generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
+        generator.emitJump(finallyEndLabel.get());
+
+        // Finally block for exception path
+        RefPtr<RegisterID> tempExceptionRegister = generator.emitCatch(generator.newTemporary(), tryStartLabel.get(), generator.emitLabel(generator.newLabel().get()).get());
+        generator.emitJumpSubroutine(finallyReturnAddr.get(), finallyStart.get());
+        generator.emitThrow(tempExceptionRegister.get());
+
+        // emit the finally block itself
+        generator.emitLabel(finallyStart.get());
+        generator.emitNode(dst, m_finallyBlock.get());
+        generator.emitSubroutineReturn(finallyReturnAddr.get());
+
+        generator.emitLabel(finallyEndLabel.get());
+    }
+
+    return dst;
+}
+
+
+void TryNode::optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack& nodeStack)
 {
     // Can't optimize within catchBlock because "catch" introduces a dynamic scope.
     if (m_finallyBlock)
@@ -4561,29 +5725,10 @@
 }
 
 // ECMA 12.14
-JSValue* TryNode::execute(ExecState* exec)
+JSValue* TryNode::execute(OldInterpreterExecState*)
 {
-    JSValue* result = m_tryBlock->execute(exec);
-
-    if (m_catchBlock && exec->completionType() == Throw) {
-        JSObject* obj = new JSObject;
-        obj->putDirect(m_exceptionIdent, result, DontDelete);
-        exec->dynamicGlobalObject()->tearOffActivation(exec);
-        exec->pushScope(obj);
-        result = m_catchBlock->execute(exec);
-        exec->popScope();
-    }
-
-    if (m_finallyBlock) {
-        ComplType savedCompletionType = exec->completionType();
-        JSValue* finallyResult = m_finallyBlock->execute(exec);
-        if (exec->completionType() != Normal)
-            result = finallyResult;
-        else
-            exec->setCompletionType(savedCompletionType);
-    }
-
-    return result;
+    ASSERT_NOT_REACHED();
+    return 0;
 }
 
 // ------------------------------ FunctionBodyNode -----------------------------
@@ -4608,6 +5753,10 @@
 {
 }
 
+ProgramNode::~ProgramNode()
+{
+}
+
 ProgramNode* ProgramNode::create(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
 {
     return new ProgramNode(children, varStack, funcStack, usesEval, needsClosure);
@@ -4620,6 +5769,33 @@
 {
 }
 
+EvalNode::~EvalNode()
+{
+}
+
+RegisterID* EvalNode::emitCode(CodeGenerator& generator, RegisterID*)
+{
+    RefPtr<RegisterID> dstRegister = generator.newTemporary();
+    generator.emitLoad(dstRegister.get(), jsUndefined());
+    statementListEmitCode(m_children, generator, dstRegister.get());
+    generator.emitEnd(dstRegister.get());
+    return 0;
+}
+
+void EvalNode::generateCode(ScopeChainNode* sc)
+{
+    ScopeChain scopeChain(sc);
+    JSGlobalObject* globalObject = static_cast<JSGlobalObject*>(scopeChain.bottom());
+    ASSERT(globalObject->isGlobalObject());
+    
+    m_code.set(new EvalCodeBlock(this, globalObject));
+    
+    CodeGenerator generator(this, globalObject->debugger(), scopeChain, new SymbolTable(), m_code.get(), m_varStack, m_functionStack);
+    generator.generate();
+
+    m_children.shrinkCapacity(0);
+}
+
 EvalNode* EvalNode::create(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
 {
     return new EvalNode(children, varStack, funcStack, usesEval, needsClosure);
@@ -4629,45 +5805,74 @@
 
 FunctionBodyNode::FunctionBodyNode(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
     : ScopeNode(children, varStack, funcStack, usesEval, needsClosure)
-    , m_initialized(false)
 {
 }
 
+FunctionBodyNode::~FunctionBodyNode()
+{
+}
+
+void FunctionBodyNode::mark()
+{
+    if (m_code)
+        m_code->mark();
+}
+
 FunctionBodyNode* FunctionBodyNode::create(SourceElements* children, VarStack* varStack, FunctionStack* funcStack, bool usesEval, bool needsClosure)
 {
-    if (Debugger::debuggersPresent)
-        return new FunctionBodyNodeWithDebuggerHooks(children, varStack, funcStack, usesEval, needsClosure);
     return new FunctionBodyNode(children, varStack, funcStack, usesEval, needsClosure);
 }
 
-void FunctionBodyNode::initializeSymbolTable(ExecState* exec)
+void FunctionBodyNode::generateCode(ScopeChainNode* sc)
 {
-    SymbolTable& symbolTable = exec->variableObject()->symbolTable();
-    ASSERT(symbolTable.isEmpty());
+    m_code.set(new CodeBlock(this));
 
-    size_t localStorageIndex = 0;
+    ScopeChain scopeChain(sc);
+    JSGlobalObject* globalObject = static_cast<JSGlobalObject*>(scopeChain.bottom());
+    ASSERT(globalObject->isGlobalObject());
 
-    // Order must match the order in processDeclarations.
+    CodeGenerator generator(this, globalObject->debugger(), scopeChain, &m_symbolTable, m_code.get(), m_varStack, m_functionStack, m_parameters);
+    generator.generate();
 
-    for (size_t i = 0, size = m_parameters.size(); i < size; ++i, ++localStorageIndex) {
-        UString::Rep* rep = m_parameters[i].ustring().rep();
-        symbolTable.set(rep, localStorageIndex);
-    }
-
-    for (size_t i = 0, size = m_functionStack.size(); i < size; ++i, ++localStorageIndex) {
-        UString::Rep* rep = m_functionStack[i]->m_ident.ustring().rep();
-        symbolTable.set(rep, localStorageIndex);
-    }
-
-    for (size_t i = 0, size = m_varStack.size(); i < size; ++i, ++localStorageIndex) {
-        Identifier& ident = m_varStack[i].first;
-        if (ident == exec->propertyNames().arguments)
-            continue;
-        symbolTable.add(ident.ustring().rep(), localStorageIndex);
-    }
+    m_children.shrinkCapacity(0);
 }
 
-void ProgramNode::initializeSymbolTable(ExecState* exec)
+RegisterID* FunctionBodyNode::emitCode(CodeGenerator& generator, RegisterID*)
+{
+    generator.emitDebugHook(DidEnterCallFrame, firstLine(), lastLine());
+    statementListEmitCode(m_children, generator);
+    if (!m_children.size() || !m_children.last()->isReturnNode()) {
+        RegisterID* r0 = generator.emitLoad(generator.newTemporary(), jsUndefined());
+        generator.emitDebugHook(WillLeaveCallFrame, firstLine(), lastLine());
+        generator.emitReturn(r0);
+    }
+    return 0;
+}
+
+RegisterID* ProgramNode::emitCode(CodeGenerator& generator, RegisterID*)
+{
+    RefPtr<RegisterID> dstRegister = generator.newTemporary();
+    generator.emitLoad(dstRegister.get(), jsUndefined());
+    statementListEmitCode(m_children, generator, dstRegister.get());
+    generator.emitEnd(dstRegister.get());
+    return 0;
+}
+
+void ProgramNode::generateCode(ScopeChainNode* sc, bool canCreateGlobals)
+{
+    ScopeChain scopeChain(sc);
+    JSGlobalObject* globalObject = static_cast<JSGlobalObject*>(scopeChain.bottom());
+    ASSERT(globalObject->isGlobalObject());
+    
+    m_code.set(new ProgramCodeBlock(this, globalObject));
+    
+    CodeGenerator generator(this, globalObject->debugger(), scopeChain, &globalObject->symbolTable(), m_code.get(), m_varStack, m_functionStack, canCreateGlobals);
+    generator.generate();
+
+    m_children.shrinkCapacity(0);
+}
+
+void ProgramNode::initializeSymbolTable(OldInterpreterExecState* exec)
 {
     // If a previous script defined a symbol with the same name as one of our
     // symbols, to avoid breaking previously optimized nodes, we need to reuse
@@ -4688,7 +5893,7 @@
     for (size_t i = 0; i < size; ++i) {
         UString::Rep* rep = m_functionStack[i]->m_ident.ustring().rep();
         pair<SymbolTable::iterator, bool> result = symbolTable.add(rep, localStorageIndex);
-        m_functionIndexes[i] = result.first->second;
+        m_functionIndexes[i] = result.first->second.getIndex();
         if (result.second)
             ++localStorageIndex;
     }
@@ -4709,12 +5914,12 @@
             continue;
         }
 
-        m_varIndexes[i] = result.first->second;
+        m_varIndexes[i] = result.first->second.getIndex();
         ++localStorageIndex;
     }
 }
 
-void ScopeNode::optimizeVariableAccess(ExecState* exec)
+void ScopeNode::optimizeVariableAccess(OldInterpreterExecState* exec)
 {
     NodeStack nodeStack;
     Node* node = statementListInitializeVariableAccessStack(m_children, nodeStack);
@@ -4722,7 +5927,8 @@
         return;
 
     const SymbolTable& symbolTable = exec->variableObject()->symbolTable();
-    const LocalStorage& localStorage = exec->variableObject()->localStorage();
+    ASSERT_NOT_REACHED();
+    const LocalStorage localStorage;
     while (true) {
         node->optimizeVariableAccess(exec, symbolTable, localStorage, nodeStack);
 
@@ -4735,55 +5941,12 @@
     }
 }
 
-void FunctionBodyNode::processDeclarations(ExecState* exec)
-{
-    if (!m_initialized)
-        initializeSymbolTable(exec);
-
-    if (!m_functionStack.isEmpty())
-        exec->dynamicGlobalObject()->tearOffActivation(exec);
-
-    LocalStorage& localStorage = exec->variableObject()->localStorage();
-
-    // We can't just resize localStorage here because that would temporarily
-    // leave uninitialized entries, which would crash GC during the mark phase.
-    size_t totalSize = m_varStack.size() + m_parameters.size() + m_functionStack.size();
-    if (totalSize > localStorage.capacity()) // Doing this check inline avoids function call overhead.
-        localStorage.reserveCapacity(totalSize);
-
-    int minAttributes = DontDelete;
-
-    // In order for our localStorage indexes to be correct, we must match the
-    // order of addition in initializeSymbolTable().
-
-    const List& args = *exec->arguments();
-    for (size_t i = 0, size = m_parameters.size(); i < size; ++i)
-        localStorage.uncheckedAppend(LocalStorageEntry(args[i], DontDelete));
-
-    for (size_t i = 0, size = m_functionStack.size(); i < size; ++i) {
-        FuncDeclNode* node = m_functionStack[i];
-        localStorage.uncheckedAppend(LocalStorageEntry(node->makeFunction(exec), minAttributes));
-    }
-
-    for (size_t i = 0, size = m_varStack.size(); i < size; ++i) {
-        int attributes = minAttributes;
-        if (m_varStack[i].second & DeclarationStacks::IsConstant)
-            attributes |= ReadOnly;
-        localStorage.uncheckedAppend(LocalStorageEntry(jsUndefined(), attributes));
-    }
-
-    if (!m_initialized) {
-        optimizeVariableAccess(exec);
-        m_initialized = true;
-    }
-}
-
 static void gccIsCrazy() KJS_FAST_CALL;
 static void gccIsCrazy()
 {
 }
 
-void ProgramNode::processDeclarations(ExecState* exec)
+void ProgramNode::processDeclarations(OldInterpreterExecState* exec)
 {
     // If you remove this call, some SunSpider tests, including
     // bitops-nsieve-bits.js, will regress substantially on Mac, due to a ~40%
@@ -4792,7 +5955,8 @@
 
     initializeSymbolTable(exec);
 
-    LocalStorage& localStorage = exec->variableObject()->localStorage();
+    ASSERT_NOT_REACHED();
+    LocalStorage localStorage;
 
     // We can't just resize localStorage here because that would temporarily
     // leave uninitialized entries, which would crash GC during the mark phase.
@@ -4805,7 +5969,7 @@
 
     for (size_t i = 0, size = m_functionStack.size(); i < size; ++i) {
         FuncDeclNode* node = m_functionStack[i];
-        LocalStorageEntry entry = LocalStorageEntry(node->makeFunction(exec), minAttributes);
+        LocalStorageEntry entry = LocalStorageEntry(node->makeFunction(exec, exec->scopeChain().node()), minAttributes);
         size_t index = m_functionIndexes[i];
 
         if (index == localStorage.size())
@@ -4817,7 +5981,7 @@
     }
 
     for (size_t i = 0, size = m_varStack.size(); i < size; ++i) {
-        size_t index = m_varIndexes[i];
+        int index = m_varIndexes[i];
         if (index == missingSymbolMarker())
             continue;
 
@@ -4826,14 +5990,14 @@
             attributes |= ReadOnly;
         LocalStorageEntry entry = LocalStorageEntry(jsUndefined(), attributes);
 
-        ASSERT(index == localStorage.size());
+        ASSERT(static_cast<unsigned>(index) == localStorage.size());
         localStorage.uncheckedAppend(entry);
     }
 
     optimizeVariableAccess(exec);
 }
 
-void EvalNode::processDeclarations(ExecState* exec)
+void EvalNode::processDeclarations(OldInterpreterExecState* exec)
 {
     // We could optimize access to pre-existing symbols here, but SunSpider
     // reports that to be a net loss.
@@ -4855,7 +6019,7 @@
 
     for (i = 0, size = m_functionStack.size(); i < size; ++i) {
         FuncDeclNode* funcDecl = m_functionStack[i];
-        variableObject->putWithAttributes(exec, funcDecl->m_ident, funcDecl->makeFunction(exec), 0);
+        variableObject->putWithAttributes(exec, funcDecl->m_ident, funcDecl->makeFunction(exec, exec->scopeChain().node()), 0);
     }
 }
 
@@ -4872,19 +6036,13 @@
     return s;
 }
 
-JSValue* ProgramNode::execute(ExecState* exec)
+JSValue* ProgramNode::execute(OldInterpreterExecState* exec)
 {
     processDeclarations(exec);
     return ScopeNode::execute(exec);
 }
 
-JSValue* EvalNode::execute(ExecState* exec)
-{
-    processDeclarations(exec);
-    return ScopeNode::execute(exec);
-}
-
-JSValue* FunctionBodyNode::execute(ExecState* exec)
+JSValue* EvalNode::execute(OldInterpreterExecState* exec)
 {
     processDeclarations(exec);
     return ScopeNode::execute(exec);
@@ -4897,22 +6055,10 @@
 {
 }
 
-JSValue* FunctionBodyNodeWithDebuggerHooks::execute(ExecState* exec)
+JSValue* FunctionBodyNodeWithDebuggerHooks::execute(OldInterpreterExecState* exec)
 {
-    if (Debugger* dbg = exec->dynamicGlobalObject()->debugger()) {
-        if (!dbg->callEvent(exec, sourceId(), lineNo(), exec->function(), *exec->arguments()))
-            return exec->setInterruptedCompletion();
-    }
-
     JSValue* result = FunctionBodyNode::execute(exec);
 
-    if (Debugger* dbg = exec->dynamicGlobalObject()->debugger()) {
-        if (exec->completionType() == Throw)
-            exec->setException(result);
-        if (!dbg->returnEvent(exec, sourceId(), lastLine(), exec->function()))
-            return exec->setInterruptedCompletion();
-    }
-
     return result;
 }
 
@@ -4924,9 +6070,9 @@
         m_body->parameters().append(p->ident());
 }
 
-FunctionImp* FuncDeclNode::makeFunction(ExecState* exec)
+FunctionImp* FuncDeclNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
 {
-    FunctionImp* func = new FunctionImp(exec, m_ident, m_body.get(), exec->scopeChain());
+    FunctionImp* func = new FunctionImp(exec, m_ident, m_body.get(), scopeChain);
 
     JSObject* proto = exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList());
     proto->putDirect(exec->propertyNames().constructor, func, DontEnum);
@@ -4935,13 +6081,47 @@
     return func;
 }
 
-JSValue* FuncDeclNode::execute(ExecState* exec)
+RegisterID* FuncDeclNode::emitCode(CodeGenerator&, RegisterID* dst)
+{
+    return dst;
+}
+
+JSValue* FuncDeclNode::execute(OldInterpreterExecState* exec)
 {
     return exec->setNormalCompletion();
 }
 
 // ------------------------------ FuncExprNode ---------------------------------
 
+RegisterID* FuncExprNode::emitCode(CodeGenerator& generator, RegisterID* dst)
+{
+    return generator.emitNewFunctionExpression(generator.finalDestination(dst), this);
+}
+
+FunctionImp* FuncExprNode::makeFunction(ExecState* exec, ScopeChainNode* scopeChain)
+{
+    FunctionImp* func = new FunctionImp(exec, m_ident, m_body.get(), scopeChain);
+    JSObject* proto = exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList());
+    proto->putDirect(exec->propertyNames().constructor, func, DontEnum);
+    func->putDirect(exec->propertyNames().prototype, proto, DontDelete);
+
+    /* 
+        The Identifier in a FunctionExpression can be referenced from inside
+        the FunctionExpression's FunctionBody to allow the function to call
+        itself recursively. However, unlike in a FunctionDeclaration, the
+        Identifier in a FunctionExpression cannot be referenced from and
+        does not affect the scope enclosing the FunctionExpression.
+     */
+
+    if (!m_ident.isNull()) {
+        JSObject* functionScopeObject = new JSObject;
+        functionScopeObject->putDirect(m_ident, func, ReadOnly | DontDelete);
+        func->scope().push(functionScopeObject);
+    }
+
+    return func;
+}
+
 // ECMA 13
 void FuncExprNode::addParams()
 {
@@ -4949,9 +6129,9 @@
         m_body->parameters().append(p->ident());
 }
 
-JSValue* FuncExprNode::evaluate(ExecState* exec)
+JSValue* FuncExprNode::evaluate(OldInterpreterExecState* exec)
 {
-    exec->dynamicGlobalObject()->tearOffActivation(exec);
+    ASSERT_NOT_REACHED();
 
     bool named = !m_ident.isNull();
     JSObject* functionScopeObject = 0;
@@ -4964,7 +6144,7 @@
         exec->pushScope(functionScopeObject);
     }
 
-    FunctionImp* func = new FunctionImp(exec, m_ident, m_body.get(), exec->scopeChain());
+    FunctionImp* func = new FunctionImp(exec, m_ident, m_body.get(), exec->scopeChain().node());
     JSObject* proto = exec->lexicalGlobalObject()->objectConstructor()->construct(exec, exec->emptyList());
     proto->putDirect(exec->propertyNames().constructor, func, DontEnum);
     func->putDirect(exec->propertyNames().prototype, proto, DontDelete);
diff --git a/JavaScriptCore/kjs/nodes.h b/JavaScriptCore/kjs/nodes.h
index 6a086d0..ddebedf 100644
--- a/JavaScriptCore/kjs/nodes.h
+++ b/JavaScriptCore/kjs/nodes.h
@@ -28,7 +28,10 @@
 
 #include "internal.h"
 #include "regexp.h"
+#include "RegisterID.h"
+#include "SourceRange.h"
 #include "SymbolTable.h"
+#include <wtf/UnusedParam.h>
 #include <wtf/ListRefPtr.h>
 #include <wtf/MathExtras.h>
 #include <wtf/OwnPtr.h>
@@ -43,9 +46,13 @@
 namespace KJS {
 
     class ArgumentsNode;
+    class CodeBlock;
+    class CodeGenerator;
     class ConstDeclNode;
     class FuncDeclNode;
     class Node;
+    class EvalCodeBlock;
+    class ProgramCodeBlock;
     class PropertyListNode;
     class SourceStream;
 
@@ -137,40 +144,74 @@
         {
         }
 
+        /*
+            Return value: The register holding the production's value.
+                     dst: An optional parameter specifying the most efficient
+                          destination at which to store the production's value.
+                          The callee must honor dst.
+
+            dst provides for a crude form of copy propagation. For example,
+
+            x = 1
+
+            becomes
+            
+            load r[x], 1
+            
+            instead of 
+
+            load r0, 1
+            mov r[x], r0
+            
+            because the assignment node, "x =", passes r[x] as dst to the number
+            node, "1".
+        */
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* dst = 0) KJS_FAST_CALL 
+        {
+            ASSERT_WITH_MESSAGE(0, "Don't know how to generate code for:\n%s\n", toString().ascii());
+            UNUSED_PARAM(dst); 
+            return 0; 
+        } // FIXME: Make this pure virtual.
+
         UString toString() const KJS_FAST_CALL;
         int lineNo() const KJS_FAST_CALL { return m_line; }
 
+        virtual bool isReturnNode() const KJS_FAST_CALL { return false; }
+
         // Serialization.
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL = 0;
         virtual Precedence precedence() const = 0;
         virtual bool needsParensIfLeftmost() const { return false; }
-
+        
         // Used for iterative, depth-first traversal of the node tree. Does not cross function call boundaries.
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL { }
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL { }
 
     protected:
         Node(JSType) KJS_FAST_CALL; // used by ExpressionNode
 
         // 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;
+        JSValue* setErrorCompletion(OldInterpreterExecState*, ErrorType, const char* msg) KJS_FAST_CALL;
+        JSValue* setErrorCompletion(OldInterpreterExecState*, 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;
-        JSValue* throwError(ExecState*, ErrorType, const char* msg, const Identifier&) KJS_FAST_CALL;
-        JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, const Identifier&) KJS_FAST_CALL;
-        JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, Node*, Node*) KJS_FAST_CALL;
-        JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, Node*, const Identifier&) KJS_FAST_CALL;
+        JSValue* throwError(OldInterpreterExecState*, ErrorType, const char* msg) KJS_FAST_CALL;
+        JSValue* throwError(OldInterpreterExecState*, ErrorType, const char* msg, const char*) KJS_FAST_CALL;
+        JSValue* throwError(OldInterpreterExecState*, ErrorType, const char* msg, JSValue*, Node*) KJS_FAST_CALL;
+        JSValue* throwError(OldInterpreterExecState*, ErrorType, const char* msg, const Identifier&) KJS_FAST_CALL;
+        JSValue* throwError(OldInterpreterExecState*, ErrorType, const char* msg, JSValue*, const Identifier&) KJS_FAST_CALL;
+        JSValue* throwError(OldInterpreterExecState*, ErrorType, const char* msg, JSValue*, Node*, Node*) KJS_FAST_CALL;
+        JSValue* throwError(OldInterpreterExecState*, ErrorType, const char* msg, JSValue*, Node*, const Identifier&) KJS_FAST_CALL;
+        
+        RegisterID* emitThrowError(CodeGenerator&, ErrorType, const char* msg);
+        RegisterID* emitThrowError(CodeGenerator&, ErrorType, const char* msg, const Identifier&);
 
-        JSValue* throwUndefinedVariableError(ExecState*, const Identifier&) KJS_FAST_CALL;
+        JSValue* throwUndefinedVariableError(OldInterpreterExecState*, const Identifier&) KJS_FAST_CALL;
 
-        void handleException(ExecState*) KJS_FAST_CALL;
-        void handleException(ExecState*, JSValue*) KJS_FAST_CALL;
+        void handleException(OldInterpreterExecState*) KJS_FAST_CALL;
+        void handleException(OldInterpreterExecState*, JSValue*) KJS_FAST_CALL;
 
         // for use in execute()
-        JSValue* rethrowException(ExecState*) KJS_FAST_CALL;
+        JSValue* rethrowException(OldInterpreterExecState*) KJS_FAST_CALL;
 
         int m_line : 28;
         unsigned m_expectedReturnType : 3; // JSType
@@ -198,11 +239,11 @@
 
         JSType expectedReturnType() const KJS_FAST_CALL { return static_cast<JSType>(m_expectedReturnType); }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL = 0;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL = 0;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
 
         // Used to optimize those nodes that do extra work when returning a result, even if the result has no semantic relevance
         virtual void optimizeForUnnecessaryResult() { }
@@ -210,7 +251,7 @@
         // This needs to be in public in order to compile using GCC 3.x 
         typedef enum { EvalOperator, FunctionCall } CallerType;
     protected:
-        template <CallerType, bool> inline JSValue* resolveAndCall(ExecState*, const Identifier&, ArgumentsNode*, size_t = 0);
+        template <CallerType, bool> inline JSValue* resolveAndCall(OldInterpreterExecState*, const Identifier&, ArgumentsNode*, size_t = 0);
     };
 
     class StatementNode : public Node {
@@ -219,7 +260,9 @@
         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; }
-        virtual JSValue* execute(ExecState *exec) KJS_FAST_CALL = 0;
+
+        virtual JSValue* execute(OldInterpreterExecState *exec) KJS_FAST_CALL = 0;
+
         virtual void pushLabel(const Identifier& ident) KJS_FAST_CALL { m_labelStack.push(ident); }
         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
         virtual bool isEmptyStatement() const KJS_FAST_CALL { return false; }
@@ -233,8 +276,14 @@
 
     class NullNode : public ExpressionNode {
     public:
-        NullNode() KJS_FAST_CALL : ExpressionNode(NullType) {}
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        NullNode() KJS_FAST_CALL
+            : ExpressionNode(NullType)
+        {
+        }
+
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPrimary; }
     };
@@ -246,8 +295,10 @@
         {
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL { return false; }
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL { return false; }
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPrimary; }
     };
@@ -259,8 +310,10 @@
         {
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL { return true; }
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL { return true; }
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPrimary; }
     };
@@ -284,11 +337,13 @@
         {
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return signbit(m_double) ? PrecUnary : PrecPrimary; }
 
@@ -309,9 +364,9 @@
             ASSERT(v == JSImmediate::from(d));
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
 
         virtual void setValue(double d) KJS_FAST_CALL { m_double = d; m_value = JSImmediate::from(d); ASSERT(m_value); }
 
@@ -327,9 +382,11 @@
         {
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPrimary; }
 
@@ -344,7 +401,9 @@
         {
         }
 
-        JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPrimary; }
 
@@ -358,7 +417,9 @@
         {
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPrimary; }
     };
@@ -377,13 +438,14 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPrimary; }
 
@@ -392,36 +454,36 @@
         const Identifier& identifier() const KJS_FAST_CALL { return m_ident; }
 
     protected:
-        ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
+        ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);
         Identifier m_ident;
-        size_t m_index; // Used by LocalVarAccessNode and ScopedVarAccessNode.
+        int m_index; // Used by LocalVarAccessNode and ScopedVarAccessNode.
         size_t m_scopeDepth; // Used by ScopedVarAccessNode
     };
 
     class LocalVarAccessNode : public ResolveNode {
     public:
         // Overwrites a ResolveNode in place.
-        LocalVarAccessNode(size_t i) KJS_FAST_CALL
+        LocalVarAccessNode(int i) KJS_FAST_CALL
             : ResolveNode(PlacementNewAdopt)
         {
             ASSERT(i != missingSymbolMarker());
             m_index = i;
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
 
     private:
-        ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
+        ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);
     };
     
     class ScopedVarAccessNode : public ResolveNode {
     public:
         // Overwrites a ResolveNode in place.
-        ScopedVarAccessNode(size_t i, size_t scopeDepth) KJS_FAST_CALL
+        ScopedVarAccessNode(int i, size_t scopeDepth) KJS_FAST_CALL
         : ResolveNode(PlacementNewAdopt)
         {
             ASSERT(i != missingSymbolMarker());
@@ -429,14 +491,14 @@
             m_scopeDepth = scopeDepth;
         }
         
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
         
     private:
-        ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
+        ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);
     };
     
     class NonLocalVarAccessNode : public ResolveNode {
@@ -449,14 +511,14 @@
             m_scopeDepth = scopeDepth;
         }
         
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
         
     private:
-        ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
+        ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);
     };
 
     class ElementNode : public Node {
@@ -476,11 +538,11 @@
 
         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
 
         PassRefPtr<ElementNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
 
-        JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
 
     private:
         friend class ArrayNode;
@@ -511,8 +573,10 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPrimary; }
 
@@ -533,11 +597,11 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
 
-        JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         const Identifier& name() const { return m_name; }
 
     private:
@@ -560,11 +624,12 @@
             list->m_next = this;
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
 
-        JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         PassRefPtr<PropertyListNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
 
     private:
@@ -584,8 +649,9 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPrimary; }
         virtual bool needsParensIfLeftmost() const { return true; }
@@ -602,12 +668,14 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecMember; }
 
@@ -617,7 +685,7 @@
         ExpressionNode* subscript() KJS_FAST_CALL { return m_subscript.get(); }
 
     private:
-        ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
+        ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);
 
         RefPtr<ExpressionNode> m_base;
         RefPtr<ExpressionNode> m_subscript;
@@ -631,12 +699,13 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecMember; }
 
@@ -646,7 +715,7 @@
         const Identifier& identifier() const KJS_FAST_CALL { return m_ident; }
 
     private:
-        ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
+        ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);
 
         RefPtr<ExpressionNode> m_base;
         Identifier m_ident;
@@ -665,15 +734,14 @@
             listNode->m_next = this;
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
 
-        void evaluateList(ExecState*, List&) KJS_FAST_CALL;
+        void evaluateList(OldInterpreterExecState*, List&) KJS_FAST_CALL;
         PassRefPtr<ArgumentListNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
 
-    private:
-        friend class ArgumentsNode;
         ListRefPtr<ArgumentListNode> m_next;
         RefPtr<ExpressionNode> m_expr;
     };
@@ -689,13 +757,12 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
 
-        void evaluateList(ExecState* exec, List& list) KJS_FAST_CALL { if (m_listNode) m_listNode->evaluateList(exec, list); }
+        void evaluateList(OldInterpreterExecState* exec, List& list) KJS_FAST_CALL { if (m_listNode) m_listNode->evaluateList(exec, list); }
 
-    private:
         RefPtr<ArgumentListNode> m_listNode;
     };
 
@@ -712,17 +779,19 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecLeftHandSide; }
 
     private:
-        ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
+        ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);
 
         RefPtr<ExpressionNode> m_expr;
         RefPtr<ArgumentsNode> m_args;
@@ -735,8 +804,9 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecCall; }
 
@@ -752,8 +822,9 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecCall; }
 
@@ -777,17 +848,19 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecCall; }
 
     protected:
-        ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
+        ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);
 
         Identifier m_ident;
         RefPtr<ArgumentsNode> m_args;
@@ -797,26 +870,26 @@
     
     class LocalVarFunctionCallNode : public FunctionCallResolveNode {
     public:
-        LocalVarFunctionCallNode(size_t i) KJS_FAST_CALL
+        LocalVarFunctionCallNode(int i) KJS_FAST_CALL
             : FunctionCallResolveNode(PlacementNewAdopt)
         {
             ASSERT(i != missingSymbolMarker());
             m_index = i;
         }
         
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
         
     private:
-        ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
+        ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);
     };
     
     class ScopedVarFunctionCallNode : public FunctionCallResolveNode {
     public:
-        ScopedVarFunctionCallNode(size_t i, size_t depth) KJS_FAST_CALL
+        ScopedVarFunctionCallNode(int i, size_t depth) KJS_FAST_CALL
             : FunctionCallResolveNode(PlacementNewAdopt)
         {
             ASSERT(i != missingSymbolMarker());
@@ -824,14 +897,14 @@
             m_scopeDepth = depth;
         }
         
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
         
     private:
-        ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
+        ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);
     };
     
     class NonLocalVarFunctionCallNode : public FunctionCallResolveNode {
@@ -842,14 +915,14 @@
             m_scopeDepth = depth;
         }
         
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
         
     private:
-        ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
+        ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);
     };
 
     class FunctionCallBracketNode : public ExpressionNode {
@@ -861,8 +934,9 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecCall; }
 
@@ -881,17 +955,18 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecCall; }
 
     private:
-        ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
+        ALWAYS_INLINE JSValue* inlineEvaluate(OldInterpreterExecState*);
 
         RefPtr<ExpressionNode> m_base;
         Identifier m_ident;
@@ -929,8 +1004,9 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPostfix; }
         virtual void optimizeForUnnecessaryResult();
@@ -938,27 +1014,27 @@
 
     class PostIncLocalVarNode : public PostIncResolveNode {
     public:
-        PostIncLocalVarNode(size_t i) KJS_FAST_CALL
+        PostIncLocalVarNode(int i) KJS_FAST_CALL
             : PostIncResolveNode(PlacementNewAdopt)
         {
             ASSERT(i != missingSymbolMarker());
             m_index = i;
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void optimizeForUnnecessaryResult();
     };
 
     class PostIncConstNode : public PostIncResolveNode {
     public:
-        PostIncConstNode(size_t i) KJS_FAST_CALL
+        PostIncConstNode(int i) KJS_FAST_CALL
             : PostIncResolveNode(PlacementNewAdopt)
         {
             ASSERT(i != missingSymbolMarker());
             m_index = i;
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
     };
 
     class PostDecResolveNode : public PrePostResolveNode {
@@ -973,8 +1049,10 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPostfix; }
         virtual void optimizeForUnnecessaryResult();
@@ -982,34 +1060,34 @@
 
     class PostDecLocalVarNode : public PostDecResolveNode {
     public:
-        PostDecLocalVarNode(size_t i) KJS_FAST_CALL
+        PostDecLocalVarNode(int i) KJS_FAST_CALL
             : PostDecResolveNode(PlacementNewAdopt)
         {
             ASSERT(i != missingSymbolMarker());
             m_index = i;
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void optimizeForUnnecessaryResult();
 
     private:
-        ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
+        ALWAYS_INLINE double inlineEvaluateToNumber(OldInterpreterExecState*);
     };
 
     class PostDecConstNode : public PostDecResolveNode {
     public:
-        PostDecConstNode(size_t i) KJS_FAST_CALL
+        PostDecConstNode(int i) KJS_FAST_CALL
             : PostDecResolveNode(PlacementNewAdopt)
         {
             ASSERT(i != missingSymbolMarker());
             m_index = i;
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
     };
 
     class PostfixBracketNode : public ExpressionNode {
@@ -1020,7 +1098,7 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPostfix; }
 
     protected:
@@ -1035,7 +1113,9 @@
         {
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     };
 
@@ -1046,7 +1126,9 @@
         {
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     };
 
@@ -1058,7 +1140,7 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPostfix; }
 
     protected:
@@ -1073,7 +1155,9 @@
         {
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     };
 
@@ -1084,7 +1168,9 @@
         {
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     };
 
@@ -1096,7 +1182,8 @@
         {
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPostfix; }
 
@@ -1118,8 +1205,10 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
 
@@ -1134,7 +1223,7 @@
         {
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
     };
 
     class DeleteBracketNode : public ExpressionNode {
@@ -1145,8 +1234,10 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
 
@@ -1163,8 +1254,10 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
 
@@ -1180,8 +1273,10 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
 
@@ -1196,8 +1291,10 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
 
@@ -1220,9 +1317,10 @@
             m_expectedReturnType = StringType;
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
 
@@ -1235,7 +1333,7 @@
 
     class LocalVarTypeOfNode : public TypeOfResolveNode {
     public:
-        LocalVarTypeOfNode(size_t i) KJS_FAST_CALL
+        LocalVarTypeOfNode(int i) KJS_FAST_CALL
             : TypeOfResolveNode(PlacementNewAdopt)
         {
             m_expectedReturnType = StringType;
@@ -1243,7 +1341,7 @@
             m_index = i;
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
     };
 
     class TypeOfValueNode : public ExpressionNode {
@@ -1254,8 +1352,10 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
 
@@ -1275,35 +1375,36 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
     };
 
     class PreIncLocalVarNode : public PreIncResolveNode {
     public:
-        PreIncLocalVarNode(size_t i) KJS_FAST_CALL
+        PreIncLocalVarNode(int i) KJS_FAST_CALL
             : PreIncResolveNode(PlacementNewAdopt)
         {
             ASSERT(i != missingSymbolMarker());
             m_index = i;
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
     };
 
     class PreIncConstNode : public PreIncResolveNode {
     public:
-        PreIncConstNode(size_t i) KJS_FAST_CALL
+        PreIncConstNode(int i) KJS_FAST_CALL
             : PreIncResolveNode(PlacementNewAdopt)
         {
             ASSERT(i != missingSymbolMarker());
             m_index = i;
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
     };
 
     class PreDecResolveNode : public PrePostResolveNode {
@@ -1318,35 +1419,36 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
     };
 
     class PreDecLocalVarNode : public PreDecResolveNode {
     public:
-        PreDecLocalVarNode(size_t i) KJS_FAST_CALL
+        PreDecLocalVarNode(int i) KJS_FAST_CALL
             : PreDecResolveNode(PlacementNewAdopt)
         {
             ASSERT(i != missingSymbolMarker());
             m_index = i;
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
     };
 
     class PreDecConstNode : public PreDecResolveNode {
     public:
-        PreDecConstNode(size_t i) KJS_FAST_CALL
+        PreDecConstNode(int i) KJS_FAST_CALL
             : PreDecResolveNode(PlacementNewAdopt)
         {
             ASSERT(i != missingSymbolMarker());
             m_index = i;
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
     };
 
     class PrefixBracketNode : public ExpressionNode {
@@ -1357,7 +1459,7 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
 
     protected:
@@ -1372,7 +1474,9 @@
         {
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     };
 
@@ -1383,7 +1487,9 @@
         {
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     };
 
@@ -1395,7 +1501,7 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecPostfix; }
 
     protected:
@@ -1410,7 +1516,9 @@
         {
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     };
 
@@ -1421,7 +1529,9 @@
         {
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
     };
 
@@ -1433,7 +1543,8 @@
         {
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
 
@@ -1450,12 +1561,13 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
 
@@ -1471,9 +1583,10 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
 
@@ -1489,17 +1602,18 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
 
     private:
-        ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
+        ALWAYS_INLINE int32_t inlineEvaluateToInt32(OldInterpreterExecState*);
 
         RefPtr<ExpressionNode> m_expr;
     };
@@ -1512,9 +1626,10 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecUnary; }
 
@@ -1531,17 +1646,18 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecMultiplicitave; }
 
     private:
-        ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
+        ALWAYS_INLINE double inlineEvaluateToNumber(OldInterpreterExecState*);
 
         RefPtr<ExpressionNode> m_term1;
         RefPtr<ExpressionNode> m_term2;
@@ -1556,16 +1672,17 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecMultiplicitave; }
 
     private:
-        ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
+        ALWAYS_INLINE double inlineEvaluateToNumber(OldInterpreterExecState*);
 
         RefPtr<ExpressionNode> m_term1;
         RefPtr<ExpressionNode> m_term2;
@@ -1580,17 +1697,18 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecMultiplicitave; }
 
     private:
-        ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
+        ALWAYS_INLINE double inlineEvaluateToNumber(OldInterpreterExecState*);
 
         RefPtr<ExpressionNode> m_term1;
         RefPtr<ExpressionNode> m_term2;
@@ -1604,11 +1722,12 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecAdditive; }
 
@@ -1624,7 +1743,7 @@
         RefPtr<ExpressionNode> m_term2;
 
     private:
-        ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
+        ALWAYS_INLINE double inlineEvaluateToNumber(OldInterpreterExecState*);
     };
 
     class AddNumbersNode : public AddNode {
@@ -1634,13 +1753,13 @@
         {
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
 
     private:
-        ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*) KJS_FAST_CALL;
+        ALWAYS_INLINE double inlineEvaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
     };
 
     class AddStringLeftNode : public AddNode {
@@ -1650,7 +1769,7 @@
         {
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
     };
 
     class AddStringRightNode : public AddNode {
@@ -1660,7 +1779,7 @@
         {
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
     };
 
     class AddStringsNode : public AddNode {
@@ -1670,7 +1789,7 @@
         {
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
     };
 
     class SubNode : public ExpressionNode {
@@ -1682,16 +1801,17 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecAdditive; }
 
     private:
-        ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
+        ALWAYS_INLINE double inlineEvaluateToNumber(OldInterpreterExecState*);
 
         RefPtr<ExpressionNode> m_term1;
         RefPtr<ExpressionNode> m_term2;
@@ -1706,16 +1826,17 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecShift; }
 
     private:
-        ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
+        ALWAYS_INLINE int32_t inlineEvaluateToInt32(OldInterpreterExecState*);
 
         RefPtr<ExpressionNode> m_term1;
         RefPtr<ExpressionNode> m_term2;
@@ -1730,16 +1851,17 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecShift; }
 
     private:
-        ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
+        ALWAYS_INLINE int32_t inlineEvaluateToInt32(OldInterpreterExecState*);
 
         RefPtr<ExpressionNode> m_term1;
         RefPtr<ExpressionNode> m_term2;
@@ -1754,15 +1876,16 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecShift; }
     private:
-        ALWAYS_INLINE uint32_t inlineEvaluateToUInt32(ExecState*);
+        ALWAYS_INLINE uint32_t inlineEvaluateToUInt32(OldInterpreterExecState*);
 
         RefPtr<ExpressionNode> m_term1;
         RefPtr<ExpressionNode> m_term2;
@@ -1777,14 +1900,15 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecRelational; }
 
     private:
-        ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
+        ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);
 
     protected:
         RefPtr<ExpressionNode> m_expr1;
@@ -1798,11 +1922,11 @@
         {
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
 
     private:
-        ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
+        ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);
     };
 
     class LessStringsNode : public LessNode {
@@ -1812,11 +1936,11 @@
         {
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
 
     private:
-        ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
+        ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);
     };
 
     class GreaterNode : public ExpressionNode {
@@ -1827,14 +1951,15 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecRelational; }
 
     private:
-        ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
+        ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);
 
         RefPtr<ExpressionNode> m_expr1;
         RefPtr<ExpressionNode> m_expr2;
@@ -1848,14 +1973,15 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecRelational; }
 
     private:
-        ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
+        ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);
 
         RefPtr<ExpressionNode> m_expr1;
         RefPtr<ExpressionNode> m_expr2;
@@ -1869,14 +1995,15 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecRelational; }
 
     private:
-        ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
+        ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);
 
         RefPtr<ExpressionNode> m_expr1;
         RefPtr<ExpressionNode> m_expr2;
@@ -1891,9 +2018,10 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecRelational; }
 
@@ -1910,9 +2038,11 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecRelational; }
 
@@ -1930,14 +2060,15 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecEquality; }
 
     private:
-        ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
+        ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);
 
         RefPtr<ExpressionNode> m_expr1;
         RefPtr<ExpressionNode> m_expr2;
@@ -1952,14 +2083,15 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecEquality; }
 
     private:
-        ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
+        ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);
 
         RefPtr<ExpressionNode> m_expr1;
         RefPtr<ExpressionNode> m_expr2;
@@ -1974,14 +2106,15 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecEquality; }
 
     private:
-        ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
+        ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);
 
         RefPtr<ExpressionNode> m_expr1;
         RefPtr<ExpressionNode> m_expr2;
@@ -1996,14 +2129,15 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecEquality; }
 
     private:
-        ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
+        ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);
 
         RefPtr<ExpressionNode> m_expr1;
         RefPtr<ExpressionNode> m_expr2;
@@ -2018,17 +2152,18 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecBitwiseAnd; }
 
     private:
-        ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
+        ALWAYS_INLINE int32_t inlineEvaluateToInt32(OldInterpreterExecState*);
 
         RefPtr<ExpressionNode> m_expr1;
         RefPtr<ExpressionNode> m_expr2;
@@ -2043,17 +2178,18 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecBitwiseOr; }
 
     private:
-        ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
+        ALWAYS_INLINE int32_t inlineEvaluateToInt32(OldInterpreterExecState*);
 
         RefPtr<ExpressionNode> m_expr1;
         RefPtr<ExpressionNode> m_expr2;
@@ -2068,17 +2204,18 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecBitwiseXor; }
 
     private:
-        ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
+        ALWAYS_INLINE int32_t inlineEvaluateToInt32(OldInterpreterExecState*);
 
         RefPtr<ExpressionNode> m_expr1;
         RefPtr<ExpressionNode> m_expr2;
@@ -2096,14 +2233,15 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecLogicalAnd; }
 
     private:
-        ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
+        ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);
 
         RefPtr<ExpressionNode> m_expr1;
         RefPtr<ExpressionNode> m_expr2;
@@ -2118,14 +2256,15 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecLogicalOr; }
 
     private:
-        ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
+        ALWAYS_INLINE bool inlineEvaluateToBoolean(OldInterpreterExecState*);
 
         RefPtr<ExpressionNode> m_expr1;
         RefPtr<ExpressionNode> m_expr2;
@@ -2143,12 +2282,13 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
-        virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
-        virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
-        virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual bool evaluateToBoolean(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual double evaluateToNumber(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual int32_t evaluateToInt32(OldInterpreterExecState*) KJS_FAST_CALL;
+        virtual uint32_t evaluateToUInt32(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecConditional; }
 
@@ -2160,10 +2300,11 @@
 
     class ReadModifyResolveNode : public ExpressionNode {
     public:
-        ReadModifyResolveNode(const Identifier& ident, Operator oper, ExpressionNode*  right) KJS_FAST_CALL
+        ReadModifyResolveNode(const Identifier& ident, Operator oper, ExpressionNode*  right, bool rightHasAssignments) KJS_FAST_CALL
             : m_ident(ident)
-            , m_operator(oper)
             , m_right(right)
+            , m_operator(oper)
+            , m_rightHasAssignments(rightHasAssignments)
         {
         }
 
@@ -2171,50 +2312,55 @@
             : ExpressionNode(PlacementNewAdopt)
             , m_ident(PlacementNewAdopt)
             , m_right(PlacementNewAdopt)
+            , m_rightHasAssignments(true)
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecAssignment; }
 
     protected:
         Identifier m_ident;
-        Operator m_operator;
         RefPtr<ExpressionNode> m_right;
         size_t m_index; // Used by ReadModifyLocalVarNode.
+        Operator m_operator : 31;
+        bool m_rightHasAssignments : 1;
     };
 
     class ReadModifyLocalVarNode : public ReadModifyResolveNode {
     public:
-        ReadModifyLocalVarNode(size_t i) KJS_FAST_CALL
+        ReadModifyLocalVarNode(int i) KJS_FAST_CALL
             : ReadModifyResolveNode(PlacementNewAdopt)
         {
             ASSERT(i != missingSymbolMarker());
             m_index = i;
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
     };
 
     class ReadModifyConstNode : public ReadModifyResolveNode {
     public:
-        ReadModifyConstNode(size_t i) KJS_FAST_CALL
+        ReadModifyConstNode(int i) KJS_FAST_CALL
             : ReadModifyResolveNode(PlacementNewAdopt)
         {
             ASSERT(i != missingSymbolMarker());
             m_index = i;
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
     };
 
     class AssignResolveNode : public ExpressionNode {
     public:
-        AssignResolveNode(const Identifier& ident, ExpressionNode* right) KJS_FAST_CALL
+        AssignResolveNode(const Identifier& ident, ExpressionNode* right, bool rightHasAssignments) KJS_FAST_CALL
             : m_ident(ident)
             , m_right(right)
+            , m_rightHasAssignments(rightHasAssignments)
         {
         }
 
@@ -2224,9 +2370,11 @@
             , m_right(PlacementNewAdopt)
         {
         }
+        
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecAssignment; }
 
@@ -2234,18 +2382,19 @@
         Identifier m_ident;
         RefPtr<ExpressionNode> m_right;
         size_t m_index; // Used by ReadModifyLocalVarNode.
+        bool m_rightHasAssignments;
     };
 
     class AssignLocalVarNode : public AssignResolveNode {
     public:
-        AssignLocalVarNode(size_t i) KJS_FAST_CALL
+        AssignLocalVarNode(int i) KJS_FAST_CALL
             : AssignResolveNode(PlacementNewAdopt)
         {
             ASSERT(i != missingSymbolMarker());
             m_index = i;
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
     };
 
     class AssignConstNode : public AssignResolveNode {
@@ -2255,42 +2404,52 @@
         {
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
     };
 
     class ReadModifyBracketNode : public ExpressionNode {
     public:
-        ReadModifyBracketNode(ExpressionNode* base, ExpressionNode* subscript, Operator oper, ExpressionNode* right) KJS_FAST_CALL
+        ReadModifyBracketNode(ExpressionNode* base, ExpressionNode* subscript, Operator oper, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments) KJS_FAST_CALL
             : m_base(base)
             , m_subscript(subscript)
-            , m_operator(oper)
             , m_right(right)
+            , m_operator(oper)
+            , m_subscriptHasAssignments(subscriptHasAssignments)
+            , m_rightHasAssignments(rightHasAssignments)
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecAssignment; }
 
     protected:
         RefPtr<ExpressionNode> m_base;
         RefPtr<ExpressionNode> m_subscript;
-        Operator m_operator;
         RefPtr<ExpressionNode> m_right;
+        Operator m_operator : 30;
+        bool m_subscriptHasAssignments : 1;
+        bool m_rightHasAssignments : 1;
     };
 
     class AssignBracketNode : public ExpressionNode {
     public:
-        AssignBracketNode(ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right) KJS_FAST_CALL
+        AssignBracketNode(ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments) KJS_FAST_CALL
             : m_base(base)
             , m_subscript(subscript)
             , m_right(right)
+            , m_subscriptHasAssignments(subscriptHasAssignments)
+            , m_rightHasAssignments(rightHasAssignments)
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecAssignment; }
 
@@ -2298,19 +2457,23 @@
         RefPtr<ExpressionNode> m_base;
         RefPtr<ExpressionNode> m_subscript;
         RefPtr<ExpressionNode> m_right;
+        bool m_subscriptHasAssignments : 1;
+        bool m_rightHasAssignments : 1;
     };
 
     class AssignDotNode : public ExpressionNode {
     public:
-        AssignDotNode(ExpressionNode* base, const Identifier& ident, ExpressionNode* right) KJS_FAST_CALL
+        AssignDotNode(ExpressionNode* base, const Identifier& ident, ExpressionNode* right, bool rightHasAssignments) KJS_FAST_CALL
             : m_base(base)
             , m_ident(ident)
             , m_right(right)
+            , m_rightHasAssignments(rightHasAssignments)
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecAssignment; }
 
@@ -2318,28 +2481,33 @@
         RefPtr<ExpressionNode> m_base;
         Identifier m_ident;
         RefPtr<ExpressionNode> m_right;
+        bool m_rightHasAssignments;
     };
 
     class ReadModifyDotNode : public ExpressionNode {
     public:
-        ReadModifyDotNode(ExpressionNode* base, const Identifier& ident, Operator oper, ExpressionNode* right) KJS_FAST_CALL
+        ReadModifyDotNode(ExpressionNode* base, const Identifier& ident, Operator oper, ExpressionNode* right, bool rightHasAssignments) KJS_FAST_CALL
             : m_base(base)
             , m_ident(ident)
-            , m_operator(oper)
             , m_right(right)
+            , m_operator(oper)
+            , m_rightHasAssignments(rightHasAssignments)
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecAssignment; }
 
     protected:
         RefPtr<ExpressionNode> m_base;
         Identifier m_ident;
-        Operator m_operator;
         RefPtr<ExpressionNode> m_right;
+        Operator m_operator : 31;
+        bool m_rightHasAssignments : 1;
     };
 
     class AssignErrorNode : public ExpressionNode {
@@ -2351,7 +2519,8 @@
         {
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecAssignment; }
 
@@ -2370,8 +2539,9 @@
             m_expr1->optimizeForUnnecessaryResult();
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecExpression; }
 
@@ -2393,9 +2563,9 @@
     public:
         ConstDeclNode(const Identifier& ident, ExpressionNode* in) KJS_FAST_CALL;
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual KJS::JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        void evaluateSingle(ExecState*) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual KJS::JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        void evaluateSingle(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
         PassRefPtr<ConstDeclNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
@@ -2403,9 +2573,11 @@
         Identifier m_ident;
         ListRefPtr<ConstDeclNode> m_next;
         RefPtr<ExpressionNode> m_init;
-
+        
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual RegisterID* emitCodeSingle(CodeGenerator&) KJS_FAST_CALL;
     private:
-        void handleSlowCase(ExecState*, const ScopeChain&, JSValue*) KJS_FAST_CALL NEVER_INLINE;
+        void handleSlowCase(OldInterpreterExecState*, const ScopeChain&, JSValue*) KJS_FAST_CALL NEVER_INLINE;
     };
 
     class ConstStatementNode : public StatementNode {
@@ -2415,10 +2587,11 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
-
+        
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
     private:
         RefPtr<ConstDeclNode> m_next;
     };
@@ -2442,8 +2615,9 @@
     public:
         BlockNode(SourceElements* children) KJS_FAST_CALL;
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
 
     protected:
@@ -2456,7 +2630,9 @@
         {
         }
 
-        virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual bool isEmptyStatement() const KJS_FAST_CALL { return true; }
     };
@@ -2468,8 +2644,9 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
 
     private:
@@ -2482,9 +2659,11 @@
             : m_expr(expr)
         {
         }
+        
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
 
     private:
@@ -2499,8 +2678,9 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
 
     protected:
@@ -2516,8 +2696,9 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
 
     private:
@@ -2532,8 +2713,9 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
 
     private:
@@ -2549,8 +2731,9 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
 
     private:
@@ -2576,8 +2759,9 @@
             m_expr3->optimizeForUnnecessaryResult();
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
 
     private:
@@ -2592,9 +2776,10 @@
     public:
         ForInNode(ExpressionNode*, ExpressionNode*, StatementNode*) KJS_FAST_CALL;
         ForInNode(const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*) KJS_FAST_CALL;
-
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
+        
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
 
     private:
@@ -2616,8 +2801,9 @@
             : m_ident(ident)
         {
         }
-
-        virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
+        
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
 
     private:
@@ -2634,8 +2820,9 @@
             : m_ident(ident)
         {
         }
-
-        virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
+        
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
 
     private:
@@ -2649,9 +2836,11 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
+        virtual bool isReturnNode() const KJS_FAST_CALL { return true; }
 
     private:
         RefPtr<ExpressionNode> m_value;
@@ -2665,8 +2854,9 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
 
     private:
@@ -2682,8 +2872,9 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual void pushLabel(const Identifier& ident) KJS_FAST_CALL { m_statement->pushLabel(ident); }
 
@@ -2699,8 +2890,9 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
 
     private:
@@ -2717,10 +2909,12 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
 
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* dst = 0) KJS_FAST_CALL;
+
     private:
         RefPtr<StatementNode> m_tryBlock;
         Identifier m_exceptionIdent;
@@ -2764,12 +2958,13 @@
         
         bool usesEval() const { return m_usesEval; }
         bool needsClosure() const { return m_needsClosure; }
-        
+
     protected:
-        void optimizeVariableAccess(ExecState*) KJS_FAST_CALL;
+        void optimizeVariableAccess(OldInterpreterExecState*) KJS_FAST_CALL;
 
         VarStack m_varStack;
         FunctionStack m_functionStack;
+
     private:
         UString m_sourceURL;
         int m_sourceId;
@@ -2780,69 +2975,119 @@
     class ProgramNode : public ScopeNode {
     public:
         static ProgramNode* create(SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL;
+        virtual ~ProgramNode();
+        
+        virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
 
-        virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
+        ProgramCodeBlock& code(ScopeChainNode* scopeChain, bool canCreateGlobals) KJS_FAST_CALL
+        {
+            if (!m_code)
+                generateCode(scopeChain, canCreateGlobals);
+            return *m_code;
+        }
 
     private:
         ProgramNode(SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL;
 
-        void initializeSymbolTable(ExecState*) KJS_FAST_CALL;
-        ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL;
+        void generateCode(ScopeChainNode*, bool) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        void initializeSymbolTable(OldInterpreterExecState*) KJS_FAST_CALL;
+        ALWAYS_INLINE void processDeclarations(OldInterpreterExecState*) KJS_FAST_CALL;
 
         Vector<size_t> m_varIndexes; // Storage indexes belonging to the nodes in m_varStack. (Recorded to avoid double lookup.)
         Vector<size_t> m_functionIndexes; // Storage indexes belonging to the nodes in m_functionStack. (Recorded to avoid double lookup.)
+
+        OwnPtr<ProgramCodeBlock> m_code;
     };
 
     class EvalNode : public ScopeNode {
     public:
         static EvalNode* create(SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL;
+        virtual ~EvalNode();
+        
+        virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
 
-        virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
+        EvalCodeBlock& code(ScopeChainNode* scopeChain) KJS_FAST_CALL
+        {
+            if (!m_code)
+                generateCode(scopeChain);
+            return *m_code;
+        }
 
     private:
         EvalNode(SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL;
 
-        ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL;
+        ALWAYS_INLINE void processDeclarations(OldInterpreterExecState*) KJS_FAST_CALL;
+        void generateCode(ScopeChainNode*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        OwnPtr<EvalCodeBlock> m_code;
     };
 
     class FunctionBodyNode : public ScopeNode {
     public:
         static FunctionBodyNode* create(SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL;
-
-        virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
-
-        SymbolTable& symbolTable() KJS_FAST_CALL { return m_symbolTable; }
-
+        virtual ~FunctionBodyNode();
+        
         Vector<Identifier>& parameters() KJS_FAST_CALL { return m_parameters; }
         UString paramString() const KJS_FAST_CALL;
 
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        
+        SymbolTable& symbolTable() { return m_symbolTable; } // FIXME: Remove this
+        
+        CodeBlock& code(ScopeChainNode* scopeChain) KJS_FAST_CALL
+        {
+            ASSERT(scopeChain);
+            if (!m_code)
+                generateCode(scopeChain);
+            return *m_code;
+        }
+
+        CodeBlock& generatedCode() KJS_FAST_CALL
+        {
+            ASSERT(m_code);
+            return *m_code;
+        }
+
+        void mark();
+
+        void setSource(const SourceRange& source) { m_source = source; } 
+        UString toSourceString() const KJS_FAST_CALL { return UString("{") + m_source.toString() + UString("}"); }
+
     protected:
         FunctionBodyNode(SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL;
 
     private:
-        void initializeSymbolTable(ExecState*) KJS_FAST_CALL;
-        ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL;
-
-        bool m_initialized;
+        void generateCode(ScopeChainNode*) KJS_FAST_CALL;
+        
         Vector<Identifier> m_parameters;
         SymbolTable m_symbolTable;
+        OwnPtr<CodeBlock> m_code;
+        SourceRange m_source;
     };
 
     class FuncExprNode : public ExpressionNode {
     public:
-        FuncExprNode(const Identifier& ident, FunctionBodyNode* body, ParameterNode* parameter = 0) KJS_FAST_CALL
+        FuncExprNode(const Identifier& ident, FunctionBodyNode* body, const SourceRange& source, ParameterNode* parameter = 0) KJS_FAST_CALL
             : m_ident(ident)
             , m_parameter(parameter)
             , m_body(body)
         {
             addParams();
+            m_body->setSource(source);
         }
 
-        virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+        FunctionImp* makeFunction(ExecState*, ScopeChainNode*) KJS_FAST_CALL;
+        virtual JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { return PrecMember; }
         virtual bool needsParensIfLeftmost() const { return true; }
 
+        FunctionBodyNode* body() { return m_body.get(); }
+
     private:
         void addParams() KJS_FAST_CALL;
 
@@ -2855,27 +3100,25 @@
 
     class FuncDeclNode : public StatementNode {
     public:
-        FuncDeclNode(const Identifier& ident, FunctionBodyNode* body) KJS_FAST_CALL
-            : m_ident(ident)
-            , m_body(body)
-        {
-            addParams();
-        }
-
-        FuncDeclNode(const Identifier& ident, ParameterNode* parameter, FunctionBodyNode* body) KJS_FAST_CALL
+        FuncDeclNode(const Identifier& ident, FunctionBodyNode* body, const SourceRange& source, ParameterNode* parameter = 0) KJS_FAST_CALL
             : m_ident(ident)
             , m_parameter(parameter)
             , m_body(body)
         {
             addParams();
+            m_body->setSource(source);
         }
 
-        virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
-        ALWAYS_INLINE FunctionImp* makeFunction(ExecState*) KJS_FAST_CALL;
+        FunctionImp* makeFunction(ExecState*, ScopeChainNode*) KJS_FAST_CALL;
 
         Identifier m_ident;
 
+        FunctionBodyNode* body() { return m_body.get(); }
+
     private:
         void addParams() KJS_FAST_CALL;
 
@@ -2897,12 +3140,15 @@
                 children->releaseContentsIntoVector(m_children);
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
 
-        JSValue* evaluate(ExecState*) KJS_FAST_CALL;
-        JSValue* executeStatements(ExecState*) KJS_FAST_CALL;
+        JSValue* evaluate(OldInterpreterExecState*) KJS_FAST_CALL;
+        JSValue* executeStatements(OldInterpreterExecState*) KJS_FAST_CALL;
+
+        ExpressionNode* expr() const { return m_expr.get(); }
+        StatementVector& children() { return m_children; }
 
     private:
         RefPtr<ExpressionNode> m_expr;
@@ -2922,7 +3168,7 @@
             clauseList->m_next = this;
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
         CaseClauseNode* getClause() const KJS_FAST_CALL { return m_clause.get(); }
         ClauseListNode* getNext() const KJS_FAST_CALL { return m_next.get(); }
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
@@ -2937,10 +3183,17 @@
 
     class CaseBlockNode : public Node {
     public:
-        CaseBlockNode(ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2) KJS_FAST_CALL;
+        CaseBlockNode(ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2) KJS_FAST_CALL
+            : m_list1(list1)
+            , m_defaultClause(defaultClause)
+            , m_list2(list2)
+        {
+        }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        JSValue* executeBlock(ExecState*, JSValue *input) KJS_FAST_CALL;
+        RegisterID* emitCodeForBlock(CodeGenerator&, RegisterID* input, RegisterID* dst = 0) KJS_FAST_CALL;
+
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        JSValue* executeBlock(OldInterpreterExecState*, JSValue *input) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
 
@@ -2958,8 +3211,10 @@
         {
         }
 
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
-        virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
+        virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
+
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
 
     private:
@@ -2971,9 +3226,9 @@
     public:
         BreakpointCheckStatement(PassRefPtr<StatementNode>) KJS_FAST_CALL;
 
-        virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
+        virtual JSValue* execute(OldInterpreterExecState*) KJS_FAST_CALL;
         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
-        virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
+        virtual void optimizeVariableAccess(OldInterpreterExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
 
     private:
         RefPtr<StatementNode> m_statement;
diff --git a/JavaScriptCore/kjs/number_object.cpp b/JavaScriptCore/kjs/number_object.cpp
index b72c0e6..2a3eeb7 100644
--- a/JavaScriptCore/kjs/number_object.cpp
+++ b/JavaScriptCore/kjs/number_object.cpp
@@ -495,9 +495,9 @@
     return jsNull();
 }
 
-bool NumberObjectImp::implementsConstruct() const
+ConstructType NumberObjectImp::getConstructData(ConstructData&)
 {
-    return true;
+    return ConstructTypeNative;
 }
 
 // ECMA 15.7.1
diff --git a/JavaScriptCore/kjs/number_object.h b/JavaScriptCore/kjs/number_object.h
index 36befed..0fc20ee 100644
--- a/JavaScriptCore/kjs/number_object.h
+++ b/JavaScriptCore/kjs/number_object.h
@@ -55,7 +55,7 @@
     public:
         NumberObjectImp(ExecState*, FunctionPrototype*, NumberPrototype*);
 
-        virtual bool implementsConstruct() const;
+        virtual ConstructType getConstructData(ConstructData&);
         virtual JSObject* construct(ExecState*, const List&);
 
         virtual JSValue* callAsFunction(ExecState*, JSObject*, const List&);
diff --git a/JavaScriptCore/kjs/object.cpp b/JavaScriptCore/kjs/object.cpp
index 096675f..1a5b8d6 100644
--- a/JavaScriptCore/kjs/object.cpp
+++ b/JavaScriptCore/kjs/object.cpp
@@ -164,43 +164,6 @@
   return "Object";
 }
 
-JSValue *JSObject::get(ExecState *exec, const Identifier &propertyName) const
-{
-  PropertySlot slot;
-
-  if (const_cast<JSObject *>(this)->getPropertySlot(exec, propertyName, slot))
-    return slot.getValue(exec, const_cast<JSObject *>(this), propertyName);
-    
-  return jsUndefined();
-}
-
-JSValue *JSObject::get(ExecState *exec, unsigned propertyName) const
-{
-  PropertySlot slot;
-  if (const_cast<JSObject *>(this)->getPropertySlot(exec, propertyName, slot))
-    return slot.getValue(exec, const_cast<JSObject *>(this), propertyName);
-    
-  return jsUndefined();
-}
-
-bool JSObject::getPropertySlot(ExecState *exec, unsigned propertyName, PropertySlot& slot)
-{
-  JSObject *imp = this;
-  
-  while (true) {
-    if (imp->getOwnPropertySlot(exec, propertyName, slot))
-      return true;
-    
-    JSValue *proto = imp->_proto;
-    if (!proto->isObject())
-      break;
-    
-    imp = static_cast<JSObject *>(proto);
-  }
-  
-  return false;
-}
-
 bool JSObject::getOwnPropertySlot(ExecState *exec, unsigned propertyName, PropertySlot& slot)
 {
   return getOwnPropertySlot(exec, Identifier::from(propertyName), slot);
@@ -303,7 +266,6 @@
     putWithAttributes(exec, Identifier::from(propertyName), value, attributes);
 }
 
-// ECMA 8.6.2.4
 bool JSObject::hasProperty(ExecState *exec, const Identifier &propertyName) const
 {
   PropertySlot slot;
@@ -350,16 +312,19 @@
 }
 
 static ALWAYS_INLINE JSValue *tryGetAndCallProperty(ExecState *exec, const JSObject *object, const Identifier &propertyName) {
-  JSValue *v = object->get(exec, propertyName);
+  JSValue* v = object->get(exec, propertyName);
   if (v->isObject()) {
-    JSObject *o = static_cast<JSObject*>(v);
-    if (o->implementsCall()) { // spec says "not primitive type" but ...
-      JSObject *thisObj = const_cast<JSObject*>(object);
-      JSValue* def = o->call(exec, thisObj->toThisObject(exec), exec->emptyList());
-      JSType defType = def->type();
-      ASSERT(defType != GetterSetterType);
-      if (defType != ObjectType)
-        return def;
+      JSObject* o = static_cast<JSObject*>(v);
+      CallData data;
+      CallType callType = o->getCallData(data);
+      // spec says "not primitive type" but ...
+      if (callType != CallTypeNone) {
+          JSObject* thisObj = const_cast<JSObject*>(object);
+          JSValue* def = o->call(exec, thisObj->toThisObject(exec), exec->emptyList());
+          JSType defType = def->type();
+          ASSERT(defType != GetterSetterType);
+          if (defType != ObjectType)
+              return def;
     }
   }
   return NULL;
@@ -375,6 +340,11 @@
 // ECMA 8.6.2.6
 JSValue* JSObject::defaultValue(ExecState* exec, JSType hint) const
 {
+  // We need this check to guard against the case where this object is rhs of
+  // a binary expression where lhs threw an exception in its conversion to
+  // primitive
+  if (exec->hadException())
+    return exec->exception();
   /* Prefer String for Date objects */
   if ((hint == StringType) || (hint != NumberType && _proto == exec->lexicalGlobalObject()->datePrototype())) {
     if (JSValue* v = tryGetAndCallProperty(exec, this, exec->propertyNames().toString))
@@ -477,11 +447,6 @@
     }
 }
 
-bool JSObject::implementsConstruct() const
-{
-  return false;
-}
-
 JSObject* JSObject::construct(ExecState*, const List& /*args*/)
 {
   ASSERT(false);
@@ -493,9 +458,10 @@
   return construct(exec, args);
 }
 
-bool JSObject::implementsCall() const
+bool JSObject::implementsCall()
 {
-  return false;
+    CallData callData;
+    return getCallData(callData) != CallTypeNone;
 }
 
 JSValue *JSObject::callAsFunction(ExecState* /*exec*/, JSObject* /*thisObj*/, const List &/*args*/)
@@ -613,16 +579,6 @@
     return 0;
 }
 
-void JSObject::putDirect(const Identifier &propertyName, JSValue *value, int attr)
-{
-    _prop.put(propertyName, value, attr);
-}
-
-void JSObject::putDirect(const Identifier &propertyName, int value, int attr)
-{
-    _prop.put(propertyName, jsNumber(value), attr);
-}
-
 void JSObject::removeDirect(const Identifier &propertyName)
 {
     _prop.remove(propertyName);
diff --git a/JavaScriptCore/kjs/object.h b/JavaScriptCore/kjs/object.h
index 90f5c32..aebc4d0 100644
--- a/JavaScriptCore/kjs/object.h
+++ b/JavaScriptCore/kjs/object.h
@@ -234,14 +234,14 @@
      *
      * @return The specified property, or Undefined
      */
-    JSValue *get(ExecState *exec, const Identifier &propertyName) const;
-    JSValue *get(ExecState *exec, unsigned propertyName) const;
+    JSValue* get(ExecState* exec, const Identifier& propertyName) const;
+    JSValue* get(ExecState* exec, unsigned propertyName) const;
 
-    bool getPropertySlot(ExecState *, const Identifier&, PropertySlot&);
-    bool getPropertySlot(ExecState *, unsigned, PropertySlot&);
+    bool getPropertySlot(ExecState*, const Identifier&, PropertySlot&);
+    bool getPropertySlot(ExecState*, unsigned, PropertySlot&);
 
-    virtual bool getOwnPropertySlot(ExecState *, const Identifier&, PropertySlot&);
-    virtual bool getOwnPropertySlot(ExecState *, unsigned index, PropertySlot&);
+    virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
+    virtual bool getOwnPropertySlot(ExecState*, unsigned index, PropertySlot&);
 
     /**
      * Sets the specified property.
@@ -316,16 +316,6 @@
     virtual JSValue *defaultValue(ExecState *exec, JSType hint) const;
 
     /**
-     * Whether or not the object implements the construct() method. If this
-     * returns false you should not call the construct() method on this
-     * object (typically, an assertion will fail to indicate this).
-     *
-     * @return true if this object implements the construct() method, otherwise
-     * false
-     */
-    virtual bool implementsConstruct() const;
-
-    /**
      * Creates a new object based on this object. Typically this means the
      * following:
      * 1. A new object is created
@@ -342,8 +332,8 @@
      * will be set. This can be tested for with ExecState::hadException().
      * Under some circumstances, the exception object may also be returned.
      *
-     * Note: This function should not be called if implementsConstruct() returns
-     * false, in which case it will result in an assertion failure.
+     * Note: This function should not be called if getConstructData() returns
+     * ConstructTypeNone, in which case it will result in an assertion failure.
      *
      * @param exec The current execution state
      * @param args The arguments to be passed to call() once the new object has
@@ -357,16 +347,6 @@
     virtual JSObject* construct(ExecState* exec, const List& args, const Identifier& functionName, const UString& sourceURL, int lineNumber);
 
     /**
-     * Whether or not the object implements the call() method. If this returns
-     * false you should not call the call() method on this object (typically,
-     * an assertion will fail to indicate this).
-     *
-     * @return true if this object implements the call() method, otherwise
-     * false
-     */
-    virtual bool implementsCall() const;
-
-    /**
      * Calls this object as if it is a function.
      *
      * Note: This function should not be called if implementsCall() returns
@@ -383,7 +363,9 @@
      * @param args List of arguments to be passed to the function
      * @return The return value from the function
      */
+    bool implementsCall();
     JSValue *call(ExecState *exec, JSObject *thisObj, const List &args);
+
     virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args);
 
     /**
@@ -431,6 +413,8 @@
         { return _prop.get(propertyName); }
     JSValue **getDirectLocation(const Identifier& propertyName)
         { return _prop.getLocation(propertyName); }
+   JSValue **getDirectLocation(const Identifier& propertyName, bool& isWriteable)
+        { return _prop.getLocation(propertyName, isWriteable); }
     void putDirect(const Identifier &propertyName, JSValue *value, int attr = 0);
     void putDirect(const Identifier &propertyName, int value, int attr = 0);
     void removeDirect(const Identifier &propertyName);
@@ -451,6 +435,7 @@
 
   protected:
     PropertyMap _prop;
+    bool getOwnPropertySlotForWrite(ExecState*, const Identifier&, PropertySlot&, bool& slotIsWriteable);
 
   private:
     const HashEntry* findPropertyHashEntry(ExecState*, const Identifier& propertyName) const;
@@ -540,6 +525,25 @@
     return !JSImmediate::isImmediate(this) && asCell()->isObject(c);
 }
 
+inline JSValue *JSObject::get(ExecState *exec, const Identifier &propertyName) const
+{
+  PropertySlot slot;
+
+  if (const_cast<JSObject *>(this)->getPropertySlot(exec, propertyName, slot))
+    return slot.getValue(exec, const_cast<JSObject *>(this), propertyName);
+    
+  return jsUndefined();
+}
+
+inline JSValue *JSObject::get(ExecState *exec, unsigned propertyName) const
+{
+  PropertySlot slot;
+  if (const_cast<JSObject *>(this)->getPropertySlot(exec, propertyName, slot))
+    return slot.getValue(exec, const_cast<JSObject *>(this), propertyName);
+    
+  return jsUndefined();
+}
+
 // It may seem crazy to inline a function this large but it makes a big difference
 // since this is function very hot in variable lookup
 inline bool JSObject::getPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot)
@@ -557,6 +561,48 @@
     }
 }
 
+inline bool JSObject::getPropertySlot(ExecState *exec, unsigned propertyName, PropertySlot& slot)
+{
+  JSObject *imp = this;
+  
+  while (true) {
+    if (imp->getOwnPropertySlot(exec, propertyName, slot))
+      return true;
+    
+    JSValue *proto = imp->_proto;
+    if (!proto->isObject())
+      break;
+    
+    imp = static_cast<JSObject *>(proto);
+  }
+  
+  return false;
+}
+
+// It may seem crazy to inline a function this large, especially a virtual function,
+// but it makes a big difference to property lookup that derived classes can inline their
+// base class call to this.
+ALWAYS_INLINE bool JSObject::getOwnPropertySlotForWrite(ExecState* exec, const Identifier& propertyName, PropertySlot& slot, bool& slotIsWriteable)
+{
+    if (JSValue **location = getDirectLocation(propertyName, slotIsWriteable)) {
+        if (_prop.hasGetterSetterProperties() && location[0]->type() == GetterSetterType) {
+            slotIsWriteable = false;
+            fillGetterPropertySlot(slot, location);
+        } else
+            slot.setValueSlot(this, location);
+        return true;
+    }
+
+    // non-standard Netscape extension
+    if (propertyName == exec->propertyNames().underscoreProto) {
+        slot.setValueSlot(this, &_proto);
+        slotIsWriteable = true;
+        return true;
+    }
+
+    return false;
+}
+
 // It may seem crazy to inline a function this large, especially a virtual function,
 // but it makes a big difference to property lookup that derived classes can inline their
 // base class call to this.
@@ -579,17 +625,14 @@
     return false;
 }
 
-inline void ScopeChain::release()
+inline void JSObject::putDirect(const Identifier &propertyName, JSValue *value, int attr)
 {
-    // This function is only called by deref(),
-    // Deref ensures these conditions are true.
-    ASSERT(_node && _node->refCount == 0);
-    ScopeChainNode *n = _node;
-    do {
-        ScopeChainNode *next = n->next;
-        delete n;
-        n = next;
-    } while (n && --n->refCount == 0);
+    _prop.put(propertyName, value, attr);
+}
+
+inline void JSObject::putDirect(const Identifier &propertyName, int value, int attr)
+{
+    _prop.put(propertyName, jsNumber(value), attr);
 }
 
 inline JSValue* JSObject::toPrimitive(ExecState* exec, JSType preferredType) const
diff --git a/JavaScriptCore/kjs/object_object.cpp b/JavaScriptCore/kjs/object_object.cpp
index 9bc1fe2..24ca3fd 100644
--- a/JavaScriptCore/kjs/object_object.cpp
+++ b/JavaScriptCore/kjs/object_object.cpp
@@ -143,10 +143,9 @@
   putDirect(exec->propertyNames().length, jsNumber(1), ReadOnly|DontDelete|DontEnum);
 }
 
-
-bool ObjectObjectImp::implementsConstruct() const
+ConstructType ObjectObjectImp::getConstructData(ConstructData&)
 {
-  return true;
+    return ConstructTypeNative;
 }
 
 // ECMA 15.2.2
diff --git a/JavaScriptCore/kjs/object_object.h b/JavaScriptCore/kjs/object_object.h
index 0ee5482..c3348e9 100644
--- a/JavaScriptCore/kjs/object_object.h
+++ b/JavaScriptCore/kjs/object_object.h
@@ -47,8 +47,9 @@
     public:
         ObjectObjectImp(ExecState*, ObjectPrototype*, FunctionPrototype*);
 
-        virtual bool implementsConstruct() const;
+        virtual ConstructType getConstructData(ConstructData&);
         virtual JSObject* construct(ExecState*, const List&);
+
         virtual JSValue* callAsFunction(ExecState*, JSObject*, const List&);
     };
 
diff --git a/JavaScriptCore/kjs/operations.cpp b/JavaScriptCore/kjs/operations.cpp
index d2b3892..81da680 100644
--- a/JavaScriptCore/kjs/operations.cpp
+++ b/JavaScriptCore/kjs/operations.cpp
@@ -98,31 +98,28 @@
     return v1 == v2;
 }
 
-bool strictEqual(ExecState *exec, JSValue *v1, JSValue *v2)
+bool strictEqual(JSValue* v1, JSValue* v2)
 {
     JSType t1 = v1->type();
     JSType t2 = v2->type();
     
     if (t1 != t2)
         return false;
-    if (t1 == UndefinedType || t1 == NullType)
-        return true;
-    if (t1 == NumberType) {
-        double n1 = v1->toNumber(exec);
-        double n2 = v2->toNumber(exec);
-        if (n1 == n2)
-            return true;
-        return false;
-    } else if (t1 == StringType)
-        return v1->toString(exec) == v2->toString(exec);
-    else if (t2 == BooleanType)
-        return v1->toBoolean(exec) == v2->toBoolean(exec);
+
+    if (t1 == NumberType)
+        return v1->getNumber() == v2->getNumber();
     
-    if (v1 == v2)
-        return true;
-    /* TODO: joined objects */
+    if (t1 == StringType)
+        return static_cast<StringImp*>(v1)->value() == static_cast<StringImp*>(v2)->value();
     
-    return false;
+    return v1 == v2; // covers object, boolean, null, and undefined types
+}
+
+JSValue* throwOutOfMemoryError(ExecState* exec)
+{
+    JSObject* error = Error::create(exec, GeneralError, "Out of memory");
+    exec->setException(error);
+    return error;
 }
 
 }
diff --git a/JavaScriptCore/kjs/operations.h b/JavaScriptCore/kjs/operations.h
index 96656f0..55f3ae9 100644
--- a/JavaScriptCore/kjs/operations.h
+++ b/JavaScriptCore/kjs/operations.h
@@ -29,7 +29,8 @@
   class JSValue;
 
   bool equal(ExecState *exec, JSValue *v1, JSValue *v2);
-  bool strictEqual(ExecState *exec, JSValue *v1, JSValue *v2);
+  bool strictEqual(JSValue*, JSValue*);
+  JSValue* throwOutOfMemoryError(ExecState*);
 }
 
 #endif
diff --git a/JavaScriptCore/kjs/property_map.cpp b/JavaScriptCore/kjs/property_map.cpp
index 41d141a..0ecc8ab 100644
--- a/JavaScriptCore/kjs/property_map.cpp
+++ b/JavaScriptCore/kjs/property_map.cpp
@@ -327,6 +327,61 @@
     }
 }
 
+JSValue** PropertyMap::getLocation(const Identifier& name, bool& isWriteable)
+{
+    ASSERT(!name.isNull());
+    
+    UString::Rep* rep = name._ustring.rep();
+    
+    if (!m_usingTable) {
+#if USE_SINGLE_ENTRY
+        if (rep == m_singleEntryKey) {
+            isWriteable = !(m_singleEntryAttributes & ReadOnly);
+            return &m_u.singleEntryValue;
+        }
+#endif
+        return 0;
+    }
+    
+    unsigned i = rep->computedHash();
+
+#if DUMP_PROPERTYMAP_STATS
+    ++numProbes;
+#endif
+
+    unsigned entryIndex = m_u.table->entryIndicies[i & m_u.table->sizeMask];
+    if (entryIndex == emptyEntryIndex)
+        return 0;
+
+    if (rep == m_u.table->entries()[entryIndex - 1].key) {
+        isWriteable = !(m_u.table->entries()[entryIndex - 1].attributes & ReadOnly);
+        return &m_u.table->entries()[entryIndex - 1].value;
+    }
+
+#if DUMP_PROPERTYMAP_STATS
+    ++numCollisions;
+#endif
+
+    unsigned k = 1 | doubleHash(rep->computedHash());
+
+    while (1) {
+        i += k;
+
+#if DUMP_PROPERTYMAP_STATS
+        ++numRehashes;
+#endif
+
+        entryIndex = m_u.table->entryIndicies[i & m_u.table->sizeMask];
+        if (entryIndex == emptyEntryIndex)
+            return 0;
+
+        if (rep == m_u.table->entries()[entryIndex - 1].key) {
+            isWriteable = !(m_u.table->entries()[entryIndex - 1].attributes & ReadOnly);
+            return &m_u.table->entries()[entryIndex - 1].value;
+        }
+    }
+}
+
 void PropertyMap::put(const Identifier& name, JSValue* value, unsigned attributes, bool checkReadOnly)
 {
     ASSERT(!name.isNull());
diff --git a/JavaScriptCore/kjs/property_map.h b/JavaScriptCore/kjs/property_map.h
index 30f3612..e64071f 100644
--- a/JavaScriptCore/kjs/property_map.h
+++ b/JavaScriptCore/kjs/property_map.h
@@ -68,6 +68,7 @@
         JSValue* get(const Identifier&) const;
         JSValue* get(const Identifier&, unsigned& attributes) const;
         JSValue** getLocation(const Identifier& name);
+        JSValue** getLocation(const Identifier& name, bool& isWriteable);
 
         void mark() const;
         void getEnumerablePropertyNames(PropertyNameArray&) const;
diff --git a/JavaScriptCore/kjs/property_slot.cpp b/JavaScriptCore/kjs/property_slot.cpp
index ef2525f..595965db 100644
--- a/JavaScriptCore/kjs/property_slot.cpp
+++ b/JavaScriptCore/kjs/property_slot.cpp
@@ -23,7 +23,10 @@
 
 #include "config.h"
 #include "property_slot.h"
+
+#include "JSGlobalObject.h"
 #include "object.h"
+#include "RegisterFileStack.h"
 
 namespace KJS {
 
@@ -40,7 +43,16 @@
 
 JSValue *PropertySlot::functionGetter(ExecState* exec, JSObject* originalObject, const Identifier&, const PropertySlot& slot)
 {
-    return slot.m_data.getterFunc->call(exec, originalObject, exec->emptyList());
+    CallData data;
+    CallType callType = slot.m_data.getterFunc->getCallData(data);
+    if (callType == CallTypeNative)
+        return slot.m_data.getterFunc->call(exec, originalObject, exec->emptyList());
+    ASSERT(callType == CallTypeJS);
+    RegisterFileStack* stack = &exec->dynamicGlobalObject()->registerFileStack();
+    stack->pushFunctionRegisterFile();
+    JSValue* result = slot.m_data.getterFunc->call(exec, originalObject, exec->emptyList());
+    stack->popFunctionRegisterFile();
+    return result;    
 }
 
 }
diff --git a/JavaScriptCore/kjs/property_slot.h b/JavaScriptCore/kjs/property_slot.h
index 4ec8b46..41ff671 100644
--- a/JavaScriptCore/kjs/property_slot.h
+++ b/JavaScriptCore/kjs/property_slot.h
@@ -57,6 +57,12 @@
             return m_data.numericFunc(exec, originalObject, propertyName, *this);
         return m_getValue(exec, originalObject, Identifier::from(propertyName), *this); 
     }
+
+    void putValue(JSValue* value)
+    { 
+        ASSERT(m_getValue == KJS_VALUE_SLOT_MARKER);
+        *m_data.valueSlot = value;
+    }
     
     void setValueSlot(JSObject* slotBase, JSValue** valueSlot) 
     {
diff --git a/JavaScriptCore/kjs/regexp_object.cpp b/JavaScriptCore/kjs/regexp_object.cpp
index b723798..196d967 100644
--- a/JavaScriptCore/kjs/regexp_object.cpp
+++ b/JavaScriptCore/kjs/regexp_object.cpp
@@ -230,9 +230,9 @@
         :  jsNull();
 }
 
-bool RegExpImp::implementsCall() const
+CallType RegExpImp::getCallData(CallData&)
 {
-    return true;
+    return CallTypeNative;
 }
 
 JSValue* RegExpImp::callAsFunction(ExecState* exec, JSObject*, const List& args)
@@ -425,9 +425,9 @@
   }
 }
   
-bool RegExpObjectImp::implementsConstruct() const
+ConstructType RegExpObjectImp::getConstructData(ConstructData&)
 {
-  return true;
+    return ConstructTypeNative;
 }
 
 // ECMA 15.10.4
@@ -445,14 +445,10 @@
   UString pattern = arg0->isUndefined() ? UString("") : arg0->toString(exec);
   UString flags = arg1->isUndefined() ? UString("") : arg1->toString(exec);
   
-  return createRegExpImp(exec, RegExp::create(pattern, flags));
-}
-
-JSObject* RegExpObjectImp::createRegExpImp(ExecState* exec, PassRefPtr<RegExp> regExp)
-{
-    return regExp->isValid()
-        ? new RegExpImp(static_cast<RegExpPrototype*>(exec->lexicalGlobalObject()->regExpPrototype()), regExp)
-        : throwError(exec, SyntaxError, UString("Invalid regular expression: ").append(regExp->errorMessage()));
+  RefPtr<RegExp> regExp = RegExp::create(pattern, flags);
+  return regExp->isValid()
+    ? new RegExpImp(exec->lexicalGlobalObject()->regExpPrototype(), regExp.release())
+    : throwError(exec, SyntaxError, UString("Invalid regular expression: ").append(regExp->errorMessage()));
 }
 
 // ECMA 15.10.3
diff --git a/JavaScriptCore/kjs/regexp_object.h b/JavaScriptCore/kjs/regexp_object.h
index c69e8f7..8157c0d 100644
--- a/JavaScriptCore/kjs/regexp_object.h
+++ b/JavaScriptCore/kjs/regexp_object.h
@@ -49,8 +49,9 @@
         JSValue* test(ExecState*, const List& args);
         JSValue* exec(ExecState*, const List& args);
 
-        virtual bool implementsCall() const;
+        virtual CallType getCallData(CallData&);
         virtual JSValue* callAsFunction(ExecState*, JSObject*, const List&);
+
         bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
         JSValue* getValueProperty(ExecState*, int token) const;
         void put(ExecState*, const Identifier&, JSValue*);
@@ -75,15 +76,18 @@
 
         RegExpObjectImp(ExecState*, FunctionPrototype*, RegExpPrototype*);
 
-        virtual bool implementsConstruct() const;
+        virtual ConstructType getConstructData(ConstructData&);
         virtual JSObject* construct(ExecState*, const List&);
-        JSObject* createRegExpImp(ExecState*, PassRefPtr<RegExp>);
+
         virtual JSValue* callAsFunction(ExecState*, JSObject*, const List&);
+
         virtual void put(ExecState*, const Identifier&, JSValue*);
         void putValueProperty(ExecState*, int token, JSValue*);
         virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
         JSValue* getValueProperty(ExecState*, int token) const;
+
         virtual const ClassInfo* classInfo() const { return &info; }
+        static const ClassInfo info;
 
         void performMatch(RegExp*, const UString&, int startOffset, int& position, int& length, int** ovector = 0);
         JSObject* arrayOfMatches(ExecState*) const;
@@ -96,8 +100,6 @@
         JSValue* getRightContext() const;
 
         OwnPtr<RegExpObjectImpPrivate> d;
-
-        static const ClassInfo info;
     };
 
 } // namespace
diff --git a/JavaScriptCore/kjs/scope_chain.cpp b/JavaScriptCore/kjs/scope_chain.cpp
index aba066a..9b8e976 100644
--- a/JavaScriptCore/kjs/scope_chain.cpp
+++ b/JavaScriptCore/kjs/scope_chain.cpp
@@ -1,6 +1,6 @@
 /*
  *  This file is part of the KDE libraries
- *  Copyright (C) 2003, 2006 Apple Inc.
+ *  Copyright (C) 2003, 2006, 2008 Apple Inc.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
@@ -21,25 +21,16 @@
 
 #include "config.h"
 #include "scope_chain.h"
+
 #include "PropertyNameArray.h"
-#include <stdio.h>
 #include "object.h"
+#include <stdio.h>
 
 namespace KJS {
 
-void ScopeChain::push(const ScopeChain &c)
-{
-    ScopeChainNode **tail = &_node;
-    for (ScopeChainNode *n = c._node; n; n = n->next) {
-        ScopeChainNode *newNode = new ScopeChainNode(*tail, n->object);
-        *tail = newNode;
-        tail = &newNode->next;
-    }
-}
-
 #ifndef NDEBUG
 
-void ScopeChain::print()
+void ScopeChainNode::print() const
 {
     ScopeChainIterator scopeEnd = end();
     for (ScopeChainIterator scopeIter = begin(); scopeIter != scopeEnd; ++scopeIter) {
diff --git a/JavaScriptCore/kjs/scope_chain.h b/JavaScriptCore/kjs/scope_chain.h
index b409417..5383932 100644
--- a/JavaScriptCore/kjs/scope_chain.h
+++ b/JavaScriptCore/kjs/scope_chain.h
@@ -1,6 +1,6 @@
 /*
  *  This file is part of the KDE libraries
- *  Copyright (C) 2003 Apple Computer, Inc.
+ *  Copyright (C) 2003, 2008 Apple Computer, Inc.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
@@ -19,32 +19,106 @@
  *
  */
 
-#ifndef KJS_SCOPE_CHAIN_H
-#define KJS_SCOPE_CHAIN_H
+#ifndef ScopeChain_h
+#define ScopeChain_h
 
 #include <wtf/Assertions.h>
 
 namespace KJS {
 
+    class JSGlobalObject;
     class JSObject;
-    class ExecState;
+    class ScopeChainIterator;
     
     class ScopeChainNode {
     public:
-        ScopeChainNode(ScopeChainNode *n, JSObject *o)
-            : next(n), object(o), refCount(1) { }
+        ScopeChainNode(ScopeChainNode* n, JSObject* o)
+            : next(n)
+            , object(o)
+            , refCount(1)
+        {
+        }
 
-        ScopeChainNode *next;
-        JSObject *object;
+        ScopeChainNode* next;
+        JSObject* object;
         int refCount;
+        
+        void deref() { if (--refCount == 0) release(); }
+        void ref() { ++refCount; }
+        void release();
+
+        // Before calling "push" on a bare ScopeChainNode, a client should
+        // logically "copy" the node. Later, the client can "deref" the head
+        // of its chain of ScopeChainNodes to reclaim all the nodes it added
+        // after the logical copy, leaving nodes added before the logical copy
+        // (nodes shared with other clients) untouched.
+        ScopeChainNode* copy()
+        {
+            ref();
+            return this;
+        }
+
+        JSObject* bottom() const;
+
+        ScopeChainNode* push(JSObject*);
+        ScopeChainNode* pop();
+
+        ScopeChainIterator begin() const;
+        ScopeChainIterator end() const;
+        
+        JSGlobalObject* globalObject() const; // defined in JSGlobalObject.h
+        
+#ifndef NDEBUG        
+        void print() const;
+#endif
     };
 
+    inline ScopeChainNode* ScopeChainNode::push(JSObject* o)
+    {
+        ASSERT(o);
+        return new ScopeChainNode(this, o);
+    }
+
+    inline ScopeChainNode* ScopeChainNode::pop()
+    {
+        ASSERT(next);
+        ScopeChainNode* result = next;
+        
+        if (--refCount != 0)
+            ++result->refCount;
+        else
+            delete this;
+        
+        return result;
+    }
+
+    inline JSObject* ScopeChainNode::bottom() const
+    {
+        const ScopeChainNode* n = this;
+        while (n->next)
+            n = n->next;
+        return n->object;
+    }
+
+    inline void ScopeChainNode::release()
+    {
+        // This function is only called by deref(),
+        // Deref ensures these conditions are true.
+        ASSERT(refCount == 0);
+        ScopeChainNode* n = this;
+        do {
+            ScopeChainNode* next = n->next;
+            delete n;
+            n = next;
+        } while (n && --n->refCount == 0);
+    }
+
     class ScopeChainIterator {
     public:
-        ScopeChainIterator(ScopeChainNode *node) : m_node(node) {}
+        ScopeChainIterator(const ScopeChainNode* node) : m_node(node) {}
 
-        JSObject * const & operator*() const { return m_node->object; }
-        JSObject * const * operator->() const { return &(operator*()); }
+        JSObject* const & operator*() const { return m_node->object; }
+        JSObject* const * operator->() const { return &(operator*()); }
     
         ScopeChainIterator& operator++() { m_node = m_node->next; return *this; }
 
@@ -54,129 +128,81 @@
         bool operator!=(const ScopeChainIterator& other) const { return m_node != other.m_node; }
 
     private:
-        ScopeChainNode *m_node;
+        const ScopeChainNode* m_node;
     };
 
+    inline ScopeChainIterator ScopeChainNode::begin() const
+    {
+        return ScopeChainIterator(this); 
+    }
+
+    inline ScopeChainIterator ScopeChainNode::end() const
+    { 
+        return ScopeChainIterator(0); 
+    }
+
     class ScopeChain {
     public:
-        typedef ScopeChainIterator const_iterator;
-        typedef JSObject* ValueType;
-
-        ScopeChain() : _node(0) { }
-        ~ScopeChain() { deref(); }
-
-        ScopeChain(const ScopeChain& c)
-            : _node(c._node)
-        {
-            if (_node)
-                ++_node->refCount;
-        }
-
         ScopeChain(JSObject* o)
             : _node(new ScopeChainNode(0, o))
         {
         }
 
-        ScopeChain &operator=(const ScopeChain &);
+        ScopeChain(const ScopeChain& c)
+            : _node(c._node->copy())
+        {
+        }
 
-        bool isEmpty() const { return !_node; }
-        JSObject *top() const { return _node->object; }
+        ScopeChain& operator=(const ScopeChain& c);
 
-        JSObject *bottom() const;
+        explicit ScopeChain(ScopeChainNode* node)
+            : _node(node->copy())
+        {
+        }
+    
+        ~ScopeChain() { _node->deref(); }
 
-        ScopeChainIterator begin() const { return ScopeChainIterator(_node); }
-        ScopeChainIterator end() const { return ScopeChainIterator(0); }
+        void swap(ScopeChain&);
 
-        void clear() { deref(); _node = 0; }
-        void push(JSObject *);
-        void push(const ScopeChain &);
-        void push(ScopeChainNode*);
-        void replaceTop(JSObject*);
-        void pop();
-        void popInlineScopeNode();
+        ScopeChainNode* node() const { return _node; }
 
-        void mark();
+        JSObject* top() const { return _node->object; }
+        JSObject* bottom() const { return _node->bottom(); }
+
+        ScopeChainIterator begin() const { return _node->begin(); }
+        ScopeChainIterator end() const { return _node->end(); }
+
+        void push(JSObject* o) { _node = _node->push(o); }
+
+        void pop() { _node = _node->pop(); }
+        void clear() { _node->deref(); _node = 0; }
+        
+        JSGlobalObject* globalObject() const { return _node->globalObject(); }
+
+        void mark() const;
 
 #ifndef NDEBUG        
-        void print();
+        void print() const { _node->print(); }
 #endif
         
     private:
-        ScopeChainNode *_node;
-        
-        void deref() { if (_node && --_node->refCount == 0) release(); }
-        void ref() const;
-        
-        void release();
+        ScopeChainNode* _node;
     };
 
-inline void ScopeChain::ref() const
-{
-    for (ScopeChainNode *n = _node; n; n = n->next) {
-        if (n->refCount++ != 0)
-            break;
+    inline void ScopeChain::swap(ScopeChain& o)
+    {
+        ScopeChainNode* tmp = _node;
+        _node = o._node;
+        o._node = tmp;
     }
-}
 
-inline ScopeChain &ScopeChain::operator=(const ScopeChain &c)
-{
-    c.ref();
-    deref();
-    _node = c._node;
-    return *this;
-}
-
-inline JSObject *ScopeChain::bottom() const
-{
-    ScopeChainNode *last = 0;
-    for (ScopeChainNode *n = _node; n; n = n->next)
-        last = n;
-    if (!last)
-        return 0;
-    return last->object;
-}
-
-inline void ScopeChain::push(JSObject *o)
-{
-    ASSERT(o);
-    _node = new ScopeChainNode(_node, o);
-}
-
-inline void ScopeChain::push(ScopeChainNode *node)
-{
-    ASSERT(node);
-    ASSERT(node->object);
-    node->refCount++;
-    node->next = _node;
-    _node = node;
-}
-
-inline void ScopeChain::replaceTop(JSObject* o)
-{
-    ASSERT(o);
-    _node->object = o;
-}
-
-inline void ScopeChain::pop()
-{
-    ScopeChainNode *oldNode = _node;
-    ASSERT(oldNode);
-    ScopeChainNode *newNode = oldNode->next;
-    _node = newNode;
-    
-    if (--oldNode->refCount != 0) {
-        if (newNode)
-            ++newNode->refCount;
-    } else {
-        delete oldNode;
+    inline ScopeChain& ScopeChain::operator=(const ScopeChain& c)
+    {
+        ScopeChain tmp(c);
+        swap(tmp);
+        return *this;
     }
-}
-
-inline void ScopeChain::popInlineScopeNode()
-{
-    _node = _node->next;
-}
 
 } // namespace KJS
 
-#endif // KJS_SCOPE_CHAIN_H
+#endif // ScopeChain_h
diff --git a/JavaScriptCore/kjs/scope_chain_mark.h b/JavaScriptCore/kjs/scope_chain_mark.h
index bc4d5f8..a60fdd7 100644
--- a/JavaScriptCore/kjs/scope_chain_mark.h
+++ b/JavaScriptCore/kjs/scope_chain_mark.h
@@ -21,25 +21,15 @@
 #ifndef scope_chain_mark_h
 #define scope_chain_mark_h
 
-#include "Activation.h"
 #include "scope_chain.h"
 
 namespace KJS {
 
-    inline void ScopeChain::mark()
+    inline void ScopeChain::mark() const
     {
         for (ScopeChainNode* n = _node; n; n = n->next) {
             JSObject* o = n->object;
-            
-            // An ActivationImp that is on the activation stack can't have the
-            // JSObject::marked() method called on it, because it doesn't have an
-            // entry in a GC mark bitmap, so we check here whether it is on the
-            // stack and directly call the portion of the marking code that is
-            // still relevant.
-            
-            if (o->isActivationObject() && static_cast<ActivationImp*>(o)->isOnStack())
-                static_cast<ActivationImp*>(o)->markChildren();
-            else if (!o->marked())
+            if (!o->marked())
                 o->mark();
         }
     }
diff --git a/JavaScriptCore/kjs/string_object.cpp b/JavaScriptCore/kjs/string_object.cpp
index 415ae37..8a55e53 100644
--- a/JavaScriptCore/kjs/string_object.cpp
+++ b/JavaScriptCore/kjs/string_object.cpp
@@ -972,9 +972,9 @@
 }
 
 
-bool StringObjectImp::implementsConstruct() const
+ConstructType StringObjectImp::getConstructData(ConstructData&)
 {
-  return true;
+    return ConstructTypeNative;
 }
 
 // ECMA 15.5.2
diff --git a/JavaScriptCore/kjs/string_object.h b/JavaScriptCore/kjs/string_object.h
index 8508788..d53b1db 100644
--- a/JavaScriptCore/kjs/string_object.h
+++ b/JavaScriptCore/kjs/string_object.h
@@ -126,13 +126,12 @@
    */
   class StringObjectImp : public InternalFunctionImp {
   public:
-    StringObjectImp(ExecState *exec,
-                    FunctionPrototype *funcProto,
-                    StringPrototype *stringProto);
+    StringObjectImp(ExecState*, FunctionPrototype*, StringPrototype*);
 
-    virtual bool implementsConstruct() const;
-    virtual JSObject *construct(ExecState *exec, const List &args);
-    virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args);
+    virtual ConstructType getConstructData(ConstructData&);
+    virtual JSObject* construct(ExecState*, const List&);
+
+    virtual JSValue* callAsFunction(ExecState*, JSObject* thisObj, const List& args);
   };
 
   /**
diff --git a/JavaScriptCore/kjs/testkjs.cpp b/JavaScriptCore/kjs/testkjs.cpp
index 153bdf9..26f5d2e 100644
--- a/JavaScriptCore/kjs/testkjs.cpp
+++ b/JavaScriptCore/kjs/testkjs.cpp
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include "CodeGenerator.h"
 #include "JSGlobalObject.h"
 #include "JSLock.h"
 #include "Parser.h"
@@ -183,8 +184,10 @@
     if (!fillBufferWithContentsOfFile(fileName, script))
         return throwError(exec, GeneralError, "Could not open file.");
 
+    JSGlobalObject* globalObject = exec->dynamicGlobalObject();
+
     stopWatch.start();
-    Interpreter::evaluate(exec->dynamicGlobalObject()->globalExec(), fileName, 0, script.data());
+    Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), fileName, 0, script.data());
     stopWatch.stop();
 
     return jsNumber(stopWatch.getElapsedMS());
@@ -197,7 +200,8 @@
     if (!fillBufferWithContentsOfFile(fileName, script))
         return throwError(exec, GeneralError, "Could not open file.");
 
-    Interpreter::evaluate(exec->dynamicGlobalObject()->globalExec(), fileName, 0, script.data());
+    JSGlobalObject* globalObject = exec->dynamicGlobalObject();
+    Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), fileName, 0, script.data());
 
     return jsUndefined();
 }
@@ -258,12 +262,12 @@
     return res;
 }
 
-static bool prettyPrintScript(const UString& fileName, const Vector<char>& script)
+static bool prettyPrintScript(ExecState* exec, const UString& fileName, const Vector<char>& script)
 {
     int errLine = 0;
     UString errMsg;
     UString scriptUString(script.data());
-    RefPtr<ProgramNode> programNode = parser().parse<ProgramNode>(fileName, 0, scriptUString.data(), scriptUString.size(), 0, &errLine, &errMsg);
+    RefPtr<ProgramNode> programNode = parser().parse<ProgramNode>(exec, fileName, 0, UStringSourceProvider::create(scriptUString), 0, &errLine, &errMsg);
     if (!programNode) {
         fprintf(stderr, "%s:%d: %s.\n", fileName.UTF8String().c_str(), errLine, errMsg.UTF8String().c_str());
         return false;
@@ -273,11 +277,14 @@
     return true;
 }
 
-static bool runWithScripts(const Vector<UString>& fileNames, Vector<UString>& arguments, bool prettyPrint)
+static bool runWithScripts(const Vector<UString>& fileNames, Vector<UString>& arguments, bool prettyPrint, bool dump)
 {
     GlobalObject* globalObject = new GlobalObject(arguments);
     Vector<char> script;
 
+    if (dump)
+        CodeGenerator::setDumpsGeneratedCode(true);
+
     bool success = true;
 
     for (size_t i = 0; i < fileNames.size(); i++) {
@@ -287,10 +294,16 @@
             return false; // fail early so we can catch missing files
 
         if (prettyPrint)
-            prettyPrintScript(fileName, script);
+            prettyPrintScript(globalObject->globalExec(), fileName, script);
         else {
-            Completion completion = Interpreter::evaluate(globalObject->globalExec(), fileName, 0, script.data());
+            Completion completion = Interpreter::evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), fileName, 0, script.data());
             success = success && completion.complType() != Throw;
+            if (dump) {
+                if (success)
+                    printf("End: %s\n", completion.value()->toString(globalObject->globalExec()).ascii());
+                else
+                    printf("Exception: %s\n", completion.value()->toString(globalObject->globalExec()).ascii());
+            }
         }
     }
     return success;
@@ -302,7 +315,7 @@
     exit(-1);
 }
 
-static void parseArguments(int argc, char** argv, Vector<UString>& fileNames, Vector<UString>& arguments, bool& prettyPrint)
+static void parseArguments(int argc, char** argv, Vector<UString>& fileNames, Vector<UString>& arguments, bool& prettyPrint, bool& dump)
 {
     if (argc < 3)
         printUsageStatement();
@@ -320,6 +333,19 @@
             prettyPrint = true;
             continue;
         }
+        if (strcmp(arg, "-d") == 0) {
+            dump = true;
+            continue;
+        }
+        if (strcmp(arg, "-s") == 0) {
+#if PLATFORM(UNIX)
+            signal(SIGILL, _exit);
+            signal(SIGFPE, _exit);
+            signal(SIGBUS, _exit);
+            signal(SIGSEGV, _exit);
+#endif
+            continue;
+        }
         if (strcmp(arg, "--") == 0) {
             ++i;
             break;
@@ -338,11 +364,12 @@
     JSLock lock;
 
     bool prettyPrint = false;
+    bool dump = false;
     Vector<UString> fileNames;
     Vector<UString> arguments;
-    parseArguments(argc, argv, fileNames, arguments, prettyPrint);
+    parseArguments(argc, argv, fileNames, arguments, prettyPrint, dump);
 
-    bool success = runWithScripts(fileNames, arguments, prettyPrint);
+    bool success = runWithScripts(fileNames, arguments, prettyPrint, dump);
 
 #ifndef NDEBUG
     Collector::collect();
diff --git a/JavaScriptCore/kjs/testkjs.pro b/JavaScriptCore/kjs/testkjs.pro
index cabeace..3886f20 100644
--- a/JavaScriptCore/kjs/testkjs.pro
+++ b/JavaScriptCore/kjs/testkjs.pro
@@ -4,7 +4,12 @@
 SOURCES = testkjs.cpp
 QT -= gui
 DEFINES -= KJS_IDENTIFIER_HIDE_GLOBALS 
-INCLUDEPATH += $$PWD/.. $$PWD $$PWD/../bindings $$PWD/../bindings/c $$PWD/../wtf
+INCLUDEPATH += $$PWD/.. \
+    $$PWD \
+    $$PWD/../bindings \
+    $$PWD/../bindings/c \
+    $$PWD/../wtf \
+    $$PWD/../VM
 CONFIG -= app_bundle
 DEFINES += BUILDING_QT__
 
diff --git a/JavaScriptCore/kjs/value.cpp b/JavaScriptCore/kjs/value.cpp
index 55da40b..0b67849 100644
--- a/JavaScriptCore/kjs/value.cpp
+++ b/JavaScriptCore/kjs/value.cpp
@@ -207,6 +207,16 @@
     return isObject() ? static_cast<const JSObject *>(this) : 0;
 }
 
+CallType JSCell::getCallData(CallData&)
+{
+    return CallTypeNone;
+}
+
+ConstructType JSCell::getConstructData(ConstructData&)
+{
+    return ConstructTypeNone;
+}
+
 JSCell* jsString(const char* s)
 {
     return new StringImp(s ? s : "");
@@ -222,11 +232,4 @@
     return s.isNull() ? new StringImp("", StringImp::HasOtherOwner) : new StringImp(s, StringImp::HasOtherOwner);
 }
 
-// This method includes a PIC branch to set up the NumberImp's vtable, so we quarantine
-// it in a separate function to keep the normal case speedy.
-JSValue *jsNumberCell(double d)
-{
-    return new NumberImp(d);
-}
-
 } // namespace KJS
diff --git a/JavaScriptCore/kjs/value.h b/JavaScriptCore/kjs/value.h
index dfbeee4..916bea9 100644
--- a/JavaScriptCore/kjs/value.h
+++ b/JavaScriptCore/kjs/value.h
@@ -23,6 +23,8 @@
 #ifndef KJS_VALUE_H
 #define KJS_VALUE_H
 
+#include "CallData.h"
+#include "ConstructData.h"
 #include "JSImmediate.h"
 #include "collector.h"
 #include "ustring.h"
@@ -35,6 +37,7 @@
 class JSCell;
 
 struct ClassInfo;
+struct Instruction;
 
 /**
  * JSValue is the base type for all primitives (Undefined, Null, Boolean,
@@ -69,21 +72,28 @@
     bool getBoolean() const; // false if not a boolean
     bool getNumber(double&) const;
     double getNumber() const; // NaN if not a number
+    double uncheckedGetNumber() const;
     bool getString(UString&) const;
     UString getString() const; // null string if not a string
     JSObject *getObject(); // NULL if not an object
     const JSObject *getObject() const; // NULL if not an object
 
+    CallType getCallData(CallData&);
+    ConstructType getConstructData(ConstructData&);
+
     // Extracting integer values.
     bool getUInt32(uint32_t&) const;
     bool getTruncatedInt32(int32_t&) const;
     bool getTruncatedUInt32(uint32_t&) const;
-
+    
     // Basic conversions.
     JSValue* toPrimitive(ExecState* exec, JSType preferredType = UnspecifiedType) const;
     bool getPrimitiveNumber(ExecState* exec, double& number, JSValue*& value);
 
     bool toBoolean(ExecState *exec) const;
+
+    // toNumber conversion is expected to be side effect free if an exception has
+    // been set in the ExecState already.
     double toNumber(ExecState *exec) const;
     JSValue* toJSNumber(ExecState*) const; // Fast path for when you expect that the value is an immediate number.
     UString toString(ExecState *exec) const;
@@ -130,6 +140,7 @@
     friend class StringImp;
     friend class JSObject;
     friend class GetterSetterImp;
+    friend class JSPropertyNameIterator;
 private:
     JSCell();
     virtual ~JSCell();
@@ -148,6 +159,9 @@
     UString getString() const; // null string if not a string
     JSObject *getObject(); // NULL if not an object
     const JSObject *getObject() const; // NULL if not an object
+    
+    virtual CallType getCallData(CallData&);
+    virtual ConstructType getConstructData(ConstructData&);
 
     // Extracting integer values.
     virtual bool getUInt32(uint32_t&) const;
@@ -168,7 +182,35 @@
     bool marked() const;
 };
 
-JSValue *jsNumberCell(double);
+class NumberImp : public JSCell {
+  friend JSValue* jsNumberCell(double);
+
+public:
+  double value() const { return val; }
+
+  virtual JSType type() const;
+
+  virtual JSValue* toPrimitive(ExecState*, JSType preferred = UnspecifiedType) const;
+  virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);
+  virtual bool toBoolean(ExecState* exec) const;
+  virtual double toNumber(ExecState* exec) const;
+  virtual UString toString(ExecState* exec) const;
+  virtual JSObject* toObject(ExecState* exec) const;
+  
+  void* operator new(size_t size)
+  {
+      return Collector::allocateNumber(size);
+  }
+
+private:
+  NumberImp(double v) : val(v) { }
+
+  virtual bool getUInt32(uint32_t&) const;
+  virtual bool getTruncatedInt32(int32_t&) const;
+  virtual bool getTruncatedUInt32(uint32_t&) const;
+
+  double val;
+};
 
 JSCell *jsString(const UString&); // returns empty string if passed null string
 JSCell *jsString(const char* = ""); // returns empty string if passed 0
@@ -181,7 +223,14 @@
 extern const double NaN;
 extern const double Inf;
 
-inline JSValue *jsUndefined()
+// Beware marking this function ALWAYS_INLINE: It takes a PIC branch, so
+// inlining it may not always be a win.
+inline JSValue* jsNumberCell(double d)
+{
+    return new NumberImp(d);
+}
+
+ALWAYS_INLINE JSValue *jsUndefined()
 {
     return JSImmediate::undefinedImmediate();
 }
@@ -367,6 +416,12 @@
     return JSImmediate::isImmediate(this) ? JSImmediate::toDouble(this) : asCell()->getNumber();
 }
 
+inline double JSValue::uncheckedGetNumber() const
+{
+    ASSERT(JSImmediate::isImmediate(this) || asCell()->isNumber());
+    return JSImmediate::isImmediate(this) ? JSImmediate::toDouble(this) : static_cast<const NumberImp*>(this)->value();
+}
+
 inline bool JSValue::getString(UString& s) const
 {
     return !JSImmediate::isImmediate(this) && asCell()->getString(s);
@@ -387,6 +442,16 @@
     return JSImmediate::isImmediate(this) ? 0 : asCell()->getObject();
 }
 
+inline CallType JSValue::getCallData(CallData& callData)
+{
+    return JSImmediate::isImmediate(this) ? CallTypeNone : asCell()->getCallData(callData);
+}
+
+inline ConstructType JSValue::getConstructData(ConstructData& constructData)
+{
+    return JSImmediate::isImmediate(this) ? ConstructTypeNone : asCell()->getConstructData(constructData);
+}
+
 ALWAYS_INLINE bool JSValue::getUInt32(uint32_t& v) const
 {
     return JSImmediate::isImmediate(this) ? JSImmediate::getUInt32(this, v) : asCell()->getUInt32(v);