Refactor (structure): add vm_stats module; move BoxCall debug logger into vm_boxcall; add quick-reference/code-map.md for AI-friendly repo navigation. Keep behavior unchanged.

This commit is contained in:
Moe Charm
2025-08-26 00:58:57 +09:00
parent 2a02eb7a52
commit edadf67ca0
5 changed files with 111 additions and 71 deletions

View File

@ -672,76 +672,6 @@ impl VM {
*self.instr_counter.entry(key).or_insert(0) += 1;
}
pub(super) fn debug_log_boxcall(&self, recv: &VMValue, method: &str, args: &[Box<dyn NyashBox>], stage: &str, result: Option<&VMValue>) {
if std::env::var("NYASH_VM_DEBUG_BOXCALL").ok().as_deref() == Some("1") {
let recv_ty = match recv {
VMValue::BoxRef(arc) => arc.type_name().to_string(),
VMValue::Integer(_) => "Integer".to_string(),
VMValue::Float(_) => "Float".to_string(),
VMValue::Bool(_) => "Bool".to_string(),
VMValue::String(_) => "String".to_string(),
VMValue::Future(_) => "Future".to_string(),
VMValue::Void => "Void".to_string(),
};
let args_desc: Vec<String> = args.iter().map(|a| a.type_name().to_string()).collect();
if let Some(res) = result {
let res_ty = match res {
VMValue::BoxRef(arc) => format!("BoxRef({})", arc.type_name()),
VMValue::Integer(_) => "Integer".to_string(),
VMValue::Float(_) => "Float".to_string(),
VMValue::Bool(_) => "Bool".to_string(),
VMValue::String(_) => "String".to_string(),
VMValue::Future(_) => "Future".to_string(),
VMValue::Void => "Void".to_string(),
};
eprintln!("[VM-BOXCALL][{}] recv_ty={} method={} argc={} args={:?} => result_ty={}", stage, recv_ty, method, args.len(), args_desc, res_ty);
} else {
eprintln!("[VM-BOXCALL][{}] recv_ty={} method={} argc={} args={:?}", stage, recv_ty, method, args.len(), args_desc);
}
}
}
/// Print simple VM execution statistics when enabled via env var
fn maybe_print_stats(&mut self) {
let enabled = std::env::var("NYASH_VM_STATS").ok().map(|v| v != "0").unwrap_or(false);
if !enabled { return; }
let elapsed_ms = self.exec_start.map(|t| t.elapsed().as_secs_f64() * 1000.0).unwrap_or(0.0);
let mut items: Vec<(&str, usize)> = self.instr_counter.iter().map(|(k,v)| (*k, *v)).collect();
items.sort_by(|a,b| b.1.cmp(&a.1).then_with(|| a.0.cmp(&b.0)));
let total: usize = items.iter().map(|(_,v)| *v).sum();
let json_enabled = std::env::var("NYASH_VM_STATS_JSON").ok().map(|v| v != "0").unwrap_or(false)
|| std::env::var("NYASH_VM_STATS_FORMAT").map(|v| v == "json").unwrap_or(false);
if json_enabled {
// Build JSON structure: { total, elapsed_ms, counts: {op: n, ...}, top20: [{op, count}], timestamp_ms }
let counts_obj: std::collections::BTreeMap<&str, usize> = self.instr_counter.iter().map(|(k,v)| (*k, *v)).collect();
let top20: Vec<_> = items.iter().take(20).map(|(op,cnt)| {
serde_json::json!({ "op": op, "count": cnt })
}).collect();
let now_ms = {
use std::time::{SystemTime, UNIX_EPOCH};
SystemTime::now().duration_since(UNIX_EPOCH).map(|d| d.as_millis() as u64).unwrap_or(0)
};
let payload = serde_json::json!({
"total": total,
"elapsed_ms": elapsed_ms,
"counts": counts_obj,
"top20": top20,
"timestamp_ms": now_ms
});
match serde_json::to_string_pretty(&payload) {
Ok(s) => println!("{}", s),
Err(_) => println!("{{\"total\":{},\"elapsed_ms\":{:.3}}}", total, elapsed_ms),
}
} else {
println!("\n🧮 VM Stats: {} instructions in {:.3} ms", total, elapsed_ms);
for (k, v) in items.into_iter().take(20) {
println!(" {:>10}: {:>8}", k, v);
}
}
}
/// Phase 9.78a: Unified method dispatch for all Box types
fn call_unified_method(&self, box_value: Box<dyn NyashBox>, method: &str, args: Vec<Box<dyn NyashBox>>) -> Result<Box<dyn NyashBox>, VMError> {