1 // Copyright © 2024 Collabora, Ltd. 2 // SPDX-License-Identifier: MIT 3 4 use std::pin::Pin; 5 6 use compiler::bindings::nir_instr; 7 use nak_bindings::nak_clear_memstream; 8 use nak_bindings::nak_close_memstream; 9 use nak_bindings::nak_memstream; 10 use nak_bindings::nak_nir_asprint_instr; 11 use nak_bindings::nak_open_memstream; 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 bytes = std::slice::from_raw_parts( 36 stream.buffer as *const u8, 37 stream.written, 38 ); 39 let string = String::from_utf8_lossy(bytes).into_owned(); 40 nak_clear_memstream(stream); 41 string 42 } 43 } 44 } 45 46 impl Drop for NirInstrPrinter { drop(&mut self)47 fn drop(&mut self) { 48 unsafe { 49 let stream = self.stream.as_mut().get_unchecked_mut(); 50 nak_close_memstream(stream) 51 } 52 } 53 } 54