2020-03-07 18:42:11 +00:00
|
|
|
/*
|
2021-06-03 08:46:30 +00:00
|
|
|
* Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
|
2021-04-22 20:51:19 +00:00
|
|
|
* Copyright (c) 2020, Linus Groh <linusg@serenityos.org>
|
2020-03-07 18:42:11 +00:00
|
|
|
*
|
2021-04-22 08:24:48 +00:00
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
2020-03-07 18:42:11 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2020-03-23 15:46:41 +00:00
|
|
|
#include <AK/FlyString.h>
|
2020-03-21 00:29:00 +00:00
|
|
|
#include <AK/HashMap.h>
|
2020-03-18 10:23:53 +00:00
|
|
|
#include <AK/NonnullRefPtrVector.h>
|
2021-05-29 11:33:19 +00:00
|
|
|
#include <AK/OwnPtr.h>
|
2020-03-18 10:23:53 +00:00
|
|
|
#include <AK/RefPtr.h>
|
2020-03-07 18:42:11 +00:00
|
|
|
#include <AK/String.h>
|
2021-05-29 11:33:19 +00:00
|
|
|
#include <AK/Variant.h>
|
2020-03-12 11:22:13 +00:00
|
|
|
#include <AK/Vector.h>
|
2020-03-07 18:42:11 +00:00
|
|
|
#include <LibJS/Forward.h>
|
2020-04-06 15:08:23 +00:00
|
|
|
#include <LibJS/Runtime/PropertyName.h>
|
2020-03-16 13:20:30 +00:00
|
|
|
#include <LibJS/Runtime/Value.h>
|
2020-12-28 17:15:22 +00:00
|
|
|
#include <LibJS/SourceRange.h>
|
2020-03-07 18:42:11 +00:00
|
|
|
|
|
|
|
namespace JS {
|
|
|
|
|
2020-04-13 14:42:54 +00:00
|
|
|
class VariableDeclaration;
|
2020-06-04 12:48:36 +00:00
|
|
|
class FunctionDeclaration;
|
2021-05-29 11:33:19 +00:00
|
|
|
class Identifier;
|
2020-04-13 14:42:54 +00:00
|
|
|
|
2021-06-10 23:08:05 +00:00
|
|
|
enum class FunctionKind {
|
|
|
|
Generator,
|
|
|
|
Regular,
|
|
|
|
};
|
|
|
|
|
2020-03-18 10:23:53 +00:00
|
|
|
template<class T, class... Args>
|
|
|
|
static inline NonnullRefPtr<T>
|
2020-12-28 17:15:22 +00:00
|
|
|
create_ast_node(SourceRange range, Args&&... args)
|
2020-03-18 10:23:53 +00:00
|
|
|
{
|
2021-04-23 14:46:57 +00:00
|
|
|
return adopt_ref(*new T(range, forward<Args>(args)...));
|
2020-03-18 10:23:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
class ASTNode : public RefCounted<ASTNode> {
|
2020-03-07 18:42:11 +00:00
|
|
|
public:
|
2020-05-04 11:30:40 +00:00
|
|
|
virtual ~ASTNode() { }
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const = 0;
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const;
|
2020-03-07 18:42:11 +00:00
|
|
|
virtual void dump(int indent) const;
|
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
SourceRange const& source_range() const { return m_source_range; }
|
2020-12-28 17:15:22 +00:00
|
|
|
SourceRange& source_range() { return m_source_range; }
|
|
|
|
|
2021-01-17 08:21:15 +00:00
|
|
|
String class_name() const;
|
|
|
|
|
2021-06-13 09:23:23 +00:00
|
|
|
template<typename T>
|
|
|
|
bool fast_is() const = delete;
|
|
|
|
|
|
|
|
virtual bool is_new_expression() const { return false; }
|
|
|
|
virtual bool is_member_expression() const { return false; }
|
|
|
|
virtual bool is_super_expression() const { return false; }
|
|
|
|
virtual bool is_expression_statement() const { return false; }
|
|
|
|
virtual bool is_identifier() const { return false; }
|
|
|
|
virtual bool is_scope_node() const { return false; }
|
|
|
|
virtual bool is_program() const { return false; }
|
|
|
|
|
2020-03-07 18:42:11 +00:00
|
|
|
protected:
|
2020-12-28 17:15:22 +00:00
|
|
|
ASTNode(SourceRange source_range)
|
|
|
|
: m_source_range(move(source_range))
|
|
|
|
{
|
|
|
|
}
|
2020-03-07 18:42:11 +00:00
|
|
|
|
|
|
|
private:
|
2020-12-28 17:15:22 +00:00
|
|
|
SourceRange m_source_range;
|
2020-03-07 18:42:11 +00:00
|
|
|
};
|
|
|
|
|
2020-03-11 18:27:43 +00:00
|
|
|
class Statement : public ASTNode {
|
2020-05-28 18:09:19 +00:00
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
Statement(SourceRange source_range)
|
|
|
|
: ASTNode(move(source_range))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
FlyString const& label() const { return m_label; }
|
2020-05-28 18:09:19 +00:00
|
|
|
void set_label(FlyString string) { m_label = string; }
|
|
|
|
|
|
|
|
protected:
|
|
|
|
FlyString m_label;
|
2020-03-11 18:27:43 +00:00
|
|
|
};
|
|
|
|
|
2020-05-03 09:59:00 +00:00
|
|
|
class EmptyStatement final : public Statement {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
EmptyStatement(SourceRange source_range)
|
|
|
|
: Statement(move(source_range))
|
|
|
|
{
|
|
|
|
}
|
2021-03-16 08:12:34 +00:00
|
|
|
Value execute(Interpreter&, GlobalObject&) const override { return {}; }
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-05-03 09:59:00 +00:00
|
|
|
};
|
|
|
|
|
2020-03-11 18:27:43 +00:00
|
|
|
class ErrorStatement final : public Statement {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
ErrorStatement(SourceRange source_range)
|
|
|
|
: Statement(move(source_range))
|
|
|
|
{
|
|
|
|
}
|
2021-03-16 08:12:34 +00:00
|
|
|
Value execute(Interpreter&, GlobalObject&) const override { return {}; }
|
2020-03-11 18:27:43 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class ExpressionStatement final : public Statement {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
ExpressionStatement(SourceRange source_range, NonnullRefPtr<Expression> expression)
|
|
|
|
: Statement(move(source_range))
|
|
|
|
, m_expression(move(expression))
|
2020-03-11 18:27:43 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-11-01 21:49:25 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-03-11 18:27:43 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-11-01 21:49:25 +00:00
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
Expression const& expression() const { return m_expression; };
|
2020-03-11 18:27:43 +00:00
|
|
|
|
|
|
|
private:
|
2021-06-13 09:23:23 +00:00
|
|
|
virtual bool is_expression_statement() const override { return true; }
|
|
|
|
|
2020-03-18 10:23:53 +00:00
|
|
|
NonnullRefPtr<Expression> m_expression;
|
2020-03-11 18:27:43 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class ScopeNode : public Statement {
|
2020-03-07 18:42:11 +00:00
|
|
|
public:
|
|
|
|
template<typename T, typename... Args>
|
2020-12-28 17:15:22 +00:00
|
|
|
T& append(SourceRange range, Args&&... args)
|
2020-03-07 18:42:11 +00:00
|
|
|
{
|
2020-12-28 17:15:22 +00:00
|
|
|
auto child = create_ast_node<T>(range, forward<Args>(args)...);
|
2020-03-07 18:42:11 +00:00
|
|
|
m_children.append(move(child));
|
|
|
|
return static_cast<T&>(m_children.last());
|
|
|
|
}
|
2020-03-18 10:23:53 +00:00
|
|
|
void append(NonnullRefPtr<Statement> child)
|
2020-03-11 18:27:43 +00:00
|
|
|
{
|
|
|
|
m_children.append(move(child));
|
|
|
|
}
|
2020-03-07 18:42:11 +00:00
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
NonnullRefPtrVector<Statement> const& children() const { return m_children; }
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-03-07 18:42:11 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-03-07 18:42:11 +00:00
|
|
|
|
2020-04-13 14:42:54 +00:00
|
|
|
void add_variables(NonnullRefPtrVector<VariableDeclaration>);
|
2020-06-04 12:48:36 +00:00
|
|
|
void add_functions(NonnullRefPtrVector<FunctionDeclaration>);
|
2021-06-10 21:43:06 +00:00
|
|
|
NonnullRefPtrVector<VariableDeclaration> const& variables() const { return m_variables; }
|
|
|
|
NonnullRefPtrVector<FunctionDeclaration> const& functions() const { return m_functions; }
|
2020-05-28 05:22:08 +00:00
|
|
|
|
2020-03-07 18:42:11 +00:00
|
|
|
protected:
|
2020-12-28 17:15:22 +00:00
|
|
|
ScopeNode(SourceRange source_range)
|
|
|
|
: Statement(move(source_range))
|
|
|
|
{
|
|
|
|
}
|
2020-03-07 18:42:11 +00:00
|
|
|
|
|
|
|
private:
|
2021-06-13 09:23:23 +00:00
|
|
|
virtual bool is_scope_node() const final { return true; }
|
|
|
|
|
2020-03-18 10:23:53 +00:00
|
|
|
NonnullRefPtrVector<Statement> m_children;
|
2020-04-13 14:42:54 +00:00
|
|
|
NonnullRefPtrVector<VariableDeclaration> m_variables;
|
2020-06-04 12:48:36 +00:00
|
|
|
NonnullRefPtrVector<FunctionDeclaration> m_functions;
|
2020-03-07 18:42:11 +00:00
|
|
|
};
|
|
|
|
|
2020-09-16 18:13:32 +00:00
|
|
|
class Program final : public ScopeNode {
|
2020-03-07 18:42:11 +00:00
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
Program(SourceRange source_range)
|
|
|
|
: ScopeNode(move(source_range))
|
|
|
|
{
|
|
|
|
}
|
2020-03-07 18:42:11 +00:00
|
|
|
|
2020-10-04 00:02:43 +00:00
|
|
|
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; }
|
|
|
|
|
2020-03-07 18:42:11 +00:00
|
|
|
private:
|
2021-06-13 09:23:23 +00:00
|
|
|
virtual bool is_program() const override { return true; }
|
|
|
|
|
2020-10-04 00:02:43 +00:00
|
|
|
bool m_is_strict_mode { false };
|
2020-03-07 18:42:11 +00:00
|
|
|
};
|
|
|
|
|
2020-09-16 18:13:32 +00:00
|
|
|
class BlockStatement final : public ScopeNode {
|
2020-03-07 18:42:11 +00:00
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
BlockStatement(SourceRange source_range)
|
|
|
|
: ScopeNode(move(source_range))
|
|
|
|
{
|
|
|
|
}
|
2020-03-07 18:42:11 +00:00
|
|
|
};
|
|
|
|
|
2020-03-19 10:12:08 +00:00
|
|
|
class Expression : public ASTNode {
|
2020-04-27 10:10:16 +00:00
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
Expression(SourceRange source_range)
|
|
|
|
: ASTNode(move(source_range))
|
|
|
|
{
|
|
|
|
}
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Reference to_reference(Interpreter&, GlobalObject&) const;
|
2020-03-19 10:12:08 +00:00
|
|
|
};
|
|
|
|
|
2020-04-04 19:32:10 +00:00
|
|
|
class Declaration : public Statement {
|
2020-12-28 17:15:22 +00:00
|
|
|
public:
|
|
|
|
Declaration(SourceRange source_range)
|
|
|
|
: Statement(move(source_range))
|
|
|
|
{
|
|
|
|
}
|
2020-04-04 19:32:10 +00:00
|
|
|
};
|
|
|
|
|
2020-10-22 22:30:07 +00:00
|
|
|
class ErrorDeclaration final : public Declaration {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
ErrorDeclaration(SourceRange source_range)
|
|
|
|
: Declaration(move(source_range))
|
|
|
|
{
|
|
|
|
}
|
2021-03-16 08:12:34 +00:00
|
|
|
Value execute(Interpreter&, GlobalObject&) const override { return {}; }
|
2020-10-22 22:30:07 +00:00
|
|
|
};
|
|
|
|
|
2021-05-29 11:33:19 +00:00
|
|
|
struct BindingPattern : RefCounted<BindingPattern> {
|
|
|
|
struct BindingProperty {
|
|
|
|
RefPtr<Identifier> name;
|
|
|
|
RefPtr<Identifier> alias;
|
|
|
|
RefPtr<BindingPattern> pattern;
|
|
|
|
RefPtr<Expression> initializer;
|
|
|
|
bool is_rest { false };
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class Kind {
|
|
|
|
Array,
|
|
|
|
Object,
|
|
|
|
};
|
|
|
|
|
|
|
|
void dump(int indent) const;
|
|
|
|
template<typename C>
|
|
|
|
void for_each_assigned_name(C&& callback) const;
|
|
|
|
|
|
|
|
Vector<BindingProperty> properties;
|
|
|
|
Kind kind { Kind::Object };
|
|
|
|
};
|
|
|
|
|
2020-03-19 10:12:08 +00:00
|
|
|
class FunctionNode {
|
|
|
|
public:
|
2020-05-02 18:46:39 +00:00
|
|
|
struct Parameter {
|
2021-05-29 11:33:19 +00:00
|
|
|
Variant<FlyString, NonnullRefPtr<BindingPattern>> binding;
|
2020-05-02 18:46:39 +00:00
|
|
|
RefPtr<Expression> default_value;
|
2020-05-04 15:05:13 +00:00
|
|
|
bool is_rest { false };
|
2020-05-02 18:46:39 +00:00
|
|
|
};
|
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
FlyString const& name() const { return m_name; }
|
|
|
|
Statement const& body() const { return *m_body; }
|
|
|
|
Vector<Parameter> const& parameters() const { return m_parameters; };
|
2020-06-04 12:48:36 +00:00
|
|
|
i32 function_length() const { return m_function_length; }
|
2020-10-04 00:02:43 +00:00
|
|
|
bool is_strict_mode() const { return m_is_strict_mode; }
|
2021-06-11 08:45:49 +00:00
|
|
|
bool is_arrow_function() const { return m_is_arrow_function; }
|
2021-06-10 23:08:05 +00:00
|
|
|
FunctionKind kind() const { return m_kind; }
|
2020-03-19 10:12:08 +00:00
|
|
|
|
|
|
|
protected:
|
2021-06-10 23:08:05 +00:00
|
|
|
FunctionNode(FlyString const& name, NonnullRefPtr<Statement> body, Vector<Parameter> parameters, i32 function_length, NonnullRefPtrVector<VariableDeclaration> variables, FunctionKind kind, bool is_strict_mode, bool is_arrow_function)
|
2020-03-22 10:07:55 +00:00
|
|
|
: m_name(name)
|
2020-03-07 18:42:11 +00:00
|
|
|
, m_body(move(body))
|
2020-03-12 11:22:13 +00:00
|
|
|
, m_parameters(move(parameters))
|
2020-04-13 14:42:54 +00:00
|
|
|
, m_variables(move(variables))
|
2020-05-06 03:02:14 +00:00
|
|
|
, m_function_length(function_length)
|
2021-06-10 23:08:05 +00:00
|
|
|
, m_kind(kind)
|
2020-10-04 00:02:43 +00:00
|
|
|
, m_is_strict_mode(is_strict_mode)
|
2021-06-11 08:45:49 +00:00
|
|
|
, m_is_arrow_function(is_arrow_function)
|
2020-03-07 18:42:11 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
void dump(int indent, String const& class_name) const;
|
2020-03-19 10:12:08 +00:00
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
NonnullRefPtrVector<VariableDeclaration> const& variables() const { return m_variables; }
|
2020-04-13 14:42:54 +00:00
|
|
|
|
2021-03-22 11:44:07 +00:00
|
|
|
protected:
|
|
|
|
void set_name(FlyString name)
|
|
|
|
{
|
|
|
|
VERIFY(m_name.is_empty());
|
|
|
|
m_name = move(name);
|
|
|
|
}
|
|
|
|
|
2020-03-19 10:12:08 +00:00
|
|
|
private:
|
2020-03-22 10:07:55 +00:00
|
|
|
FlyString m_name;
|
2020-04-05 09:11:07 +00:00
|
|
|
NonnullRefPtr<Statement> m_body;
|
2021-06-10 21:43:06 +00:00
|
|
|
Vector<Parameter> const m_parameters;
|
2020-04-13 14:42:54 +00:00
|
|
|
NonnullRefPtrVector<VariableDeclaration> m_variables;
|
2020-05-06 03:02:14 +00:00
|
|
|
const i32 m_function_length;
|
2021-06-10 23:08:05 +00:00
|
|
|
FunctionKind m_kind;
|
2020-10-04 00:02:43 +00:00
|
|
|
bool m_is_strict_mode;
|
2021-06-11 08:45:49 +00:00
|
|
|
bool m_is_arrow_function { false };
|
2020-03-19 10:12:08 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class FunctionDeclaration final
|
2020-04-04 19:32:10 +00:00
|
|
|
: public Declaration
|
2020-03-19 10:12:08 +00:00
|
|
|
, public FunctionNode {
|
|
|
|
public:
|
2020-03-19 10:52:56 +00:00
|
|
|
static bool must_have_name() { return true; }
|
|
|
|
|
2021-06-10 23:08:05 +00:00
|
|
|
FunctionDeclaration(SourceRange source_range, FlyString const& name, NonnullRefPtr<Statement> body, Vector<Parameter> parameters, i32 function_length, NonnullRefPtrVector<VariableDeclaration> variables, FunctionKind kind, bool is_strict_mode = false)
|
2020-12-28 17:15:22 +00:00
|
|
|
: Declaration(move(source_range))
|
2021-06-10 23:08:05 +00:00
|
|
|
, FunctionNode(name, move(body), move(parameters), function_length, move(variables), kind, is_strict_mode, false)
|
2020-03-19 10:12:08 +00:00
|
|
|
{
|
|
|
|
}
|
2020-03-07 18:42:11 +00:00
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-03-07 18:42:11 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-03-07 18:42:11 +00:00
|
|
|
};
|
|
|
|
|
2020-05-26 17:52:03 +00:00
|
|
|
class FunctionExpression final
|
|
|
|
: public Expression
|
2020-03-19 10:12:08 +00:00
|
|
|
, public FunctionNode {
|
2020-03-07 18:42:11 +00:00
|
|
|
public:
|
2020-03-19 10:52:56 +00:00
|
|
|
static bool must_have_name() { return false; }
|
|
|
|
|
2021-06-10 23:08:05 +00:00
|
|
|
FunctionExpression(SourceRange source_range, FlyString const& name, NonnullRefPtr<Statement> body, Vector<Parameter> parameters, i32 function_length, NonnullRefPtrVector<VariableDeclaration> variables, FunctionKind kind, bool is_strict_mode, bool is_arrow_function = false)
|
2021-03-22 11:44:07 +00:00
|
|
|
: Expression(source_range)
|
2021-06-10 23:08:05 +00:00
|
|
|
, FunctionNode(name, move(body), move(parameters), function_length, move(variables), kind, is_strict_mode, is_arrow_function)
|
2020-03-19 10:12:08 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-03-19 10:12:08 +00:00
|
|
|
virtual void dump(int indent) const override;
|
|
|
|
|
2021-03-22 11:44:07 +00:00
|
|
|
void set_name_if_possible(FlyString new_name)
|
|
|
|
{
|
|
|
|
if (m_cannot_auto_rename)
|
|
|
|
return;
|
|
|
|
m_cannot_auto_rename = true;
|
|
|
|
if (name().is_empty())
|
|
|
|
set_name(move(new_name));
|
|
|
|
}
|
|
|
|
bool cannot_auto_rename() const { return m_cannot_auto_rename; }
|
|
|
|
void set_cannot_auto_rename() { m_cannot_auto_rename = true; }
|
|
|
|
|
2021-06-11 08:46:46 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
|
|
|
|
2020-03-19 10:12:08 +00:00
|
|
|
private:
|
2021-03-22 11:44:07 +00:00
|
|
|
bool m_cannot_auto_rename { false };
|
2020-03-07 18:42:11 +00:00
|
|
|
};
|
|
|
|
|
2020-03-11 18:27:43 +00:00
|
|
|
class ErrorExpression final : public Expression {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
explicit ErrorExpression(SourceRange source_range)
|
|
|
|
: Expression(move(source_range))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-03-16 08:12:34 +00:00
|
|
|
Value execute(Interpreter&, GlobalObject&) const override { return {}; }
|
2020-03-11 18:27:43 +00:00
|
|
|
};
|
|
|
|
|
2021-06-10 21:08:30 +00:00
|
|
|
class YieldExpression final : public Expression {
|
|
|
|
public:
|
2021-06-14 11:16:41 +00:00
|
|
|
explicit YieldExpression(SourceRange source_range, RefPtr<Expression> argument, bool is_yield_from)
|
2021-06-10 21:08:30 +00:00
|
|
|
: Expression(move(source_range))
|
|
|
|
, m_argument(move(argument))
|
2021-06-14 11:16:41 +00:00
|
|
|
, m_is_yield_from(is_yield_from)
|
2021-06-10 21:08:30 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
Expression const* argument() const { return m_argument; }
|
2021-06-14 11:16:41 +00:00
|
|
|
bool is_yield_from() const { return m_is_yield_from; }
|
2021-06-10 21:08:30 +00:00
|
|
|
|
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
|
|
|
virtual void dump(int indent) const override;
|
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
RefPtr<Expression> m_argument;
|
2021-06-14 11:16:41 +00:00
|
|
|
bool m_is_yield_from { false };
|
2021-06-10 21:08:30 +00:00
|
|
|
};
|
|
|
|
|
2020-09-16 18:13:32 +00:00
|
|
|
class ReturnStatement final : public Statement {
|
2020-03-07 18:42:11 +00:00
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
explicit ReturnStatement(SourceRange source_range, RefPtr<Expression> argument)
|
|
|
|
: Statement(move(source_range))
|
|
|
|
, m_argument(move(argument))
|
2020-03-07 18:42:11 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
Expression const* argument() const { return m_argument; }
|
2020-03-07 18:42:11 +00:00
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-03-07 18:42:11 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-03-07 18:42:11 +00:00
|
|
|
|
|
|
|
private:
|
2020-03-18 10:23:53 +00:00
|
|
|
RefPtr<Expression> m_argument;
|
2020-03-07 18:42:11 +00:00
|
|
|
};
|
|
|
|
|
2020-09-16 18:13:32 +00:00
|
|
|
class IfStatement final : public Statement {
|
2020-03-08 05:58:58 +00:00
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
IfStatement(SourceRange source_range, NonnullRefPtr<Expression> predicate, NonnullRefPtr<Statement> consequent, RefPtr<Statement> alternate)
|
|
|
|
: Statement(move(source_range))
|
|
|
|
, m_predicate(move(predicate))
|
2020-03-08 05:58:58 +00:00
|
|
|
, m_consequent(move(consequent))
|
|
|
|
, m_alternate(move(alternate))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
Expression const& predicate() const { return *m_predicate; }
|
|
|
|
Statement const& consequent() const { return *m_consequent; }
|
|
|
|
Statement const* alternate() const { return m_alternate; }
|
2020-03-08 05:58:58 +00:00
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-03-08 05:58:58 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-03-08 05:58:58 +00:00
|
|
|
|
|
|
|
private:
|
2020-03-18 10:23:53 +00:00
|
|
|
NonnullRefPtr<Expression> m_predicate;
|
2020-03-23 15:46:41 +00:00
|
|
|
NonnullRefPtr<Statement> m_consequent;
|
|
|
|
RefPtr<Statement> m_alternate;
|
2020-03-08 05:58:58 +00:00
|
|
|
};
|
|
|
|
|
2020-09-16 18:13:32 +00:00
|
|
|
class WhileStatement final : public Statement {
|
2020-03-08 19:22:21 +00:00
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
WhileStatement(SourceRange source_range, NonnullRefPtr<Expression> test, NonnullRefPtr<Statement> body)
|
|
|
|
: Statement(move(source_range))
|
|
|
|
, m_test(move(test))
|
2020-03-08 19:22:21 +00:00
|
|
|
, m_body(move(body))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
Expression const& test() const { return *m_test; }
|
|
|
|
Statement const& body() const { return *m_body; }
|
2020-03-08 19:22:21 +00:00
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-03-08 19:22:21 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-03-08 19:22:21 +00:00
|
|
|
|
|
|
|
private:
|
2020-04-04 19:21:19 +00:00
|
|
|
NonnullRefPtr<Expression> m_test;
|
2020-04-05 09:11:07 +00:00
|
|
|
NonnullRefPtr<Statement> m_body;
|
2020-03-08 19:22:21 +00:00
|
|
|
};
|
|
|
|
|
2020-09-16 18:13:32 +00:00
|
|
|
class DoWhileStatement final : public Statement {
|
2020-04-04 19:29:23 +00:00
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
DoWhileStatement(SourceRange source_range, NonnullRefPtr<Expression> test, NonnullRefPtr<Statement> body)
|
|
|
|
: Statement(move(source_range))
|
|
|
|
, m_test(move(test))
|
2020-04-04 19:29:23 +00:00
|
|
|
, m_body(move(body))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
Expression const& test() const { return *m_test; }
|
|
|
|
Statement const& body() const { return *m_body; }
|
2020-04-04 19:29:23 +00:00
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-04-04 19:29:23 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-04-04 19:29:23 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
NonnullRefPtr<Expression> m_test;
|
2020-04-05 09:11:07 +00:00
|
|
|
NonnullRefPtr<Statement> m_body;
|
2020-04-04 19:29:23 +00:00
|
|
|
};
|
|
|
|
|
2020-11-28 14:05:57 +00:00
|
|
|
class WithStatement final : public Statement {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
WithStatement(SourceRange source_range, NonnullRefPtr<Expression> object, NonnullRefPtr<Statement> body)
|
|
|
|
: Statement(move(source_range))
|
|
|
|
, m_object(move(object))
|
2020-11-28 14:05:57 +00:00
|
|
|
, m_body(move(body))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
Expression const& object() const { return *m_object; }
|
|
|
|
Statement const& body() const { return *m_body; }
|
2020-11-28 14:05:57 +00:00
|
|
|
|
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
|
|
|
virtual void dump(int indent) const override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
NonnullRefPtr<Expression> m_object;
|
|
|
|
NonnullRefPtr<Statement> m_body;
|
|
|
|
};
|
|
|
|
|
2020-09-16 18:13:32 +00:00
|
|
|
class ForStatement final : public Statement {
|
2020-03-12 12:12:12 +00:00
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
ForStatement(SourceRange source_range, RefPtr<ASTNode> init, RefPtr<Expression> test, RefPtr<Expression> update, NonnullRefPtr<Statement> body)
|
|
|
|
: Statement(move(source_range))
|
|
|
|
, m_init(move(init))
|
2020-03-12 12:12:12 +00:00
|
|
|
, m_test(move(test))
|
|
|
|
, m_update(move(update))
|
|
|
|
, m_body(move(body))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
ASTNode const* init() const { return m_init; }
|
|
|
|
Expression const* test() const { return m_test; }
|
|
|
|
Expression const* update() const { return m_update; }
|
|
|
|
Statement const& body() const { return *m_body; }
|
2020-03-12 12:12:12 +00:00
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-03-12 12:12:12 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-03-12 12:12:12 +00:00
|
|
|
|
|
|
|
private:
|
2020-03-23 18:08:32 +00:00
|
|
|
RefPtr<ASTNode> m_init;
|
2020-03-18 10:23:53 +00:00
|
|
|
RefPtr<Expression> m_test;
|
|
|
|
RefPtr<Expression> m_update;
|
2020-04-05 09:11:07 +00:00
|
|
|
NonnullRefPtr<Statement> m_body;
|
2020-03-12 12:12:12 +00:00
|
|
|
};
|
|
|
|
|
2020-09-16 18:13:32 +00:00
|
|
|
class ForInStatement final : public Statement {
|
2020-04-21 18:21:26 +00:00
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
ForInStatement(SourceRange source_range, NonnullRefPtr<ASTNode> lhs, NonnullRefPtr<Expression> rhs, NonnullRefPtr<Statement> body)
|
|
|
|
: Statement(move(source_range))
|
|
|
|
, m_lhs(move(lhs))
|
2020-04-21 18:21:26 +00:00
|
|
|
, m_rhs(move(rhs))
|
|
|
|
, m_body(move(body))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
ASTNode const& lhs() const { return *m_lhs; }
|
|
|
|
Expression const& rhs() const { return *m_rhs; }
|
|
|
|
Statement const& body() const { return *m_body; }
|
2020-04-21 18:21:26 +00:00
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-04-21 18:21:26 +00:00
|
|
|
virtual void dump(int indent) const override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
NonnullRefPtr<ASTNode> m_lhs;
|
|
|
|
NonnullRefPtr<Expression> m_rhs;
|
|
|
|
NonnullRefPtr<Statement> m_body;
|
|
|
|
};
|
|
|
|
|
2020-09-16 18:13:32 +00:00
|
|
|
class ForOfStatement final : public Statement {
|
2020-04-21 18:21:26 +00:00
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
ForOfStatement(SourceRange source_range, NonnullRefPtr<ASTNode> lhs, NonnullRefPtr<Expression> rhs, NonnullRefPtr<Statement> body)
|
|
|
|
: Statement(move(source_range))
|
|
|
|
, m_lhs(move(lhs))
|
2020-04-21 18:21:26 +00:00
|
|
|
, m_rhs(move(rhs))
|
|
|
|
, m_body(move(body))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
ASTNode const& lhs() const { return *m_lhs; }
|
|
|
|
Expression const& rhs() const { return *m_rhs; }
|
|
|
|
Statement const& body() const { return *m_body; }
|
2020-04-21 18:21:26 +00:00
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-04-21 18:21:26 +00:00
|
|
|
virtual void dump(int indent) const override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
NonnullRefPtr<ASTNode> m_lhs;
|
|
|
|
NonnullRefPtr<Expression> m_rhs;
|
|
|
|
NonnullRefPtr<Statement> m_body;
|
|
|
|
};
|
|
|
|
|
2020-03-07 18:42:11 +00:00
|
|
|
enum class BinaryOp {
|
2020-04-05 11:56:53 +00:00
|
|
|
Addition,
|
|
|
|
Subtraction,
|
|
|
|
Multiplication,
|
|
|
|
Division,
|
2020-04-04 19:17:34 +00:00
|
|
|
Modulo,
|
2020-04-05 12:40:00 +00:00
|
|
|
Exponentiation,
|
2020-03-08 05:53:02 +00:00
|
|
|
TypedEquals,
|
2020-03-08 21:27:18 +00:00
|
|
|
TypedInequals,
|
2020-03-15 22:23:38 +00:00
|
|
|
AbstractEquals,
|
|
|
|
AbstractInequals,
|
2020-03-10 10:35:05 +00:00
|
|
|
GreaterThan,
|
2020-03-12 12:07:08 +00:00
|
|
|
GreaterThanEquals,
|
2020-03-10 10:35:05 +00:00
|
|
|
LessThan,
|
2020-03-12 12:07:08 +00:00
|
|
|
LessThanEquals,
|
2020-03-10 10:35:05 +00:00
|
|
|
BitwiseAnd,
|
|
|
|
BitwiseOr,
|
|
|
|
BitwiseXor,
|
|
|
|
LeftShift,
|
|
|
|
RightShift,
|
2020-04-23 14:43:10 +00:00
|
|
|
UnsignedRightShift,
|
2020-04-23 15:06:01 +00:00
|
|
|
In,
|
2020-03-28 15:56:54 +00:00
|
|
|
InstanceOf,
|
2020-03-07 18:42:11 +00:00
|
|
|
};
|
|
|
|
|
2020-09-16 18:13:32 +00:00
|
|
|
class BinaryExpression final : public Expression {
|
2020-03-07 18:42:11 +00:00
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
BinaryExpression(SourceRange source_range, BinaryOp op, NonnullRefPtr<Expression> lhs, NonnullRefPtr<Expression> rhs)
|
|
|
|
: Expression(move(source_range))
|
|
|
|
, m_op(op)
|
2020-03-07 18:42:11 +00:00
|
|
|
, m_lhs(move(lhs))
|
|
|
|
, m_rhs(move(rhs))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-03-07 18:42:11 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-03-07 18:42:11 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
BinaryOp m_op;
|
2020-03-18 10:23:53 +00:00
|
|
|
NonnullRefPtr<Expression> m_lhs;
|
|
|
|
NonnullRefPtr<Expression> m_rhs;
|
2020-03-07 18:42:11 +00:00
|
|
|
};
|
|
|
|
|
2020-03-08 05:55:44 +00:00
|
|
|
enum class LogicalOp {
|
|
|
|
And,
|
|
|
|
Or,
|
2020-04-17 23:49:11 +00:00
|
|
|
NullishCoalescing,
|
2020-03-08 05:55:44 +00:00
|
|
|
};
|
|
|
|
|
2020-09-16 18:13:32 +00:00
|
|
|
class LogicalExpression final : public Expression {
|
2020-03-08 05:55:44 +00:00
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
LogicalExpression(SourceRange source_range, LogicalOp op, NonnullRefPtr<Expression> lhs, NonnullRefPtr<Expression> rhs)
|
|
|
|
: Expression(move(source_range))
|
|
|
|
, m_op(op)
|
2020-03-08 05:55:44 +00:00
|
|
|
, m_lhs(move(lhs))
|
|
|
|
, m_rhs(move(rhs))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-03-08 05:55:44 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-03-08 05:55:44 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
LogicalOp m_op;
|
2020-03-18 10:23:53 +00:00
|
|
|
NonnullRefPtr<Expression> m_lhs;
|
|
|
|
NonnullRefPtr<Expression> m_rhs;
|
2020-03-08 05:55:44 +00:00
|
|
|
};
|
|
|
|
|
2020-03-08 21:27:18 +00:00
|
|
|
enum class UnaryOp {
|
2020-03-14 18:43:35 +00:00
|
|
|
BitwiseNot,
|
2020-03-09 17:04:44 +00:00
|
|
|
Not,
|
2020-04-02 16:58:39 +00:00
|
|
|
Plus,
|
|
|
|
Minus,
|
2020-03-17 19:33:32 +00:00
|
|
|
Typeof,
|
2020-04-15 16:55:03 +00:00
|
|
|
Void,
|
2020-04-26 11:53:40 +00:00
|
|
|
Delete,
|
2020-03-08 21:27:18 +00:00
|
|
|
};
|
|
|
|
|
2020-09-16 18:13:32 +00:00
|
|
|
class UnaryExpression final : public Expression {
|
2020-03-08 21:27:18 +00:00
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
UnaryExpression(SourceRange source_range, UnaryOp op, NonnullRefPtr<Expression> lhs)
|
|
|
|
: Expression(move(source_range))
|
|
|
|
, m_op(op)
|
2020-03-08 21:27:18 +00:00
|
|
|
, m_lhs(move(lhs))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-03-08 21:27:18 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-03-08 21:27:18 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
UnaryOp m_op;
|
2020-03-18 10:23:53 +00:00
|
|
|
NonnullRefPtr<Expression> m_lhs;
|
2020-03-08 21:27:18 +00:00
|
|
|
};
|
|
|
|
|
2020-04-07 13:11:05 +00:00
|
|
|
class SequenceExpression final : public Expression {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
SequenceExpression(SourceRange source_range, NonnullRefPtrVector<Expression> expressions)
|
|
|
|
: Expression(move(source_range))
|
|
|
|
, m_expressions(move(expressions))
|
2020-04-07 13:11:05 +00:00
|
|
|
{
|
2021-03-16 21:03:31 +00:00
|
|
|
VERIFY(m_expressions.size() >= 2);
|
2020-04-07 13:11:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
virtual void dump(int indent) const override;
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-04-07 13:11:05 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
NonnullRefPtrVector<Expression> m_expressions;
|
|
|
|
};
|
|
|
|
|
2020-03-07 18:42:11 +00:00
|
|
|
class Literal : public Expression {
|
2020-03-12 11:19:11 +00:00
|
|
|
protected:
|
2020-12-28 17:15:22 +00:00
|
|
|
explicit Literal(SourceRange source_range)
|
|
|
|
: Expression(move(source_range))
|
|
|
|
{
|
|
|
|
}
|
2020-03-12 11:19:11 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class BooleanLiteral final : public Literal {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
explicit BooleanLiteral(SourceRange source_range, bool value)
|
|
|
|
: Literal(move(source_range))
|
|
|
|
, m_value(value)
|
2020-03-12 11:19:11 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-03-12 11:19:11 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-03-12 11:19:11 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
bool m_value { false };
|
|
|
|
};
|
|
|
|
|
|
|
|
class NumericLiteral final : public Literal {
|
2020-03-07 18:42:11 +00:00
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
explicit NumericLiteral(SourceRange source_range, double value)
|
2021-03-21 17:03:00 +00:00
|
|
|
: Literal(source_range)
|
2020-12-28 17:15:22 +00:00
|
|
|
, m_value(value)
|
2020-03-12 11:19:11 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-03-12 11:19:11 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-03-12 11:19:11 +00:00
|
|
|
|
|
|
|
private:
|
2021-03-21 17:03:00 +00:00
|
|
|
Value m_value;
|
2020-03-12 11:19:11 +00:00
|
|
|
};
|
|
|
|
|
2020-06-06 00:14:10 +00:00
|
|
|
class BigIntLiteral final : public Literal {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
explicit BigIntLiteral(SourceRange source_range, String value)
|
|
|
|
: Literal(move(source_range))
|
|
|
|
, m_value(move(value))
|
2020-06-06 00:14:10 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-06-06 00:14:10 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-06-06 00:14:10 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
String m_value;
|
|
|
|
};
|
|
|
|
|
2020-03-12 11:19:11 +00:00
|
|
|
class StringLiteral final : public Literal {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
explicit StringLiteral(SourceRange source_range, String value, bool is_use_strict_directive = false)
|
|
|
|
: Literal(move(source_range))
|
|
|
|
, m_value(move(value))
|
2020-11-01 21:49:25 +00:00
|
|
|
, m_is_use_strict_directive(is_use_strict_directive)
|
2020-03-07 18:42:11 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-03-07 18:42:11 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-11-01 21:49:25 +00:00
|
|
|
|
|
|
|
StringView value() const { return m_value; }
|
|
|
|
bool is_use_strict_directive() const { return m_is_use_strict_directive; };
|
2020-03-07 18:42:11 +00:00
|
|
|
|
|
|
|
private:
|
2020-03-12 11:19:11 +00:00
|
|
|
String m_value;
|
2020-11-01 21:49:25 +00:00
|
|
|
bool m_is_use_strict_directive;
|
2020-03-07 18:42:11 +00:00
|
|
|
};
|
|
|
|
|
2020-03-15 21:32:34 +00:00
|
|
|
class NullLiteral final : public Literal {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
explicit NullLiteral(SourceRange source_range)
|
|
|
|
: Literal(move(source_range))
|
|
|
|
{
|
|
|
|
}
|
2020-03-15 21:32:34 +00:00
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-03-15 21:32:34 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-03-15 21:32:34 +00:00
|
|
|
};
|
|
|
|
|
2020-06-03 23:05:49 +00:00
|
|
|
class RegExpLiteral final : public Literal {
|
|
|
|
public:
|
2021-05-10 10:56:08 +00:00
|
|
|
explicit RegExpLiteral(SourceRange source_range, String pattern, String flags)
|
2020-12-28 17:15:22 +00:00
|
|
|
: Literal(move(source_range))
|
2021-05-10 10:56:08 +00:00
|
|
|
, m_pattern(move(pattern))
|
|
|
|
, m_flags(move(flags))
|
2020-06-03 23:05:49 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-06-03 23:05:49 +00:00
|
|
|
virtual void dump(int indent) const override;
|
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
String const& pattern() const { return m_pattern; }
|
|
|
|
String const& flags() const { return m_flags; }
|
2020-06-03 23:05:49 +00:00
|
|
|
|
|
|
|
private:
|
2021-05-10 10:56:08 +00:00
|
|
|
String m_pattern;
|
2020-06-03 23:05:49 +00:00
|
|
|
String m_flags;
|
|
|
|
};
|
|
|
|
|
2020-03-10 10:48:49 +00:00
|
|
|
class Identifier final : public Expression {
|
2020-03-09 20:13:55 +00:00
|
|
|
public:
|
2021-06-14 07:30:43 +00:00
|
|
|
explicit Identifier(SourceRange source_range, FlyString string, Optional<size_t> argument_index = {})
|
|
|
|
: Expression(source_range)
|
|
|
|
, m_string(move(string))
|
|
|
|
, m_argument_index(move(argument_index))
|
2020-03-09 20:13:55 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
FlyString const& string() const { return m_string; }
|
2021-06-14 07:30:43 +00:00
|
|
|
Optional<size_t> const& argument_index() const { return m_argument_index; }
|
2020-03-09 20:13:55 +00:00
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-03-09 20:13:55 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Reference to_reference(Interpreter&, GlobalObject&) const override;
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-03-09 20:13:55 +00:00
|
|
|
|
|
|
|
private:
|
2021-06-13 09:23:23 +00:00
|
|
|
virtual bool is_identifier() const override { return true; }
|
|
|
|
|
2020-03-22 10:07:55 +00:00
|
|
|
FlyString m_string;
|
2021-06-14 07:30:43 +00:00
|
|
|
Optional<size_t> m_argument_index;
|
2020-03-09 20:13:55 +00:00
|
|
|
};
|
|
|
|
|
2020-06-08 18:31:21 +00:00
|
|
|
class ClassMethod final : public ASTNode {
|
|
|
|
public:
|
|
|
|
enum class Kind {
|
|
|
|
Method,
|
|
|
|
Getter,
|
|
|
|
Setter,
|
|
|
|
};
|
|
|
|
|
2020-12-28 17:15:22 +00:00
|
|
|
ClassMethod(SourceRange source_range, NonnullRefPtr<Expression> key, NonnullRefPtr<FunctionExpression> function, Kind kind, bool is_static)
|
|
|
|
: ASTNode(move(source_range))
|
|
|
|
, m_key(move(key))
|
2020-06-08 18:31:21 +00:00
|
|
|
, m_function(move(function))
|
|
|
|
, m_kind(kind)
|
|
|
|
, m_is_static(is_static)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
Expression const& key() const { return *m_key; }
|
2020-06-08 18:31:21 +00:00
|
|
|
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:
|
|
|
|
NonnullRefPtr<Expression> m_key;
|
|
|
|
NonnullRefPtr<FunctionExpression> m_function;
|
|
|
|
Kind m_kind;
|
|
|
|
bool m_is_static;
|
|
|
|
};
|
|
|
|
|
|
|
|
class SuperExpression final : public Expression {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
SuperExpression(SourceRange source_range)
|
|
|
|
: Expression(move(source_range))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-06-08 18:31:21 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
|
|
|
virtual void dump(int indent) const override;
|
2021-06-13 09:23:23 +00:00
|
|
|
|
|
|
|
virtual bool is_super_expression() const override { return true; }
|
2020-06-08 18:31:21 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class ClassExpression final : public Expression {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
ClassExpression(SourceRange source_range, String name, RefPtr<FunctionExpression> constructor, RefPtr<Expression> super_class, NonnullRefPtrVector<ClassMethod> methods)
|
|
|
|
: Expression(move(source_range))
|
|
|
|
, m_name(move(name))
|
2020-06-08 18:31:21 +00:00
|
|
|
, 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:
|
|
|
|
String m_name;
|
|
|
|
RefPtr<FunctionExpression> m_constructor;
|
|
|
|
RefPtr<Expression> m_super_class;
|
|
|
|
NonnullRefPtrVector<ClassMethod> m_methods;
|
|
|
|
};
|
|
|
|
|
|
|
|
class ClassDeclaration final : public Declaration {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
ClassDeclaration(SourceRange source_range, NonnullRefPtr<ClassExpression> class_expression)
|
|
|
|
: Declaration(move(source_range))
|
|
|
|
, m_class_expression(move(class_expression))
|
2020-06-08 18:31:21 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
|
|
|
virtual void dump(int indent) const override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
NonnullRefPtr<ClassExpression> m_class_expression;
|
|
|
|
};
|
|
|
|
|
2020-04-27 06:05:37 +00:00
|
|
|
class SpreadExpression final : public Expression {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
explicit SpreadExpression(SourceRange source_range, NonnullRefPtr<Expression> target)
|
|
|
|
: Expression(move(source_range))
|
|
|
|
, m_target(target)
|
2020-04-27 06:05:37 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-04-27 06:05:37 +00:00
|
|
|
virtual void dump(int indent) const override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
NonnullRefPtr<Expression> m_target;
|
|
|
|
};
|
|
|
|
|
2020-04-12 22:42:14 +00:00
|
|
|
class ThisExpression final : public Expression {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
ThisExpression(SourceRange source_range)
|
|
|
|
: Expression(move(source_range))
|
|
|
|
{
|
|
|
|
}
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-04-12 22:42:14 +00:00
|
|
|
virtual void dump(int indent) const override;
|
|
|
|
};
|
|
|
|
|
2020-03-07 18:42:11 +00:00
|
|
|
class CallExpression : public Expression {
|
|
|
|
public:
|
2020-05-06 05:36:24 +00:00
|
|
|
struct Argument {
|
|
|
|
NonnullRefPtr<Expression> value;
|
|
|
|
bool is_spread;
|
|
|
|
};
|
|
|
|
|
2020-12-28 17:15:22 +00:00
|
|
|
CallExpression(SourceRange source_range, NonnullRefPtr<Expression> callee, Vector<Argument> arguments = {})
|
|
|
|
: Expression(move(source_range))
|
|
|
|
, m_callee(move(callee))
|
2020-03-12 11:22:13 +00:00
|
|
|
, m_arguments(move(arguments))
|
2020-03-07 18:42:11 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-03-07 18:42:11 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-03-07 18:42:11 +00:00
|
|
|
|
|
|
|
private:
|
2020-04-01 16:51:27 +00:00
|
|
|
struct ThisAndCallee {
|
|
|
|
Value this_value;
|
|
|
|
Value callee;
|
|
|
|
};
|
2020-06-08 18:57:54 +00:00
|
|
|
ThisAndCallee compute_this_and_callee(Interpreter&, GlobalObject&) const;
|
2020-04-01 16:51:27 +00:00
|
|
|
|
2020-03-18 10:23:53 +00:00
|
|
|
NonnullRefPtr<Expression> m_callee;
|
2021-06-10 21:43:06 +00:00
|
|
|
Vector<Argument> const m_arguments;
|
2020-03-07 18:42:11 +00:00
|
|
|
};
|
|
|
|
|
2020-03-28 15:33:52 +00:00
|
|
|
class NewExpression final : public CallExpression {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
NewExpression(SourceRange source_range, NonnullRefPtr<Expression> callee, Vector<Argument> arguments = {})
|
|
|
|
: CallExpression(move(source_range), move(callee), move(arguments))
|
2020-03-28 15:33:52 +00:00
|
|
|
{
|
|
|
|
}
|
2021-06-13 09:23:23 +00:00
|
|
|
|
|
|
|
virtual bool is_new_expression() const override { return true; }
|
2020-03-28 15:33:52 +00:00
|
|
|
};
|
|
|
|
|
2020-03-09 20:13:55 +00:00
|
|
|
enum class AssignmentOp {
|
2020-03-12 12:54:56 +00:00
|
|
|
Assignment,
|
|
|
|
AdditionAssignment,
|
|
|
|
SubtractionAssignment,
|
|
|
|
MultiplicationAssignment,
|
|
|
|
DivisionAssignment,
|
2020-05-04 22:07:05 +00:00
|
|
|
ModuloAssignment,
|
2020-05-04 22:03:35 +00:00
|
|
|
ExponentiationAssignment,
|
2020-05-04 21:34:45 +00:00
|
|
|
BitwiseAndAssignment,
|
|
|
|
BitwiseOrAssignment,
|
|
|
|
BitwiseXorAssignment,
|
2020-04-23 12:36:14 +00:00
|
|
|
LeftShiftAssignment,
|
2020-04-23 12:45:19 +00:00
|
|
|
RightShiftAssignment,
|
2020-04-23 14:43:10 +00:00
|
|
|
UnsignedRightShiftAssignment,
|
2020-10-05 15:49:43 +00:00
|
|
|
AndAssignment,
|
|
|
|
OrAssignment,
|
|
|
|
NullishAssignment,
|
2020-03-09 20:13:55 +00:00
|
|
|
};
|
|
|
|
|
2020-09-16 18:13:32 +00:00
|
|
|
class AssignmentExpression final : public Expression {
|
2020-03-09 20:13:55 +00:00
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
AssignmentExpression(SourceRange source_range, AssignmentOp op, NonnullRefPtr<Expression> lhs, NonnullRefPtr<Expression> rhs)
|
|
|
|
: Expression(move(source_range))
|
|
|
|
, m_op(op)
|
2020-03-09 20:13:55 +00:00
|
|
|
, m_lhs(move(lhs))
|
|
|
|
, m_rhs(move(rhs))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-03-09 20:13:55 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-03-09 20:13:55 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
AssignmentOp m_op;
|
2020-04-27 10:56:09 +00:00
|
|
|
NonnullRefPtr<Expression> m_lhs;
|
2020-03-18 10:23:53 +00:00
|
|
|
NonnullRefPtr<Expression> m_rhs;
|
2020-03-09 20:13:55 +00:00
|
|
|
};
|
|
|
|
|
2020-03-12 11:45:45 +00:00
|
|
|
enum class UpdateOp {
|
|
|
|
Increment,
|
|
|
|
Decrement,
|
|
|
|
};
|
|
|
|
|
2020-09-16 18:13:32 +00:00
|
|
|
class UpdateExpression final : public Expression {
|
2020-03-12 11:45:45 +00:00
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
UpdateExpression(SourceRange source_range, UpdateOp op, NonnullRefPtr<Expression> argument, bool prefixed = false)
|
|
|
|
: Expression(move(source_range))
|
|
|
|
, m_op(op)
|
2020-03-12 11:45:45 +00:00
|
|
|
, m_argument(move(argument))
|
2020-03-14 18:44:57 +00:00
|
|
|
, m_prefixed(prefixed)
|
2020-03-12 11:45:45 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-03-12 11:45:45 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2021-06-09 09:40:38 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-03-12 11:45:45 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
UpdateOp m_op;
|
2020-04-05 09:11:07 +00:00
|
|
|
NonnullRefPtr<Expression> m_argument;
|
2020-03-14 18:44:57 +00:00
|
|
|
bool m_prefixed;
|
2020-03-12 11:45:45 +00:00
|
|
|
};
|
|
|
|
|
2020-04-08 09:59:18 +00:00
|
|
|
enum class DeclarationKind {
|
2020-03-11 19:09:20 +00:00
|
|
|
Var,
|
|
|
|
Let,
|
2020-03-12 12:24:34 +00:00
|
|
|
Const,
|
2020-03-11 19:09:20 +00:00
|
|
|
};
|
|
|
|
|
2020-04-04 19:46:25 +00:00
|
|
|
class VariableDeclarator final : public ASTNode {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
VariableDeclarator(SourceRange source_range, NonnullRefPtr<Identifier> id)
|
|
|
|
: ASTNode(move(source_range))
|
2021-05-29 11:33:19 +00:00
|
|
|
, m_target(move(id))
|
2020-04-21 18:21:26 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-05-29 11:33:19 +00:00
|
|
|
VariableDeclarator(SourceRange source_range, NonnullRefPtr<Identifier> target, RefPtr<Expression> init)
|
2020-12-28 17:15:22 +00:00
|
|
|
: ASTNode(move(source_range))
|
2021-05-29 11:33:19 +00:00
|
|
|
, m_target(move(target))
|
2020-04-04 19:46:25 +00:00
|
|
|
, m_init(move(init))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-05-29 11:33:19 +00:00
|
|
|
VariableDeclarator(SourceRange source_range, Variant<NonnullRefPtr<Identifier>, NonnullRefPtr<BindingPattern>> target, RefPtr<Expression> init)
|
|
|
|
: ASTNode(move(source_range))
|
|
|
|
, m_target(move(target))
|
|
|
|
, m_init(move(init))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
auto& target() const { return m_target; }
|
2021-06-10 21:43:06 +00:00
|
|
|
Expression const* init() const { return m_init; }
|
2020-04-04 19:46:25 +00:00
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-04-04 19:46:25 +00:00
|
|
|
virtual void dump(int indent) const override;
|
|
|
|
|
|
|
|
private:
|
2021-05-29 11:33:19 +00:00
|
|
|
Variant<NonnullRefPtr<Identifier>, NonnullRefPtr<BindingPattern>> m_target;
|
2020-04-04 19:46:25 +00:00
|
|
|
RefPtr<Expression> m_init;
|
|
|
|
};
|
|
|
|
|
2020-09-16 18:13:32 +00:00
|
|
|
class VariableDeclaration final : public Declaration {
|
2020-03-09 20:13:55 +00:00
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
VariableDeclaration(SourceRange source_range, DeclarationKind declaration_kind, NonnullRefPtrVector<VariableDeclarator> declarations)
|
|
|
|
: Declaration(move(source_range))
|
|
|
|
, m_declaration_kind(declaration_kind)
|
2020-04-04 19:46:25 +00:00
|
|
|
, m_declarations(move(declarations))
|
2020-03-09 20:13:55 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-04-08 09:59:18 +00:00
|
|
|
DeclarationKind declaration_kind() const { return m_declaration_kind; }
|
2020-03-09 20:13:55 +00:00
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-03-09 20:13:55 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2021-06-09 22:29:17 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-03-09 20:13:55 +00:00
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
NonnullRefPtrVector<VariableDeclarator> const& declarations() const { return m_declarations; }
|
2020-04-13 14:42:54 +00:00
|
|
|
|
2020-03-09 20:13:55 +00:00
|
|
|
private:
|
2020-04-08 09:59:18 +00:00
|
|
|
DeclarationKind m_declaration_kind;
|
2020-04-04 19:46:25 +00:00
|
|
|
NonnullRefPtrVector<VariableDeclarator> m_declarations;
|
2020-03-09 20:13:55 +00:00
|
|
|
};
|
|
|
|
|
2020-04-23 18:37:53 +00:00
|
|
|
class ObjectProperty final : public ASTNode {
|
|
|
|
public:
|
2020-05-22 00:28:28 +00:00
|
|
|
enum class Type {
|
|
|
|
KeyValue,
|
|
|
|
Getter,
|
|
|
|
Setter,
|
|
|
|
Spread,
|
|
|
|
};
|
|
|
|
|
2020-12-28 17:15:22 +00:00
|
|
|
ObjectProperty(SourceRange source_range, NonnullRefPtr<Expression> key, RefPtr<Expression> value, Type property_type, bool is_method)
|
|
|
|
: ASTNode(move(source_range))
|
|
|
|
, m_key(move(key))
|
2020-04-23 18:37:53 +00:00
|
|
|
, m_value(move(value))
|
2020-05-22 00:28:28 +00:00
|
|
|
, m_property_type(property_type)
|
2020-06-08 18:31:21 +00:00
|
|
|
, m_is_method(is_method)
|
2020-04-23 18:37:53 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
Expression const& key() const { return m_key; }
|
|
|
|
Expression const& value() const
|
2020-05-29 05:50:06 +00:00
|
|
|
{
|
2021-02-23 19:42:32 +00:00
|
|
|
VERIFY(m_value);
|
2020-05-29 05:50:06 +00:00
|
|
|
return *m_value;
|
|
|
|
}
|
2020-04-23 18:37:53 +00:00
|
|
|
|
2020-05-22 00:28:28 +00:00
|
|
|
Type type() const { return m_property_type; }
|
2020-06-08 18:31:21 +00:00
|
|
|
bool is_method() const { return m_is_method; }
|
2020-04-28 04:52:47 +00:00
|
|
|
|
2020-04-23 18:37:53 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-04-23 18:37:53 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
NonnullRefPtr<Expression> m_key;
|
2020-05-29 05:50:06 +00:00
|
|
|
RefPtr<Expression> m_value;
|
2020-05-22 00:28:28 +00:00
|
|
|
Type m_property_type;
|
2020-06-08 18:31:21 +00:00
|
|
|
bool m_is_method { false };
|
2020-04-23 18:37:53 +00:00
|
|
|
};
|
|
|
|
|
2020-09-16 18:13:32 +00:00
|
|
|
class ObjectExpression final : public Expression {
|
2020-03-09 20:28:31 +00:00
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
ObjectExpression(SourceRange source_range, NonnullRefPtrVector<ObjectProperty> properties = {})
|
|
|
|
: Expression(move(source_range))
|
|
|
|
, m_properties(move(properties))
|
2020-03-21 00:29:00 +00:00
|
|
|
{
|
|
|
|
}
|
2020-03-09 20:28:31 +00:00
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-03-09 20:28:31 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-03-09 20:28:31 +00:00
|
|
|
|
|
|
|
private:
|
2020-04-23 18:37:53 +00:00
|
|
|
NonnullRefPtrVector<ObjectProperty> m_properties;
|
2020-03-09 20:28:31 +00:00
|
|
|
};
|
|
|
|
|
2020-09-16 18:13:32 +00:00
|
|
|
class ArrayExpression final : public Expression {
|
2020-03-20 19:29:57 +00:00
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
ArrayExpression(SourceRange source_range, Vector<RefPtr<Expression>> elements)
|
|
|
|
: Expression(move(source_range))
|
|
|
|
, m_elements(move(elements))
|
2020-03-20 19:29:57 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
Vector<RefPtr<Expression>> const& elements() const { return m_elements; }
|
2020-03-20 19:29:57 +00:00
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-03-20 19:29:57 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2021-06-08 21:06:52 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-03-20 19:29:57 +00:00
|
|
|
|
|
|
|
private:
|
2020-04-15 19:09:06 +00:00
|
|
|
Vector<RefPtr<Expression>> m_elements;
|
2020-03-20 19:29:57 +00:00
|
|
|
};
|
|
|
|
|
LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
> `foo
> bar`
'foo
bar'
2020-05-03 22:41:14 +00:00
|
|
|
class TemplateLiteral final : public Expression {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
TemplateLiteral(SourceRange source_range, NonnullRefPtrVector<Expression> expressions)
|
|
|
|
: Expression(move(source_range))
|
|
|
|
, m_expressions(move(expressions))
|
2020-05-06 23:34:14 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-12-28 17:15:22 +00:00
|
|
|
TemplateLiteral(SourceRange source_range, NonnullRefPtrVector<Expression> expressions, NonnullRefPtrVector<Expression> raw_strings)
|
|
|
|
: Expression(move(source_range))
|
|
|
|
, m_expressions(move(expressions))
|
2020-05-06 23:34:14 +00:00
|
|
|
, m_raw_strings(move(raw_strings))
|
LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
> `foo
> bar`
'foo
bar'
2020-05-03 22:41:14 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
> `foo
> bar`
'foo
bar'
2020-05-03 22:41:14 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
> `foo
> bar`
'foo
bar'
2020-05-03 22:41:14 +00:00
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
NonnullRefPtrVector<Expression> const& expressions() const { return m_expressions; }
|
|
|
|
NonnullRefPtrVector<Expression> const& raw_strings() const { return m_raw_strings; }
|
LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
> `foo
> bar`
'foo
bar'
2020-05-03 22:41:14 +00:00
|
|
|
|
|
|
|
private:
|
2021-06-10 21:43:06 +00:00
|
|
|
NonnullRefPtrVector<Expression> const m_expressions;
|
|
|
|
NonnullRefPtrVector<Expression> const m_raw_strings;
|
LibJS: Add template literals
Adds fully functioning template literals. Because template literals
contain expressions, most of the work has to be done in the Lexer rather
than the Parser. And because of the complexity of template literals
(expressions, nesting, escapes, etc), the Lexer needs to have some
template-related state.
When entering a new template literal, a TemplateLiteralStart token is
emitted. When inside a literal, all text will be parsed up until a '${'
or '`' (or EOF, but that's a syntax error) is seen, and then a
TemplateLiteralExprStart token is emitted. At this point, the Lexer
proceeds as normal, however it keeps track of the number of opening
and closing curly braces it has seen in order to determine the close
of the expression. Once it finds a matching curly brace for the '${',
a TemplateLiteralExprEnd token is emitted and the state is updated
accordingly.
When the Lexer is inside of a template literal, but not an expression,
and sees a '`', this must be the closing grave: a TemplateLiteralEnd
token is emitted.
The state required to correctly parse template strings consists of a
vector (for nesting) of two pieces of information: whether or not we
are in a template expression (as opposed to a template string); and
the count of the number of unmatched open curly braces we have seen
(only applicable if the Lexer is currently in a template expression).
TODO: Add support for template literal newlines in the JS REPL (this will
cause a syntax error currently):
> `foo
> bar`
'foo
bar'
2020-05-03 22:41:14 +00:00
|
|
|
};
|
|
|
|
|
2020-05-06 09:17:35 +00:00
|
|
|
class TaggedTemplateLiteral final : public Expression {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
TaggedTemplateLiteral(SourceRange source_range, NonnullRefPtr<Expression> tag, NonnullRefPtr<TemplateLiteral> template_literal)
|
|
|
|
: Expression(move(source_range))
|
|
|
|
, m_tag(move(tag))
|
2020-05-06 09:17:35 +00:00
|
|
|
, m_template_literal(move(template_literal))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-05-06 09:17:35 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2021-06-09 19:02:24 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-05-06 09:17:35 +00:00
|
|
|
|
|
|
|
private:
|
2021-06-10 21:43:06 +00:00
|
|
|
NonnullRefPtr<Expression> const m_tag;
|
|
|
|
NonnullRefPtr<TemplateLiteral> const m_template_literal;
|
2020-05-06 09:17:35 +00:00
|
|
|
};
|
|
|
|
|
2020-03-11 17:58:19 +00:00
|
|
|
class MemberExpression final : public Expression {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
MemberExpression(SourceRange source_range, NonnullRefPtr<Expression> object, NonnullRefPtr<Expression> property, bool computed = false)
|
|
|
|
: Expression(move(source_range))
|
|
|
|
, m_object(move(object))
|
2020-03-11 17:58:19 +00:00
|
|
|
, m_property(move(property))
|
2020-03-20 19:51:03 +00:00
|
|
|
, m_computed(computed)
|
2020-03-11 17:58:19 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-03-11 17:58:19 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Reference to_reference(Interpreter&, GlobalObject&) const override;
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-03-11 17:58:19 +00:00
|
|
|
|
2020-03-20 19:51:03 +00:00
|
|
|
bool is_computed() const { return m_computed; }
|
2021-06-10 21:43:06 +00:00
|
|
|
Expression const& object() const { return *m_object; }
|
|
|
|
Expression const& property() const { return *m_property; }
|
2020-03-15 14:01:10 +00:00
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
PropertyName computed_property_name(Interpreter&, GlobalObject&) const;
|
2020-03-20 19:51:03 +00:00
|
|
|
|
2020-04-19 00:12:51 +00:00
|
|
|
String to_string_approximation() const;
|
|
|
|
|
2020-03-11 17:58:19 +00:00
|
|
|
private:
|
2021-06-13 09:23:23 +00:00
|
|
|
virtual bool is_member_expression() const override { return true; }
|
|
|
|
|
2020-03-18 10:23:53 +00:00
|
|
|
NonnullRefPtr<Expression> m_object;
|
|
|
|
NonnullRefPtr<Expression> m_property;
|
2020-03-20 19:51:03 +00:00
|
|
|
bool m_computed { false };
|
2020-03-11 17:58:19 +00:00
|
|
|
};
|
|
|
|
|
2020-11-02 21:27:42 +00:00
|
|
|
class MetaProperty final : public Expression {
|
|
|
|
public:
|
|
|
|
enum class Type {
|
|
|
|
NewTarget,
|
|
|
|
ImportMeta,
|
|
|
|
};
|
|
|
|
|
2020-12-28 17:15:22 +00:00
|
|
|
MetaProperty(SourceRange source_range, Type type)
|
|
|
|
: Expression(move(source_range))
|
|
|
|
, m_type(type)
|
2020-11-02 21:27:42 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
|
|
|
virtual void dump(int indent) const override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
Type m_type;
|
|
|
|
};
|
|
|
|
|
2020-04-03 10:14:28 +00:00
|
|
|
class ConditionalExpression final : public Expression {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
ConditionalExpression(SourceRange source_range, NonnullRefPtr<Expression> test, NonnullRefPtr<Expression> consequent, NonnullRefPtr<Expression> alternate)
|
|
|
|
: Expression(move(source_range))
|
|
|
|
, m_test(move(test))
|
2020-04-03 10:14:28 +00:00
|
|
|
, m_consequent(move(consequent))
|
|
|
|
, m_alternate(move(alternate))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void dump(int indent) const override;
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-04-03 10:14:28 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
NonnullRefPtr<Expression> m_test;
|
|
|
|
NonnullRefPtr<Expression> m_consequent;
|
|
|
|
NonnullRefPtr<Expression> m_alternate;
|
|
|
|
};
|
|
|
|
|
2020-03-24 13:03:55 +00:00
|
|
|
class CatchClause final : public ASTNode {
|
|
|
|
public:
|
2021-06-10 21:43:06 +00:00
|
|
|
CatchClause(SourceRange source_range, FlyString const& parameter, NonnullRefPtr<BlockStatement> body)
|
2020-12-28 17:15:22 +00:00
|
|
|
: ASTNode(move(source_range))
|
|
|
|
, m_parameter(parameter)
|
2020-03-24 13:03:55 +00:00
|
|
|
, m_body(move(body))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
FlyString const& parameter() const { return m_parameter; }
|
|
|
|
BlockStatement const& body() const { return m_body; }
|
2020-03-24 13:03:55 +00:00
|
|
|
|
|
|
|
virtual void dump(int indent) const override;
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-03-24 13:03:55 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
FlyString m_parameter;
|
|
|
|
NonnullRefPtr<BlockStatement> m_body;
|
|
|
|
};
|
|
|
|
|
|
|
|
class TryStatement final : public Statement {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
TryStatement(SourceRange source_range, NonnullRefPtr<BlockStatement> block, RefPtr<CatchClause> handler, RefPtr<BlockStatement> finalizer)
|
|
|
|
: Statement(move(source_range))
|
|
|
|
, m_block(move(block))
|
2020-03-24 13:03:55 +00:00
|
|
|
, m_handler(move(handler))
|
|
|
|
, m_finalizer(move(finalizer))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
BlockStatement const& block() const { return m_block; }
|
|
|
|
CatchClause const* handler() const { return m_handler; }
|
|
|
|
BlockStatement const* finalizer() const { return m_finalizer; }
|
2020-03-24 13:03:55 +00:00
|
|
|
|
|
|
|
virtual void dump(int indent) const override;
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2021-06-10 13:04:38 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-03-24 13:03:55 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
NonnullRefPtr<BlockStatement> m_block;
|
|
|
|
RefPtr<CatchClause> m_handler;
|
|
|
|
RefPtr<BlockStatement> m_finalizer;
|
|
|
|
};
|
|
|
|
|
2020-03-24 21:03:50 +00:00
|
|
|
class ThrowStatement final : public Statement {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
explicit ThrowStatement(SourceRange source_range, NonnullRefPtr<Expression> argument)
|
|
|
|
: Statement(move(source_range))
|
|
|
|
, m_argument(move(argument))
|
2020-03-24 21:03:50 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
Expression const& argument() const { return m_argument; }
|
2020-03-24 21:03:50 +00:00
|
|
|
|
|
|
|
virtual void dump(int indent) const override;
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2021-06-09 16:18:56 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-03-24 21:03:50 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
NonnullRefPtr<Expression> m_argument;
|
|
|
|
};
|
|
|
|
|
2020-03-29 11:09:54 +00:00
|
|
|
class SwitchCase final : public ASTNode {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
SwitchCase(SourceRange source_range, RefPtr<Expression> test, NonnullRefPtrVector<Statement> consequent)
|
|
|
|
: ASTNode(move(source_range))
|
|
|
|
, m_test(move(test))
|
2020-03-29 11:09:54 +00:00
|
|
|
, m_consequent(move(consequent))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
Expression const* test() const { return m_test; }
|
|
|
|
NonnullRefPtrVector<Statement> const& consequent() const { return m_consequent; }
|
2020-03-29 12:34:25 +00:00
|
|
|
|
2020-03-29 11:09:54 +00:00
|
|
|
virtual void dump(int indent) const override;
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-03-29 11:09:54 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
RefPtr<Expression> m_test;
|
|
|
|
NonnullRefPtrVector<Statement> m_consequent;
|
|
|
|
};
|
|
|
|
|
|
|
|
class SwitchStatement final : public Statement {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
SwitchStatement(SourceRange source_range, NonnullRefPtr<Expression> discriminant, NonnullRefPtrVector<SwitchCase> cases)
|
|
|
|
: Statement(move(source_range))
|
|
|
|
, m_discriminant(move(discriminant))
|
2020-03-29 11:09:54 +00:00
|
|
|
, m_cases(move(cases))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
virtual void dump(int indent) const override;
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2021-06-10 22:36:16 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-03-29 11:09:54 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
NonnullRefPtr<Expression> m_discriminant;
|
|
|
|
NonnullRefPtrVector<SwitchCase> m_cases;
|
|
|
|
};
|
|
|
|
|
|
|
|
class BreakStatement final : public Statement {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
BreakStatement(SourceRange source_range, FlyString target_label)
|
|
|
|
: Statement(move(source_range))
|
|
|
|
, m_target_label(target_label)
|
2020-05-28 19:02:32 +00:00
|
|
|
{
|
|
|
|
}
|
2020-03-29 11:09:54 +00:00
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2020-03-29 11:09:54 +00:00
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
FlyString const& target_label() const { return m_target_label; }
|
2021-06-10 12:28:43 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-05-28 19:02:32 +00:00
|
|
|
|
2020-03-29 11:09:54 +00:00
|
|
|
private:
|
2020-05-28 19:02:32 +00:00
|
|
|
FlyString m_target_label;
|
2020-03-29 11:09:54 +00:00
|
|
|
};
|
|
|
|
|
2020-04-04 22:22:42 +00:00
|
|
|
class ContinueStatement final : public Statement {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
ContinueStatement(SourceRange source_range, FlyString target_label)
|
|
|
|
: Statement(move(source_range))
|
|
|
|
, m_target_label(target_label)
|
2020-05-28 19:02:32 +00:00
|
|
|
{
|
|
|
|
}
|
2020-04-04 22:22:42 +00:00
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-04-04 22:22:42 +00:00
|
|
|
|
2021-06-10 21:43:06 +00:00
|
|
|
FlyString const& target_label() const { return m_target_label; }
|
2020-05-28 19:02:32 +00:00
|
|
|
|
2020-04-04 22:22:42 +00:00
|
|
|
private:
|
2020-05-28 19:02:32 +00:00
|
|
|
FlyString m_target_label;
|
2020-04-04 22:22:42 +00:00
|
|
|
};
|
|
|
|
|
2020-04-30 16:26:27 +00:00
|
|
|
class DebuggerStatement final : public Statement {
|
|
|
|
public:
|
2020-12-28 17:15:22 +00:00
|
|
|
DebuggerStatement(SourceRange source_range)
|
|
|
|
: Statement(move(source_range))
|
|
|
|
{
|
|
|
|
}
|
2020-04-30 16:26:27 +00:00
|
|
|
|
2020-06-08 18:57:54 +00:00
|
|
|
virtual Value execute(Interpreter&, GlobalObject&) const override;
|
2021-06-08 03:58:36 +00:00
|
|
|
virtual void generate_bytecode(Bytecode::Generator&) const override;
|
2020-04-30 16:26:27 +00:00
|
|
|
};
|
|
|
|
|
2021-05-29 11:33:19 +00:00
|
|
|
template<typename C>
|
|
|
|
void BindingPattern::for_each_assigned_name(C&& callback) const
|
|
|
|
{
|
|
|
|
for (auto& property : properties) {
|
|
|
|
if (property.name) {
|
|
|
|
callback(property.name->string());
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
property.pattern->template for_each_assigned_name(forward<C>(callback));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-13 09:23:23 +00:00
|
|
|
template<>
|
|
|
|
inline bool ASTNode::fast_is<NewExpression>() const { return is_new_expression(); }
|
|
|
|
|
|
|
|
template<>
|
|
|
|
inline bool ASTNode::fast_is<MemberExpression>() const { return is_member_expression(); }
|
|
|
|
|
|
|
|
template<>
|
|
|
|
inline bool ASTNode::fast_is<SuperExpression>() const { return is_super_expression(); }
|
|
|
|
|
|
|
|
template<>
|
|
|
|
inline bool ASTNode::fast_is<Identifier>() const { return is_identifier(); }
|
|
|
|
|
|
|
|
template<>
|
|
|
|
inline bool ASTNode::fast_is<ExpressionStatement>() const { return is_expression_statement(); }
|
|
|
|
|
|
|
|
template<>
|
|
|
|
inline bool ASTNode::fast_is<ScopeNode>() const { return is_scope_node(); }
|
|
|
|
|
|
|
|
template<>
|
|
|
|
inline bool ASTNode::fast_is<Program>() const { return is_program(); }
|
|
|
|
|
2020-03-07 18:42:11 +00:00
|
|
|
}
|