Skip to main content

luaur_code_gen/functions/
destroy_native_proto_exec_data.rs

1use crate::functions::compute_native_exec_data_size::compute_native_exec_data_size;
2use crate::functions::get_native_proto_exec_data_header_native_proto_exec_data_alt_b::get_native_proto_exec_data_header;
3use crate::records::native_proto_exec_data_header::NativeProtoExecDataHeader;
4
5/// # Safety
6///
7/// This function performs a manual memory deallocation of the `NativeProtoExecData`
8/// structure. The caller must ensure that `instruction_offsets` points to a valid
9/// `NativeProtoExecData` block previously allocated by `createNativeProtoExecData`.
10/// The pointer must not be used after this call.
11#[no_mangle]
12pub unsafe extern "C" fn destroy_native_proto_exec_data(instruction_offsets: *const u32) {
13    if instruction_offsets.is_null() {
14        return;
15    }
16
17    let header = get_native_proto_exec_data_header(instruction_offsets);
18    if header.is_null() {
19        return;
20    }
21
22    // The C++ code calls the destructor and then deletes the memory block.
23    // In Rust, we drop the header and then free the memory.
24    // Since the header is at the start of the allocation, we cast the header
25    // pointer to a byte pointer to free the entire block.
26    unsafe {
27        let bytecode_instruction_count = (*header).bytecode_instruction_count;
28        let extra_data_count = (*header).extra_data_count;
29        let layout = core::alloc::Layout::from_size_align(
30            compute_native_exec_data_size(bytecode_instruction_count, extra_data_count),
31            core::mem::align_of::<u32>(),
32        )
33        .expect("invalid NativeProtoExecData layout");
34        core::ptr::drop_in_place(header as *mut NativeProtoExecDataHeader);
35        alloc::alloc::dealloc(header as *mut u8, layout);
36    }
37}