luaur_compiler/methods/
compiler_compile_expr_and_or.rs1use crate::enums::type_constant_folding::Type;
2use crate::records::compiler::Compiler;
3use crate::records::constant::Constant;
4use crate::records::reg_scope::RegScope;
5use luaur_ast::records::ast_expr_binary::AstExprBinary;
6use luaur_common::enums::luau_opcode::LuauOpcode;
7
8impl Compiler {
9 pub fn compile_expr_and_or(&mut self, expr: *mut AstExprBinary, target: u8, target_temp: bool) {
10 unsafe {
11 let expr_ref = &*expr;
12 let and_ = expr_ref.op == luaur_ast::records::ast_expr_binary::AstExprBinaryOp::And;
13 let mut rs = self.reg_scope_compiler();
14
15 if let Some(cl) = self.constants.find(&expr_ref.left) {
16 if cl.r#type != Type::Type_Unknown {
17 self.compile_expr(
18 if and_ == cl.is_truthful() {
19 expr_ref.right
20 } else {
21 expr_ref.left
22 },
23 target,
24 target_temp,
25 );
26 return;
27 }
28 }
29
30 if !self.is_condition_fast(expr_ref.left) {
31 if let reg = self.get_expr_local_reg(expr_ref.right) {
32 if reg >= 0 {
33 let lr = self.compile_expr_auto(expr_ref.left, &mut rs);
34 (*self.bytecode).emit_abc(
35 if and_ {
36 LuauOpcode::LOP_AND
37 } else {
38 LuauOpcode::LOP_OR
39 },
40 target,
41 lr,
42 reg as u8,
43 );
44 return;
45 }
46 }
47
48 let cid = self.get_constant_index(expr_ref.right);
49 if cid >= 0 && cid <= 255 {
50 let lr = self.compile_expr_auto(expr_ref.left, &mut rs);
51 (*self.bytecode).emit_abc(
52 if and_ {
53 LuauOpcode::LOP_ANDK
54 } else {
55 LuauOpcode::LOP_ORK
56 },
57 target,
58 lr,
59 cid as u8,
60 );
61 return;
62 }
63 }
64
65 let reg = if target_temp {
66 target
67 } else {
68 self.alloc_reg(expr as *mut _, 1)
69 };
70 let mut skip_jump = Vec::new();
71 self.compile_condition_value(expr_ref.left, ®, &mut skip_jump, !and_);
72 self.compile_expr_temp(expr_ref.right, reg);
73 let move_label = (*self.bytecode).emit_label();
74 self.patch_jumps(expr as *mut _, &mut skip_jump, move_label);
75
76 if target != reg {
77 (*self.bytecode).emit_abc(LuauOpcode::LOP_MOVE, target, reg, 0);
78 }
79 }
80 }
81}