xref: /aosp_15_r20/external/mesa3d/src/etnaviv/isa/util.rs (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 // Copyright © 2024 Igalia S.L.
2 // SPDX-License-Identifier: MIT
3 
4 use isa_bindings::*;
5 use std::ffi::CString;
6 use std::mem::ManuallyDrop;
7 use std::ptr;
8 
9 pub trait EtnaAsmResultExt {
set_error(&mut self, error_message: &str)10     fn set_error(&mut self, error_message: &str);
dealloc_error(&mut self)11     fn dealloc_error(&mut self);
12 
append_instruction(&mut self, new_inst: etna_inst)13     fn append_instruction(&mut self, new_inst: etna_inst);
dealloc_instructions(&mut self)14     fn dealloc_instructions(&mut self);
15 }
16 
17 impl EtnaAsmResultExt for etna_asm_result {
set_error(&mut self, error_message: &str)18     fn set_error(&mut self, error_message: &str) {
19         self.dealloc_error();
20 
21         self.error = CString::new(error_message)
22             .expect("CString::new failed")
23             .into_raw();
24     }
25 
dealloc_error(&mut self)26     fn dealloc_error(&mut self) {
27         if !self.error.is_null() {
28             // SAFETY: Previously obtained from CString::into_raw in set_error
29             let _ = unsafe { CString::from_raw(self.error) };
30             self.error = ptr::null_mut();
31         }
32     }
33 
append_instruction(&mut self, new_inst: etna_inst)34     fn append_instruction(&mut self, new_inst: etna_inst) {
35         let mut instrs = if self.instr.is_null() {
36             Vec::new()
37         } else {
38             // SAFETY: These values come from a previous call to `append_instruction` where we turned a Vec into raw parts
39             unsafe { Vec::from_raw_parts(self.instr, self.num_instr, self.capacity_instr) }
40         };
41 
42         instrs.push(new_inst);
43 
44         // This is Vec::into_raw_parts, which is still unstable
45         let mut md_vec = ManuallyDrop::new(instrs);
46         self.num_instr = md_vec.len();
47         self.capacity_instr = md_vec.capacity();
48         self.instr = md_vec.as_mut_ptr();
49     }
50 
dealloc_instructions(&mut self)51     fn dealloc_instructions(&mut self) {
52         if !self.instr.is_null() {
53             // SAFETY: These values come from a previous call to `append_instruction` where we turned a Vec into raw parts
54             let _ = unsafe { Vec::from_raw_parts(self.instr, self.num_instr, self.capacity_instr) };
55             (self.instr, self.num_instr, self.capacity_instr) = (ptr::null_mut(), 0, 0);
56         }
57     }
58 }
59