From 0a6d7ce70c39b73184c2cbc49996a567e76010ac Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Thu, 9 May 2024 17:10:20 +0200 Subject: [PATCH] LibJS: Ensure capacity of lex/var environments --- Userland/Libraries/LibJS/Bytecode/Generator.cpp | 4 ++-- Userland/Libraries/LibJS/Bytecode/Interpreter.cpp | 5 ++++- Userland/Libraries/LibJS/Bytecode/Op.h | 12 ++++++++++-- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/Userland/Libraries/LibJS/Bytecode/Generator.cpp b/Userland/Libraries/LibJS/Bytecode/Generator.cpp index 016b23103b816d5..968beb52ae4ecf9 100644 --- a/Userland/Libraries/LibJS/Bytecode/Generator.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Generator.cpp @@ -116,7 +116,7 @@ CodeGenerationErrorOr Generator::emit_function_declaration_instantiation(E } } } else { - generator.emit(); + generator.emit(function.m_var_environment_bindings_count); if (scope_body) { for (auto const& variable_to_initialize : function.m_var_names_to_initialize_binding) { @@ -157,7 +157,7 @@ CodeGenerationErrorOr Generator::emit_function_declaration_instantiation(E if (!function.m_strict) { bool can_elide_declarative_environment = !function.m_contains_direct_call_to_eval && (!scope_body || !scope_body->has_lexical_declarations()); if (!can_elide_declarative_environment) { - generator.emit(); + generator.emit(function.m_lex_environment_bindings_count); } } diff --git a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp index 4d3c6980cececc2..75b1013d0b3a622 100644 --- a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp @@ -1258,7 +1258,9 @@ ThrowCompletionOr DeleteVariable::execute_impl(Bytecode::Interpreter& inte ThrowCompletionOr CreateLexicalEnvironment::execute_impl(Bytecode::Interpreter& interpreter) const { auto make_and_swap_envs = [&](auto& old_environment) { - GCPtr environment = new_declarative_environment(*old_environment).ptr(); + auto declarative_environment = new_declarative_environment(*old_environment).ptr(); + declarative_environment->ensure_capacity(m_capacity); + GCPtr environment = declarative_environment; swap(old_environment, environment); return environment; }; @@ -1271,6 +1273,7 @@ ThrowCompletionOr CreateVariableEnvironment::execute_impl(Bytecode::Interp { auto& running_execution_context = interpreter.vm().running_execution_context(); auto var_environment = new_declarative_environment(*running_execution_context.lexical_environment); + var_environment->ensure_capacity(m_capacity); running_execution_context.variable_environment = var_environment; running_execution_context.lexical_environment = var_environment; return {}; diff --git a/Userland/Libraries/LibJS/Bytecode/Op.h b/Userland/Libraries/LibJS/Bytecode/Op.h index c8fbf6480add653..baa1398b8d2e245 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.h +++ b/Userland/Libraries/LibJS/Bytecode/Op.h @@ -451,24 +451,32 @@ enum class EnvironmentMode { class CreateLexicalEnvironment final : public Instruction { public: - explicit CreateLexicalEnvironment() + explicit CreateLexicalEnvironment(u32 capacity = 0) : Instruction(Type::CreateLexicalEnvironment) + , m_capacity(capacity) { } ThrowCompletionOr execute_impl(Bytecode::Interpreter&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const; + +private: + u32 m_capacity { 0 }; }; class CreateVariableEnvironment final : public Instruction { public: - explicit CreateVariableEnvironment() + explicit CreateVariableEnvironment(u32 capacity = 0) : Instruction(Type::CreateVariableEnvironment) + , m_capacity(capacity) { } ThrowCompletionOr execute_impl(Bytecode::Interpreter&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const; + +private: + u32 m_capacity { 0 }; }; class EnterObjectEnvironment final : public Instruction {