mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 10:42:45 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1295 lines
		
	
	
	
		
			38 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1295 lines
		
	
	
	
		
			38 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
 | |
|  * Copyright (c) 2020, Linus Groh <mail@linusgroh.de>
 | |
|  * All rights reserved.
 | |
|  *
 | |
|  * Redistribution and use in source and binary forms, with or without
 | |
|  * modification, are permitted provided that the following conditions are met:
 | |
|  *
 | |
|  * 1. Redistributions of source code must retain the above copyright notice, this
 | |
|  *    list of conditions and the following disclaimer.
 | |
|  *
 | |
|  * 2. Redistributions in binary form must reproduce the above copyright notice,
 | |
|  *    this list of conditions and the following disclaimer in the documentation
 | |
|  *    and/or other materials provided with the distribution.
 | |
|  *
 | |
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | |
|  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | |
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 | |
|  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 | |
|  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 | |
|  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 | |
|  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 | |
|  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 | |
|  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
|  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
|  */
 | |
| 
 | |
| #pragma once
 | |
| 
 | |
| #include <AK/FlyString.h>
 | |
| #include <AK/HashMap.h>
 | |
| #include <AK/NonnullRefPtrVector.h>
 | |
| #include <AK/RefPtr.h>
 | |
| #include <AK/String.h>
 | |
| #include <AK/Vector.h>
 | |
| #include <LibJS/Forward.h>
 | |
| #include <LibJS/Runtime/PropertyName.h>
 | |
| #include <LibJS/Runtime/Value.h>
 | |
| 
 | |
| namespace JS {
 | |
| 
 | |
| class VariableDeclaration;
 | |
| class FunctionDeclaration;
 | |
| 
 | |
| template<class T, class... Args>
 | |
| static inline NonnullRefPtr<T>
 | |
| create_ast_node(Args&&... args)
 | |
| {
 | |
|     return adopt(*new T(forward<Args>(args)...));
 | |
| }
 | |
| 
 | |
| class ASTNode : public RefCounted<ASTNode> {
 | |
| public:
 | |
|     virtual ~ASTNode() { }
 | |
|     virtual const char* class_name() const = 0;
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const = 0;
 | |
|     virtual void dump(int indent) const;
 | |
|     virtual bool is_identifier() const { return false; }
 | |
|     virtual bool is_spread_expression() const { return false; }
 | |
|     virtual bool is_member_expression() const { return false; }
 | |
|     virtual bool is_scope_node() const { return false; }
 | |
|     virtual bool is_program() const { return false; }
 | |
|     virtual bool is_variable_declaration() const { return false; }
 | |
|     virtual bool is_call_expression() const { return false; }
 | |
|     virtual bool is_new_expression() const { return false; }
 | |
|     virtual bool is_super_expression() const { return false; }
 | |
|     virtual bool is_expression_statement() const { return false; };
 | |
|     virtual bool is_string_literal() const { return false; };
 | |
| 
 | |
| protected:
 | |
|     ASTNode() { }
 | |
| 
 | |
| private:
 | |
| };
 | |
| 
 | |
| class Statement : public ASTNode {
 | |
| public:
 | |
|     const FlyString& label() const { return m_label; }
 | |
|     void set_label(FlyString string) { m_label = string; }
 | |
| 
 | |
| protected:
 | |
|     FlyString m_label;
 | |
| };
 | |
| 
 | |
| class EmptyStatement final : public Statement {
 | |
| public:
 | |
|     Value execute(Interpreter&, GlobalObject&) const override { return js_undefined(); }
 | |
|     const char* class_name() const override { return "EmptyStatement"; }
 | |
| };
 | |
| 
 | |
| class ErrorStatement final : public Statement {
 | |
| public:
 | |
|     Value execute(Interpreter&, GlobalObject&) const override { return js_undefined(); }
 | |
|     const char* class_name() const override { return "ErrorStatement"; }
 | |
| };
 | |
| 
 | |
| class ExpressionStatement final : public Statement {
 | |
| public:
 | |
|     ExpressionStatement(NonnullRefPtr<Expression> expression)
 | |
|         : m_expression(move(expression))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
|     virtual bool is_expression_statement() const override { return true; }
 | |
| 
 | |
|     const Expression& expression() const { return m_expression; };
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "ExpressionStatement"; }
 | |
| 
 | |
|     NonnullRefPtr<Expression> m_expression;
 | |
| };
 | |
| 
 | |
