Skip to main content

luaur_compiler/methods/
compiler_compile_expr_index_expr.rs

1use crate::enums::type_constant_folding::Type;
2use crate::functions::sref_compiler_alt_c::sref_ast_array_c_char;
3use crate::records::compiler::Compiler;
4use crate::records::constant::Constant;
5use crate::records::reg_scope::RegScope;
6use luaur_ast::records::ast_expr_index_expr::AstExprIndexExpr;
7use luaur_bytecode::methods::bytecode_builder_get_string_hash::bytecode_builder_get_string_hash;
8use luaur_common::enums::luau_bytecode_type::LuauBytecodeType;
9use luaur_common::enums::luau_opcode::LuauOpcode;
10
11impl Compiler {
12    pub fn compile_expr_index_expr(&mut self, expr: *mut AstExprIndexExpr, target: u8) {
13        unsafe {
14            let expr_ref = &*expr;
15            let mut rs = self.reg_scope_compiler();
16            let cv = self.get_constant(expr_ref.index);
17
18            if cv.r#type == Type::Type_Number
19                && cv.data.value_number >= 1.0
20                && cv.data.value_number <= 256.0
21                && (cv.data.value_number as i32) as f64 == cv.data.value_number
22            {
23                let i = (cv.data.value_number as i32 - 1) as u8;
24                let rt = self.compile_expr_auto(expr_ref.expr, &mut rs);
25                self.set_debug_line_location(&(*expr_ref.index).base.location);
26                (*self.bytecode).emit_abc(LuauOpcode::LOP_GETTABLEN, target, rt, i);
27                self.hint_temporary_expr_reg_type(expr_ref.expr, rt as i32, LuauBytecodeType(4), 1);
28            } else if cv.r#type == Type::Type_String {
29                let iname = sref_ast_array_c_char(cv.get_string());
30                let cid = (*self.bytecode).add_constant_string(iname);
31                if cid < 0 {
32                    crate::records::compile_error::CompileError::raise(
33                        &expr_ref.base.base.location,
34                        format_args!("Exceeded constant limit; simplify the code to compile"),
35                    );
36                }
37                let rt = self.compile_expr_auto(expr_ref.expr, &mut rs);
38                self.set_debug_line_location(&(*expr_ref.index).base.location);
39                (*self.bytecode).emit_abc(
40                    LuauOpcode::LOP_GETTABLEKS,
41                    target,
42                    rt,
43                    bytecode_builder_get_string_hash(iname) as u8,
44                );
45                (*self.bytecode).emit_aux(cid as u32);
46                self.hint_temporary_expr_reg_type(expr_ref.expr, rt as i32, LuauBytecodeType(4), 2);
47            } else {
48                let rt = self.compile_expr_auto(expr_ref.expr, &mut rs);
49                let ri = self.compile_expr_auto(expr_ref.index, &mut rs);
50                (*self.bytecode).emit_abc(LuauOpcode::LOP_GETTABLE, target, rt, ri);
51                self.hint_temporary_expr_reg_type(expr_ref.expr, rt as i32, LuauBytecodeType(4), 1);
52                self.hint_temporary_expr_reg_type(
53                    expr_ref.index,
54                    ri as i32,
55                    LuauBytecodeType(2),
56                    1,
57                );
58            }
59        }
60    }
61}