From 7e180d9ac1d1406520c4b9e110228050f12f75af Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Sun, 16 Aug 2026 15:02:04 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=8E=A7=E5=88=B6=E6=B5=81=E9=80=83?= =?UTF-8?q?=E5=87=BA=E8=AE=A1=E6=95=B0=E8=AF=BB=E8=B6=8A=E7=95=8C=E9=98=B2?= =?UTF-8?q?=E5=BE=A1=EF=BC=8C=E6=97=A0=20ext=20=E5=AD=97=E7=9A=84=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=E5=AE=89=E5=85=A8=E9=99=8D=E7=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_vm/src/vm_dispatch_ctrl.rs | 7 +++++++ crates/oxide_vm/tests/spill_stack_tests.rs | 7 ++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/crates/oxide_vm/src/vm_dispatch_ctrl.rs b/crates/oxide_vm/src/vm_dispatch_ctrl.rs index d5308ee..273971e 100644 --- a/crates/oxide_vm/src/vm_dispatch_ctrl.rs +++ b/crates/oxide_vm/src/vm_dispatch_ctrl.rs @@ -350,7 +350,14 @@ impl Vm { /// 读取 BREAK/CONTINUE/RETURN 的 ext 字逃出计数(低 16 位 for-of,高 16 位 /// for-in)。调用时机:主循环已把 pc 推进到 ext 字位置;两条跳转/返回路径 /// 都会覆盖 pc,此处无需再推进。 + /// + /// # 边界与前提 + /// - 手工构造的 IR 可能让 RETURN/BREAK/CONTINUE 落在末位且无 ext 字(pc == len), + /// 此时按 (0, 0) 处理:无迭代器逃出,语义正确。 fn read_escape_counts(&self) -> (usize, usize) { + if self.pc >= self.bytecode.len() { + return (0, 0); + } let packed = self.bytecode[self.pc]; ((packed & 0xFFFF) as usize, (packed >> 16) as usize) } diff --git a/crates/oxide_vm/tests/spill_stack_tests.rs b/crates/oxide_vm/tests/spill_stack_tests.rs index ef7929f..58c1161 100644 --- a/crates/oxide_vm/tests/spill_stack_tests.rs +++ b/crates/oxide_vm/tests/spill_stack_tests.rs @@ -62,10 +62,7 @@ fn spill_unspill_roundtrip() { #[test] fn frame_boundary_parent_spill_survives_call() { let child = int_module( - vec![ - Inst::load_const(Operand::Reg(3), 0), - Inst::new(OpCode::RETURN, Operand::Reg(3), Operand::None, Operand::None), - ], + vec![Inst::load_const(Operand::Reg(3), 0), Inst::ret(Operand::Reg(3), 0, 0)], 99, 4, Vec::new(), @@ -90,7 +87,7 @@ fn nested_call_both_spill() { vec![ Inst::load_const(Operand::Reg(3), 0), Inst::inst_spill(Operand::Reg(3), 0), - Inst::new(OpCode::RETURN, Operand::Reg(3), Operand::None, Operand::None), + Inst::ret(Operand::Reg(3), 0, 0), ], 99, 4,