mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-23 18:21:13 +08:00
fix: BigInt64Array/BigUint64Array 与 DataView BigInt 存取走真 BigInt 语义
TA 元素读写按 kind 分流:BigInt 类型走 ToBigInt(Number 入参抛 TypeError、 写入 mod 2^64 截断、读出为真 BigInt 值),数值类型走 ToNumber 且显式拒绝 BigInt 值;消除 64 位整数经 f64 中转的静默精度丢失。 - runtime_api 新增公共 to_bigint_full / string_to_bigint_full,bigint 构造器 与 asIntN/asUintN 改调公共版消除双实现 - sort/toSorted 默认序对 BigInt 类型按 i64/u64 值比较;reverse/copyWithin/ filter/toReversed/with 消除无谓数值中转 - 构造器第一参数非对象统一走 ToIndex(bool/null/BigInt/字符串),Symbol 抛 TypeError - DataView get/setBigInt64/getBigUint64 返回 BigInt 值、入参按 ToBigInt 校验 - 测试:精度往返 / TypeError / mod 2^64 / 字节序 / 排序 / 回调值类型断言
This commit is contained in:
@@ -890,6 +890,77 @@ pub fn to_string_full<H: VmHost>(val: JsValue, host: &mut H) -> Result<String, S
|
||||
Ok(to_string(primitive))
|
||||
}
|
||||
|
||||
/// 带完整对象强制转换的 ToBigInt(input)(§7.1.14):BigInt 原样;Boolean → 0/1;
|
||||
/// String 走 StringToBigInt;Number/Symbol/undefined/null → TypeError;对象经
|
||||
/// ToPrimitive(default hint)后递归处理。
|
||||
pub fn to_bigint_full<H: VmHost>(val: JsValue, host: &mut H) -> Result<JsValue, String> {
|
||||
let primitive = to_primitive(val, ToPrimitiveHint::Default, host)?;
|
||||
if primitive.is_bigint() {
|
||||
return Ok(primitive);
|
||||
}
|
||||
if primitive.is_bool() {
|
||||
let v = if primitive.as_bool() { 1 } else { 0 };
|
||||
return Ok(host.new_bigint(num_bigint::BigInt::from(v)));
|
||||
}
|
||||
if primitive.is_int() || primitive.is_double() {
|
||||
return Err(host.error_message_text("TypeError", "Cannot convert a Number value to a BigInt"));
|
||||
}
|
||||
if primitive.is_string() {
|
||||
return string_to_bigint_full(host, &to_string(primitive));
|
||||
}
|
||||
// undefined / null / symbol。
|
||||
Err(host.error_message_text("TypeError", "Cannot convert value to a BigInt"))
|
||||
}
|
||||
|
||||
/// StringToBigInt(§7.1.14 步骤):去首尾空白,可选 +/- 号与 0x/0o/0b 前缀;
|
||||
/// 空串 → 0n;非法 → SyntaxError。
|
||||
fn string_to_bigint_full<H: VmHost>(host: &mut H, s: &str) -> Result<JsValue, String> {
|
||||
let trimmed = s.trim();
|
||||
if trimmed.is_empty() {
|
||||
return Ok(host.new_bigint(num_bigint::BigInt::from(0)));
|
||||
}
|
||||
let (neg, rest) = if let Some(r) = trimmed.strip_prefix('-') {
|
||||
(true, r)
|
||||
} else if let Some(r) = trimmed.strip_prefix('+') {
|
||||
(false, r)
|
||||
} else {
|
||||
(false, trimmed)
|
||||
};
|
||||
// StringIntegerLiteral:符号只允许出现在纯十进制前;0x/0o/0b 前缀前带
|
||||
// +/-(如 "-0x1")属于非法语法。
|
||||
let (radix, digits) = if let Some(hex) = rest.strip_prefix("0x").or_else(|| rest.strip_prefix("0X")) {
|
||||
if neg {
|
||||
return Err(
|
||||
host.error_message_text("SyntaxError", "Cannot convert string to BigInt: invalid integer literal")
|
||||
);
|
||||
}
|
||||
(16u32, hex)
|
||||
} else if let Some(oct) = rest.strip_prefix("0o").or_else(|| rest.strip_prefix("0O")) {
|
||||
if neg {
|
||||
return Err(
|
||||
host.error_message_text("SyntaxError", "Cannot convert string to BigInt: invalid integer literal")
|
||||
);
|
||||
}
|
||||
(8u32, oct)
|
||||
} else if let Some(bin) = rest.strip_prefix("0b").or_else(|| rest.strip_prefix("0B")) {
|
||||
if neg {
|
||||
return Err(
|
||||
host.error_message_text("SyntaxError", "Cannot convert string to BigInt: invalid integer literal")
|
||||
);
|
||||
}
|
||||
(2u32, bin)
|
||||
} else {
|
||||
(10u32, rest)
|
||||
};
|
||||
if digits.is_empty() {
|
||||
return Err(host.error_message_text("SyntaxError", "Cannot convert string to BigInt: invalid integer literal"));
|
||||
}
|
||||
let m = num_bigint::BigInt::parse_bytes(digits.as_bytes(), radix).ok_or_else(|| {
|
||||
host.error_message_text("SyntaxError", "Cannot convert string to BigInt: invalid integer literal")
|
||||
})?;
|
||||
Ok(host.new_bigint(if neg { -m } else { m }))
|
||||
}
|
||||
|
||||
/// `String()` 构造器的字符串转换(§21.1.1.1):Symbol 值(及本引擎以空对象表示的
|
||||
/// well-known symbol)返回描述串 `Symbol(desc)`;其余走完整 ToString。
|
||||
pub fn to_string_for_string_constructor<H: VmHost>(val: JsValue, host: &mut H) -> Result<String, String> {
|
||||
|
||||
Reference in New Issue
Block a user