fix: 绑定侧解构计算键参与闭包捕获遍历防静默错值

This commit is contained in:
2026-08-16 14:30:20 +08:00
parent 7de55b25d8
commit 84f84402ba
5 changed files with 306 additions and 10 deletions
@@ -250,3 +250,102 @@ fn computed_key_evaluated_before_default_and_getter() {
let s = unsafe { &*result.as_string_ptr() }.as_str().to_string();
assert_eq!(s, "5:key,get");
}
// 跨作用域:绑定侧计算键引用外层绑定须走闭包捕获(修复前键引用落 LOAD_GLOBAL
// 兜底——读全局错值或 ReferenceError)。
#[test]
fn computed_key_binding_captures_outer_identifier_key() {
let mut vm = Vm::new();
let result = eval(
&mut vm,
"function f(){ let k='x'; return function(){ const {[k]: a}={x:1}; return a; }; } f()()",
)
.unwrap();
assert_num(result, 1.0);
}
#[test]
fn computed_key_binding_captures_outer_const_key() {
let mut vm = Vm::new();
let result = eval(
&mut vm,
"function f(){ const k='x'; return function(){ const {[k]: a}={x:2}; return a; }; } f()()",
)
.unwrap();
assert_num(result, 2.0);
}
#[test]
fn computed_key_binding_captures_outer_call_key() {
let mut vm = Vm::new();
let result = eval(
&mut vm,
"function f(){ function k(){return 'x'} return function(){ const {[k()]: a}={x:1}; return a; }; } f()()",
)
.unwrap();
assert_num(result, 1.0);
}
#[test]
fn computed_key_binding_captures_outer_template_key() {
// 模板插值键引用外层绑定同样须捕获。
let mut vm = Vm::new();
let result = eval(
&mut vm,
"function f(){ let k='x'; return function(){ const {[`${k}`]: a}={x:3}; return a; }; } f()()",
)
.unwrap();
assert_num(result, 3.0);
}
#[test]
fn computed_key_binding_captures_outer_nested_pattern_key() {
// 嵌套解构的内层计算键引用外层绑定。
let mut vm = Vm::new();
let result = eval(
&mut vm,
"function f(){ function k(){return 'x'} return function(){ const {a: {[k()]: b}}={a:{x:4}}; return b; }; } f()()",
)
.unwrap();
assert_num(result, 4.0);
}
#[test]
fn computed_key_binding_captures_outer_in_catch_pattern() {
// catch 参数解构模式的计算键引用外层绑定。
let mut vm = Vm::new();
let result = eval(
&mut vm,
"function f(){ function k(){return 'x'} return function(){ try { throw {x:5}; } catch ({[k()]: a}) { return a; } }; } f()()",
)
.unwrap();
assert_num(result, 5.0);
}
#[test]
fn computed_key_binding_captures_outer_in_fn_default_pattern() {
// 函数形参解构默认值的计算键引用外层绑定。
let mut vm = Vm::new();
let result = eval(
&mut vm,
"function f(){ function k(){return 'x'} return function g({[k()]: a} = {x:6}) { return a; }; } f()()",
)
.unwrap();
assert_num(result, 6.0);
}
#[test]
fn computed_key_binding_same_scope_identifier_key() {
// 同作用域标识符键(无外层绑定)不回归,仍走局部符号表。
let mut vm = Vm::new();
let result = eval(&mut vm, "const key='x'; const {[key]: a}={x:9}; a").unwrap();
assert_num(result, 9.0);
}
#[test]
fn computed_key_binding_undeclared_key_throws_reference_error() {
// 未声明标识符计算键:读取抛 ReferenceError,而非静默读全局槽错值。
let mut vm = Vm::new();
let err = eval(&mut vm, "const {[undeclaredKey]: a} = {x:1};").unwrap_err();
assert!(err.contains("ReferenceError"), "expected ReferenceError, got {err:?}");
}