1use crate::enums::dump_flags::DumpFlags;
2use crate::enums::r#type::Type;
3use crate::records::bytecode_encoder::BytecodeEncoder;
4use crate::records::class_shape::ClassShape;
5use crate::records::constant::Constant;
6use crate::records::constant_key::ConstantKey;
7use crate::records::constant_key_hash::ConstantKeyHash;
8use crate::records::debug_local_bytecode_builder::DebugLocal;
9use crate::records::debug_upval::DebugUpval;
10use crate::records::function::Function;
11use crate::records::jump::Jump;
12use crate::records::string_ref::StringRef;
13use crate::records::string_ref_hash::StringRefHash;
14use crate::records::table_shape::TableShape;
15use crate::records::table_shape_hash::TableShapeHash;
16use crate::records::typed_local_bytecode_builder::TypedLocal;
17use crate::records::typed_upval::TypedUpval;
18use crate::records::userdata_type::UserdataType;
19use luaur_common::records::dense_hash_map::DenseHashMap;
20use luaur_common::records::dense_hash_table::DenseEqDefault;
21use luaur_common::type_aliases::dense_hash_default::DenseHashDefault;
22
23#[derive(Debug, Clone)]
24pub struct BytecodeBuilder {
25 pub(crate) functions: Vec<Function>,
26 pub(crate) current_function: u32,
27 pub(crate) main_function: u32,
28
29 pub(crate) total_instruction_count: usize,
30 pub(crate) insns: Vec<u32>,
31 pub(crate) lines: Vec<i32>,
32 pub(crate) constants: Vec<Constant>,
33 pub(crate) protos: Vec<u32>,
34 pub(crate) jumps: Vec<Jump>,
35
36 pub(crate) table_shapes: Vec<TableShape>,
37 pub(crate) class_shapes: Vec<ClassShape>,
38
39 pub(crate) fb_slots: Vec<u32>,
40
41 pub(crate) has_long_jumps: bool,
42
43 pub(crate) constant_map:
44 DenseHashMap<ConstantKey, i32, DenseHashDefault<ConstantKey>, DenseEqDefault<ConstantKey>>,
45 pub(crate) table_shape_map:
46 DenseHashMap<TableShape, i32, DenseHashDefault<TableShape>, DenseEqDefault<TableShape>>,
47 pub(crate) proto_map: DenseHashMap<u32, i16>,
48
49 pub(crate) debug_line: i32,
50
51 pub(crate) debug_locals: Vec<DebugLocal>,
52 pub(crate) debug_upvals: Vec<DebugUpval>,
53
54 pub(crate) typed_locals: Vec<TypedLocal>,
55 pub(crate) typed_upvals: Vec<TypedUpval>,
56
57 pub(crate) userdata_types: Vec<UserdataType>,
58
59 pub(crate) string_table:
60 DenseHashMap<StringRef, u32, DenseHashDefault<StringRef>, DenseEqDefault<StringRef>>,
61 pub(crate) debug_strings: Vec<StringRef>,
62
63 pub(crate) debug_remarks: Vec<(u32, u32)>,
64 pub(crate) debug_remark_buffer: String,
65
66 pub(crate) encoder: Option<*mut dyn BytecodeEncoder>,
67 pub(crate) bytecode: String,
68
69 pub(crate) dump_flags: u32,
70 pub(crate) dump_source: Vec<String>,
71 pub(crate) dump_remarks: Vec<(i32, String)>,
72
73 pub(crate) temp_type_info: String,
74
75 pub(crate) dump_function_ptr: Option<fn(&BytecodeBuilder, &mut Vec<i32>) -> String>,
76}
77
78impl BytecodeBuilder {
79 pub fn get_string_hash(key: StringRef) -> u32 {
80 crate::methods::bytecode_builder_get_string_hash::bytecode_builder_get_string_hash(key)
81 }
82
83 pub const DUMP_CODE: u32 = DumpFlags::Dump_Code as u32;
84 pub const DUMP_LINES: u32 = DumpFlags::Dump_Lines as u32;
85 pub const DUMP_SOURCE: u32 = DumpFlags::Dump_Source as u32;
86 pub const DUMP_LOCALS: u32 = DumpFlags::Dump_Locals as u32;
87 pub const DUMP_REMARKS: u32 = DumpFlags::Dump_Remarks as u32;
88 pub const DUMP_TYPES: u32 = DumpFlags::Dump_Types as u32;
89 pub const DUMP_CONSTANTS: u32 = DumpFlags::Dump_Constants as u32;
90}
91
92struct DummyEncoder;
93
94impl BytecodeEncoder for DummyEncoder {
95 fn encode(&mut self, _data: &mut [u32]) {}
96}
97
98impl Default for ConstantKey {
99 fn default() -> Self {
100 Self {
101 r#type: Type::Type_Nil,
102 value: 0,
103 extra: 0,
104 }
105 }
106}
107
108impl Default for BytecodeBuilder {
109 fn default() -> Self {
110 Self {
111 functions: Vec::new(),
112 current_function: !0u32,
113 main_function: !0u32,
114 total_instruction_count: 0,
115 insns: Vec::new(),
116 lines: Vec::new(),
117 constants: Vec::new(),
118 protos: Vec::new(),
119 jumps: Vec::new(),
120 table_shapes: Vec::new(),
121 class_shapes: Vec::new(),
122 fb_slots: Vec::new(),
123 has_long_jumps: false,
124 constant_map: DenseHashMap::new(ConstantKey {
125 r#type: Type::Type_Nil,
126 value: 0,
127 extra: 0,
128 }),
129 table_shape_map: DenseHashMap::new(TableShape {
130 keys: [0; 32],
131 constants: [-1; 32],
132 length: 0,
133 hasConstants: false,
134 }),
135 proto_map: DenseHashMap::new(!0u32),
136 debug_line: 0,
137 debug_locals: Vec::new(),
138 debug_upvals: Vec::new(),
139 typed_locals: Vec::new(),
140 typed_upvals: Vec::new(),
141 userdata_types: Vec::new(),
142 string_table: DenseHashMap::new(StringRef::default()),
143 debug_strings: Vec::new(),
144 debug_remarks: Vec::new(),
145 debug_remark_buffer: String::new(),
146 encoder: None,
147 bytecode: String::new(),
148 dump_flags: 0,
149 dump_source: Vec::new(),
150 dump_remarks: Vec::new(),
151 temp_type_info: String::new(),
152 dump_function_ptr: None,
153 }
154 }
155}