Skip to main content

luaur_code_gen/functions/
bind_native_protos.rs

1use crate::functions::get_native_proto_exec_data_header_native_proto_exec_data_alt_b::get_native_proto_exec_data_header;
2use crate::macros::codegen_assert::CODEGEN_ASSERT;
3use crate::type_aliases::native_proto_exec_data_ptr::NativeProtoExecDataPtr;
4use alloc::vec::Vec;
5use luaur_common::enums::luau_opcode::LuauOpcode;
6use luaur_vm::records::proto::Proto;
7use luaur_vm::type_aliases::instruction::Instruction;
8
9static K_CODE_ENTRY_INSN: Instruction = LuauOpcode::LOP_NATIVECALL as u32;
10
11pub fn bind_native_protos(
12    module_protos: &Vec<*mut Proto>,
13    native_protos: &mut Vec<NativeProtoExecDataPtr>,
14    _release: bool,
15) -> u32 {
16    let mut protos_bound = 0u32;
17    let mut proto_it = 0usize;
18
19    for native_proto in native_protos.iter_mut() {
20        let header = unsafe { &*get_native_proto_exec_data_header(native_proto.as_ptr()) };
21
22        while proto_it != module_protos.len()
23            && unsafe { (*module_protos[proto_it]).bytecodeid as u32 } != header.bytecode_id
24        {
25            proto_it += 1;
26        }
27
28        CODEGEN_ASSERT!(proto_it != module_protos.len());
29
30        let proto = module_protos[proto_it];
31
32        unsafe {
33            (*proto).execdata = native_proto.as_ptr().cast();
34            (*proto).exectarget = header.entry_offset_or_address as usize;
35            (*proto).codeentry = &K_CODE_ENTRY_INSN;
36        }
37
38        protos_bound += 1;
39    }
40
41    protos_bound
42}