diff --git a/Userland/Libraries/LibJS/Bytecode/BasicBlock.cpp b/Userland/Libraries/LibJS/Bytecode/BasicBlock.cpp index 0e78e963604..d2119988515 100644 --- a/Userland/Libraries/LibJS/Bytecode/BasicBlock.cpp +++ b/Userland/Libraries/LibJS/Bytecode/BasicBlock.cpp @@ -10,13 +10,14 @@ namespace JS::Bytecode { -NonnullOwnPtr BasicBlock::create(String name) +NonnullOwnPtr BasicBlock::create(u32 index, String name) { - return adopt_own(*new BasicBlock(move(name))); + return adopt_own(*new BasicBlock(index, move(name))); } -BasicBlock::BasicBlock(String name) - : m_name(move(name)) +BasicBlock::BasicBlock(u32 index, String name) + : m_index(index) + , m_name(move(name)) { } diff --git a/Userland/Libraries/LibJS/Bytecode/BasicBlock.h b/Userland/Libraries/LibJS/Bytecode/BasicBlock.h index 7eb45767cd7..d33aab9f874 100644 --- a/Userland/Libraries/LibJS/Bytecode/BasicBlock.h +++ b/Userland/Libraries/LibJS/Bytecode/BasicBlock.h @@ -25,9 +25,11 @@ class BasicBlock { AK_MAKE_NONCOPYABLE(BasicBlock); public: - static NonnullOwnPtr create(String name); + static NonnullOwnPtr create(u32 index, String name); ~BasicBlock(); + u32 index() const { return m_index; } + ReadonlyBytes instruction_stream() const { return m_buffer.span(); } u8* data() { return m_buffer.data(); } u8 const* data() const { return m_buffer.data(); } @@ -50,8 +52,9 @@ public: void add_source_map_entry(size_t bytecode_offset, SourceRecord const& source_record) { m_source_map.set(bytecode_offset, source_record); } private: - explicit BasicBlock(String name); + explicit BasicBlock(u32 index, String name); + u32 m_index { 0 }; Vector m_buffer; BasicBlock const* m_handler { nullptr }; BasicBlock const* m_finalizer { nullptr }; diff --git a/Userland/Libraries/LibJS/Bytecode/Generator.cpp b/Userland/Libraries/LibJS/Bytecode/Generator.cpp index 137fc7f0d02..41b84e99286 100644 --- a/Userland/Libraries/LibJS/Bytecode/Generator.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Generator.cpp @@ -135,7 +135,7 @@ CodeGenerationErrorOr> Generator::generate(VM& vm, ASTN } for (auto label_offset : label_offsets) { auto& label = *reinterpret_cast(bytecode.data() + label_offset); - auto* block = &label.block(); + auto* block = generator.m_root_basic_blocks[label.basic_block_index()].ptr(); label.set_address(block_offsets.get(block).value()); } diff --git a/Userland/Libraries/LibJS/Bytecode/Generator.h b/Userland/Libraries/LibJS/Bytecode/Generator.h index 7279d39203a..59982ee3bd8 100644 --- a/Userland/Libraries/LibJS/Bytecode/Generator.h +++ b/Userland/Libraries/LibJS/Bytecode/Generator.h @@ -150,12 +150,12 @@ public: { if (name.is_empty()) name = MUST(String::number(m_next_block++)); - auto block = BasicBlock::create(name); + auto block = BasicBlock::create(m_root_basic_blocks.size(), name); if (auto const* context = m_current_unwind_context) { if (context->handler().has_value()) - block->set_handler(context->handler().value().block()); + block->set_handler(*m_root_basic_blocks[context->handler().value().basic_block_index()]); if (m_current_unwind_context->finalizer().has_value()) - block->set_finalizer(context->finalizer().value().block()); + block->set_finalizer(*m_root_basic_blocks[context->finalizer().value().basic_block_index()]); } m_root_basic_blocks.append(move(block)); return *m_root_basic_blocks.last(); diff --git a/Userland/Libraries/LibJS/Bytecode/Label.cpp b/Userland/Libraries/LibJS/Bytecode/Label.cpp new file mode 100644 index 00000000000..99d7f348a81 --- /dev/null +++ b/Userland/Libraries/LibJS/Bytecode/Label.cpp @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include + +namespace JS::Bytecode { + +Label::Label(Bytecode::BasicBlock const& basic_block) + : m_address_or_basic_block_index(basic_block.index()) +{ +} + +} diff --git a/Userland/Libraries/LibJS/Bytecode/Label.h b/Userland/Libraries/LibJS/Bytecode/Label.h index d20dd1843d1..f28c565feef 100644 --- a/Userland/Libraries/LibJS/Bytecode/Label.h +++ b/Userland/Libraries/LibJS/Bytecode/Label.h @@ -14,27 +14,23 @@ class BasicBlock; class Label { public: - explicit Label(BasicBlock const& block) - : m_block(&block) + explicit Label(BasicBlock const&); + + explicit Label(u32 basic_block_index) + : m_address_or_basic_block_index(basic_block_index) { } // Used while compiling. - BasicBlock const& block() const { return *m_block; } + size_t basic_block_index() const { return m_address_or_basic_block_index; } // Used after compiling. - size_t address() const { return m_address; } + size_t address() const { return m_address_or_basic_block_index; } - void set_address(size_t address) { m_address = address; } + void set_address(size_t address) { m_address_or_basic_block_index = address; } private: - union { - // Relevant while compiling. - BasicBlock const* m_block { nullptr }; - - // Relevant after compiling. - size_t m_address; - }; + u32 m_address_or_basic_block_index { 0 }; }; } diff --git a/Userland/Libraries/LibJS/CMakeLists.txt b/Userland/Libraries/LibJS/CMakeLists.txt index 66fde5f5773..c60ac43685f 100644 --- a/Userland/Libraries/LibJS/CMakeLists.txt +++ b/Userland/Libraries/LibJS/CMakeLists.txt @@ -9,6 +9,7 @@ set(SOURCES Bytecode/IdentifierTable.cpp Bytecode/Instruction.cpp Bytecode/Interpreter.cpp + Bytecode/Label.cpp Bytecode/RegexTable.cpp Bytecode/StringTable.cpp Console.cpp