mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-25 11:11:11 +08:00
744899aae9
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 嵌套
28 lines
1.0 KiB
Rust
28 lines
1.0 KiB
Rust
//! do-while 语句 emit:`emit_do_while_statement` 先执行体后测条件。
|
||
|
||
use crate::{CompileCtx, Emitter};
|
||
use oxide_ir::inst::Inst;
|
||
use oxide_parser::Statement;
|
||
|
||
impl Emitter {
|
||
pub(crate) fn emit_do_while_statement(
|
||
&self, stmt: &Statement, ctx: &mut CompileCtx,
|
||
) -> Result<Option<u32>, String> {
|
||
let Statement::DoWhileStatement(dw) = stmt else {
|
||
return Ok(None);
|
||
};
|
||
let start_label = ctx.next_label_id();
|
||
let end_label = ctx.next_label_id();
|
||
ctx.labels.set_label_pos(start_label, ctx.insts.len());
|
||
ctx.push_loop(end_label, start_label, crate::emit_ctx::LoopKind::Plain);
|
||
let n_labeled = ctx.take_pending_loop_labels(end_label, start_label);
|
||
self.emit_statement(&dw.body, ctx)?;
|
||
let test_reg = self.emit_expression(&dw.test, ctx)?;
|
||
ctx.inst(Inst::jmp_if_true(test_reg, start_label));
|
||
ctx.labels.set_label_pos(end_label, ctx.insts.len());
|
||
ctx.pop_label_scopes(n_labeled);
|
||
ctx.pop_loop();
|
||
Ok(None)
|
||
}
|
||
}
|