feat: SharedArrayBuffer 最小构造器与载荷生命周期

This commit is contained in:
2026-09-23 12:44:05 +00:00
parent 7457740c36
commit 3d50306853
8 changed files with 121 additions and 7 deletions
+1 -1
View File
@@ -20,7 +20,7 @@ const STUBS: [(&str, *const (), u8); 7] = [
),
(
"SharedArrayBuffer",
oxide_builtins::stubs::shared_array_buffer_stub::<crate::vm::Vm> as *const (),
oxide_builtins::array_buffer::shared_array_buffer_constructor::<crate::vm::Vm> as *const (),
1,
),
("Atomics", oxide_builtins::stubs::atomics_stub::<crate::vm::Vm> as *const (), 0),
+1 -1
View File
@@ -882,7 +882,7 @@ fn bind_stub_globals(core: &Arc<KernelCore>, session: &KernelSession, global: &m
),
(
"SharedArrayBuffer",
oxide_builtins::stubs::shared_array_buffer_stub::<crate::vm::Vm> as *const (),
oxide_builtins::array_buffer::shared_array_buffer_constructor::<crate::vm::Vm> as *const (),
1,
),
("Atomics", oxide_builtins::stubs::atomics_stub::<crate::vm::Vm> as *const (), 0),
+3
View File
@@ -67,6 +67,9 @@ impl Vm {
} else if src_ref.is_array_buffer_obj() {
// 字节缓冲深拷贝到新对象:源 Vec 随 epoch 释放,互不共享。
array_buffer::clone_array_buffer_native(src_ref, dst_ref);
} else if src_ref.is_shared_array_buffer_obj() {
// 字节缓冲深拷贝到新对象:源 Vec 随 epoch 释放,互不共享。
array_buffer::clone_shared_array_buffer_native(src_ref, dst_ref);
} else if src_ref.is_generator_obj() {
// 生成器状态盒深拷贝到新对象:源盒随 epoch 释放,互不共享。
crate::generator::clone_generator_native_with_rewrite(src_ref, dst_ref, |value| {
+4
View File
@@ -116,6 +116,7 @@ impl SessionGc {
bytes += module::module_ns_native_size(obj);
bytes += disposable_stack::disposable_stack_native_size(obj);
bytes += array_buffer::array_buffer_native_size(obj);
bytes += array_buffer::shared_array_buffer_native_size(obj);
bytes += regexp::regexp_native_size(obj);
bytes += typed_array::typed_array_native_size(obj);
bytes += data_view::data_view_native_size(obj);
@@ -537,6 +538,7 @@ impl SessionGc {
freed_bytes += module::drop_module_ns_native(obj);
freed_bytes += disposable_stack::drop_dispose_native(obj);
freed_bytes += array_buffer::drop_array_buffer_native(obj);
freed_bytes += array_buffer::drop_shared_array_buffer_native(obj);
freed_bytes += regexp::drop_regexp_native(obj);
freed_bytes += typed_array::drop_typed_array_native(obj);
freed_bytes += data_view::drop_data_view_native(obj);
@@ -625,6 +627,8 @@ impl SessionGc {
disposable_stack::clone_dispose_native_with_rewrite(old_ref, new_ref, |value| value);
} else if old_ref.is_array_buffer_obj() {
array_buffer::clone_array_buffer_native(old_ref, new_ref);
} else if old_ref.is_shared_array_buffer_obj() {
array_buffer::clone_shared_array_buffer_native(old_ref, new_ref);
} else if old_ref.is_typed_array_obj() {
typed_array::clone_typed_array_native_with_rewrite(old_ref, new_ref, |value| value);
} else if old_ref.is_data_view_obj() {
@@ -1134,7 +1134,26 @@ fn ab_sti_brand_family() {
var t2 = false, t3 = false; \
var nab = new ArrayBuffer(8); \
try { new nab.sliceToImmutable(); t3 = true; } catch (e) { t2 = e instanceof TypeError; t3 = false; } \
return ok && calls.length === 0 && t2 && calls2.length === 0 && !t3; })()",
return ok && calls.length === 0 && t2 && calls2.length === 0 && !t3; })()",
)
.unwrap();
assert!(result.as_bool());
}
/// SharedArrayBuffer 最小构造钉:`new SharedArrayBuffer(n)` 建 n 字节缓冲,
/// 非 ArrayBuffer 品牌(ArrayBuffer 方法族对其先读参后抛 TypeError)。
#[test]
fn sab_constructor_and_brand_rejection() {
let mut vm = Vm::new();
let result = eval(
&mut vm,
"(function () { var sab = new SharedArrayBuffer(4); \
var calls = []; \
var start = { valueOf: function () { calls.push('s'); return 0; } }; \
var t = false; \
try { ArrayBuffer.prototype.sliceToImmutable.call(sab, start); t = true; } \
catch (e) { t = e instanceof TypeError; } \
return t && calls.length === 0; })()",
)
.unwrap();
assert!(result.as_bool());