diff --git a/crates/oxide_builtins/src/data_view.rs b/crates/oxide_builtins/src/data_view.rs index 9f629d93..74913c8d 100644 --- a/crates/oxide_builtins/src/data_view.rs +++ b/crates/oxide_builtins/src/data_view.rs @@ -328,6 +328,17 @@ pub fn data_view_get_float32(vm: &mut H, args: &[u8]) -> NativeResult NativeResult::Ok(JsValue::float(n as f64)) } +/// `DataView.prototype.getFloat16(byteOffset, littleEndian)`:读取 2 字节半精度浮点。 +pub fn data_view_get_float16(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 字节双精度浮点。 pub fn data_view_get_float64(vm: &mut H, args: &[u8]) -> NativeResult { let bytes = native_try!(read_bytes::<8, H>(vm, args)); @@ -437,6 +448,20 @@ pub fn data_view_set_float32(vm: &mut H, args: &[u8]) -> NativeResult 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(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)`:写入双精度浮点。 pub fn data_view_set_float64(vm: &mut H, args: &[u8]) -> NativeResult { let value = numeric_arg(vm, args, 2); diff --git a/crates/oxide_builtins/src/math.rs b/crates/oxide_builtins/src/math.rs index 21d7db0a..28128050 100644 --- a/crates/oxide_builtins/src/math.rs +++ b/crates/oxide_builtins/src/math.rs @@ -119,7 +119,7 @@ pub fn math_fround(vm: &mut H, args: &[u8]) -> NativeResult { /// - 尾数进位溢出到指数后若超出 f16 指数上限 15 → ±Infinity(与规范溢出点一致) /// - 输出直接以 f16 的 u16 位模式给出,供 Math.f16round 还原为 f64 /// 或 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 sign = ((bits >> 63) & 1) as u16; 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 全可精确表示)。 /// 供 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 exp = ((h >> 10) & 0x1F) as i32; let mant = (h & 0x3FF) as f64; diff --git a/crates/oxide_vm/src/bindings/bind_data_view.rs b/crates/oxide_vm/src/bindings/bind_data_view.rs index 621a7f39..72ddc7c4 100644 --- a/crates/oxide_vm/src/bindings/bind_data_view.rs +++ b/crates/oxide_vm/src/bindings/bind_data_view.rs @@ -32,42 +32,47 @@ pub fn bind_data_view(core: &Arc, session: &KernelSession, global: & ( "getInt16", oxide_builtins::data_view::data_view_get_int16:: as *const (), - 2, + 1, ), ( "getUint16", oxide_builtins::data_view::data_view_get_uint16:: as *const (), - 2, + 1, ), ( "getInt32", oxide_builtins::data_view::data_view_get_int32:: as *const (), - 2, + 1, ), ( "getUint32", oxide_builtins::data_view::data_view_get_uint32:: as *const (), - 2, + 1, ), ( "getFloat32", oxide_builtins::data_view::data_view_get_float32:: as *const (), - 2, + 1, + ), + ( + "getFloat16", + oxide_builtins::data_view::data_view_get_float16:: as *const (), + 1, ), ( "getFloat64", oxide_builtins::data_view::data_view_get_float64:: as *const (), - 2, + 1, ), ( "getBigInt64", oxide_builtins::data_view::data_view_get_big_int64:: as *const (), - 2, + 1, ), ( "getBigUint64", oxide_builtins::data_view::data_view_get_big_uint64:: as *const (), - 2, + 1, ), ("setInt8", oxide_builtins::data_view::data_view_set_int8:: as *const (), 2), ( @@ -78,42 +83,47 @@ pub fn bind_data_view(core: &Arc, session: &KernelSession, global: & ( "setInt16", oxide_builtins::data_view::data_view_set_int16:: as *const (), - 3, + 2, ), ( "setUint16", oxide_builtins::data_view::data_view_set_uint16:: as *const (), - 3, + 2, ), ( "setInt32", oxide_builtins::data_view::data_view_set_int32:: as *const (), - 3, + 2, ), ( "setUint32", oxide_builtins::data_view::data_view_set_uint32:: as *const (), - 3, + 2, ), ( "setFloat32", oxide_builtins::data_view::data_view_set_float32:: as *const (), - 3, + 2, + ), + ( + "setFloat16", + oxide_builtins::data_view::data_view_set_float16:: as *const (), + 2, ), ( "setFloat64", oxide_builtins::data_view::data_view_set_float64:: as *const (), - 3, + 2, ), ( "setBigInt64", oxide_builtins::data_view::data_view_set_big_int64:: as *const (), - 3, + 2, ), ( "setBigUint64", oxide_builtins::data_view::data_view_set_big_uint64:: as *const (), - 3, + 2, ), ( "toString",