for-of 迭代器栈条目化:迭代器与最近 next 结果配对存放

单一 last_for_of_result 槽被嵌套迭代覆盖,CLOSE 判定本迭代器是否
自然 done 时误读他者结果,导致数组解构/spread/嵌套 for-of 提前退出
漏调或误调 return()。改为栈条目 (iterator, last_result) 配对:

- IterState.for_of_iters 元素改 ForOfEntry,删除 last_for_of_result
- INIT 压条目,DONE 写本条目,NEXT/CLOSE 读本条目结果判 done
- GC mark/rewrite、inline save/restore、挂起帧快照同步配对遍历
- for-await-of 数组解构提前 break 现正确触发 return()(任务 40 样例)
This commit is contained in:
2026-08-16 04:00:06 +08:00
parent 19fcdd73d0
commit b885b672b9
9 changed files with 166 additions and 65 deletions
+30 -15
View File
@@ -116,18 +116,29 @@ impl SymbolState {
}
}
/// for-of 迭代器栈条目:迭代器对象与其最近一次 `next()` 结果对象配对存放。
///
/// `last_result` 只属于本迭代器(嵌套 for-of / 数组解构 / spread 各自持有自己的
/// 结果),`FOR_OF_CLOSE`/`FOR_AWAIT_OF_CLOSE` 据此判定本迭代器是否自然 done,
/// 避免共享单槽被其它迭代器覆盖导致漏调/多调 `return()`。
#[derive(Debug, Clone, Copy)]
pub(crate) struct ForOfEntry {
/// 迭代器对象(同步迭代器 / 异步迭代器 / AsyncFromSyncIterator 包装)。
pub(crate) iterator: JsValue,
/// 本迭代器最近一次 DONE 返回的结果对象(CLOSE 判 done 用)。
pub(crate) last_result: JsValue,
}
/// for-in / for-of 的活跃迭代器状态。
pub(crate) struct IterState {
pub(crate) for_in_iters: Vec<*mut ForInIter<'static>>,
pub(crate) for_of_iters: Vec<JsValue>,
pub(crate) last_for_of_result: JsValue,
pub(crate) for_of_iters: Vec<ForOfEntry>,
}
impl IterState {
pub(crate) fn reset(&mut self) {
self.for_in_iters.clear();
self.for_of_iters.clear();
self.last_for_of_result = JsValue::undefined();
}
pub(crate) fn push_for_in(&mut self, iter: *mut ForInIter<'static>) {
@@ -142,28 +153,32 @@ impl IterState {
self.for_in_iters.last().copied().unwrap_or(std::ptr::null_mut())
}
pub(crate) fn push_for_of(&mut self, val: JsValue) {
self.for_of_iters.push(val);
/// 压入新迭代器条目:`last_result` 初始为 undefined(尚未执行任何 next())。
pub(crate) fn push_for_of(&mut self, iterator: JsValue) {
self.for_of_iters.push(ForOfEntry {
iterator,
last_result: JsValue::undefined(),
});
}
pub(crate) fn last_for_of(&self) -> Option<JsValue> {
self.for_of_iters.last().copied()
self.for_of_iters.last().map(|e| e.iterator)
}
pub(crate) fn pop_for_of(&mut self) -> Option<JsValue> {
pub(crate) fn pop_for_of(&mut self) -> Option<ForOfEntry> {
self.for_of_iters.pop()
}
pub(crate) fn last_for_of_result(&self) -> JsValue {
self.last_for_of_result
/// 栈顶条目最近一次 DONE 结果;栈空时返回 undefined(防御)。
pub(crate) fn last_result(&self) -> JsValue {
self.for_of_iters.last().map(|e| e.last_result).unwrap_or(JsValue::undefined())
}
pub(crate) fn set_last_for_of_result(&mut self, val: JsValue) {
self.last_for_of_result = val;
}
pub(crate) fn clear_last_for_of_result(&mut self) {
self.last_for_of_result = JsValue::undefined();
/// 写入栈顶条目的 DONE 结果(本迭代器自身的结果,不跨迭代器覆盖)。
pub(crate) fn set_last_result(&mut self, val: JsValue) {
if let Some(entry) = self.for_of_iters.last_mut() {
entry.last_result = val;
}
}
}