1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-16 13:44:57 +00:00

LibJS: Avoid creating empty environment for catch without parameter

When there is no `catch` parameter to bind the error, we don't need
to allocate an environment, since there's nothing to add to it.

This avoids one environment allocation every time we catch like this:

    try {
        ...
    } catch {
        ...
    }
This commit is contained in:
Andreas Kling 2023-09-25 14:11:27 +02:00
parent 4c64c0b61e
commit 4f488f7e07

View file

@ -2369,10 +2369,14 @@ Bytecode::CodeGenerationErrorOr<void> TryStatement::generate_bytecode(Bytecode::
if (!m_finalizer)
generator.emit<Bytecode::Op::LeaveUnwindContext>();
generator.begin_variable_scope();
// OPTIMIZATION: We avoid creating a lexical environment if the catch clause has no parameter.
bool did_create_variable_scope_for_catch_clause = false;
TRY(m_handler->parameter().visit(
[&](DeprecatedFlyString const& parameter) -> Bytecode::CodeGenerationErrorOr<void> {
if (!parameter.is_empty()) {
generator.begin_variable_scope();
did_create_variable_scope_for_catch_clause = true;
auto parameter_identifier = generator.intern_identifier(parameter);
generator.emit<Bytecode::Op::CreateVariable>(parameter_identifier, Bytecode::Op::EnvironmentMode::Lexical, false);
generator.emit<Bytecode::Op::SetVariable>(parameter_identifier, Bytecode::Op::SetVariable::InitializationMode::Initialize);
@ -2380,6 +2384,9 @@ Bytecode::CodeGenerationErrorOr<void> TryStatement::generate_bytecode(Bytecode::
return {};
},
[&](NonnullRefPtr<BindingPattern const> const& binding_pattern) -> Bytecode::CodeGenerationErrorOr<void> {
generator.begin_variable_scope();
did_create_variable_scope_for_catch_clause = true;
auto value_register = generator.allocate_register();
generator.emit<Bytecode::Op::Store>(value_register);
TRY(generate_binding_pattern_bytecode(generator, *binding_pattern, Bytecode::Op::SetVariable::InitializationMode::Initialize, value_register, true));
@ -2393,7 +2400,9 @@ Bytecode::CodeGenerationErrorOr<void> TryStatement::generate_bytecode(Bytecode::
TRY(m_handler->body().generate_bytecode(generator));
handler_target = Bytecode::Label { handler_block };
generator.end_variable_scope();
if (did_create_variable_scope_for_catch_clause)
generator.end_variable_scope();
if (!generator.is_current_block_terminated()) {
if (m_finalizer) {