From 2755894330ba012334e271f85cc9e6c7175023f2 Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Sun, 16 Aug 2026 12:34:14 +0800 Subject: [PATCH] =?UTF-8?q?test:=20upvalue=20cell=20=E6=97=B6=E5=BA=8F?= =?UTF-8?q?=E5=88=A4=E5=88=AB=E7=94=A8=E4=BE=8B=EF=BC=88class=20=E6=8D=95?= =?UTF-8?q?=E8=8E=B7/var=20=E5=85=A5=E5=8F=A3=E5=88=9D=E5=A7=8B=E5=8C=96/?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E9=BB=98=E8=AE=A4=E5=80=BC=E9=93=BE=E5=BC=8F?= =?UTF-8?q?=E6=8D=95=E8=8E=B7=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_vm/tests/async_tests.rs | 57 ++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/crates/oxide_vm/tests/async_tests.rs b/crates/oxide_vm/tests/async_tests.rs index e2d7439..bc1984e 100644 --- a/crates/oxide_vm/tests/async_tests.rs +++ b/crates/oxide_vm/tests/async_tests.rs @@ -285,3 +285,60 @@ fn object_async_generator_method_yields() { "\"5:true\"" ); } + +// ── upvalue cell 运行时 TDZ 误报(判别测试) ── + +// T1(根因 A):class 声明在前、async 函数在后。hoisting 使 async 体先编译, +// 若 class 名未进 captured_bindings → 编译期 THROW(命名错),期望经 cell 读到构造器。 +#[test] +fn async_body_reads_top_level_class_after_decl() { + assert_eq!( + eval( + "class E {} var r; var p = (async function(){ return E; })().then(function(v){ r = v.name; });\ + p; Promise.resolve().then(function(){ return r; })" + ), + "\"E\"" + ); +} + +// T1-sync(根因 A 对照):普通函数读其后声明的 class,应与 async 同因失败。 +#[test] +fn hoisted_sync_fn_reads_later_class() { + assert_eq!(eval("function f(){ return C; } class C {} f().name"), "\"C\""); +} + +// T2(根因 B):提升的闭包在 var 声明语句执行前被调用。规范上 var 入口实例化 +// 为 undefined,声明语句只是赋值;若语句点才初始化 cell → 运行时通用错误报。 +#[test] +fn closure_reads_var_before_declaration_statement_returns_undefined() { + assert_eq!(eval("var log; function f(){ return x; } log = f(); var x = 1; log"), "undefined"); +} + +// T3(根因 C):async-gen 参数默认值内 IIFE 读文件级 var(var 全在 f 之前, +// 理论上捕获 cell 已初始化)。期望 body 断言通过(initCount==1, iterCount==0)。 +#[test] +fn async_gen_param_default_closure_reads_file_var() { + assert_eq!( + eval( + "var initCount=0; var iterCount=0; var iter=function*(){iterCount+=1;}(); var callCount=0; var f;\ + f=async function*([[]=function(){initCount+=1; return iter;}()]){ callCount+=1; };\ + var r; var p=f([]).next().then(function(){r=[initCount,iterCount,callCount].join(',');});\ + p; Promise.resolve().then(function(){return r;})" + ), + "\"1,0,1\"" + ); +} + +// T4(根因 C 链式):async-gen 参数默认值内 IIFE 闭包读两个不同位置的文件级 +// var,验证链式 parent_uv_idx 取父 upvalue cell 的序与值。 +#[test] +fn async_gen_param_default_iife_chained_upvalue() { + assert_eq!( + eval( + "var a=1; var b=2; var f;\ + f=async function*(x=(function(){return a+b;})()){ yield x; };\ + (async function(){ var g=f(); var r=await g.next(); return r.value; })()" + ), + "3" + ); +}