luaur_compiler/methods/
compiler_compile_expr_constant.rs1use crate::enums::type_constant_folding::Type;
2use crate::functions::sref_compiler_alt_c::sref_ast_array_c_char;
3use crate::records::compile_error::CompileError;
4use crate::records::compiler::Compiler;
5use crate::records::constant::Constant;
6use luaur_ast::records::ast_expr::AstExpr;
7use luaur_common::enums::luau_opcode::LuauOpcode;
8
9use core::ffi::c_char;
10
11impl Compiler {
12 pub fn compile_expr_constant(&mut self, node: *mut AstExpr, cv: &Constant, target: u8) {
13 match cv.r#type {
14 Type::Type_Nil => unsafe {
15 (*self.bytecode).emit_abc(LuauOpcode::LOP_LOADNIL, target, 0, 0);
16 },
17 Type::Type_Boolean => {
18 let b = unsafe { cv.data.value_boolean };
19 unsafe {
20 (*self.bytecode).emit_abc(LuauOpcode::LOP_LOADB, target, b as u8, 0);
21 }
22 }
23 Type::Type_Number => {
24 let d = unsafe { cv.data.value_number };
25
26 let fits_i16 = d >= (i16::MIN as f64)
27 && d <= (i16::MAX as f64)
28 && (d as i16 as f64) == d
29 && !(d == 0.0 && d.is_sign_negative());
30
31 if fits_i16 {
32 unsafe {
33 (*self.bytecode).emit_ad(LuauOpcode::LOP_LOADN, target, d as i16);
34 }
35 } else {
36 let cid = unsafe { (*self.bytecode).add_constant_number(d) };
37 if cid < 0 {
38 let location = unsafe { (*node).base.location };
39 CompileError::raise(
40 &location,
41 format_args!("Exceeded constant limit; simplify the code to compile"),
42 );
43 }
44 self.emit_load_k(target, cid);
45 }
46 }
47 Type::Type_Integer => {
48 let l = unsafe { cv.data.value_integer64 };
49 let cid = unsafe { (*self.bytecode).add_constant_integer(l) };
50 if cid < 0 {
51 let location = unsafe { (*node).base.location };
52 CompileError::raise(
53 &location,
54 format_args!("Exceeded constant limit; simplify the code to compile"),
55 );
56 }
57 self.emit_load_k(target, cid);
58 }
59 Type::Type_Vector => {
60 let x = unsafe { cv.data.value_vector[0] };
61 let y = unsafe { cv.data.value_vector[1] };
62 let z = unsafe { cv.data.value_vector[2] };
63 let w = unsafe { cv.data.value_vector[3] };
64
65 let cid = unsafe { (*self.bytecode).add_constant_vector(x, y, z, w) };
66 if cid < 0 {
67 let location = unsafe { (*node).base.location };
68 CompileError::raise(
69 &location,
70 format_args!("Exceeded constant limit; simplify the code to compile"),
71 );
72 }
73 self.emit_load_k(target, cid);
74 }
75 Type::Type_String => {
76 let s = cv.get_string();
77 let cid = unsafe { (*self.bytecode).add_constant_string(sref_ast_array_c_char(s)) };
78 if cid < 0 {
79 let location = unsafe { (*node).base.location };
80 CompileError::raise(
81 &location,
82 format_args!("Exceeded constant limit; simplify the code to compile"),
83 );
84 }
85 self.emit_load_k(target, cid);
86 }
87 _ => {
88 luaur_common::macros::luau_assert::LUAU_ASSERT!(false);
89 }
90 }
91 }
92}