finally blocks should not set the exception stack trace when re-throwing the exception.
[WebKit-https.git] / Source / JavaScriptCore / parser / Nodes.h
index e04de7a..92f1a21 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, 2013 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013, 2015 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>
@@ -76,11 +76,11 @@ namespace JSC {
     };
     inline FallThroughMode invert(FallThroughMode fallThroughMode) { return static_cast<FallThroughMode>(!fallThroughMode); }
 
-    typedef HashSet<RefPtr<StringImpl>, IdentifierRepHash> IdentifierSet;
+    typedef HashSet<RefPtr<UniquedStringImpl>, IdentifierRepHash> IdentifierSet;
 
     namespace DeclarationStacks {
         enum VarAttrs { IsConstant = 1, HasInitializer = 2 };
-        typedef Vector<std::pair<const Identifier*, unsigned> > VarStack;
+        typedef Vector<std::pair<Identifier, unsigned>> VarStack;
         typedef Vector<FunctionBodyNode*> FunctionStack;
     }
 
@@ -94,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, VM*);
+        void* operator new(size_t, ParserArena&);
     };
 
     class ParserArenaDeletable {
@@ -103,23 +103,20 @@ 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, VM*);
+        void* operator new(size_t, ParserArena&);
     };
 
-    template <typename T>
-    struct ParserArenaData : ParserArenaDeletable {
-        T data;
-    };
-
-    class ParserArenaRefCounted : public RefCounted<ParserArenaRefCounted> {
+    class ParserArenaRoot {
+        WTF_MAKE_FAST_ALLOCATED;
     protected:
-        ParserArenaRefCounted(VM*);
+        ParserArenaRoot(ParserArena&);
 
     public:
-        virtual ~ParserArenaRefCounted()
-        {
-            ASSERT(deletionHasBegun());
-        }
+        ParserArena& parserArena() { return m_arena; }
+        virtual ~ParserArenaRoot() { }
+
+    protected:
+        ParserArena m_arena;
     };
 
     class Node : public ParserArenaFreeable {
@@ -129,13 +126,17 @@ namespace JSC {
     public:
         virtual ~Node() { }
 
-        int lineNo() const { return m_lineNumber; }
-
-        int charPosition() const { return m_charPosition; }
+        int firstLine() const { return m_position.line; }
+        int startOffset() const { return m_position.offset; }
+        int endOffset() const { return m_endOffset; }
+        int lineStartOffset() const { return m_position.lineStartOffset; }
+        const JSTextPosition& position() const { return m_position; }
+        void setEndOffset(int offset) { m_endOffset = offset; }
+        void setStartOffset(int offset) { m_position.offset = offset; }
 
     protected:
-        int m_lineNumber;
-        int m_charPosition;
+        JSTextPosition m_position;
+        int m_endOffset;
     };
 
     class ExpressionNode : public Node {
@@ -151,15 +152,19 @@ namespace JSC {
         virtual bool isPure(BytecodeGenerator&) const { return false; }        
         virtual bool isConstant() const { return false; }
         virtual bool isLocation() const { return false; }
+        virtual bool isAssignmentLocation() const { return isLocation(); }
         virtual bool isResolveNode() const { return false; }
         virtual bool isBracketAccessorNode() const { return false; }
         virtual bool isDotAccessorNode() const { return false; }
+        virtual bool isDeconstructionNode() const { return false; }
         virtual bool isFuncExprNode() const { return false; }
         virtual bool isCommaNode() const { return false; }
         virtual bool isSimpleArray() const { return false; }
         virtual bool isAdd() const { return false; }
         virtual bool isSubtract() const { return false; }
         virtual bool isBoolean() const { return false; }
+        virtual bool isSpreadExpression() const { return false; }
+        virtual bool isSuperNode() const { return false; }
 
         virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label*, Label*, FallThroughMode);
 
@@ -178,9 +183,11 @@ namespace JSC {
     public:
         virtual void emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0;
 
-        void setLoc(int firstLine, int lastLine, int charPosition);
-        int firstLine() const { return lineNo(); }
-        int lastLine() const { return m_lastLine; }
+        void setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset);
+        unsigned lastLine() const { return m_lastLine; }
+
+        StatementNode* next() { return m_next; }
+        void setNext(StatementNode* next) { m_next = next; }
 
         virtual bool isEmptyStatement() const { return false; }
         virtual bool isReturnNode() const { return false; }
@@ -188,20 +195,22 @@ namespace JSC {
         virtual bool isBreak() const { return false; }
         virtual bool isContinue() const { return false; }
         virtual bool isBlock() const { return false; }
+        virtual bool isFuncDeclNode() const { return false; }
 
-    private:
+    protected:
+        StatementNode* m_next;
         int m_lastLine;
     };
 
     class ConstantNode : public ExpressionNode {
     public:
         ConstantNode(const JSTokenLocation&, ResultType);
-        virtual bool isPure(BytecodeGenerator&) const { return true; }
-        virtual bool isConstant() const { return true; }
+        virtual bool isPure(BytecodeGenerator&) const override { return true; }
+        virtual bool isConstant() const  override { return true; }
         virtual JSValue jsValue(BytecodeGenerator&) const = 0;
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-        void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+        virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode) override;
     };
 
     class NullNode : public ConstantNode {
@@ -209,8 +218,8 @@ namespace JSC {
         NullNode(const JSTokenLocation&);
 
     private:
-        virtual bool isNull() const { return true; }
-        virtual JSValue jsValue(BytecodeGenerator&) const { return jsNull(); }
+        virtual bool isNull() const override { return true; }
+        virtual JSValue jsValue(BytecodeGenerator&) const override { return jsNull(); }
     };
 
     class BooleanNode : public ConstantNode {
@@ -219,8 +228,8 @@ namespace JSC {
         bool value() { return m_value; }
 
     private:
-        virtual bool isBoolean() const { return true; }
-        virtual JSValue jsValue(BytecodeGenerator&) const { return jsBoolean(m_value); }
+        virtual bool isBoolean() const override { return true; }
+        virtual JSValue jsValue(BytecodeGenerator&) const override { return jsBoolean(m_value); }
 
         bool m_value;
     };
@@ -228,62 +237,84 @@ namespace JSC {
     class NumberNode : public ConstantNode {
     public:
         NumberNode(const JSTokenLocation&, double value);
-        double value() { return m_value; }
-        void setValue(double value) { m_value = value; }
+        double value() const { return m_value; }
+        virtual bool isIntegerNode() const = 0;
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override final;
 
     private:
-        virtual bool isNumber() const { return true; }
-        virtual JSValue jsValue(BytecodeGenerator&) const { return jsNumber(m_value); }
+        virtual bool isNumber() const override final { return true; }
+        virtual JSValue jsValue(BytecodeGenerator&) const override { return jsNumber(m_value); }
 
         double m_value;
     };
 
+    class DoubleNode : public NumberNode {
+    public:
+        DoubleNode(const JSTokenLocation&, double value);
+
+    private:
+        virtual bool isIntegerNode() const override { return false; }
+    };
+
+    // An integer node represent a number represented as an integer (e.g. 42 instead of 42., 42.0, 42e0)
+    class IntegerNode : public DoubleNode {
+    public:
+        IntegerNode(const JSTokenLocation&, double value);
+        virtual bool isIntegerNode() const override final { return true; }
+    };
+
     class StringNode : public ConstantNode {
     public:
         StringNode(const JSTokenLocation&, const Identifier&);
         const Identifier& value() { return m_value; }
 
     private:
-        virtual bool isString() const { return true; }
-        virtual JSValue jsValue(BytecodeGenerator&) const;
+        virtual bool isString() const override { return true; }
+        virtual JSValue jsValue(BytecodeGenerator&) const override;
 
         const Identifier& m_value;
     };
-    
+
     class ThrowableExpressionData {
     public:
         ThrowableExpressionData()
-            : m_divot(static_cast<uint32_t>(-1))
-            , m_startOffset(static_cast<uint16_t>(-1))
-            , m_endOffset(static_cast<uint16_t>(-1))
+            : m_divot(-1, -1, -1)
+            , m_divotStart(-1, -1, -1)
+            , m_divotEnd(-1, -1, -1)
         {
         }
         
-        ThrowableExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
+        ThrowableExpressionData(const JSTextPosition& divot, const JSTextPosition& start, const JSTextPosition& end)
             : m_divot(divot)
-            , m_startOffset(startOffset)
-            , m_endOffset(endOffset)
+            , m_divotStart(start)
+            , m_divotEnd(end)
         {
+            ASSERT(m_divot.offset >= m_divot.lineStartOffset);
+            ASSERT(m_divotStart.offset >= m_divotStart.lineStartOffset);
+            ASSERT(m_divotEnd.offset >= m_divotEnd.lineStartOffset);
         }
-        
-        void setExceptionSourceCode(unsigned divot, unsigned startOffset, unsigned endOffset)
+
+        void setExceptionSourceCode(const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
         {
+            ASSERT(divot.offset >= divot.lineStartOffset);
+            ASSERT(divotStart.offset >= divotStart.lineStartOffset);
+            ASSERT(divotEnd.offset >= divotEnd.lineStartOffset);
             m_divot = divot;
-            m_startOffset = startOffset;
-            m_endOffset = endOffset;
+            m_divotStart = divotStart;
+            m_divotEnd = divotEnd;
         }
 
-        uint32_t divot() const { return m_divot; }
-        uint16_t startOffset() const { return m_startOffset; }
-        uint16_t endOffset() const { return m_endOffset; }
+        const JSTextPosition& divot() const { return m_divot; }
+        const JSTextPosition& divotStart() const { return m_divotStart; }
+        const JSTextPosition& divotEnd() const { return m_divotEnd; }
 
     protected:
         RegisterID* emitThrowReferenceError(BytecodeGenerator&, const String& message);
 
     private:
-        uint32_t m_divot;
-        uint16_t m_startOffset;
-        uint16_t m_endOffset;
+        JSTextPosition m_divot;
+        JSTextPosition m_divotStart;
+        JSTextPosition m_divotEnd;
     };
 
     class ThrowableSubExpressionData : public ThrowableExpressionData {
@@ -291,28 +322,54 @@ 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(const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
+            : ThrowableExpressionData(divot, divotStart, divotEnd)
             , m_subexpressionDivotOffset(0)
             , m_subexpressionEndOffset(0)
+            , m_subexpressionLineOffset(0)
+            , m_subexpressionLineStartOffset(0)
         {
         }
 
-        void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset)
+        void setSubexpressionInfo(const JSTextPosition& subexpressionDivot, int subexpressionOffset)
         {
-            ASSERT(subexpressionDivot <= divot());
-            if ((divot() - subexpressionDivot) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot
+            ASSERT(subexpressionDivot.offset <= divot().offset);
+            // Overflow means we can't do this safely, so just point at the primary divot,
+            // divotLine, or divotLineStart.
+            if ((divot() - subexpressionDivot.offset) & ~0xFFFF)
+                return;
+            if ((divot().line - subexpressionDivot.line) & ~0xFFFF)
                 return;
-            m_subexpressionDivotOffset = divot() - subexpressionDivot;
-            m_subexpressionEndOffset = subexpressionOffset;
+            if ((divot().lineStartOffset - subexpressionDivot.lineStartOffset) & ~0xFFFF)
+                return;
+            if ((divotEnd() - subexpressionOffset) & ~0xFFFF)
+                return;
+            m_subexpressionDivotOffset = divot() - subexpressionDivot.offset;
+            m_subexpressionEndOffset = divotEnd() - subexpressionOffset;
+            m_subexpressionLineOffset = divot().line - subexpressionDivot.line;
+            m_subexpressionLineStartOffset = divot().lineStartOffset - subexpressionDivot.lineStartOffset;
+        }
+
+        JSTextPosition subexpressionDivot()
+        {
+            int newLine = divot().line - m_subexpressionLineOffset;
+            int newOffset = divot().offset - m_subexpressionDivotOffset;
+            int newLineStartOffset = divot().lineStartOffset - m_subexpressionLineStartOffset;
+            return JSTextPosition(newLine, newOffset, newLineStartOffset);
         }
+        JSTextPosition subexpressionStart() { return divotStart(); }
+        JSTextPosition subexpressionEnd() { return divotEnd() - static_cast<int>(m_subexpressionEndOffset); }
 
     protected:
         uint16_t m_subexpressionDivotOffset;
         uint16_t m_subexpressionEndOffset;
+        uint16_t m_subexpressionLineOffset;
+        uint16_t m_subexpressionLineStartOffset;
     };
     
     class ThrowablePrefixedSubExpressionData : public ThrowableExpressionData {
@@ -320,36 +377,132 @@ 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(const JSTextPosition& divot, const JSTextPosition& start, const JSTextPosition& end)
+            : ThrowableExpressionData(divot, start, end)
             , m_subexpressionDivotOffset(0)
             , m_subexpressionStartOffset(0)
+            , m_subexpressionLineOffset(0)
+            , m_subexpressionLineStartOffset(0)
         {
         }
 
-        void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset)
+        void setSubexpressionInfo(const JSTextPosition& subexpressionDivot, int subexpressionOffset)
         {
-            ASSERT(subexpressionDivot >= divot());
-            if ((subexpressionDivot - divot()) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot
+            ASSERT(subexpressionDivot.offset >= divot().offset);
+            // Overflow means we can't do this safely, so just point at the primary divot,
+            // divotLine, or divotLineStart.
+            if ((subexpressionDivot.offset - divot()) & ~0xFFFF) 
+                return;
+            if ((subexpressionDivot.line - divot().line) & ~0xFFFF)
+                return;
+            if ((subexpressionDivot.lineStartOffset - divot().lineStartOffset) & ~0xFFFF)
                 return;
-            m_subexpressionDivotOffset = subexpressionDivot - divot();
-            m_subexpressionStartOffset = subexpressionOffset;
+            if ((subexpressionOffset - divotStart()) & ~0xFFFF) 
+                return;
+            m_subexpressionDivotOffset = subexpressionDivot.offset - divot();
+            m_subexpressionStartOffset = subexpressionOffset - divotStart();
+            m_subexpressionLineOffset = subexpressionDivot.line - divot().line;
+            m_subexpressionLineStartOffset = subexpressionDivot.lineStartOffset - divot().lineStartOffset;
+        }
+
+        JSTextPosition subexpressionDivot()
+        {
+            int newLine = divot().line + m_subexpressionLineOffset;
+            int newOffset = divot().offset + m_subexpressionDivotOffset;
+            int newLineStartOffset = divot().lineStartOffset + m_subexpressionLineStartOffset;
+            return JSTextPosition(newLine, newOffset, newLineStartOffset);
         }
+        JSTextPosition subexpressionStart() { return divotStart() + static_cast<int>(m_subexpressionStartOffset); }
+        JSTextPosition subexpressionEnd() { return divotEnd(); }
 
     protected:
         uint16_t m_subexpressionDivotOffset;
         uint16_t m_subexpressionStartOffset;
+        uint16_t m_subexpressionLineOffset;
+        uint16_t m_subexpressionLineStartOffset;
+    };
+
+#if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
+    class TemplateExpressionListNode : public ParserArenaFreeable {
+    public:
+        TemplateExpressionListNode(ExpressionNode*);
+        TemplateExpressionListNode(TemplateExpressionListNode*, ExpressionNode*);
+
+        ExpressionNode* value() { return m_node; }
+        TemplateExpressionListNode* next() { return m_next; }
+
+    private:
+        TemplateExpressionListNode* m_next { nullptr };
+        ExpressionNode* m_node { nullptr };
+    };
+
+    class TemplateStringNode : public ExpressionNode {
+    public:
+        TemplateStringNode(const JSTokenLocation&, const Identifier& cooked, const Identifier& raw);
+
+        const Identifier& cooked() { return m_cooked; }
+        const Identifier& raw() { return m_raw; }
+
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+        const Identifier& m_cooked;
+        const Identifier& m_raw;
+    };
+
+    class TemplateStringListNode : public ParserArenaFreeable {
+    public:
+        TemplateStringListNode(TemplateStringNode*);
+        TemplateStringListNode(TemplateStringListNode*, TemplateStringNode*);
+
+        TemplateStringNode* value() { return m_node; }
+        TemplateStringListNode* next() { return m_next; }
+
+    private:
+        TemplateStringListNode* m_next { nullptr };
+        TemplateStringNode* m_node { nullptr };
     };
 
+    class TemplateLiteralNode : public ExpressionNode {
+    public:
+        TemplateLiteralNode(const JSTokenLocation&, TemplateStringListNode*);
+        TemplateLiteralNode(const JSTokenLocation&, TemplateStringListNode*, TemplateExpressionListNode*);
+
+        TemplateStringListNode* templateStrings() const { return m_templateStrings; }
+        TemplateExpressionListNode* templateExpressions() const { return m_templateExpressions; }
+
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+        TemplateStringListNode* m_templateStrings;
+        TemplateExpressionListNode* m_templateExpressions;
+    };
+
+    class TaggedTemplateNode : public ExpressionNode, public ThrowableExpressionData {
+    public:
+        TaggedTemplateNode(const JSTokenLocation&, ExpressionNode*, TemplateLiteralNode*);
+
+        TemplateLiteralNode* templateLiteral() const { return m_templateLiteral; }
+
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+        ExpressionNode* m_tag;
+        TemplateLiteralNode* m_templateLiteral;
+    };
+#endif
+
     class RegExpNode : public ExpressionNode, public ThrowableExpressionData {
     public:
         RegExpNode(const JSTokenLocation&, const Identifier& pattern, const Identifier& flags);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         const Identifier& m_pattern;
         const Identifier& m_flags;
@@ -357,27 +510,38 @@ namespace JSC {
 
     class ThisNode : public ExpressionNode {
     public:
-        ThisNode(const JSTokenLocation&);
+        ThisNode(const JSTokenLocation&, ThisTDZMode);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+        bool m_shouldAlwaysEmitTDZCheck;
+    };
+
+    class SuperNode final : public ExpressionNode {
+    public:
+        SuperNode(const JSTokenLocation&);
+
+    private:
+        virtual bool isSuperNode() const override { return true; }
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
     };
 
     class ResolveNode : public ExpressionNode {
     public:
-        ResolveNode(const JSTokenLocation&, const Identifier&, int startOffset);
+        ResolveNode(const JSTokenLocation&, const Identifier&, const JSTextPosition& start);
 
         const Identifier& identifier() const { return m_ident; }
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
-        virtual bool isPure(BytecodeGenerator&) const ;
-        virtual bool isLocation() const { return true; }
-        virtual bool isResolveNode() const { return true; }
+        virtual bool isPure(BytecodeGenerator&) const override;
+        virtual bool isLocation() const override { return true; }
+        virtual bool isResolveNode() const override { return true; }
 
         const Identifier& m_ident;
-        int32_t m_startOffset;
+        JSTextPosition m_start;
     };
 
     class ElementNode : public ParserArenaFreeable {
@@ -401,12 +565,13 @@ namespace JSC {
         ArrayNode(const JSTokenLocation&, ElementNode*);
         ArrayNode(const JSTokenLocation&, int elision, ElementNode*);
 
-        ArgumentListNode* toArgumentList(VM*, int, int) const;
+        ArgumentListNode* toArgumentList(ParserArena&, int, int) const;
 
+        ElementNode* elements() const { ASSERT(isSimpleArray()); return m_element; }
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
-        virtual bool isSimpleArray() const ;
+        virtual bool isSimpleArray() const override;
 
         ElementNode* m_element;
         int m_elision;
@@ -415,19 +580,27 @@ namespace JSC {
 
     class PropertyNode : public ParserArenaFreeable {
     public:
-        enum Type { Constant = 1, Getter = 2, Setter = 4 };
+        enum Type { Constant = 1, Getter = 2, Setter = 4, Computed = 8, Shorthand = 16 };
+        enum PutType { Unknown, KnownDirect };
+
+        PropertyNode(const Identifier&, ExpressionNode*, Type, PutType, SuperBinding);
+        PropertyNode(ExpressionNode* propertyName, ExpressionNode*, Type, PutType);
 
-        PropertyNode(VM*, const Identifier&, ExpressionNode*, Type);
-        PropertyNode(VM*, double, ExpressionNode*, Type);
+        ExpressionNode* expressionName() const { return m_expression; }
+        const Identifier* name() const { return m_name; }
 
-        const Identifier& name() const { return m_name; }
-        Type type() const { return m_type; }
+        Type type() const { return static_cast<Type>(m_type); }
+        bool needsSuperBinding() const { return m_needsSuperBinding; }
+        PutType putType() const { return static_cast<PutType>(m_putType); }
 
     private:
         friend class PropertyListNode;
-        const Identifier& m_name;
+        const Identifier* m_name;
+        ExpressionNode* m_expression;
         ExpressionNode* m_assign;
-        Type m_type;
+        unsigned m_type : 5;
+        unsigned m_needsSuperBinding : 1;
+        unsigned m_putType : 1;
     };
 
     class PropertyListNode : public ExpressionNode {
@@ -435,9 +608,10 @@ namespace JSC {
         PropertyListNode(const JSTokenLocation&, PropertyNode*);
         PropertyListNode(const JSTokenLocation&, PropertyNode*, PropertyListNode*);
 
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-
     private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+        void emitPutConstantProperty(BytecodeGenerator&, RegisterID*, PropertyNode&);
+
         PropertyNode* m_node;
         PropertyListNode* m_next;
     };
@@ -448,7 +622,7 @@ namespace JSC {
         ObjectLiteralNode(const JSTokenLocation&, PropertyListNode*);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         PropertyListNode* m_list;
     };
@@ -463,10 +637,10 @@ namespace JSC {
         bool subscriptHasAssignments() const { return m_subscriptHasAssignments; }
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
-        virtual bool isLocation() const { return true; }
-        virtual bool isBracketAccessorNode() const { return true; }
+        virtual bool isLocation() const override { return true; }
+        virtual bool isBracketAccessorNode() const override { return true; }
 
         ExpressionNode* m_base;
         ExpressionNode* m_subscript;
@@ -481,15 +655,28 @@ namespace JSC {
         const Identifier& identifier() const { return m_ident; }
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
-        virtual bool isLocation() const { return true; }
-        virtual bool isDotAccessorNode() const { return true; }
+        virtual bool isLocation() const override { return true; }
+        virtual bool isDotAccessorNode() const override { return true; }
 
         ExpressionNode* m_base;
         const Identifier& m_ident;
     };
 
+    class SpreadExpressionNode : public ExpressionNode, public ThrowableExpressionData {
+    public:
+        SpreadExpressionNode(const JSTokenLocation&, ExpressionNode*);
+        
+        ExpressionNode* expression() const { return m_expression; }
+        
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+        
+        virtual bool isSpreadExpression() const override { return true; }
+        ExpressionNode* m_expression;
+    };
+
     class ArgumentListNode : public ExpressionNode {
     public:
         ArgumentListNode(const JSTokenLocation&, ExpressionNode*);
@@ -499,7 +686,7 @@ namespace JSC {
         ExpressionNode* m_expr;
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
     };
 
     class ArgumentsNode : public ParserArenaFreeable {
@@ -516,7 +703,7 @@ namespace JSC {
         NewExprNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         ExpressionNode* m_expr;
         ArgumentsNode* m_args;
@@ -524,20 +711,20 @@ namespace JSC {
 
     class EvalFunctionCallNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        EvalFunctionCallNode(const JSTokenLocation&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+        EvalFunctionCallNode(const JSTokenLocation&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         ArgumentsNode* m_args;
     };
 
     class FunctionCallValueNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        FunctionCallValueNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+        FunctionCallValueNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         ExpressionNode* m_expr;
         ArgumentsNode* m_args;
@@ -545,10 +732,10 @@ namespace JSC {
 
     class FunctionCallResolveNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        FunctionCallResolveNode(const JSTokenLocation&, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+        FunctionCallResolveNode(const JSTokenLocation&, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         const Identifier& m_ident;
         ArgumentsNode* m_args;
@@ -556,22 +743,23 @@ namespace JSC {
     
     class FunctionCallBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
     public:
-        FunctionCallBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+        FunctionCallBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         ExpressionNode* m_base;
         ExpressionNode* m_subscript;
         ArgumentsNode* m_args;
+        bool m_subscriptHasAssignments;
     };
 
     class FunctionCallDotNode : public ExpressionNode, public ThrowableSubExpressionData {
     public:
-        FunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+        FunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
     protected:
         ExpressionNode* m_base;
@@ -579,38 +767,58 @@ namespace JSC {
         ArgumentsNode* m_args;
     };
 
+    class BytecodeIntrinsicNode : public ExpressionNode, public ThrowableExpressionData {
+    public:
+        typedef RegisterID* (BytecodeIntrinsicNode::* EmitterType)(BytecodeGenerator&, RegisterID*);
+
+        BytecodeIntrinsicNode(const JSTokenLocation&, EmitterType, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
+
+        const Identifier& identifier() const { return m_ident; }
+
+#define JSC_DECLARE_BYTECODE_INTRINSIC_FUNCTIONS(name) RegisterID* emit_intrinsic_##name(BytecodeGenerator&, RegisterID*);
+        JSC_COMMON_BYTECODE_INTRINSICS_EACH_NAME(JSC_DECLARE_BYTECODE_INTRINSIC_FUNCTIONS)
+#undef JSC_DECLARE_BYTECODE_INTRINSIC_FUNCTIONS
+
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+        EmitterType m_emitter;
+        const Identifier& m_ident;
+        ArgumentsNode* m_args;
+    };
+
     class CallFunctionCallDotNode : public FunctionCallDotNode {
     public:
-        CallFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+        CallFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
     };
     
     class ApplyFunctionCallDotNode : public FunctionCallDotNode {
     public:
-        ApplyFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+        ApplyFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
     };
 
     class DeleteResolveNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        DeleteResolveNode(const JSTokenLocation&, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DeleteResolveNode(const JSTokenLocation&, const Identifier&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         const Identifier& m_ident;
     };
 
     class DeleteBracketNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        DeleteBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DeleteBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         ExpressionNode* m_base;
         ExpressionNode* m_subscript;
@@ -618,10 +826,10 @@ namespace JSC {
 
     class DeleteDotNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        DeleteDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DeleteDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         ExpressionNode* m_base;
         const Identifier& m_ident;
@@ -632,7 +840,7 @@ namespace JSC {
         DeleteValueNode(const JSTokenLocation&, ExpressionNode*);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         ExpressionNode* m_expr;
     };
@@ -642,7 +850,7 @@ namespace JSC {
         VoidNode(const JSTokenLocation&, ExpressionNode*);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         ExpressionNode* m_expr;
     };
@@ -654,7 +862,7 @@ namespace JSC {
         const Identifier& identifier() const { return m_ident; }
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         const Identifier& m_ident;
     };
@@ -664,17 +872,17 @@ namespace JSC {
         TypeOfValueNode(const JSTokenLocation&, ExpressionNode*);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         ExpressionNode* m_expr;
     };
 
     class PrefixNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
     public:
-        PrefixNode(const JSTokenLocation&, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
+        PrefixNode(const JSTokenLocation&, ExpressionNode*, Operator, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
 
     protected:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
         virtual RegisterID* emitResolve(BytecodeGenerator&, RegisterID* = 0);
         virtual RegisterID* emitBracket(BytecodeGenerator&, RegisterID* = 0);
         virtual RegisterID* emitDot(BytecodeGenerator&, RegisterID* = 0);
@@ -685,13 +893,13 @@ namespace JSC {
 
     class PostfixNode : public PrefixNode {
     public:
-        PostfixNode(const JSTokenLocation&, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
+        PostfixNode(const JSTokenLocation&, ExpressionNode*, Operator, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-        virtual RegisterID* emitResolve(BytecodeGenerator&, RegisterID* = 0);
-        virtual RegisterID* emitBracket(BytecodeGenerator&, RegisterID* = 0);
-        virtual RegisterID* emitDot(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+        virtual RegisterID* emitResolve(BytecodeGenerator&, RegisterID* = 0) override;
+        virtual RegisterID* emitBracket(BytecodeGenerator&, RegisterID* = 0) override;
+        virtual RegisterID* emitDot(BytecodeGenerator&, RegisterID* = 0) override;
     };
 
     class UnaryOpNode : public ExpressionNode {
@@ -703,7 +911,7 @@ namespace JSC {
         const ExpressionNode* expr() const { return m_expr; }
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         OpcodeID opcodeID() const { return m_opcodeID; }
 
@@ -716,7 +924,7 @@ namespace JSC {
         UnaryPlusNode(const JSTokenLocation&, ExpressionNode*);
 
     private:
-        virtual ExpressionNode* stripUnaryPlus() { return expr(); }
+        virtual ExpressionNode* stripUnaryPlus() override { return expr(); }
     };
 
     class NegateNode : public UnaryOpNode {
@@ -733,7 +941,7 @@ namespace JSC {
         const ExpressionNode* expr() const { return m_expr; }
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         ExpressionNode* m_expr;
     };
@@ -742,7 +950,7 @@ namespace JSC {
     public:
         LogicalNotNode(const JSTokenLocation&, ExpressionNode*);
     private:
-        void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode);
+        virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode) override;
     };
 
     class BinaryOpNode : public ExpressionNode {
@@ -751,14 +959,14 @@ namespace JSC {
         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);
+        virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode) override;
 
         ExpressionNode* lhs() { return m_expr1; };
         ExpressionNode* rhs() { return m_expr2; };
 
     private:
         void tryFoldToBranch(BytecodeGenerator&, TriState& branchCondition, ExpressionNode*& branchExpression);
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
     protected:
         OpcodeID opcodeID() const { return m_opcodeID; }
@@ -791,14 +999,14 @@ namespace JSC {
     public:
         AddNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
 
-        virtual bool isAdd() const { return true; }
+        virtual bool isAdd() const override { return true; }
     };
 
     class SubNode : public BinaryOpNode {
     public:
         SubNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
 
-        virtual bool isSubtract() const { return true; }
+        virtual bool isSubtract() const override { return true; }
     };
 
     class LeftShiftNode : public BinaryOpNode {
@@ -842,7 +1050,7 @@ namespace JSC {
         ThrowableBinaryOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
     };
     
     class InstanceOfNode : public ThrowableBinaryOpNode {
@@ -850,7 +1058,7 @@ namespace JSC {
         InstanceOfNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
     };
 
     class InNode : public ThrowableBinaryOpNode {
@@ -863,7 +1071,7 @@ namespace JSC {
         EqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
     };
 
     class NotEqualNode : public BinaryOpNode {
@@ -876,7 +1084,7 @@ namespace JSC {
         StrictEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
     };
 
     class NotStrictEqualNode : public BinaryOpNode {
@@ -905,8 +1113,8 @@ namespace JSC {
         LogicalOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
-        void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+        virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode) override;
 
         ExpressionNode* m_expr1;
         ExpressionNode* m_expr2;
@@ -919,7 +1127,7 @@ namespace JSC {
         ConditionalNode(const JSTokenLocation&, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         ExpressionNode* m_logical;
         ExpressionNode* m_expr1;
@@ -928,10 +1136,10 @@ namespace JSC {
 
     class ReadModifyResolveNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        ReadModifyResolveNode(const JSTokenLocation&, const Identifier&, Operator, ExpressionNode*  right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
+        ReadModifyResolveNode(const JSTokenLocation&, const Identifier&, Operator, ExpressionNode*  right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         const Identifier& m_ident;
         ExpressionNode* m_right;
@@ -944,7 +1152,7 @@ namespace JSC {
         AssignResolveNode(const JSTokenLocation&, const Identifier&, ExpressionNode* right);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         const Identifier& m_ident;
         ExpressionNode* m_right;
@@ -952,25 +1160,25 @@ namespace JSC {
 
     class ReadModifyBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
     public:
-        ReadModifyBracketNode(const JSTokenLocation&, 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, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         ExpressionNode* m_base;
         ExpressionNode* m_subscript;
         ExpressionNode* m_right;
-        Operator m_operator : 30;
+        unsigned m_operator : 30;
         bool m_subscriptHasAssignments : 1;
         bool m_rightHasAssignments : 1;
     };
 
     class AssignBracketNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        AssignBracketNode(const JSTokenLocation&, 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, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         ExpressionNode* m_base;
         ExpressionNode* m_subscript;
@@ -981,10 +1189,10 @@ namespace JSC {
 
     class AssignDotNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        AssignDotNode(const JSTokenLocation&, 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, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         ExpressionNode* m_base;
         const Identifier& m_ident;
@@ -994,41 +1202,39 @@ namespace JSC {
 
     class ReadModifyDotNode : public ExpressionNode, public ThrowableSubExpressionData {
     public:
-        ReadModifyDotNode(const JSTokenLocation&, 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, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         ExpressionNode* m_base;
         const Identifier& m_ident;
         ExpressionNode* m_right;
-        Operator m_operator : 31;
+        unsigned m_operator : 31;
         bool m_rightHasAssignments : 1;
     };
 
     class AssignErrorNode : public ExpressionNode, public ThrowableExpressionData {
     public:
-        AssignErrorNode(const JSTokenLocation&, unsigned divot, unsigned startOffset, unsigned endOffset);
+        AssignErrorNode(const JSTokenLocation&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
     };
     
-    typedef Vector<ExpressionNode*, 8> ExpressionVector;
-
-    class CommaNode : public ExpressionNode, public ParserArenaDeletable {
+    class CommaNode final : public ExpressionNode {
     public:
-        CommaNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2);
+        CommaNode(const JSTokenLocation&, ExpressionNode*);
 
-        using ParserArenaDeletable::operator new;
-
-        void append(ExpressionNode* expr) { m_expressions.append(expr); }
+        void setNext(CommaNode* next) { m_next = next; }
+        CommaNode* next() { return m_next; }
 
     private:
-        virtual bool isCommaNode() const { return true; }
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual bool isCommaNode() const override { return true; }
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
-        ExpressionVector m_expressions;
+        ExpressionNode* m_expr;
+        CommaNode* m_next;
     };
     
     class ConstDeclNode : public ExpressionNode {
@@ -1039,7 +1245,7 @@ namespace JSC {
         const Identifier& ident() { return m_ident; }
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
         virtual RegisterID* emitCodeSingle(BytecodeGenerator&);
 
         const Identifier& m_ident;
@@ -1056,12 +1262,12 @@ namespace JSC {
         ConstStatementNode(const JSTokenLocation&, ConstDeclNode* next);
 
     private:
-        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         ConstDeclNode* m_next;
     };
 
-    class SourceElements : public ParserArenaDeletable {
+    class SourceElements final : public ParserArenaFreeable {
     public:
         SourceElements();
 
@@ -1073,7 +1279,8 @@ namespace JSC {
         void emitBytecode(BytecodeGenerator&, RegisterID* destination);
 
     private:
-        Vector<StatementNode*> m_statements;
+        StatementNode* m_head;
+        StatementNode* m_tail;
     };
 
     class BlockNode : public StatementNode {
@@ -1084,9 +1291,9 @@ namespace JSC {
         StatementNode* lastStatement() const;
 
     private:
-        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
-        virtual bool isBlock() const { return true; }
+        virtual bool isBlock() const override { return true; }
 
         SourceElements* m_statements;
     };
@@ -1096,9 +1303,9 @@ namespace JSC {
         EmptyStatementNode(const JSTokenLocation&);
 
     private:
-        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
-        virtual bool isEmptyStatement() const { return true; }
+        virtual bool isEmptyStatement() const override { return true; }
     };
     
     class DebuggerStatementNode : public StatementNode {
@@ -1106,7 +1313,7 @@ namespace JSC {
         DebuggerStatementNode(const JSTokenLocation&);
         
     private:
-        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
     };
 
     class ExprStatementNode : public StatementNode {
@@ -1116,9 +1323,9 @@ namespace JSC {
         ExpressionNode* expr() const { return m_expr; }
 
     private:
-        virtual bool isExprStatement() const { return true; }
+        virtual bool isExprStatement() const override { return true; }
 
-        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         ExpressionNode* m_expr;
     };
@@ -1127,17 +1334,28 @@ namespace JSC {
     public:
         VarStatementNode(const JSTokenLocation&, ExpressionNode*);
     private:
-        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         ExpressionNode* m_expr;
     };
 
+    class EmptyVarExpression : public ExpressionNode {
+    public:
+        EmptyVarExpression(const JSTokenLocation&, const Identifier&);
+
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+        const Identifier& m_ident;
+    };
+
+
     class IfElseNode : public StatementNode {
     public:
         IfElseNode(const JSTokenLocation&, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock);
 
     private:
-        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
         bool tryFoldBreakAndContinue(BytecodeGenerator&, StatementNode* ifBlock,
             Label*& trueTarget, FallThroughMode&);
 
@@ -1151,7 +1369,7 @@ namespace JSC {
         DoWhileNode(const JSTokenLocation&, StatementNode*, ExpressionNode*);
 
     private:
-        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         StatementNode* m_statement;
         ExpressionNode* m_expr;
@@ -1162,7 +1380,7 @@ namespace JSC {
         WhileNode(const JSTokenLocation&, ExpressionNode*, StatementNode*);
 
     private:
-        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         ExpressionNode* m_expr;
         StatementNode* m_statement;
@@ -1173,50 +1391,66 @@ namespace JSC {
         ForNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode*);
 
     private:
-        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         ExpressionNode* m_expr1;
         ExpressionNode* m_expr2;
         ExpressionNode* m_expr3;
         StatementNode* m_statement;
     };
-
-    class ForInNode : public StatementNode, public ThrowableExpressionData {
+    
+    class DeconstructionPatternNode;
+    
+    class EnumerationNode : public StatementNode, public ThrowableExpressionData {
+    public:
+        EnumerationNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*);
+        
+    protected:
+        ExpressionNode* m_lexpr;
+        ExpressionNode* m_expr;
+        StatementNode* m_statement;
+    };
+    
+    class ForInNode : public EnumerationNode {
     public:
         ForInNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*);
-        ForInNode(VM*, const JSTokenLocation&, const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*, int divot, int startOffset, int endOffset);
 
     private:
-        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        RegisterID* tryGetBoundLocal(BytecodeGenerator&);
+        void emitLoopHeader(BytecodeGenerator&, RegisterID* propertyName);
+        void emitMultiLoopBytecode(BytecodeGenerator&, RegisterID* dst);
 
-        ExpressionNode* m_init;
-        ExpressionNode* m_lexpr;
-        ExpressionNode* m_expr;
-        StatementNode* m_statement;
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+    };
+    
+    class ForOfNode : public EnumerationNode {
+    public:
+        ForOfNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*);
+        
+    private:
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
     };
 
     class ContinueNode : public StatementNode, public ThrowableExpressionData {
     public:
-        ContinueNode(VM*, const JSTokenLocation&);
         ContinueNode(const JSTokenLocation&, const Identifier&);
         Label* trivialTarget(BytecodeGenerator&);
         
     private:
-        virtual bool isContinue() const { return true; }
-        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual bool isContinue() const override { return true; }
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         const Identifier& m_ident;
     };
 
     class BreakNode : public StatementNode, public ThrowableExpressionData {
     public:
-        BreakNode(VM*, const JSTokenLocation&);
         BreakNode(const JSTokenLocation&, const Identifier&);
         Label* trivialTarget(BytecodeGenerator&);
         
     private:
-        virtual bool isBreak() const { return true; }
-        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual bool isBreak() const override { return true; }
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         const Identifier& m_ident;
     };
@@ -1228,23 +1462,23 @@ namespace JSC {
         ExpressionNode* value() { return m_value; }
 
     private:
-        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
-        virtual bool isReturnNode() const { return true; }
+        virtual bool isReturnNode() const override { return true; }
 
         ExpressionNode* m_value;
     };
 
     class WithNode : public StatementNode {
     public:
-        WithNode(const JSTokenLocation&, ExpressionNode*, StatementNode*, uint32_t divot, uint32_t expressionLength);
+        WithNode(const JSTokenLocation&, ExpressionNode*, StatementNode*, const JSTextPosition& divot, uint32_t expressionLength);
 
     private:
-        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         ExpressionNode* m_expr;
         StatementNode* m_statement;
-        uint32_t m_divot;
+        JSTextPosition m_divot;
         uint32_t m_expressionLength;
     };
 
@@ -1253,7 +1487,7 @@ namespace JSC {
         LabelNode(const JSTokenLocation&, const Identifier& name, StatementNode*);
 
     private:
-        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         const Identifier& m_name;
         StatementNode* m_statement;
@@ -1264,7 +1498,7 @@ namespace JSC {
         ThrowNode(const JSTokenLocation&, ExpressionNode*);
 
     private:
-        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         ExpressionNode* m_expr;
     };
@@ -1274,58 +1508,52 @@ namespace JSC {
         TryNode(const JSTokenLocation&, StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock);
 
     private:
-        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         StatementNode* m_tryBlock;
-        const Identifier& m_exceptionIdent;
+        const Identifier& m_thrownValueIdent;
         StatementNode* m_catchBlock;
         StatementNode* m_finallyBlock;
     };
 
-    class ParameterNode : public ParserArenaFreeable {
+    class ParameterNode : public ParserArenaDeletable {
     public:
-        ParameterNode(const Identifier&);
-        ParameterNode(ParameterNode*, const Identifier&);
+        ParameterNode(PassRefPtr<DeconstructionPatternNode>);
+        ParameterNode(ParameterNode*, PassRefPtr<DeconstructionPatternNode>);
 
-        const Identifier& ident() const { return m_ident; }
+        DeconstructionPatternNode* pattern() const { return m_pattern.get(); }
         ParameterNode* nextParam() const { return m_next; }
 
     private:
-        const Identifier& m_ident;
+        RefPtr<DeconstructionPatternNode> m_pattern;
         ParameterNode* m_next;
     };
 
-    class ScopeNode : public StatementNode, public ParserArenaRefCounted {
+    class ScopeNode : public StatementNode, public ParserArenaRoot {
     public:
         typedef DeclarationStacks::VarStack VarStack;
         typedef DeclarationStacks::FunctionStack FunctionStack;
 
-        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);
+        ScopeNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, bool inStrictContext);
+        ScopeNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, const SourceCode&, SourceElements*, VarStack&, FunctionStack&, IdentifierSet&, CodeFeatures, int numConstants);
 
-        using ParserArenaRefCounted::operator new;
-
-        void destroyData()
-        {
-            m_arena.reset();
-            m_varStack.clear();
-            m_functionStack.clear();
-            m_statements = 0;
-            m_capturedVariables.clear();
-        }
+        using ParserArenaRoot::operator new;
 
         const SourceCode& source() const { return m_source; }
         const String& sourceURL() const { return m_source.provider()->url(); }
         intptr_t sourceID() const { return m_source.providerID(); }
 
         int startLine() const { return m_startLineNumber; }
-        int startCharPosition() const { return m_startCharPosition;}
+        int startStartOffset() const { return m_startStartOffset; }
+        int startLineStartOffset() const { return m_startLineStartOffset; }
 
         void setFeatures(CodeFeatures features) { m_features = features; }
         CodeFeatures features() { return m_features; }
 
         bool usesEval() const { return m_features & EvalFeature; }
         bool usesArguments() const { return (m_features & ArgumentsFeature) && !(m_features & ShadowsArgumentsFeature); }
+        bool modifiesParameter() const { return m_features & ModifiedParameterFeature; }
+        bool modifiesArguments() const { return m_features & (EvalFeature | ModifiedArgumentsFeature); }
         bool isStrictMode() const { return m_features & StrictModeFeature; }
         void setUsesArguments() { m_features |= ArgumentsFeature; }
         bool usesThis() const { return m_features & ThisFeature; }
@@ -1333,7 +1561,9 @@ namespace JSC {
         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()); }
+        const IdentifierSet& capturedVariables() const { return m_capturedVariables; }
+        bool captures(UniquedStringImpl* uid) { return m_capturedVariables.contains(uid); }
+        bool captures(const Identifier& ident) { return captures(ident.impl()); }
 
         VarStack& varStack() { return m_varStack; }
         FunctionStack& functionStack() { return m_functionStack; }
@@ -1348,13 +1578,13 @@ namespace JSC {
         StatementNode* singleStatement() const;
 
         void emitStatementsBytecode(BytecodeGenerator&, RegisterID* destination);
+        
+        void setClosedVariables(Vector<RefPtr<UniquedStringImpl>>&&) { }
 
     protected:
-        void setSource(const SourceCode& source) { m_source = source; }
-        ParserArena m_arena;
-
         int m_startLineNumber;
-        int m_startCharPosition;
+        unsigned m_startStartOffset;
+        unsigned m_startLineStartOffset;
 
     private:
         CodeFeatures m_features;
@@ -1368,84 +1598,135 @@ namespace JSC {
 
     class ProgramNode : public ScopeNode {
     public:
-        static const bool isFunctionNode = false;
-        static PassRefPtr<ProgramNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+        ProgramNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack&, FunctionStack&, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+
+        unsigned startColumn() const { return m_startColumn; }
+        unsigned endColumn() const { return m_endColumn; }
 
         static const bool scopeIsFunction = false;
 
-    private:
-        ProgramNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+        void setClosedVariables(Vector<RefPtr<UniquedStringImpl>>&&);
+        const Vector<RefPtr<UniquedStringImpl>>& closedVariables() const { return m_closedVariables; }
 
-        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+    private:
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+        Vector<RefPtr<UniquedStringImpl>> m_closedVariables;
+        unsigned m_startColumn;
+        unsigned m_endColumn;
     };
 
     class EvalNode : public ScopeNode {
     public:
-        static const bool isFunctionNode = false;
-        static PassRefPtr<EvalNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+        EvalNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack&, FunctionStack&, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+
+        ALWAYS_INLINE unsigned startColumn() const { return 0; }
+        unsigned endColumn() const { return m_endColumn; }
 
         static const bool scopeIsFunction = false;
 
     private:
-        EvalNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
-        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        unsigned m_endColumn;
     };
 
     class FunctionParameters : public RefCounted<FunctionParameters> {
         WTF_MAKE_FAST_ALLOCATED;
+        WTF_MAKE_NONCOPYABLE(FunctionParameters);
     public:
         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]; }
+        DeconstructionPatternNode* at(unsigned index) { ASSERT(index < m_size); return patterns()[index]; }
 
     private:
         FunctionParameters(ParameterNode*, unsigned size);
 
-        Identifier* identifiers() { return reinterpret_cast<Identifier*>(&m_storage); }
-        const Identifier* identifiers() const { return reinterpret_cast<const Identifier*>(&m_storage); }
+        DeconstructionPatternNode** patterns() { return &m_storage; }
 
         unsigned m_size;
-        void* m_storage;
+        DeconstructionPatternNode* m_storage;
     };
 
-    class FunctionBodyNode : public ScopeNode {
+    class FunctionBodyNode final : public StatementNode, public ParserArenaDeletable {
     public:
-        static const bool isFunctionNode = true;
-        static FunctionBodyNode* create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, bool isStrictMode);
-        static PassRefPtr<FunctionBodyNode> create(VM*, const JSTokenLocation& start, const JSTokenLocation& end, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+        using ParserArenaDeletable::operator new;
+
+        FunctionBodyNode(
+            ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, 
+            unsigned startColumn, unsigned endColumn, int functionKeywordStart, 
+            int functionNameStart, int parametersStart, bool isInStrictContext, 
+            ConstructorKind);
 
         FunctionParameters* parameters() const { return m_parameters.get(); }
-        size_t parameterCount() const { return m_parameters->size(); }
 
-        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
-        void finishParsing(const SourceCode&, ParameterNode*, const Identifier&, FunctionNameIsInScopeToggle);
-        void finishParsing(PassRefPtr<FunctionParameters>, const Identifier&, FunctionNameIsInScopeToggle);
+        void finishParsing(const SourceCode&, ParameterNode*, const Identifier&, FunctionMode);
         
+        void overrideName(const Identifier& ident) { m_ident = ident; }
         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; }
+        FunctionMode functionMode() { return m_functionMode; }
 
-        void setFunctionStart(int functionStart) { m_functionStart = functionStart; }
-        int functionStart() const { return m_functionStart; }
+        int functionNameStart() const { return m_functionNameStart; }
+        int functionKeywordStart() const { return m_functionKeywordStart; }
+        int parametersStart() const { return m_parametersStart; }
+        unsigned startColumn() const { return m_startColumn; }
+        unsigned endColumn() const { return m_endColumn; }
 
-        static const bool scopeIsFunction = true;
+        void setEndPosition(JSTextPosition);
 
-    private:
-        FunctionBodyNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, bool inStrictContext);
-        FunctionBodyNode(VM*, const JSTokenLocation& start, const JSTokenLocation& end, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+        const SourceCode& source() const { return m_source; }
+
+        int startStartOffset() const { return m_startStartOffset; }
+        bool isInStrictContext() const { return m_isInStrictContext; }
+        ConstructorKind constructorKind() { return static_cast<ConstructorKind>(m_constructorKind); }
 
+    protected:
         Identifier m_ident;
         Identifier m_inferredName;
-        FunctionNameIsInScopeToggle m_functionNameIsInScopeToggle;
+        FunctionMode m_functionMode;
         RefPtr<FunctionParameters> m_parameters;
-        int m_functionStart;
+        unsigned m_startColumn;
+        unsigned m_endColumn;
+        int m_functionKeywordStart;
+        int m_functionNameStart;
+        int m_parametersStart;
+        SourceCode m_source;
+        int m_startStartOffset;
+        unsigned m_isInStrictContext : 1;
+        unsigned m_constructorKind : 2;
+    };
+
+    class FunctionNode final : public ScopeNode {
+    public:
+        FunctionNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack&, FunctionStack&, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
+
+        FunctionParameters* parameters() const { return m_parameters.get(); }
+
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+        void finishParsing(PassRefPtr<FunctionParameters>, const Identifier&, FunctionMode);
+        
+        const Identifier& ident() { return m_ident; }
+
+        FunctionMode functionMode() { return m_functionMode; }
+
+        unsigned startColumn() const { return m_startColumn; }
+        unsigned endColumn() const { return m_endColumn; }
+
+        static const bool scopeIsFunction = true;
+
+    private:
+        Identifier m_ident;
+        FunctionMode m_functionMode;
+        RefPtr<FunctionParameters> m_parameters;
+        unsigned m_startColumn;
+        unsigned m_endColumn;
     };
 
     class FuncExprNode : public ExpressionNode {
@@ -1455,25 +1736,158 @@ namespace JSC {
         FunctionBodyNode* body() { return m_body; }
 
     private:
-        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
-        virtual bool isFuncExprNode() const { return true; } 
+        virtual bool isFuncExprNode() const override { return true; }
 
         FunctionBodyNode* m_body;
     };
 
+#if ENABLE(ES6_CLASS_SYNTAX)
+    class ClassExprNode final : public ExpressionNode {
+    public:
+        ClassExprNode(const JSTokenLocation&, const Identifier&, ExpressionNode* constructorExpresssion,
+            ExpressionNode* parentClass, PropertyListNode* instanceMethods, PropertyListNode* staticMethods);
+
+        const Identifier& name() { return m_name; }
+
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+        const Identifier& m_name;
+        ExpressionNode* m_constructorExpression;
+        ExpressionNode* m_classHeritage;
+        PropertyListNode* m_instanceMethods;
+        PropertyListNode* m_staticMethods;
+    };
+#endif
+
+    class DeconstructionPatternNode : public RefCounted<DeconstructionPatternNode> {
+        WTF_MAKE_NONCOPYABLE(DeconstructionPatternNode);
+        WTF_MAKE_FAST_ALLOCATED;
+
+    public:
+        virtual void collectBoundIdentifiers(Vector<Identifier>&) const = 0;
+        virtual void bindValue(BytecodeGenerator&, RegisterID* source) const = 0;
+        virtual void toString(StringBuilder&) const = 0;
+
+        virtual bool isBindingNode() const { return false; }
+        virtual RegisterID* emitDirectBinding(BytecodeGenerator&, RegisterID*, ExpressionNode*) { return 0; }
+        
+        virtual ~DeconstructionPatternNode() = 0;
+        
+    protected:
+        DeconstructionPatternNode();
+    };
+
+    class ArrayPatternNode : public DeconstructionPatternNode {
+    public:
+        static PassRefPtr<ArrayPatternNode> create();
+        void appendIndex(const JSTokenLocation&, DeconstructionPatternNode* node)
+        {
+            m_targetPatterns.append(node);
+        }
+
+    private:
+        ArrayPatternNode();
+        virtual void collectBoundIdentifiers(Vector<Identifier>&) const override;
+        virtual void bindValue(BytecodeGenerator&, RegisterID*) const override;
+        virtual RegisterID* emitDirectBinding(BytecodeGenerator&, RegisterID* dst, ExpressionNode*) override;
+        virtual void toString(StringBuilder&) const override;
+
+        Vector<RefPtr<DeconstructionPatternNode>> m_targetPatterns;
+    };
+    
+    class ObjectPatternNode : public DeconstructionPatternNode {
+    public:
+        static PassRefPtr<ObjectPatternNode> create();
+        void appendEntry(const JSTokenLocation&, const Identifier& identifier, bool wasString, DeconstructionPatternNode* pattern)
+        {
+            m_targetPatterns.append(Entry(identifier, wasString, pattern));
+        }
+        
+    private:
+        ObjectPatternNode();
+        virtual void collectBoundIdentifiers(Vector<Identifier>&) const override;
+        virtual void bindValue(BytecodeGenerator&, RegisterID*) const override;
+        virtual void toString(StringBuilder&) const override;
+        struct Entry {
+            Entry(const Identifier& propertyName, bool wasString, DeconstructionPatternNode* pattern)
+                : propertyName(propertyName)
+                , wasString(wasString)
+                , pattern(pattern)
+            {
+            }
+            Identifier propertyName;
+            bool wasString;
+            RefPtr<DeconstructionPatternNode> pattern;
+        };
+        Vector<Entry> m_targetPatterns;
+    };
+
+    class BindingNode : public DeconstructionPatternNode {
+    public:
+        static PassRefPtr<BindingNode> create(const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end);
+        const Identifier& boundProperty() const { return m_boundProperty; }
+
+        const JSTextPosition& divotStart() const { return m_divotStart; }
+        const JSTextPosition& divotEnd() const { return m_divotEnd; }
+        
+    private:
+        BindingNode(const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end);
+
+        virtual void collectBoundIdentifiers(Vector<Identifier>&) const override;
+        virtual void bindValue(BytecodeGenerator&, RegisterID*) const override;
+        virtual void toString(StringBuilder&) const override;
+        
+        virtual bool isBindingNode() const override { return true; }
+
+        JSTextPosition m_divotStart;
+        JSTextPosition m_divotEnd;
+        Identifier m_boundProperty;
+    };
+
+    class DeconstructingAssignmentNode : public ExpressionNode, public ParserArenaDeletable {
+    public:
+        DeconstructingAssignmentNode(const JSTokenLocation&, PassRefPtr<DeconstructionPatternNode>, ExpressionNode*);
+        DeconstructionPatternNode* bindings() { return m_bindings.get(); }
+        
+        using ParserArenaDeletable::operator new;
+
+    private:
+        virtual bool isAssignmentLocation() const override { return true; }
+        virtual bool isDeconstructionNode() const override { return true; }
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+        RefPtr<DeconstructionPatternNode> m_bindings;
+        ExpressionNode* m_initializer;
+    };
+
     class FuncDeclNode : public StatementNode {
     public:
         FuncDeclNode(const JSTokenLocation&, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
 
+        virtual bool isFuncDeclNode() const override { return true; }
         FunctionBodyNode* body() { return m_body; }
 
     private:
-        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         FunctionBodyNode* m_body;
     };
 
+#if ENABLE(ES6_CLASS_SYNTAX)
+    class ClassDeclNode final : public StatementNode {
+    public:
+        ClassDeclNode(const JSTokenLocation&, ExpressionNode* classExpression);
+
+    private:
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
+
+        ExpressionNode* m_classDeclaration;
+    };
+#endif
+
     class CaseClauseNode : public ParserArenaFreeable {
     public:
         CaseClauseNode(ExpressionNode*, SourceElements* = 0);
@@ -1481,10 +1895,12 @@ namespace JSC {
         ExpressionNode* expr() const { return m_expr; }
 
         void emitBytecode(BytecodeGenerator&, RegisterID* destination);
+        void setStartOffset(int offset) { m_startOffset = offset; }
 
     private:
         ExpressionNode* m_expr;
         SourceElements* m_statements;
+        int m_startOffset;
     };
 
     class ClauseListNode : public ParserArenaFreeable {
@@ -1508,7 +1924,7 @@ namespace JSC {
 
     private:
         SwitchInfo::SwitchType tryTableSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num);
-        static const size_t s_tableSwitchMinimum = 10;
+        static const size_t s_tableSwitchMinimum = 3;
         ClauseListNode* m_list1;
         CaseClauseNode* m_defaultClause;
         ClauseListNode* m_list2;
@@ -1519,7 +1935,7 @@ namespace JSC {
         SwitchNode(const JSTokenLocation&, ExpressionNode*, CaseBlockNode*);
 
     private:
-        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+        virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         ExpressionNode* m_expr;
         CaseBlockNode* m_block;