Skip to main content

luaur_bytecode/methods/
bytecode_builder_end_function.rs

1use 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}