luaur_code_gen/methods/
unwind_builder_win_finish_function.rs1use crate::macros::codegen_assert::CODEGEN_ASSERT;
2use crate::records::unwind_builder_win::UnwindBuilderWin;
3use crate::records::unwind_code_win::UnwindCodeWin;
4use crate::records::unwind_info_win::UnwindInfoWin;
5
6impl UnwindBuilderWin {
7 pub fn finish_function(&mut self, begin_offset: u32, end_offset: u32) {
8 let last = self
9 .unwind_functions
10 .last_mut()
11 .expect("finish_function without start_function");
12 last.begin_offset = begin_offset;
13 last.end_offset = end_offset;
14
15 CODEGEN_ASSERT!(self.unwind_codes.len() < 256);
16
17 let mut info = UnwindInfoWin::default();
18 info.set_version(1);
19 info.set_flags(0);
20 info.prologsize = self.prolog_size;
21 info.unwindcodecount = self.unwind_codes.len() as u8;
22
23 CODEGEN_ASSERT!(self.frame_reg.index() < 16);
24 info.set_framereg(self.frame_reg.index());
25
26 CODEGEN_ASSERT!(self.frame_reg_offset < 16);
27 info.set_frameregoff(self.frame_reg_offset);
28
29 unsafe {
30 let raw_end = self
31 .raw_data
32 .as_mut_ptr()
33 .add(UnwindBuilderWin::kRawDataLimit as usize);
34 CODEGEN_ASSERT!(
35 self.raw_data_pos.add(core::mem::size_of::<UnwindInfoWin>()) <= raw_end
36 );
37
38 core::ptr::copy_nonoverlapping(
39 &info as *const UnwindInfoWin as *const u8,
40 self.raw_data_pos,
41 core::mem::size_of::<UnwindInfoWin>(),
42 );
43 self.raw_data_pos = self.raw_data_pos.add(core::mem::size_of::<UnwindInfoWin>());
44
45 if !self.unwind_codes.is_empty() {
46 let mut unwind_code_pos = self
47 .raw_data_pos
48 .add(core::mem::size_of::<UnwindCodeWin>() * (self.unwind_codes.len() - 1));
49 CODEGEN_ASSERT!(unwind_code_pos <= raw_end);
50
51 for code in &self.unwind_codes {
52 core::ptr::copy_nonoverlapping(
53 code as *const UnwindCodeWin as *const u8,
54 unwind_code_pos,
55 core::mem::size_of::<UnwindCodeWin>(),
56 );
57 unwind_code_pos = unwind_code_pos.sub(core::mem::size_of::<UnwindCodeWin>());
58 }
59 }
60
61 self.raw_data_pos = self
62 .raw_data_pos
63 .add(core::mem::size_of::<UnwindCodeWin>() * self.unwind_codes.len());
64
65 if self.unwind_codes.len() % 2 != 0 {
66 self.raw_data_pos = self.raw_data_pos.add(core::mem::size_of::<UnwindCodeWin>());
67 }
68
69 CODEGEN_ASSERT!(self.raw_data_pos <= raw_end);
70 }
71 }
72}