feat(vm): add call stack depth guard to MirInterpreter
This commit is contained in:
@ -13,6 +13,23 @@ impl MirInterpreter {
|
||||
func: &MirFunction,
|
||||
arg_vals: Option<&[VMValue]>,
|
||||
) -> Result<VMValue, VMError> {
|
||||
// Safety valve: cap nested exec_function_inner depth to avoid Rust stack overflow
|
||||
// on accidental infinite recursion in MIR (e.g., self-recursive call chains).
|
||||
const MAX_CALL_DEPTH: usize = 1024;
|
||||
self.call_depth = self.call_depth.saturating_add(1);
|
||||
if self.call_depth > MAX_CALL_DEPTH {
|
||||
eprintln!(
|
||||
"[vm-call-depth] exceeded {} in fn={} (depth={})",
|
||||
MAX_CALL_DEPTH,
|
||||
func.signature.name,
|
||||
self.call_depth
|
||||
);
|
||||
self.call_depth = self.call_depth.saturating_sub(1);
|
||||
return Err(VMError::InvalidInstruction(format!(
|
||||
"vm call stack depth exceeded (max_depth={}, fn={})",
|
||||
MAX_CALL_DEPTH, func.signature.name
|
||||
)));
|
||||
}
|
||||
// Phase 1: delegate cross-class reroute / narrow fallbacks to method_router
|
||||
if let Some(r) = super::method_router::pre_exec_reroute(self, func, arg_vals) { return r; }
|
||||
let saved_regs = mem::take(&mut self.regs);
|
||||
@ -96,6 +113,7 @@ impl MirInterpreter {
|
||||
BlockOutcome::Return(result) => {
|
||||
self.cur_fn = saved_fn;
|
||||
self.regs = saved_regs;
|
||||
self.call_depth = self.call_depth.saturating_sub(1);
|
||||
return Ok(result);
|
||||
}
|
||||
BlockOutcome::Next {
|
||||
|
||||
@ -41,6 +41,9 @@ pub struct MirInterpreter {
|
||||
pub(super) inst_count: u64,
|
||||
pub(super) branch_count: u64,
|
||||
pub(super) compare_count: u64,
|
||||
/// Call stack depth (exec_function_inner nesting). Used as a safety valve
|
||||
/// to prevent Rust stack overflow on accidental infinite recursion in MIR.
|
||||
pub(super) call_depth: usize,
|
||||
}
|
||||
|
||||
impl MirInterpreter {
|
||||
@ -58,6 +61,7 @@ impl MirInterpreter {
|
||||
inst_count: 0,
|
||||
branch_count: 0,
|
||||
compare_count: 0,
|
||||
call_depth: 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user