/src/serenity/Userland/Libraries/LibJS/Bytecode/Executable.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2021-2024, Andreas Kling <kling@serenityos.org> |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #pragma once |
8 | | |
9 | | #include <AK/DeprecatedFlyString.h> |
10 | | #include <AK/HashMap.h> |
11 | | #include <AK/NonnullOwnPtr.h> |
12 | | #include <AK/OwnPtr.h> |
13 | | #include <AK/WeakPtr.h> |
14 | | #include <LibJS/Bytecode/IdentifierTable.h> |
15 | | #include <LibJS/Bytecode/Label.h> |
16 | | #include <LibJS/Bytecode/StringTable.h> |
17 | | #include <LibJS/Forward.h> |
18 | | #include <LibJS/Heap/Cell.h> |
19 | | #include <LibJS/Heap/CellAllocator.h> |
20 | | #include <LibJS/Runtime/EnvironmentCoordinate.h> |
21 | | #include <LibJS/SourceRange.h> |
22 | | |
23 | | namespace JS::Bytecode { |
24 | | |
25 | | struct PropertyLookupCache { |
26 | | WeakPtr<Shape> shape; |
27 | | Optional<u32> property_offset; |
28 | | WeakPtr<Object> prototype; |
29 | | WeakPtr<PrototypeChainValidity> prototype_chain_validity; |
30 | | }; |
31 | | |
32 | | struct GlobalVariableCache : public PropertyLookupCache { |
33 | | u64 environment_serial_number { 0 }; |
34 | | Optional<u32> environment_binding_index; |
35 | | }; |
36 | | |
37 | | struct SourceRecord { |
38 | | u32 source_start_offset {}; |
39 | | u32 source_end_offset {}; |
40 | | }; |
41 | | |
42 | | class Executable final : public Cell { |
43 | | JS_CELL(Executable, Cell); |
44 | | JS_DECLARE_ALLOCATOR(Executable); |
45 | | |
46 | | public: |
47 | | Executable( |
48 | | Vector<u8> bytecode, |
49 | | NonnullOwnPtr<IdentifierTable>, |
50 | | NonnullOwnPtr<StringTable>, |
51 | | NonnullOwnPtr<RegexTable>, |
52 | | Vector<Value> constants, |
53 | | NonnullRefPtr<SourceCode const>, |
54 | | size_t number_of_property_lookup_caches, |
55 | | size_t number_of_global_variable_caches, |
56 | | size_t number_of_registers, |
57 | | bool is_strict_mode); |
58 | | |
59 | | virtual ~Executable() override; |
60 | | |
61 | | DeprecatedFlyString name; |
62 | | Vector<u8> bytecode; |
63 | | Vector<PropertyLookupCache> property_lookup_caches; |
64 | | Vector<GlobalVariableCache> global_variable_caches; |
65 | | NonnullOwnPtr<StringTable> string_table; |
66 | | NonnullOwnPtr<IdentifierTable> identifier_table; |
67 | | NonnullOwnPtr<RegexTable> regex_table; |
68 | | Vector<Value> constants; |
69 | | |
70 | | NonnullRefPtr<SourceCode const> source_code; |
71 | | size_t number_of_registers { 0 }; |
72 | | bool is_strict_mode { false }; |
73 | | |
74 | | struct ExceptionHandlers { |
75 | | size_t start_offset; |
76 | | size_t end_offset; |
77 | | Optional<size_t> handler_offset; |
78 | | Optional<size_t> finalizer_offset; |
79 | | }; |
80 | | |
81 | | Vector<ExceptionHandlers> exception_handlers; |
82 | | Vector<size_t> basic_block_start_offsets; |
83 | | |
84 | | HashMap<size_t, SourceRecord> source_map; |
85 | | |
86 | | Vector<DeprecatedFlyString> local_variable_names; |
87 | | size_t local_index_base { 0 }; |
88 | | |
89 | | Optional<IdentifierTableIndex> length_identifier; |
90 | | |
91 | 2 | ByteString const& get_string(StringTableIndex index) const { return string_table->get(index); } |
92 | 13 | DeprecatedFlyString const& get_identifier(IdentifierTableIndex index) const { return identifier_table->get(index); } |
93 | | |
94 | | Optional<DeprecatedFlyString const&> get_identifier(Optional<IdentifierTableIndex> const& index) const |
95 | 0 | { |
96 | 0 | if (!index.has_value()) |
97 | 0 | return {}; |
98 | 0 | return get_identifier(*index); |
99 | 0 | } |
100 | | |
101 | | [[nodiscard]] Optional<ExceptionHandlers const&> exception_handlers_for_offset(size_t offset) const; |
102 | | |
103 | | [[nodiscard]] UnrealizedSourceRange source_range_at(size_t offset) const; |
104 | | |
105 | | void dump() const; |
106 | | |
107 | | private: |
108 | | virtual void visit_edges(Visitor&) override; |
109 | | }; |
110 | | |
111 | | } |