feat: 内核与内置层增 Atomics 对象槽位与十方法

This commit is contained in:
2026-09-23 18:29:51 +00:00
parent 2adac5547c
commit c5589c98c2
7 changed files with 320 additions and 9 deletions
+5 -1
View File
@@ -360,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 non_object_protos: [&P<JsObject>; 26] = [
let non_object_protos: [&P<JsObject>; 27] = [
&world.array_proto,
&world.function_proto,
&world.string_proto,
@@ -374,6 +374,7 @@ pub(crate) fn wire_builtin_world_links(world: &BuiltinWorld) {
&world.regexp_proto,
&world.array_buffer_proto,
&world.shared_array_buffer_proto,
&world.atomics_object,
&world.data_view_proto,
&world.typed_array_proto,
&world.instant_proto,
@@ -484,6 +485,8 @@ impl BuiltinWorld {
let json_object = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null()));
let atomics_object = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null()));
let console_object = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null()));
let (date_proto, date_constructor) = make_named_pair(string_forge, shape_forge, labels, "Date");
@@ -583,6 +586,7 @@ impl BuiltinWorld {
array_buffer_proto,
shared_array_buffer_proto,
shared_array_buffer_constructor,
atomics_object,
data_view_constructor,
data_view_proto,
typed_array_proto: typed_arrays.typed_array_proto,
@@ -314,6 +314,11 @@ impl BuiltinWorld {
} else {
(current.shared_array_buffer_proto.clone(), current.shared_array_buffer_constructor.clone())
};
let atomics_object = if dirty.atomics {
P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null()))
} else {
current.atomics_object.clone()
};
let (data_view_proto, data_view_constructor) = if dirty.data_view {
make_named_pair(string_forge, shape_forge, labels, "DataView")
} else {
@@ -518,6 +523,7 @@ impl BuiltinWorld {
array_buffer_proto,
shared_array_buffer_proto,
shared_array_buffer_constructor,
atomics_object,
data_view_constructor,
data_view_proto,
typed_array_proto: typed_arrays.typed_array_proto,
+33 -1
View File
@@ -52,6 +52,9 @@ pub struct BuiltinWorld {
/// `make_named_pair` 成对构造,方法/访问器由绑定层安装。
pub shared_array_buffer_proto: P<JsObject>,
pub shared_array_buffer_constructor: P<JsObject>,
/// `Atomics` 全局纯对象(非函数):10 个原子方法由绑定层安装,
/// `@@toStringTag` 与原型链在 `wire_builtin_world_links` 落到 Object.prototype。
pub atomics_object: P<JsObject>,
pub data_view_constructor: P<JsObject>,
pub data_view_proto: P<JsObject>,
pub typed_array_proto: P<JsObject>,
@@ -347,7 +350,7 @@ impl BuiltinWorld {
/// session 收尾(`teardown_heap_data`)与选择性重建收尾(`retire_replaced`)
/// 的 P 字段枚举唯一入口:`BuiltinWorld` 新增 P 字段须在此同步补一行,否则
/// 收尾时该字段属性区无法释放、重建原型槽改写/释放漏掉该字段。
pub(crate) fn all_p_fields(&self) -> [&P<JsObject>; 106] {
pub(crate) fn all_p_fields(&self) -> [&P<JsObject>; 107] {
[
&self.object_proto,
&self.array_proto,
@@ -386,6 +389,7 @@ impl BuiltinWorld {
&self.array_buffer_proto,
&self.shared_array_buffer_proto,
&self.shared_array_buffer_constructor,
&self.atomics_object,
&self.data_view_constructor,
&self.data_view_proto,
&self.typed_array_proto,
@@ -540,6 +544,7 @@ impl BuiltinWorld {
BuiltinId::ArrayBufferProto => &self.array_buffer_proto,
BuiltinId::SharedArrayBufferProto => &self.shared_array_buffer_proto,
BuiltinId::SharedArrayBufferConstructor => &self.shared_array_buffer_constructor,
BuiltinId::AtomicsObject => &self.atomics_object,
BuiltinId::DataViewConstructor => &self.data_view_constructor,
BuiltinId::DataViewProto => &self.data_view_proto,
BuiltinId::TypedArrayProto => &self.typed_array_proto,
@@ -699,4 +704,31 @@ mod tests {
));
assert!(std::ptr::eq(ab_proto, session.builtin_world.array_buffer_proto.as_ptr() as *mut JsObject));
}
/// Atomics 家族脏线冒烟:仅 Atomics 单例世代漂移 → 选择性重置只判 Atomics
/// 家族脏,ArrayBuffer 家族指针原样保留(钉 dirty_since_snapshot 家族线接线)。
#[test]
fn atomics_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 atomics = old_world.atomics_object.as_ptr() as *mut JsObject;
let ab_proto = old_world.array_buffer_proto.as_ptr() as *mut JsObject;
unsafe {
(&mut *atomics).bump_generation();
}
let dirty = session.selective_reset(&core);
assert!(dirty.atomics);
assert!(!dirty.array_buffer);
assert!(!dirty.shared_array_buffer);
// 脏家族换新对象,未脏家族指针原样保留。
assert!(!std::ptr::eq(
atomics,
session.builtin_world.atomics_object.as_ptr() as *mut JsObject
));
assert!(std::ptr::eq(ab_proto, session.builtin_world.array_buffer_proto.as_ptr() as *mut JsObject));
}
}
+11 -5
View File
@@ -11,7 +11,7 @@ use crate::builtin::BuiltinWorld;
/// 维护注意:每个新增的 `BuiltinWorld` 对象字段都必须加到这里以及
/// `KernelSession::dirty_since_snapshot()`,以便选择性重置重建正确的
/// builtin 家族。
pub const NUM_BUILTINS: usize = 96;
pub const NUM_BUILTINS: usize = 97;
/// 内置对象枚举 id,与 `BuiltinWorld` 中的存储槽一一对应。
///
@@ -117,6 +117,7 @@ pub enum BuiltinId {
PlainYearMonthProto = 93,
SharedArrayBufferProto = 94,
SharedArrayBufferConstructor = 95,
AtomicsObject = 96,
}
impl BuiltinId {
@@ -220,6 +221,7 @@ impl BuiltinId {
BuiltinId::PlainYearMonthProto,
BuiltinId::SharedArrayBufferProto,
BuiltinId::SharedArrayBufferConstructor,
BuiltinId::AtomicsObject,
];
}
@@ -288,6 +290,7 @@ pub struct BuiltinDirtySet {
pub regexp: bool,
pub array_buffer: bool,
pub shared_array_buffer: bool,
pub atomics: bool,
pub data_view: bool,
pub typed_array_family: bool,
pub temporal: bool,
@@ -320,6 +323,7 @@ impl BuiltinDirtySet {
regexp: true,
array_buffer: true,
shared_array_buffer: true,
atomics: true,
data_view: true,
typed_array_family: true,
temporal: true,
@@ -347,6 +351,7 @@ impl BuiltinDirtySet {
|| self.regexp
|| self.array_buffer
|| self.shared_array_buffer
|| self.atomics
|| self.data_view
|| self.typed_array_family
|| self.temporal
@@ -364,18 +369,19 @@ impl BuiltinDirtySet {
mod tests {
use super::*;
/// 槽对齐面:表尾追加 SAB 家族后总槽数 96,既有 94 个判别值零位移,
/// 槽对齐面:表尾追加 Atomics 单例后总槽数 97,既有 96 个判别值零位移,
/// 快照数组随 NUM_BUILTINS 自动扩维、逐槽对齐。
#[test]
fn builtin_snapshot_all_slots_aligned() {
assert_eq!(NUM_BUILTINS, 96);
assert_eq!(NUM_BUILTINS, 97);
assert_eq!(BuiltinId::ALL.len(), NUM_BUILTINS);
// 前 94 项判别值 0-93 逐项不变(尾追加零位移)。
for i in 0..94usize {
// 前 96 项判别值 0-95 逐项不变(尾追加零位移)。
for i in 0..96usize {
assert_eq!(BuiltinId::ALL[i] as usize, i);
}
assert_eq!(BuiltinId::ALL[94], BuiltinId::SharedArrayBufferProto);
assert_eq!(BuiltinId::ALL[95], BuiltinId::SharedArrayBufferConstructor);
assert_eq!(BuiltinId::ALL[96], BuiltinId::AtomicsObject);
// 快照经 session 全量构造路径采集,generations 数组维度 = 槽数。
use crate::kernel::{KernelConfig, KernelCore, KernelSession};
@@ -159,6 +159,7 @@ impl KernelSession {
|| gen(BuiltinId::ArrayBufferProto) != snap(BuiltinId::ArrayBufferProto),
shared_array_buffer: gen(BuiltinId::SharedArrayBufferProto) != snap(BuiltinId::SharedArrayBufferProto)
|| gen(BuiltinId::SharedArrayBufferConstructor) != snap(BuiltinId::SharedArrayBufferConstructor),
atomics: gen(BuiltinId::AtomicsObject) != snap(BuiltinId::AtomicsObject),
data_view: gen(BuiltinId::DataViewConstructor) != snap(BuiltinId::DataViewConstructor)
|| gen(BuiltinId::DataViewProto) != snap(BuiltinId::DataViewProto),
typed_array_family: gen(BuiltinId::TypedArrayProto) != snap(BuiltinId::TypedArrayProto)