luaur_compiler/methods/
compiler_compile_stat_local.rs1use crate::functions::sref_compiler::sref_ast_name;
2use crate::records::compile_error::CompileError;
3use crate::records::compiler::Compiler;
4use luaur_ast::records::ast_expr::AstExpr;
5use luaur_ast::records::ast_node::AstNode;
6use luaur_ast::records::ast_stat_local::AstStatLocal;
7use luaur_bytecode::methods::bytecode_builder_get_string_hash::bytecode_builder_get_string_hash;
8use luaur_common::enums::luau_opcode::LuauOpcode;
9
10impl Compiler {
11 pub fn compile_stat_local(&mut self, stat: *mut AstStatLocal) {
12 unsafe {
13 if self.options.optimization_level >= 1
14 && self.options.debug_level <= 1
15 && self.are_locals_redundant(stat)
16 {
17 return;
18 }
19
20 let stat_ref = &*stat;
21
22 if self.options.optimization_level >= 1
23 && stat_ref.vars.size == 1
24 && stat_ref.values.size == 1
25 {
26 let value = *stat_ref.values.data;
27 let re = self.get_expr_local(value);
28
29 if !re.is_null() {
30 let local = *stat_ref.vars.data;
31 let lv_written = self.variables.find(&local).map_or(false, |lv| lv.written);
32 let rv_local = (*re).local;
33 let rv_written = self
34 .variables
35 .find(&rv_local)
36 .map_or(false, |rv| rv.written);
37 let reg = self.get_expr_local_reg(value);
38
39 if reg >= 0
40 && !lv_written
41 && !rv_written
42 && !(*local).is_exported
43 && !(*rv_local).is_exported
44 {
45 let allocpc = (*self.bytecode).get_debug_pc();
46 self.push_local(local, reg as u8, allocpc);
47 return;
48 }
49 }
50 }
51
52 let vars = self.alloc_reg(stat as *mut AstNode, stat_ref.vars.size as u32);
53 let allocpc = (*self.bytecode).get_debug_pc();
54
55 self.compile_expr_list_temp(&stat_ref.values, vars, stat_ref.vars.size as u8, true);
56
57 for i in 0..stat_ref.vars.size {
58 let local = *stat_ref.vars.data.add(i);
59
60 if luaur_common::FFlag::LuauExportValueSyntax.get() && (*local).is_exported {
61 self.ensure_export_table(stat as *mut AstNode);
62
63 let name_ref = sref_ast_name((*local).name);
64 let cid = (*self.bytecode).add_constant_string(name_ref);
65 if cid < 0 {
66 CompileError::raise(
67 &(*local).location,
68 format_args!("Exceeded constant limit; simplify the code to compile"),
69 );
70 }
71
72 let table_reg = self.get_export_table_reg(stat as *mut AstNode);
73 (*self.bytecode).emit_abc(
74 LuauOpcode::LOP_SETTABLEKS,
75 vars + i as u8,
76 table_reg,
77 bytecode_builder_get_string_hash(name_ref) as u8,
78 );
79 (*self.bytecode).emit_aux(cid as u32);
80 } else {
81 self.push_local(local, vars + i as u8, allocpc);
82 }
83 }
84 }
85 }
86}