From a811857cc85a01f921e5ad4891bd7674fa00b781 Mon Sep 17 00:00:00 2001 From: Selfhosting Dev Date: Sat, 20 Sep 2025 05:50:45 +0900 Subject: [PATCH] mir(hints): add runtime tracing via NYASH_MIR_TRACE_HINTS; wire scope enter/leave at function entry/exit; add smoke to validate trace --- src/mir/hints.rs | 19 +++++++++++++-- tools/test/smoke/mir/hints_trace_smoke.sh | 28 +++++++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 tools/test/smoke/mir/hints_trace_smoke.sh diff --git a/src/mir/hints.rs b/src/mir/hints.rs index 299e5da7..e8237f84 100644 --- a/src/mir/hints.rs +++ b/src/mir/hints.rs @@ -27,7 +27,23 @@ impl HintSink { pub fn new() -> Self { Self { enabled: false } } pub fn with_enabled(mut self, enabled: bool) -> Self { self.enabled = enabled; self } - #[inline] pub fn record(&mut self, _hint: HintKind) {} + #[inline] + pub fn record(&mut self, hint: HintKind) { + // Lightweight trace: print only when explicitly enabled via env + let enabled = self.enabled + || std::env::var("NYASH_MIR_TRACE_HINTS").ok().as_deref() == Some("1"); + if !enabled { return; } + match hint { + HintKind::ScopeEnter(id) => eprintln!("[mir][hint] ScopeEnter({})", id), + HintKind::ScopeLeave(id) => eprintln!("[mir][hint] ScopeLeave({})", id), + HintKind::Defer(calls) => eprintln!("[mir][hint] Defer({})", calls.join(";")), + HintKind::JoinResult(var) => eprintln!("[mir][hint] JoinResult({})", var), + HintKind::LoopCarrier(vars) => eprintln!("[mir][hint] LoopCarrier({})", vars.join(",")), + HintKind::LoopHeader => eprintln!("[mir][hint] LoopHeader"), + HintKind::LoopLatch => eprintln!("[mir][hint] LoopLatch"), + HintKind::NoEmptyPhi => eprintln!("[mir][hint] NoEmptyPhi"), + } + } #[inline] pub fn scope_enter(&mut self, id: u32) { self.record(HintKind::ScopeEnter(id)); } #[inline] pub fn scope_leave(&mut self, id: u32) { self.record(HintKind::ScopeLeave(id)); } #[inline] pub fn defer_calls>(&mut self, calls: impl IntoIterator) { @@ -41,4 +57,3 @@ impl HintSink { #[inline] pub fn loop_latch(&mut self) { self.record(HintKind::LoopLatch); } #[inline] pub fn no_empty_phi(&mut self) { self.record(HintKind::NoEmptyPhi); } } - diff --git a/tools/test/smoke/mir/hints_trace_smoke.sh b/tools/test/smoke/mir/hints_trace_smoke.sh new file mode 100644 index 00000000..18f8816d --- /dev/null +++ b/tools/test/smoke/mir/hints_trace_smoke.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +set -euo pipefail + +root=$(cd "$(dirname "$0")"/../../../.. && pwd) +bin="$root/target/release/nyash" +src="apps/tests/macro/match/literal_basic.nyash" + +if [ ! -x "$bin" ]; then + echo "nyash binary not found at $bin; build first (cargo build --release)" >&2 + exit 1 +fi + +export NYASH_MIR_TRACE_HINTS=1 + +# Capture stderr (where hints are printed) +out=$({ "$bin" --backend vm "$src" 1>/dev/null; } 2>&1 || true) + +echo "$out" | rg -q "\[mir\]\[hint\] ScopeEnter\(0\)" || { + echo "[FAIL] missing ScopeEnter(0) hint" >&2 + exit 2 +} +echo "$out" | rg -q "\[mir\]\[hint\] ScopeLeave\(0\)" || { + echo "[FAIL] missing ScopeLeave(0) hint" >&2 + exit 2 +} + +echo "[OK] MIR hints trace smoke passed" +