use core::ffi::c_void;
pub fn demangle(mangled: &str) -> String {
let prefixed = if mangled.starts_with("$s") || mangled.starts_with("_$s") {
mangled.to_string()
} else {
format!("$s{mangled}")
};
let Ok(cstr) = std::ffi::CString::new(prefixed.as_bytes()) else {
return mangled.to_string();
};
swift_runtime::demangle::demangle(&cstr).unwrap_or_else(|| mangled.to_string())
}
pub fn demangle_type(mangled: &[u8]) -> String {
let s = std::str::from_utf8(mangled).unwrap_or("<invalid utf8>");
demangle(s)
}
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub fn type_name(metadata: *const c_void) -> String {
if metadata.is_null() {
return "<null>".to_string();
}
unsafe {
match swift_runtime_sys::SwiftCCThunks::swift_getTypeName(metadata, true) {
Ok((name, len)) if len > 0 => name.to_string(),
_ => format!("<metadata {metadata:?}>"),
}
}
}
pub fn symbol_name(sym: &core::ffi::CStr) -> String {
let raw = sym.to_str().unwrap_or("<invalid>");
let demangled = demangle(raw);
if demangled == raw {
raw.to_string()
} else {
format!("{demangled} ({raw})")
}
}
pub unsafe fn dump_any(value: *mut c_void, metadata: *const c_void, max_depth: u64) -> String {
use crate::{abi, resolve};
unsafe {
let _pool = crate::objc::AutoreleasePool::new();
let mut target = abi::swift_string("");
let name = abi::swift_string("v");
let n0 = u64::from_le_bytes(name[0..8].try_into().expect("name lo"));
let n1 = u64::from_le_bytes(name[8..16].try_into().expect("name hi"));
let mut returned = vec![0u8; abi::type_bytes(metadata)];
core::arch::asm!(
"sub sp, sp, #32",
"stp {sm}, {wt}, [sp]",
"blr {f}",
"add sp, sp, #32",
f = in(reg) resolve::dump_fn(),
sm = in(reg) resolve::string_meta(),
wt = in(reg) resolve::string_text_output_wt(),
in("x0") value,
in("x1") target.as_mut_ptr(),
in("x2") n0,
in("x3") n1,
in("x4") 0u64,
in("x5") max_depth,
in("x6") 400u64,
in("x7") metadata,
in("x8") returned.as_mut_ptr(),
lateout("x9") _, lateout("x10") _, lateout("x11") _, lateout("x12") _,
lateout("x13") _, lateout("x14") _, lateout("x15") _, lateout("x16") _,
lateout("x17") _, lateout("lr") _, lateout("x20") _, lateout("x21") _,
clobber_abi("C"),
);
let vwt = &*swift_runtime_sys::SwiftABI::get_value_witness_table(metadata);
(vwt.destroy)(returned.as_mut_ptr() as *mut c_void, metadata);
let text = abi::read_swift_string(target);
let string_meta = resolve::string_meta();
let string_vwt = &*swift_runtime_sys::SwiftABI::get_value_witness_table(string_meta);
(string_vwt.destroy)(target.as_mut_ptr() as *mut c_void, string_meta);
text
}
}