1 // Copyright © 2024 Collabora, Ltd. 2 // SPDX-License-Identifier: MIT 3 4 use std::pin::Pin; 5 6 use nak_bindings::nak_clear_memstream; 7 use nak_bindings::nak_close_memstream; 8 use nak_bindings::nak_memstream; 9 use nak_bindings::nak_nir_asprint_instr; 10 use nak_bindings::nak_open_memstream; 11 use nak_bindings::nir_instr; 12 13 /// A memstream that holds the printed NIR instructions. 14 pub struct NirInstrPrinter { 15 // XXX: we need this to be pinned because we've passed references to its 16 // fields when calling open_memstream. 17 stream: Pin<Box<nak_memstream>>, 18 } 19 20 impl NirInstrPrinter { new() -> Self21 pub fn new() -> Self { 22 let mut stream = 23 Box::pin(unsafe { std::mem::zeroed::<nak_memstream>() }); 24 unsafe { 25 nak_open_memstream(stream.as_mut().get_unchecked_mut()); 26 } 27 Self { stream } 28 } 29 30 /// Prints the given NIR instruction. instr_to_string(&mut self, instr: &nir_instr) -> String31 pub fn instr_to_string(&mut self, instr: &nir_instr) -> String { 32 unsafe { 33 let stream = self.stream.as_mut().get_unchecked_mut(); 34 nak_nir_asprint_instr(stream, instr); 35 let c_str = std::ffi::CStr::from_ptr(stream.buffer); 36 let string = c_str.to_string_lossy().into_owned(); 37 nak_clear_memstream(stream); 38 string 39 } 40 } 41 } 42 43 impl Drop for NirInstrPrinter { drop(&mut self)44 fn drop(&mut self) { 45 unsafe { 46 let stream = self.stream.as_mut().get_unchecked_mut(); 47 nak_close_memstream(stream) 48 } 49 } 50 } 51