mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-24 18:51:13 +08:00
fix: 修复块级闭包 TDZ 占位与调用窗口踩踏及 for-of 迭代器展开
This commit is contained in:
@@ -303,8 +303,16 @@ impl Vm {
|
||||
// 窗口 = min(调用方活动寄存器, 存活上界);call_window=0 表示调用方全量
|
||||
// (运行时发起路径 / 未编码的旧模块)。恢复按窗口回拷,active_reg_limit
|
||||
// 仍还原为调用方真实值(caller_active_reg_limit)。
|
||||
// native 调用在飞(native_call_depth > 0)时窗口扩到全量 254:native 实参
|
||||
// 暂存在调用点参数窗口(物理槽 252/253 一带),内层字节码调用复用同一
|
||||
// 参数窗口会踩掉外层 native 实参;窗口截断不覆盖参数窗口时 restore
|
||||
// 不还原,外层 builtin 后续读实参得踩值。
|
||||
let caller_active_reg_limit = self.active_reg_limit.max(1);
|
||||
let caller_reg_limit = self.call_window_limit(caller_active_reg_limit, call_window);
|
||||
let caller_reg_limit = if self.native_call_depth > 0 {
|
||||
254
|
||||
} else {
|
||||
self.call_window_limit(caller_active_reg_limit, call_window)
|
||||
};
|
||||
let saved_reg_offset = self.save_stack.len() as u32;
|
||||
self.save_stack.extend_from_slice(&self.regs[..caller_reg_limit as usize]);
|
||||
let saved_this = self.regs[254];
|
||||
|
||||
@@ -1032,8 +1032,15 @@ impl Vm {
|
||||
pub(crate) fn dispatch_for_of_init(&mut self, a: usize) -> Result<(), String> {
|
||||
vm_trace!("FOR_OF_INIT r{}={:?}", a, self.regs[a]);
|
||||
let iterable = self.regs[a];
|
||||
let pc_before = self.pc;
|
||||
match oxide_builtins::iterator::make_iterator_for_value(self, iterable) {
|
||||
Ok(iterator) => {
|
||||
// 取迭代器期间源 getter 抛出:深度 0 的 raise_call_error 已就地
|
||||
// unwind(跳转 catch),pc 已改写——迭代器值无效,直接返回,
|
||||
// 派发循环自 catch 点续行,不得再触碰迭代器栈。
|
||||
if self.pc != pc_before {
|
||||
return Ok(());
|
||||
}
|
||||
// 内置包装器检测:Array/String/TA/Map/Set 走快路径(异步恒慢)。
|
||||
// init 期把 inner 快照入条目,步内不重读 `__inner__` 槽。
|
||||
let (kind, inner) = match oxide_builtins::iterator::builtin_iter_kind(self, iterator) {
|
||||
@@ -1044,6 +1051,12 @@ impl Vm {
|
||||
Ok(())
|
||||
}
|
||||
Err(err) => {
|
||||
// 取迭代器期间源 getter 抛出:深度 0 的 raise_call_error 已就地
|
||||
// unwind(跳转 catch),pc 已改写、handler 已弹出——不得再 unwind
|
||||
//(二次展开无 handler 必报未捕获),派发循环自 catch 点续行。
|
||||
if self.pc != pc_before {
|
||||
return Ok(());
|
||||
}
|
||||
self.exception_value = Some(err);
|
||||
self.pending_error_kind = Some(self.thrown_error_kind(err));
|
||||
self.unwind()
|
||||
|
||||
@@ -466,7 +466,15 @@ impl Vm {
|
||||
vm_trace!("call_bytecode: saving state pc={} depth={}", self.pc, self.frames.len());
|
||||
// 窗口 = max(调用方活跃寄存器, callee 寄存器数):restore 只回拷窗口,正好
|
||||
// 覆盖 callee 写入区(regs[0..n_registers] + 254/255)与调用方活动区。
|
||||
let window = self.active_reg_limit.max(sub.n_registers).max(1) as usize;
|
||||
// native 调用在飞(native_call_depth > 0)时窗口扩到全量 254:native 实参
|
||||
// 暂存在调用点参数窗口(物理槽 252/253 一带,arg_window_base = 254 − max_nargs),
|
||||
// 内层字节码调用复用同一参数窗口会踩掉外层 native 实参;窗口截断不覆盖
|
||||
// 参数窗口时 restore 不还原,外层 builtin 后续读实参得踩值。
|
||||
let window = if self.native_call_depth > 0 {
|
||||
254
|
||||
} else {
|
||||
self.active_reg_limit.max(sub.n_registers).max(1) as usize
|
||||
};
|
||||
let saved = self.save_inline_state(window);
|
||||
|
||||
// 只零填 callee 读区 regs[0..n_registers];高位残留调用方旧值无害
|
||||
|
||||
Reference in New Issue
Block a user