From c2d3d9d1d4f33e2a646b5604878e31c256ce7b5b Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 5 May 2024 11:52:14 +0200 Subject: [PATCH] LibJS/Bytecode: Make each Jump instruction inherit Instruction directly Before this change, all JumpFoo instructions inherited from Jump, which forced the unconditional Jump to have an unusued "false target" member. Also, labels were unnecessarily wrapped in Optional<>. By defining each jump instruction separately, they all shrink in size, and all ambiguity is removed. --- .../Libraries/LibJS/Bytecode/Interpreter.cpp | 51 +++++------ Userland/Libraries/LibJS/Bytecode/Op.h | 87 ++++++++++--------- 2 files changed, 73 insertions(+), 65 deletions(-) diff --git a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp index 9298f86e61e..6f7fa4dd75d 100644 --- a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp @@ -332,26 +332,32 @@ void Interpreter::run_bytecode() accumulator = get(static_cast(instruction).value()); return; case Instruction::Type::Jump: - m_current_block = &static_cast(instruction).true_target()->block(); + m_current_block = &static_cast(instruction).target().block(); goto start; - case Instruction::Type::JumpIf: - if (get(static_cast(instruction).condition()).to_boolean()) - m_current_block = &static_cast(instruction).true_target()->block(); + case Instruction::Type::JumpIf: { + auto& jump = static_cast(instruction); + if (get(jump.condition()).to_boolean()) + m_current_block = &jump.true_target().block(); else - m_current_block = &static_cast(instruction).false_target()->block(); + m_current_block = &jump.false_target().block(); goto start; - case Instruction::Type::JumpNullish: - if (get(static_cast(instruction).condition()).is_nullish()) - m_current_block = &static_cast(instruction).true_target()->block(); + } + case Instruction::Type::JumpNullish: { + auto& jump = static_cast(instruction); + if (get(jump.condition()).is_nullish()) + m_current_block = &jump.true_target().block(); else - m_current_block = &static_cast(instruction).false_target()->block(); + m_current_block = &jump.false_target().block(); goto start; - case Instruction::Type::JumpUndefined: - if (get(static_cast(instruction).condition()).is_undefined()) - m_current_block = &static_cast(instruction).true_target()->block(); + } + case Instruction::Type::JumpUndefined: { + auto& jump = static_cast(instruction); + if (get(jump.condition()).is_undefined()) + m_current_block = &jump.true_target().block(); else - m_current_block = &static_cast(instruction).false_target()->block(); + m_current_block = &jump.false_target().block(); goto start; + } case Instruction::Type::EnterUnwindContext: enter_unwind_context(); m_current_block = &static_cast(instruction).entry_point().block(); @@ -1869,36 +1875,31 @@ ByteString DeleteByIdWithThis::to_byte_string_impl(Bytecode::Executable const& e ByteString Jump::to_byte_string_impl(Bytecode::Executable const&) const { - if (m_true_target.has_value()) - return ByteString::formatted("Jump {}", *m_true_target); - return ByteString::formatted("Jump "); + return ByteString::formatted("Jump {}", m_target); } ByteString JumpIf::to_byte_string_impl(Bytecode::Executable const& executable) const { - auto true_string = m_true_target.has_value() ? ByteString::formatted("{}", *m_true_target) : ""; - auto false_string = m_false_target.has_value() ? ByteString::formatted("{}", *m_false_target) : ""; return ByteString::formatted("JumpIf {}, \033[32mtrue\033[0m:{} \033[32mfalse\033[0m:{}", format_operand("condition"sv, m_condition, executable), - true_string, false_string); + m_true_target, + m_false_target); } ByteString JumpNullish::to_byte_string_impl(Bytecode::Executable const& executable) const { - auto true_string = m_true_target.has_value() ? ByteString::formatted("{}", *m_true_target) : ""; - auto false_string = m_false_target.has_value() ? ByteString::formatted("{}", *m_false_target) : ""; return ByteString::formatted("JumpNullish {}, null:{} nonnull:{}", format_operand("condition"sv, m_condition, executable), - true_string, false_string); + m_true_target, + m_false_target); } ByteString JumpUndefined::to_byte_string_impl(Bytecode::Executable const& executable) const { - auto true_string = m_true_target.has_value() ? ByteString::formatted("{}", *m_true_target) : ""; - auto false_string = m_false_target.has_value() ? ByteString::formatted("{}", *m_false_target) : ""; return ByteString::formatted("JumpUndefined {}, undefined:{} defined:{}", format_operand("condition"sv, m_condition, executable), - true_string, false_string); + m_true_target, + m_false_target); } static StringView call_type_to_string(CallType type) diff --git a/Userland/Libraries/LibJS/Bytecode/Op.h b/Userland/Libraries/LibJS/Bytecode/Op.h index 6b3567f8fad..a2999cf4608 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.h +++ b/Userland/Libraries/LibJS/Bytecode/Op.h @@ -1057,64 +1057,59 @@ private: Operand m_property; }; -class Jump : public Instruction { +class Jump final : public Instruction { public: constexpr static bool IsTerminator = true; - explicit Jump(Type type, Label taken_target, Optional