| class ScopeNode : public Statement {
 | |
| public:
 | |
|     template<typename T, typename... Args>
 | |
|     T& append(Args&&... args)
 | |
|     {
 | |
|         auto child = create_ast_node<T>(forward<Args>(args)...);
 | |
|         m_children.append(move(child));
 | |
|         return static_cast<T&>(m_children.last());
 | |
|     }
 | |
|     void append(NonnullRefPtr<Statement> child)
 | |
|     {
 | |
|         m_children.append(move(child));
 | |
|     }
 | |
| 
 | |
|     const NonnullRefPtrVector<Statement>& children() const { return m_children; }
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
|     void add_variables(NonnullRefPtrVector<VariableDeclaration>);
 | |
|     void add_functions(NonnullRefPtrVector<FunctionDeclaration>);
 | |
|     const NonnullRefPtrVector<VariableDeclaration>& variables() const { return m_variables; }
 | |
|     const NonnullRefPtrVector<FunctionDeclaration>& functions() const { return m_functions; }
 | |
| 
 | |
| protected:
 | |
|     ScopeNode() { }
 | |
| 
 | |
| private:
 | |
|     virtual bool is_scope_node() const final { return true; }
 | |
|     NonnullRefPtrVector<Statement> m_children;
 | |
|     NonnullRefPtrVector<VariableDeclaration> m_variables;
 | |
|     NonnullRefPtrVector<FunctionDeclaration> m_functions;
 | |
| };
 | |
| 
 | |
| class Program final : public ScopeNode {
 | |
| public:
 | |
|     Program() { }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
| 
 | |
|     bool is_strict_mode() const { return m_is_strict_mode; }
 | |
|     void set_strict_mode() { m_is_strict_mode = true; }
 | |
| 
 | |
| private:
 | |
|     bool m_is_strict_mode { false };
 | |
| 
 | |
|     virtual bool is_program() const override { return true; }
 | |
|     virtual const char* class_name() const override { return "Program"; }
 | |
| };
 | |
| 
 | |
| class BlockStatement final : public ScopeNode {
 | |
| public:
 | |
|     BlockStatement() { }
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "BlockStatement"; }
 | |
| };
 | |
| 
 | |
| class Expression : public ASTNode {
 | |
| public:
 | |
|     virtual Reference to_reference(Interpreter&, GlobalObject&) const;
 | |
| };
 | |
| 
 | |
| class Declaration : public Statement {
 | |
| };
 | |
| 
 | |
| class ErrorDeclaration final : public Declaration {
 | |
| public:
 | |
|     Value execute(Interpreter&, GlobalObject&) const override { return js_undefined(); }
 | |
|     const char* class_name() const override { return "ErrorDeclaration"; }
 | |
| };
 | |
| 
 | |
| class FunctionNode {
 | |
| public:
 | |
|     struct Parameter {
 | |
|         FlyString name;
 | |
|         RefPtr<Expression> default_value;
 | |
|         bool is_rest { false };
 | |
|     };
 | |
| 
 | |
|     const FlyString& name() const { return m_name; }
 | |
|     const Statement& body() const { return *m_body; }
 | |
|     const Vector<Parameter>& parameters() const { return m_parameters; };
 | |
|     i32 function_length() const { return m_function_length; }
 | |
|     bool is_strict_mode() const { return m_is_strict_mode; }
 | |
| 
 | |
| protected:
 | |
|     FunctionNode(const FlyString& name, NonnullRefPtr<Statement> body, Vector<Parameter> parameters, i32 function_length, NonnullRefPtrVector<VariableDeclaration> variables, bool is_strict_mode)
 | |
|         : m_name(name)
 | |
|         , m_body(move(body))
 | |
|         , m_parameters(move(parameters))
 | |
|         , m_variables(move(variables))
 | |
|         , m_function_length(function_length)
 | |
|         , m_is_strict_mode(is_strict_mode)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     void dump(int indent, const char* class_name) const;
 | |
| 
 | |
|     const NonnullRefPtrVector<VariableDeclaration>& variables() const { return m_variables; }
 | |
| 
 | |
| private:
 | |
|     FlyString m_name;
 | |
|     NonnullRefPtr<Statement> m_body;
 | |
|     const Vector<Parameter> m_parameters;
 | |
|     NonnullRefPtrVector<VariableDeclaration> m_variables;
 | |
|     const i32 m_function_length;
 | |
|     bool m_is_strict_mode;
 | |
| };
 | |
| 
 | |
| class FunctionDeclaration final
 | |
|     : public Declaration
 | |
|     , public FunctionNode {
 | |
| public:
 | |
|     static bool must_have_name() { return true; }
 | |
| 
 | |
|     FunctionDeclaration(const FlyString& name, NonnullRefPtr<Statement> body, Vector<Parameter> parameters, i32 function_length, NonnullRefPtrVector<VariableDeclaration> variables, bool is_strict_mode = false)
 | |
|         : FunctionNode(name, move(body), move(parameters), function_length, move(variables), is_strict_mode)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "FunctionDeclaration"; }
 | |
| };
 | |
| 
 | |
| class FunctionExpression final
 | |
|     : public Expression
 | |
|     , public FunctionNode {
 | |
| public:
 | |
|     static bool must_have_name() { return false; }
 | |
| 
 | |
|     FunctionExpression(const FlyString& name, NonnullRefPtr<Statement> body, Vector<Parameter> parameters, i32 function_length, NonnullRefPtrVector<VariableDeclaration> variables, bool is_strict_mode, bool is_arrow_function = false)
 | |
|         : FunctionNode(name, move(body), move(parameters), function_length, move(variables), is_strict_mode)
 | |
|         , m_is_arrow_function(is_arrow_function)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "FunctionExpression"; }
 | |
