luaur_compiler/methods/
compiler_resolve_assign_conflicts.rs1use crate::enums::kind::Kind;
2use crate::records::assignment::Assignment;
3use crate::records::compiler::Compiler;
4use crate::records::visitor::Visitor;
5use luaur_ast::records::ast_array::AstArray;
6use luaur_ast::records::ast_expr::AstExpr;
7use luaur_ast::records::ast_stat::AstStat;
8use luaur_ast::visit::ast_expr_visit;
9
10impl Compiler {
11 pub fn resolve_assign_conflicts(
12 &mut self,
13 stat: *mut AstStat,
14 vars: &mut Vec<Assignment>,
15 values: &AstArray<*mut AstExpr>,
16 ) {
17 let mut visitor = self.visitor_visitor();
18
19 for i in 0..vars.len() {
20 let li = &vars[i].lvalue;
21 if li.kind == Kind::Kind_Local {
22 if i < values.size {
23 unsafe {
24 ast_expr_visit(*values.data.add(i), &mut visitor);
25 }
26 }
27 let reg = li.reg as usize;
28 visitor.assigned[reg / 64] |= 1 << (reg % 64);
29 }
30 }
31
32 for i in 0..vars.len() {
33 let li = &vars[i].lvalue;
34 if li.kind != Kind::Kind_Local && i < values.size {
35 unsafe {
36 ast_expr_visit(*values.data.add(i), &mut visitor);
37 }
38 }
39 }
40
41 for i in vars.len()..values.size {
42 unsafe {
43 ast_expr_visit(*values.data.add(i), &mut visitor);
44 }
45 }
46
47 for var in vars.iter() {
48 let li = &var.lvalue;
49 if (li.kind == Kind::Kind_IndexName
50 || li.kind == Kind::Kind_IndexNumber
51 || li.kind == Kind::Kind_IndexExpr)
52 {
53 let reg = li.reg as usize;
54 if (visitor.assigned[reg / 64] & (1 << (reg % 64))) != 0 {
55 visitor.conflict[reg / 64] |= 1 << (reg % 64);
56 }
57 }
58 if li.kind == Kind::Kind_IndexExpr {
59 let idx = li.index as usize;
60 if (visitor.assigned[idx / 64] & (1 << (idx % 64))) != 0 {
61 visitor.conflict[idx / 64] |= 1 << (idx % 64);
62 }
63 }
64 }
65
66 for var in vars.iter_mut() {
67 let li = &var.lvalue;
68 if li.kind == Kind::Kind_Local {
69 let reg = li.reg as usize;
70 if (visitor.conflict[reg / 64] & (1 << (reg % 64))) != 0 {
71 var.conflict_reg =
72 self.alloc_reg(stat as *mut luaur_ast::records::ast_node::AstNode, 1);
73 }
74 }
75 }
76 }
77}