123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- /*
- * Copyright (c) 2021-2024, Andreas Kling <andreas@ladybird.org>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
- #include <LibJS/Bytecode/BasicBlock.h>
- #include <LibJS/Bytecode/Executable.h>
- #include <LibJS/Bytecode/Instruction.h>
- #include <LibJS/Bytecode/RegexTable.h>
- #include <LibJS/SourceCode.h>
- namespace JS::Bytecode {
- JS_DEFINE_ALLOCATOR(Executable);
- Executable::Executable(
- Vector<u8> bytecode,
- NonnullOwnPtr<IdentifierTable> identifier_table,
- NonnullOwnPtr<StringTable> string_table,
- NonnullOwnPtr<RegexTable> regex_table,
- Vector<Value> constants,
- NonnullRefPtr<SourceCode const> source_code,
- size_t number_of_property_lookup_caches,
- size_t number_of_global_variable_caches,
- size_t number_of_registers,
- bool is_strict_mode)
- : bytecode(move(bytecode))
- , string_table(move(string_table))
- , identifier_table(move(identifier_table))
- , regex_table(move(regex_table))
- , constants(move(constants))
- , source_code(move(source_code))
- , number_of_registers(number_of_registers)
- , is_strict_mode(is_strict_mode)
- {
- property_lookup_caches.resize(number_of_property_lookup_caches);
- global_variable_caches.resize(number_of_global_variable_caches);
- }
- Executable::~Executable() = default;
- void Executable::dump() const
- {
- warnln("\033[37;1mJS bytecode executable\033[0m \"{}\"", name);
- InstructionStreamIterator it(bytecode, this);
- size_t basic_block_offset_index = 0;
- while (!it.at_end()) {
- bool print_basic_block_marker = false;
- if (basic_block_offset_index < basic_block_start_offsets.size()
- && it.offset() == basic_block_start_offsets[basic_block_offset_index]) {
- ++basic_block_offset_index;
- print_basic_block_marker = true;
- }
- StringBuilder builder;
- builder.appendff("[{:4x}] ", it.offset());
- if (print_basic_block_marker)
- builder.appendff("{:4}: ", basic_block_offset_index - 1);
- else
- builder.append(" "sv);
- builder.append((*it).to_byte_string(*this));
- warnln("{}", builder.string_view());
- ++it;
- }
- if (!exception_handlers.is_empty()) {
- warnln("");
- warnln("Exception handlers:");
- for (auto& handlers : exception_handlers) {
- warnln(" from {:4x} to {:4x} handler {:4x} finalizer {:4x}",
- handlers.start_offset,
- handlers.end_offset,
- handlers.handler_offset.value_or(0),
- handlers.finalizer_offset.value_or(0));
- }
- }
- warnln("");
- }
- void Executable::visit_edges(Visitor& visitor)
- {
- Base::visit_edges(visitor);
- visitor.visit(constants);
- }
- Optional<Executable::ExceptionHandlers const&> Executable::exception_handlers_for_offset(size_t offset) const
- {
- for (auto& handlers : exception_handlers) {
- if (handlers.start_offset <= offset && offset < handlers.end_offset)
- return handlers;
- }
- return {};
- }
- UnrealizedSourceRange Executable::source_range_at(size_t offset) const
- {
- if (offset >= bytecode.size())
- return {};
- auto it = InstructionStreamIterator(bytecode.span().slice(offset), this);
- VERIFY(!it.at_end());
- auto mapping = source_map.get(offset);
- if (!mapping.has_value())
- return {};
- return UnrealizedSourceRange {
- .source_code = source_code,
- .start_offset = mapping->source_start_offset,
- .end_offset = mapping->source_end_offset,
- };
- }
- }
|