luaur_bytecode/methods/
bytecode_builder_finalize.rs1use crate::functions::write_byte::write_byte;
11use crate::functions::write_var_int::write_var_int;
12use crate::records::bytecode_builder::BytecodeBuilder;
13use crate::records::string_ref::StringRef;
14use luaur_common::enums::luau_bytecode_tag::{
15 LBC_TYPE_VERSION_MAX, LBC_TYPE_VERSION_MIN, LBC_VERSION_MAX, LBC_VERSION_MIN,
16};
17use luaur_common::macros::luau_assert::LUAU_ASSERT;
18
19impl BytecodeBuilder {
20 pub fn finalize(&mut self) {
21 LUAU_ASSERT!(self.bytecode.is_empty());
22
23 for i in 0..self.userdata_types.len() {
24 if self.userdata_types[i].used {
25 let sref = {
26 let name = &self.userdata_types[i].name;
27 StringRef {
28 data: name.as_ptr() as *const i8,
29 length: name.len(),
30 }
31 };
32 self.userdata_types[i].nameRef = self.add_string_table_entry(sref);
33 }
34 }
35
36 let mut capacity: usize = 16;
38
39 for (string_ref, _index) in self.string_table.iter() {
40 capacity += string_ref.length + 2;
41 }
42
43 for func in &self.functions {
44 capacity += func.data.len();
45 }
46
47 let mut bytecode = core::mem::take(&mut self.bytecode);
50 bytecode.reserve(capacity);
51
52 let version = self.get_version();
53 LUAU_ASSERT!(version >= LBC_VERSION_MIN.0 as u8 && version <= LBC_VERSION_MAX.0 as u8);
54
55 unsafe {
56 bytecode.as_mut_vec().push(version);
57 }
58
59 let typesversion = self.get_type_encoding_version();
60 LUAU_ASSERT!(
61 typesversion >= LBC_TYPE_VERSION_MIN.0 as u8
62 && typesversion <= LBC_TYPE_VERSION_MAX.0 as u8
63 );
64 write_byte(&mut bytecode, typesversion);
65
66 self.write_string_table(&mut bytecode);
67
68 for i in 0..self.userdata_types.len() {
70 if self.userdata_types[i].used {
71 write_byte(&mut bytecode, (i + 1) as u8);
72 write_var_int(&mut bytecode, self.userdata_types[i].nameRef as u64);
73 }
74 }
75
76 write_byte(&mut bytecode, 0);
78
79 write_var_int(&mut bytecode, self.functions.len() as u64);
80
81 for func in &self.functions {
82 unsafe {
83 bytecode
84 .as_mut_vec()
85 .extend_from_slice(func.data.as_bytes());
86 }
87 }
88
89 LUAU_ASSERT!((self.main_function as usize) < self.functions.len());
90 write_var_int(&mut bytecode, self.main_function as u64);
91
92 self.bytecode = bytecode;
93 }
94}