Skip to main content

luaur_bytecode/methods/
bytecode_builder_bytecode_builder.rs

1use crate::records::bytecode_builder::BytecodeBuilder;
2use crate::records::bytecode_encoder::BytecodeEncoder;
3use crate::records::constant_key::ConstantKey;
4use crate::records::string_ref::StringRef;
5use crate::records::table_shape::TableShape;
6use alloc::string::String;
7use alloc::vec::Vec;
8use luaur_common::macros::luau_assert::LUAU_ASSERT;
9use luaur_common::records::dense_hash_map::DenseHashMap;
10
11impl BytecodeBuilder {
12    pub fn new(encoder: Option<*mut dyn BytecodeEncoder>) -> Self {
13        let constant_map = DenseHashMap::new(ConstantKey {
14            r#type: crate::enums::r#type::Type::Type_Nil,
15            value: !0u64,
16            extra: 0,
17        });
18
19        let table_shape_map = DenseHashMap::new(TableShape::default());
20
21        let proto_map = DenseHashMap::new(!0u32);
22
23        let string_table = DenseHashMap::new(StringRef {
24            data: core::ptr::null(),
25            length: 0,
26        });
27
28        let mut result = BytecodeBuilder {
29            functions: Vec::new(),
30            current_function: !0u32,
31            main_function: !0u32,
32            total_instruction_count: 0,
33            insns: Vec::new(),
34            lines: Vec::new(),
35            constants: Vec::new(),
36            protos: Vec::new(),
37            jumps: Vec::new(),
38            table_shapes: Vec::new(),
39            class_shapes: Vec::new(),
40            fb_slots: Vec::new(),
41            has_long_jumps: false,
42            constant_map,
43            table_shape_map,
44            proto_map,
45            debug_line: 0,
46            debug_locals: Vec::new(),
47            debug_upvals: Vec::new(),
48            typed_locals: Vec::new(),
49            typed_upvals: Vec::new(),
50            userdata_types: Vec::new(),
51            string_table,
52            debug_strings: Vec::new(),
53            debug_remarks: Vec::new(),
54            debug_remark_buffer: String::new(),
55            encoder,
56            bytecode: String::new(),
57            dump_flags: 0,
58            dump_source: Vec::new(),
59            dump_remarks: Vec::new(),
60            temp_type_info: String::new(),
61            dump_function_ptr: None,
62        };
63
64        // preallocate some buffers that are very likely to grow anyway; this works around std::vector's inefficient growth policy for small arrays
65        result.insns.reserve(32);
66        result.lines.reserve(32);
67        result.constants.reserve(16);
68        result.protos.reserve(16);
69        result.functions.reserve(8);
70
71        // LUAU_ASSERT(stringTable.find(StringRef{"", 0}) == nullptr);
72        let empty_key = StringRef {
73            data: b"\0".as_ptr() as *const i8,
74            length: 0,
75        };
76        LUAU_ASSERT!(result.string_table.find(&empty_key).is_none());
77
78        result
79    }
80}