From 4f488f7e07b0c9c8411a384f0ba76edab5c98777 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 25 Sep 2023 14:11:27 +0200 Subject: [PATCH] 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 { ... } --- Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp index 26fa3937e8..a66e569422 100644 --- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp @@ -2369,10 +2369,14 @@ Bytecode::CodeGenerationErrorOr TryStatement::generate_bytecode(Bytecode:: if (!m_finalizer) generator.emit(); - 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 { 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(parameter_identifier, Bytecode::Op::EnvironmentMode::Lexical, false); generator.emit(parameter_identifier, Bytecode::Op::SetVariable::InitializationMode::Initialize); @@ -2380,6 +2384,9 @@ Bytecode::CodeGenerationErrorOr TryStatement::generate_bytecode(Bytecode:: return {}; }, [&](NonnullRefPtr const& binding_pattern) -> Bytecode::CodeGenerationErrorOr { + generator.begin_variable_scope(); + did_create_variable_scope_for_catch_clause = true; + auto value_register = generator.allocate_register(); generator.emit(value_register); TRY(generate_binding_pattern_bytecode(generator, *binding_pattern, Bytecode::Op::SetVariable::InitializationMode::Initialize, value_register, true)); @@ -2393,7 +2400,9 @@ Bytecode::CodeGenerationErrorOr 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) {