Skip to main content

luaur_code_gen/methods/
code_allocator_allocate_deprecated.rs

1use crate::functions::flush_instruction_cache_code_allocator::flush_instruction_cache;
2use crate::functions::make_pages_executable_code_allocator::make_pages_executable;
3use crate::macros::codegen_assert::CODEGEN_ASSERT;
4use crate::records::code_allocator::CodeAllocator;
5use core::ffi::c_char;
6use core::ffi::c_void;
7use core::ptr;
8
9impl CodeAllocator {
10    pub fn allocate_deprecated(
11        &mut self,
12        data: *const u8,
13        data_size: usize,
14        code: *const u8,
15        code_size: usize,
16        result: &mut *mut u8,
17        result_size: &mut usize,
18        result_code_start: &mut *mut u8,
19    ) -> bool {
20        CODEGEN_ASSERT!(true);
21
22        const K_CODE_ALIGNMENT: usize = 32;
23        let aligned_data_size = (data_size + (K_CODE_ALIGNMENT - 1)) & !(K_CODE_ALIGNMENT - 1);
24        let total_size = aligned_data_size + code_size;
25
26        if total_size > self.block_size - Self::kMaxReservedDataSize {
27            return false;
28        }
29
30        let mut start_offset = 0;
31
32        if total_size > (self.block_end as usize - self.block_pos as usize) {
33            if !self.allocate_new_block(&mut start_offset) {
34                return false;
35            }
36            CODEGEN_ASSERT!(total_size <= (self.block_end as usize - self.block_pos as usize));
37        }
38
39        CODEGEN_ASSERT!(
40            CodeAllocator::align_to_page_size(self.block_pos as usize) == self.block_pos as usize
41        );
42
43        let data_offset = start_offset + aligned_data_size - data_size;
44        let code_offset = start_offset + aligned_data_size;
45
46        if data_size > 0 {
47            unsafe {
48                ptr::copy_nonoverlapping(data, self.block_pos.add(data_offset), data_size);
49            }
50        }
51        if code_size > 0 {
52            unsafe {
53                ptr::copy_nonoverlapping(code, self.block_pos.add(code_offset), code_size);
54            }
55        }
56
57        let page_aligned_size = Self::align_to_page_size(start_offset + total_size);
58
59        if !make_pages_executable(self.block_pos, page_aligned_size) {
60            return false;
61        }
62
63        flush_instruction_cache(unsafe { self.block_pos.add(code_offset) }, code_size);
64
65        *result = unsafe { self.block_pos.add(start_offset) };
66        *result_size = total_size;
67        *result_code_start = unsafe { self.block_pos.add(code_offset) };
68
69        if page_aligned_size <= (self.block_end as usize - self.block_pos as usize) {
70            unsafe {
71                self.block_pos = self.block_pos.add(page_aligned_size);
72            }
73            CODEGEN_ASSERT!(
74                CodeAllocator::align_to_page_size(self.block_pos as usize)
75                    == self.block_pos as usize
76            );
77            CODEGEN_ASSERT!(self.block_pos <= self.block_end);
78        } else {
79            self.block_pos = self.block_end;
80        }
81
82        true
83    }
84}