diff --git a/Userland/Libraries/LibJS/Bytecode/Generator.cpp b/Userland/Libraries/LibJS/Bytecode/Generator.cpp index 290829b2b6..f7b6b5b4f2 100644 --- a/Userland/Libraries/LibJS/Bytecode/Generator.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Generator.cpp @@ -120,7 +120,7 @@ CodeGenerationErrorOr Generator::emit_function_declaration_instantiation(E } } } else { - emit(); + emit(function.m_var_environment_bindings_count); if (scope_body) { for (auto const& variable_to_initialize : function.m_var_names_to_initialize_binding) { @@ -158,7 +158,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_non_local_lexical_declarations()); if (!can_elide_declarative_environment) { - emit(); + emit(function.m_lex_environment_bindings_count); } } diff --git a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp index 22f2895c26..d39b0cbd15 100644 --- a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp @@ -1256,7 +1256,9 @@ ThrowCompletionOr DeleteVariable::execute_impl(Bytecode::Interpreter& inte void 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; }; @@ -1268,6 +1270,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 661a7b25d9..970d2c2bd9 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.h +++ b/Userland/Libraries/LibJS/Bytecode/Op.h @@ -443,24 +443,32 @@ enum class EnvironmentMode { class CreateLexicalEnvironment final : public Instruction { public: - explicit CreateLexicalEnvironment() + explicit CreateLexicalEnvironment(u32 capacity = 0) : Instruction(Type::CreateLexicalEnvironment) + , m_capacity(capacity) { } void 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 {