diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp index fad316e040f..6d95b6940f7 100644 --- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp @@ -426,8 +426,7 @@ Bytecode::CodeGenerationErrorOr> AssignmentExpressio // https://tc39.es/ecma262/#sec-super-keyword-runtime-semantics-evaluation // 1. Let env be GetThisEnvironment(). // 2. Let actualThis be ? env.GetThisBinding(). - this_value = Bytecode::Operand(generator.allocate_register()); - generator.emit(*this_value); + this_value = generator.get_this(); // SuperProperty : super [ Expression ] // 3. Let propertyNameReference be ? Evaluation of Expression. @@ -1486,8 +1485,7 @@ static Bytecode::CodeGenerationErrorOr get_base_and_value_from_mem if (is(member_expression.object())) { // 1. Let env be GetThisEnvironment(). // 2. Let actualThis be ? env.GetThisBinding(). - auto this_value = Bytecode::Operand(generator.allocate_register()); - generator.emit(this_value); + auto this_value = generator.get_this(); Optional computed_property; @@ -2718,9 +2716,7 @@ Bytecode::CodeGenerationErrorOr> SpreadExpression::g Bytecode::CodeGenerationErrorOr> ThisExpression::generate_bytecode(Bytecode::Generator& generator, Optional preferred_dst) const { Bytecode::Generator::SourceLocationScope scope(generator, *this); - auto dst = choose_dst(generator, preferred_dst); - generator.emit(dst); - return dst; + return generator.get_this(preferred_dst); } static Bytecode::Operand generate_await( diff --git a/Userland/Libraries/LibJS/Bytecode/BasicBlock.h b/Userland/Libraries/LibJS/Bytecode/BasicBlock.h index d33aab9f874..5f13ab95c0c 100644 --- a/Userland/Libraries/LibJS/Bytecode/BasicBlock.h +++ b/Userland/Libraries/LibJS/Bytecode/BasicBlock.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -51,6 +52,9 @@ public: auto const& source_map() const { return m_source_map; } void add_source_map_entry(size_t bytecode_offset, SourceRecord const& source_record) { m_source_map.set(bytecode_offset, source_record); } + auto const& this_() const { return m_this; } + void set_this(Operand operand) { m_this = operand; } + private: explicit BasicBlock(u32 index, String name); @@ -62,6 +66,8 @@ private: bool m_terminated { false }; HashMap m_source_map; + + Optional m_this; }; } diff --git a/Userland/Libraries/LibJS/Bytecode/Generator.cpp b/Userland/Libraries/LibJS/Bytecode/Generator.cpp index 278e39c5803..aaa41c35043 100644 --- a/Userland/Libraries/LibJS/Bytecode/Generator.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Generator.cpp @@ -798,4 +798,14 @@ void Generator::set_local_initialized(u32 local_index) m_initialized_locals.set(local_index); } +Operand Generator::get_this(Optional preferred_dst) +{ + if (m_current_basic_block->this_().has_value()) + return m_current_basic_block->this_().value(); + auto dst = preferred_dst.has_value() ? preferred_dst.value() : Operand(allocate_register()); + emit(dst); + m_current_basic_block->set_this(dst); + return dst; +} + } diff --git a/Userland/Libraries/LibJS/Bytecode/Generator.h b/Userland/Libraries/LibJS/Bytecode/Generator.h index b3665bf2fb1..28eefc1c026 100644 --- a/Userland/Libraries/LibJS/Bytecode/Generator.h +++ b/Userland/Libraries/LibJS/Bytecode/Generator.h @@ -257,6 +257,8 @@ public: m_boundaries.take_last(); } + [[nodiscard]] Operand get_this(Optional preferred_dst = {}); + void emit_get_by_id(Operand dst, Operand base, IdentifierTableIndex property_identifier, Optional base_identifier = {}); void emit_get_by_id_with_this(Operand dst, Operand base, IdentifierTableIndex, Operand this_value);