use crate::memory::{Memory, StackFrame};
use std::fmt::Write;
pub fn heap_dump_ascii(object_count: usize, array_count: usize) -> String {
format!(
"=== Heap Dump ===\nObjects: {}\nArrays: {}\n",
object_count, array_count
)
}
pub fn memory_dump_ascii(memory: &Memory) -> String {
let mut out = String::from("=== Memory Dump ===\n\n");
out.push_str(&heap_dump_ascii(
memory.heap.object_count(),
memory.heap.array_count(),
));
out.push_str("\n=== Call Stack ===\n");
for (i, frame) in memory.stack.frames().iter().enumerate() {
out.push_str(&format!("\n--- Frame {} ---\n", i));
out.push_str(&frame_dump_ascii(frame));
}
out
}
pub fn frame_dump_ascii(frame: &StackFrame) -> String {
let mut out = String::from("=== Stack Frame ===\n");
let _ = write!(out, "Method: {}\n", frame.method_name);
let _ = write!(out, "PC: {}\n", frame.pc);
let _ = write!(out, "Locals ({}):\n", frame.locals.len());
for (i, v) in frame.locals.iter().enumerate() {
let _ = write!(out, " [{}] {:?}\n", i, v);
}
let _ = write!(out, "Operand stack ({}):\n", frame.stack.len());
for (i, v) in frame.stack.iter().enumerate() {
let _ = write!(out, " [{}] {:?}\n", i, v);
}
out
}
pub fn export_html_fragment(frames: &[StackFrame]) -> String {
let mut out = String::from("<div class=\"jvmrs-dump\">\n");
for (i, f) in frames.iter().enumerate() {
let _ = write!(out, "<div class=\"frame\"><h4>Frame {}</h4>\n", i);
let _ = write!(
out,
"<pre>{}</pre></div>\n",
html_escape(&frame_dump_ascii(f))
);
}
out.push_str("</div>\n");
out
}
fn html_escape(s: &str) -> String {
s.replace('&', "&")
.replace('<', "<")
.replace('>', ">")
.replace('"', """)
}