From 9a47ad7c1f93a09e0d00155f29ab5d643fd62b4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=88=B1=E7=89=B9=E6=AF=8F=E7=BE=8A=E9=98=9F?= Date: Fri, 7 Aug 2026 16:19:35 +0800 Subject: [PATCH] =?UTF-8?q?fix(vm):=20=E9=97=AD=E5=8C=85=E6=8D=95=E8=8E=B7?= =?UTF-8?q?=20let/const=20=E7=9A=84=20cell=20=E6=9C=AA=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=EF=BC=88TDZ=EF=BC=89=E8=AF=BB=E5=8F=96=E6=8A=9B=20Ref?= =?UTF-8?q?erenceError?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_vm/src/dispatch/call.rs | 30 +++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/crates/oxide_vm/src/dispatch/call.rs b/crates/oxide_vm/src/dispatch/call.rs index 7b06ddf..92cce68 100644 --- a/crates/oxide_vm/src/dispatch/call.rs +++ b/crates/oxide_vm/src/dispatch/call.rs @@ -154,8 +154,10 @@ impl Vm { // MAKE_CELL)——建占位 Cell,后续 MAKE_CELL 更新同一 Cell 的值, // 保证 upvalue 始终指向定义方表里的稳定 cell(而非调用方表)。 if current_cells[cell_idx].is_null() { + // 占位 Cell 保持未初始化(TDZ)直到 MAKE_CELL 置位; + // 若绑定为 var 则其初始化 MAKE_CELL 在函数序言先于任何读取执行。 let cell = - self.gc_state.session_epoch.alloc(Cell::new(JsValue::undefined(), true)); + self.gc_state.session_epoch.alloc(Cell::new(JsValue::undefined(), false)); current_cells[cell_idx] = cell as *mut Cell; } current_cells[cell_idx] @@ -184,9 +186,11 @@ impl Vm { current[cell_idx] = cell as *mut Cell; } else { // 更新占位 cell(CREATE_CLOSURE 已建),使闭包 upvalue 指向的 - // cell 值跟随初始化。 + // cell 值跟随初始化;赋值即解除 TDZ。 unsafe { - (*current[cell_idx]).value = value; + let cell = &mut *current[cell_idx]; + cell.value = value; + cell.set_initialized(true); } } Ok(()) @@ -204,7 +208,11 @@ impl Vm { let cell = self.gc_state.session_epoch.alloc(Cell::new(val, true)); current[cell_idx] = cell as *mut Cell; } - self.regs[rd] = unsafe { (*current[cell_idx]).value }; + let c = unsafe { &*current[cell_idx] }; + if !c.is_initialized() { + return self.raise_error_kind("ReferenceError", "Cannot access variable before initialization"); + } + self.regs[rd] = c.value; Ok(()) } @@ -221,7 +229,9 @@ impl Vm { return Ok(()); } unsafe { - (*cell_ptr).value = src_val; + let cell = &mut *cell_ptr; + cell.value = src_val; + cell.set_initialized(true); } Ok(()) } @@ -242,7 +252,11 @@ impl Vm { if uv_idx < upvals.len() { let cell = upvals[uv_idx]; if !cell.is_null() { - self.regs[rd] = unsafe { (*cell).value }; + let c = unsafe { &*cell }; + if !c.is_initialized() { + return self.raise_error_kind("ReferenceError", "Cannot access variable before initialization"); + } + self.regs[rd] = c.value; return Ok(()); } } @@ -292,7 +306,9 @@ impl Vm { if uv_idx < upvals.len() { if !upvals[uv_idx].is_null() { unsafe { - (*upvals[uv_idx]).value = src_val; + let cell = &mut *upvals[uv_idx]; + cell.value = src_val; + cell.set_initialized(true); } vm_debug!("STORE_UPVALUE len={} wrote existing", upvals.len()); } else {