feat: DataView getFloat16/setFloat16

This commit is contained in:
2026-08-22 11:15:55 +08:00
parent 0ffb5d2cf3
commit e460a1aea1
3 changed files with 53 additions and 18 deletions
+25
View File
@@ -328,6 +328,17 @@ pub fn data_view_get_float32<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult
NativeResult::Ok(JsValue::float(n as f64)) NativeResult::Ok(JsValue::float(n as f64))
} }
/// `DataView.prototype.getFloat16(byteOffset, littleEndian)`:读取 2 字节半精度浮点。
pub fn data_view_get_float16<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
let bytes = native_try!(read_bytes::<2, H>(vm, args));
let bits = if is_little_endian(vm, args, 2) {
u16::from_le_bytes(bytes)
} else {
u16::from_be_bytes(bytes)
};
NativeResult::Ok(JsValue::float(crate::math::f16_bits_to_f64(bits)))
}
/// `DataView.prototype.getFloat64(byteOffset, littleEndian)`:读取 8 字节双精度浮点。 /// `DataView.prototype.getFloat64(byteOffset, littleEndian)`:读取 8 字节双精度浮点。
pub fn data_view_get_float64<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult { pub fn data_view_get_float64<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
let bytes = native_try!(read_bytes::<8, H>(vm, args)); let bytes = native_try!(read_bytes::<8, H>(vm, args));
@@ -437,6 +448,20 @@ pub fn data_view_set_float32<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult
NativeResult::Ok(JsValue::undefined()) NativeResult::Ok(JsValue::undefined())
} }
/// `DataView.prototype.setFloat16(byteOffset, value, littleEndian)`:按 IEEE 754
/// binary16 舍入写入 2 字节半精度浮点(NaN 规范化由 `f64_to_f16_bits` 处理)。
pub fn data_view_set_float16<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
let value = numeric_arg(vm, args, 2);
let bits = crate::math::f64_to_f16_bits(value);
let bytes = if is_little_endian(vm, args, 3) {
bits.to_le_bytes()
} else {
bits.to_be_bytes()
};
native_try!(write_bytes(vm, args, bytes));
NativeResult::Ok(JsValue::undefined())
}
/// `DataView.prototype.setFloat64(byteOffset, value, littleEndian)`:写入双精度浮点。 /// `DataView.prototype.setFloat64(byteOffset, value, littleEndian)`:写入双精度浮点。
pub fn data_view_set_float64<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult { pub fn data_view_set_float64<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
let value = numeric_arg(vm, args, 2); let value = numeric_arg(vm, args, 2);
+2 -2
View File
@@ -119,7 +119,7 @@ pub fn math_fround<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
/// - 尾数进位溢出到指数后若超出 f16 指数上限 15 → ±Infinity(与规范溢出点一致) /// - 尾数进位溢出到指数后若超出 f16 指数上限 15 → ±Infinity(与规范溢出点一致)
/// - 输出直接以 f16 的 u16 位模式给出,供 Math.f16round 还原为 f64 /// - 输出直接以 f16 的 u16 位模式给出,供 Math.f16round 还原为 f64
/// 或 DataView setFloat16 写缓冲复用 /// 或 DataView setFloat16 写缓冲复用
fn f64_to_f16_bits(x: f64) -> u16 { pub(crate) fn f64_to_f16_bits(x: f64) -> u16 {
let bits = x.to_bits(); let bits = x.to_bits();
let sign = ((bits >> 63) & 1) as u16; let sign = ((bits >> 63) & 1) as u16;
let exp = ((bits >> 52) & 0x7FF) as i32; let exp = ((bits >> 52) & 0x7FF) as i32;
@@ -182,7 +182,7 @@ fn f64_to_f16_bits(x: f64) -> u16 {
/// IEEE 754 binary16 → f64 精确还原(f16 有效位 ≤ 11 bit,f64 全可精确表示)。 /// IEEE 754 binary16 → f64 精确还原(f16 有效位 ≤ 11 bit,f64 全可精确表示)。
/// 供 Math.f16round 与 DataView getFloat16 复用。 /// 供 Math.f16round 与 DataView getFloat16 复用。
fn f16_bits_to_f64(h: u16) -> f64 { pub(crate) fn f16_bits_to_f64(h: u16) -> f64 {
let sign = ((h >> 15) & 1) as f64; let sign = ((h >> 15) & 1) as f64;
let exp = ((h >> 10) & 0x1F) as i32; let exp = ((h >> 10) & 0x1F) as i32;
let mant = (h & 0x3FF) as f64; let mant = (h & 0x3FF) as f64;
+26 -16
View File
@@ -32,42 +32,47 @@ pub fn bind_data_view(core: &Arc<KernelCore>, session: &KernelSession, global: &
( (
"getInt16", "getInt16",
oxide_builtins::data_view::data_view_get_int16::<crate::vm::Vm> as *const (), oxide_builtins::data_view::data_view_get_int16::<crate::vm::Vm> as *const (),
2, 1,
), ),
( (
"getUint16", "getUint16",
oxide_builtins::data_view::data_view_get_uint16::<crate::vm::Vm> as *const (), oxide_builtins::data_view::data_view_get_uint16::<crate::vm::Vm> as *const (),
2, 1,
), ),
( (
"getInt32", "getInt32",
oxide_builtins::data_view::data_view_get_int32::<crate::vm::Vm> as *const (), oxide_builtins::data_view::data_view_get_int32::<crate::vm::Vm> as *const (),
2, 1,
), ),
( (
"getUint32", "getUint32",
oxide_builtins::data_view::data_view_get_uint32::<crate::vm::Vm> as *const (), oxide_builtins::data_view::data_view_get_uint32::<crate::vm::Vm> as *const (),
2, 1,
), ),
( (
"getFloat32", "getFloat32",
oxide_builtins::data_view::data_view_get_float32::<crate::vm::Vm> as *const (), oxide_builtins::data_view::data_view_get_float32::<crate::vm::Vm> as *const (),
2, 1,
),
(
"getFloat16",
oxide_builtins::data_view::data_view_get_float16::<crate::vm::Vm> as *const (),
1,
), ),
( (
"getFloat64", "getFloat64",
oxide_builtins::data_view::data_view_get_float64::<crate::vm::Vm> as *const (), oxide_builtins::data_view::data_view_get_float64::<crate::vm::Vm> as *const (),
2, 1,
), ),
( (
"getBigInt64", "getBigInt64",
oxide_builtins::data_view::data_view_get_big_int64::<crate::vm::Vm> as *const (), oxide_builtins::data_view::data_view_get_big_int64::<crate::vm::Vm> as *const (),
2, 1,
), ),
( (
"getBigUint64", "getBigUint64",
oxide_builtins::data_view::data_view_get_big_uint64::<crate::vm::Vm> as *const (), oxide_builtins::data_view::data_view_get_big_uint64::<crate::vm::Vm> as *const (),
2, 1,
), ),
("setInt8", oxide_builtins::data_view::data_view_set_int8::<crate::vm::Vm> as *const (), 2), ("setInt8", oxide_builtins::data_view::data_view_set_int8::<crate::vm::Vm> as *const (), 2),
( (
@@ -78,42 +83,47 @@ pub fn bind_data_view(core: &Arc<KernelCore>, session: &KernelSession, global: &
( (
"setInt16", "setInt16",
oxide_builtins::data_view::data_view_set_int16::<crate::vm::Vm> as *const (), oxide_builtins::data_view::data_view_set_int16::<crate::vm::Vm> as *const (),
3, 2,
), ),
( (
"setUint16", "setUint16",
oxide_builtins::data_view::data_view_set_uint16::<crate::vm::Vm> as *const (), oxide_builtins::data_view::data_view_set_uint16::<crate::vm::Vm> as *const (),
3, 2,
), ),
( (
"setInt32", "setInt32",
oxide_builtins::data_view::data_view_set_int32::<crate::vm::Vm> as *const (), oxide_builtins::data_view::data_view_set_int32::<crate::vm::Vm> as *const (),
3, 2,
), ),
( (
"setUint32", "setUint32",
oxide_builtins::data_view::data_view_set_uint32::<crate::vm::Vm> as *const (), oxide_builtins::data_view::data_view_set_uint32::<crate::vm::Vm> as *const (),
3, 2,
), ),
( (
"setFloat32", "setFloat32",
oxide_builtins::data_view::data_view_set_float32::<crate::vm::Vm> as *const (), oxide_builtins::data_view::data_view_set_float32::<crate::vm::Vm> as *const (),
3, 2,
),
(
"setFloat16",
oxide_builtins::data_view::data_view_set_float16::<crate::vm::Vm> as *const (),
2,
), ),
( (
"setFloat64", "setFloat64",
oxide_builtins::data_view::data_view_set_float64::<crate::vm::Vm> as *const (), oxide_builtins::data_view::data_view_set_float64::<crate::vm::Vm> as *const (),
3, 2,
), ),
( (
"setBigInt64", "setBigInt64",
oxide_builtins::data_view::data_view_set_big_int64::<crate::vm::Vm> as *const (), oxide_builtins::data_view::data_view_set_big_int64::<crate::vm::Vm> as *const (),
3, 2,
), ),
( (
"setBigUint64", "setBigUint64",
oxide_builtins::data_view::data_view_set_big_uint64::<crate::vm::Vm> as *const (), oxide_builtins::data_view::data_view_set_big_uint64::<crate::vm::Vm> as *const (),
3, 2,
), ),
( (
"toString", "toString",