]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - parser/Nodes.h
JavaScriptCore-1218.34.tar.gz
[apple/javascriptcore.git] / parser / Nodes.h
index 6e73c00ccce939286826b3beb5a67d2537d82d4b..2eeaae9d971d233bb20f74165ef282d342b5f4d2 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
- *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights reserved.
  *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
  *  Copyright (C) 2007 Maks Orlovich
  *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
@@ -30,6 +30,7 @@
 #include "JITCode.h"
 #include "Opcode.h"
 #include "ParserArena.h"
+#include "ParserTokens.h"
 #include "ResultType.h"
 #include "SourceCode.h"
 #include "SymbolTable.h"
@@ -44,25 +45,9 @@ namespace JSC {
     class PropertyListNode;
     class ReadModifyResolveNode;
     class RegisterID;
-    class ScopeChainNode;
+    class JSScope;
     class ScopeNode;
 
-    typedef unsigned CodeFeatures;
-
-    const CodeFeatures NoFeatures = 0;
-    const CodeFeatures EvalFeature = 1 << 0;
-    const CodeFeatures ClosureFeature = 1 << 1;
-    const CodeFeatures AssignFeature = 1 << 2;
-    const CodeFeatures ArgumentsFeature = 1 << 3;
-    const CodeFeatures WithFeature = 1 << 4;
-    const CodeFeatures CatchFeature = 1 << 5;
-    const CodeFeatures ThisFeature = 1 << 6;
-    const CodeFeatures StrictModeFeature = 1 << 7;
-    const CodeFeatures ShadowsArgumentsFeature = 1 << 8;
-    
-    
-    const CodeFeatures AllFeatures = EvalFeature | ClosureFeature | AssignFeature | ArgumentsFeature | WithFeature | CatchFeature | ThisFeature | StrictModeFeature | ShadowsArgumentsFeature;
-
     enum Operator {
         OpEqual,
         OpPlusEq,
@@ -85,6 +70,12 @@ namespace JSC {
         OpLogicalOr
     };
 
+    enum FallThroughMode {
+        FallThroughMeansTrue = 0,
+        FallThroughMeansFalse = 1
+    };
+    inline FallThroughMode invert(FallThroughMode fallThroughMode) { return static_cast<FallThroughMode>(!fallThroughMode); }
+
     typedef HashSet<RefPtr<StringImpl>, IdentifierRepHash> IdentifierSet;
 
     namespace DeclarationStacks {
@@ -103,7 +94,7 @@ namespace JSC {
     public:
         // ParserArenaFreeable objects are are freed when the arena is deleted.
         // Destructors are not called. Clients must not call delete on such objects.
-        void* operator new(size_t, JSGlobalData*);
+        void* operator new(size_t, VM*);
     };
 
     class ParserArenaDeletable {
@@ -112,12 +103,17 @@ namespace JSC {
 
         // ParserArenaDeletable objects are deleted when the arena is deleted.
         // Clients must not call delete directly on such objects.
-        void* operator new(size_t, JSGlobalData*);
+        void* operator new(size_t, VM*);
+    };
+
+    template <typename T>
+    struct ParserArenaData : ParserArenaDeletable {
+        T data;
     };
 
     class ParserArenaRefCounted : public RefCounted<ParserArenaRefCounted> {
     protected:
-        ParserArenaRefCounted(JSGlobalData*);
+        ParserArenaRefCounted(VM*);
 
     public:
         virtual ~ParserArenaRefCounted()
@@ -128,28 +124,33 @@ namespace JSC {
 
     class Node : public ParserArenaFreeable {
     protected:
-        Node(JSGlobalData*);
+        Node(const JSTokenLocation&);
 
     public:
         virtual ~Node() { }
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0;
-
-        int lineNo() const { return m_line; }
+        int lineNo() const { return m_lineNumber; }
+        int startOffset() const { return m_startOffset; }
+        int lineStartOffset() const { return m_lineStartOffset; }
 
     protected:
-        int m_line;
+        int m_lineNumber;
+        int m_startOffset;
+        int m_lineStartOffset;
     };
 
     class ExpressionNode : public Node {
     protected:
-        ExpressionNode(JSGlobalData*, ResultType = ResultType::unknownType());
+        ExpressionNode(const JSTokenLocation&, ResultType = ResultType::unknownType());
 
     public:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0;
+
         virtual bool isNumber() const { return false; }
         virtual bool isString() const { return false; }
         virtual bool isNull() const { return false; }
         virtual bool isPure(BytecodeGenerator&) const { return false; }        
+        virtual bool isConstant() const { return false; }
         virtual bool isLocation() const { return false; }
         virtual bool isResolveNode() const { return false; }
         virtual bool isBracketAccessorNode() const { return false; }
@@ -159,9 +160,9 @@ namespace JSC {
         virtual bool isSimpleArray() const { return false; }
         virtual bool isAdd() const { return false; }
         virtual bool isSubtract() const { return false; }
-        virtual bool hasConditionContextCodegen() const { return false; }
+        virtual bool isBoolean() const { return false; }
 
-        virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label*, Label*, bool) { ASSERT_NOT_REACHED(); }
+        virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label*, Label*, FallThroughMode);
 
         virtual ExpressionNode* stripUnaryPlus() { return this; }
 
@@ -173,73 +174,79 @@ namespace JSC {
 
     class StatementNode : public Node {
     protected:
-        StatementNode(JSGlobalData*);
+        StatementNode(const JSTokenLocation&);
 
     public:
-        void setLoc(int firstLine, int lastLine);
-        int firstLine() const { return lineNo(); }
-        int lastLine() const { return m_lastLine; }
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0;
+
+        void setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset);
+        unsigned firstLine() const { return lineNo(); }
+        unsigned lastLine() const { return m_lastLine; }
 
         virtual bool isEmptyStatement() const { return false; }
         virtual bool isReturnNode() const { return false; }
         virtual bool isExprStatement() const { return false; }
-
+        virtual bool isBreak() const { return false; }
+        virtual bool isContinue() const { return false; }
         virtual bool isBlock() const { return false; }
 
     private:
         int m_lastLine;
     };
 
-    class NullNode : public ExpressionNode {
+    class ConstantNode : public ExpressionNode {
     public:
-        NullNode(JSGlobalData*);
-
+        ConstantNode(const JSTokenLocation&, ResultType);
+        virtual bool isPure(BytecodeGenerator&) const { return true; }
+        virtual bool isConstant() const { return true; }
+        virtual JSValue jsValue(BytecodeGenerator&) const = 0;
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode);
+    };
+
+    class NullNode : public ConstantNode {
+    public:
+        NullNode(const JSTokenLocation&);
 
+    private:
         virtual bool isNull() const { return true; }
+        virtual JSValue jsValue(BytecodeGenerator&) const { return jsNull(); }
     };
 
-    class BooleanNode : public ExpressionNode {
+    class BooleanNode : public ConstantNode {
     public:
-        BooleanNode(JSGlobalData*, bool value);
+        BooleanNode(const JSTokenLocation&, bool value);
+        bool value() { return m_value; }
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
-        virtual bool isPure(BytecodeGenerator&) const { return true; }
+        virtual bool isBoolean() const { return true; }
+        virtual JSValue jsValue(BytecodeGenerator&) const { return jsBoolean(m_value); }
 
         bool m_value;
     };
 
-    class NumberNode : public ExpressionNode {
+    class NumberNode : public ConstantNode {
     public:
-        NumberNode(JSGlobalData*, double value);
-
-        double value() const { return m_value; }
+        NumberNode(const JSTokenLocation&, double value);
+        double value() { return m_value; }
         void setValue(double value) { m_value = value; }
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
         virtual bool isNumber() const { return true; }
-        virtual bool isPure(BytecodeGenerator&) const { return true; }
+        virtual JSValue jsValue(BytecodeGenerator&) const { return jsNumber(m_value); }
 
         double m_value;
     };
 
-    class StringNode : public ExpressionNode {
+    class StringNode : public ConstantNode {
     public:
-        StringNode(JSGlobalData*, const Identifier&);
-
+        StringNode(const JSTokenLocation&, const Identifier&);
         const Identifier& value() { return m_value; }
 
     private:
-        virtual bool isPure(BytecodeGenerator&) const { return true; }
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-        
         virtual bool isString() const { return true; }
+        virtual JSValue jsValue(BytecodeGenerator&) const;
 
         const Identifier& m_value;
     };
@@ -248,36 +255,48 @@ namespace JSC {
     public:
         ThrowableExpressionData()
             : m_divot(static_cast<uint32_t>(-1))
-            , m_startOffset(static_cast<uint16_t>(-1))
-            , m_endOffset(static_cast<uint16_t>(-1))
+            , m_divotStartOffset(static_cast<uint16_t>(-1))
+            , m_divotEndOffset(static_cast<uint16_t>(-1))
+            , m_divotLine(static_cast<uint32_t>(-1))
+            , m_divotLineStart(static_cast<uint32_t>(-1))
         {
         }
         
-        ThrowableExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
+        ThrowableExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
             : m_divot(divot)
-            , m_startOffset(startOffset)
-            , m_endOffset(endOffset)
+            , m_divotStartOffset(startOffset)
+            , m_divotEndOffset(endOffset)
+            , m_divotLine(divotLine)
+            , m_divotLineStart(divotLineStart)
         {
+            ASSERT(m_divot >= m_divotLineStart);
         }
         
-        void setExceptionSourceCode(unsigned divot, unsigned startOffset, unsigned endOffset)
+        void setExceptionSourceCode(unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
         {
+            ASSERT(divot >= divotLineStart);
             m_divot = divot;
-            m_startOffset = startOffset;
-            m_endOffset = endOffset;
+            m_divotStartOffset = startOffset;
+            m_divotEndOffset = endOffset;
+            m_divotLine = divotLine;
+            m_divotLineStart = divotLineStart;
         }
 
         uint32_t divot() const { return m_divot; }
-        uint16_t startOffset() const { return m_startOffset; }
-        uint16_t endOffset() const { return m_endOffset; }
+        uint16_t divotStartOffset() const { return m_divotStartOffset; }
+        uint16_t divotEndOffset() const { return m_divotEndOffset; }
+        uint32_t divotLine() const { return m_divotLine; }
+        uint32_t divotLineStart() const { return m_divotLineStart; }
 
     protected:
-        RegisterID* emitThrowReferenceError(BytecodeGenerator&, const UString& message);
+        RegisterID* emitThrowReferenceError(BytecodeGenerator&, const String& message);
 
     private:
         uint32_t m_divot;
-        uint16_t m_startOffset;
-        uint16_t m_endOffset;
+        uint16_t m_divotStartOffset;
+        uint16_t m_divotEndOffset;
+        uint32_t m_divotLine;
+        uint32_t m_divotLineStart;
     };
 
     class ThrowableSubExpressionData : public ThrowableExpressionData {
@@ -285,28 +304,48 @@ namespace JSC {
         ThrowableSubExpressionData()
             : m_subexpressionDivotOffset(0)
             , m_subexpressionEndOffset(0)
+            , m_subexpressionLineOffset(0)
+            , m_subexpressionLineStartOffset(0)
         {
         }
 
-        ThrowableSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
-            : ThrowableExpressionData(divot, startOffset, endOffset)
+        ThrowableSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
+            : ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart)
             , m_subexpressionDivotOffset(0)
             , m_subexpressionEndOffset(0)
+            , m_subexpressionLineOffset(0)
+            , m_subexpressionLineStartOffset(0)
         {
         }
 
-        void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset)
+        void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset, uint32_t subexpressionLine, uint32_t subexpressionLineStart)
         {
             ASSERT(subexpressionDivot <= divot());
-            if ((divot() - subexpressionDivot) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot
+            // Overflow means we can't do this safely, so just point at the primary divot,
+            // divotLine, or divotLineStart.
+            if ((divot() - subexpressionDivot) & ~0xFFFF)
+                return;
+            if ((divotLine() - subexpressionLine) & ~0xFFFF)
+                return;
+            if ((divotLineStart() - subexpressionLineStart) & ~0xFFFF)
                 return;
             m_subexpressionDivotOffset = divot() - subexpressionDivot;
             m_subexpressionEndOffset = subexpressionOffset;
+            m_subexpressionLineOffset = divotLine() - subexpressionLine;
+            m_subexpressionLineStartOffset = divotLineStart() - subexpressionLineStart;
         }
 
+        unsigned subexpressionDivot() { return divot() - m_subexpressionDivotOffset; }
+        unsigned subexpressionStartOffset() { return divotStartOffset() - m_subexpressionDivotOffset; }
+        unsigned subexpressionEndOffset() { return m_subexpressionEndOffset; }
+        unsigned subexpressionLine() { return divotLine() - m_subexpressionLineOffset; }
+        unsigned subexpressionLineStart() { return divotLineStart() - m_subexpressionLineStartOffset; }
+
     protected:
         uint16_t m_subexpressionDivotOffset;
         uint16_t m_subexpressionEndOffset;
+        uint16_t m_subexpressionLineOffset;
+        uint16_t m_subexpressionLineStartOffset;
     };
     
     class ThrowablePrefixedSubExpressionData : public ThrowableExpressionData {
@@ -314,33 +353,53 @@ namespace JSC {
         ThrowablePrefixedSubExpressionData()
             : m_subexpressionDivotOffset(0)
             , m_subexpressionStartOffset(0)
+            , m_subexpressionLineOffset(0)
+            , m_subexpressionLineStartOffset(0)
         {
         }
 
-        ThrowablePrefixedSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
-            : ThrowableExpressionData(divot, startOffset, endOffset)
+        ThrowablePrefixedSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart)
+            : ThrowableExpressionData(divot, startOffset, endOffset, divotLine, divotLineStart)
             , m_subexpressionDivotOffset(0)
             , m_subexpressionStartOffset(0)
+            , m_subexpressionLineOffset(0)
+            , m_subexpressionLineStartOffset(0)
         {
         }
 
-        void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset)
+        void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset, uint32_t subexpressionLine, uint32_t subexpressionLineStart)
         {
             ASSERT(subexpressionDivot >= divot());
-            if ((subexpressionDivot - divot()) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot
+            // Overflow means we can't do this safely, so just point at the primary divot,
+            // divotLine, or divotLineStart.
+            if ((subexpressionDivot - divot()) & ~0xFFFF) 
+                return;
+            if ((subexpressionLine - divotLine()) & ~0xFFFF)
+                return;
+            if ((subexpressionLineStart - divotLineStart()) & ~0xFFFF)
                 return;
             m_subexpressionDivotOffset = subexpressionDivot - divot();
             m_subexpressionStartOffset = subexpressionOffset;
+            m_subexpressionLineOffset = subexpressionLine - divotLine();
+            m_subexpressionLineStartOffset = subexpressionLineStart - divotLineStart();
         }
 
+        unsigned subexpressionDivot() { return divot() + m_subexpressionDivotOffset; }
+        unsigned subexpressionStartOffset() { return m_subexpressionStartOffset; }
+        unsigned subexpressionEndOffset() { return divotEndOffset() + m_subexpressionDivotOffset; }
+        unsigned subexpressionLine() { return divotLine() + m_subexpressionLineOffset; }
+        unsigned subexpressionLineStart() { return divotLineStart() + m_subexpressionLineStartOffset; }
+
     protected:
         uint16_t m_subexpressionDivotOffset;
         uint16_t m_subexpressionStartOffset;
+        uint16_t m_subexpressionLineOffset;
+        uint16_t m_subexpressionLineStartOffset;
     };
 
     class RegExpNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        RegExpNode(JSGlobalData*, const Identifier& pattern, const Identifier& flags);
+        RegExpNode(const JSTokenLocation&, const Identifier& pattern, const Identifier& flags);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -351,7 +410,7 @@ namespace JSC {
 
     class ThisNode : public ExpressionNode {
     public:
-        ThisNode(JSGlobalData*);
+        ThisNode(const JSTokenLocation&);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -359,7 +418,7 @@ namespace JSC {
 
     class ResolveNode : public ExpressionNode {
     public:
-        ResolveNode(JSGlobalData*, const Identifier&, int startOffset);
+        ResolveNode(const JSTokenLocation&, const Identifier&, unsigned startOffset, unsigned divotLine, unsigned divotLineStart);
 
         const Identifier& identifier() const { return m_ident; }
 
@@ -371,13 +430,15 @@ namespace JSC {
         virtual bool isResolveNode() const { return true; }
 
         const Identifier& m_ident;
-        int32_t m_startOffset;
+        uint32_t m_startOffset;
+        uint32_t m_divotLine;
+        uint32_t m_divotLineStart;
     };
 
     class ElementNode : public ParserArenaFreeable {
     public:
-        ElementNode(JSGlobalData*, int elision, ExpressionNode*);
-        ElementNode(JSGlobalData*, ElementNode*, int elision, ExpressionNode*);
+        ElementNode(int elision, ExpressionNode*);
+        ElementNode(ElementNode*, int elision, ExpressionNode*);
 
         int elision() const { return m_elision; }
         ExpressionNode* value() { return m_node; }
@@ -391,11 +452,11 @@ namespace JSC {
 
     class ArrayNode : public ExpressionNode {
     public:
-        ArrayNode(JSGlobalData*, int elision);
-        ArrayNode(JSGlobalData*, ElementNode*);
-        ArrayNode(JSGlobalData*, int elision, ElementNode*);
+        ArrayNode(const JSTokenLocation&, int elision);
+        ArrayNode(const JSTokenLocation&, ElementNode*);
+        ArrayNode(const JSTokenLocation&, int elision, ElementNode*);
 
-        ArgumentListNode* toArgumentList(JSGlobalData*) const;
+        ArgumentListNode* toArgumentList(VM*, int, int) const;
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -411,8 +472,8 @@ namespace JSC {
     public:
         enum Type { Constant = 1, Getter = 2, Setter = 4 };
 
-        PropertyNode(JSGlobalData*, const Identifier& name, ExpressionNode* value, Type);
-        PropertyNode(JSGlobalData*, double name, ExpressionNode* value, Type);
+        PropertyNode(VM*, const Identifier&, ExpressionNode*, Type);
+        PropertyNode(VM*, double, ExpressionNode*, Type);
 
         const Identifier& name() const { return m_name; }
         Type type() const { return m_type; }
@@ -424,10 +485,10 @@ namespace JSC {
         Type m_type;
     };
 
-    class PropertyListNode : public Node {
+    class PropertyListNode : public ExpressionNode {
     public:
-        PropertyListNode(JSGlobalData*, PropertyNode*);
-        PropertyListNode(JSGlobalData*, PropertyNode*, PropertyListNode*);
+        PropertyListNode(const JSTokenLocation&, PropertyNode*);
+        PropertyListNode(const JSTokenLocation&, PropertyNode*, PropertyListNode*);
 
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
@@ -438,8 +499,8 @@ namespace JSC {
 
     class ObjectLiteralNode : public ExpressionNode {
     public:
-        ObjectLiteralNode(JSGlobalData*);
-        ObjectLiteralNode(JSGlobalData*, PropertyListNode*);
+        ObjectLiteralNode(const JSTokenLocation&);
+        ObjectLiteralNode(const JSTokenLocation&, PropertyListNode*);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -449,11 +510,13 @@ namespace JSC {
     
     class BracketAccessorNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        BracketAccessorNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments);
+        BracketAccessorNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments);
 
         ExpressionNode* base() const { return m_base; }
         ExpressionNode* subscript() const { return m_subscript; }
 
+        bool subscriptHasAssignments() const { return m_subscriptHasAssignments; }
+
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
@@ -467,7 +530,7 @@ namespace JSC {
 
     class DotAccessorNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        DotAccessorNode(JSGlobalData*, ExpressionNode* base, const Identifier&);
+        DotAccessorNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&);
 
         ExpressionNode* base() const { return m_base; }
         const Identifier& identifier() const { return m_ident; }
@@ -482,10 +545,10 @@ namespace JSC {
         const Identifier& m_ident;
     };
 
-    class ArgumentListNode : public Node {
+    class ArgumentListNode : public ExpressionNode {
     public:
-        ArgumentListNode(JSGlobalData*, ExpressionNode*);
-        ArgumentListNode(JSGlobalData*, ArgumentListNode*, ExpressionNode*);
+        ArgumentListNode(const JSTokenLocation&, ExpressionNode*);
+        ArgumentListNode(const JSTokenLocation&, ArgumentListNode*, ExpressionNode*);
 
         ArgumentListNode* m_next;
         ExpressionNode* m_expr;
@@ -496,16 +559,16 @@ namespace JSC {
 
     class ArgumentsNode : public ParserArenaFreeable {
     public:
-        ArgumentsNode(JSGlobalData*);
-        ArgumentsNode(JSGlobalData*, ArgumentListNode*);
+        ArgumentsNode();
+        ArgumentsNode(ArgumentListNode*);
 
         ArgumentListNode* m_listNode;
     };
 
     class NewExprNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        NewExprNode(JSGlobalData*, ExpressionNode*);
-        NewExprNode(JSGlobalData*, ExpressionNode*, ArgumentsNode*);
+        NewExprNode(const JSTokenLocation&, ExpressionNode*);
+        NewExprNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -516,7 +579,7 @@ namespace JSC {
 
     class EvalFunctionCallNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        EvalFunctionCallNode(JSGlobalData*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+        EvalFunctionCallNode(const JSTokenLocation&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -526,7 +589,7 @@ namespace JSC {
 
     class FunctionCallValueNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        FunctionCallValueNode(JSGlobalData*, ExpressionNode*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+        FunctionCallValueNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -537,20 +600,18 @@ namespace JSC {
 
     class FunctionCallResolveNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        FunctionCallResolveNode(JSGlobalData*, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+        FunctionCallResolveNode(const JSTokenLocation&, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
         const Identifier& m_ident;
         ArgumentsNode* m_args;
-        size_t m_index; // Used by LocalVarFunctionCallNode.
-        size_t m_scopeDepth; // Used by ScopedVarFunctionCallNode and NonLocalVarFunctionCallNode
     };
     
     class FunctionCallBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
     public:
-        FunctionCallBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+        FunctionCallBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -562,7 +623,7 @@ namespace JSC {
 
     class FunctionCallDotNode : public ExpressionNode, public ThrowableSubExpressionData {
     public:
-        FunctionCallDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+        FunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -575,7 +636,7 @@ namespace JSC {
 
     class CallFunctionCallDotNode : public FunctionCallDotNode {
     public:
-        CallFunctionCallDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+        CallFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -583,68 +644,15 @@ namespace JSC {
     
     class ApplyFunctionCallDotNode : public FunctionCallDotNode {
     public:
-        ApplyFunctionCallDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
-
-    private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-    };
-
-    class PrePostResolveNode : public ExpressionNode, public ThrowableExpressionData {
-    public:
-        PrePostResolveNode(JSGlobalData*, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
-
-    protected:
-        const Identifier& m_ident;
-    };
-
-    class PostfixResolveNode : public PrePostResolveNode {
-    public:
-        PostfixResolveNode(JSGlobalData*, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
-
-    private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
-        Operator m_operator;
-    };
-
-    class PostfixBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
-    public:
-        PostfixBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
-
-    private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
-        ExpressionNode* m_base;
-        ExpressionNode* m_subscript;
-        Operator m_operator;
-    };
-
-    class PostfixDotNode : public ExpressionNode, public ThrowableSubExpressionData {
-    public:
-        PostfixDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
-
-    private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
-        ExpressionNode* m_base;
-        const Identifier& m_ident;
-        Operator m_operator;
-    };
-
-    class PostfixErrorNode : public ExpressionNode, public ThrowableSubExpressionData {
-    public:
-        PostfixErrorNode(JSGlobalData*, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
+        ApplyFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
-        ExpressionNode* m_expr;
-        Operator m_operator;
     };
 
     class DeleteResolveNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        DeleteResolveNode(JSGlobalData*, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DeleteResolveNode(const JSTokenLocation&, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -654,7 +662,7 @@ namespace JSC {
 
     class DeleteBracketNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        DeleteBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DeleteBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -665,7 +673,7 @@ namespace JSC {
 
     class DeleteDotNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        DeleteDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DeleteDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -676,7 +684,7 @@ namespace JSC {
 
     class DeleteValueNode : public ExpressionNode {
     public:
-        DeleteValueNode(JSGlobalData*, ExpressionNode*);
+        DeleteValueNode(const JSTokenLocation&, ExpressionNode*);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -686,7 +694,7 @@ namespace JSC {
 
     class VoidNode : public ExpressionNode {
     public:
-        VoidNode(JSGlobalData*, ExpressionNode*);
+        VoidNode(const JSTokenLocation&, ExpressionNode*);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -696,7 +704,7 @@ namespace JSC {
 
     class TypeOfResolveNode : public ExpressionNode {
     public:
-        TypeOfResolveNode(JSGlobalData*, const Identifier&);
+        TypeOfResolveNode(const JSTokenLocation&, const Identifier&);
 
         const Identifier& identifier() const { return m_ident; }
 
@@ -708,7 +716,7 @@ namespace JSC {
 
     class TypeOfValueNode : public ExpressionNode {
     public:
-        TypeOfValueNode(JSGlobalData*, ExpressionNode*);
+        TypeOfValueNode(const JSTokenLocation&, ExpressionNode*);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -716,54 +724,34 @@ namespace JSC {
         ExpressionNode* m_expr;
     };
 
-    class PrefixResolveNode : public PrePostResolveNode {
-    public:
-        PrefixResolveNode(JSGlobalData*, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
-
-    private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
-        Operator m_operator;
-    };
-
-    class PrefixBracketNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
-    public:
-        PrefixBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
-
-    private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
-        ExpressionNode* m_base;
-        ExpressionNode* m_subscript;
-        Operator m_operator;
-    };
-
-    class PrefixDotNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
+    class PrefixNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
     public:
-        PrefixDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
+        PrefixNode(const JSTokenLocation&, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
 
-    private:
+    protected:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitResolve(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBracket(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitDot(BytecodeGenerator&, RegisterID* = 0);
 
-        ExpressionNode* m_base;
-        const Identifier& m_ident;
+        ExpressionNode* m_expr;
         Operator m_operator;
     };
 
-    class PrefixErrorNode : public ExpressionNode, public ThrowableExpressionData {
+    class PostfixNode : public PrefixNode {
     public:
-        PrefixErrorNode(JSGlobalData*, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
+        PostfixNode(const JSTokenLocation&, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
-        ExpressionNode* m_expr;
-        Operator m_operator;
+        virtual RegisterID* emitResolve(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBracket(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitDot(BytecodeGenerator&, RegisterID* = 0);
     };
 
     class UnaryOpNode : public ExpressionNode {
     public:
-        UnaryOpNode(JSGlobalData*, ResultType, ExpressionNode*, OpcodeID);
+        UnaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode*, OpcodeID);
 
     protected:
         ExpressionNode* expr() { return m_expr; }
@@ -780,7 +768,7 @@ namespace JSC {
 
     class UnaryPlusNode : public UnaryOpNode {
     public:
-        UnaryPlusNode(JSGlobalData*, ExpressionNode*);
+        UnaryPlusNode(const JSTokenLocation&, ExpressionNode*);
 
     private:
         virtual ExpressionNode* stripUnaryPlus() { return expr(); }
@@ -788,33 +776,43 @@ namespace JSC {
 
     class NegateNode : public UnaryOpNode {
     public:
-        NegateNode(JSGlobalData*, ExpressionNode*);
+        NegateNode(const JSTokenLocation&, ExpressionNode*);
     };
 
-    class BitwiseNotNode : public UnaryOpNode {
+    class BitwiseNotNode : public ExpressionNode {
     public:
-        BitwiseNotNode(JSGlobalData*, ExpressionNode*);
-    };
+        BitwiseNotNode(const JSTokenLocation&, ExpressionNode*);
 
+    protected:
+        ExpressionNode* expr() { return m_expr; }
+        const ExpressionNode* expr() const { return m_expr; }
+
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_expr;
+    };
     class LogicalNotNode : public UnaryOpNode {
     public:
-        LogicalNotNode(JSGlobalData*, ExpressionNode*);
+        LogicalNotNode(const JSTokenLocation&, ExpressionNode*);
     private:
-        void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue);
-        virtual bool hasConditionContextCodegen() const { return expr()->hasConditionContextCodegen(); }
+        void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode);
     };
 
     class BinaryOpNode : public ExpressionNode {
     public:
-        BinaryOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
-        BinaryOpNode(JSGlobalData*, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
+        BinaryOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
+        BinaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
 
         RegisterID* emitStrcat(BytecodeGenerator& generator, RegisterID* destination, RegisterID* lhs = 0, ReadModifyResolveNode* emitExpressionInfoForMe = 0);
+        void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode);
 
         ExpressionNode* lhs() { return m_expr1; };
         ExpressionNode* rhs() { return m_expr2; };
 
     private:
+        void tryFoldToBranch(BytecodeGenerator&, TriState& branchCondition, ExpressionNode*& branchExpression);
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
     protected:
@@ -829,82 +827,74 @@ namespace JSC {
         bool m_rightHasAssignments;
     };
 
-    class ReverseBinaryOpNode : public BinaryOpNode {
-    public:
-        ReverseBinaryOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
-        ReverseBinaryOpNode(JSGlobalData*, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
-
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-    };
-
     class MultNode : public BinaryOpNode {
     public:
-        MultNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        MultNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class DivNode : public BinaryOpNode {
     public:
-        DivNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        DivNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class ModNode : public BinaryOpNode {
     public:
-        ModNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        ModNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class AddNode : public BinaryOpNode {
     public:
-        AddNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        AddNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
 
         virtual bool isAdd() const { return true; }
     };
 
     class SubNode : public BinaryOpNode {
     public:
-        SubNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        SubNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
 
         virtual bool isSubtract() const { return true; }
     };
 
     class LeftShiftNode : public BinaryOpNode {
     public:
-        LeftShiftNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        LeftShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class RightShiftNode : public BinaryOpNode {
     public:
-        RightShiftNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        RightShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class UnsignedRightShiftNode : public BinaryOpNode {
     public:
-        UnsignedRightShiftNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        UnsignedRightShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class LessNode : public BinaryOpNode {
     public:
-        LessNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        LessNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
-    class GreaterNode : public ReverseBinaryOpNode {
+    class GreaterNode : public BinaryOpNode {
     public:
-        GreaterNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        GreaterNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class LessEqNode : public BinaryOpNode {
     public:
-        LessEqNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        LessEqNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
-    class GreaterEqNode : public ReverseBinaryOpNode {
+    class GreaterEqNode : public BinaryOpNode {
     public:
-        GreaterEqNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        GreaterEqNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class ThrowableBinaryOpNode : public BinaryOpNode, public ThrowableExpressionData {
     public:
-        ThrowableBinaryOpNode(JSGlobalData*, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
-        ThrowableBinaryOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
+        ThrowableBinaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
+        ThrowableBinaryOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -912,7 +902,7 @@ namespace JSC {
     
     class InstanceOfNode : public ThrowableBinaryOpNode {
     public:
-        InstanceOfNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        InstanceOfNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -920,12 +910,12 @@ namespace JSC {
 
     class InNode : public ThrowableBinaryOpNode {
     public:
-        InNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        InNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class EqualNode : public BinaryOpNode {
     public:
-        EqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        EqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -933,12 +923,12 @@ namespace JSC {
 
     class NotEqualNode : public BinaryOpNode {
     public:
-        NotEqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        NotEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class StrictEqualNode : public BinaryOpNode {
     public:
-        StrictEqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        StrictEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -946,33 +936,32 @@ namespace JSC {
 
     class NotStrictEqualNode : public BinaryOpNode {
     public:
-        NotStrictEqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        NotStrictEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class BitAndNode : public BinaryOpNode {
     public:
-        BitAndNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        BitAndNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class BitOrNode : public BinaryOpNode {
     public:
-        BitOrNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        BitOrNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     class BitXOrNode : public BinaryOpNode {
     public:
-        BitXOrNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        BitXOrNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
     };
 
     // m_expr1 && m_expr2, m_expr1 || m_expr2
     class LogicalOpNode : public ExpressionNode {
     public:
-        LogicalOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator);
+        LogicalOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-        void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue);
-        virtual bool hasConditionContextCodegen() const { return true; }
+        void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode);
 
         ExpressionNode* m_expr1;
         ExpressionNode* m_expr2;
@@ -982,7 +971,7 @@ namespace JSC {
     // The ternary operator, "m_logical ? m_expr1 : m_expr2"
     class ConditionalNode : public ExpressionNode {
     public:
-        ConditionalNode(JSGlobalData*, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2);
+        ConditionalNode(const JSTokenLocation&, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -994,34 +983,31 @@ namespace JSC {
 
     class ReadModifyResolveNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        ReadModifyResolveNode(JSGlobalData*, const Identifier&, Operator, ExpressionNode*  right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
+        ReadModifyResolveNode(const JSTokenLocation&, const Identifier&, Operator, ExpressionNode*  right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned line, unsigned lineStart);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
         const Identifier& m_ident;
         ExpressionNode* m_right;
-        size_t m_index; // Used by ReadModifyLocalVarNode.
         Operator m_operator;
         bool m_rightHasAssignments;
     };
 
     class AssignResolveNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        AssignResolveNode(JSGlobalData*, const Identifier&, ExpressionNode* right, bool rightHasAssignments);
+        AssignResolveNode(const JSTokenLocation&, const Identifier&, ExpressionNode* right);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
         const Identifier& m_ident;
         ExpressionNode* m_right;
-        size_t m_index; // Used by ReadModifyLocalVarNode.
-        bool m_rightHasAssignments;
     };
 
     class ReadModifyBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
     public:
-        ReadModifyBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, Operator, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
+        ReadModifyBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, Operator, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1036,7 +1022,7 @@ namespace JSC {
 
     class AssignBracketNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        AssignBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
+        AssignBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1050,7 +1036,7 @@ namespace JSC {
 
     class AssignDotNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        AssignDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
+        AssignDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1063,7 +1049,7 @@ namespace JSC {
 
     class ReadModifyDotNode : public ExpressionNode, public ThrowableSubExpressionData {
     public:
-        ReadModifyDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
+        ReadModifyDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1077,21 +1063,17 @@ namespace JSC {
 
     class AssignErrorNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        AssignErrorNode(JSGlobalData*, ExpressionNode* left, Operator, ExpressionNode* right, unsigned divot, unsigned startOffset, unsigned endOffset);
+        AssignErrorNode(const JSTokenLocation&, unsigned divot, unsigned startOffset, unsigned endOffset, unsigned divotLine, unsigned divotLineStart);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
-        ExpressionNode* m_left;
-        Operator m_operator;
-        ExpressionNode* m_right;
     };
     
     typedef Vector<ExpressionNode*, 8> ExpressionVector;
 
     class CommaNode : public ExpressionNode, public ParserArenaDeletable {
     public:
-        CommaNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2);
+        CommaNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2);
 
         using ParserArenaDeletable::operator new;
 
@@ -1106,7 +1088,7 @@ namespace JSC {
     
     class ConstDeclNode : public ExpressionNode {
     public:
-        ConstDeclNode(JSGlobalData*, const Identifier&, ExpressionNode*);
+        ConstDeclNode(const JSTokenLocation&, const Identifier&, ExpressionNode*);
 
         bool hasInitializer() const { return m_init; }
         const Identifier& ident() { return m_ident; }
@@ -1126,17 +1108,17 @@ namespace JSC {
 
     class ConstStatementNode : public StatementNode {
     public:
-        ConstStatementNode(JSGlobalData*, ConstDeclNode* next);
+        ConstStatementNode(const JSTokenLocation&, ConstDeclNode* next);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
         ConstDeclNode* m_next;
     };
 
     class SourceElements : public ParserArenaDeletable {
     public:
-        SourceElements(JSGlobalData*);
+        SourceElements();
 
         void append(StatementNode*);
 
@@ -1151,13 +1133,13 @@ namespace JSC {
 
     class BlockNode : public StatementNode {
     public:
-        BlockNode(JSGlobalData*, SourceElements* = 0);
+        BlockNode(const JSTokenLocation&, SourceElements* = 0);
 
         StatementNode* singleStatement() const;
         StatementNode* lastStatement() const;
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
         virtual bool isBlock() const { return true; }
 
@@ -1166,73 +1148,65 @@ namespace JSC {
 
     class EmptyStatementNode : public StatementNode {
     public:
-        EmptyStatementNode(JSGlobalData*);
+        EmptyStatementNode(const JSTokenLocation&);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
         virtual bool isEmptyStatement() const { return true; }
     };
     
     class DebuggerStatementNode : public StatementNode {
     public:
-        DebuggerStatementNode(JSGlobalData*);
+        DebuggerStatementNode(const JSTokenLocation&);
         
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
     };
 
     class ExprStatementNode : public StatementNode {
     public:
-        ExprStatementNode(JSGlobalData*, ExpressionNode*);
+        ExprStatementNode(const JSTokenLocation&, ExpressionNode*);
 
         ExpressionNode* expr() const { return m_expr; }
 
     private:
         virtual bool isExprStatement() const { return true; }
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
         ExpressionNode* m_expr;
     };
 
     class VarStatementNode : public StatementNode {
     public:
-        VarStatementNode(JSGlobalData*, ExpressionNode*);        
-
+        VarStatementNode(const JSTokenLocation&, ExpressionNode*);
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
         ExpressionNode* m_expr;
     };
 
-    class IfNode : public StatementNode {
+    class IfElseNode : public StatementNode {
     public:
-        IfNode(JSGlobalData*, ExpressionNode* condition, StatementNode* ifBlock);
+        IfElseNode(const JSTokenLocation&, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock);
 
-    protected:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+    private:
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        bool tryFoldBreakAndContinue(BytecodeGenerator&, StatementNode* ifBlock,
+            Label*& trueTarget, FallThroughMode&);
 
         ExpressionNode* m_condition;
         StatementNode* m_ifBlock;
-    };
-
-    class IfElseNode : public IfNode {
-    public:
-        IfElseNode(JSGlobalData*, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock);
-
-    private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
         StatementNode* m_elseBlock;
     };
 
     class DoWhileNode : public StatementNode {
     public:
-        DoWhileNode(JSGlobalData*, StatementNode* statement, ExpressionNode*);
+        DoWhileNode(const JSTokenLocation&, StatementNode*, ExpressionNode*);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
         StatementNode* m_statement;
         ExpressionNode* m_expr;
@@ -1240,10 +1214,10 @@ namespace JSC {
 
     class WhileNode : public StatementNode {
     public:
-        WhileNode(JSGlobalData*, ExpressionNode*, StatementNode* statement);
+        WhileNode(const JSTokenLocation&, ExpressionNode*, StatementNode*);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
         ExpressionNode* m_expr;
         StatementNode* m_statement;
@@ -1251,64 +1225,65 @@ namespace JSC {
 
     class ForNode : public StatementNode {
     public:
-        ForNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode* statement, bool expr1WasVarDecl);
+        ForNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode*);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
         ExpressionNode* m_expr1;
         ExpressionNode* m_expr2;
         ExpressionNode* m_expr3;
         StatementNode* m_statement;
-        bool m_expr1WasVarDecl;
     };
 
     class ForInNode : public StatementNode, public ThrowableExpressionData {
     public:
-        ForInNode(JSGlobalData*, ExpressionNode*, ExpressionNode*, StatementNode*);
-        ForInNode(JSGlobalData*, const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*, int divot, int startOffset, int endOffset);
+        ForInNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*);
+        ForInNode(VM*, const JSTokenLocation&, const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*, unsigned divot, int startOffset, int endOffset, unsigned divotLine, unsigned divotLineStart);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
-        const Identifier& m_ident;
         ExpressionNode* m_init;
         ExpressionNode* m_lexpr;
         ExpressionNode* m_expr;
         StatementNode* m_statement;
-        bool m_identIsVarDecl;
     };
 
     class ContinueNode : public StatementNode, public ThrowableExpressionData {
     public:
-        ContinueNode(JSGlobalData*);
-        ContinueNode(JSGlobalData*, const Identifier&);
+        ContinueNode(VM*, const JSTokenLocation&);
+        ContinueNode(const JSTokenLocation&, const Identifier&);
+        Label* trivialTarget(BytecodeGenerator&);
         
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual bool isContinue() const { return true; }
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
         const Identifier& m_ident;
     };
 
     class BreakNode : public StatementNode, public ThrowableExpressionData {
     public:
-        BreakNode(JSGlobalData*);
-        BreakNode(JSGlobalData*, const Identifier&);
+        BreakNode(VM*, const JSTokenLocation&);
+        BreakNode(const JSTokenLocation&, const Identifier&);
+        Label* trivialTarget(BytecodeGenerator&);
         
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual bool isBreak() const { return true; }
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
         const Identifier& m_ident;
     };
 
     class ReturnNode : public StatementNode, public ThrowableExpressionData {
     public:
-        ReturnNode(JSGlobalData*, ExpressionNode* value);
+        ReturnNode(const JSTokenLocation&, ExpressionNode* value);
 
         ExpressionNode* value() { return m_value; }
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
         virtual bool isReturnNode() const { return true; }
 
@@ -1317,23 +1292,25 @@ namespace JSC {
 
     class WithNode : public StatementNode {
     public:
-        WithNode(JSGlobalData*, ExpressionNode*, StatementNode*, uint32_t divot, uint32_t expressionLength);
+        WithNode(const JSTokenLocation&, ExpressionNode*, StatementNode*, uint32_t divot, unsigned divotLine, unsigned divotLineStart, uint32_t expressionLength);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
         ExpressionNode* m_expr;
         StatementNode* m_statement;
         uint32_t m_divot;
+        uint32_t m_divotLine;
+        uint32_t m_divotLineStart;
         uint32_t m_expressionLength;
     };
 
     class LabelNode : public StatementNode, public ThrowableExpressionData {
     public:
-        LabelNode(JSGlobalData*, const Identifier& name, StatementNode*);
+        LabelNode(const JSTokenLocation&, const Identifier& name, StatementNode*);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
         const Identifier& m_name;
         StatementNode* m_statement;
@@ -1341,32 +1318,31 @@ namespace JSC {
 
     class ThrowNode : public StatementNode, public ThrowableExpressionData {
     public:
-        ThrowNode(JSGlobalData*, ExpressionNode*);
+        ThrowNode(const JSTokenLocation&, ExpressionNode*);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
         ExpressionNode* m_expr;
     };
 
     class TryNode : public StatementNode {
     public:
-        TryNode(JSGlobalData*, StatementNode* tryBlock, const Identifier& exceptionIdent, bool catchHasEval, StatementNode* catchBlock, StatementNode* finallyBlock);
+        TryNode(const JSTokenLocation&, StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
         StatementNode* m_tryBlock;
         const Identifier& m_exceptionIdent;
         StatementNode* m_catchBlock;
         StatementNode* m_finallyBlock;
-        bool m_catchHasEval;
     };
 
     class ParameterNode : public ParserArenaFreeable {
     public:
-        ParameterNode(JSGlobalData*, const Identifier&);
-        ParameterNode(JSGlobalData*, ParameterNode*, const Identifier&);
+        ParameterNode(const Identifier&);
+        ParameterNode(ParameterNode*, const Identifier&);
 
         const Identifier& ident() const { return m_ident; }
         ParameterNode* nextParam() const { return m_next; }
@@ -1376,38 +1352,32 @@ namespace JSC {
         ParameterNode* m_next;
     };
 
-    struct ScopeNodeData {
-        WTF_MAKE_FAST_ALLOCATED;
-    public:
-        typedef DeclarationStacks::VarStack VarStack;
-        typedef DeclarationStacks::FunctionStack FunctionStack;
-
-        ScopeNodeData(ParserArena&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, int numConstants);
-
-        ParserArena m_arena;
-        VarStack m_varStack;
-        FunctionStack m_functionStack;
-        int m_numConstants;
-        SourceElements* m_statements;
-        IdentifierSet m_capturedVariables;
-    };
-
     class ScopeNode : public StatementNode, public ParserArenaRefCounted {
     public:
         typedef DeclarationStacks::VarStack VarStack;
         typedef DeclarationStacks::FunctionStack FunctionStack;
 
-        ScopeNode(JSGlobalData*, bool inStrictContext);
-        ScopeNode(JSGlobalData*, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, CodeFeatures, int numConstants);
+        ScopeNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, bool inStrictContext);
+        ScopeNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, CodeFeatures, int numConstants);
 
         using ParserArenaRefCounted::operator new;
 
-        ScopeNodeData* data() const { return m_data.get(); }
-        void destroyData() { m_data.clear(); }
+        void destroyData()
+        {
+            m_arena.reset();
+            m_varStack.clear();
+            m_functionStack.clear();
+            m_statements = 0;
+            m_capturedVariables.clear();
+        }
 
         const SourceCode& source() const { return m_source; }
-        const UString& sourceURL() const { return m_source.provider()->url(); }
-        intptr_t sourceID() const { return m_source.provider()->asID(); }
+        const String& sourceURL() const { return m_source.provider()->url(); }
+        intptr_t sourceID() const { return m_source.providerID(); }
+
+        int startLine() const { return m_startLineNumber; }
+        int startStartOffset() const { return m_startStartOffset; }
+        int startLineStartOffset() const { return m_startLineStartOffset; }
 
         void setFeatures(CodeFeatures features) { m_features = features; }
         CodeFeatures features() { return m_features; }
@@ -1417,21 +1387,20 @@ namespace JSC {
         bool isStrictMode() const { return m_features & StrictModeFeature; }
         void setUsesArguments() { m_features |= ArgumentsFeature; }
         bool usesThis() const { return m_features & ThisFeature; }
-        bool needsActivationForMoreThanVariables() const { ASSERT(m_data); return m_features & (EvalFeature | WithFeature | CatchFeature); }
-        bool needsActivation() const { ASSERT(m_data); return (hasCapturedVariables()) || (m_features & (EvalFeature | WithFeature | CatchFeature)); }
-        bool hasCapturedVariables() const { return !!m_data->m_capturedVariables.size(); }
-        size_t capturedVariableCount() const { return m_data->m_capturedVariables.size(); }
-        bool captures(const Identifier& ident) { return m_data->m_capturedVariables.contains(ident.impl()); }
+        bool needsActivationForMoreThanVariables() const { return m_features & (EvalFeature | WithFeature | CatchFeature); }
+        bool needsActivation() const { return (hasCapturedVariables()) || (m_features & (EvalFeature | WithFeature | CatchFeature)); }
+        bool hasCapturedVariables() const { return !!m_capturedVariables.size(); }
+        size_t capturedVariableCount() const { return m_capturedVariables.size(); }
+        bool captures(const Identifier& ident) { return m_capturedVariables.contains(ident.impl()); }
 
-        VarStack& varStack() { ASSERT(m_data); return m_data->m_varStack; }
-        FunctionStack& functionStack() { ASSERT(m_data); return m_data->m_functionStack; }
+        VarStack& varStack() { return m_varStack; }
+        FunctionStack& functionStack() { return m_functionStack; }
 
         int neededConstants()
         {
-            ASSERT(m_data);
             // We may need 2 more constants than the count given by the parser,
             // because of the various uses of jsUndefined() and jsNull().
-            return m_data->m_numConstants + 2;
+            return m_numConstants + 2;
         }
 
         StatementNode* singleStatement() const;
@@ -1440,77 +1409,115 @@ namespace JSC {
 
     protected:
         void setSource(const SourceCode& source) { m_source = source; }
+        ParserArena m_arena;
+
+        int m_startLineNumber;
+        unsigned m_startStartOffset;
+        unsigned m_startLineStartOffset;
 
     private:
-        OwnPtr<ScopeNodeData> m_data;
         CodeFeatures m_features;
         SourceCode m_source;
+        VarStack m_varStack;
+        FunctionStack m_functionStack;
+        int m_numConstants;
+        SourceElements* m_statements;
+        IdentifierSet m_capturedVariables;
     };
 
     class ProgramNode : public ScopeNode {
     public:
         static const bool isFunctionNode = false;
-        static PassRefPtr<ProgramNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+        static PassRefPtr<ProgramNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+
+        unsigned startColumn() { return m_startColumn; }
 
         static const bool scopeIsFunction = false;
 
     private:
-        ProgramNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+        ProgramNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        unsigned m_startColumn;
     };
 
     class EvalNode : public ScopeNode {
     public:
         static const bool isFunctionNode = false;
-        static PassRefPtr<EvalNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+        static PassRefPtr<EvalNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+
+        unsigned startColumn() { return 1; }
 
         static const bool scopeIsFunction = false;
 
     private:
-        EvalNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+        EvalNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
     };
 
-    class FunctionParameters : public Vector<Identifier>, public RefCounted<FunctionParameters> {
+    class FunctionParameters : public RefCounted<FunctionParameters> {
         WTF_MAKE_FAST_ALLOCATED;
     public:
-        static PassRefPtr<FunctionParameters> create(ParameterNode* firstParameter) { return adoptRef(new FunctionParameters(firstParameter)); }
+        static PassRefPtr<FunctionParameters> create(ParameterNode*);
+        ~FunctionParameters();
+
+        unsigned size() const { return m_size; }
+        const Identifier& at(unsigned index) const { ASSERT(index < m_size); return identifiers()[index]; }
 
     private:
-        FunctionParameters(ParameterNode*);
+        FunctionParameters(ParameterNode*, unsigned size);
+
+        Identifier* identifiers() { return reinterpret_cast<Identifier*>(&m_storage); }
+        const Identifier* identifiers() const { return reinterpret_cast<const Identifier*>(&m_storage); }
+
+        unsigned m_size;
+        void* m_storage;
     };
 
     class FunctionBodyNode : public ScopeNode {
     public:
         static const bool isFunctionNode = true;
-        static FunctionBodyNode* create(JSGlobalData*, bool isStrictMode);
-        static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+        static FunctionBodyNode* create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, bool isStrictMode);
+        static PassRefPtr<FunctionBodyNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
 
         FunctionParameters* parameters() const { return m_parameters.get(); }
         size_t parameterCount() const { return m_parameters->size(); }
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
-        void finishParsing(const SourceCode&, ParameterNode*, const Identifier&);
-        void finishParsing(PassRefPtr<FunctionParameters>, const Identifier&);
+        void finishParsing(const SourceCode&, ParameterNode*, const Identifier&, FunctionNameIsInScopeToggle);
+        void finishParsing(PassRefPtr<FunctionParameters>, const Identifier&, FunctionNameIsInScopeToggle);
         
         const Identifier& ident() { return m_ident; }
+        void setInferredName(const Identifier& inferredName) { ASSERT(!inferredName.isNull()); m_inferredName = inferredName; }
+        const Identifier& inferredName() { return m_inferredName.isEmpty() ? m_ident : m_inferredName; }
+
+        bool functionNameIsInScope() { return m_functionNameIsInScopeToggle == FunctionNameIsInScope; }
+        FunctionNameIsInScopeToggle functionNameIsInScopeToggle() { return m_functionNameIsInScopeToggle; }
+
+        void setFunctionStart(int functionStart) { m_functionStart = functionStart; }
+        int functionStart() const { return m_functionStart; }
+        unsigned startColumn() const { return m_startColumn; }
 
         static const bool scopeIsFunction = true;
 
     private:
-        FunctionBodyNode(JSGlobalData*, bool inStrictContext);
-        FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+        FunctionBodyNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, bool inStrictContext);
+        FunctionBodyNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
 
         Identifier m_ident;
+        Identifier m_inferredName;
+        FunctionNameIsInScopeToggle m_functionNameIsInScopeToggle;
         RefPtr<FunctionParameters> m_parameters;
+        int m_functionStart;
+        unsigned m_startColumn;
     };
 
     class FuncExprNode : public ExpressionNode {
     public:
-        FuncExprNode(JSGlobalData*, const Identifier&, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter = 0);
+        FuncExprNode(const JSTokenLocation&, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
 
         FunctionBodyNode* body() { return m_body; }
 
@@ -1524,19 +1531,19 @@ namespace JSC {
 
     class FuncDeclNode : public StatementNode {
     public:
-        FuncDeclNode(JSGlobalData*, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
+        FuncDeclNode(const JSTokenLocation&, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
 
         FunctionBodyNode* body() { return m_body; }
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
         FunctionBodyNode* m_body;
     };
 
     class CaseClauseNode : public ParserArenaFreeable {
     public:
-        CaseClauseNode(JSGlobalData*, ExpressionNode*, SourceElements* = 0);
+        CaseClauseNode(ExpressionNode*, SourceElements* = 0);
 
         ExpressionNode* expr() const { return m_expr; }
 
@@ -1549,8 +1556,8 @@ namespace JSC {
 
     class ClauseListNode : public ParserArenaFreeable {
     public:
-        ClauseListNode(JSGlobalData*, CaseClauseNode*);
-        ClauseListNode(JSGlobalData*, ClauseListNode*, CaseClauseNode*);
+        ClauseListNode(CaseClauseNode*);
+        ClauseListNode(ClauseListNode*, CaseClauseNode*);
 
         CaseClauseNode* getClause() const { return m_clause; }
         ClauseListNode* getNext() const { return m_next; }
@@ -1562,12 +1569,13 @@ namespace JSC {
 
     class CaseBlockNode : public ParserArenaFreeable {
     public:
-        CaseBlockNode(JSGlobalData*, ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2);
+        CaseBlockNode(ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2);
 
-        RegisterID* emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* destination);
+        void emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* destination);
 
     private:
-        SwitchInfo::SwitchType tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num);
+        SwitchInfo::SwitchType tryTableSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num);
+        static const size_t s_tableSwitchMinimum = 10;
         ClauseListNode* m_list1;
         CaseClauseNode* m_defaultClause;
         ClauseListNode* m_list2;
@@ -1575,10 +1583,10 @@ namespace JSC {
 
     class SwitchNode : public StatementNode {
     public:
-        SwitchNode(JSGlobalData*, ExpressionNode*, CaseBlockNode*);
+        SwitchNode(const JSTokenLocation&, ExpressionNode*, CaseBlockNode*);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
         ExpressionNode* m_expr;
         CaseBlockNode* m_block;