Skip to main content

luaur_code_gen/functions/
init_header_functions_code_gen_x_64.rs

1use crate::enums::arch::Arch;
2use crate::functions::build_entry_function_code_gen_x_64::build_entry_function;
3use crate::macros::codegen_assert::CODEGEN_ASSERT;
4use crate::records::assembly_builder_x_64::AssemblyBuilderX64;
5use crate::records::base_code_gen_context::BaseCodeGenContext;
6use crate::records::unwind_builder::UnwindBuilder;
7
8pub fn init_header_functions(code_gen_context: &mut BaseCodeGenContext) -> bool {
9    let mut build = AssemblyBuilderX64::assembly_builder_x_64_bool_i32(false, 0);
10
11    unsafe {
12        start_info(&mut *code_gen_context.unwind_builder, Arch::X64);
13    }
14
15    let entry_locations =
16        unsafe { build_entry_function(&mut build, &mut *code_gen_context.unwind_builder) };
17
18    build.finalize();
19
20    unsafe {
21        finish_info(&mut *code_gen_context.unwind_builder);
22    }
23
24    CODEGEN_ASSERT!(build.data.is_empty());
25
26    let mut code_start: *mut u8 = core::ptr::null_mut();
27
28    if luaur_common::FFlag::LuauCodegenFreeBlocks.get() {
29        code_gen_context.gate_allocation_data = code_gen_context.code_allocator.allocate(
30            build.data.as_ptr(),
31            build.data.len(),
32            build.code.as_ptr(),
33            build.code.len(),
34        );
35
36        if code_gen_context.gate_allocation_data.start.is_null() {
37            return false;
38        }
39
40        code_start = code_gen_context.gate_allocation_data.code_start;
41    } else if !code_gen_context.code_allocator.allocate_deprecated(
42        build.data.as_ptr(),
43        build.data.len(),
44        build.code.as_ptr(),
45        build.code.len(),
46        &mut code_gen_context.gate_data_deprecated,
47        &mut code_gen_context.gate_data_size_deprecated,
48        &mut code_start,
49    ) {
50        return false;
51    }
52
53    unsafe {
54        set_begin_offset(
55            &mut *code_gen_context.unwind_builder,
56            build.get_label_offset(&entry_locations.prologueEnd) as usize,
57        );
58
59        code_gen_context.context.gateEntry =
60            code_start.add(build.get_label_offset(&entry_locations.start) as usize);
61        code_gen_context.context.gateExit =
62            code_start.add(build.get_label_offset(&entry_locations.epilogueStart) as usize);
63    }
64
65    true
66}
67
68#[cfg(target_os = "windows")]
69unsafe fn start_info(unwind: &mut UnwindBuilder, arch: Arch) {
70    (&mut *(unwind as *mut UnwindBuilder)
71        .cast::<crate::records::unwind_builder_win::UnwindBuilderWin>())
72        .start_info(arch);
73}
74
75#[cfg(not(target_os = "windows"))]
76unsafe fn start_info(unwind: &mut UnwindBuilder, arch: Arch) {
77    (&mut *(unwind as *mut UnwindBuilder)
78        .cast::<crate::records::unwind_builder_dwarf_2::UnwindBuilderDwarf2>())
79        .start_info(arch);
80}
81
82#[cfg(target_os = "windows")]
83unsafe fn finish_info(unwind: &mut UnwindBuilder) {
84    (&mut *(unwind as *mut UnwindBuilder)
85        .cast::<crate::records::unwind_builder_win::UnwindBuilderWin>())
86        .finish_info();
87}
88
89#[cfg(not(target_os = "windows"))]
90unsafe fn finish_info(unwind: &mut UnwindBuilder) {
91    (&mut *(unwind as *mut UnwindBuilder)
92        .cast::<crate::records::unwind_builder_dwarf_2::UnwindBuilderDwarf2>())
93        .finish_info();
94}
95
96#[cfg(target_os = "windows")]
97unsafe fn set_begin_offset(unwind: &mut UnwindBuilder, begin_offset: usize) {
98    (&mut *(unwind as *mut UnwindBuilder)
99        .cast::<crate::records::unwind_builder_win::UnwindBuilderWin>())
100        .set_begin_offset(begin_offset);
101}
102
103#[cfg(not(target_os = "windows"))]
104unsafe fn set_begin_offset(unwind: &mut UnwindBuilder, begin_offset: usize) {
105    (&mut *(unwind as *mut UnwindBuilder)
106        .cast::<crate::records::unwind_builder_dwarf_2::UnwindBuilderDwarf2>())
107        .set_begin_offset(begin_offset);
108}