fix: for-of/for-in 提前退出时按规范顺序完成 IteratorClose

return/break/continue 逃出 for-of 时此前完全不执行 IteratorClose:
BREAK/CONTINUE/RETURN 指令现在经 ext 字携带词法逃出的迭代器层数
(for-of + for-in 各 16 位),运行时在全部 finally 穿越之后、真正
跳转/返回之前按 LIFO 关闭——与规范 §13.7.5.4(循环体完成值已含
内部 try-finally 处理,IteratorClose 在后)顺序一致。

- emit 词法:LabelCtx 增加 for-of/for-in 深度计数,loop/switch/label
  打开时快照,break/continue/return 按当前深度减目标深度计算逃出层数
  (switch 内 break 以 switch 打开点为基准,目标循环自身不计入)
- 指令编码:brk/cont/ret 三参构造,lower 跳转路径补发 ext 字
- 运行时:dispatch_break/continue/return 读取逃出计数,无 finally 时
  直接关闭后跳转/返回,有 finally 时随 Completion 悬挂由 TRY_FINALLY_END
  在穿越完成后消费;生成器 .return()/.throw() 注入经 complete_generator_return
  全关快照栈迭代器;return() 抛错经 unwind 替代完成值并关闭剩余迭代器
- 顺带:for-in 逃出残留(无 return() 语义,仅弹栈);for-await-of 的
  异步迭代器不做同步关闭(return() promise 须 await,走异步机制)
- 新增 15 项回归测试:return/labeled break/continue/switch/while/finally
  顺序/抛错优先/生成器注入/for-in/for-await-of 嵌套
This commit is contained in:
2026-08-16 09:31:39 +08:00
parent b885b672b9
commit a8378694be
23 changed files with 893 additions and 204 deletions
+11 -11
View File
@@ -129,12 +129,7 @@ impl Emitter {
// accessor calls (which clear the register file). The synthetic key keeps user
// bindings with the same name (outer scopes) untouched.
let class_self_cell: Option<u8> = ctor_name.as_deref().map(|_| {
let cell_idx = ctx
.captured_bindings
.values()
.copied()
.max()
.map_or(0, |m| m.saturating_add(1));
let cell_idx = ctx.captured_bindings.values().copied().max().map_or(0, |m| m.saturating_add(1));
ctx.captured_bindings.insert(format!("@@class_self_{cell_idx}"), cell_idx);
cell_idx
});
@@ -302,9 +297,7 @@ impl Emitter {
module.insts.extend(field_ctx.insts);
module.constants = field_ctx.constants;
module.n_registers = field_ctx.max_regs.max(1);
module
.insts
.push(Inst::new(OpCode::RETURN, Operand::None, Operand::None, Operand::None));
module.insts.push(Inst::ret(Operand::None, 0, 0));
}
module
};
@@ -377,10 +370,17 @@ impl Emitter {
Operand::None,
));
}
self.emit_class_methods(&class.body.body, ctor_reg, proto_reg, &self_binding, class_self_cell, &key_slots, ctx)?;
self.emit_class_methods(
&class.body.body,
ctor_reg,
proto_reg,
&self_binding,
class_self_cell,
&key_slots,
ctx,
)?;
self.emit_class_static_elements(&class.body.body, ctor_reg, &key_slots, ctx)?;
// 类构建完成:初始化类名绑定并写入类构造器(类内方法引用该寄存器/捕获)。
if let Some(name) = ctor_name.as_deref() {
ctx.init_var(name);