| 
 | |
|     bool m_is_arrow_function;
 | |
| };
 | |
| 
 | |
| class ErrorExpression final : public Expression {
 | |
| public:
 | |
|     Value execute(Interpreter&, GlobalObject&) const override { return js_undefined(); }
 | |
|     const char* class_name() const override { return "ErrorExpression"; }
 | |
| };
 | |
| 
 | |
| class ReturnStatement final : public Statement {
 | |
| public:
 | |
|     explicit ReturnStatement(RefPtr<Expression> argument)
 | |
|         : m_argument(move(argument))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     const Expression* argument() const { return m_argument; }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "ReturnStatement"; }
 | |
| 
 | |
|     RefPtr<Expression> m_argument;
 | |
| };
 | |
| 
 | |
| class IfStatement final : public Statement {
 | |
| public:
 | |
|     IfStatement(NonnullRefPtr<Expression> predicate, NonnullRefPtr<Statement> consequent, RefPtr<Statement> alternate)
 | |
|         : m_predicate(move(predicate))
 | |
|         , m_consequent(move(consequent))
 | |
|         , m_alternate(move(alternate))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     const Expression& predicate() const { return *m_predicate; }
 | |
|     const Statement& consequent() const { return *m_consequent; }
 | |
|     const Statement* alternate() const { return m_alternate; }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "IfStatement"; }
 | |
| 
 | |
|     NonnullRefPtr<Expression> m_predicate;
 | |
|     NonnullRefPtr<Statement> m_consequent;
 | |
|     RefPtr<Statement> m_alternate;
 | |
| };
 | |
| 
 | |
| class WhileStatement final : public Statement {
 | |
| public:
 | |
|     WhileStatement(NonnullRefPtr<Expression> test, NonnullRefPtr<Statement> body)
 | |
|         : m_test(move(test))
 | |
|         , m_body(move(body))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     const Expression& test() const { return *m_test; }
 | |
|     const Statement& body() const { return *m_body; }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "WhileStatement"; }
 | |
| 
 | |
|     NonnullRefPtr<Expression> m_test;
 | |
|     NonnullRefPtr<Statement> m_body;
 | |
| };
 | |
| 
 | |
| class DoWhileStatement final : public Statement {
 | |
| public:
 | |
|     DoWhileStatement(NonnullRefPtr<Expression> test, NonnullRefPtr<Statement> body)
 | |
|         : m_test(move(test))
 | |
|         , m_body(move(body))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     const Expression& test() const { return *m_test; }
 | |
|     const Statement& body() const { return *m_body; }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "DoWhileStatement"; }
 | |
| 
 | |
|     NonnullRefPtr<Expression> m_test;
 | |
|     NonnullRefPtr<Statement> m_body;
 | |
| };
 | |
| 
 | |
| class WithStatement final : public Statement {
 | |
| public:
 | |
|     WithStatement(NonnullRefPtr<Expression> object, NonnullRefPtr<Statement> body)
 | |
|         : m_object(move(object))
 | |
|         , m_body(move(body))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     const Expression& object() const { return *m_object; }
 | |
|     const Statement& body() const { return *m_body; }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "WithStatement"; }
 | |
| 
 | |
|     NonnullRefPtr<Expression> m_object;
 | |
|     NonnullRefPtr<Statement> m_body;
 | |
| };
 | |
| 
 | |
| class ForStatement final : public Statement {
 | |
| public:
 | |
|     ForStatement(RefPtr<ASTNode> init, RefPtr<Expression> test, RefPtr<Expression> update, NonnullRefPtr<Statement> body)
 | |
|         : m_init(move(init))
 | |
|         , m_test(move(test))
 | |
|         , m_update(move(update))
 | |
|         , m_body(move(body))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     const ASTNode* init() const { return m_init; }
 | |
|     const Expression* test() const { return m_test; }
 | |
|     const Expression* update() const { return m_update; }
 | |
|     const Statement& body() const { return *m_body; }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "ForStatement"; }
 | |
| 
 | |
|     RefPtr<ASTNode> m_init;
 | |
|     RefPtr<Expression> m_test;
 | |
|     RefPtr<Expression> m_update;
 | |
|     NonnullRefPtr<Statement> m_body;
 | |
| };
 | |
| 
 | |
| class ForInStatement final : public Statement {
 | |
| public:
 | |
|     ForInStatement(NonnullRefPtr<ASTNode> lhs, NonnullRefPtr<Expression> rhs, NonnullRefPtr<Statement> body)
 | |
|         : m_lhs(move(lhs))
 | |
|         , m_rhs(move(rhs))
 | |
|         , m_body(move(body))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     const ASTNode& lhs() const { return *m_lhs; }
 | |
|     const Expression& rhs() const { return *m_rhs; }
 | |
|     const Statement& body() const { return *m_body; }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "ForInStatement"; }
 | |
| 
 | |
|     NonnullRefPtr<ASTNode> m_lhs;
 | |
|     NonnullRefPtr<Expression> m_rhs;
 | |
|     NonnullRefPtr<Statement> m_body;
 | |
