mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-25 03:01:12 +08:00
feat: 绑定 Atomics 全局对象方法并接入 test262
This commit is contained in:
@@ -65,10 +65,10 @@ fn is_bigint_kind(kind: TypedArrayKind) -> bool {
|
||||
/// # 步骤
|
||||
/// 1. `get_typed_array_data` 品牌校验(非 TA 对象抛 TypeError)。
|
||||
/// 2. 整数宽度守卫(浮点/clamped 视图抛 TypeError)。
|
||||
/// 3. 索引经 ToIntegerOrInfinity(valueOf/toString 抛错原值上抛,先于越界判)。
|
||||
/// 4. 相对字节偏移 = view.byte_offset + index·bpe(f64 运算);越界
|
||||
/// 3. 写族加查写守卫(immutable/detach 抛 TypeError),先于索引/值 coercion。
|
||||
/// 4. 索引经 ToIntegerOrInfinity(valueOf/toString 抛错原值上抛,先于越界判)。
|
||||
/// 5. 相对字节偏移 = view.byte_offset + index·bpe(f64 运算);越界
|
||||
/// (`< 0` 或 `>= buffer 字节长`)抛 RangeError,detach 视同越界。
|
||||
/// 5. 写族加查写守卫(immutable/detach 抛 TypeError)。
|
||||
///
|
||||
/// # 边界与前提
|
||||
/// - 返回的载荷指针、视图与偏移在 session 独占期内有效,调用方同一语句内消费。
|
||||
@@ -83,6 +83,11 @@ fn resolve_atomic_access<H: VmHost>(
|
||||
if !is_integer_kind(view.kind) {
|
||||
return Err(type_error(vm, "Atomics operations require an integer TypedArray type"));
|
||||
}
|
||||
// 写守卫(不可变缓冲 TypeError)先于索引/值 coercion 求值:守卫抛错时
|
||||
// index/value 的 valueOf 不得被调用(语料 calls 序列口径)。
|
||||
if writable {
|
||||
ta_validate(vm, view, true)?;
|
||||
}
|
||||
let index = ta_to_integer_or_infinity(vm, index_val)?;
|
||||
|
||||
// 缓冲字节长:AB/SAB 双认(buffer_payload_ptr),载荷缺失视同越界。
|
||||
@@ -102,9 +107,6 @@ fn resolve_atomic_access<H: VmHost>(
|
||||
if offset < 0.0 || offset >= buffer_len as f64 {
|
||||
return Err(range_error(vm, "invalid indexed access to Atomics"));
|
||||
}
|
||||
if writable {
|
||||
ta_validate(vm, view, true)?;
|
||||
}
|
||||
Ok((payload_ptr, view, offset as usize))
|
||||
}
|
||||
|
||||
@@ -161,18 +163,18 @@ fn arithmetic_write_value<H: VmHost>(
|
||||
|
||||
/// `Atomics.load(typedArray, index)`:读指定索引元素。
|
||||
pub fn atomics_load<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
let this_val = arg_at(vm, args, 0);
|
||||
let index_val = arg_at(vm, args, 1);
|
||||
let (payload_ptr, view, offset) = native_try!(resolve_atomic_access(vm, this_val, false, index_val));
|
||||
let ta_val = arg_at(vm, args, 1);
|
||||
let index_val = arg_at(vm, args, 2);
|
||||
let (payload_ptr, view, offset) = native_try!(resolve_atomic_access(vm, ta_val, false, index_val));
|
||||
NativeResult::Ok(atomic_read(vm, payload_ptr, view.kind, offset).unwrap_or(JsValue::undefined()))
|
||||
}
|
||||
|
||||
/// `Atomics.store(typedArray, index, value)`:写值后读回返回(宽度归一,-0 → +0)。
|
||||
pub fn atomics_store<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
let this_val = arg_at(vm, args, 0);
|
||||
let index_val = arg_at(vm, args, 1);
|
||||
let value_val = arg_at(vm, args, 2);
|
||||
let (payload_ptr, view, offset) = native_try!(resolve_atomic_access(vm, this_val, true, index_val));
|
||||
let ta_val = arg_at(vm, args, 1);
|
||||
let index_val = arg_at(vm, args, 2);
|
||||
let value_val = arg_at(vm, args, 3);
|
||||
let (payload_ptr, view, offset) = native_try!(resolve_atomic_access(vm, ta_val, true, index_val));
|
||||
let value = native_try!(ta_element_value(vm, view.kind, value_val));
|
||||
atomic_write(vm, payload_ptr, view.kind, offset, value);
|
||||
NativeResult::Ok(atomic_read(vm, payload_ptr, view.kind, offset).unwrap_or(value))
|
||||
@@ -180,10 +182,10 @@ pub fn atomics_store<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
|
||||
/// `Atomics.exchange(typedArray, index, value)`:读旧值、写新值、返回旧值。
|
||||
pub fn atomics_exchange<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
let this_val = arg_at(vm, args, 0);
|
||||
let index_val = arg_at(vm, args, 1);
|
||||
let value_val = arg_at(vm, args, 2);
|
||||
let (payload_ptr, view, offset) = native_try!(resolve_atomic_access(vm, this_val, true, index_val));
|
||||
let ta_val = arg_at(vm, args, 1);
|
||||
let index_val = arg_at(vm, args, 2);
|
||||
let value_val = arg_at(vm, args, 3);
|
||||
let (payload_ptr, view, offset) = native_try!(resolve_atomic_access(vm, ta_val, true, index_val));
|
||||
let old = atomic_read(vm, payload_ptr, view.kind, offset).unwrap_or(JsValue::undefined());
|
||||
let value = native_try!(ta_element_value(vm, view.kind, value_val));
|
||||
atomic_write(vm, payload_ptr, view.kind, offset, value);
|
||||
@@ -217,10 +219,10 @@ pub fn atomics_xor<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
|
||||
/// add/sub/and/or/xor 共享核:读旧值 → 运算值转换 → 读-改-写 → 返回旧值。
|
||||
fn atomic_arithmetic<H: VmHost>(vm: &mut H, args: &[u8], op: &str) -> NativeResult {
|
||||
let this_val = arg_at(vm, args, 0);
|
||||
let index_val = arg_at(vm, args, 1);
|
||||
let value_val = arg_at(vm, args, 2);
|
||||
let (payload_ptr, view, offset) = native_try!(resolve_atomic_access(vm, this_val, true, index_val));
|
||||
let ta_val = arg_at(vm, args, 1);
|
||||
let index_val = arg_at(vm, args, 2);
|
||||
let value_val = arg_at(vm, args, 3);
|
||||
let (payload_ptr, view, offset) = native_try!(resolve_atomic_access(vm, ta_val, true, index_val));
|
||||
let old = atomic_read(vm, payload_ptr, view.kind, offset).unwrap_or(JsValue::undefined());
|
||||
let value = native_try!(ta_element_value(vm, view.kind, value_val));
|
||||
let result = arithmetic_write_value(vm, view.kind, op, old, value);
|
||||
@@ -231,11 +233,11 @@ fn atomic_arithmetic<H: VmHost>(vm: &mut H, args: &[u8], op: &str) -> NativeResu
|
||||
/// `Atomics.compareExchange(typedArray, index, expected, replacement)`:读旧值;
|
||||
/// 相等(数值宽度 `==`、BigInt 宽度 BigInt 相等)则写 replacement;返回旧值。
|
||||
pub fn atomics_compare_exchange<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
|
||||
let this_val = arg_at(vm, args, 0);
|
||||
let index_val = arg_at(vm, args, 1);
|
||||
let expected_val = arg_at(vm, args, 2);
|
||||
let replacement_val = arg_at(vm, args, 3);
|
||||
let (payload_ptr, view, offset) = native_try!(resolve_atomic_access(vm, this_val, true, index_val));
|
||||
let ta_val = arg_at(vm, args, 1);
|
||||
let index_val = arg_at(vm, args, 2);
|
||||
let expected_val = arg_at(vm, args, 3);
|
||||
let replacement_val = arg_at(vm, args, 4);
|
||||
let (payload_ptr, view, offset) = native_try!(resolve_atomic_access(vm, ta_val, true, index_val));
|
||||
let old = atomic_read(vm, payload_ptr, view.kind, offset).unwrap_or(JsValue::undefined());
|
||||
let expected = native_try!(ta_element_value(vm, view.kind, expected_val));
|
||||
let matched = if is_bigint_kind(view.kind) {
|
||||
|
||||
@@ -25,7 +25,3 @@ pub fn weakref_stub<H: VmHost>(vm: &mut H, _args: &[u8]) -> NativeResult {
|
||||
pub fn finalization_registry_stub<H: VmHost>(vm: &mut H, _args: &[u8]) -> NativeResult {
|
||||
stub_error(vm, "FinalizationRegistry")
|
||||
}
|
||||
/// `Atomics` 全局占位:始终抛 TypeError。按设计延后实现。
|
||||
pub fn atomics_stub<H: VmHost>(vm: &mut H, _args: &[u8]) -> NativeResult {
|
||||
stub_error(vm, "Atomics")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user