mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-25 03:01:12 +08:00
feat: 缓冲区载荷双认入口 DataView/TA SAB 读写面与 SAB 门控解除
This commit is contained in:
@@ -296,3 +296,158 @@ fn dv_ctor_fixed_default_len_static() {
|
||||
.unwrap();
|
||||
assert!(result.as_bool());
|
||||
}
|
||||
|
||||
/// DV-over-SAB 构造基础形:缺省长视图,buffer 指向 SAB 本体。
|
||||
#[test]
|
||||
fn dv_sab_ctor_basic() {
|
||||
let mut vm = Vm::new();
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"var sab = new SharedArrayBuffer(8); \
|
||||
var dv = new DataView(sab); \
|
||||
dv.byteLength === 8 && dv.byteOffset === 0 && dv.buffer === sab \
|
||||
&& Object.getPrototypeOf(dv) === DataView.prototype",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(result.as_bool());
|
||||
}
|
||||
|
||||
/// DV-over-SAB 显式 offset/length 形:视图界与 buffer 指向。
|
||||
#[test]
|
||||
fn dv_sab_ctor_offset_length() {
|
||||
let mut vm = Vm::new();
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"var sab = new SharedArrayBuffer(8); \
|
||||
var dv = new DataView(sab, 2, 4); \
|
||||
dv.byteLength === 4 && dv.byteOffset === 2 && dv.buffer === sab",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(result.as_bool());
|
||||
}
|
||||
|
||||
/// DV-over-SAB 构造越界三形:offset > live / 显式长越界 / 负 offset 均 RangeError。
|
||||
#[test]
|
||||
fn dv_sab_ctor_oob() {
|
||||
let mut vm = Vm::new();
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"(function () { \
|
||||
var sab = new SharedArrayBuffer(4); \
|
||||
function kind(expr) { try { expr(); return 'none'; } catch (e) { return e.name; } } \
|
||||
return kind(function () { new DataView(sab, 5); }) === 'RangeError' \
|
||||
&& kind(function () { new DataView(sab, 0, 5); }) === 'RangeError' \
|
||||
&& kind(function () { new DataView(sab, -1); }) === 'RangeError'; })()",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(result.as_bool());
|
||||
}
|
||||
|
||||
/// DV-over-SAB 读写核回卷:各宽 get/set 位模式与同形 AB 视图对照同值。
|
||||
#[test]
|
||||
fn dv_sab_get_set_roundtrip() {
|
||||
let mut vm = Vm::new();
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"(function () { \
|
||||
var sab = new SharedArrayBuffer(32); \
|
||||
var dv = new DataView(sab); \
|
||||
dv.setInt8(0, -7); \
|
||||
dv.setUint8(1, 200); \
|
||||
dv.setInt32(2, 0x01020304, true); \
|
||||
dv.setInt32(6, 0x01020304, false); \
|
||||
dv.setFloat64(8, 1.5); \
|
||||
dv.setBigInt64(16, 42n); \
|
||||
dv.setBigUint64(24, 18446744073709551615n); \
|
||||
var ab = new ArrayBuffer(32); \
|
||||
var ref = new DataView(ab); \
|
||||
ref.setInt8(0, -7); \
|
||||
ref.setUint8(1, 200); \
|
||||
ref.setInt32(2, 0x01020304, true); \
|
||||
ref.setInt32(6, 0x01020304, false); \
|
||||
ref.setFloat64(8, 1.5); \
|
||||
ref.setBigInt64(16, 42n); \
|
||||
ref.setBigUint64(24, 18446744073709551615n); \
|
||||
return dv.getInt8(0) === ref.getInt8(0) \
|
||||
&& dv.getUint8(1) === ref.getUint8(1) \
|
||||
&& dv.getInt32(2, true) === ref.getInt32(2, true) \
|
||||
&& dv.getInt32(6, false) === ref.getInt32(6, false) \
|
||||
&& dv.getFloat64(8, true) === ref.getFloat64(8, true) \
|
||||
&& dv.getBigInt64(16, true) === ref.getBigInt64(16, true) \
|
||||
&& dv.getBigUint64(24, false) === ref.getBigUint64(24, false); })()",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(result.as_bool());
|
||||
}
|
||||
|
||||
/// DV-over-SAB 读越界:跨视图尾 getInt32 → RangeError。
|
||||
#[test]
|
||||
fn dv_sab_get_oob() {
|
||||
let mut vm = Vm::new();
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"(function () { \
|
||||
var dv = new DataView(new SharedArrayBuffer(4)); \
|
||||
try { dv.getInt32(1); return false; } catch (e) { return e instanceof RangeError; } })()",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(result.as_bool());
|
||||
}
|
||||
|
||||
/// DV-over-SAB live 读:定长视图静态界 + growable SAB auto 视图随 grow 活读。
|
||||
#[test]
|
||||
fn dv_sab_live_getters() {
|
||||
let mut vm = Vm::new();
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"(function () { \
|
||||
var sab = new SharedArrayBuffer(8); \
|
||||
var fixed = new DataView(sab, 1, 3); \
|
||||
var ok = fixed.byteOffset === 1 && fixed.byteLength === 3; \
|
||||
var growable = new SharedArrayBuffer(4, { maxByteLength: 8 }); \
|
||||
var auto = new DataView(growable); \
|
||||
ok = ok && auto.byteLength === 4 && auto.byteOffset === 0; \
|
||||
growable.grow(8); \
|
||||
return ok && auto.byteLength === 8 && auto.byteOffset === 0; })()",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(result.as_bool());
|
||||
}
|
||||
|
||||
/// DV-over-SAB 原型链:buffer 属性返回 SAB 本体 + custom-proto 臂
|
||||
/// (newTarget 自定义原型经 GpFC 落位)。
|
||||
#[test]
|
||||
fn dv_sab_proto_chain() {
|
||||
let mut vm = Vm::new();
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"(function () { \
|
||||
var sab = new SharedArrayBuffer(4); \
|
||||
var dv = new DataView(sab); \
|
||||
var ok = dv.buffer === sab; \
|
||||
var newTarget = function() {}.bind(null); \
|
||||
newTarget.prototype = {}; \
|
||||
var dv2 = Reflect.construct(DataView, [sab], newTarget); \
|
||||
return ok && Object.getPrototypeOf(dv2) === newTarget.prototype; })()",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(result.as_bool());
|
||||
}
|
||||
|
||||
/// DV-over-SAB 品牌负钉:非缓冲区对象(裸对象 / TypedArray / null)构造
|
||||
/// 首检均 TypeError。
|
||||
#[test]
|
||||
fn dv_sab_brand_reject() {
|
||||
let mut vm = Vm::new();
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"(function () { \
|
||||
function kind(expr) { try { expr(); return 'none'; } catch (e) { return e.name; } } \
|
||||
var ta = new Int8Array(4); \
|
||||
return kind(function () { new DataView({}); }) === 'TypeError' \
|
||||
&& kind(function () { new DataView(ta); }) === 'TypeError' \
|
||||
&& kind(function () { new DataView(null); }) === 'TypeError'; })()",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(result.as_bool());
|
||||
}
|
||||
|
||||
@@ -2131,3 +2131,146 @@ fn ta_for_in_stable_after_delete_str_prop() {
|
||||
.unwrap();
|
||||
assert!(result.as_bool());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ta_sab_fill() {
|
||||
// TA-over-SAB fill 全量回填并读回,构造/写/读同走双认载荷入口。
|
||||
let mut vm = Vm::new();
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"(function () { var ta = new Int32Array(new SharedArrayBuffer(16)); \
|
||||
var ok = ta.length === 4 && ta.buffer instanceof SharedArrayBuffer; \
|
||||
ta.fill(7); \
|
||||
return ok && ta[0] === 7 && ta[1] === 7 && ta[2] === 7 && ta[3] === 7; })()",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(result.as_bool());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ta_sab_set_ta_source() {
|
||||
// TA-over-SAB set(TypedArray) 三形:跨 buffer 拷贝、同 buffer 快照
|
||||
// 写前取值、BigInt 宽度源。
|
||||
let mut vm = Vm::new();
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"(function () { \
|
||||
var src = new Int32Array(new SharedArrayBuffer(16)); src.fill(5); \
|
||||
var dst = new Int32Array(new SharedArrayBuffer(32)); \
|
||||
dst.set(src, 2); \
|
||||
var ok = dst[0] === 0 && dst[2] === 5 && dst[5] === 5 && dst[6] === 0; \
|
||||
var t2 = new Int32Array(new SharedArrayBuffer(16)); t2.fill(1); t2[0] = 9; \
|
||||
t2.set(t2.subarray(1, 3), 0); \
|
||||
ok = ok && t2[0] === 1 && t2[1] === 1; \
|
||||
var bs = new BigInt64Array(new SharedArrayBuffer(16)); bs.fill(9n); \
|
||||
var bd = new BigInt64Array(new SharedArrayBuffer(32)); \
|
||||
bd.set(bs, 1); \
|
||||
return ok && bd[0] === 0n && bd[1] === 9n && bd[2] === 9n; })()",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(result.as_bool());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ta_sab_copy_within() {
|
||||
// TA-over-SAB copyWithin 前/后向重叠两形全位回卷。
|
||||
let mut vm = Vm::new();
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"(function () { \
|
||||
var f = new Int8Array(new SharedArrayBuffer(8)); \
|
||||
f.set([1, 2, 3, 4, 5, 6, 7, 8]); \
|
||||
f.copyWithin(2, 0, 6); \
|
||||
var ok = f.join(',') === '1,2,1,2,3,4,5,6'; \
|
||||
var r = new Int8Array(new SharedArrayBuffer(8)); \
|
||||
r.set([1, 2, 3, 4, 5, 6, 7, 8]); \
|
||||
r.copyWithin(0, 2, 8); \
|
||||
return ok && r.join(',') === '3,4,5,6,7,8,7,8'; })()",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(result.as_bool());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ta_sab_subarray() {
|
||||
// TA-over-SAB subarray:视图属性指向 SAB 本体,界内子视图共享 buffer。
|
||||
let mut vm = Vm::new();
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"(function () { var sab = new SharedArrayBuffer(16); \
|
||||
var ta = new Int32Array(sab); \
|
||||
var sub = ta.subarray(1, 3); \
|
||||
return sub.length === 2 && sub.byteOffset === 4 \
|
||||
&& sub.buffer === sab && ta.buffer instanceof SharedArrayBuffer; })()",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(result.as_bool());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ta_sab_slice() {
|
||||
// TA-over-SAB slice 返回独立 AB 缓冲:值拷贝 + 缓冲类型断言。
|
||||
let mut vm = Vm::new();
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"(function () { var ta = new Int32Array(new SharedArrayBuffer(16)); \
|
||||
ta.fill(3); \
|
||||
var out = ta.slice(1, 3); \
|
||||
return out.length === 2 && out[0] === 3 && out[1] === 3 \
|
||||
&& out.buffer instanceof ArrayBuffer \
|
||||
&& !(out.buffer instanceof SharedArrayBuffer); })()",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(result.as_bool());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ta_sab_element_rw() {
|
||||
// TA-over-SAB 元素读写:写命中 SAB 载荷、读回值 + 邻位不受扰。
|
||||
let mut vm = Vm::new();
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"(function () { var ta = new Int32Array(new SharedArrayBuffer(16)); \
|
||||
ta[2] = 42; \
|
||||
return ta[2] === 42 && ta[0] === 0 && ta[3] === 0; })()",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(result.as_bool());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ta_sab_sort_reverse() {
|
||||
// TA-over-SAB sort/reverse:原地重排回卷,reverse 返回 this。
|
||||
let mut vm = Vm::new();
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"(function () { var ta = new Int32Array(new SharedArrayBuffer(16)); \
|
||||
ta.set([3, 1, 4, 2]); \
|
||||
ta.sort(); \
|
||||
var ok = ta.join(',') === '1,2,3,4'; \
|
||||
var rv = ta.reverse(); \
|
||||
return ok && rv === ta && ta.join(',') === '4,3,2,1'; })()",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(result.as_bool());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ta_sab_base64() {
|
||||
// TA-over-SAB base64 对:编码输出与同形 AB 视图逐位一致(双认入口
|
||||
// 零漂移)+ setFromBase64 解码计数与未写尾位清零。
|
||||
let mut vm = Vm::new();
|
||||
let result = eval(
|
||||
&mut vm,
|
||||
"(function () { var ta = new Uint8Array(new SharedArrayBuffer(4)); \
|
||||
ta.set([0xfb, 0xff, 0xfe, 0x00]); \
|
||||
var ref = new Uint8Array(new ArrayBuffer(4)); \
|
||||
ref.set([0xfb, 0xff, 0xfe, 0x00]); \
|
||||
var ok = ta.toBase64() === ref.toBase64(); \
|
||||
var r = ta.setFromBase64('////'); \
|
||||
return ok && r.read === 4 && r.written === 3 \
|
||||
&& ta[0] === 0xff && ta[1] === 0xff && ta[2] === 0xff && ta[3] === 0; })()",
|
||||
)
|
||||
.unwrap();
|
||||
assert!(result.as_bool());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user