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