struct StackWriter {
buffer: core::mem::MaybeUninit<[u8; 256]>,
length: usize,
}
impl StackWriter {
#[inline(always)]
fn new() -> Self {
Self { buffer: core::mem::MaybeUninit::uninit(), length: 0 }
}
fn write_bytes(&mut self, bytes: &[u8]) {
let max_length = core::mem::size_of_val(&self.buffer);
for &byte in bytes {
if self.length >= max_length {
break;
}
unsafe {
let pointer = self.buffer.as_mut_ptr().cast::<u8>().add(self.length);
pointer.write(byte);
}
self.length += 1;
}
}
fn finish(&mut self) -> &[u8] {
unsafe { core::slice::from_raw_parts(self.buffer.as_ptr().cast::<u8>(), self.length) }
}
}
impl core::fmt::Write for StackWriter {
fn write_str(&mut self, s: &str) -> core::fmt::Result {
self.write_bytes(s.as_bytes());
Ok(())
}
}
#[panic_handler]
fn panic(info: &core::panic::PanicInfo) -> ! {
unsafe {
let initial_message = "Panic handler called!";
crate::imports::log(
1,
core::ptr::null(),
0,
initial_message.as_ptr(),
initial_message.len() as u64,
);
use core::fmt::Write;
let mut writer = StackWriter::new();
let _ = writer.write_str("Panic message: ");
let _ = write!(&mut writer, "{}", info);
let msg = writer.finish();
crate::imports::log(1, core::ptr::null(), 0, msg.as_ptr(), msg.len() as u64);
core::arch::asm!("unimp", options(noreturn));
}
}