| };
 | |
| 
 | |
| class ForOfStatement final : public Statement {
 | |
| public:
 | |
|     ForOfStatement(NonnullRefPtr<ASTNode> lhs, NonnullRefPtr<Expression> rhs, NonnullRefPtr<Statement> body)
 | |
|         : m_lhs(move(lhs))
 | |
|         , m_rhs(move(rhs))
 | |
|         , m_body(move(body))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     const ASTNode& lhs() const { return *m_lhs; }
 | |
|     const Expression& rhs() const { return *m_rhs; }
 | |
|     const Statement& body() const { return *m_body; }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "ForOfStatement"; }
 | |
| 
 | |
|     NonnullRefPtr<ASTNode> m_lhs;
 | |
|     NonnullRefPtr<Expression> m_rhs;
 | |
|     NonnullRefPtr<Statement> m_body;
 | |
| };
 | |
| 
 | |
| enum class BinaryOp {
 | |
|     Addition,
 | |
|     Subtraction,
 | |
|     Multiplication,
 | |
|     Division,
 | |
|     Modulo,
 | |
|     Exponentiation,
 | |
|     TypedEquals,
 | |
|     TypedInequals,
 | |
|     AbstractEquals,
 | |
|     AbstractInequals,
 | |
|     GreaterThan,
 | |
|     GreaterThanEquals,
 | |
|     LessThan,
 | |
|     LessThanEquals,
 | |
|     BitwiseAnd,
 | |
|     BitwiseOr,
 | |
|     BitwiseXor,
 | |
|     LeftShift,
 | |
|     RightShift,
 | |
|     UnsignedRightShift,
 | |
|     In,
 | |
|     InstanceOf,
 | |
| };
 | |
| 
 | |
| class BinaryExpression final : public Expression {
 | |
| public:
 | |
|     BinaryExpression(BinaryOp op, NonnullRefPtr<Expression> lhs, NonnullRefPtr<Expression> rhs)
 | |
|         : m_op(op)
 | |
|         , m_lhs(move(lhs))
 | |
|         , m_rhs(move(rhs))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "BinaryExpression"; }
 | |
| 
 | |
|     BinaryOp m_op;
 | |
|     NonnullRefPtr<Expression> m_lhs;
 | |
|     NonnullRefPtr<Expression> m_rhs;
 | |
| };
 | |
| 
 | |
| enum class LogicalOp {
 | |
|     And,
 | |
|     Or,
 | |
|     NullishCoalescing,
 | |
| };
 | |
| 
 | |
| class LogicalExpression final : public Expression {
 | |
| public:
 | |
|     LogicalExpression(LogicalOp op, NonnullRefPtr<Expression> lhs, NonnullRefPtr<Expression> rhs)
 | |
|         : m_op(op)
 | |
|         , m_lhs(move(lhs))
 | |
|         , m_rhs(move(rhs))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "LogicalExpression"; }
 | |
| 
 | |
|     LogicalOp m_op;
 | |
|     NonnullRefPtr<Expression> m_lhs;
 | |
|     NonnullRefPtr<Expression> m_rhs;
 | |
| };
 | |
| 
 | |
| enum class UnaryOp {
 | |
|     BitwiseNot,
 | |
|     Not,
 | |
|     Plus,
 | |
|     Minus,
 | |
|     Typeof,
 | |
|     Void,
 | |
|     Delete,
 | |
| };
 | |
| 
 | |
| class UnaryExpression final : public Expression {
 | |
| public:
 | |
|     UnaryExpression(UnaryOp op, NonnullRefPtr<Expression> lhs)
 | |
|         : m_op(op)
 | |
|         , m_lhs(move(lhs))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "UnaryExpression"; }
 | |
| 
 | |
|     UnaryOp m_op;
 | |
|     NonnullRefPtr<Expression> m_lhs;
 | |
| };
 | |
| 
 | |
| class SequenceExpression final : public Expression {
 | |
| public:
 | |
|     SequenceExpression(NonnullRefPtrVector<Expression> expressions)
 | |
|         : m_expressions(move(expressions))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual void dump(int indent) const override;
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "SequenceExpression"; }
 | |
| 
 | |
|     NonnullRefPtrVector<Expression> m_expressions;
 | |
| };
 | |
| 
 | |
| class Literal : public Expression {
 | |
| protected:
 | |
|     explicit Literal() { }
 | |
| };
 | |
| 
 | |
| class BooleanLiteral final : public Literal {
 | |
| public:
 | |
|     explicit BooleanLiteral(bool value)
 | |
|         : m_value(value)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "BooleanLiteral"; }
 | |
| 
 | |
|     bool m_value { false };
 | |
| };
 | |
| 
 | |
| class NumericLiteral final : public Literal {
 | |
| public:
 | |
|     explicit NumericLiteral(double value)
 | |
|         : m_value(value)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "NumericLiteral"; }
 | |
| 
 | |
|     double m_value { 0 };
 | |
| };
 | |
| 
 | |
| class BigIntLiteral final : public Literal {
 | |
| public:
 | |
|     explicit BigIntLiteral(String value)
 | |
|         : m_value(move(value))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "BigIntLiteral"; }
 | |
