diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp index 88dc36a633f..5b986151a9b 100644 --- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp @@ -397,7 +397,7 @@ Bytecode::CodeGenerationErrorOr> Identifier::generate_by if (is_global()) { generator.emit(dst, generator.intern_identifier(m_string), generator.next_global_variable_cache()); } else { - generator.emit(dst, generator.intern_identifier(m_string), generator.next_environment_variable_cache()); + generator.emit(dst, generator.intern_identifier(m_string)); } return dst; } @@ -1140,8 +1140,8 @@ Bytecode::CodeGenerationErrorOr> FunctionDeclaration::ge Bytecode::Generator::SourceLocationScope scope(generator, *this); auto index = generator.intern_identifier(name()); auto value = generator.allocate_register(); - generator.emit(value, index, generator.next_environment_variable_cache()); - generator.emit(index, value, generator.next_environment_variable_cache(), Bytecode::Op::SetVariable::InitializationMode::Set, Bytecode::Op::EnvironmentMode::Var); + generator.emit(value, index); + generator.emit(index, value, Bytecode::Op::SetVariable::InitializationMode::Set, Bytecode::Op::EnvironmentMode::Var); } return Optional {}; } @@ -1163,7 +1163,7 @@ Bytecode::CodeGenerationErrorOr> FunctionExpression::gen generator.emit_new_function(new_function, *this, lhs_name); if (has_name) { - generator.emit(*name_identifier, new_function, generator.next_environment_variable_cache(), Bytecode::Op::SetVariable::InitializationMode::Initialize, Bytecode::Op::EnvironmentMode::Lexical); + generator.emit(*name_identifier, new_function, Bytecode::Op::SetVariable::InitializationMode::Initialize, Bytecode::Op::EnvironmentMode::Lexical); generator.end_variable_scope(); } @@ -1641,8 +1641,7 @@ Bytecode::CodeGenerationErrorOr> CallExpression::generat generator.emit( *original_callee, this_value, - generator.intern_identifier(identifier.string()), - generator.next_environment_variable_cache()); + generator.intern_identifier(identifier.string())); } } else { // FIXME: this = global object in sloppy mode. @@ -2553,7 +2552,7 @@ Bytecode::CodeGenerationErrorOr> TryStatement::generate_ 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, caught_value, generator.next_environment_variable_cache(), Bytecode::Op::SetVariable::InitializationMode::Initialize); + generator.emit(parameter_identifier, caught_value, Bytecode::Op::SetVariable::InitializationMode::Initialize); } return {}; }, @@ -3437,7 +3436,6 @@ Bytecode::CodeGenerationErrorOr> ExportStatement::genera generator.emit( generator.intern_identifier(ExportStatement::local_name_for_default), value, - generator.next_environment_variable_cache(), Bytecode::Op::SetVariable::InitializationMode::Initialize); } @@ -3450,7 +3448,6 @@ Bytecode::CodeGenerationErrorOr> ExportStatement::genera generator.emit( generator.intern_identifier(ExportStatement::local_name_for_default), value, - generator.next_environment_variable_cache(), Bytecode::Op::SetVariable::InitializationMode::Initialize); return value; } diff --git a/Userland/Libraries/LibJS/Bytecode/CommonImplementations.h b/Userland/Libraries/LibJS/Bytecode/CommonImplementations.h index 7e6e23c3f4d..f502df24411 100644 --- a/Userland/Libraries/LibJS/Bytecode/CommonImplementations.h +++ b/Userland/Libraries/LibJS/Bytecode/CommonImplementations.h @@ -405,12 +405,12 @@ inline ThrowCompletionOr set_variable( Value value, Op::EnvironmentMode mode, Op::SetVariable::InitializationMode initialization_mode, - EnvironmentVariableCache& cache) + EnvironmentCoordinate& cache) { auto environment = mode == Op::EnvironmentMode::Lexical ? vm.running_execution_context().lexical_environment : vm.running_execution_context().variable_environment; auto reference = TRY(vm.resolve_binding(name, environment)); if (reference.environment_coordinate().has_value()) - cache = reference.environment_coordinate(); + cache = reference.environment_coordinate().value(); switch (initialization_mode) { case Op::SetVariable::InitializationMode::Initialize: TRY(reference.initialize_referenced_binding(vm, value)); @@ -530,19 +530,19 @@ struct CalleeAndThis { Value this_value; }; -inline ThrowCompletionOr get_callee_and_this_from_environment(Bytecode::Interpreter& interpreter, DeprecatedFlyString const& name, EnvironmentVariableCache& cache) +inline ThrowCompletionOr get_callee_and_this_from_environment(Bytecode::Interpreter& interpreter, DeprecatedFlyString const& name, EnvironmentCoordinate& cache) { auto& vm = interpreter.vm(); Value callee = js_undefined(); Value this_value = js_undefined(); - if (cache.has_value()) { + if (cache.is_valid()) { auto const* environment = interpreter.running_execution_context().lexical_environment.ptr(); - for (size_t i = 0; i < cache->hops; ++i) + for (size_t i = 0; i < cache.hops; ++i) environment = environment->outer_environment(); if (!environment->is_permanently_screwed_by_eval()) { - callee = TRY(static_cast(*environment).get_binding_value_direct(vm, cache.value().index)); + callee = TRY(static_cast(*environment).get_binding_value_direct(vm, cache.index)); this_value = js_undefined(); if (auto base_object = environment->with_base_object()) this_value = base_object; @@ -556,7 +556,7 @@ inline ThrowCompletionOr get_callee_and_this_from_environment(Byt auto reference = TRY(vm.resolve_binding(name)); if (reference.environment_coordinate().has_value()) - cache = reference.environment_coordinate(); + cache = reference.environment_coordinate().value(); callee = TRY(reference.get_value(vm)); diff --git a/Userland/Libraries/LibJS/Bytecode/Executable.cpp b/Userland/Libraries/LibJS/Bytecode/Executable.cpp index fad33864d87..c8ec6bcac5a 100644 --- a/Userland/Libraries/LibJS/Bytecode/Executable.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Executable.cpp @@ -23,7 +23,6 @@ Executable::Executable( NonnullRefPtr source_code, size_t number_of_property_lookup_caches, size_t number_of_global_variable_caches, - size_t number_of_environment_variable_caches, size_t number_of_registers, bool is_strict_mode) : bytecode(move(bytecode)) @@ -37,7 +36,6 @@ Executable::Executable( { property_lookup_caches.resize(number_of_property_lookup_caches); global_variable_caches.resize(number_of_global_variable_caches); - environment_variable_caches.resize(number_of_environment_variable_caches); } Executable::~Executable() = default; diff --git a/Userland/Libraries/LibJS/Bytecode/Executable.h b/Userland/Libraries/LibJS/Bytecode/Executable.h index 79b026ca07a..01270a0f0bc 100644 --- a/Userland/Libraries/LibJS/Bytecode/Executable.h +++ b/Userland/Libraries/LibJS/Bytecode/Executable.h @@ -33,8 +33,6 @@ struct GlobalVariableCache : public PropertyLookupCache { u64 environment_serial_number { 0 }; }; -using EnvironmentVariableCache = Optional; - struct SourceRecord { u32 source_start_offset {}; u32 source_end_offset {}; @@ -54,7 +52,6 @@ public: NonnullRefPtr, size_t number_of_property_lookup_caches, size_t number_of_global_variable_caches, - size_t number_of_environment_variable_caches, size_t number_of_registers, bool is_strict_mode); @@ -64,7 +61,6 @@ public: Vector bytecode; Vector property_lookup_caches; Vector global_variable_caches; - Vector environment_variable_caches; NonnullOwnPtr string_table; NonnullOwnPtr identifier_table; NonnullOwnPtr regex_table; diff --git a/Userland/Libraries/LibJS/Bytecode/Generator.cpp b/Userland/Libraries/LibJS/Bytecode/Generator.cpp index 246e68bbbea..ee5320099c1 100644 --- a/Userland/Libraries/LibJS/Bytecode/Generator.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Generator.cpp @@ -38,7 +38,7 @@ CodeGenerationErrorOr Generator::emit_function_declaration_instantiation(E auto id = intern_identifier(parameter_name.key); emit(id, Op::EnvironmentMode::Lexical, false); if (function.m_has_duplicates) { - emit(id, add_constant(js_undefined()), next_environment_variable_cache(), Op::SetVariable::InitializationMode::Initialize, Op::EnvironmentMode::Lexical); + emit(id, add_constant(js_undefined()), Op::SetVariable::InitializationMode::Initialize, Op::EnvironmentMode::Lexical); } } } @@ -90,7 +90,6 @@ CodeGenerationErrorOr Generator::emit_function_declaration_instantiation(E auto argument_reg = allocate_register(); emit(argument_reg.operand(), param_index); emit(id, argument_reg.operand(), - next_environment_variable_cache(), init_mode, Op::EnvironmentMode::Lexical); } @@ -115,7 +114,7 @@ CodeGenerationErrorOr Generator::emit_function_declaration_instantiation(E } else { auto intern_id = intern_identifier(id.string()); emit(intern_id, Op::EnvironmentMode::Var, false); - emit(intern_id, add_constant(js_undefined()), next_environment_variable_cache(), Bytecode::Op::SetVariable::InitializationMode::Initialize, Op::EnvironmentMode::Var); + emit(intern_id, add_constant(js_undefined()), Bytecode::Op::SetVariable::InitializationMode::Initialize, Op::EnvironmentMode::Var); } } } @@ -132,7 +131,7 @@ CodeGenerationErrorOr Generator::emit_function_declaration_instantiation(E if (id.is_local()) { emit(initial_value, local(id.local_variable_index())); } else { - emit(initial_value, intern_identifier(id.string()), next_environment_variable_cache()); + emit(initial_value, intern_identifier(id.string())); } } @@ -141,7 +140,7 @@ CodeGenerationErrorOr Generator::emit_function_declaration_instantiation(E } else { auto intern_id = intern_identifier(id.string()); emit(intern_id, Op::EnvironmentMode::Var, false); - emit(intern_id, initial_value, next_environment_variable_cache(), Op::SetVariable::InitializationMode::Initialize, Op::EnvironmentMode::Var); + emit(intern_id, initial_value, Op::SetVariable::InitializationMode::Initialize, Op::EnvironmentMode::Var); } } } @@ -151,7 +150,7 @@ CodeGenerationErrorOr Generator::emit_function_declaration_instantiation(E for (auto const& function_name : function.m_function_names_to_initialize_binding) { auto intern_id = intern_identifier(function_name); emit(intern_id, Op::EnvironmentMode::Var, false); - emit(intern_id, add_constant(js_undefined()), next_environment_variable_cache(), Bytecode::Op::SetVariable::InitializationMode::Initialize, Op::EnvironmentMode::Var); + emit(intern_id, add_constant(js_undefined()), Bytecode::Op::SetVariable::InitializationMode::Initialize, Op::EnvironmentMode::Var); } } @@ -184,7 +183,7 @@ CodeGenerationErrorOr Generator::emit_function_declaration_instantiation(E if (declaration.name_identifier()->is_local()) { emit(local(declaration.name_identifier()->local_variable_index()), function); } else { - emit(intern_identifier(declaration.name()), function, next_environment_variable_cache(), Op::SetVariable::InitializationMode::Set, Op::EnvironmentMode::Var); + emit(intern_identifier(declaration.name()), function, Op::SetVariable::InitializationMode::Set, Op::EnvironmentMode::Var); } } @@ -355,7 +354,6 @@ CodeGenerationErrorOr> Generator::emit_function_body_by node.source_code(), generator.m_next_property_lookup_cache, generator.m_next_global_variable_cache, - generator.m_next_environment_variable_cache, generator.m_next_register, is_strict_mode); @@ -776,7 +774,7 @@ void Generator::emit_set_variable(JS::Identifier const& identifier, ScopedOperan } emit(identifier.local_variable_index(), value); } else { - emit(intern_identifier(identifier.string()), value, next_environment_variable_cache(), initialization_mode, mode); + emit(intern_identifier(identifier.string()), value, initialization_mode, mode); } } diff --git a/Userland/Libraries/LibJS/Bytecode/Generator.h b/Userland/Libraries/LibJS/Bytecode/Generator.h index 5ef5b1d49ee..6b577e55174 100644 --- a/Userland/Libraries/LibJS/Bytecode/Generator.h +++ b/Userland/Libraries/LibJS/Bytecode/Generator.h @@ -280,7 +280,6 @@ public: void emit_iterator_complete(ScopedOperand dst, ScopedOperand result); [[nodiscard]] size_t next_global_variable_cache() { return m_next_global_variable_cache++; } - [[nodiscard]] size_t next_environment_variable_cache() { return m_next_environment_variable_cache++; } [[nodiscard]] size_t next_property_lookup_cache() { return m_next_property_lookup_cache++; } enum class DeduplicateConstant { @@ -345,7 +344,6 @@ private: u32 m_next_block { 1 }; u32 m_next_property_lookup_cache { 0 }; u32 m_next_global_variable_cache { 0 }; - u32 m_next_environment_variable_cache { 0 }; FunctionKind m_enclosing_function_kind { FunctionKind::Normal }; Vector m_continuable_scopes; Vector m_breakable_scopes; diff --git a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp index 4569817379e..8284b92cc62 100644 --- a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp @@ -1231,22 +1231,21 @@ ThrowCompletionOr GetVariable::execute_impl(Bytecode::Interpreter& interpr { auto& vm = interpreter.vm(); auto& executable = interpreter.current_executable(); - auto& cache = executable.environment_variable_caches[m_cache_index]; - if (cache.has_value()) { + if (m_cache.is_valid()) { auto const* environment = interpreter.running_execution_context().lexical_environment.ptr(); - for (size_t i = 0; i < cache->hops; ++i) + for (size_t i = 0; i < m_cache.hops; ++i) environment = environment->outer_environment(); if (!environment->is_permanently_screwed_by_eval()) { - interpreter.set(dst(), TRY(static_cast(*environment).get_binding_value_direct(vm, cache.value().index))); + interpreter.set(dst(), TRY(static_cast(*environment).get_binding_value_direct(vm, m_cache.index))); return {}; } - cache = {}; + m_cache = {}; } auto reference = TRY(vm.resolve_binding(executable.get_identifier(m_identifier))); if (reference.environment_coordinate().has_value()) - cache = reference.environment_coordinate(); + m_cache = reference.environment_coordinate().value(); interpreter.set(dst(), TRY(reference.get_value(vm))); return {}; } @@ -1256,7 +1255,7 @@ ThrowCompletionOr GetCalleeAndThisFromEnvironment::execute_impl(Bytecode:: auto callee_and_this = TRY(get_callee_and_this_from_environment( interpreter, interpreter.current_executable().get_identifier(m_identifier), - interpreter.current_executable().environment_variable_caches[m_cache_index])); + m_cache)); interpreter.set(m_callee, callee_and_this.callee); interpreter.set(m_this_value, callee_and_this.this_value); return {}; @@ -1379,7 +1378,7 @@ ThrowCompletionOr SetVariable::execute_impl(Bytecode::Interpreter& interpr interpreter.get(src()), m_mode, m_initialization_mode, - interpreter.current_executable().environment_variable_caches[m_cache_index])); + m_cache)); return {}; } diff --git a/Userland/Libraries/LibJS/Bytecode/Op.h b/Userland/Libraries/LibJS/Bytecode/Op.h index 1819efa5eda..2a214e9adde 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.h +++ b/Userland/Libraries/LibJS/Bytecode/Op.h @@ -588,13 +588,12 @@ public: Initialize, Set, }; - explicit SetVariable(IdentifierTableIndex identifier, Operand src, u32 cache_index, InitializationMode initialization_mode = InitializationMode::Set, EnvironmentMode mode = EnvironmentMode::Lexical) + explicit SetVariable(IdentifierTableIndex identifier, Operand src, InitializationMode initialization_mode = InitializationMode::Set, EnvironmentMode mode = EnvironmentMode::Lexical) : Instruction(Type::SetVariable) , m_identifier(identifier) , m_src(src) , m_mode(mode) , m_initialization_mode(initialization_mode) - , m_cache_index(cache_index) { } @@ -605,14 +604,13 @@ public: Operand src() const { return m_src; } EnvironmentMode mode() const { return m_mode; } InitializationMode initialization_mode() const { return m_initialization_mode; } - u32 cache_index() const { return m_cache_index; } private: IdentifierTableIndex m_identifier; Operand m_src; EnvironmentMode m_mode; InitializationMode m_initialization_mode { InitializationMode::Set }; - u32 m_cache_index { 0 }; + mutable EnvironmentCoordinate m_cache; }; class SetLocal final : public Instruction { @@ -678,12 +676,11 @@ private: class GetCalleeAndThisFromEnvironment final : public Instruction { public: - explicit GetCalleeAndThisFromEnvironment(Operand callee, Operand this_value, IdentifierTableIndex identifier, u32 cache_index) + explicit GetCalleeAndThisFromEnvironment(Operand callee, Operand this_value, IdentifierTableIndex identifier) : Instruction(Type::GetCalleeAndThisFromEnvironment) , m_identifier(identifier) , m_callee(callee) , m_this_value(this_value) - , m_cache_index(cache_index) { } @@ -691,7 +688,6 @@ public: ByteString to_byte_string_impl(Bytecode::Executable const&) const; IdentifierTableIndex identifier() const { return m_identifier; } - u32 cache_index() const { return m_cache_index; } Operand callee() const { return m_callee; } Operand this_() const { return m_this_value; } @@ -699,16 +695,15 @@ private: IdentifierTableIndex m_identifier; Operand m_callee; Operand m_this_value; - u32 m_cache_index { 0 }; + mutable EnvironmentCoordinate m_cache; }; class GetVariable final : public Instruction { public: - explicit GetVariable(Operand dst, IdentifierTableIndex identifier, u32 cache_index) + explicit GetVariable(Operand dst, IdentifierTableIndex identifier) : Instruction(Type::GetVariable) , m_dst(dst) , m_identifier(identifier) - , m_cache_index(cache_index) { } @@ -717,12 +712,11 @@ public: Operand dst() const { return m_dst; } IdentifierTableIndex identifier() const { return m_identifier; } - u32 cache_index() const { return m_cache_index; } private: Operand m_dst; IdentifierTableIndex m_identifier; - u32 m_cache_index { 0 }; + mutable EnvironmentCoordinate m_cache; }; class GetGlobal final : public Instruction {