feat: 异常与 return 穿越释放资源,dispose_count 门控

This commit is contained in:
2026-10-09 19:14:36 +00:00
parent 48ffb54c4f
commit ae73fb8da5
20 changed files with 264 additions and 152 deletions
+12 -10
View File
@@ -447,39 +447,41 @@ impl Inst {
/// break 完成:label 指向循环/switch 出口,`crossed` 为逃出的 finally 域数
/// (emit 词法计算,运行时据此逐个穿越 finally;0 表示未逃出,不产生完成语义)。
/// `for_of_count`/`for_in_count` 为逃出的迭代器层数,编码进 ext 字——
/// BREAK/CONTINUE 的 a/b 槽被跳转 offset 占用,无空闲位。
/// 编码:rd 槽放 crossed(≤255),label 放 b 槽,ext[0] 打包两个逃出计数。
pub fn brk(label: LabelId, crossed: u16, for_of_count: usize, for_in_count: usize) -> Self {
/// `for_of_count`/`for_in_count` 为逃出的迭代器层数,`dispose_count` 为逃出的
/// 资源条数,编码进 ext 字——BREAK/CONTINUE 的 a/b 槽被跳转 offset 占用,无空闲位。
/// 编码:rd 槽放 crossed(≤255),label 放 b 槽,ext[0] 打包两个迭代器计数,
/// ext[1] 放 dispose_count。
pub fn brk(label: LabelId, crossed: u16, for_of_count: usize, for_in_count: usize, dispose_count: usize) -> Self {
Self::with_ext(
OpCode::BREAK,
Operand::Imm(crossed),
Operand::None,
Operand::Label(label),
&[pack_escape_counts(for_of_count, for_in_count)],
&[pack_escape_counts(for_of_count, for_in_count), dispose_count as u32],
)
}
/// continue 完成:同 break,label 指向循环继续目标。
pub fn cont(label: LabelId, crossed: u16, for_of_count: usize, for_in_count: usize) -> Self {
pub fn cont(label: LabelId, crossed: u16, for_of_count: usize, for_in_count: usize, dispose_count: usize) -> Self {
Self::with_ext(
OpCode::CONTINUE,
Operand::Imm(crossed),
Operand::None,
Operand::Label(label),
&[pack_escape_counts(for_of_count, for_in_count)],
&[pack_escape_counts(for_of_count, for_in_count), dispose_count as u32],
)
}
/// return 完成:`src` 为返回值寄存器(None = 隐式 undefined,reg 0)。
/// `for_of_count`/`for_in_count` 为逃出的迭代器层数,编码进 ext 字。
pub fn ret(src: Operand, for_of_count: usize, for_in_count: usize) -> Self {
/// `for_of_count`/`for_in_count` 为逃出的迭代器层数,`dispose_count` 为逃出的
/// 资源条数,编码进 ext 字。
pub fn ret(src: Operand, for_of_count: usize, for_in_count: usize, dispose_count: usize) -> Self {
Self::with_ext(
OpCode::RETURN,
src,
Operand::None,
Operand::None,
&[pack_escape_counts(for_of_count, for_in_count)],
&[pack_escape_counts(for_of_count, for_in_count), dispose_count as u32],
)
}