luaur_compiler/methods/
compiler_compile_class_declaration.rs1use crate::records::compiler::Compiler;
2use alloc::vec::Vec;
3use luaur_ast::records::ast_stat_class::AstStatClass;
4use luaur_common::enums::luau_opcode::LuauOpcode;
5use luaur_common::macros::luau_assert::LUAU_ASSERT;
6use luaur_common::records::variant::Variant2;
7
8impl Compiler {
9 pub fn compile_class_declaration(&mut self, decl: *mut AstStatClass) {
10 let dest = self.alloc_reg(decl as *mut _, 1);
11 self.push_local(unsafe { (*decl).name }, dest, !0u32);
12 let _rs = self.reg_scope_compiler();
15 unsafe {
16 (*self.bytecode).emit_ad(LuauOpcode::LOP_LOADKX, dest, 0);
17 let aux_offset = (*self.bytecode).emit_label();
18 (*self.bytecode).emit_aux(0xDEADBEEF);
19 let mut shape = luaur_bytecode::records::class_shape::ClassShape::default();
23 let class_name = (*(*decl).name).name;
24 let class_name_cid = (*self.bytecode)
25 .add_constant_string(crate::functions::sref_compiler::sref_ast_name(class_name));
26 self.check_constant(class_name_cid, &(*(*decl).name).location);
27 shape.className = class_name_cid;
28 let temp = self.alloc_reg(decl as *mut _, 1);
29 for member in (*decl).members.as_slice() {
30 match member {
31 Variant2::V0(prop) => {
32 let cid = (*self.bytecode).add_constant_string(
33 crate::functions::sref_compiler::sref_ast_name(prop.name),
34 );
35 self.check_constant(cid, &prop.name_location);
36 shape.propertyNames.push(cid);
37 }
38 Variant2::V1(method) => {
39 self.compile_expr_function(method.function, temp);
40 let cid = (*self.bytecode).add_constant_string(
41 crate::functions::sref_compiler::sref_ast_name(method.function_name),
42 );
43 self.check_constant(cid, &(*method.function).base.base.location);
44 shape.methodNames.push(cid);
45 (*self.bytecode).emit_abc(LuauOpcode::LOP_NEWCLASSMEMBER, dest, 0, temp);
46 (*self.bytecode).emit_aux(cid as u32);
47 }
48 }
49 }
50 let class_const = (*self.bytecode).add_class_shape(shape);
51 self.check_constant(class_const, &(*decl).base.base.location);
52 (*self.bytecode).patch_aux(aux_offset, class_const);
53 if luaur_common::FFlag::LuauExportValueSyntax.get() && (*decl).exported {
54 self.exported_classes.push((class_name, dest));
55 }
56 }
57 }
58}