luaur_bytecode/methods/
bytecode_builder_end_function.rs1use crate::records::bytecode_builder::BytecodeBuilder;
2use alloc::string::String;
3use luaur_common::macros::luau_assert::LUAU_ASSERT;
4
5pub struct HotComment {
6 pub content: String,
7 pub header: bool,
8}
9
10pub fn has_native_comment_directive(hotcomments: &[HotComment]) -> bool {
11 for hc in hotcomments {
12 if hc.content.is_empty()
13 || hc.content.as_bytes().first() == Some(&b' ')
14 || hc.content.as_bytes().first() == Some(&b'\t')
15 {
16 continue;
17 }
18
19 if hc.header {
20 let bytes = hc.content.as_bytes();
21 let space_pos = bytes.iter().position(|&b| b == b' ' || b == b'\t');
22
23 let first = if let Some(pos) = space_pos {
24 &hc.content[..pos]
25 } else {
26 &hc.content[..]
27 };
28
29 if first == "native" {
30 return true;
31 }
32 }
33 }
34
35 false
36}
37
38impl BytecodeBuilder {
39 pub fn end_function(&mut self, maxstacksize: u8, numupvalues: u8, flags: u8) {
40 LUAU_ASSERT!(self.current_function != u32::MAX);
41
42 let current_function = self.current_function;
43 let dump = if let Some(dump_fn) = self.dump_function_ptr {
44 let mut dumpinstoffs =
45 core::mem::take(&mut self.functions[current_function as usize].dumpinstoffs);
46 let dump = dump_fn(self, &mut dumpinstoffs);
47 self.functions[current_function as usize].dumpinstoffs = dumpinstoffs;
48 Some(dump)
49 } else {
50 None
51 };
52 {
53 let func = &mut self.functions[current_function as usize];
54 func.maxstacksize = maxstacksize;
55 func.numupvalues = numupvalues;
56
57 if let Some(dump) = dump {
58 func.dump = dump;
59 }
60
61 func.data.reserve(32 + self.insns.len() * 7);
62 }
63
64 if let Some(encoder) = self.encoder {
65 unsafe {
66 (*encoder).encode(&mut self.insns);
67 }
68 }
69
70 let mut data = String::new();
71 self.write_function(&mut data, current_function, flags);
72 self.functions[current_function as usize].data = data;
73
74 self.current_function = u32::MAX;
75 self.total_instruction_count += self.insns.len();
76
77 self.insns.clear();
78 self.lines.clear();
79 self.constants.clear();
80 self.protos.clear();
81 self.jumps.clear();
82 self.fb_slots.clear();
83 self.table_shapes.clear();
84
85 self.debug_locals.clear();
86 self.debug_upvals.clear();
87
88 self.typed_locals.clear();
89 self.typed_upvals.clear();
90
91 self.constant_map.clear();
92 self.table_shape_map.clear();
93 self.proto_map.clear();
94
95 self.debug_remarks.clear();
96 self.debug_remark_buffer.clear();
97 }
98}