use crate::panic::GoPanic;
use std::io::Write;
pub fn fatal(msg: &[u8]) -> ! {
let mut err = std::io::stderr().lock();
let _ = err.write_all(b"fatal error: ");
let _ = err.write_all(msg);
let _ = err.write_all(b"\n");
std::process::exit(2)
}
pub fn write_err(p: crate::unsafe_ptr::UPtr, n: i64) {
if n <= 0 || p.addr() == 0 {
return;
}
let bytes = unsafe { std::slice::from_raw_parts(p.addr() as usize as *const u8, n as usize) };
let _ = std::io::stderr().lock().write_all(bytes);
}
pub fn nanotime() -> i64 {
static START: std::sync::OnceLock<std::time::Instant> = std::sync::OnceLock::new();
START
.get_or_init(std::time::Instant::now)
.elapsed()
.as_nanos() as i64
}
pub fn run_main(init: fn(), main: fn()) -> ! {
let result = std::panic::catch_unwind(|| {
init();
main();
});
match result {
Ok(()) => std::process::exit(0),
Err(payload) => {
let mut err = std::io::stderr().lock();
match payload.downcast::<GoPanic>() {
Ok(p) => {
let _ = err.write_all(b"panic: ");
let _ = err.write_all(p.text());
let _ = err.write_all(b"\n\ngoroutine 1 [running]:\n");
}
Err(_) => {
let _ = err.write_all(b"fatal error: unexpected Rust panic\n");
}
}
std::process::exit(2)
}
}
}