finally blocks should not set the exception stack trace when re-throwing the exception.
[WebKit-https.git] / Source / JavaScriptCore / parser / Nodes.h
index bdc691e..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,7 +76,7 @@ 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 };
@@ -126,12 +126,13 @@ namespace JSC {
     public:
         virtual ~Node() { }
 
-        int lineNo() const { return m_position.line; }
+        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:
         JSTextPosition m_position;
@@ -163,6 +164,7 @@ namespace JSC {
         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);
 
@@ -182,7 +184,6 @@ namespace JSC {
         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; }
 
         StatementNode* next() { return m_next; }
@@ -194,6 +195,7 @@ 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; }
 
     protected:
         StatementNode* m_next;
@@ -235,16 +237,32 @@ 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 override { return true; }
+        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&);
@@ -256,7 +274,7 @@ namespace JSC {
 
         const Identifier& m_value;
     };
-    
+
     class ThrowableExpressionData {
     public:
         ThrowableExpressionData()
@@ -409,6 +427,76 @@ namespace JSC {
         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);
@@ -422,10 +510,21 @@ namespace JSC {
 
     class ThisNode : public ExpressionNode {
     public:
-        ThisNode(const JSTokenLocation&);
+        ThisNode(const JSTokenLocation&, ThisTDZMode);
 
     private:
         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 {
@@ -481,22 +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(const Identifier&, ExpressionNode*, Type);
-        PropertyNode(ExpressionNode* propertyName, ExpressionNode*, Type);
-        
         ExpressionNode* expressionName() const { return m_expression; }
         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;
         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 {
@@ -639,7 +743,7 @@ namespace JSC {
     
     class FunctionCallBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
     public:
-        FunctionCallBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
+        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) override;
@@ -647,6 +751,7 @@ namespace JSC {
         ExpressionNode* m_base;
         ExpressionNode* m_subscript;
         ArgumentsNode* m_args;
+        bool m_subscriptHasAssignments;
     };
 
     class FunctionCallDotNode : public ExpressionNode, public ThrowableSubExpressionData {
@@ -662,6 +767,26 @@ 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*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
@@ -1386,7 +1511,7 @@ namespace JSC {
         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
 
         StatementNode* m_tryBlock;
-        const Identifier& m_exceptionIdent;
+        const Identifier& m_thrownValueIdent;
         StatementNode* m_catchBlock;
         StatementNode* m_finallyBlock;
     };
@@ -1437,7 +1562,8 @@ namespace JSC {
         bool hasCapturedVariables() const { return !!m_capturedVariables.size(); }
         size_t capturedVariableCount() const { return m_capturedVariables.size(); }
         const IdentifierSet& capturedVariables() const { return m_capturedVariables; }
-        bool captures(const Identifier& ident) { return m_capturedVariables.contains(ident.impl()); }
+        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; }
@@ -1453,7 +1579,7 @@ namespace JSC {
 
         void emitStatementsBytecode(BytecodeGenerator&, RegisterID* destination);
         
-        void setClosedVariables(Vector<RefPtr<StringImpl>>&&) { }
+        void setClosedVariables(Vector<RefPtr<UniquedStringImpl>>&&) { }
 
     protected:
         int m_startLineNumber;
@@ -1479,12 +1605,12 @@ namespace JSC {
 
         static const bool scopeIsFunction = false;
 
-        void setClosedVariables(Vector<RefPtr<StringImpl>>&&);
-        const Vector<RefPtr<StringImpl>>& closedVariables() const { return m_closedVariables; }
+        void setClosedVariables(Vector<RefPtr<UniquedStringImpl>>&&);
+        const Vector<RefPtr<UniquedStringImpl>>& closedVariables() const { return m_closedVariables; }
 
     private:
         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
-        Vector<RefPtr<StringImpl>> m_closedVariables;
+        Vector<RefPtr<UniquedStringImpl>> m_closedVariables;
         unsigned m_startColumn;
         unsigned m_endColumn;
     };
@@ -1527,7 +1653,11 @@ namespace JSC {
     public:
         using ParserArenaDeletable::operator new;
 
-        FunctionBodyNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, bool isInStrictContext);
+        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(); }
 
@@ -1542,10 +1672,9 @@ namespace JSC {
 
         FunctionMode functionMode() { return m_functionMode; }
 
-        void setFunctionNameStart(int functionNameStart) { m_functionNameStart = functionNameStart; }
         int functionNameStart() const { return m_functionNameStart; }
-        void setFunctionKeywordStart(int functionKeywordStart) { m_functionKeywordStart = functionKeywordStart; }
         int functionKeywordStart() const { return m_functionKeywordStart; }
+        int parametersStart() const { return m_parametersStart; }
         unsigned startColumn() const { return m_startColumn; }
         unsigned endColumn() const { return m_endColumn; }
 
@@ -1555,19 +1684,22 @@ namespace JSC {
 
         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;
         FunctionMode m_functionMode;
         RefPtr<FunctionParameters> m_parameters;
-        int m_functionNameStart;
-        int m_functionKeywordStart;
         unsigned m_startColumn;
         unsigned m_endColumn;
+        int m_functionKeywordStart;
+        int m_functionNameStart;
+        int m_parametersStart;
         SourceCode m_source;
         int m_startStartOffset;
-        bool m_isInStrictContext;
+        unsigned m_isInStrictContext : 1;
+        unsigned m_constructorKind : 2;
     };
 
     class FunctionNode final : public ScopeNode {
@@ -1624,7 +1756,7 @@ namespace JSC {
 
         const Identifier& m_name;
         ExpressionNode* m_constructorExpression;
-        ExpressionNode* m_parentClassExpression;
+        ExpressionNode* m_classHeritage;
         PropertyListNode* m_instanceMethods;
         PropertyListNode* m_staticMethods;
     };
@@ -1735,6 +1867,7 @@ namespace JSC {
     public:
         FuncDeclNode(const JSTokenLocation&, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
 
+        virtual bool isFuncDeclNode() const override { return true; }
         FunctionBodyNode* body() { return m_body; }
 
     private: