docs: 内建绑定连线组注释改写与断链修复

This commit is contained in:
2026-09-17 03:47:41 +00:00
parent d474ef6b46
commit 2d48a7e253
4 changed files with 59 additions and 20 deletions
+7 -7
View File
@@ -1,5 +1,5 @@
//! 方法安装职责:绑定层经公开入口调用的 native 方法 wrapper 工厂与五个家族的
//! bind_*_methods;选择性重建复用键(FnWrapperKey)命中前轮旧 wrapper 时只迁移槽位。
//! bind_*_methods;选择性重建复用键(FnWrapperKey)命中旧 wrapper 时只迁移槽位。
use oxide_types::mem::P;
use oxide_types::object::{JsObject, NativeFnPtr, PropAttributes};
@@ -375,9 +375,9 @@ impl BuiltinWorld {
native_fn_ptr: NativeFnPtr, arg_count: u8, world: &BuiltinWorld, label: u32,
) -> Result<(), String> {
let si = string_forge.intern(method_name).0;
// 选择性重建复用:同键前轮旧 wrapper 迁移到新 proto 槽位——其 proto 槽
// 已由重建收尾重指(或 Function 家族保留而不变),length/name 属性区
// 随对象保留,不再新建对象、登记表跨轮不增长。
// 选择性重建复用:同键旧 wrapper 迁移到新 proto 槽位——其 proto 槽
// 已由重建收尾改写到新指针(或 Function 家族保留而不变),length/name
// 属性区随对象保留,不再新建对象、登记表跨重建不增长。
let reuse_key = FnWrapperKey::new(world.wrapper_family_of(proto as *const JsObject), label, key, si);
let wrapper_ptr = match world.find_fn_wrapper(reuse_key, native_fn_ptr, arg_count) {
Some(ptr) => ptr,
@@ -397,15 +397,15 @@ impl BuiltinWorld {
// 的调用方,均使用函数项表达式)。
wrapper.set_native_fn(Some(native_fn_ptr));
wrapper.set_native_arg_count(arg_count);
// 设置 .length (ES spec: Function.length = formal parameter count,
// {[[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true})
// 设置 .length(JS 规范:值为形式参数个数,
// writable:false, enumerable:false, configurable:true)。
let si_length = string_forge.intern("length").0;
let length_shape = shape_forge.make_shape(wrapper.shape_id(), si_length);
wrapper.set_shape_id(length_shape);
wrapper.ensure_hash_props().push(JsValue::int(arg_count as i32));
let length_pos = wrapper.hash_props_vec().map_or(0, |v| v.len() as u32).saturating_sub(1);
wrapper.set_data_meta(length_pos, oxide_types::object::PropAttributes::new(false, false, true));
// 设置 .name ({[[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true})
// 设置 .name(writable:false, enumerable:false, configurable:true)。
let si_name = string_forge.intern("name").0;
let name_shape = shape_forge.make_shape(wrapper.shape_id(), si_name);
wrapper.set_shape_id(name_shape);
+34 -8
View File
@@ -20,7 +20,7 @@ fn make_pair(
si_name: u32,
) -> (P<JsObject>, P<JsObject>) {
intern_label(string_forge, name);
let name_si = string_forge.intern(name).0; // 同时 intern 构造器名作为属性值
let name_si = string_forge.intern(name).0;
let mut proto = JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null());
let mut ctor = JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null());
@@ -34,9 +34,9 @@ fn make_pair(
ctor.set_function(true);
// 预分配槽位:proto[0]="constructor"、ctor[0]="prototype"、ctor[1]="name"。
proto.ensure_hash_props().push(JsValue::undefined()); // 占位
ctor.ensure_hash_props().push(JsValue::undefined()); // "prototype" 占位
// 立即写入实际 name 值(ctor vec[1])。
proto.ensure_hash_props().push(JsValue::undefined());
ctor.ensure_hash_props().push(JsValue::undefined());
// 立即写入实际 name 值(ctor vec[1])。
ctor.ensure_hash_props()
.push(JsValue::perm_string(string_forge.string_ptr(name_si)));
// 属性元数据:.prototype(ctor[0])= writable:false, enumerable:false, configurable:false。
@@ -232,6 +232,30 @@ fn set_proto_if_changed(obj: &P<JsObject>, proto: JsValue) {
}
}
/// 建立全部内置对象的原型链连线:构造器/原型对互指与各原型的
/// `[[Prototype]]` 赋值。
///
/// # 步骤
/// 1. 35 组构造器/原型对互指(`.prototype` / `.constructor` 槽,含
/// TypedArray 家族共享对),经 `wire_ctor_proto` 覆盖占位槽;
/// 2. 23 个非 TypedArray 构造器的 `[[Prototype]]` → Function.prototype
/// (标准内置函数对象均继承 Function.prototype);
/// 3. 25 个非 Object 原型的 `[[Prototype]]` → Object.prototype,另含
/// Temporal 命名空间对象、Temporal.now 与 Console 单例;
/// 4. %IteratorPrototype% → Object.prototype,6 个集合迭代器原型
/// → %IteratorPrototype%;
/// 5. TypedArray 家族:11 个具体原型 → %TypedArray% 共享原型,11 个具体
/// 构造器 → %TypedArray% 抽象构造器,抽象构造器 `[[Prototype]]`
/// → Function.prototype。
///
/// # 边界与前提
/// - 在 `BuiltinWorld::new` 全量构造末尾与选择性重建(`rebuild_with_dirty`)
/// 构造出新 world 后调用,各对对象均已构造完毕,本函数只填槽不改形状;
/// - `set_proto_if_changed` 仅当槽值不同才改写,重复调用幂等。
///
/// # 副作用
/// - 改写上述对象的 `.prototype` / `.constructor` 槽值与 `[[Prototype]]`
/// 槽,每次 `[[Prototype]]` 改写递增该对象 generation。
pub(crate) fn wire_builtin_world_links(world: &BuiltinWorld) {
wire_ctor_proto(&world.object_constructor, &world.object_proto);
wire_ctor_proto(&world.array_constructor, &world.array_proto);
@@ -268,8 +292,8 @@ pub(crate) fn wire_builtin_world_links(world: &BuiltinWorld) {
wire_ctor_proto(&world.plain_year_month_constructor, &world.plain_year_month_proto);
wire_ctor_proto(&world.bigint_constructor, &world.bigint_proto);
// 所有内置构造器的 [[Prototype]] 指向 %FunctionPrototype%(ECMA-262 §17:
// 标准内置函数对象均继承 Function.prototype;此前仅 TypedArray 构造器设置过)。
// 非 TypedArray 构造器的 [[Prototype]] 指向 Function.prototype:
// 标准内置函数对象均继承 Function.prototype。
let fn_proto_val = world.fn_proto_val();
for ctor in [
&world.object_constructor,
@@ -339,7 +363,8 @@ pub(crate) fn wire_builtin_world_links(world: &BuiltinWorld) {
set_proto_if_changed(&world.console_object, obj_proto_val);
// 迭代器原型链:%IteratorPrototype% → Object.prototype;各集合迭代器原型
// → %IteratorPrototype%(next/@@iterator 方法由绑定层安装到对应原型)。
// → %IteratorPrototype%(next/@@iterator 方法由绑定层——oxide_builtins
// 中安装方法 wrapper 的代码——安装到对应原型)。
set_proto_if_changed(&world.iterator_proto, obj_proto_val);
let iterator_proto_val = JsValue::from_js_object(world.iterator_proto.as_ptr() as *mut JsObject);
let iterator_protos: [&P<JsObject>; 6] = [
@@ -460,7 +485,8 @@ impl BuiltinWorld {
let stub_objects = Vec::new();
// 迭代器原型家族:链关系(→ %IteratorPrototype% → Object.prototype)在
// wire_builtin_world_links 中建立,next/@@iterator 方法由绑定层安装。
// wire_builtin_world_links 中建立,next/@@iterator 方法由绑定层
// (oxide_builtins 中安装方法 wrapper 的代码)安装。
let iterator_proto = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null()));
let array_iterator_proto = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null()));
let map_iterator_proto = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null()));
+5 -5
View File
@@ -1,6 +1,6 @@
//! 内置对象方法的 native 函数指针表:由绑定层填充后交给 BuiltinWorld 的 bind 方法安装到构造器/原型上。
/// Object 静态方法与原型方法的 native 函数指针集合,由 builtin 绑定层填充后交给
/// [`BuiltinWorld::bind_object_methods`] 安装到对象/原型上。
/// [crate::builtin::BuiltinWorld::bind_object_methods] 安装到对象/原型上。
pub struct ObjectMethods {
pub keys: *const (),
pub create: *const (),
@@ -27,7 +27,7 @@ pub struct ObjectMethods {
pub group_by: *const (),
}
/// Array 静态方法与原型方法的 native 函数指针集合,由 [`BuiltinWorld::bind_array_methods`] 安装。
/// Array 静态方法与原型方法的 native 函数指针集合,由 [crate::builtin::BuiltinWorld::bind_array_methods] 安装。
pub struct ArrayMethods {
pub is_array: *const (),
pub from: *const (),
@@ -70,7 +70,7 @@ pub struct ArrayMethods {
pub with_method: *const (),
}
/// Error 家族(含各子类型)构造器与原型方法的 native 函数指针集合,由 [`BuiltinWorld::bind_error_methods`] 安装。
/// Error 家族(含各子类型)构造器与原型方法的 native 函数指针集合,由 [crate::builtin::BuiltinWorld::bind_error_methods] 安装。
pub struct ErrorMethods {
pub error: *const (),
pub type_error: *const (),
@@ -84,7 +84,7 @@ pub struct ErrorMethods {
pub stack: *const (),
}
/// String 静态方法与原型方法的 native 函数指针集合,由 [`BuiltinWorld::bind_string_methods`] 安装。
/// String 静态方法与原型方法的 native 函数指针集合,由 [crate::builtin::BuiltinWorld::bind_string_methods] 安装。
pub struct StringMethods {
pub from_char_code: *const (),
pub index_of: *const (),
@@ -129,7 +129,7 @@ pub struct RegExpMethods {
pub to_string: *const (),
}
/// Function 原型方法的 native 函数指针集合,由 [`BuiltinWorld::bind_function_methods`] 安装。
/// Function 原型方法的 native 函数指针集合,由 [crate::builtin::BuiltinWorld::bind_function_methods] 安装。
pub struct FunctionMethods {
pub call: *const (),
pub apply: *const (),
+13
View File
@@ -9,6 +9,13 @@ mod world;
pub use methods::{ArrayMethods, ErrorMethods, FunctionMethods, ObjectMethods, RegExpMethods, StringMethods};
pub use world::{BuiltinWorld, FnWrapperKey};
/// 把一个 native 方法绑定到目标对象:构造(或复用)wrapper 函数对象,以
/// `$name` 为属性名写入目标对象的命名属性区。
///
/// `$world` 是 wrapper 归属的 `BuiltinWorld`(wrapper 原型取自它的
/// Function.prototype,本体登记进它的释放登记表,选择性重建时按键复用);
/// `$sf` / `$sh` 为字符串 / 形状 interner;`$nargs` 是 native 函数形式参数
/// 个数,写入 wrapper 的 `length` 属性。
#[macro_export]
macro_rules! bind_method {
($world:expr, $target:expr, $sf:expr, $sh:expr, $name:literal, $func:expr, $nargs:expr) => {{
@@ -19,6 +26,8 @@ macro_rules! bind_method {
}};
}
/// 批量绑定一组 native 方法,条目形如 `(名称, 函数指针, 参数个数)`;
/// 逐条展开为 `bind_method!`。
#[macro_export]
macro_rules! bind_methods {
($world:expr, $target:expr, $sf:expr, $sh:expr,
@@ -27,6 +36,10 @@ macro_rules! bind_methods {
};
}
/// `bind_methods!` 的静态版本:初始化阶段调用,显式传入 `$world`(宏展开到
/// `BuiltinWorld::bind_method_static` / `bind_method_labeled_static`)。
/// 第二形态多一个 `$label`(绑定站点标签):非 P 目标上同名方法槽
/// (Generator / AsyncGenerator 原型的 next / return / throw)靠它区分。
#[macro_export]
macro_rules! bind_methods_static {
($target:expr, $sf:expr, $sh:expr, $world:expr,