LibJS: Add ECMAScriptFunctionObject::create_from_function_node() helper

This gives us a shared entry point for every situation where we
instantiate a function based on a FunctionNode from the AST.
This commit is contained in:
Andreas Kling 2025-04-07 21:08:55 +02:00 committed by Andreas Kling
commit 4209b18b88
Notes: github-actions[bot] 2025-04-08 16:54:03 +00:00
7 changed files with 95 additions and 27 deletions

View file

@ -972,8 +972,12 @@ ThrowCompletionOr<void> eval_declaration_instantiation(VM& vm, Program const& pr
for (auto& declaration : functions_to_initialize.in_reverse()) {
// a. Let fn be the sole element of the BoundNames of f.
// b. Let fo be InstantiateFunctionObject of f with arguments lexEnv and privateEnv.
auto function = ECMAScriptFunctionObject::create(realm, declaration.name(), declaration.source_text(), declaration.body(), declaration.parameters(), declaration.function_length(), declaration.local_variables_names(), lexical_environment, private_environment, declaration.kind(), declaration.is_strict_mode(),
declaration.parsing_insights());
auto function = ECMAScriptFunctionObject::create_from_function_node(
declaration,
declaration.name(),
realm,
lexical_environment,
private_environment);
// c. If varEnv is a global Environment Record, then
if (global_var_environment) {

View file

@ -58,6 +58,47 @@ GC::Ref<ECMAScriptFunctionObject> ECMAScriptFunctionObject::create(Realm& realm,
return realm.create<ECMAScriptFunctionObject>(move(name), move(source_text), ecmascript_code, move(parameters), m_function_length, move(local_variables_names), parent_environment, private_environment, prototype, kind, is_strict, parsing_insights, is_arrow_function, move(class_field_initializer_name));
}
GC::Ref<ECMAScriptFunctionObject> ECMAScriptFunctionObject::create_from_function_node(
FunctionNode const& function_node,
FlyString name,
GC::Ref<Realm> realm,
GC::Ptr<Environment> parent_environment,
GC::Ptr<PrivateEnvironment> private_environment)
{
GC::Ptr<Object> prototype = nullptr;
switch (function_node.kind()) {
case FunctionKind::Normal:
prototype = realm->intrinsics().function_prototype();
break;
case FunctionKind::Generator:
prototype = realm->intrinsics().generator_function_prototype();
break;
case FunctionKind::Async:
prototype = realm->intrinsics().async_function_prototype();
break;
case FunctionKind::AsyncGenerator:
prototype = realm->intrinsics().async_generator_function_prototype();
break;
}
return create(
*realm,
move(name),
*prototype,
function_node.source_text(),
*function_node.body_ptr(),
function_node.parameters(),
function_node.function_length(),
function_node.local_variables_names(),
parent_environment,
private_environment,
function_node.kind(),
function_node.is_strict_mode(),
function_node.parsing_insights(),
function_node.is_arrow_function(),
Variant<PropertyKey, PrivateName, Empty> {});
}
ECMAScriptFunctionObject::ECMAScriptFunctionObject(FlyString name, ByteString source_text, Statement const& ecmascript_code, NonnullRefPtr<FunctionParameters const> formal_parameters, i32 function_length, Vector<FlyString> local_variables_names, Environment* parent_environment, PrivateEnvironment* private_environment, Object& prototype, FunctionKind kind, bool strict, FunctionParsingInsights parsing_insights, bool is_arrow_function, Variant<PropertyKey, PrivateName, Empty> class_field_initializer_name)
: FunctionObject(prototype)
, m_name(move(name))

View file

@ -42,6 +42,13 @@ public:
static GC::Ref<ECMAScriptFunctionObject> create(Realm&, FlyString name, ByteString source_text, Statement const& ecmascript_code, NonnullRefPtr<FunctionParameters const> parameters, i32 m_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 m_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 = {});
[[nodiscard]] static GC::Ref<ECMAScriptFunctionObject> create_from_function_node(
FunctionNode const&,
FlyString name,
GC::Ref<Realm>,
GC::Ptr<Environment> parent_environment,
GC::Ptr<PrivateEnvironment>);
virtual void initialize(Realm&) override;
virtual ~ECMAScriptFunctionObject() override = default;