mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-08 05:27:14 +09:00
LibJS: Preserve information about local variables declaration kind
This is required for upcoming change where we want to emit ThrowIfTDZ for assignment expressions only for lexical declarations.
This commit is contained in:
parent
2774068ca0
commit
db480b1f0c
Notes:
github-actions[bot]
2025-05-06 10:07:32 +00:00
Author: https://github.com/kalenikaliaksandr
Commit: db480b1f0c
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4616
Reviewed-by: https://github.com/awesomekling
11 changed files with 83 additions and 40 deletions
|
@ -826,7 +826,7 @@ void BindingPattern::dump(int indent) const
|
|||
}
|
||||
}
|
||||
|
||||
FunctionNode::FunctionNode(RefPtr<Identifier const> name, ByteString source_text, NonnullRefPtr<Statement const> body, NonnullRefPtr<FunctionParameters const> parameters, i32 function_length, FunctionKind kind, bool is_strict_mode, FunctionParsingInsights parsing_insights, bool is_arrow_function, Vector<FlyString> local_variables_names)
|
||||
FunctionNode::FunctionNode(RefPtr<Identifier const> name, ByteString source_text, NonnullRefPtr<Statement const> body, NonnullRefPtr<FunctionParameters const> parameters, i32 function_length, FunctionKind kind, bool is_strict_mode, FunctionParsingInsights parsing_insights, bool is_arrow_function, Vector<LocalVariable> local_variables_names)
|
||||
: m_name(move(name))
|
||||
, m_source_text(move(source_text))
|
||||
, m_body(move(body))
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <LibJS/Bytecode/Operand.h>
|
||||
#include <LibJS/Bytecode/ScopedOperand.h>
|
||||
#include <LibJS/Forward.h>
|
||||
#include <LibJS/LocalVariable.h>
|
||||
#include <LibJS/Runtime/ClassFieldDefinition.h>
|
||||
#include <LibJS/Runtime/Completion.h>
|
||||
#include <LibJS/Runtime/EnvironmentCoordinate.h>
|
||||
|
@ -340,11 +341,11 @@ public:
|
|||
|
||||
ThrowCompletionOr<void> for_each_function_hoistable_with_annexB_extension(ThrowCompletionOrVoidCallback<FunctionDeclaration&>&& callback) const;
|
||||
|
||||
Vector<FlyString> const& local_variables_names() const { return m_local_variables_names; }
|
||||
size_t add_local_variable(FlyString name)
|
||||
auto const& local_variables_names() const { return m_local_variables_names; }
|
||||
size_t add_local_variable(FlyString name, LocalVariable::DeclarationKind declaration_kind)
|
||||
{
|
||||
auto index = m_local_variables_names.size();
|
||||
m_local_variables_names.append(move(name));
|
||||
m_local_variables_names.append({ move(name), declaration_kind });
|
||||
return index;
|
||||
}
|
||||
|
||||
|
@ -363,7 +364,7 @@ private:
|
|||
|
||||
Vector<NonnullRefPtr<FunctionDeclaration const>> m_functions_hoistable_with_annexB_extension;
|
||||
|
||||
Vector<FlyString> m_local_variables_names;
|
||||
Vector<LocalVariable> m_local_variables_names;
|
||||
};
|
||||
|
||||
// ImportEntry Record, https://tc39.es/ecma262/#table-importentry-record-fields
|
||||
|
@ -785,7 +786,7 @@ public:
|
|||
auto const& body_ptr() const { return m_body; }
|
||||
auto const& parameters() const { return m_parameters; }
|
||||
i32 function_length() const { return m_function_length; }
|
||||
Vector<FlyString> const& local_variables_names() const { return m_local_variables_names; }
|
||||
Vector<LocalVariable> const& local_variables_names() const { return m_local_variables_names; }
|
||||
bool is_strict_mode() const { return m_is_strict_mode; }
|
||||
bool might_need_arguments_object() const { return m_parsing_insights.might_need_arguments_object; }
|
||||
bool contains_direct_call_to_eval() const { return m_parsing_insights.contains_direct_call_to_eval; }
|
||||
|
@ -803,7 +804,7 @@ public:
|
|||
virtual ~FunctionNode();
|
||||
|
||||
protected:
|
||||
FunctionNode(RefPtr<Identifier const> name, ByteString source_text, NonnullRefPtr<Statement const> body, NonnullRefPtr<FunctionParameters const> parameters, i32 function_length, FunctionKind kind, bool is_strict_mode, FunctionParsingInsights parsing_insights, bool is_arrow_function, Vector<FlyString> local_variables_names);
|
||||
FunctionNode(RefPtr<Identifier const> name, ByteString source_text, NonnullRefPtr<Statement const> body, NonnullRefPtr<FunctionParameters const> parameters, i32 function_length, FunctionKind kind, bool is_strict_mode, FunctionParsingInsights parsing_insights, bool is_arrow_function, Vector<LocalVariable> local_variables_names);
|
||||
void dump(int indent, ByteString const& class_name) const;
|
||||
|
||||
RefPtr<Identifier const> m_name { nullptr };
|
||||
|
@ -818,7 +819,7 @@ private:
|
|||
bool m_is_arrow_function : 1 { false };
|
||||
FunctionParsingInsights m_parsing_insights;
|
||||
|
||||
Vector<FlyString> m_local_variables_names;
|
||||
Vector<LocalVariable> m_local_variables_names;
|
||||
|
||||
mutable RefPtr<SharedFunctionInstanceData> m_shared_data;
|
||||
};
|
||||
|
@ -829,7 +830,7 @@ class FunctionDeclaration final
|
|||
public:
|
||||
static bool must_have_name() { return true; }
|
||||
|
||||
FunctionDeclaration(SourceRange source_range, RefPtr<Identifier const> name, ByteString source_text, NonnullRefPtr<Statement const> body, NonnullRefPtr<FunctionParameters const> parameters, i32 function_length, FunctionKind kind, bool is_strict_mode, FunctionParsingInsights insights, Vector<FlyString> local_variables_names)
|
||||
FunctionDeclaration(SourceRange source_range, RefPtr<Identifier const> name, ByteString source_text, NonnullRefPtr<Statement const> body, NonnullRefPtr<FunctionParameters const> parameters, i32 function_length, FunctionKind kind, bool is_strict_mode, FunctionParsingInsights insights, Vector<LocalVariable> local_variables_names)
|
||||
: Declaration(move(source_range))
|
||||
, FunctionNode(move(name), move(source_text), move(body), move(parameters), function_length, kind, is_strict_mode, insights, false, move(local_variables_names))
|
||||
{
|
||||
|
@ -859,7 +860,7 @@ class FunctionExpression final
|
|||
public:
|
||||
static bool must_have_name() { return false; }
|
||||
|
||||
FunctionExpression(SourceRange source_range, RefPtr<Identifier const> name, ByteString source_text, NonnullRefPtr<Statement const> body, NonnullRefPtr<FunctionParameters const> parameters, i32 function_length, FunctionKind kind, bool is_strict_mode, FunctionParsingInsights insights, Vector<FlyString> local_variables_names, bool is_arrow_function = false)
|
||||
FunctionExpression(SourceRange source_range, RefPtr<Identifier const> name, ByteString source_text, NonnullRefPtr<Statement const> body, NonnullRefPtr<FunctionParameters const> parameters, i32 function_length, FunctionKind kind, bool is_strict_mode, FunctionParsingInsights insights, Vector<LocalVariable> local_variables_names, bool is_arrow_function = false)
|
||||
: Expression(move(source_range))
|
||||
, FunctionNode(move(name), move(source_text), move(body), move(parameters), function_length, kind, is_strict_mode, insights, is_arrow_function, move(local_variables_names))
|
||||
{
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <LibJS/Bytecode/StringTable.h>
|
||||
#include <LibJS/Forward.h>
|
||||
#include <LibJS/Heap/Cell.h>
|
||||
#include <LibJS/LocalVariable.h>
|
||||
#include <LibJS/Runtime/EnvironmentCoordinate.h>
|
||||
#include <LibJS/SourceRange.h>
|
||||
|
||||
|
@ -85,7 +86,7 @@ public:
|
|||
|
||||
HashMap<size_t, SourceRecord> source_map;
|
||||
|
||||
Vector<FlyString> local_variable_names;
|
||||
Vector<LocalVariable> local_variable_names;
|
||||
size_t local_index_base { 0 };
|
||||
size_t argument_index_base { 0 };
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ CodeGenerationErrorOr<void> Generator::emit_function_declaration_instantiation(E
|
|||
|
||||
if (function.shared_data().m_arguments_object_needed) {
|
||||
Optional<Operand> dst;
|
||||
auto local_var_index = function.shared_data().m_local_variables_names.find_first_index("arguments"_fly_string);
|
||||
auto local_var_index = function.shared_data().m_local_variables_names.find_first_index_if([](auto const& local) { return local.declaration_kind == LocalVariable::DeclarationKind::ArgumentsObject; });
|
||||
if (local_var_index.has_value())
|
||||
dst = local(Identifier::Local::variable(local_var_index.value()));
|
||||
|
||||
|
@ -215,9 +215,10 @@ CodeGenerationErrorOr<void> Generator::emit_function_declaration_instantiation(E
|
|||
return {};
|
||||
}
|
||||
|
||||
CodeGenerationErrorOr<GC::Ref<Executable>> Generator::compile(VM& vm, ASTNode const& node, FunctionKind enclosing_function_kind, GC::Ptr<ECMAScriptFunctionObject const> function, MustPropagateCompletion must_propagate_completion, Vector<FlyString> local_variable_names)
|
||||
CodeGenerationErrorOr<GC::Ref<Executable>> Generator::compile(VM& vm, ASTNode const& node, FunctionKind enclosing_function_kind, GC::Ptr<ECMAScriptFunctionObject const> function, MustPropagateCompletion must_propagate_completion, Vector<LocalVariable> local_variable_names)
|
||||
{
|
||||
Generator generator(vm, function, must_propagate_completion);
|
||||
generator.m_local_variables = local_variable_names;
|
||||
|
||||
generator.switch_to_basic_block(generator.make_block());
|
||||
SourceLocationScope scope(generator, node);
|
||||
|
@ -483,7 +484,7 @@ CodeGenerationErrorOr<GC::Ref<Executable>> Generator::compile(VM& vm, ASTNode co
|
|||
|
||||
CodeGenerationErrorOr<GC::Ref<Executable>> Generator::generate_from_ast_node(VM& vm, ASTNode const& node, FunctionKind enclosing_function_kind)
|
||||
{
|
||||
Vector<FlyString> local_variable_names;
|
||||
Vector<LocalVariable> local_variable_names;
|
||||
if (is<ScopeNode>(node))
|
||||
local_variable_names = static_cast<ScopeNode const&>(node).local_variables_names();
|
||||
return compile(vm, node, enclosing_function_kind, {}, MustPropagateCompletion::Yes, move(local_variable_names));
|
||||
|
@ -1211,6 +1212,13 @@ void Generator::set_local_initialized(Identifier::Local const& local)
|
|||
}
|
||||
}
|
||||
|
||||
bool Generator::is_local_lexically_declared(Identifier::Local const& local) const
|
||||
{
|
||||
if (local.is_argument())
|
||||
return false;
|
||||
return m_local_variables[local.index].declaration_kind == LocalVariable::DeclarationKind::LetOrConst;
|
||||
}
|
||||
|
||||
ScopedOperand Generator::get_this(Optional<ScopedOperand> preferred_dst)
|
||||
{
|
||||
if (m_current_basic_block->has_resolved_this())
|
||||
|
|
|
@ -53,6 +53,7 @@ public:
|
|||
void set_local_initialized(Identifier::Local const&);
|
||||
[[nodiscard]] bool is_local_initialized(u32 local_index) const;
|
||||
[[nodiscard]] bool is_local_initialized(Identifier::Local const&) const;
|
||||
[[nodiscard]] bool is_local_lexically_declared(Identifier::Local const& local) const;
|
||||
|
||||
class SourceLocationScope {
|
||||
public:
|
||||
|
@ -358,7 +359,7 @@ public:
|
|||
private:
|
||||
VM& m_vm;
|
||||
|
||||
static CodeGenerationErrorOr<GC::Ref<Executable>> compile(VM&, ASTNode const&, FunctionKind, GC::Ptr<ECMAScriptFunctionObject const>, MustPropagateCompletion, Vector<FlyString> local_variable_names);
|
||||
static CodeGenerationErrorOr<GC::Ref<Executable>> compile(VM&, ASTNode const&, FunctionKind, GC::Ptr<ECMAScriptFunctionObject const>, MustPropagateCompletion, Vector<LocalVariable> local_variable_names);
|
||||
|
||||
enum class JumpType {
|
||||
Continue,
|
||||
|
@ -413,6 +414,7 @@ private:
|
|||
|
||||
HashTable<u32> m_initialized_locals;
|
||||
HashTable<u32> m_initialized_arguments;
|
||||
Vector<LocalVariable> m_local_variables;
|
||||
|
||||
bool m_finished { false };
|
||||
bool m_must_propagate_completion { true };
|
||||
|
|
|
@ -83,7 +83,7 @@ static ByteString format_operand(StringView name, Operand operand, Bytecode::Exe
|
|||
}
|
||||
break;
|
||||
case Operand::Type::Local:
|
||||
builder.appendff("\033[34m{}~{}\033[0m", executable.local_variable_names[operand.index() - executable.local_index_base], operand.index() - executable.local_index_base);
|
||||
builder.appendff("\033[34m{}~{}\033[0m", executable.local_variable_names[operand.index() - executable.local_index_base].name, operand.index() - executable.local_index_base);
|
||||
break;
|
||||
case Operand::Type::Argument:
|
||||
builder.appendff("\033[34marg{}\033[0m", operand.index() - executable.argument_index_base);
|
||||
|
|
25
Libraries/LibJS/LocalVariable.h
Normal file
25
Libraries/LibJS/LocalVariable.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/FlyString.h>
|
||||
|
||||
namespace JS {
|
||||
|
||||
struct LocalVariable {
|
||||
FlyString name;
|
||||
enum class DeclarationKind {
|
||||
Var,
|
||||
LetOrConst,
|
||||
Function,
|
||||
ArgumentsObject,
|
||||
CatchClauseParameter
|
||||
};
|
||||
DeclarationKind declaration_kind;
|
||||
};
|
||||
|
||||
}
|
|
@ -298,17 +298,22 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
bool scope_has_declaration = false;
|
||||
if (is_top_level() && m_var_names.contains(identifier_group_name))
|
||||
scope_has_declaration = true;
|
||||
else if (m_lexical_names.contains(identifier_group_name) || m_function_names.contains(identifier_group_name))
|
||||
scope_has_declaration = true;
|
||||
Optional<LocalVariable::DeclarationKind> local_variable_declaration_kind;
|
||||
if (is_top_level() && m_var_names.contains(identifier_group_name)) {
|
||||
local_variable_declaration_kind = LocalVariable::DeclarationKind::Var;
|
||||
} else if (m_lexical_names.contains(identifier_group_name)) {
|
||||
local_variable_declaration_kind = LocalVariable::DeclarationKind::LetOrConst;
|
||||
} else if (m_function_names.contains(identifier_group_name)) {
|
||||
local_variable_declaration_kind = LocalVariable::DeclarationKind::Function;
|
||||
}
|
||||
|
||||
if (m_type == ScopeType::Function && !m_is_arrow_function && identifier_group_name == "arguments"sv)
|
||||
scope_has_declaration = true;
|
||||
if (m_type == ScopeType::Function && !m_is_arrow_function && identifier_group_name == "arguments"sv) {
|
||||
local_variable_declaration_kind = LocalVariable::DeclarationKind::ArgumentsObject;
|
||||
}
|
||||
|
||||
if (m_type == ScopeType::Catch && m_catch_parameter_names.contains(identifier_group_name))
|
||||
scope_has_declaration = true;
|
||||
if (m_type == ScopeType::Catch && m_catch_parameter_names.contains(identifier_group_name)) {
|
||||
local_variable_declaration_kind = LocalVariable::DeclarationKind::CatchClauseParameter;
|
||||
}
|
||||
|
||||
bool hoistable_function_declaration = false;
|
||||
for (auto const& function_declaration : m_functions_to_hoist) {
|
||||
|
@ -329,7 +334,7 @@ public:
|
|||
|
||||
if (m_type == ScopeType::ClassDeclaration) {
|
||||
// NOTE: Class declaration doesn't not have own ScopeNode hence can't contain declaration of any variable
|
||||
scope_has_declaration = false;
|
||||
local_variable_declaration_kind.clear();
|
||||
}
|
||||
|
||||
bool is_function_parameter = false;
|
||||
|
@ -353,7 +358,7 @@ public:
|
|||
for (auto& identifier : identifier_group.identifiers)
|
||||
identifier->set_is_global();
|
||||
}
|
||||
} else if (scope_has_declaration || is_function_parameter) {
|
||||
} else if (local_variable_declaration_kind.has_value() || is_function_parameter) {
|
||||
if (hoistable_function_declaration)
|
||||
continue;
|
||||
|
||||
|
@ -380,7 +385,7 @@ public:
|
|||
for (auto& identifier : identifier_group.identifiers)
|
||||
identifier->set_argument_index(argument_index.value());
|
||||
} else {
|
||||
auto local_variable_index = local_scope->m_node->add_local_variable(identifier_group_name);
|
||||
auto local_variable_index = local_scope->m_node->add_local_variable(identifier_group_name, *local_variable_declaration_kind);
|
||||
for (auto& identifier : identifier_group.identifiers)
|
||||
identifier->set_local_variable_index(local_variable_index);
|
||||
}
|
||||
|
@ -1656,7 +1661,7 @@ NonnullRefPtr<ClassExpression const> Parser::parse_class_expression(bool expect_
|
|||
constructor = create_ast_node<FunctionExpression>(
|
||||
{ m_source_code, rule_start.position(), position() }, class_name, "",
|
||||
move(constructor_body), FunctionParameters::create(Vector { FunctionParameter { move(argument_name), nullptr, true } }), 0, FunctionKind::Normal,
|
||||
/* is_strict_mode */ true, parsing_insights, /* local_variables_names */ Vector<FlyString> {});
|
||||
/* is_strict_mode */ true, parsing_insights, /* local_variables_names */ Vector<LocalVariable> {});
|
||||
} else {
|
||||
FunctionParsingInsights parsing_insights;
|
||||
parsing_insights.uses_this_from_environment = true;
|
||||
|
@ -1664,7 +1669,7 @@ NonnullRefPtr<ClassExpression const> Parser::parse_class_expression(bool expect_
|
|||
constructor = create_ast_node<FunctionExpression>(
|
||||
{ m_source_code, rule_start.position(), position() }, class_name, "",
|
||||
move(constructor_body), FunctionParameters::empty(), 0, FunctionKind::Normal,
|
||||
/* is_strict_mode */ true, parsing_insights, /* local_variables_names */ Vector<FlyString> {});
|
||||
/* is_strict_mode */ true, parsing_insights, /* local_variables_names */ Vector<LocalVariable> {});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace JS {
|
|||
|
||||
GC_DEFINE_ALLOCATOR(ECMAScriptFunctionObject);
|
||||
|
||||
GC::Ref<ECMAScriptFunctionObject> ECMAScriptFunctionObject::create(Realm& realm, FlyString name, ByteString source_text, Statement const& ecmascript_code, NonnullRefPtr<FunctionParameters const> parameters, i32 function_length, Vector<FlyString> local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, FunctionParsingInsights parsing_insights, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name)
|
||||
GC::Ref<ECMAScriptFunctionObject> ECMAScriptFunctionObject::create(Realm& realm, FlyString name, ByteString source_text, Statement const& ecmascript_code, NonnullRefPtr<FunctionParameters const> parameters, i32 function_length, Vector<LocalVariable> local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, FunctionParsingInsights parsing_insights, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name)
|
||||
{
|
||||
Object* prototype = nullptr;
|
||||
switch (kind) {
|
||||
|
@ -73,7 +73,7 @@ GC::Ref<ECMAScriptFunctionObject> ECMAScriptFunctionObject::create(Realm& realm,
|
|||
*prototype);
|
||||
}
|
||||
|
||||
GC::Ref<ECMAScriptFunctionObject> ECMAScriptFunctionObject::create(Realm& realm, FlyString name, Object& prototype, ByteString source_text, Statement const& ecmascript_code, NonnullRefPtr<FunctionParameters const> parameters, i32 function_length, Vector<FlyString> local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, FunctionParsingInsights parsing_insights, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name)
|
||||
GC::Ref<ECMAScriptFunctionObject> ECMAScriptFunctionObject::create(Realm& realm, FlyString name, Object& prototype, ByteString source_text, Statement const& ecmascript_code, NonnullRefPtr<FunctionParameters const> parameters, i32 function_length, Vector<LocalVariable> local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, FunctionParsingInsights parsing_insights, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name)
|
||||
{
|
||||
auto shared_data = adopt_ref(*new SharedFunctionInstanceData(
|
||||
realm.vm(),
|
||||
|
@ -153,7 +153,7 @@ SharedFunctionInstanceData::SharedFunctionInstanceData(
|
|||
bool strict,
|
||||
bool is_arrow_function,
|
||||
FunctionParsingInsights const& parsing_insights,
|
||||
Vector<FlyString> local_variables_names)
|
||||
Vector<LocalVariable> local_variables_names)
|
||||
: m_formal_parameters(move(formal_parameters))
|
||||
, m_ecmascript_code(move(ecmascript_code))
|
||||
, m_name(move(name))
|
||||
|
@ -295,7 +295,7 @@ SharedFunctionInstanceData::SharedFunctionInstanceData(
|
|||
|
||||
HashMap<FlyString, ParameterIsLocal> parameter_bindings;
|
||||
|
||||
auto arguments_object_needs_binding = m_arguments_object_needed && !m_local_variables_names.contains_slow(vm.names.arguments.as_string());
|
||||
auto arguments_object_needs_binding = m_arguments_object_needed && !m_local_variables_names.first_matching([](auto const& local) { return local.declaration_kind == LocalVariable::DeclarationKind::ArgumentsObject; }).has_value();
|
||||
|
||||
// 22. If argumentsObjectNeeded is true, then
|
||||
if (m_arguments_object_needed) {
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
bool strict,
|
||||
bool is_arrow_function,
|
||||
FunctionParsingInsights const&,
|
||||
Vector<FlyString> local_variables_names);
|
||||
Vector<LocalVariable> local_variables_names);
|
||||
|
||||
RefPtr<FunctionParameters const> m_formal_parameters; // [[FormalParameters]]
|
||||
RefPtr<Statement const> m_ecmascript_code; // [[ECMAScriptCode]]
|
||||
|
@ -54,7 +54,7 @@ public:
|
|||
FlyString m_name;
|
||||
ByteString m_source_text; // [[SourceText]]
|
||||
|
||||
Vector<FlyString> m_local_variables_names;
|
||||
Vector<LocalVariable> m_local_variables_names;
|
||||
|
||||
i32 m_function_length { 0 };
|
||||
|
||||
|
@ -103,8 +103,8 @@ class ECMAScriptFunctionObject final : public FunctionObject {
|
|||
GC_DECLARE_ALLOCATOR(ECMAScriptFunctionObject);
|
||||
|
||||
public:
|
||||
static GC::Ref<ECMAScriptFunctionObject> create(Realm&, FlyString name, ByteString source_text, Statement const& ecmascript_code, NonnullRefPtr<FunctionParameters const> parameters, i32 function_length, Vector<FlyString> local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind, bool is_strict, FunctionParsingInsights, bool is_arrow_function = false, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name = {});
|
||||
static GC::Ref<ECMAScriptFunctionObject> create(Realm&, FlyString name, Object& prototype, ByteString source_text, Statement const& ecmascript_code, NonnullRefPtr<FunctionParameters const> parameters, i32 function_length, Vector<FlyString> local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind, bool is_strict, FunctionParsingInsights, bool is_arrow_function = false, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name = {});
|
||||
static GC::Ref<ECMAScriptFunctionObject> create(Realm&, FlyString name, ByteString source_text, Statement const& ecmascript_code, NonnullRefPtr<FunctionParameters const> parameters, i32 function_length, Vector<LocalVariable> local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind, bool is_strict, FunctionParsingInsights, bool is_arrow_function = false, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name = {});
|
||||
static GC::Ref<ECMAScriptFunctionObject> create(Realm&, FlyString name, Object& prototype, ByteString source_text, Statement const& ecmascript_code, NonnullRefPtr<FunctionParameters const> parameters, i32 function_length, Vector<LocalVariable> local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind, bool is_strict, FunctionParsingInsights, bool is_arrow_function = false, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name = {});
|
||||
|
||||
[[nodiscard]] static GC::Ref<ECMAScriptFunctionObject> create_from_function_node(
|
||||
FunctionNode const&,
|
||||
|
@ -167,7 +167,7 @@ public:
|
|||
// Equivalent to absence of [[Construct]]
|
||||
virtual bool has_constructor() const override { return kind() == FunctionKind::Normal && !shared_data().m_is_arrow_function; }
|
||||
|
||||
virtual Vector<FlyString> const& local_variables_names() const override { return shared_data().m_local_variables_names; }
|
||||
virtual Vector<LocalVariable> const& local_variables_names() const override { return shared_data().m_local_variables_names; }
|
||||
|
||||
FunctionKind kind() const { return shared_data().m_kind; }
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/StringView.h>
|
||||
#include <LibJS/LocalVariable.h>
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
#include <LibJS/Runtime/PrivateEnvironment.h>
|
||||
#include <LibJS/Runtime/PropertyKey.h>
|
||||
|
@ -37,7 +38,7 @@ public:
|
|||
// [[Realm]]
|
||||
virtual Realm* realm() const { return nullptr; }
|
||||
|
||||
virtual Vector<FlyString> const& local_variables_names() const { VERIFY_NOT_REACHED(); }
|
||||
virtual Vector<LocalVariable> const& local_variables_names() const { VERIFY_NOT_REACHED(); }
|
||||
|
||||
virtual FunctionParameters const& formal_parameters() const { VERIFY_NOT_REACHED(); }
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue