From 4fa21d85d82fe1a5a4ee61d37ac08f232a5dec34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=88=B1=E7=89=B9=E6=AF=8F=E7=BE=8A=E9=98=9F?= Date: Fri, 7 Aug 2026 00:42:33 +0800 Subject: [PATCH] =?UTF-8?q?fix(vm):=20CREATE=5FCLOSURE=20=E8=B6=8A?= =?UTF-8?q?=E7=95=8C=E6=94=B9=E8=BF=90=E8=A1=8C=E6=97=B6=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E9=98=B2=E8=BF=9B=E7=A8=8B=E4=B8=AD=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_vm/src/dispatch/call.rs | 13 +++++++++++-- crates/oxide_vm/src/vm.rs | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/crates/oxide_vm/src/dispatch/call.rs b/crates/oxide_vm/src/dispatch/call.rs index c609477..bcc0e86 100644 --- a/crates/oxide_vm/src/dispatch/call.rs +++ b/crates/oxide_vm/src/dispatch/call.rs @@ -86,10 +86,18 @@ impl Vm { } impl Vm { - pub(crate) fn dispatch_create_closure(&mut self, rd: usize, instr: u32) { + pub(crate) fn dispatch_create_closure(&mut self, rd: usize, instr: u32) -> Result<(), String> { let sub_idx = opcode::imm16(instr) as u32; vm_trace!("CREATE_CLOSURE rd={} sub_idx={}", rd, sub_idx); - debug_assert!(sub_idx > 0 && (sub_idx as usize) <= self.sub_modules.len()); + if sub_idx == 0 || (sub_idx as usize) > self.sub_modules.len() { + // 逃逸闭包(函数对象在定义模块之外被创建)时 sub_idx 相对定义模块, + // 超出当前 sub_modules 上下文——按运行时错误处理而非索引越界 panic。 + return Err(format!( + "CREATE_CLOSURE: sub_module_index {} out of bounds (max {})", + sub_idx, + self.sub_modules.len() + )); + } let sub = &self.sub_modules[sub_idx as usize - 1]; let is_arrow = sub.is_arrow; let is_class_constructor = sub.is_class_constructor; @@ -119,6 +127,7 @@ impl Vm { } } self.regs[rd] = result; + Ok(()) } #[allow(dead_code)] diff --git a/crates/oxide_vm/src/vm.rs b/crates/oxide_vm/src/vm.rs index ce51d26..30f2ac3 100644 --- a/crates/oxide_vm/src/vm.rs +++ b/crates/oxide_vm/src/vm.rs @@ -869,7 +869,7 @@ impl Vm { } OpCode::CREATE_CLOSURE => { - self.dispatch_create_closure(rd, instr); + self.dispatch_create_closure(rd, instr)?; } OpCode::MAKE_CELL => { self.dispatch_make_cell(rd, instr)?;