| 
 | |
|     String m_value;
 | |
| };
 | |
| 
 | |
| class StringLiteral final : public Literal {
 | |
| public:
 | |
|     explicit StringLiteral(String value, bool is_use_strict_directive = false)
 | |
|         : m_value(move(value))
 | |
|         , m_is_use_strict_directive(is_use_strict_directive)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
|     virtual bool is_string_literal() const override { return true; };
 | |
| 
 | |
|     StringView value() const { return m_value; }
 | |
|     bool is_use_strict_directive() const { return m_is_use_strict_directive; };
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "StringLiteral"; }
 | |
| 
 | |
|     String m_value;
 | |
|     bool m_is_use_strict_directive;
 | |
| };
 | |
| 
 | |
| class NullLiteral final : public Literal {
 | |
| public:
 | |
|     explicit NullLiteral() { }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "NullLiteral"; }
 | |
| };
 | |
| 
 | |
| class RegExpLiteral final : public Literal {
 | |
| public:
 | |
|     explicit RegExpLiteral(String content, String flags)
 | |
|         : m_content(content)
 | |
|         , m_flags(flags)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
|     const String& content() const { return m_content; }
 | |
|     const String& flags() const { return m_flags; }
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "RegexLiteral"; }
 | |
| 
 | |
|     String m_content;
 | |
|     String m_flags;
 | |
| };
 | |
| 
 | |
| class Identifier final : public Expression {
 | |
| public:
 | |
|     explicit Identifier(const FlyString& string)
 | |
|         : m_string(string)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     const FlyString& string() const { return m_string; }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
|     virtual bool is_identifier() const override { return true; }
 | |
|     virtual Reference to_reference(Interpreter&, GlobalObject&) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "Identifier"; }
 | |
| 
 | |
|     FlyString m_string;
 | |
| };
 | |
| 
 | |
| class ClassMethod final : public ASTNode {
 | |
| public:
 | |
|     enum class Kind {
 | |
|         Method,
 | |
|         Getter,
 | |
|         Setter,
 | |
|     };
 | |
| 
 | |
|     ClassMethod(NonnullRefPtr<Expression> key, NonnullRefPtr<FunctionExpression> function, Kind kind, bool is_static)
 | |
|         : m_key(move(key))
 | |
|         , m_function(move(function))
 | |
|         , m_kind(kind)
 | |
|         , m_is_static(is_static)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     const Expression& key() const { return *m_key; }
 | |
|     Kind kind() const { return m_kind; }
 | |
|     bool is_static() const { return m_is_static; }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "ClassMethod"; }
 | |
| 
 | |
|     NonnullRefPtr<Expression> m_key;
 | |
|     NonnullRefPtr<FunctionExpression> m_function;
 | |
|     Kind m_kind;
 | |
|     bool m_is_static;
 | |
| };
 | |
| 
 | |
| class SuperExpression final : public Expression {
 | |
| public:
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual bool is_super_expression() const override { return true; }
 | |
|     virtual const char* class_name() const override { return "SuperExpression"; }
 | |
| };
 | |
| 
 | |
| class ClassExpression final : public Expression {
 | |
| public:
 | |
|     ClassExpression(String name, RefPtr<FunctionExpression> constructor, RefPtr<Expression> super_class, NonnullRefPtrVector<ClassMethod> methods)
 | |
|         : m_name(move(name))
 | |
|         , m_constructor(move(constructor))
 | |
|         , m_super_class(move(super_class))
 | |
|         , m_methods(move(methods))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     StringView name() const { return m_name; }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "ClassExpression"; }
 | |
| 
 | |
|     String m_name;
 | |
|     RefPtr<FunctionExpression> m_constructor;
 | |
|     RefPtr<Expression> m_super_class;
 | |
|     NonnullRefPtrVector<ClassMethod> m_methods;
 | |
| };
 | |
| 
 | |
| class ClassDeclaration final : public Declaration {
 | |
| public:
 | |
|     ClassDeclaration(NonnullRefPtr<ClassExpression> class_expression)
 | |
|         : m_class_expression(move(class_expression))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "ClassDeclaration"; }
 | |
|     NonnullRefPtr<ClassExpression> m_class_expression;
 | |
| };
 | |
| 
 | |
| class SpreadExpression final : public Expression {
 | |
| public:
 | |
|     explicit SpreadExpression(NonnullRefPtr<Expression> target)
 | |
|         : m_target(target)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
|     virtual bool is_spread_expression() const override { return true; }
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "SpreadExpression"; }
 | |
| 
 | |
|     NonnullRefPtr<Expression> m_target;
 | |
| };
 | |
| 
 | |
| class ThisExpression final : public Expression {
 | |
| public:
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "ThisExpression"; }
 | |
| };
 | |
| 
 | |
| class CallExpression : public Expression {
 | |
| public:
 | |
|     struct Argument {
 | |
|         NonnullRefPtr<Expression> value;
 | |
|         bool is_spread;
 | |
|     };
 | |
| 
 | |
|     CallExpression(NonnullRefPtr<Expression> callee, Vector<Argument> arguments = {})
 | |
|         : m_callee(move(callee))
 | |
|         , m_arguments(move(arguments))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "CallExpression"; }
 | |
