From 2d48a7e253590e2f4fc5c136a46a523111a997b6 Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Thu, 17 Sep 2026 03:47:41 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20=E5=86=85=E5=BB=BA=E7=BB=91=E5=AE=9A?= =?UTF-8?q?=E8=BF=9E=E7=BA=BF=E7=BB=84=E6=B3=A8=E9=87=8A=E6=94=B9=E5=86=99?= =?UTF-8?q?=E4=B8=8E=E6=96=AD=E9=93=BE=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_kernel/src/builtin/bind.rs | 14 +++---- crates/oxide_kernel/src/builtin/construct.rs | 42 ++++++++++++++++---- crates/oxide_kernel/src/builtin/methods.rs | 10 ++--- crates/oxide_kernel/src/builtin/mod.rs | 13 ++++++ 4 files changed, 59 insertions(+), 20 deletions(-) diff --git a/crates/oxide_kernel/src/builtin/bind.rs b/crates/oxide_kernel/src/builtin/bind.rs index c249dc9e..abff51b9 100644 --- a/crates/oxide_kernel/src/builtin/bind.rs +++ b/crates/oxide_kernel/src/builtin/bind.rs @@ -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); diff --git a/crates/oxide_kernel/src/builtin/construct.rs b/crates/oxide_kernel/src/builtin/construct.rs index 401caadf..f1326a10 100644 --- a/crates/oxide_kernel/src/builtin/construct.rs +++ b/crates/oxide_kernel/src/builtin/construct.rs @@ -20,7 +20,7 @@ fn make_pair( si_name: u32, ) -> (P, P) { 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, 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; 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())); diff --git a/crates/oxide_kernel/src/builtin/methods.rs b/crates/oxide_kernel/src/builtin/methods.rs index 6a129c0d..1ad04d78 100644 --- a/crates/oxide_kernel/src/builtin/methods.rs +++ b/crates/oxide_kernel/src/builtin/methods.rs @@ -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 (), diff --git a/crates/oxide_kernel/src/builtin/mod.rs b/crates/oxide_kernel/src/builtin/mod.rs index e2a9f071..d47ac349 100644 --- a/crates/oxide_kernel/src/builtin/mod.rs +++ b/crates/oxide_kernel/src/builtin/mod.rs @@ -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,