fix: 解构赋值 rest 目标按 emitter 递归计数,修嵌套 rest 死循环
This commit is contained in:
@@ -237,20 +237,40 @@ fn date_local_setters_preserve_utc_offset() {
|
||||
#[test]
|
||||
fn date_set_utc_full_year_works() {
|
||||
let mut vm = Vm::new();
|
||||
let r = eval(&mut vm, "var d = new Date(2020, 0, 1, 0, 0, 0); d.setUTCFullYear(2025); d.getUTCFullYear()").unwrap();
|
||||
let r = eval(
|
||||
&mut vm,
|
||||
"var d = new Date(2020, 0, 1, 0, 0, 0); d.setUTCFullYear(2025); d.getUTCFullYear()",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(r.as_double(), 2025.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn date_set_utc_hours_optional_chain() {
|
||||
let mut vm = Vm::new();
|
||||
let r = eval(&mut vm, "var d = new Date(2020, 0, 1, 0, 0, 0); d.setUTCHours(23, 59, 59, 999); d.getUTCHours()").unwrap();
|
||||
let r = eval(
|
||||
&mut vm,
|
||||
"var d = new Date(2020, 0, 1, 0, 0, 0); d.setUTCHours(23, 59, 59, 999); d.getUTCHours()",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(r.as_double(), 23.0);
|
||||
let r = eval(&mut vm, "var d = new Date(2020, 0, 1, 0, 0, 0); d.setUTCHours(23, 59, 59, 999); d.getUTCMinutes()").unwrap();
|
||||
let r = eval(
|
||||
&mut vm,
|
||||
"var d = new Date(2020, 0, 1, 0, 0, 0); d.setUTCHours(23, 59, 59, 999); d.getUTCMinutes()",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(r.as_double(), 59.0);
|
||||
let r = eval(&mut vm, "var d = new Date(2020, 0, 1, 0, 0, 0); d.setUTCHours(23, 59, 59, 999); d.getUTCSeconds()").unwrap();
|
||||
let r = eval(
|
||||
&mut vm,
|
||||
"var d = new Date(2020, 0, 1, 0, 0, 0); d.setUTCHours(23, 59, 59, 999); d.getUTCSeconds()",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(r.as_double(), 59.0);
|
||||
let r = eval(&mut vm, "var d = new Date(2020, 0, 1, 0, 0, 0); d.setUTCHours(23, 59, 59, 999); d.getUTCMilliseconds()").unwrap();
|
||||
let r = eval(
|
||||
&mut vm,
|
||||
"var d = new Date(2020, 0, 1, 0, 0, 0); d.setUTCHours(23, 59, 59, 999); d.getUTCMilliseconds()",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(r.as_double(), 999.0);
|
||||
}
|
||||
|
||||
|
||||
@@ -87,3 +87,36 @@ fn function_and_method_parameter_destructuring() {
|
||||
.unwrap();
|
||||
assert_num(result, 10.0);
|
||||
}
|
||||
|
||||
// Regression: a for-of whose assignment target has a NESTED rest pattern (the rest
|
||||
// element is itself a pattern, e.g. `[...[x]]`) used to loop forever / error, because the
|
||||
// counter undercounted the rest target's instructions vs the emitter, corrupting the loop's
|
||||
// jump offsets. (Object rest with a nested target is a syntax error per spec, so untested.)
|
||||
#[test]
|
||||
fn for_of_assignment_nested_rest_target_runs_once() {
|
||||
let mut vm = Vm::new();
|
||||
let result = eval(&mut vm, "var x; var c=0; for([...[x]] of [[1,2,3]]){ c=c+1; } c").unwrap();
|
||||
assert_num(result, 1.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn for_of_assignment_nested_rest_empty_body_binds_inner() {
|
||||
let mut vm = Vm::new();
|
||||
let result = eval(&mut vm, "var x; for([...[x]] of [[1,2,3]]){} x").unwrap();
|
||||
assert_num(result, 1.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn for_of_assignment_nested_rest_with_leading_element() {
|
||||
let mut vm = Vm::new();
|
||||
// outer iterates once; a=1, rest=[2,3,4], then [x,y] from rest -> x=2, y=3
|
||||
let result = eval(&mut vm, "var a,x,y; for([a,...[x,y]] of [[1,2,3,4]]){} a*100+x*10+y").unwrap();
|
||||
assert_num(result, 123.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn standalone_nested_rest_assignment() {
|
||||
let mut vm = Vm::new();
|
||||
let result = eval(&mut vm, "var x; [...[x]]=[1,2,3]; x").unwrap();
|
||||
assert_num(result, 1.0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user