fix: 控制流逃出计数读越界防御,无 ext 字的返回安全降级
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user