feat: 新增 Intl 特性域骨架实现

This commit is contained in:
2026-10-16 05:08:58 +00:00
parent 5e7808bb08
commit 04b991f5d8
17 changed files with 2417 additions and 31 deletions
+77 -1
View File
@@ -347,6 +347,16 @@ pub(crate) fn wire_builtin_world_links(world: &BuiltinWorld) {
wire_ctor_proto(&world.plain_month_day_constructor, &world.plain_month_day_proto);
wire_ctor_proto(&world.plain_year_month_constructor, &world.plain_year_month_proto);
wire_ctor_proto(&world.bigint_constructor, &world.bigint_proto);
wire_ctor_proto(&world.number_format_constructor, &world.number_format_proto);
wire_ctor_proto(&world.date_time_format_constructor, &world.date_time_format_proto);
wire_ctor_proto(&world.collator_constructor, &world.collator_proto);
wire_ctor_proto(&world.plural_rules_constructor, &world.plural_rules_proto);
wire_ctor_proto(&world.list_format_constructor, &world.list_format_proto);
wire_ctor_proto(&world.relative_time_format_constructor, &world.relative_time_format_proto);
wire_ctor_proto(&world.display_names_constructor, &world.display_names_proto);
wire_ctor_proto(&world.segmenter_constructor, &world.segmenter_proto);
wire_ctor_proto(&world.locale_constructor, &world.locale_proto);
wire_ctor_proto(&world.duration_format_constructor, &world.duration_format_proto);
// 非 TypedArray 构造器的 [[Prototype]] 指向 Function.prototype:
// 标准内置函数对象均继承 Function.prototype。
@@ -376,12 +386,22 @@ pub(crate) fn wire_builtin_world_links(world: &BuiltinWorld) {
&world.plain_date_time_constructor,
&world.plain_month_day_constructor,
&world.plain_year_month_constructor,
&world.number_format_constructor,
&world.date_time_format_constructor,
&world.collator_constructor,
&world.plural_rules_constructor,
&world.list_format_constructor,
&world.relative_time_format_constructor,
&world.display_names_constructor,
&world.segmenter_constructor,
&world.locale_constructor,
&world.duration_format_constructor,
] {
set_proto_if_changed(ctor, fn_proto_val);
}
let obj_proto_val = JsValue::from_js_object(world.object_proto.as_ptr() as *mut JsObject);
let non_object_protos: [&P<JsObject>; 28] = [
let non_object_protos: [&P<JsObject>; 38] = [
&world.array_proto,
&world.function_proto,
&world.string_proto,
@@ -410,6 +430,16 @@ pub(crate) fn wire_builtin_world_links(world: &BuiltinWorld) {
&world.disposable_stack_proto,
&world.async_disposable_stack_proto,
&world.async_iterator_proto,
&world.number_format_proto,
&world.date_time_format_proto,
&world.collator_proto,
&world.plural_rules_proto,
&world.list_format_proto,
&world.relative_time_format_proto,
&world.display_names_proto,
&world.segmenter_proto,
&world.locale_proto,
&world.duration_format_proto,
];
for proto in &non_object_protos {
set_proto_if_changed(proto, obj_proto_val);
@@ -419,6 +449,9 @@ pub(crate) fn wire_builtin_world_links(world: &BuiltinWorld) {
set_proto_if_changed(&world.temporal_object, obj_proto_val);
set_proto_if_changed(&world.temporal_now_object, obj_proto_val);
// Intl 命名空间对象(非构造器)继承 Object.prototype。
set_proto_if_changed(&world.intl_object, obj_proto_val);
// Console 对象(单例命名空间)继承 Object.prototype。
set_proto_if_changed(&world.console_object, obj_proto_val);
@@ -569,6 +602,28 @@ impl BuiltinWorld {
let (bigint_proto, bigint_constructor) = make_named_pair(string_forge, shape_forge, labels, "BigInt");
let stub_objects = Vec::new();
// Intl 命名空间对象(非构造器空对象)与十组构造器/原型对:骨架阶段
// 构造语义(实例化/resolvedOptions/静态方法)由绑定层 native 填充,
// 本处只预留 P 字段使快照/脏检查/收尾枚举覆盖到这二十一枚对象。
let intl_object = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null()));
let (number_format_proto, number_format_constructor) =
make_named_pair(string_forge, shape_forge, labels, "NumberFormat");
let (date_time_format_proto, date_time_format_constructor) =
make_named_pair(string_forge, shape_forge, labels, "DateTimeFormat");
let (collator_proto, collator_constructor) = make_named_pair(string_forge, shape_forge, labels, "Collator");
let (plural_rules_proto, plural_rules_constructor) =
make_named_pair(string_forge, shape_forge, labels, "PluralRules");
let (list_format_proto, list_format_constructor) =
make_named_pair(string_forge, shape_forge, labels, "ListFormat");
let (relative_time_format_proto, relative_time_format_constructor) =
make_named_pair(string_forge, shape_forge, labels, "RelativeTimeFormat");
let (display_names_proto, display_names_constructor) =
make_named_pair(string_forge, shape_forge, labels, "DisplayNames");
let (segmenter_proto, segmenter_constructor) = make_named_pair(string_forge, shape_forge, labels, "Segmenter");
let (locale_proto, locale_constructor) = make_named_pair(string_forge, shape_forge, labels, "Locale");
let (duration_format_proto, duration_format_constructor) =
make_named_pair(string_forge, shape_forge, labels, "DurationFormat");
// 迭代器原型家族:链关系(→ %IteratorPrototype% → Object.prototype)在
// wire_builtin_world_links 中建立,next/@@iterator 方法由绑定层
// (oxide_builtins 中安装方法 wrapper 的代码)安装。
@@ -699,6 +754,27 @@ impl BuiltinWorld {
custom_event_proto,
custom_event_constructor,
event_target_proto,
intl_object,
number_format_constructor,
number_format_proto,
date_time_format_constructor,
date_time_format_proto,
collator_constructor,
collator_proto,
plural_rules_constructor,
plural_rules_proto,
list_format_constructor,
list_format_proto,
relative_time_format_constructor,
relative_time_format_proto,
display_names_constructor,
display_names_proto,
segmenter_constructor,
segmenter_proto,
locale_constructor,
locale_proto,
duration_format_constructor,
duration_format_proto,
leaked_objects: std::cell::RefCell::new(Vec::new()),
};
wire_builtin_world_links(&world);
+113
View File
@@ -460,6 +460,98 @@ impl BuiltinWorld {
)
};
// Intl 命名空间对象(非构造器空对象)与十组构造器/原型对:脏则换新
// 空对象占位(与全量构造同形),未脏沿用旧指针。
let (
intl_object,
number_format_constructor,
number_format_proto,
date_time_format_constructor,
date_time_format_proto,
collator_constructor,
collator_proto,
plural_rules_constructor,
plural_rules_proto,
list_format_constructor,
list_format_proto,
relative_time_format_constructor,
relative_time_format_proto,
display_names_constructor,
display_names_proto,
segmenter_constructor,
segmenter_proto,
locale_constructor,
locale_proto,
duration_format_constructor,
duration_format_proto,
) = if dirty.intl {
let (number_format_proto, number_format_constructor) =
make_named_pair(string_forge, shape_forge, labels, "NumberFormat");
let (date_time_format_proto, date_time_format_constructor) =
make_named_pair(string_forge, shape_forge, labels, "DateTimeFormat");
let (collator_proto, collator_constructor) = make_named_pair(string_forge, shape_forge, labels, "Collator");
let (plural_rules_proto, plural_rules_constructor) =
make_named_pair(string_forge, shape_forge, labels, "PluralRules");
let (list_format_proto, list_format_constructor) =
make_named_pair(string_forge, shape_forge, labels, "ListFormat");
let (relative_time_format_proto, relative_time_format_constructor) =
make_named_pair(string_forge, shape_forge, labels, "RelativeTimeFormat");
let (display_names_proto, display_names_constructor) =
make_named_pair(string_forge, shape_forge, labels, "DisplayNames");
let (segmenter_proto, segmenter_constructor) =
make_named_pair(string_forge, shape_forge, labels, "Segmenter");
let (locale_proto, locale_constructor) = make_named_pair(string_forge, shape_forge, labels, "Locale");
let (duration_format_proto, duration_format_constructor) =
make_named_pair(string_forge, shape_forge, labels, "DurationFormat");
(
P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())),
number_format_constructor,
number_format_proto,
date_time_format_constructor,
date_time_format_proto,
collator_constructor,
collator_proto,
plural_rules_constructor,
plural_rules_proto,
list_format_constructor,
list_format_proto,
relative_time_format_constructor,
relative_time_format_proto,
display_names_constructor,
display_names_proto,
segmenter_constructor,
segmenter_proto,
locale_constructor,
locale_proto,
duration_format_constructor,
duration_format_proto,
)
} else {
(
current.intl_object.clone(),
current.number_format_constructor.clone(),
current.number_format_proto.clone(),
current.date_time_format_constructor.clone(),
current.date_time_format_proto.clone(),
current.collator_constructor.clone(),
current.collator_proto.clone(),
current.plural_rules_constructor.clone(),
current.plural_rules_proto.clone(),
current.list_format_constructor.clone(),
current.list_format_proto.clone(),
current.relative_time_format_constructor.clone(),
current.relative_time_format_proto.clone(),
current.display_names_constructor.clone(),
current.display_names_proto.clone(),
current.segmenter_constructor.clone(),
current.segmenter_proto.clone(),
current.locale_constructor.clone(),
current.locale_proto.clone(),
current.duration_format_constructor.clone(),
current.duration_format_proto.clone(),
)
};
// 迭代器原型与资源栈原型依赖 Object.prototype(链到其上):object 家族重建时
// 一并重建,否则旧原型链指向已释放的 object_proto。
let (
@@ -623,6 +715,27 @@ impl BuiltinWorld {
custom_event_proto,
custom_event_constructor,
event_target_proto,
intl_object,
number_format_constructor,
number_format_proto,
date_time_format_constructor,
date_time_format_proto,
collator_constructor,
collator_proto,
plural_rules_constructor,
plural_rules_proto,
list_format_constructor,
list_format_proto,
relative_time_format_constructor,
relative_time_format_proto,
display_names_constructor,
display_names_proto,
segmenter_constructor,
segmenter_proto,
locale_constructor,
locale_proto,
duration_format_constructor,
duration_format_proto,
leaked_objects: std::cell::RefCell::new(Vec::new()),
};
wire_builtin_world_links(&world);
+79 -3
View File
@@ -1,5 +1,5 @@
//! 注册表职责:BuiltinWorld 结构(108 固定 P 字段 + stub 族 + Box::into_raw
//! 登记表)、get_by_id 派发、all_p_fields 108 元组枚举(新增 P 字段四处同步
//! 注册表职责:BuiltinWorld 结构(129 固定 P 字段 + stub 族 + Box::into_raw
//! 登记表)、get_by_id 派发、all_p_fields 129 元组枚举(新增 P 字段四处同步
//! 约束载体)与登记表 track/find/inherit/teardown。
use oxide_types::mem::P;
@@ -177,6 +177,40 @@ pub struct BuiltinWorld {
/// `EventTarget.prototype` 槽位:纯内核接线占位(空对象),真实原型
/// 本体由绑定层后续任务填充(EventTarget 无构造器,仅暴露原型)。
pub event_target_proto: P<JsObject>,
/// `Intl` 命名空间对象(非构造器):构造器/原型对与静态方法由绑定层
/// 安装;脏家族位为 `intl`。
pub intl_object: P<JsObject>,
/// `Intl.NumberFormat` 构造器与原型对:经 `make_named_pair` 成对构造,
/// 骨架阶段构造语义(实例化/resolvedOptions)由绑定层 native 填充。
pub number_format_constructor: P<JsObject>,
pub number_format_proto: P<JsObject>,
/// `Intl.DateTimeFormat` 构造器与原型对。
pub date_time_format_constructor: P<JsObject>,
pub date_time_format_proto: P<JsObject>,
/// `Intl.Collator` 构造器与原型对。
pub collator_constructor: P<JsObject>,
pub collator_proto: P<JsObject>,
/// `Intl.PluralRules` 构造器与原型对。
pub plural_rules_constructor: P<JsObject>,
pub plural_rules_proto: P<JsObject>,
/// `Intl.ListFormat` 构造器与原型对。
pub list_format_constructor: P<JsObject>,
pub list_format_proto: P<JsObject>,
/// `Intl.RelativeTimeFormat` 构造器与原型对。
pub relative_time_format_constructor: P<JsObject>,
pub relative_time_format_proto: P<JsObject>,
/// `Intl.DisplayNames` 构造器与原型对。
pub display_names_constructor: P<JsObject>,
pub display_names_proto: P<JsObject>,
/// `Intl.Segmenter` 构造器与原型对。
pub segmenter_constructor: P<JsObject>,
pub segmenter_proto: P<JsObject>,
/// `Intl.Locale` 构造器与原型对。
pub locale_constructor: P<JsObject>,
pub locale_proto: P<JsObject>,
/// `Intl.DurationFormat` 构造器与原型对。
pub duration_format_constructor: P<JsObject>,
pub duration_format_proto: P<JsObject>,
/// 释放登记表(`Box::into_raw` 对象的清单,session 收尾统一释放,非内存泄漏):
/// 绑定层经 `Box::into_raw` 持有的函数/宿主对象(方法 wrapper、访问器、
/// 错误构造器、Reflect/Iterator、内建原型构造器、`$262` 宿主等)。
@@ -407,7 +441,7 @@ impl BuiltinWorld {
/// session 收尾(`teardown_heap_data`)与选择性重建收尾(`retire_replaced`)
/// 的 P 字段枚举唯一入口:`BuiltinWorld` 新增 P 字段须在此同步补一行,否则
/// 收尾时该字段属性区无法释放、重建原型槽改写/释放漏掉该字段。
pub(crate) fn all_p_fields(&self) -> [&P<JsObject>; 108] {
pub(crate) fn all_p_fields(&self) -> [&P<JsObject>; 129] {
[
&self.object_proto,
&self.array_proto,
@@ -517,6 +551,27 @@ impl BuiltinWorld {
&self.custom_event_proto,
&self.custom_event_constructor,
&self.event_target_proto,
&self.intl_object,
&self.number_format_constructor,
&self.number_format_proto,
&self.date_time_format_constructor,
&self.date_time_format_proto,
&self.collator_constructor,
&self.collator_proto,
&self.plural_rules_constructor,
&self.plural_rules_proto,
&self.list_format_constructor,
&self.list_format_proto,
&self.relative_time_format_constructor,
&self.relative_time_format_proto,
&self.display_names_constructor,
&self.display_names_proto,
&self.segmenter_constructor,
&self.segmenter_proto,
&self.locale_constructor,
&self.locale_proto,
&self.duration_format_constructor,
&self.duration_format_proto,
]
}
@@ -663,6 +718,27 @@ impl BuiltinWorld {
BuiltinId::CustomEventProto => &self.custom_event_proto,
BuiltinId::CustomEventCtor => &self.custom_event_constructor,
BuiltinId::EventTargetProto => &self.event_target_proto,
BuiltinId::IntlObject => &self.intl_object,
BuiltinId::NumberFormatConstructor => &self.number_format_constructor,
BuiltinId::NumberFormatProto => &self.number_format_proto,
BuiltinId::DateTimeFormatConstructor => &self.date_time_format_constructor,
BuiltinId::DateTimeFormatProto => &self.date_time_format_proto,
BuiltinId::CollatorConstructor => &self.collator_constructor,
BuiltinId::CollatorProto => &self.collator_proto,
BuiltinId::PluralRulesConstructor => &self.plural_rules_constructor,
BuiltinId::PluralRulesProto => &self.plural_rules_proto,
BuiltinId::ListFormatConstructor => &self.list_format_constructor,
BuiltinId::ListFormatProto => &self.list_format_proto,
BuiltinId::RelativeTimeFormatConstructor => &self.relative_time_format_constructor,
BuiltinId::RelativeTimeFormatProto => &self.relative_time_format_proto,
BuiltinId::DisplayNamesConstructor => &self.display_names_constructor,
BuiltinId::DisplayNamesProto => &self.display_names_proto,
BuiltinId::SegmenterConstructor => &self.segmenter_constructor,
BuiltinId::SegmenterProto => &self.segmenter_proto,
BuiltinId::LocaleConstructor => &self.locale_constructor,
BuiltinId::LocaleProto => &self.locale_proto,
BuiltinId::DurationFormatConstructor => &self.duration_format_constructor,
BuiltinId::DurationFormatProto => &self.duration_format_proto,
}
}
}
+50 -5
View File
@@ -1,4 +1,4 @@
//! 内置对象 id 枚举(`BuiltinId` 98 变体 + `ALL` 顺序钉表)、世代快照
//! 内置对象 id 枚举(`BuiltinId` 119 变体 + `ALL` 顺序钉表)、世代快照
//! (`BuiltinSnapshot`)与按家族划分的脏标记位集(`BuiltinDirtySet`);
//! `NUM_BUILTINS` 文档承载"新增 BuiltinWorld 字段须同步"四处约束注记。
@@ -11,7 +11,7 @@ use crate::builtin::BuiltinWorld;
/// 维护注意:每个新增的 `BuiltinWorld` 对象字段都必须加到这里以及
/// `KernelSession::dirty_since_snapshot()`,以便选择性重置重建正确的
/// builtin 家族。
pub const NUM_BUILTINS: usize = 98;
pub const NUM_BUILTINS: usize = 119;
/// 内置对象枚举 id,与 `BuiltinWorld` 中的存储槽一一对应。
///
@@ -118,6 +118,27 @@ pub enum BuiltinId {
CustomEventProto = 95,
CustomEventCtor = 96,
EventTargetProto = 97,
IntlObject = 98,
NumberFormatConstructor = 99,
NumberFormatProto = 100,
DateTimeFormatConstructor = 101,
DateTimeFormatProto = 102,
CollatorConstructor = 103,
CollatorProto = 104,
PluralRulesConstructor = 105,
PluralRulesProto = 106,
ListFormatConstructor = 107,
ListFormatProto = 108,
RelativeTimeFormatConstructor = 109,
RelativeTimeFormatProto = 110,
DisplayNamesConstructor = 111,
DisplayNamesProto = 112,
SegmenterConstructor = 113,
SegmenterProto = 114,
LocaleConstructor = 115,
LocaleProto = 116,
DurationFormatConstructor = 117,
DurationFormatProto = 118,
}
impl BuiltinId {
@@ -223,6 +244,27 @@ impl BuiltinId {
BuiltinId::CustomEventProto,
BuiltinId::CustomEventCtor,
BuiltinId::EventTargetProto,
BuiltinId::IntlObject,
BuiltinId::NumberFormatConstructor,
BuiltinId::NumberFormatProto,
BuiltinId::DateTimeFormatConstructor,
BuiltinId::DateTimeFormatProto,
BuiltinId::CollatorConstructor,
BuiltinId::CollatorProto,
BuiltinId::PluralRulesConstructor,
BuiltinId::PluralRulesProto,
BuiltinId::ListFormatConstructor,
BuiltinId::ListFormatProto,
BuiltinId::RelativeTimeFormatConstructor,
BuiltinId::RelativeTimeFormatProto,
BuiltinId::DisplayNamesConstructor,
BuiltinId::DisplayNamesProto,
BuiltinId::SegmenterConstructor,
BuiltinId::SegmenterProto,
BuiltinId::LocaleConstructor,
BuiltinId::LocaleProto,
BuiltinId::DurationFormatConstructor,
BuiltinId::DurationFormatProto,
];
}
@@ -301,6 +343,7 @@ pub struct BuiltinDirtySet {
pub message_channel: bool,
pub broadcast_channel: bool,
pub event: bool,
pub intl: bool,
}
impl BuiltinDirtySet {
@@ -337,6 +380,7 @@ impl BuiltinDirtySet {
message_channel: true,
broadcast_channel: true,
event: true,
intl: true,
}
}
@@ -367,6 +411,7 @@ impl BuiltinDirtySet {
|| self.message_channel
|| self.broadcast_channel
|| self.event
|| self.intl
}
/// 是否存在任何污染(builtin world 或 global object)。
@@ -379,13 +424,13 @@ impl BuiltinDirtySet {
mod tests {
use super::*;
/// 槽对齐面:ALL 表与判别值 0..97 严格同序,快照数组随 NUM_BUILTINS
/// 槽对齐面:ALL 表与判别值 0..118 严格同序,快照数组随 NUM_BUILTINS
/// 自动扩维、逐槽对齐。
#[test]
fn builtin_snapshot_all_slots_aligned() {
assert_eq!(NUM_BUILTINS, 98);
assert_eq!(NUM_BUILTINS, 119);
assert_eq!(BuiltinId::ALL.len(), NUM_BUILTINS);
for i in 0..97usize {
for i in 0..118usize {
assert_eq!(BuiltinId::ALL[i] as usize, i);
}
assert_eq!(BuiltinId::ALL[81], BuiltinId::SharedArrayBufferProto);
+21
View File
@@ -209,6 +209,27 @@ impl KernelSession {
|| gen(BuiltinId::CustomEventProto) != snap(BuiltinId::CustomEventProto)
|| gen(BuiltinId::CustomEventCtor) != snap(BuiltinId::CustomEventCtor)
|| gen(BuiltinId::EventTargetProto) != snap(BuiltinId::EventTargetProto),
intl: gen(BuiltinId::IntlObject) != snap(BuiltinId::IntlObject)
|| gen(BuiltinId::NumberFormatConstructor) != snap(BuiltinId::NumberFormatConstructor)
|| gen(BuiltinId::NumberFormatProto) != snap(BuiltinId::NumberFormatProto)
|| gen(BuiltinId::DateTimeFormatConstructor) != snap(BuiltinId::DateTimeFormatConstructor)
|| gen(BuiltinId::DateTimeFormatProto) != snap(BuiltinId::DateTimeFormatProto)
|| gen(BuiltinId::CollatorConstructor) != snap(BuiltinId::CollatorConstructor)
|| gen(BuiltinId::CollatorProto) != snap(BuiltinId::CollatorProto)
|| gen(BuiltinId::PluralRulesConstructor) != snap(BuiltinId::PluralRulesConstructor)
|| gen(BuiltinId::PluralRulesProto) != snap(BuiltinId::PluralRulesProto)
|| gen(BuiltinId::ListFormatConstructor) != snap(BuiltinId::ListFormatConstructor)
|| gen(BuiltinId::ListFormatProto) != snap(BuiltinId::ListFormatProto)
|| gen(BuiltinId::RelativeTimeFormatConstructor) != snap(BuiltinId::RelativeTimeFormatConstructor)
|| gen(BuiltinId::RelativeTimeFormatProto) != snap(BuiltinId::RelativeTimeFormatProto)
|| gen(BuiltinId::DisplayNamesConstructor) != snap(BuiltinId::DisplayNamesConstructor)
|| gen(BuiltinId::DisplayNamesProto) != snap(BuiltinId::DisplayNamesProto)
|| gen(BuiltinId::SegmenterConstructor) != snap(BuiltinId::SegmenterConstructor)
|| gen(BuiltinId::SegmenterProto) != snap(BuiltinId::SegmenterProto)
|| gen(BuiltinId::LocaleConstructor) != snap(BuiltinId::LocaleConstructor)
|| gen(BuiltinId::LocaleProto) != snap(BuiltinId::LocaleProto)
|| gen(BuiltinId::DurationFormatConstructor) != snap(BuiltinId::DurationFormatConstructor)
|| gen(BuiltinId::DurationFormatProto) != snap(BuiltinId::DurationFormatProto),
};
// wrapper 本体被写不落在任何家族位上(写的是 wrapper 自身而非所属 P
// 对象):收缩为全脏,强制重建全部家族与 global,使被写的可复用