LibJS: Keep parsed function parameters in a shared data structure

Instead of making a copy of the Vector<FunctionParameter> from the AST
every time we instantiate an ECMAScriptFunctionObject, we now keep the
parameters in a ref-counted FunctionParameters object.

This reduces memory usage, and also allows us to cache the bytecode
executables for default parameter expressions without recompiling them
for every instantiation. :^)
This commit is contained in:
Andreas Kling 2025-03-27 12:59:50 +00:00 committed by Jelle Raaijmakers
parent 634f0c2469
commit 7477002e46
Notes: github-actions[bot] 2025-03-27 15:02:02 +00:00
11 changed files with 68 additions and 38 deletions

View file

@ -1074,7 +1074,7 @@ Object* create_unmapped_arguments_object(VM& vm, ReadonlySpan<Value> 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<FunctionParameter> const& formals, ReadonlySpan<Value> arguments, Environment& environment)
Object* create_mapped_arguments_object(VM& vm, FunctionObject& function, NonnullRefPtr<FunctionParameters const> const& formals, ReadonlySpan<Value> arguments, Environment& environment)
{
auto& realm = *vm.current_realm();
@ -1113,10 +1113,10 @@ Object* create_mapped_arguments_object(VM& vm, FunctionObject& function, Vector<
// 18. Set index to numberOfParameters - 1.
// 19. Repeat, while index ≥ 0,
VERIFY(formals.size() <= NumericLimits<i32>::max());
for (i32 index = static_cast<i32>(formals.size()) - 1; index >= 0; --index) {
VERIFY(formals->size() <= NumericLimits<i32>::max());
for (i32 index = static_cast<i32>(formals->size()) - 1; index >= 0; --index) {
// a. Let name be parameterNames[index].
auto const& name = formals[index].binding.get<NonnullRefPtr<Identifier const>>()->string();
auto const& name = formals->parameters()[index].binding.get<NonnullRefPtr<Identifier const>>()->string();
// b. If name is not an element of mappedNames, then
if (mapped_names.contains(name))