From fc189ebd85200f599db792118a2ba39497d505f6 Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Tue, 22 Sep 2026 12:20:32 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=B1=BB=E5=9E=8B=E5=8C=96=E6=95=B0?= =?UTF-8?q?=E7=BB=84=E7=B4=A2=E5=BC=95=E5=8A=A9=E6=89=8B=E6=81=A2=E5=A4=8D?= =?UTF-8?q?=20BigInt=20=E5=AE=9E=E5=8F=82=E6=8A=9B=20TypeError=20=E8=AF=AD?= =?UTF-8?q?=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_builtins/src/typed_array.rs | 41 ++++++------------- .../tests/builtins_typed_array_tests.rs | 7 +++- 2 files changed, 17 insertions(+), 31 deletions(-) diff --git a/crates/oxide_builtins/src/typed_array.rs b/crates/oxide_builtins/src/typed_array.rs index e5f330e4..eb1d3655 100644 --- a/crates/oxide_builtins/src/typed_array.rs +++ b/crates/oxide_builtins/src/typed_array.rs @@ -35,15 +35,6 @@ fn range_error(vm: &mut H, msg: &str) -> JsValue { } fn to_index(vm: &mut H, value: JsValue, msg: &str) -> Result { - // ToIndex 的 BigInt 面:整数原语截断即自身,负值或超 2^53-1 抛 - // RangeError(与数值臂同消息),无 NaN 概念。 - if value.is_bigint() { - let b = vm.bigint_value(value); - if *b < BigInt::from(0) || *b > BigInt::from(9_007_199_254_740_991u64) { - return Err(range_error(vm, msg)); - } - return Ok(b.to_usize().unwrap_or(0)); - } let n = match vm.coerce_number_bounded(value) { Ok(n) => n, Err(e) => return Err(crate::iterator::engine_error(vm, &e)), @@ -60,27 +51,19 @@ fn to_index(vm: &mut H, value: JsValue, msg: &str) -> Result(vm: &mut H, value: JsValue, len: usize) -> Result { - // BigInt 面:ToIntegerOrInfinity 对整数原语即截断自身(无 NaN/±Infinity 臂), - // 超 isize 域饱和到对应端点后走同一负/正夹取尾段。 - let int: isize = if value.is_bigint() { - let b = vm.bigint_value(value); - b.to_isize() - .unwrap_or(if *b < BigInt::from(0) { isize::MIN } else { isize::MAX }) - } else { - let n = match vm.coerce_number_bounded(value) { - Ok(n) => n, - Err(e) => return Err(crate::iterator::engine_error(vm, &e)), - }; - if n.is_nan() { - return Ok(0); - } - // ToIntegerOrInfinity:±Infinity 不截断,负无穷归 0、正无穷归 len, - // 避免饱和成 isize::MIN 后取负溢出。 - if n.is_infinite() { - return Ok(if n < 0.0 { 0 } else { len }); - } - n.trunc() as isize + let n = match vm.coerce_number_bounded(value) { + Ok(n) => n, + Err(e) => return Err(crate::iterator::engine_error(vm, &e)), }; + if n.is_nan() { + return Ok(0); + } + // ToIntegerOrInfinity:±Infinity 不截断,负无穷归 0、正无穷归 len, + // 避免饱和成 isize::MIN 后取负溢出。 + if n.is_infinite() { + return Ok(if n < 0.0 { 0 } else { len }); + } + let int = n.trunc() as isize; if int < 0 { Ok(len.saturating_sub(int.unsigned_abs())) } else { diff --git a/crates/oxide_vm/tests/builtins_typed_array_tests.rs b/crates/oxide_vm/tests/builtins_typed_array_tests.rs index ea242872..f5714d67 100644 --- a/crates/oxide_vm/tests/builtins_typed_array_tests.rs +++ b/crates/oxide_vm/tests/builtins_typed_array_tests.rs @@ -278,10 +278,13 @@ fn typed_array_numeric_write_bigint_throws() { #[test] fn typed_array_constructor_bigint_length() { let mut vm = Vm::new(); - // G6:第一参数 BigInt 按 ToIndex 语义建数组。 + // 长度参数走 ToIndex:BigInt 实参在 ToNumber 步抛 TypeError,不截断建数组; + // 布尔/null 等原语按数值转换语义建数组。 let result = eval( &mut vm, - "new BigInt64Array(5n).length === 5 && new Int8Array(true).length === 1 && new Int8Array(null).length === 0", + "(function () { var t = false; \ + try { new BigInt64Array(5n); } catch (e) { t = e instanceof TypeError; } \ + return t && new Int8Array(true).length === 1 && new Int8Array(null).length === 0; })()", ) .unwrap(); assert!(result.as_bool());