mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-25 19:21:11 +08:00
feat: BuiltinWorld 增 SharedArrayBuffer 原型与构造器槽
This commit is contained in:
@@ -269,11 +269,11 @@ fn set_proto_if_changed(obj: &P<JsObject>, proto: JsValue) {
|
|||||||
/// `[[Prototype]]` 赋值。
|
/// `[[Prototype]]` 赋值。
|
||||||
///
|
///
|
||||||
/// # 步骤
|
/// # 步骤
|
||||||
/// 1. 35 组构造器/原型对互指(`.prototype` / `.constructor` 槽,含
|
/// 1. 36 组构造器/原型对互指(`.prototype` / `.constructor` 槽,含
|
||||||
/// TypedArray 家族共享对),经 `wire_ctor_proto` 覆盖占位槽;
|
/// TypedArray 家族共享对),经 `wire_ctor_proto` 覆盖占位槽;
|
||||||
/// 2. 23 个非 TypedArray 构造器的 `[[Prototype]]` → Function.prototype
|
/// 2. 24 个非 TypedArray 构造器的 `[[Prototype]]` → Function.prototype
|
||||||
/// (标准内置函数对象均继承 Function.prototype);
|
/// (标准内置函数对象均继承 Function.prototype);
|
||||||
/// 3. 25 个非 Object 原型的 `[[Prototype]]` → Object.prototype,另含
|
/// 3. 26 个非 Object 原型的 `[[Prototype]]` → Object.prototype,另含
|
||||||
/// Temporal 命名空间对象、Temporal.now、Console 单例与 Math/JSON
|
/// Temporal 命名空间对象、Temporal.now、Console 单例与 Math/JSON
|
||||||
/// 命名空间对象;
|
/// 命名空间对象;
|
||||||
/// 4. %IteratorPrototype% → Object.prototype,6 个集合迭代器原型
|
/// 4. %IteratorPrototype% → Object.prototype,6 个集合迭代器原型
|
||||||
@@ -304,6 +304,7 @@ pub(crate) fn wire_builtin_world_links(world: &BuiltinWorld) {
|
|||||||
wire_ctor_proto(&world.map_constructor, &world.map_proto);
|
wire_ctor_proto(&world.map_constructor, &world.map_proto);
|
||||||
wire_ctor_proto(&world.regexp_constructor, &world.regexp_proto);
|
wire_ctor_proto(&world.regexp_constructor, &world.regexp_proto);
|
||||||
wire_ctor_proto(&world.array_buffer_constructor, &world.array_buffer_proto);
|
wire_ctor_proto(&world.array_buffer_constructor, &world.array_buffer_proto);
|
||||||
|
wire_ctor_proto(&world.shared_array_buffer_constructor, &world.shared_array_buffer_proto);
|
||||||
wire_ctor_proto(&world.data_view_constructor, &world.data_view_proto);
|
wire_ctor_proto(&world.data_view_constructor, &world.data_view_proto);
|
||||||
wire_ctor_proto(&world.int8array_constructor, &world.int8array_proto);
|
wire_ctor_proto(&world.int8array_constructor, &world.int8array_proto);
|
||||||
wire_ctor_proto(&world.uint8array_constructor, &world.uint8array_proto);
|
wire_ctor_proto(&world.uint8array_constructor, &world.uint8array_proto);
|
||||||
@@ -343,6 +344,7 @@ pub(crate) fn wire_builtin_world_links(world: &BuiltinWorld) {
|
|||||||
&world.map_constructor,
|
&world.map_constructor,
|
||||||
&world.regexp_constructor,
|
&world.regexp_constructor,
|
||||||
&world.array_buffer_constructor,
|
&world.array_buffer_constructor,
|
||||||
|
&world.shared_array_buffer_constructor,
|
||||||
&world.data_view_constructor,
|
&world.data_view_constructor,
|
||||||
&world.bigint_constructor,
|
&world.bigint_constructor,
|
||||||
&world.instant_constructor,
|
&world.instant_constructor,
|
||||||
@@ -358,7 +360,7 @@ pub(crate) fn wire_builtin_world_links(world: &BuiltinWorld) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let obj_proto_val = JsValue::from_js_object(world.object_proto.as_ptr() as *mut JsObject);
|
let obj_proto_val = JsValue::from_js_object(world.object_proto.as_ptr() as *mut JsObject);
|
||||||
let non_object_protos: [&P<JsObject>; 25] = [
|
let non_object_protos: [&P<JsObject>; 26] = [
|
||||||
&world.array_proto,
|
&world.array_proto,
|
||||||
&world.function_proto,
|
&world.function_proto,
|
||||||
&world.string_proto,
|
&world.string_proto,
|
||||||
@@ -371,6 +373,7 @@ pub(crate) fn wire_builtin_world_links(world: &BuiltinWorld) {
|
|||||||
&world.map_proto,
|
&world.map_proto,
|
||||||
&world.regexp_proto,
|
&world.regexp_proto,
|
||||||
&world.array_buffer_proto,
|
&world.array_buffer_proto,
|
||||||
|
&world.shared_array_buffer_proto,
|
||||||
&world.data_view_proto,
|
&world.data_view_proto,
|
||||||
&world.typed_array_proto,
|
&world.typed_array_proto,
|
||||||
&world.instant_proto,
|
&world.instant_proto,
|
||||||
@@ -489,6 +492,8 @@ impl BuiltinWorld {
|
|||||||
let (regexp_proto, regexp_constructor) = make_named_pair(string_forge, shape_forge, labels, "RegExp");
|
let (regexp_proto, regexp_constructor) = make_named_pair(string_forge, shape_forge, labels, "RegExp");
|
||||||
let (array_buffer_proto, array_buffer_constructor) =
|
let (array_buffer_proto, array_buffer_constructor) =
|
||||||
make_named_pair(string_forge, shape_forge, labels, "ArrayBuffer");
|
make_named_pair(string_forge, shape_forge, labels, "ArrayBuffer");
|
||||||
|
let (shared_array_buffer_proto, shared_array_buffer_constructor) =
|
||||||
|
make_named_pair(string_forge, shape_forge, labels, "SharedArrayBuffer");
|
||||||
let (data_view_proto, data_view_constructor) = make_named_pair(string_forge, shape_forge, labels, "DataView");
|
let (data_view_proto, data_view_constructor) = make_named_pair(string_forge, shape_forge, labels, "DataView");
|
||||||
let typed_arrays = make_typed_array_family(string_forge, shape_forge, labels, &object_proto);
|
let typed_arrays = make_typed_array_family(string_forge, shape_forge, labels, &object_proto);
|
||||||
|
|
||||||
@@ -576,6 +581,8 @@ impl BuiltinWorld {
|
|||||||
regexp_proto,
|
regexp_proto,
|
||||||
array_buffer_constructor,
|
array_buffer_constructor,
|
||||||
array_buffer_proto,
|
array_buffer_proto,
|
||||||
|
shared_array_buffer_proto,
|
||||||
|
shared_array_buffer_constructor,
|
||||||
data_view_constructor,
|
data_view_constructor,
|
||||||
data_view_proto,
|
data_view_proto,
|
||||||
typed_array_proto: typed_arrays.typed_array_proto,
|
typed_array_proto: typed_arrays.typed_array_proto,
|
||||||
|
|||||||
@@ -309,6 +309,11 @@ impl BuiltinWorld {
|
|||||||
} else {
|
} else {
|
||||||
(current.array_buffer_proto.clone(), current.array_buffer_constructor.clone())
|
(current.array_buffer_proto.clone(), current.array_buffer_constructor.clone())
|
||||||
};
|
};
|
||||||
|
let (shared_array_buffer_proto, shared_array_buffer_constructor) = if dirty.shared_array_buffer {
|
||||||
|
make_named_pair(string_forge, shape_forge, labels, "SharedArrayBuffer")
|
||||||
|
} else {
|
||||||
|
(current.shared_array_buffer_proto.clone(), current.shared_array_buffer_constructor.clone())
|
||||||
|
};
|
||||||
let (data_view_proto, data_view_constructor) = if dirty.data_view {
|
let (data_view_proto, data_view_constructor) = if dirty.data_view {
|
||||||
make_named_pair(string_forge, shape_forge, labels, "DataView")
|
make_named_pair(string_forge, shape_forge, labels, "DataView")
|
||||||
} else {
|
} else {
|
||||||
@@ -511,6 +516,8 @@ impl BuiltinWorld {
|
|||||||
regexp_proto,
|
regexp_proto,
|
||||||
array_buffer_constructor,
|
array_buffer_constructor,
|
||||||
array_buffer_proto,
|
array_buffer_proto,
|
||||||
|
shared_array_buffer_proto,
|
||||||
|
shared_array_buffer_constructor,
|
||||||
data_view_constructor,
|
data_view_constructor,
|
||||||
data_view_proto,
|
data_view_proto,
|
||||||
typed_array_proto: typed_arrays.typed_array_proto,
|
typed_array_proto: typed_arrays.typed_array_proto,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//! 注册表职责:BuiltinWorld 结构(104 固定 P 字段 + stub 族 + Box::into_raw
|
//! 注册表职责:BuiltinWorld 结构(106 固定 P 字段 + stub 族 + Box::into_raw
|
||||||
//! 登记表)、get_by_id 派发、all_p_fields 104 元组枚举(新增 P 字段四处同步
|
//! 登记表)、get_by_id 派发、all_p_fields 104 元组枚举(新增 P 字段四处同步
|
||||||
//! 约束载体)与登记表 track/find/inherit/teardown。
|
//! 约束载体)与登记表 track/find/inherit/teardown。
|
||||||
|
|
||||||
@@ -48,6 +48,10 @@ pub struct BuiltinWorld {
|
|||||||
pub regexp_proto: P<JsObject>,
|
pub regexp_proto: P<JsObject>,
|
||||||
pub array_buffer_constructor: P<JsObject>,
|
pub array_buffer_constructor: P<JsObject>,
|
||||||
pub array_buffer_proto: P<JsObject>,
|
pub array_buffer_proto: P<JsObject>,
|
||||||
|
/// `SharedArrayBuffer.prototype` 与 `SharedArrayBuffer` 构造器:经
|
||||||
|
/// `make_named_pair` 成对构造,方法/访问器由绑定层安装。
|
||||||
|
pub shared_array_buffer_proto: P<JsObject>,
|
||||||
|
pub shared_array_buffer_constructor: P<JsObject>,
|
||||||
pub data_view_constructor: P<JsObject>,
|
pub data_view_constructor: P<JsObject>,
|
||||||
pub data_view_proto: P<JsObject>,
|
pub data_view_proto: P<JsObject>,
|
||||||
pub typed_array_proto: P<JsObject>,
|
pub typed_array_proto: P<JsObject>,
|
||||||
@@ -343,7 +347,7 @@ impl BuiltinWorld {
|
|||||||
/// session 收尾(`teardown_heap_data`)与选择性重建收尾(`retire_replaced`)
|
/// session 收尾(`teardown_heap_data`)与选择性重建收尾(`retire_replaced`)
|
||||||
/// 的 P 字段枚举唯一入口:`BuiltinWorld` 新增 P 字段须在此同步补一行,否则
|
/// 的 P 字段枚举唯一入口:`BuiltinWorld` 新增 P 字段须在此同步补一行,否则
|
||||||
/// 收尾时该字段属性区无法释放、重建原型槽改写/释放漏掉该字段。
|
/// 收尾时该字段属性区无法释放、重建原型槽改写/释放漏掉该字段。
|
||||||
pub(crate) fn all_p_fields(&self) -> [&P<JsObject>; 104] {
|
pub(crate) fn all_p_fields(&self) -> [&P<JsObject>; 106] {
|
||||||
[
|
[
|
||||||
&self.object_proto,
|
&self.object_proto,
|
||||||
&self.array_proto,
|
&self.array_proto,
|
||||||
@@ -380,6 +384,8 @@ impl BuiltinWorld {
|
|||||||
&self.regexp_proto,
|
&self.regexp_proto,
|
||||||
&self.array_buffer_constructor,
|
&self.array_buffer_constructor,
|
||||||
&self.array_buffer_proto,
|
&self.array_buffer_proto,
|
||||||
|
&self.shared_array_buffer_proto,
|
||||||
|
&self.shared_array_buffer_constructor,
|
||||||
&self.data_view_constructor,
|
&self.data_view_constructor,
|
||||||
&self.data_view_proto,
|
&self.data_view_proto,
|
||||||
&self.typed_array_proto,
|
&self.typed_array_proto,
|
||||||
@@ -532,6 +538,8 @@ impl BuiltinWorld {
|
|||||||
BuiltinId::RegExpProto => &self.regexp_proto,
|
BuiltinId::RegExpProto => &self.regexp_proto,
|
||||||
BuiltinId::ArrayBufferConstructor => &self.array_buffer_constructor,
|
BuiltinId::ArrayBufferConstructor => &self.array_buffer_constructor,
|
||||||
BuiltinId::ArrayBufferProto => &self.array_buffer_proto,
|
BuiltinId::ArrayBufferProto => &self.array_buffer_proto,
|
||||||
|
BuiltinId::SharedArrayBufferProto => &self.shared_array_buffer_proto,
|
||||||
|
BuiltinId::SharedArrayBufferConstructor => &self.shared_array_buffer_constructor,
|
||||||
BuiltinId::DataViewConstructor => &self.data_view_constructor,
|
BuiltinId::DataViewConstructor => &self.data_view_constructor,
|
||||||
BuiltinId::DataViewProto => &self.data_view_proto,
|
BuiltinId::DataViewProto => &self.data_view_proto,
|
||||||
BuiltinId::TypedArrayProto => &self.typed_array_proto,
|
BuiltinId::TypedArrayProto => &self.typed_array_proto,
|
||||||
@@ -658,4 +666,37 @@ mod tests {
|
|||||||
// 登记表并入新 world:保留 wrapper 仍须由 session 收尾统一释放。
|
// 登记表并入新 world:保留 wrapper 仍须由 session 收尾统一释放。
|
||||||
assert!(session.builtin_world.leaked_objects.borrow().iter().any(|s| s.ptr == wrapper));
|
assert!(session.builtin_world.leaked_objects.borrow().iter().any(|s| s.ptr == wrapper));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// SAB 家族脏线冒烟:仅 SAB 对世代漂移 → 选择性重置只判 SAB 家族脏,
|
||||||
|
/// ArrayBuffer 家族指针原样保留(钉 dirty_since_snapshot 家族线接线)。
|
||||||
|
#[test]
|
||||||
|
fn sab_family_selective_rebuild() {
|
||||||
|
use crate::kernel::{KernelConfig, KernelCore, KernelSession};
|
||||||
|
let core = KernelCore::new(KernelConfig::minimal());
|
||||||
|
let mut session = KernelSession::new(&core);
|
||||||
|
let old_world = std::sync::Arc::clone(&session.builtin_world);
|
||||||
|
let sab_proto = old_world.shared_array_buffer_proto.as_ptr() as *mut JsObject;
|
||||||
|
let sab_ctor = old_world.shared_array_buffer_constructor.as_ptr() as *mut JsObject;
|
||||||
|
let ab_proto = old_world.array_buffer_proto.as_ptr() as *mut JsObject;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
(&mut *sab_proto).bump_generation();
|
||||||
|
(&mut *sab_ctor).bump_generation();
|
||||||
|
}
|
||||||
|
let dirty = session.selective_reset(&core);
|
||||||
|
assert!(dirty.shared_array_buffer);
|
||||||
|
assert!(!dirty.array_buffer);
|
||||||
|
assert!(!dirty.data_view);
|
||||||
|
|
||||||
|
// 脏家族换新对象对,未脏家族指针原样保留。
|
||||||
|
assert!(!std::ptr::eq(
|
||||||
|
sab_proto,
|
||||||
|
session.builtin_world.shared_array_buffer_proto.as_ptr() as *mut JsObject
|
||||||
|
));
|
||||||
|
assert!(!std::ptr::eq(
|
||||||
|
sab_ctor,
|
||||||
|
session.builtin_world.shared_array_buffer_constructor.as_ptr() as *mut JsObject
|
||||||
|
));
|
||||||
|
assert!(std::ptr::eq(ab_proto, session.builtin_world.array_buffer_proto.as_ptr() as *mut JsObject));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//! 内置对象 id 枚举(`BuiltinId` 94 变体 + `ALL` 顺序钉表)、世代快照
|
//! 内置对象 id 枚举(`BuiltinId` 96 变体 + `ALL` 顺序钉表)、世代快照
|
||||||
//! (`BuiltinSnapshot`)与按家族划分的脏标记位集(`BuiltinDirtySet`);
|
//! (`BuiltinSnapshot`)与按家族划分的脏标记位集(`BuiltinDirtySet`);
|
||||||
//! `NUM_BUILTINS` 文档承载"新增 BuiltinWorld 字段须同步"四处约束注记。
|
//! `NUM_BUILTINS` 文档承载"新增 BuiltinWorld 字段须同步"四处约束注记。
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ use crate::builtin::BuiltinWorld;
|
|||||||
/// 维护注意:每个新增的 `BuiltinWorld` 对象字段都必须加到这里以及
|
/// 维护注意:每个新增的 `BuiltinWorld` 对象字段都必须加到这里以及
|
||||||
/// `KernelSession::dirty_since_snapshot()`,以便选择性重置重建正确的
|
/// `KernelSession::dirty_since_snapshot()`,以便选择性重置重建正确的
|
||||||
/// builtin 家族。
|
/// builtin 家族。
|
||||||
pub const NUM_BUILTINS: usize = 94;
|
pub const NUM_BUILTINS: usize = 96;
|
||||||
|
|
||||||
/// 内置对象枚举 id,与 `BuiltinWorld` 中的存储槽一一对应。
|
/// 内置对象枚举 id,与 `BuiltinWorld` 中的存储槽一一对应。
|
||||||
///
|
///
|
||||||
@@ -115,6 +115,8 @@ pub enum BuiltinId {
|
|||||||
PlainMonthDayProto = 91,
|
PlainMonthDayProto = 91,
|
||||||
PlainYearMonthConstructor = 92,
|
PlainYearMonthConstructor = 92,
|
||||||
PlainYearMonthProto = 93,
|
PlainYearMonthProto = 93,
|
||||||
|
SharedArrayBufferProto = 94,
|
||||||
|
SharedArrayBufferConstructor = 95,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BuiltinId {
|
impl BuiltinId {
|
||||||
@@ -216,6 +218,8 @@ impl BuiltinId {
|
|||||||
BuiltinId::PlainMonthDayProto,
|
BuiltinId::PlainMonthDayProto,
|
||||||
BuiltinId::PlainYearMonthConstructor,
|
BuiltinId::PlainYearMonthConstructor,
|
||||||
BuiltinId::PlainYearMonthProto,
|
BuiltinId::PlainYearMonthProto,
|
||||||
|
BuiltinId::SharedArrayBufferProto,
|
||||||
|
BuiltinId::SharedArrayBufferConstructor,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,6 +287,7 @@ pub struct BuiltinDirtySet {
|
|||||||
pub map: bool,
|
pub map: bool,
|
||||||
pub regexp: bool,
|
pub regexp: bool,
|
||||||
pub array_buffer: bool,
|
pub array_buffer: bool,
|
||||||
|
pub shared_array_buffer: bool,
|
||||||
pub data_view: bool,
|
pub data_view: bool,
|
||||||
pub typed_array_family: bool,
|
pub typed_array_family: bool,
|
||||||
pub temporal: bool,
|
pub temporal: bool,
|
||||||
@@ -314,6 +319,7 @@ impl BuiltinDirtySet {
|
|||||||
map: true,
|
map: true,
|
||||||
regexp: true,
|
regexp: true,
|
||||||
array_buffer: true,
|
array_buffer: true,
|
||||||
|
shared_array_buffer: true,
|
||||||
data_view: true,
|
data_view: true,
|
||||||
typed_array_family: true,
|
typed_array_family: true,
|
||||||
temporal: true,
|
temporal: true,
|
||||||
@@ -340,6 +346,7 @@ impl BuiltinDirtySet {
|
|||||||
|| self.map
|
|| self.map
|
||||||
|| self.regexp
|
|| self.regexp
|
||||||
|| self.array_buffer
|
|| self.array_buffer
|
||||||
|
|| self.shared_array_buffer
|
||||||
|| self.data_view
|
|| self.data_view
|
||||||
|| self.typed_array_family
|
|| self.typed_array_family
|
||||||
|| self.temporal
|
|| self.temporal
|
||||||
@@ -352,3 +359,28 @@ impl BuiltinDirtySet {
|
|||||||
self.any_builtin_dirty() || self.global
|
self.any_builtin_dirty() || self.global
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
/// 槽对齐面:表尾追加 SAB 家族后总槽数 96,既有 94 个判别值零位移,
|
||||||
|
/// 快照数组随 NUM_BUILTINS 自动扩维、逐槽对齐。
|
||||||
|
#[test]
|
||||||
|
fn builtin_snapshot_all_slots_aligned() {
|
||||||
|
assert_eq!(NUM_BUILTINS, 96);
|
||||||
|
assert_eq!(BuiltinId::ALL.len(), NUM_BUILTINS);
|
||||||
|
// 前 94 项判别值 0-93 逐项不变(尾追加零位移)。
|
||||||
|
for i in 0..94usize {
|
||||||
|
assert_eq!(BuiltinId::ALL[i] as usize, i);
|
||||||
|
}
|
||||||
|
assert_eq!(BuiltinId::ALL[94], BuiltinId::SharedArrayBufferProto);
|
||||||
|
assert_eq!(BuiltinId::ALL[95], BuiltinId::SharedArrayBufferConstructor);
|
||||||
|
|
||||||
|
// 快照经 session 全量构造路径采集,generations 数组维度 = 槽数。
|
||||||
|
use crate::kernel::{KernelConfig, KernelCore, KernelSession};
|
||||||
|
let core = KernelCore::new(KernelConfig::minimal());
|
||||||
|
let session = KernelSession::new(&core);
|
||||||
|
assert_eq!(session.builtin_snapshot.generations.len(), NUM_BUILTINS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -157,6 +157,8 @@ impl KernelSession {
|
|||||||
|| gen(BuiltinId::RegExpProto) != snap(BuiltinId::RegExpProto),
|
|| gen(BuiltinId::RegExpProto) != snap(BuiltinId::RegExpProto),
|
||||||
array_buffer: gen(BuiltinId::ArrayBufferConstructor) != snap(BuiltinId::ArrayBufferConstructor)
|
array_buffer: gen(BuiltinId::ArrayBufferConstructor) != snap(BuiltinId::ArrayBufferConstructor)
|
||||||
|| gen(BuiltinId::ArrayBufferProto) != snap(BuiltinId::ArrayBufferProto),
|
|| gen(BuiltinId::ArrayBufferProto) != snap(BuiltinId::ArrayBufferProto),
|
||||||
|
shared_array_buffer: gen(BuiltinId::SharedArrayBufferProto) != snap(BuiltinId::SharedArrayBufferProto)
|
||||||
|
|| gen(BuiltinId::SharedArrayBufferConstructor) != snap(BuiltinId::SharedArrayBufferConstructor),
|
||||||
data_view: gen(BuiltinId::DataViewConstructor) != snap(BuiltinId::DataViewConstructor)
|
data_view: gen(BuiltinId::DataViewConstructor) != snap(BuiltinId::DataViewConstructor)
|
||||||
|| gen(BuiltinId::DataViewProto) != snap(BuiltinId::DataViewProto),
|
|| gen(BuiltinId::DataViewProto) != snap(BuiltinId::DataViewProto),
|
||||||
typed_array_family: gen(BuiltinId::TypedArrayProto) != snap(BuiltinId::TypedArrayProto)
|
typed_array_family: gen(BuiltinId::TypedArrayProto) != snap(BuiltinId::TypedArrayProto)
|
||||||
|
|||||||
Reference in New Issue
Block a user