|     virtual bool is_call_expression() const override { return true; }
 | |
| 
 | |
|     struct ThisAndCallee {
 | |
|         Value this_value;
 | |
|         Value callee;
 | |
|     };
 | |
|     ThisAndCallee compute_this_and_callee(Interpreter&, GlobalObject&) const;
 | |
| 
 | |
|     NonnullRefPtr<Expression> m_callee;
 | |
|     const Vector<Argument> m_arguments;
 | |
| };
 | |
| 
 | |
| class NewExpression final : public CallExpression {
 | |
| public:
 | |
|     NewExpression(NonnullRefPtr<Expression> callee, Vector<Argument> arguments = {})
 | |
|         : CallExpression(move(callee), move(arguments))
 | |
|     {
 | |
|     }
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "NewExpression"; }
 | |
|     virtual bool is_call_expression() const override { return false; }
 | |
|     virtual bool is_new_expression() const override { return true; }
 | |
| };
 | |
| 
 | |
| enum class AssignmentOp {
 | |
|     Assignment,
 | |
|     AdditionAssignment,
 | |
|     SubtractionAssignment,
 | |
|     MultiplicationAssignment,
 | |
|     DivisionAssignment,
 | |
|     ModuloAssignment,
 | |
|     ExponentiationAssignment,
 | |
|     BitwiseAndAssignment,
 | |
|     BitwiseOrAssignment,
 | |
|     BitwiseXorAssignment,
 | |
|     LeftShiftAssignment,
 | |
|     RightShiftAssignment,
 | |
|     UnsignedRightShiftAssignment,
 | |
|     AndAssignment,
 | |
|     OrAssignment,
 | |
|     NullishAssignment,
 | |
| };
 | |
| 
 | |
| class AssignmentExpression final : public Expression {
 | |
| public:
 | |
|     AssignmentExpression(AssignmentOp op, NonnullRefPtr<Expression> lhs, NonnullRefPtr<Expression> rhs)
 | |
|         : m_op(op)
 | |
|         , m_lhs(move(lhs))
 | |
|         , m_rhs(move(rhs))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "AssignmentExpression"; }
 | |
| 
 | |
|     AssignmentOp m_op;
 | |
|     NonnullRefPtr<Expression> m_lhs;
 | |
|     NonnullRefPtr<Expression> m_rhs;
 | |
| };
 | |
| 
 | |
| enum class UpdateOp {
 | |
|     Increment,
 | |
|     Decrement,
 | |
| };
 | |
| 
 | |
| class UpdateExpression final : public Expression {
 | |
| public:
 | |
|     UpdateExpression(UpdateOp op, NonnullRefPtr<Expression> argument, bool prefixed = false)
 | |
|         : m_op(op)
 | |
|         , m_argument(move(argument))
 | |
|         , m_prefixed(prefixed)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "UpdateExpression"; }
 | |
| 
 | |
|     UpdateOp m_op;
 | |
|     NonnullRefPtr<Expression> m_argument;
 | |
|     bool m_prefixed;
 | |
| };
 | |
| 
 | |
| enum class DeclarationKind {
 | |
|     Var,
 | |
|     Let,
 | |
|     Const,
 | |
| };
 | |
| 
 | |
| class VariableDeclarator final : public ASTNode {
 | |
| public:
 | |
|     VariableDeclarator(NonnullRefPtr<Identifier> id)
 | |
|         : m_id(move(id))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     VariableDeclarator(NonnullRefPtr<Identifier> id, RefPtr<Expression> init)
 | |
|         : m_id(move(id))
 | |
|         , m_init(move(init))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     const Identifier& id() const { return m_id; }
 | |
|     const Expression* init() const { return m_init; }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "VariableDeclarator"; }
 | |
| 
 | |
|     NonnullRefPtr<Identifier> m_id;
 | |
|     RefPtr<Expression> m_init;
 | |
| };
 | |
| 
 | |
| class VariableDeclaration final : public Declaration {
 | |
| public:
 | |
|     VariableDeclaration(DeclarationKind declaration_kind, NonnullRefPtrVector<VariableDeclarator> declarations)
 | |
|         : m_declaration_kind(declaration_kind)
 | |
|         , m_declarations(move(declarations))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual bool is_variable_declaration() const override { return true; }
 | |
|     DeclarationKind declaration_kind() const { return m_declaration_kind; }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
|     const NonnullRefPtrVector<VariableDeclarator>& declarations() const { return m_declarations; }
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "VariableDeclaration"; }
 | |
| 
 | |
|     DeclarationKind m_declaration_kind;
 | |
|     NonnullRefPtrVector<VariableDeclarator> m_declarations;
 | |
| };
 | |
| 
 | |
| class ObjectProperty final : public ASTNode {
 | |
| public:
 | |
|     enum class Type {
 | |
|         KeyValue,
 | |
|         Getter,
 | |
|         Setter,
 | |
|         Spread,
 | |
|     };
 | |
| 
 | |
|     ObjectProperty(NonnullRefPtr<Expression> key, RefPtr<Expression> value, Type property_type, bool is_method)
 | |
|         : m_key(move(key))
 | |
|         , m_value(move(value))
 | |
|         , m_property_type(property_type)
 | |
|         , m_is_method(is_method)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     const Expression& key() const { return m_key; }
 | |
|     const Expression& value() const
 | |
|     {
 | |
|         ASSERT(m_value);
 | |
|         return *m_value;
 | |
|     }
 | |
| 
 | |
|     Type type() const { return m_property_type; }
 | |
|     bool is_method() const { return m_is_method; }
 | |
| 
 | |
|     virtual void dump(int indent) const override;
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "ObjectProperty"; }
 | |
| 
 | |
|     NonnullRefPtr<Expression> m_key;
 | |
|     RefPtr<Expression> m_value;
 | |
|     Type m_property_type;
 | |
|     bool m_is_method { false };
 | |
| };
 | |
| 
 | |
| class ObjectExpression final : public Expression {
 | |
| public:
 | |
|     ObjectExpression(NonnullRefPtrVector<ObjectProperty> properties = {})
 | |
|         : m_properties(move(properties))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "ObjectExpression"; }
 | |
| 
 | |
|     NonnullRefPtrVector<ObjectProperty> m_properties;
 | |
| };
 | |
| 
 | |
| class ArrayExpression final : public Expression {
 | |
| public:
 | |
|     ArrayExpression(Vector<RefPtr<Expression>> elements)
 | |
|         : m_elements(move(elements))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     const Vector<RefPtr<Expression>>& elements() const { return m_elements; }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "ArrayExpression"; }
 | |
| 
 | |
|     Vector<RefPtr<Expression>> m_elements;
 | |
| };
 | |
| 
 | |
| class TemplateLiteral final : public Expression {
 | |
| public:
 | |
|     TemplateLiteral(NonnullRefPtrVector<Expression> expressions)
 | |
|         : m_expressions(move(expressions))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     TemplateLiteral(NonnullRefPtrVector<Expression> expressions, NonnullRefPtrVector<Expression> raw_strings)
 | |
|         : m_expressions(move(expressions))
 | |
|         , m_raw_strings(move(raw_strings))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
|     const NonnullRefPtrVector<Expression>& expressions() const { return m_expressions; }
 | |
|     const NonnullRefPtrVector<Expression>& raw_strings() const { return m_raw_strings; }
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "TemplateLiteral"; }
 | |
| 
 | |
|     const NonnullRefPtrVector<Expression> m_expressions;
 | |
|     const NonnullRefPtrVector<Expression> m_raw_strings;
 | |
| };
 | |
| 
 | |
| class TaggedTemplateLiteral final : public Expression {
 | |
| public:
 | |
|     TaggedTemplateLiteral(NonnullRefPtr<Expression> tag, NonnullRefPtr<TemplateLiteral> template_literal)
 | |
|         : m_tag(move(tag))
 | |
|         , m_template_literal(move(template_literal))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "TaggedTemplateLiteral"; }
 | |
| 
 | |
|     const NonnullRefPtr<Expression> m_tag;
 | |
|     const NonnullRefPtr<TemplateLiteral> m_template_literal;
 | |
| };
 | |
| 
 | |
| class MemberExpression final : public Expression {
 | |
| public:
 | |
|     MemberExpression(NonnullRefPtr<Expression> object, NonnullRefPtr<Expression> property, bool computed = false)
 | |
|         : m_object(move(object))
 | |
|         , m_property(move(property))
 | |
|         , m_computed(computed)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
|     virtual Reference to_reference(Interpreter&, GlobalObject&) const override;
 | |
| 
 | |
|     bool is_computed() const { return m_computed; }
 | |
|     const Expression& object() const { return *m_object; }
 | |
|     const Expression& property() const { return *m_property; }
 | |
| 
 | |
|     PropertyName computed_property_name(Interpreter&, GlobalObject&) const;
 | |
| 
 | |
|     String to_string_approximation() const;
 | |
| 
 | |
| private:
 | |
|     virtual bool is_member_expression() const override { return true; }
 | |
|     virtual const char* class_name() const override { return "MemberExpression"; }
 | |
| 
 | |
|     NonnullRefPtr<Expression> m_object;
 | |
|     NonnullRefPtr<Expression> m_property;
 | |
|     bool m_computed { false };
 | |
| };
 | |
| 
 | |
| class MetaProperty final : public Expression {
 | |
| public:
 | |
|     enum class Type {
 | |
|         NewTarget,
 | |
|         ImportMeta,
 | |
|     };
 | |
| 
 | |
|     MetaProperty(Type type)
 | |
|         : m_type(type)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
|     virtual void dump(int indent) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "MetaProperty"; }
 | |
| 
 | |
|     Type m_type;
 | |
| };
 | |
| 
 | |
