luaur_code_gen/records/
native_module.rs1use crate::functions::get_native_proto_exec_data_header_native_proto_exec_data::get_native_proto_exec_data_header_mut;
4use crate::macros::codegen_assert::CODEGEN_ASSERT;
5use crate::records::code_allocation_data::CodeAllocationData;
6use crate::records::shared_code_allocator::SharedCodeAllocator;
7use crate::type_aliases::module_id::ModuleId;
8use crate::type_aliases::native_proto_exec_data_ptr::NativeProtoExecDataPtr;
9use alloc::vec::Vec;
10use core::sync::atomic::AtomicUsize;
11
12#[derive(Debug)]
13pub struct NativeModule {
14 pub(crate) refcount: AtomicUsize,
15 pub(crate) allocator: *mut SharedCodeAllocator,
16 pub(crate) module_id: Option<ModuleId>,
17 pub(crate) module_base_address_deprecated: *const u8,
18 pub(crate) code_allocation_data: CodeAllocationData,
19 pub(crate) native_protos: Vec<NativeProtoExecDataPtr>,
20}
21
22impl NativeModule {
23 pub fn native_module_shared_code_allocator_optional_module_id_u8_vector_native_proto_exec_data_ptr(
24 allocator: *mut SharedCodeAllocator,
25 module_id: &Option<ModuleId>,
26 module_base_address: *const u8,
27 native_protos: Vec<NativeProtoExecDataPtr>,
28 ) -> Self {
29 use luaur_common::FFlag;
30
31 CODEGEN_ASSERT!(!FFlag::LuauCodegenFreeBlocks.get());
32 CODEGEN_ASSERT!(!allocator.is_null());
33 CODEGEN_ASSERT!(!module_base_address.is_null());
34
35 let mut result = Self {
36 refcount: AtomicUsize::new(0),
37 allocator,
38 module_id: *module_id,
39 module_base_address_deprecated: module_base_address,
40 code_allocation_data: CodeAllocationData::default(),
41 native_protos,
42 };
43
44 result.bind_native_protos(module_base_address);
45 result
46 }
47
48 pub fn native_module_shared_code_allocator_optional_module_id_code_allocation_data_vector_native_proto_exec_data_ptr(
49 allocator: *mut SharedCodeAllocator,
50 module_id: &Option<ModuleId>,
51 code_allocation_data: CodeAllocationData,
52 native_protos: Vec<NativeProtoExecDataPtr>,
53 ) -> Self {
54 use luaur_common::FFlag;
55
56 CODEGEN_ASSERT!(FFlag::LuauCodegenFreeBlocks.get());
57 CODEGEN_ASSERT!(!allocator.is_null());
58 CODEGEN_ASSERT!(!code_allocation_data.start.is_null());
59
60 let mut result = Self {
61 refcount: AtomicUsize::new(0),
62 allocator,
63 module_id: *module_id,
64 module_base_address_deprecated: core::ptr::null(),
65 code_allocation_data,
66 native_protos,
67 };
68
69 result.bind_native_protos(code_allocation_data.code_start);
70 result
71 }
72
73 fn bind_native_protos(&mut self, code_base: *const u8) {
74 let native_module = self as *mut NativeModule;
75
76 for native_proto in &self.native_protos {
77 unsafe {
78 let header = get_native_proto_exec_data_header_mut(native_proto.as_ptr());
79 (*header).native_module = native_module;
80 (*header).entry_offset_or_address =
81 code_base.add((*header).entry_offset_or_address as usize);
82 }
83 }
84
85 self.native_protos.sort_by_key(|native_proto| unsafe {
86 (*get_native_proto_exec_data_header_mut(native_proto.as_ptr())).bytecode_id
87 });
88
89 for pair in self.native_protos.windows(2) {
90 unsafe {
91 let left = (*get_native_proto_exec_data_header_mut(pair[0].as_ptr())).bytecode_id;
92 let right = (*get_native_proto_exec_data_header_mut(pair[1].as_ptr())).bytecode_id;
93 CODEGEN_ASSERT!(left != right);
94 }
95 }
96 }
97}