LibJS: Allow using local variable for catch parameters

Local variables are faster to access and if all catch parameters are
locals we can skip lexical environment allocation.
This commit is contained in:
Aliaksandr Kalenik 2025-04-22 00:05:36 +02:00 committed by Alexander Kalenik
parent 0f14c70252
commit 7932091e02
Notes: github-actions[bot] 2025-04-22 19:58:29 +00:00
3 changed files with 49 additions and 28 deletions

View file

@ -2661,17 +2661,35 @@ Bytecode::CodeGenerationErrorOr<Optional<ScopedOperand>> TryStatement::generate_
TRY(m_handler->parameter().visit(
[&](NonnullRefPtr<Identifier const> const& parameter) -> Bytecode::CodeGenerationErrorOr<void> {
generator.begin_variable_scope();
did_create_variable_scope_for_catch_clause = true;
auto parameter_identifier = generator.intern_identifier(parameter->string());
generator.emit<Bytecode::Op::CreateVariable>(parameter_identifier, Bytecode::Op::EnvironmentMode::Lexical, false);
generator.emit<Bytecode::Op::InitializeLexicalBinding>(parameter_identifier, caught_value);
if (parameter->is_local()) {
auto local = generator.local(parameter->local_variable_index());
generator.emit_mov(local, caught_value);
} else {
generator.begin_variable_scope();
did_create_variable_scope_for_catch_clause = true;
auto parameter_identifier = generator.intern_identifier(parameter->string());
generator.emit<Bytecode::Op::CreateVariable>(parameter_identifier, Bytecode::Op::EnvironmentMode::Lexical, false);
generator.emit<Bytecode::Op::InitializeLexicalBinding>(parameter_identifier, caught_value);
}
return {};
},
[&](NonnullRefPtr<BindingPattern const> const& binding_pattern) -> Bytecode::CodeGenerationErrorOr<void> {
generator.begin_variable_scope();
did_create_variable_scope_for_catch_clause = true;
TRY(binding_pattern->generate_bytecode(generator, Bytecode::Op::BindingInitializationMode::Initialize, caught_value, true));
MUST(binding_pattern->for_each_bound_identifier([&](auto const& identifier) {
if (!identifier.is_local())
did_create_variable_scope_for_catch_clause = true;
}));
if (did_create_variable_scope_for_catch_clause)
generator.begin_variable_scope();
MUST(binding_pattern->for_each_bound_identifier([&](auto const& identifier) {
if (identifier.is_local())
return;
auto parameter_identifier = generator.intern_identifier(identifier.string());
generator.emit<Bytecode::Op::CreateVariable>(parameter_identifier, Bytecode::Op::EnvironmentMode::Lexical, false);
}));
TRY(binding_pattern->generate_bytecode(generator, Bytecode::Op::BindingInitializationMode::Initialize, caught_value, false));
return {};
},
[](Empty) -> Bytecode::CodeGenerationErrorOr<void> {