diff --git a/Userland/Libraries/LibJS/AST.h b/Userland/Libraries/LibJS/AST.h index a260478866..40a23f8bb9 100644 --- a/Userland/Libraries/LibJS/AST.h +++ b/Userland/Libraries/LibJS/AST.h @@ -607,18 +607,18 @@ struct BindingPattern : RefCounted { Kind kind { Kind::Object }; }; +struct FunctionParameter { + Variant> binding; + RefPtr default_value; + bool is_rest { false }; +}; + class FunctionNode { public: - struct Parameter { - Variant> binding; - RefPtr default_value; - bool is_rest { false }; - }; - FlyString const& name() const { return m_name; } String const& source_text() const { return m_source_text; } Statement const& body() const { return *m_body; } - Vector const& parameters() const { return m_parameters; }; + Vector const& parameters() const { return m_parameters; }; i32 function_length() const { return m_function_length; } bool is_strict_mode() const { return m_is_strict_mode; } bool might_need_arguments_object() const { return m_might_need_arguments_object; } @@ -627,7 +627,7 @@ public: FunctionKind kind() const { return m_kind; } protected: - FunctionNode(FlyString name, String source_text, NonnullRefPtr body, Vector parameters, i32 function_length, FunctionKind kind, bool is_strict_mode, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function) + FunctionNode(FlyString name, String source_text, NonnullRefPtr body, Vector parameters, i32 function_length, FunctionKind kind, bool is_strict_mode, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function) : m_name(move(name)) , m_source_text(move(source_text)) , m_body(move(body)) @@ -649,7 +649,7 @@ private: FlyString m_name; String m_source_text; NonnullRefPtr m_body; - Vector const m_parameters; + Vector const m_parameters; const i32 m_function_length; FunctionKind m_kind; bool m_is_strict_mode { false }; @@ -664,7 +664,7 @@ class FunctionDeclaration final public: static bool must_have_name() { return true; } - FunctionDeclaration(SourceRange source_range, FlyString const& name, String source_text, NonnullRefPtr body, Vector parameters, i32 function_length, FunctionKind kind, bool is_strict_mode, bool might_need_arguments_object, bool contains_direct_call_to_eval) + FunctionDeclaration(SourceRange source_range, FlyString const& name, String source_text, NonnullRefPtr body, Vector parameters, i32 function_length, FunctionKind kind, bool is_strict_mode, bool might_need_arguments_object, bool contains_direct_call_to_eval) : Declaration(source_range) , FunctionNode(name, move(source_text), move(body), move(parameters), function_length, kind, is_strict_mode, might_need_arguments_object, contains_direct_call_to_eval, false) { @@ -690,7 +690,7 @@ class FunctionExpression final public: static bool must_have_name() { return false; } - FunctionExpression(SourceRange source_range, FlyString const& name, String source_text, NonnullRefPtr body, Vector parameters, i32 function_length, FunctionKind kind, bool is_strict_mode, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function = false) + FunctionExpression(SourceRange source_range, FlyString const& name, String source_text, NonnullRefPtr body, Vector parameters, i32 function_length, FunctionKind kind, bool is_strict_mode, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function = false) : Expression(source_range) , FunctionNode(name, move(source_text), move(body), move(parameters), function_length, kind, is_strict_mode, might_need_arguments_object, contains_direct_call_to_eval, is_arrow_function) { diff --git a/Userland/Libraries/LibJS/Forward.h b/Userland/Libraries/LibJS/Forward.h index f38f0d7b62..3277efe786 100644 --- a/Userland/Libraries/LibJS/Forward.h +++ b/Userland/Libraries/LibJS/Forward.h @@ -169,6 +169,7 @@ class Expression; class ForStatement; class FunctionEnvironment; class FunctionNode; +struct FunctionParameter; class GlobalEnvironment; class GlobalObject; class HandleImpl; diff --git a/Userland/Libraries/LibJS/Parser.cpp b/Userland/Libraries/LibJS/Parser.cpp index 6610a52d49..ec5387b1fa 100644 --- a/Userland/Libraries/LibJS/Parser.cpp +++ b/Userland/Libraries/LibJS/Parser.cpp @@ -59,7 +59,7 @@ private: } public: - static ScopePusher function_scope(Parser& parser, FunctionBody& function_body, Vector const& parameters) + static ScopePusher function_scope(Parser& parser, FunctionBody& function_body, Vector const& parameters) { ScopePusher scope_pusher(parser, &function_body, ScopeLevel::FunctionTopLevel); scope_pusher.m_function_parameters = parameters; @@ -200,7 +200,7 @@ public: return nullptr; } - Vector const& function_parameters() const + Vector const& function_parameters() const { return *m_function_parameters; } @@ -274,7 +274,7 @@ private: HashTable m_forbidden_var_names; NonnullRefPtrVector m_functions_to_hoist; - Optional> m_function_parameters; + Optional> m_function_parameters; bool m_contains_access_to_arguments_object { false }; bool m_contains_direct_call_to_eval { false }; @@ -704,9 +704,9 @@ static bool is_strict_reserved_word(StringView str) }); } -static bool is_simple_parameter_list(Vector const& parameters) +static bool is_simple_parameter_list(Vector const& parameters) { - return all_of(parameters, [](FunctionNode::Parameter const& parameter) { + return all_of(parameters, [](FunctionParameter const& parameter) { return !parameter.is_rest && parameter.default_value.is_null() && parameter.binding.has(); }); } @@ -756,7 +756,7 @@ RefPtr Parser::try_parse_arrow_function_expression(bool expe } } - Vector parameters; + Vector parameters; i32 function_length = -1; if (expect_parens) { // We have parens around the function parameters and can re-use the same parsing @@ -1343,12 +1343,12 @@ NonnullRefPtr Parser::parse_class_expression(bool expect_class_ constructor = create_ast_node( { m_source_code, rule_start.position(), position() }, class_name, "", - move(constructor_body), Vector { FunctionNode::Parameter { move(argument_name), nullptr, true } }, 0, FunctionKind::Normal, + move(constructor_body), Vector { FunctionParameter { move(argument_name), nullptr, true } }, 0, FunctionKind::Normal, /* is_strict_mode */ true, /* might_need_arguments_object */ false, /* contains_direct_call_to_eval */ false); } else { constructor = create_ast_node( { m_source_code, rule_start.position(), position() }, class_name, "", - move(constructor_body), Vector {}, 0, FunctionKind::Normal, + move(constructor_body), Vector {}, 0, FunctionKind::Normal, /* is_strict_mode */ true, /* might_need_arguments_object */ false, /* contains_direct_call_to_eval */ false); } } @@ -2458,7 +2458,7 @@ void Parser::parse_statement_list(ScopeNode& output_node, AllowLabelledFunction } // FunctionBody, https://tc39.es/ecma262/#prod-FunctionBody -NonnullRefPtr Parser::parse_function_body(Vector const& parameters, FunctionKind function_kind, bool& contains_direct_call_to_eval) +NonnullRefPtr Parser::parse_function_body(Vector const& parameters, FunctionKind function_kind, bool& contains_direct_call_to_eval) { auto rule_start = push_start(); auto function_body = create_ast_node({ m_source_code, rule_start.position(), position() }); @@ -2632,14 +2632,14 @@ NonnullRefPtr Parser::parse_function_node(u16 parse_options, O contains_direct_call_to_eval); } -Vector Parser::parse_formal_parameters(int& function_length, u16 parse_options) +Vector Parser::parse_formal_parameters(int& function_length, u16 parse_options) { auto rule_start = push_start(); bool has_default_parameter = false; bool has_rest_parameter = false; TemporaryChange formal_parameter_context_change { m_state.in_formal_parameter_context, true }; - Vector parameters; + Vector parameters; auto consume_identifier_or_binding_pattern = [&]() -> Variant> { if (auto pattern = parse_binding_pattern(AllowDuplicates::No, AllowMemberExpressions::No)) diff --git a/Userland/Libraries/LibJS/Parser.h b/Userland/Libraries/LibJS/Parser.h index 43cb378d8e..2f0e73db68 100644 --- a/Userland/Libraries/LibJS/Parser.h +++ b/Userland/Libraries/LibJS/Parser.h @@ -58,7 +58,7 @@ public: template NonnullRefPtr parse_function_node(u16 parse_options = FunctionNodeParseOptions::CheckForFunctionAndName, Optional const& function_start = {}); - Vector parse_formal_parameters(int& function_length, u16 parse_options = 0); + Vector parse_formal_parameters(int& function_length, u16 parse_options = 0); enum class AllowDuplicates { Yes, @@ -86,7 +86,7 @@ public: NonnullRefPtr parse_statement(AllowLabelledFunction allow_labelled_function = AllowLabelledFunction::No); NonnullRefPtr parse_block_statement(); - NonnullRefPtr parse_function_body(Vector const& parameters, FunctionKind function_kind, bool& contains_direct_call_to_eval); + NonnullRefPtr parse_function_body(Vector const& parameters, FunctionKind function_kind, bool& contains_direct_call_to_eval); NonnullRefPtr parse_return_statement(); NonnullRefPtr parse_variable_declaration(bool for_loop_variable_declaration = false); NonnullRefPtr parse_for_statement(); diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp index c3dd6b5ae7..77dfb031bb 100644 --- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp +++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp @@ -1065,7 +1065,7 @@ Object* create_unmapped_arguments_object(VM& vm, Span arguments) } // 10.4.4.7 CreateMappedArgumentsObject ( func, formals, argumentsList, env ), https://tc39.es/ecma262/#sec-createmappedargumentsobject -Object* create_mapped_arguments_object(VM& vm, FunctionObject& function, Vector const& formals, Span arguments, Environment& environment) +Object* create_mapped_arguments_object(VM& vm, FunctionObject& function, Vector const& formals, Span arguments, Environment& environment) { auto& realm = *vm.current_realm(); diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.h b/Userland/Libraries/LibJS/Runtime/AbstractOperations.h index a004f1e599..affb1a63e0 100644 --- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.h +++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.h @@ -40,7 +40,7 @@ bool is_compatible_property_descriptor(bool extensible, PropertyDescriptor const bool validate_and_apply_property_descriptor(Object*, PropertyKey const&, bool extensible, PropertyDescriptor const&, Optional const& current); ThrowCompletionOr get_prototype_from_constructor(VM&, FunctionObject const& constructor, Object* (Intrinsics::*intrinsic_default_prototype)()); Object* create_unmapped_arguments_object(VM&, Span arguments); -Object* create_mapped_arguments_object(VM&, FunctionObject&, Vector const&, Span arguments, Environment&); +Object* create_mapped_arguments_object(VM&, FunctionObject&, Vector const&, Span arguments, Environment&); enum class CanonicalIndexMode { DetectNumericRoundtrip, diff --git a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp index 5fd32e9cae..6cb9a90197 100644 --- a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp @@ -28,7 +28,7 @@ namespace JS { -ECMAScriptFunctionObject* ECMAScriptFunctionObject::create(Realm& realm, FlyString name, String source_text, Statement const& ecmascript_code, Vector parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant class_field_initializer_name) +ECMAScriptFunctionObject* ECMAScriptFunctionObject::create(Realm& realm, FlyString name, String source_text, Statement const& ecmascript_code, Vector parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant class_field_initializer_name) { Object* prototype = nullptr; switch (kind) { @@ -48,12 +48,12 @@ ECMAScriptFunctionObject* ECMAScriptFunctionObject::create(Realm& realm, FlyStri return realm.heap().allocate(realm, move(name), move(source_text), ecmascript_code, move(parameters), m_function_length, parent_environment, private_environment, *prototype, kind, is_strict, might_need_arguments_object, contains_direct_call_to_eval, is_arrow_function, move(class_field_initializer_name)); } -ECMAScriptFunctionObject* ECMAScriptFunctionObject::create(Realm& realm, FlyString name, Object& prototype, String source_text, Statement const& ecmascript_code, Vector parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant class_field_initializer_name) +ECMAScriptFunctionObject* ECMAScriptFunctionObject::create(Realm& realm, FlyString name, Object& prototype, String source_text, Statement const& ecmascript_code, Vector parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind kind, bool is_strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant class_field_initializer_name) { return realm.heap().allocate(realm, move(name), move(source_text), ecmascript_code, move(parameters), m_function_length, parent_environment, private_environment, prototype, kind, is_strict, might_need_arguments_object, contains_direct_call_to_eval, is_arrow_function, move(class_field_initializer_name)); } -ECMAScriptFunctionObject::ECMAScriptFunctionObject(FlyString name, String source_text, Statement const& ecmascript_code, Vector formal_parameters, i32 function_length, Environment* parent_environment, PrivateEnvironment* private_environment, Object& prototype, FunctionKind kind, bool strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant class_field_initializer_name) +ECMAScriptFunctionObject::ECMAScriptFunctionObject(FlyString name, String source_text, Statement const& ecmascript_code, Vector formal_parameters, i32 function_length, Environment* parent_environment, PrivateEnvironment* private_environment, Object& prototype, FunctionKind kind, bool strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant class_field_initializer_name) : FunctionObject(prototype) , m_name(move(name)) , m_function_length(function_length) diff --git a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h index 038ab5f9c1..79b6b898c7 100644 --- a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h +++ b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.h @@ -32,8 +32,8 @@ public: Global, }; - static ECMAScriptFunctionObject* create(Realm&, FlyString name, String source_text, Statement const& ecmascript_code, Vector parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind, bool is_strict, bool might_need_arguments_object = true, bool contains_direct_call_to_eval = true, bool is_arrow_function = false, Variant class_field_initializer_name = {}); - static ECMAScriptFunctionObject* create(Realm&, FlyString name, Object& prototype, String source_text, Statement const& ecmascript_code, Vector parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind, bool is_strict, bool might_need_arguments_object = true, bool contains_direct_call_to_eval = true, bool is_arrow_function = false, Variant class_field_initializer_name = {}); + static ECMAScriptFunctionObject* create(Realm&, FlyString name, String source_text, Statement const& ecmascript_code, Vector parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind, bool is_strict, bool might_need_arguments_object = true, bool contains_direct_call_to_eval = true, bool is_arrow_function = false, Variant class_field_initializer_name = {}); + static ECMAScriptFunctionObject* create(Realm&, FlyString name, Object& prototype, String source_text, Statement const& ecmascript_code, Vector parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, FunctionKind, bool is_strict, bool might_need_arguments_object = true, bool contains_direct_call_to_eval = true, bool is_arrow_function = false, Variant class_field_initializer_name = {}); virtual void initialize(Realm&) override; virtual ~ECMAScriptFunctionObject() override = default; @@ -44,7 +44,7 @@ public: void make_method(Object& home_object); Statement const& ecmascript_code() const { return m_ecmascript_code; } - Vector const& formal_parameters() const { return m_formal_parameters; }; + Vector const& formal_parameters() const { return m_formal_parameters; }; virtual FlyString const& name() const override { return m_name; }; void set_name(FlyString const& name); @@ -93,7 +93,7 @@ protected: virtual Completion ordinary_call_evaluate_body(); private: - ECMAScriptFunctionObject(FlyString name, String source_text, Statement const& ecmascript_code, Vector parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, Object& prototype, FunctionKind, bool is_strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant class_field_initializer_name); + ECMAScriptFunctionObject(FlyString name, String source_text, Statement const& ecmascript_code, Vector parameters, i32 m_function_length, Environment* parent_environment, PrivateEnvironment* private_environment, Object& prototype, FunctionKind, bool is_strict, bool might_need_arguments_object, bool contains_direct_call_to_eval, bool is_arrow_function, Variant class_field_initializer_name); virtual bool is_ecmascript_function_object() const override { return true; } virtual void visit_edges(Visitor&) override; @@ -113,7 +113,7 @@ private: // Internal Slots of ECMAScript Function Objects, https://tc39.es/ecma262/#table-internal-slots-of-ecmascript-function-objects Environment* m_environment { nullptr }; // [[Environment]] PrivateEnvironment* m_private_environment { nullptr }; // [[PrivateEnvironment]] - Vector const m_formal_parameters; // [[FormalParameters]] + Vector const m_formal_parameters; // [[FormalParameters]] NonnullRefPtr m_ecmascript_code; // [[ECMAScriptCode]] Realm* m_realm { nullptr }; // [[Realm]] ScriptOrModule m_script_or_module; // [[ScriptOrModule]]