| class ConditionalExpression final : public Expression {
 | |
| public:
 | |
|     ConditionalExpression(NonnullRefPtr<Expression> test, NonnullRefPtr<Expression> consequent, NonnullRefPtr<Expression> alternate)
 | |
|         : m_test(move(test))
 | |
|         , m_consequent(move(consequent))
 | |
|         , m_alternate(move(alternate))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual void dump(int indent) const override;
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "ConditionalExpression"; }
 | |
| 
 | |
|     NonnullRefPtr<Expression> m_test;
 | |
|     NonnullRefPtr<Expression> m_consequent;
 | |
|     NonnullRefPtr<Expression> m_alternate;
 | |
| };
 | |
| 
 | |
| class CatchClause final : public ASTNode {
 | |
| public:
 | |
|     CatchClause(const FlyString& parameter, NonnullRefPtr<BlockStatement> body)
 | |
|         : m_parameter(parameter)
 | |
|         , m_body(move(body))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     const FlyString& parameter() const { return m_parameter; }
 | |
|     const BlockStatement& body() const { return m_body; }
 | |
| 
 | |
|     virtual void dump(int indent) const override;
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "CatchClause"; }
 | |
| 
 | |
|     FlyString m_parameter;
 | |
|     NonnullRefPtr<BlockStatement> m_body;
 | |
| };
 | |
| 
 | |
| class TryStatement final : public Statement {
 | |
| public:
 | |
|     TryStatement(NonnullRefPtr<BlockStatement> block, RefPtr<CatchClause> handler, RefPtr<BlockStatement> finalizer)
 | |
|         : m_block(move(block))
 | |
|         , m_handler(move(handler))
 | |
|         , m_finalizer(move(finalizer))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     const BlockStatement& block() const { return m_block; }
 | |
|     const CatchClause* handler() const { return m_handler; }
 | |
|     const BlockStatement* finalizer() const { return m_finalizer; }
 | |
| 
 | |
|     virtual void dump(int indent) const override;
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "TryStatement"; }
 | |
| 
 | |
|     NonnullRefPtr<BlockStatement> m_block;
 | |
|     RefPtr<CatchClause> m_handler;
 | |
|     RefPtr<BlockStatement> m_finalizer;
 | |
| };
 | |
| 
 | |
| class ThrowStatement final : public Statement {
 | |
| public:
 | |
|     explicit ThrowStatement(NonnullRefPtr<Expression> argument)
 | |
|         : m_argument(move(argument))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     const Expression& argument() const { return m_argument; }
 | |
| 
 | |
|     virtual void dump(int indent) const override;
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "ThrowStatement"; }
 | |
| 
 | |
|     NonnullRefPtr<Expression> m_argument;
 | |
| };
 | |
| 
 | |
| class SwitchCase final : public ASTNode {
 | |
| public:
 | |
|     SwitchCase(RefPtr<Expression> test, NonnullRefPtrVector<Statement> consequent)
 | |
|         : m_test(move(test))
 | |
|         , m_consequent(move(consequent))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     const Expression* test() const { return m_test; }
 | |
|     const NonnullRefPtrVector<Statement>& consequent() const { return m_consequent; }
 | |
| 
 | |
|     virtual void dump(int indent) const override;
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "SwitchCase"; }
 | |
| 
 | |
|     RefPtr<Expression> m_test;
 | |
|     NonnullRefPtrVector<Statement> m_consequent;
 | |
| };
 | |
| 
 | |
| class SwitchStatement final : public Statement {
 | |
| public:
 | |
|     SwitchStatement(NonnullRefPtr<Expression> discriminant, NonnullRefPtrVector<SwitchCase> cases)
 | |
|         : m_discriminant(move(discriminant))
 | |
|         , m_cases(move(cases))
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual void dump(int indent) const override;
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "SwitchStatement"; }
 | |
| 
 | |
|     NonnullRefPtr<Expression> m_discriminant;
 | |
|     NonnullRefPtrVector<SwitchCase> m_cases;
 | |
| };
 | |
| 
 | |
| class BreakStatement final : public Statement {
 | |
| public:
 | |
|     BreakStatement(FlyString target_label)
 | |
|         : m_target_label(target_label)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
| 
 | |
|     const FlyString& target_label() const { return m_target_label; }
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "BreakStatement"; }
 | |
| 
 | |
|     FlyString m_target_label;
 | |
| };
 | |
| 
 | |
| class ContinueStatement final : public Statement {
 | |
| public:
 | |
|     ContinueStatement(FlyString target_label)
 | |
|         : m_target_label(target_label)
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
| 
 | |
|     const FlyString& target_label() const { return m_target_label; }
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "ContinueStatement"; }
 | |
| 
 | |
|     FlyString m_target_label;
 | |
| };
 | |
| 
 | |
| class DebuggerStatement final : public Statement {
 | |
| public:
 | |
|     DebuggerStatement() { }
 | |
| 
 | |
|     virtual Value execute(Interpreter&, GlobalObject&) const override;
 | |
| 
 | |
| private:
 | |
|     virtual const char* class_name() const override { return "DebuggerStatement"; }
 | |
| };
 | |
| 
 | |
| }
 | 
