Jelajahi Sumber

LibJS: Make the AST reference-counted

This allows function objects to outlive the original parsed program
without their ScopeNode disappearing.
Andreas Kling 5 tahun lalu
induk
melakukan
ddd69e3660

+ 2 - 2
Libraries/LibJS/AST.cpp

@@ -100,10 +100,10 @@ Value WhileStatement::execute(Interpreter& interpreter) const
 
 
 Value ForStatement::execute(Interpreter& interpreter) const
 Value ForStatement::execute(Interpreter& interpreter) const
 {
 {
-    OwnPtr<BlockStatement> wrapper;
+    RefPtr<BlockStatement> wrapper;
 
 
     if (m_init->is_variable_declaration() && static_cast<const VariableDeclaration*>(m_init.ptr())->declaration_type() != DeclarationType::Var) {
     if (m_init->is_variable_declaration() && static_cast<const VariableDeclaration*>(m_init.ptr())->declaration_type() != DeclarationType::Var) {
-        wrapper = make<BlockStatement>();
+        wrapper = create_ast_node<BlockStatement>();
         interpreter.enter_scope(*wrapper, {}, ScopeType::Block);
         interpreter.enter_scope(*wrapper, {}, ScopeType::Block);
     }
     }
 
 

+ 53 - 46
Libraries/LibJS/AST.h

@@ -26,8 +26,8 @@
 
 
 #pragma once
 #pragma once
 
 
-#include <AK/NonnullOwnPtrVector.h>
-#include <AK/OwnPtr.h>
+#include <AK/NonnullRefPtrVector.h>
+#include <AK/RefPtr.h>
 #include <AK/String.h>
 #include <AK/String.h>
 #include <AK/Vector.h>
 #include <AK/Vector.h>
 #include <LibJS/Forward.h>
 #include <LibJS/Forward.h>
@@ -35,7 +35,14 @@
 
 
 namespace JS {
 namespace JS {
 
 
-class ASTNode {
+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:
 public:
     virtual ~ASTNode() {}
     virtual ~ASTNode() {}
     virtual const char* class_name() const = 0;
     virtual const char* class_name() const = 0;
@@ -62,7 +69,7 @@ public:
 
 
 class ExpressionStatement final : public Statement {
 class ExpressionStatement final : public Statement {
 public:
 public:
-    ExpressionStatement(NonnullOwnPtr<Expression> expression)
+    ExpressionStatement(NonnullRefPtr<Expression> expression)
         : m_expression(move(expression))
         : m_expression(move(expression))
     {
     {
     }
     }
@@ -72,7 +79,7 @@ public:
     virtual void dump(int indent) const override;
     virtual void dump(int indent) const override;
 
 
 private:
 private:
-    NonnullOwnPtr<Expression> m_expression;
+    NonnullRefPtr<Expression> m_expression;
 };
 };
 
 
 class ScopeNode : public Statement {
 class ScopeNode : public Statement {
@@ -84,12 +91,12 @@ public:
         m_children.append(move(child));
         m_children.append(move(child));
         return static_cast<T&>(m_children.last());
         return static_cast<T&>(m_children.last());
     }
     }
-    void append(NonnullOwnPtr<Statement> child)
+    void append(NonnullRefPtr<Statement> child)
     {
     {
         m_children.append(move(child));
         m_children.append(move(child));
     }
     }
 
 
-    const NonnullOwnPtrVector<Statement>& children() const { return m_children; }
+    const NonnullRefPtrVector<Statement>& children() const { return m_children; }
     virtual Value execute(Interpreter&) const override;
     virtual Value execute(Interpreter&) const override;
     virtual void dump(int indent) const override;
     virtual void dump(int indent) const override;
 
 
@@ -97,7 +104,7 @@ protected:
     ScopeNode() {}
     ScopeNode() {}
 
 
 private:
 private:
-    NonnullOwnPtrVector<Statement> m_children;
+    NonnullRefPtrVector<Statement> m_children;
 };
 };
 
 
 class Program : public ScopeNode {
 class Program : public ScopeNode {
@@ -118,7 +125,7 @@ private:
 
 
 class FunctionDeclaration : public Statement {
 class FunctionDeclaration : public Statement {
 public:
 public:
-    FunctionDeclaration(String name, NonnullOwnPtr<ScopeNode> body, Vector<String> parameters = {})
+    FunctionDeclaration(String name, NonnullRefPtr<ScopeNode> body, Vector<String> parameters = {})
         : m_name(move(name))
         : m_name(move(name))
         , m_body(move(body))
         , m_body(move(body))
         , m_parameters(move(parameters))
         , m_parameters(move(parameters))
@@ -136,7 +143,7 @@ private:
     virtual const char* class_name() const override { return "FunctionDeclaration"; }
     virtual const char* class_name() const override { return "FunctionDeclaration"; }
 
 
     String m_name;
     String m_name;
-    NonnullOwnPtr<ScopeNode> m_body;
+    NonnullRefPtr<ScopeNode> m_body;
     const Vector<String> m_parameters;
     const Vector<String> m_parameters;
 };
 };
 
 
@@ -153,7 +160,7 @@ public:
 
 
 class ReturnStatement : public Statement {
 class ReturnStatement : public Statement {
 public:
 public:
-    explicit ReturnStatement(OwnPtr<Expression> argument)
+    explicit ReturnStatement(RefPtr<Expression> argument)
         : m_argument(move(argument))
         : m_argument(move(argument))
     {
     {
     }
     }
@@ -166,12 +173,12 @@ public:
 private:
 private:
     virtual const char* class_name() const override { return "ReturnStatement"; }
     virtual const char* class_name() const override { return "ReturnStatement"; }
 
 
-    OwnPtr<Expression> m_argument;
+    RefPtr<Expression> m_argument;
 };
 };
 
 
 class IfStatement : public Statement {
 class IfStatement : public Statement {
 public:
 public:
-    IfStatement(NonnullOwnPtr<Expression> predicate, NonnullOwnPtr<ScopeNode> consequent, NonnullOwnPtr<ScopeNode> alternate)
+    IfStatement(NonnullRefPtr<Expression> predicate, NonnullRefPtr<ScopeNode> consequent, NonnullRefPtr<ScopeNode> alternate)
         : m_predicate(move(predicate))
         : m_predicate(move(predicate))
         , m_consequent(move(consequent))
         , m_consequent(move(consequent))
         , m_alternate(move(alternate))
         , m_alternate(move(alternate))
@@ -188,14 +195,14 @@ public:
 private:
 private:
     virtual const char* class_name() const override { return "IfStatement"; }
     virtual const char* class_name() const override { return "IfStatement"; }
 
 
-    NonnullOwnPtr<Expression> m_predicate;
-    NonnullOwnPtr<ScopeNode> m_consequent;
-    NonnullOwnPtr<ScopeNode> m_alternate;
+    NonnullRefPtr<Expression> m_predicate;
+    NonnullRefPtr<ScopeNode> m_consequent;
+    NonnullRefPtr<ScopeNode> m_alternate;
 };
 };
 
 
 class WhileStatement : public Statement {
 class WhileStatement : public Statement {
 public:
 public:
-    WhileStatement(NonnullOwnPtr<Expression> predicate, NonnullOwnPtr<ScopeNode> body)
+    WhileStatement(NonnullRefPtr<Expression> predicate, NonnullRefPtr<ScopeNode> body)
         : m_predicate(move(predicate))
         : m_predicate(move(predicate))
         , m_body(move(body))
         , m_body(move(body))
     {
     {
@@ -210,13 +217,13 @@ public:
 private:
 private:
     virtual const char* class_name() const override { return "WhileStatement"; }
     virtual const char* class_name() const override { return "WhileStatement"; }
 
 
-    NonnullOwnPtr<Expression> m_predicate;
-    NonnullOwnPtr<ScopeNode> m_body;
+    NonnullRefPtr<Expression> m_predicate;
+    NonnullRefPtr<ScopeNode> m_body;
 };
 };
 
 
 class ForStatement : public Statement {
 class ForStatement : public Statement {
 public:
 public:
-    ForStatement(OwnPtr<Statement> init, OwnPtr<Expression> test, OwnPtr<Expression> update, NonnullOwnPtr<ScopeNode> body)
+    ForStatement(RefPtr<Statement> init, RefPtr<Expression> test, RefPtr<Expression> update, NonnullRefPtr<ScopeNode> body)
         : m_init(move(init))
         : m_init(move(init))
         , m_test(move(test))
         , m_test(move(test))
         , m_update(move(update))
         , m_update(move(update))
@@ -235,10 +242,10 @@ public:
 private:
 private:
     virtual const char* class_name() const override { return "ForStatement"; }
     virtual const char* class_name() const override { return "ForStatement"; }
 
 
-    OwnPtr<Statement> m_init;
-    OwnPtr<Expression> m_test;
-    OwnPtr<Expression> m_update;
-    NonnullOwnPtr<ScopeNode> m_body;
+    RefPtr<Statement> m_init;
+    RefPtr<Expression> m_test;
+    RefPtr<Expression> m_update;
+    NonnullRefPtr<ScopeNode> m_body;
 };
 };
 
 
 enum class BinaryOp {
 enum class BinaryOp {
@@ -263,7 +270,7 @@ enum class BinaryOp {
 
 
 class BinaryExpression : public Expression {
 class BinaryExpression : public Expression {
 public:
 public:
-    BinaryExpression(BinaryOp op, NonnullOwnPtr<Expression> lhs, NonnullOwnPtr<Expression> rhs)
+    BinaryExpression(BinaryOp op, NonnullRefPtr<Expression> lhs, NonnullRefPtr<Expression> rhs)
         : m_op(op)
         : m_op(op)
         , m_lhs(move(lhs))
         , m_lhs(move(lhs))
         , m_rhs(move(rhs))
         , m_rhs(move(rhs))
@@ -277,8 +284,8 @@ private:
     virtual const char* class_name() const override { return "BinaryExpression"; }
     virtual const char* class_name() const override { return "BinaryExpression"; }
 
 
     BinaryOp m_op;
     BinaryOp m_op;
-    NonnullOwnPtr<Expression> m_lhs;
-    NonnullOwnPtr<Expression> m_rhs;
+    NonnullRefPtr<Expression> m_lhs;
+    NonnullRefPtr<Expression> m_rhs;
 };
 };
 
 
 enum class LogicalOp {
 enum class LogicalOp {
@@ -288,7 +295,7 @@ enum class LogicalOp {
 
 
 class LogicalExpression : public Expression {
 class LogicalExpression : public Expression {
 public:
 public:
-    LogicalExpression(LogicalOp op, NonnullOwnPtr<Expression> lhs, NonnullOwnPtr<Expression> rhs)
+    LogicalExpression(LogicalOp op, NonnullRefPtr<Expression> lhs, NonnullRefPtr<Expression> rhs)
         : m_op(op)
         : m_op(op)
         , m_lhs(move(lhs))
         , m_lhs(move(lhs))
         , m_rhs(move(rhs))
         , m_rhs(move(rhs))
@@ -302,8 +309,8 @@ private:
     virtual const char* class_name() const override { return "LogicalExpression"; }
     virtual const char* class_name() const override { return "LogicalExpression"; }
 
 
     LogicalOp m_op;
     LogicalOp m_op;
-    NonnullOwnPtr<Expression> m_lhs;
-    NonnullOwnPtr<Expression> m_rhs;
+    NonnullRefPtr<Expression> m_lhs;
+    NonnullRefPtr<Expression> m_rhs;
 };
 };
 
 
 enum class UnaryOp {
 enum class UnaryOp {
@@ -314,7 +321,7 @@ enum class UnaryOp {
 
 
 class UnaryExpression : public Expression {
 class UnaryExpression : public Expression {
 public:
 public:
-    UnaryExpression(UnaryOp op, NonnullOwnPtr<Expression> lhs)
+    UnaryExpression(UnaryOp op, NonnullRefPtr<Expression> lhs)
         : m_op(op)
         : m_op(op)
         , m_lhs(move(lhs))
         , m_lhs(move(lhs))
     {
     {
@@ -327,7 +334,7 @@ private:
     virtual const char* class_name() const override { return "UnaryExpression"; }
     virtual const char* class_name() const override { return "UnaryExpression"; }
 
 
     UnaryOp m_op;
     UnaryOp m_op;
-    NonnullOwnPtr<Expression> m_lhs;
+    NonnullRefPtr<Expression> m_lhs;
 };
 };
 
 
 class Literal : public Expression {
 class Literal : public Expression {
@@ -432,7 +439,7 @@ private:
 
 
 class CallExpression : public Expression {
 class CallExpression : public Expression {
 public:
 public:
-    explicit CallExpression(NonnullOwnPtr<Expression> callee, NonnullOwnPtrVector<Expression> arguments = {})
+    explicit CallExpression(NonnullRefPtr<Expression> callee, NonnullRefPtrVector<Expression> arguments = {})
         : m_callee(move(callee))
         : m_callee(move(callee))
         , m_arguments(move(arguments))
         , m_arguments(move(arguments))
     {
     {
@@ -444,8 +451,8 @@ public:
 private:
 private:
     virtual const char* class_name() const override { return "CallExpression"; }
     virtual const char* class_name() const override { return "CallExpression"; }
 
 
-    NonnullOwnPtr<Expression> m_callee;
-    const NonnullOwnPtrVector<Expression> m_arguments;
+    NonnullRefPtr<Expression> m_callee;
+    const NonnullRefPtrVector<Expression> m_arguments;
 };
 };
 
 
 enum class AssignmentOp {
 enum class AssignmentOp {
@@ -458,7 +465,7 @@ enum class AssignmentOp {
 
 
 class AssignmentExpression : public Expression {
 class AssignmentExpression : public Expression {
 public:
 public:
-    AssignmentExpression(AssignmentOp op, NonnullOwnPtr<ASTNode> lhs, NonnullOwnPtr<Expression> rhs)
+    AssignmentExpression(AssignmentOp op, NonnullRefPtr<ASTNode> lhs, NonnullRefPtr<Expression> rhs)
         : m_op(op)
         : m_op(op)
         , m_lhs(move(lhs))
         , m_lhs(move(lhs))
         , m_rhs(move(rhs))
         , m_rhs(move(rhs))
@@ -472,8 +479,8 @@ private:
     virtual const char* class_name() const override { return "AssignmentExpression"; }
     virtual const char* class_name() const override { return "AssignmentExpression"; }
 
 
     AssignmentOp m_op;
     AssignmentOp m_op;
-    NonnullOwnPtr<ASTNode> m_lhs;
-    NonnullOwnPtr<Expression> m_rhs;
+    NonnullRefPtr<ASTNode> m_lhs;
+    NonnullRefPtr<Expression> m_rhs;
 };
 };
 
 
 enum class UpdateOp {
 enum class UpdateOp {
@@ -483,7 +490,7 @@ enum class UpdateOp {
 
 
 class UpdateExpression : public Expression {
 class UpdateExpression : public Expression {
 public:
 public:
-    UpdateExpression(UpdateOp op, NonnullOwnPtr<Expression> argument, bool prefixed = false)
+    UpdateExpression(UpdateOp op, NonnullRefPtr<Expression> argument, bool prefixed = false)
         : m_op(op)
         : m_op(op)
         , m_argument(move(argument))
         , m_argument(move(argument))
         , m_prefixed(prefixed)
         , m_prefixed(prefixed)
@@ -497,7 +504,7 @@ private:
     virtual const char* class_name() const override { return "UpdateExpression"; }
     virtual const char* class_name() const override { return "UpdateExpression"; }
 
 
     UpdateOp m_op;
     UpdateOp m_op;
-    NonnullOwnPtr<Identifier> m_argument;
+    NonnullRefPtr<Identifier> m_argument;
     bool m_prefixed;
     bool m_prefixed;
 };
 };
 
 
@@ -509,7 +516,7 @@ enum class DeclarationType {
 
 
 class VariableDeclaration : public Statement {
 class VariableDeclaration : public Statement {
 public:
 public:
-    VariableDeclaration(NonnullOwnPtr<Identifier> name, OwnPtr<Expression> initializer, DeclarationType declaration_type)
+    VariableDeclaration(NonnullRefPtr<Identifier> name, RefPtr<Expression> initializer, DeclarationType declaration_type)
         : m_declaration_type(declaration_type)
         : m_declaration_type(declaration_type)
         , m_name(move(name))
         , m_name(move(name))
         , m_initializer(move(initializer))
         , m_initializer(move(initializer))
@@ -527,8 +534,8 @@ private:
     virtual const char* class_name() const override { return "VariableDeclaration"; }
     virtual const char* class_name() const override { return "VariableDeclaration"; }
 
 
     DeclarationType m_declaration_type;
     DeclarationType m_declaration_type;
-    NonnullOwnPtr<Identifier> m_name;
-    OwnPtr<Expression> m_initializer;
+    NonnullRefPtr<Identifier> m_name;
+    RefPtr<Expression> m_initializer;
 };
 };
 
 
 class ObjectExpression : public Expression {
 class ObjectExpression : public Expression {
@@ -544,7 +551,7 @@ private:
 
 
 class MemberExpression final : public Expression {
 class MemberExpression final : public Expression {
 public:
 public:
-    MemberExpression(NonnullOwnPtr<Expression> object, NonnullOwnPtr<Expression> property)
+    MemberExpression(NonnullRefPtr<Expression> object, NonnullRefPtr<Expression> property)
         : m_object(move(object))
         : m_object(move(object))
         , m_property(move(property))
         , m_property(move(property))
     {
     {
@@ -559,8 +566,8 @@ private:
     virtual bool is_member_expression() const override { return true; }
     virtual bool is_member_expression() const override { return true; }
     virtual const char* class_name() const override { return "MemberExpression"; }
     virtual const char* class_name() const override { return "MemberExpression"; }
 
 
-    NonnullOwnPtr<Expression> m_object;
-    NonnullOwnPtr<Expression> m_property;
+    NonnullRefPtr<Expression> m_object;
+    NonnullRefPtr<Expression> m_property;
 };
 };
 
 
 }
 }

+ 1 - 1
Libraries/LibJS/Interpreter.cpp

@@ -72,7 +72,7 @@ void Interpreter::enter_scope(const ScopeNode& scope_node, Vector<Argument> argu
 
 
 void Interpreter::exit_scope(const ScopeNode& scope_node)
 void Interpreter::exit_scope(const ScopeNode& scope_node)
 {
 {
-    while (&m_scope_stack.last().scope_node != &scope_node)
+    while (m_scope_stack.last().scope_node.ptr() != &scope_node)
         m_scope_stack.take_last();
         m_scope_stack.take_last();
 }
 }
 
 

+ 1 - 1
Libraries/LibJS/Interpreter.h

@@ -47,7 +47,7 @@ struct Variable {
 
 
 struct ScopeFrame {
 struct ScopeFrame {
     ScopeType type;
     ScopeType type;
-    const ScopeNode& scope_node;
+    NonnullRefPtr<ScopeNode> scope_node;
     HashMap<String, Variable> variables;
     HashMap<String, Variable> variables;
 };
 };
 
 

+ 65 - 65
Libraries/LibJS/Parser.cpp

@@ -163,9 +163,9 @@ Associativity Parser::operator_associativity(TokenType type) const
     }
     }
 }
 }
 
 
-NonnullOwnPtr<Program> Parser::parse_program()
+NonnullRefPtr<Program> Parser::parse_program()
 {
 {
-    auto program = make<Program>();
+    auto program = adopt(*new Program);
     while (!done()) {
     while (!done()) {
         if (match(TokenType::Semicolon)) {
         if (match(TokenType::Semicolon)) {
             consume();
             consume();
@@ -179,10 +179,10 @@ NonnullOwnPtr<Program> Parser::parse_program()
     return program;
     return program;
 }
 }
 
 
-NonnullOwnPtr<Statement> Parser::parse_statement()
+NonnullRefPtr<Statement> Parser::parse_statement()
 {
 {
     if (match_expression()) {
     if (match_expression()) {
-        return make<JS::ExpressionStatement>(parse_expression(0));
+        return adopt(*new ExpressionStatement(parse_expression(0)));
     }
     }
 
 
     switch (m_current_token.type()) {
     switch (m_current_token.type()) {
@@ -202,11 +202,11 @@ NonnullOwnPtr<Statement> Parser::parse_statement()
         m_has_errors = true;
         m_has_errors = true;
         expected("statement (missing switch case)");
         expected("statement (missing switch case)");
         consume();
         consume();
-        return make<ErrorStatement>();
+        return create_ast_node<ErrorStatement>();
     }
     }
 }
 }
 
 
-NonnullOwnPtr<Expression> Parser::parse_primary_expression()
+NonnullRefPtr<Expression> Parser::parse_primary_expression()
 {
 {
     switch (m_current_token.type()) {
     switch (m_current_token.type()) {
     case TokenType::ParenOpen: {
     case TokenType::ParenOpen: {
@@ -216,64 +216,64 @@ NonnullOwnPtr<Expression> Parser::parse_primary_expression()
         return expression;
         return expression;
     }
     }
     case TokenType::Identifier:
     case TokenType::Identifier:
-        return make<Identifier>(consume().value());
+        return create_ast_node<Identifier>(consume().value());
     case TokenType::NumericLiteral:
     case TokenType::NumericLiteral:
-        return make<NumericLiteral>(consume().double_value());
+        return create_ast_node<NumericLiteral>(consume().double_value());
     case TokenType::BoolLiteral:
     case TokenType::BoolLiteral:
-        return make<BooleanLiteral>(consume().bool_value());
+        return create_ast_node<BooleanLiteral>(consume().bool_value());
     case TokenType::StringLiteral:
     case TokenType::StringLiteral:
-        return make<StringLiteral>(consume().string_value());
+        return create_ast_node<StringLiteral>(consume().string_value());
     case TokenType::NullLiteral:
     case TokenType::NullLiteral:
         consume();
         consume();
-        return make<NullLiteral>();
+        return create_ast_node<NullLiteral>();
     case TokenType::UndefinedLiteral:
     case TokenType::UndefinedLiteral:
         consume();
         consume();
-        return make<UndefinedLiteral>();
+        return create_ast_node<UndefinedLiteral>();
     case TokenType::CurlyOpen:
     case TokenType::CurlyOpen:
         return parse_object_expression();
         return parse_object_expression();
     default:
     default:
         m_has_errors = true;
         m_has_errors = true;
         expected("primary expression (missing switch case)");
         expected("primary expression (missing switch case)");
         consume();
         consume();
-        return make<ErrorExpression>();
+        return create_ast_node<ErrorExpression>();
     }
     }
 }
 }
 
 
-NonnullOwnPtr<Expression> Parser::parse_unary_prefixed_expression()
+NonnullRefPtr<Expression> Parser::parse_unary_prefixed_expression()
 {
 {
     switch (m_current_token.type()) {
     switch (m_current_token.type()) {
     case TokenType::PlusPlus:
     case TokenType::PlusPlus:
         consume();
         consume();
-        return make<UpdateExpression>(UpdateOp::Increment, parse_primary_expression(), true);
+        return create_ast_node<UpdateExpression>(UpdateOp::Increment, parse_primary_expression(), true);
     case TokenType::MinusMinus:
     case TokenType::MinusMinus:
         consume();
         consume();
-        return make<UpdateExpression>(UpdateOp::Decrement, parse_primary_expression(), true);
+        return create_ast_node<UpdateExpression>(UpdateOp::Decrement, parse_primary_expression(), true);
     case TokenType::ExclamationMark:
     case TokenType::ExclamationMark:
         consume();
         consume();
-        return make<UnaryExpression>(UnaryOp::Not, parse_primary_expression());
+        return create_ast_node<UnaryExpression>(UnaryOp::Not, parse_primary_expression());
     case TokenType::Tilde:
     case TokenType::Tilde:
         consume();
         consume();
-        return make<UnaryExpression>(UnaryOp::BitwiseNot, parse_primary_expression());
+        return create_ast_node<UnaryExpression>(UnaryOp::BitwiseNot, parse_primary_expression());
     case TokenType::Typeof:
     case TokenType::Typeof:
         consume();
         consume();
-        return make<UnaryExpression>(UnaryOp::Typeof, parse_primary_expression());
+        return create_ast_node<UnaryExpression>(UnaryOp::Typeof, parse_primary_expression());
     default:
     default:
         m_has_errors = true;
         m_has_errors = true;
         expected("primary expression (missing switch case)");
         expected("primary expression (missing switch case)");
         consume();
         consume();
-        return make<ErrorExpression>();
+        return create_ast_node<ErrorExpression>();
     }
     }
 }
 }
 
 
-NonnullOwnPtr<ObjectExpression> Parser::parse_object_expression()
+NonnullRefPtr<ObjectExpression> Parser::parse_object_expression()
 {
 {
     // FIXME: Parse actual object expression
     // FIXME: Parse actual object expression
     consume(TokenType::CurlyOpen);
     consume(TokenType::CurlyOpen);
     consume(TokenType::CurlyClose);
     consume(TokenType::CurlyClose);
-    return make<ObjectExpression>();
+    return create_ast_node<ObjectExpression>();
 }
 }
 
 
-NonnullOwnPtr<Expression> Parser::parse_expression(int min_precedence, Associativity associativity)
+NonnullRefPtr<Expression> Parser::parse_expression(int min_precedence, Associativity associativity)
 {
 {
     if (match_unary_prefixed_expression())
     if (match_unary_prefixed_expression())
         return parse_unary_prefixed_expression();
         return parse_unary_prefixed_expression();
@@ -292,90 +292,90 @@ NonnullOwnPtr<Expression> Parser::parse_expression(int min_precedence, Associati
     return expression;
     return expression;
 }
 }
 
 
-NonnullOwnPtr<Expression> Parser::parse_secondary_expression(NonnullOwnPtr<Expression> lhs, int min_precedence, Associativity associativity)
+NonnullRefPtr<Expression> Parser::parse_secondary_expression(NonnullRefPtr<Expression> lhs, int min_precedence, Associativity associativity)
 {
 {
     switch (m_current_token.type()) {
     switch (m_current_token.type()) {
     case TokenType::Plus:
     case TokenType::Plus:
         consume();
         consume();
-        return make<BinaryExpression>(BinaryOp::Plus, move(lhs), parse_expression(min_precedence, associativity));
+        return create_ast_node<BinaryExpression>(BinaryOp::Plus, move(lhs), parse_expression(min_precedence, associativity));
     case TokenType::PlusEquals:
     case TokenType::PlusEquals:
         consume();
         consume();
-        return make<AssignmentExpression>(AssignmentOp::AdditionAssignment, move(lhs), parse_expression(min_precedence, associativity));
+        return create_ast_node<AssignmentExpression>(AssignmentOp::AdditionAssignment, move(lhs), parse_expression(min_precedence, associativity));
     case TokenType::Minus:
     case TokenType::Minus:
         consume();
         consume();
-        return make<BinaryExpression>(BinaryOp::Minus, move(lhs), parse_expression(min_precedence, associativity));
+        return create_ast_node<BinaryExpression>(BinaryOp::Minus, move(lhs), parse_expression(min_precedence, associativity));
     case TokenType::MinusEquals:
     case TokenType::MinusEquals:
         consume();
         consume();
-        return make<AssignmentExpression>(AssignmentOp::SubtractionAssignment, move(lhs), parse_expression(min_precedence, associativity));
+        return create_ast_node<AssignmentExpression>(AssignmentOp::SubtractionAssignment, move(lhs), parse_expression(min_precedence, associativity));
     case TokenType::Asterisk:
     case TokenType::Asterisk:
         consume();
         consume();
-        return make<BinaryExpression>(BinaryOp::Asterisk, move(lhs), parse_expression(min_precedence, associativity));
+        return create_ast_node<BinaryExpression>(BinaryOp::Asterisk, move(lhs), parse_expression(min_precedence, associativity));
     case TokenType::AsteriskEquals:
     case TokenType::AsteriskEquals:
         consume();
         consume();
-        return make<AssignmentExpression>(AssignmentOp::MultiplicationAssignment, move(lhs), parse_expression(min_precedence, associativity));
+        return create_ast_node<AssignmentExpression>(AssignmentOp::MultiplicationAssignment, move(lhs), parse_expression(min_precedence, associativity));
     case TokenType::Slash:
     case TokenType::Slash:
         consume();
         consume();
-        return make<BinaryExpression>(BinaryOp::Slash, move(lhs), parse_expression(min_precedence, associativity));
+        return create_ast_node<BinaryExpression>(BinaryOp::Slash, move(lhs), parse_expression(min_precedence, associativity));
     case TokenType::SlashEquals:
     case TokenType::SlashEquals:
         consume();
         consume();
-        return make<AssignmentExpression>(AssignmentOp::DivisionAssignment, move(lhs), parse_expression(min_precedence, associativity));
+        return create_ast_node<AssignmentExpression>(AssignmentOp::DivisionAssignment, move(lhs), parse_expression(min_precedence, associativity));
     case TokenType::GreaterThan:
     case TokenType::GreaterThan:
         consume();
         consume();
-        return make<BinaryExpression>(BinaryOp::GreaterThan, move(lhs), parse_expression(min_precedence, associativity));
+        return create_ast_node<BinaryExpression>(BinaryOp::GreaterThan, move(lhs), parse_expression(min_precedence, associativity));
     case TokenType::GreaterThanEquals:
     case TokenType::GreaterThanEquals:
         consume();
         consume();
-        return make<BinaryExpression>(BinaryOp::GreaterThanEquals, move(lhs), parse_expression(min_precedence, associativity));
+        return create_ast_node<BinaryExpression>(BinaryOp::GreaterThanEquals, move(lhs), parse_expression(min_precedence, associativity));
     case TokenType::LessThan:
     case TokenType::LessThan:
         consume();
         consume();
-        return make<BinaryExpression>(BinaryOp::LessThan, move(lhs), parse_expression(min_precedence, associativity));
+        return create_ast_node<BinaryExpression>(BinaryOp::LessThan, move(lhs), parse_expression(min_precedence, associativity));
     case TokenType::LessThanEquals:
     case TokenType::LessThanEquals:
         consume();
         consume();
-        return make<BinaryExpression>(BinaryOp::LessThanEquals, move(lhs), parse_expression(min_precedence, associativity));
+        return create_ast_node<BinaryExpression>(BinaryOp::LessThanEquals, move(lhs), parse_expression(min_precedence, associativity));
     case TokenType::EqualsEqualsEquals:
     case TokenType::EqualsEqualsEquals:
         consume();
         consume();
-        return make<BinaryExpression>(BinaryOp::TypedEquals, move(lhs), parse_expression(min_precedence, associativity));
+        return create_ast_node<BinaryExpression>(BinaryOp::TypedEquals, move(lhs), parse_expression(min_precedence, associativity));
     case TokenType::ExclamationMarkEqualsEquals:
     case TokenType::ExclamationMarkEqualsEquals:
         consume();
         consume();
-        return make<BinaryExpression>(BinaryOp::TypedInequals, move(lhs), parse_expression(min_precedence, associativity));
+        return create_ast_node<BinaryExpression>(BinaryOp::TypedInequals, move(lhs), parse_expression(min_precedence, associativity));
     case TokenType::EqualsEquals:
     case TokenType::EqualsEquals:
         consume();
         consume();
-        return make<BinaryExpression>(BinaryOp::AbstractEquals, move(lhs), parse_expression(min_precedence, associativity));
+        return create_ast_node<BinaryExpression>(BinaryOp::AbstractEquals, move(lhs), parse_expression(min_precedence, associativity));
     case TokenType::ExclamationMarkEquals:
     case TokenType::ExclamationMarkEquals:
         consume();
         consume();
-        return make<BinaryExpression>(BinaryOp::AbstractInequals, move(lhs), parse_expression(min_precedence, associativity));
+        return create_ast_node<BinaryExpression>(BinaryOp::AbstractInequals, move(lhs), parse_expression(min_precedence, associativity));
     case TokenType::ParenOpen:
     case TokenType::ParenOpen:
         return parse_call_expression(move(lhs));
         return parse_call_expression(move(lhs));
     case TokenType::Equals:
     case TokenType::Equals:
         consume();
         consume();
-        return make<AssignmentExpression>(AssignmentOp::Assignment, move(lhs), parse_expression(min_precedence, associativity));
+        return create_ast_node<AssignmentExpression>(AssignmentOp::Assignment, move(lhs), parse_expression(min_precedence, associativity));
     case TokenType::Period:
     case TokenType::Period:
         consume();
         consume();
-        return make<MemberExpression>(move(lhs), parse_expression(min_precedence, associativity));
+        return create_ast_node<MemberExpression>(move(lhs), parse_expression(min_precedence, associativity));
     case TokenType::PlusPlus:
     case TokenType::PlusPlus:
         consume();
         consume();
-        return make<UpdateExpression>(UpdateOp::Increment, move(lhs));
+        return create_ast_node<UpdateExpression>(UpdateOp::Increment, move(lhs));
     case TokenType::MinusMinus:
     case TokenType::MinusMinus:
         consume();
         consume();
-        return make<UpdateExpression>(UpdateOp::Decrement, move(lhs));
+        return create_ast_node<UpdateExpression>(UpdateOp::Decrement, move(lhs));
     case TokenType::DoubleAmpersand:
     case TokenType::DoubleAmpersand:
         consume();
         consume();
-        return make<LogicalExpression>(LogicalOp::And, move(lhs), parse_expression(min_precedence, associativity));
+        return create_ast_node<LogicalExpression>(LogicalOp::And, move(lhs), parse_expression(min_precedence, associativity));
     case TokenType::DoublePipe:
     case TokenType::DoublePipe:
         consume();
         consume();
-        return make<LogicalExpression>(LogicalOp::Or, move(lhs), parse_expression(min_precedence, associativity));
+        return create_ast_node<LogicalExpression>(LogicalOp::Or, move(lhs), parse_expression(min_precedence, associativity));
     default:
     default:
         m_has_errors = true;
         m_has_errors = true;
         expected("secondary expression (missing switch case)");
         expected("secondary expression (missing switch case)");
         consume();
         consume();
-        return make<ErrorExpression>();
+        return create_ast_node<ErrorExpression>();
     }
     }
 }
 }
 
 
-NonnullOwnPtr<CallExpression> Parser::parse_call_expression(NonnullOwnPtr<Expression> lhs)
+NonnullRefPtr<CallExpression> Parser::parse_call_expression(NonnullRefPtr<Expression> lhs)
 {
 {
     consume(TokenType::ParenOpen);
     consume(TokenType::ParenOpen);
 
 
-    NonnullOwnPtrVector<Expression> arguments;
+    NonnullRefPtrVector<Expression> arguments;
 
 
     while (match_expression()) {
     while (match_expression()) {
         arguments.append(parse_expression(0));
         arguments.append(parse_expression(0));
@@ -386,21 +386,21 @@ NonnullOwnPtr<CallExpression> Parser::parse_call_expression(NonnullOwnPtr<Expres
 
 
     consume(TokenType::ParenClose);
     consume(TokenType::ParenClose);
 
 
-    return make<CallExpression>(move(lhs), move(arguments));
+    return create_ast_node<CallExpression>(move(lhs), move(arguments));
 }
 }
 
 
-NonnullOwnPtr<ReturnStatement> Parser::parse_return_statement()
+NonnullRefPtr<ReturnStatement> Parser::parse_return_statement()
 {
 {
     consume(TokenType::Return);
     consume(TokenType::Return);
     if (match_expression()) {
     if (match_expression()) {
-        return make<ReturnStatement>(parse_expression(0));
+        return create_ast_node<ReturnStatement>(parse_expression(0));
     }
     }
-    return make<ReturnStatement>(nullptr);
+    return create_ast_node<ReturnStatement>(nullptr);
 }
 }
 
 
-NonnullOwnPtr<BlockStatement> Parser::parse_block_statement()
+NonnullRefPtr<BlockStatement> Parser::parse_block_statement()
 {
 {
-    auto block = make<BlockStatement>();
+    auto block = create_ast_node<BlockStatement>();
     consume(TokenType::CurlyOpen);
     consume(TokenType::CurlyOpen);
     while (!done() && !match(TokenType::CurlyClose)) {
     while (!done() && !match(TokenType::CurlyClose)) {
         if (match(TokenType::Semicolon)) {
         if (match(TokenType::Semicolon)) {
@@ -416,7 +416,7 @@ NonnullOwnPtr<BlockStatement> Parser::parse_block_statement()
     return block;
     return block;
 }
 }
 
 
-NonnullOwnPtr<FunctionDeclaration> Parser::parse_function_declaration()
+NonnullRefPtr<FunctionDeclaration> Parser::parse_function_declaration()
 {
 {
     consume(TokenType::Function);
     consume(TokenType::Function);
     auto name = consume(TokenType::Identifier).value();
     auto name = consume(TokenType::Identifier).value();
@@ -432,10 +432,10 @@ NonnullOwnPtr<FunctionDeclaration> Parser::parse_function_declaration()
     }
     }
     consume(TokenType::ParenClose);
     consume(TokenType::ParenClose);
     auto body = parse_block_statement();
     auto body = parse_block_statement();
-    return make<FunctionDeclaration>(name, move(body), move(parameters));
+    return create_ast_node<FunctionDeclaration>(name, move(body), move(parameters));
 }
 }
 
 
-NonnullOwnPtr<VariableDeclaration> Parser::parse_variable_declaration()
+NonnullRefPtr<VariableDeclaration> Parser::parse_variable_declaration()
 {
 {
     DeclarationType declaration_type;
     DeclarationType declaration_type;
 
 
@@ -456,21 +456,21 @@ NonnullOwnPtr<VariableDeclaration> Parser::parse_variable_declaration()
         ASSERT_NOT_REACHED();
         ASSERT_NOT_REACHED();
     }
     }
     auto name = consume(TokenType::Identifier).value();
     auto name = consume(TokenType::Identifier).value();
-    OwnPtr<Expression> initializer;
+    RefPtr<Expression> initializer;
     if (match(TokenType::Equals)) {
     if (match(TokenType::Equals)) {
         consume();
         consume();
         initializer = parse_expression(0);
         initializer = parse_expression(0);
     }
     }
-    return make<VariableDeclaration>(make<Identifier>(name), move(initializer), declaration_type);
+    return create_ast_node<VariableDeclaration>(create_ast_node<Identifier>(name), move(initializer), declaration_type);
 }
 }
 
 
-NonnullOwnPtr<ForStatement> Parser::parse_for_statement()
+NonnullRefPtr<ForStatement> Parser::parse_for_statement()
 {
 {
     consume(TokenType::For);
     consume(TokenType::For);
 
 
     consume(TokenType::ParenOpen);
     consume(TokenType::ParenOpen);
 
 
-    OwnPtr<Statement> init = nullptr;
+    RefPtr<Statement> init;
     switch (m_current_token.type()) {
     switch (m_current_token.type()) {
     case TokenType::Semicolon:
     case TokenType::Semicolon:
         break;
         break;
@@ -481,7 +481,7 @@ NonnullOwnPtr<ForStatement> Parser::parse_for_statement()
 
 
     consume(TokenType::Semicolon);
     consume(TokenType::Semicolon);
 
 
-    OwnPtr<Expression> test = nullptr;
+    RefPtr<Expression> test;
     switch (m_current_token.type()) {
     switch (m_current_token.type()) {
     case TokenType::Semicolon:
     case TokenType::Semicolon:
         break;
         break;
@@ -492,7 +492,7 @@ NonnullOwnPtr<ForStatement> Parser::parse_for_statement()
 
 
     consume(TokenType::Semicolon);
     consume(TokenType::Semicolon);
 
 
-    OwnPtr<Expression> update = nullptr;
+    RefPtr<Expression> update;
     switch (m_current_token.type()) {
     switch (m_current_token.type()) {
     case TokenType::Semicolon:
     case TokenType::Semicolon:
         break;
         break;
@@ -505,7 +505,7 @@ NonnullOwnPtr<ForStatement> Parser::parse_for_statement()
 
 
     auto body = parse_block_statement();
     auto body = parse_block_statement();
 
 
-    return make<ForStatement>(move(init), move(test), move(update), move(body));
+    return create_ast_node<ForStatement>(move(init), move(test), move(update), move(body));
 }
 }
 
 
 bool Parser::match(TokenType type) const
 bool Parser::match(TokenType type) const

+ 14 - 14
Libraries/LibJS/Parser.h

@@ -28,7 +28,7 @@
 
 
 #include "AST.h"
 #include "AST.h"
 #include "Lexer.h"
 #include "Lexer.h"
-#include <AK/NonnullOwnPtr.h>
+#include <AK/NonnullRefPtr.h>
 
 
 namespace JS {
 namespace JS {
 
 
@@ -41,21 +41,21 @@ class Parser {
 public:
 public:
     explicit Parser(Lexer lexer);
     explicit Parser(Lexer lexer);
 
 
-    NonnullOwnPtr<Program> parse_program();
+    NonnullRefPtr<Program> parse_program();
 
 
-    NonnullOwnPtr<Statement> parse_statement();
-    NonnullOwnPtr<BlockStatement> parse_block_statement();
-    NonnullOwnPtr<ReturnStatement> parse_return_statement();
-    NonnullOwnPtr<FunctionDeclaration> parse_function_declaration();
-    NonnullOwnPtr<VariableDeclaration> parse_variable_declaration();
-    NonnullOwnPtr<ForStatement> parse_for_statement();
+    NonnullRefPtr<Statement> parse_statement();
+    NonnullRefPtr<BlockStatement> parse_block_statement();
+    NonnullRefPtr<ReturnStatement> parse_return_statement();
+    NonnullRefPtr<FunctionDeclaration> parse_function_declaration();
+    NonnullRefPtr<VariableDeclaration> parse_variable_declaration();
+    NonnullRefPtr<ForStatement> parse_for_statement();
 
 
-    NonnullOwnPtr<Expression> parse_expression(int min_precedence, Associativity associate = Associativity::Right);
-    NonnullOwnPtr<Expression> parse_primary_expression();
-    NonnullOwnPtr<Expression> parse_unary_prefixed_expression();
-    NonnullOwnPtr<ObjectExpression> parse_object_expression();
-    NonnullOwnPtr<Expression> parse_secondary_expression(NonnullOwnPtr<Expression>, int min_precedence, Associativity associate = Associativity::Right);
-    NonnullOwnPtr<CallExpression> parse_call_expression(NonnullOwnPtr<Expression>);
+    NonnullRefPtr<Expression> parse_expression(int min_precedence, Associativity associate = Associativity::Right);
+    NonnullRefPtr<Expression> parse_primary_expression();
+    NonnullRefPtr<Expression> parse_unary_prefixed_expression();
+    NonnullRefPtr<ObjectExpression> parse_object_expression();
+    NonnullRefPtr<Expression> parse_secondary_expression(NonnullRefPtr<Expression>, int min_precedence, Associativity associate = Associativity::Right);
+    NonnullRefPtr<CallExpression> parse_call_expression(NonnullRefPtr<Expression>);
 
 
     bool has_errors() const { return m_has_errors; }
     bool has_errors() const { return m_has_errors; }
 
 

+ 1 - 0
Libraries/LibJS/Runtime/ScriptFunction.cpp

@@ -24,6 +24,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
  */
 
 
+#include <LibJS/AST.h>
 #include <LibJS/Interpreter.h>
 #include <LibJS/Interpreter.h>
 #include <LibJS/Runtime/ScriptFunction.h>
 #include <LibJS/Runtime/ScriptFunction.h>
 #include <LibJS/Runtime/Value.h>
 #include <LibJS/Runtime/Value.h>

+ 1 - 1
Libraries/LibJS/Runtime/ScriptFunction.h

@@ -44,7 +44,7 @@ private:
     virtual bool is_script_function() const final { return true; }
     virtual bool is_script_function() const final { return true; }
     virtual const char* class_name() const override { return "ScriptFunction"; }
     virtual const char* class_name() const override { return "ScriptFunction"; }
 
 
-    const ScopeNode& m_body;
+    NonnullRefPtr<ScopeNode> m_body;
     const Vector<String> m_parameters;
     const Vector<String> m_parameters;
 };
 };