LibJS: Skip allocating locals for arguments that allowed to be local

This allows us to get rid of instructions that move arguments to locals
and allocate smaller JS::Value vector in ExecutionContext by reusing
slots that were already allocated for arguments.

With this change for following function:
```js
function f(x, y) {
    return x + y;
}
```

we now produce following bytecode:
```
[   0]    0: Add dst:reg6, lhs:arg0, rhs:arg1
[  10]       Return value:reg6
```

instead of:
```
[   0]    0: GetArgument 0, dst:x~1
[  10]       GetArgument 1, dst:y~0
[  20]       Add dst:reg6, lhs:x~1, rhs:y~0
[  30]       Return value:reg6
```
This commit is contained in:
Aliaksandr Kalenik 2025-04-25 17:10:47 +02:00 committed by Andreas Kling
commit 2d732b2251
Notes: github-actions[bot] 2025-04-26 09:03:23 +00:00
6 changed files with 102 additions and 39 deletions

View file

@ -1027,7 +1027,7 @@ void Identifier::dump(int indent) const
{
print_indent(indent);
if (is_local()) {
outln("Identifier \"{}\" is_local=(true) index=({})", m_string, m_local_variable_index);
outln("Identifier \"{}\" is_local=(true) index=({})", m_string, m_local_index->index);
} else if (is_global()) {
outln("Identifier \"{}\" is_global=(true)", m_string);
} else {
@ -1668,7 +1668,12 @@ void ScopeNode::block_declaration_instantiation(VM& vm, Environment* environment
auto& running_execution_context = vm.running_execution_context();
auto number_of_registers = running_execution_context.executable->number_of_registers;
auto number_of_constants = running_execution_context.executable->constants.size();
running_execution_context.local(function_declaration.name_identifier()->local_variable_index() + number_of_registers + number_of_constants) = function;
auto local_index = function_declaration.name_identifier()->local_index();
if (local_index.is_variable()) {
running_execution_context.local(local_index.index + number_of_registers + number_of_constants) = function;
} else {
VERIFY_NOT_REACHED();
}
} else {
VERIFY(is<DeclarativeEnvironment>(*environment));
static_cast<DeclarativeEnvironment&>(*environment).initialize_or_set_mutable_binding({}, vm, function_declaration.name(), function);