From f08e35c5f22d2ad6dd14be52244d11210b4ccd16 Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Wed, 16 Sep 2026 02:36:06 +0000 Subject: [PATCH] =?UTF-8?q?refactor:=20builtin=20=E5=AE=9E=E4=BE=8B?= =?UTF-8?q?=E5=8C=96=E6=AE=B5=E6=8B=86=E5=87=BA=E7=8B=AC=E7=AB=8B=20constr?= =?UTF-8?q?uct=20=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_kernel/src/builtin/construct.rs | 589 +++++++++++++++++++ crates/oxide_kernel/src/builtin/mod.rs | 582 +----------------- crates/oxide_kernel/src/builtin/rebuild.rs | 5 +- 3 files changed, 595 insertions(+), 581 deletions(-) create mode 100644 crates/oxide_kernel/src/builtin/construct.rs diff --git a/crates/oxide_kernel/src/builtin/construct.rs b/crates/oxide_kernel/src/builtin/construct.rs new file mode 100644 index 00000000..401caadf --- /dev/null +++ b/crates/oxide_kernel/src/builtin/construct.rs @@ -0,0 +1,589 @@ +//! 实例化职责:空槽构造原型/构造器对、Error 子类型、TypedArray 家族与全局 +//! 单例对象,并建立原型链链接(wire_ctor_proto / set_proto_if_changed / +//! wire_builtin_world_links)。 + +use oxide_types::mem::P; +use oxide_types::object::{JsObject, PropAttributes}; +use oxide_types::value::JsValue; + +use super::BuiltinWorld; +use crate::kernel_info; +use crate::shape_forge::{ShapeForge, EMPTY_SHAPE_ID}; +use crate::string_forge::PermInterner; + +fn intern_label(string_forge: &PermInterner, label: &str) -> u32 { + string_forge.intern(label).0 +} + +fn make_pair( + string_forge: &PermInterner, shape_forge: &ShapeForge, name: &str, si_prototype: u32, si_constructor: u32, + si_name: u32, +) -> (P, P) { + intern_label(string_forge, name); + let name_si = string_forge.intern(name).0; // 同时 intern 构造器名作为属性值 + + let mut proto = JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null()); + let mut ctor = JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null()); + + let proto_shape = shape_forge.make_shape(EMPTY_SHAPE_ID, si_constructor); + proto.set_shape_id(proto_shape); + + let ctor_shape1 = shape_forge.make_shape(EMPTY_SHAPE_ID, si_prototype); + let ctor_shape2 = shape_forge.make_shape(ctor_shape1, si_name); + ctor.set_shape_id(ctor_shape2); + 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])。 + ctor.ensure_hash_props() + .push(JsValue::perm_string(string_forge.string_ptr(name_si))); + // 属性元数据:.prototype(ctor[0])= writable:false, enumerable:false, configurable:false。 + ctor.set_data_meta(0u32, oxide_types::object::PropAttributes::new(false, false, false)); + // .name(ctor[1])= writable:false, enumerable:false, configurable:true。 + ctor.set_data_meta(1u32, oxide_types::object::PropAttributes::new(false, false, true)); + // .constructor(proto[0])= writable:true, enumerable:false, configurable:true。 + // (JS 规范:prototype.constructor 非枚举,避免泄漏进 for-in。) + proto.set_data_meta(0u32, oxide_types::object::PropAttributes::new(true, false, true)); + + (P::new(proto), P::new(ctor)) +} + +#[derive(Clone, Copy)] +pub(crate) struct BuiltinLabels { + prototype: u32, + constructor: u32, + name: u32, +} + +pub(crate) fn builtin_labels(string_forge: &PermInterner) -> BuiltinLabels { + let labels = BuiltinLabels { + prototype: intern_label(string_forge, "prototype"), + constructor: intern_label(string_forge, "constructor"), + name: intern_label(string_forge, "name"), + }; + intern_label(string_forge, "length"); + intern_label(string_forge, "toString"); + intern_label(string_forge, "valueOf"); + labels +} + +pub(crate) fn make_named_pair( + string_forge: &PermInterner, shape_forge: &ShapeForge, labels: BuiltinLabels, name: &str, +) -> (P, P) { + make_pair(string_forge, shape_forge, name, labels.prototype, labels.constructor, labels.name) +} + +pub(crate) fn make_error_subtypes(error_proto: &P) -> ErrorSubtypeProtos { + let error_proto_val = JsValue::from_js_object(error_proto.as_ptr() as *mut JsObject); + ErrorSubtypeProtos { + type_error_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, error_proto_val)), + reference_error_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, error_proto_val)), + range_error_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, error_proto_val)), + syntax_error_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, error_proto_val)), + uri_error_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, error_proto_val)), + eval_error_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, error_proto_val)), + suppressed_error_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, error_proto_val)), + } +} + +pub(crate) struct ErrorSubtypeProtos { + pub(crate) type_error_proto: P, + pub(crate) reference_error_proto: P, + pub(crate) range_error_proto: P, + pub(crate) syntax_error_proto: P, + pub(crate) uri_error_proto: P, + pub(crate) eval_error_proto: P, + pub(crate) suppressed_error_proto: P, +} + +pub(crate) struct TypedArrayFamily { + pub(crate) typed_array_constructor: P, + pub(crate) typed_array_proto: P, + pub(crate) int8array_constructor: P, + pub(crate) int8array_proto: P, + pub(crate) uint8array_constructor: P, + pub(crate) uint8array_proto: P, + pub(crate) uint8clampedarray_constructor: P, + pub(crate) uint8clampedarray_proto: P, + pub(crate) int16array_constructor: P, + pub(crate) int16array_proto: P, + pub(crate) uint16array_constructor: P, + pub(crate) uint16array_proto: P, + pub(crate) int32array_constructor: P, + pub(crate) int32array_proto: P, + pub(crate) uint32array_constructor: P, + pub(crate) uint32array_proto: P, + pub(crate) float32array_constructor: P, + pub(crate) float32array_proto: P, + pub(crate) float64array_constructor: P, + pub(crate) float64array_proto: P, + pub(crate) bigint64array_constructor: P, + pub(crate) bigint64array_proto: P, + pub(crate) biguint64array_constructor: P, + pub(crate) biguint64array_proto: P, +} + +/// 建 `%TypedArray%` 抽象构造器对象:name=`TypedArray`、`prototype` 指向共享原型, +/// 实际 native 实现由绑定层配置为恒抛 TypeError(不可 new 也不可调用)。 +fn make_typed_array_abstract_ctor( + string_forge: &PermInterner, shape_forge: &ShapeForge, labels: BuiltinLabels, typed_array_proto: &P, +) -> P { + let name_si = string_forge.intern("TypedArray").0; + let mut ctor = JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null()); + let ctor_shape1 = shape_forge.make_shape(EMPTY_SHAPE_ID, labels.prototype); + let ctor_shape2 = shape_forge.make_shape(ctor_shape1, labels.name); + ctor.set_shape_id(ctor_shape2); + ctor.set_function(true); + ctor.ensure_hash_props() + .push(JsValue::from_js_object(typed_array_proto.as_ptr() as *mut JsObject)); + ctor.ensure_hash_props() + .push(JsValue::perm_string(string_forge.string_ptr(name_si))); + // .prototype 不可写不可枚举不可配置;.name 不可写不可枚举可配置。 + ctor.set_data_meta(0, PropAttributes::new(false, false, false)); + ctor.set_data_meta(1, PropAttributes::new(false, false, true)); + P::new(ctor) +} + +pub(crate) fn make_typed_array_family( + string_forge: &PermInterner, shape_forge: &ShapeForge, labels: BuiltinLabels, object_proto: &P, +) -> TypedArrayFamily { + let obj_proto_val = JsValue::from_js_object(object_proto.as_ptr() as *mut JsObject); + // 给共享原型开 "constructor" 槽位(占位值在 wire 时填抽象构造器)。 + let mut typed_array_proto_obj = JsObject::new_empty(EMPTY_SHAPE_ID, obj_proto_val); + let ctor_si = labels.constructor; + let proto_shape = shape_forge.make_shape(typed_array_proto_obj.shape_id(), ctor_si); + typed_array_proto_obj.set_shape_id(proto_shape); + typed_array_proto_obj.ensure_hash_props().push(JsValue::undefined()); + typed_array_proto_obj.set_data_meta(0, PropAttributes::new(true, false, true)); + let typed_array_proto = P::new(typed_array_proto_obj); + let typed_array_constructor = make_typed_array_abstract_ctor(string_forge, shape_forge, labels, &typed_array_proto); + let (int8array_proto, int8array_constructor) = make_named_pair(string_forge, shape_forge, labels, "Int8Array"); + let (uint8array_proto, uint8array_constructor) = make_named_pair(string_forge, shape_forge, labels, "Uint8Array"); + let (uint8clampedarray_proto, uint8clampedarray_constructor) = + make_named_pair(string_forge, shape_forge, labels, "Uint8ClampedArray"); + let (int16array_proto, int16array_constructor) = make_named_pair(string_forge, shape_forge, labels, "Int16Array"); + let (uint16array_proto, uint16array_constructor) = + make_named_pair(string_forge, shape_forge, labels, "Uint16Array"); + let (int32array_proto, int32array_constructor) = make_named_pair(string_forge, shape_forge, labels, "Int32Array"); + let (uint32array_proto, uint32array_constructor) = + make_named_pair(string_forge, shape_forge, labels, "Uint32Array"); + let (float32array_proto, float32array_constructor) = + make_named_pair(string_forge, shape_forge, labels, "Float32Array"); + let (float64array_proto, float64array_constructor) = + make_named_pair(string_forge, shape_forge, labels, "Float64Array"); + let (bigint64array_proto, bigint64array_constructor) = + make_named_pair(string_forge, shape_forge, labels, "BigInt64Array"); + let (biguint64array_proto, biguint64array_constructor) = + make_named_pair(string_forge, shape_forge, labels, "BigUint64Array"); + + TypedArrayFamily { + typed_array_constructor, + typed_array_proto, + int8array_constructor, + int8array_proto, + uint8array_constructor, + uint8array_proto, + uint8clampedarray_constructor, + uint8clampedarray_proto, + int16array_constructor, + int16array_proto, + uint16array_constructor, + uint16array_proto, + int32array_constructor, + int32array_proto, + uint32array_constructor, + uint32array_proto, + float32array_constructor, + float32array_proto, + float64array_constructor, + float64array_proto, + bigint64array_constructor, + bigint64array_proto, + biguint64array_constructor, + biguint64array_proto, + } +} + +/// 用真实值覆盖(`make_pair` 设置的)占位槽。 +/// ctor.vec[0] = constructor.prototype → proto。 +/// proto.vec[0] = proto.constructor → ctor。 +fn wire_ctor_proto(ctor: &P, proto: &P) { + let ctor_ptr = ctor.as_ptr() as *mut JsObject; + let ctor = unsafe { &mut *ctor_ptr }; + let vec = ctor.ensure_hash_props(); + if !vec.is_empty() { + vec[0] = JsValue::from_js_object(proto.as_ptr() as *mut JsObject); + } + let proto_ptr = proto.as_ptr() as *mut JsObject; + let proto = unsafe { &mut *proto_ptr }; + let pvec = proto.ensure_hash_props(); + if !pvec.is_empty() { + pvec[0] = JsValue::from_js_object(ctor_ptr); + } +} + +fn set_proto_if_changed(obj: &P, proto: JsValue) { + let ptr = obj.as_ptr() as *mut JsObject; + let obj = unsafe { &mut *ptr }; + if obj.proto() != proto { + obj.set_proto(proto).ok(); + } +} + +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); + wire_ctor_proto(&world.function_constructor, &world.function_proto); + wire_ctor_proto(&world.string_constructor, &world.string_proto); + wire_ctor_proto(&world.number_constructor, &world.number_proto); + wire_ctor_proto(&world.boolean_constructor, &world.boolean_proto); + wire_ctor_proto(&world.error_constructor, &world.error_proto); + wire_ctor_proto(&world.symbol_constructor, &world.symbol_proto); + wire_ctor_proto(&world.date_constructor, &world.date_proto); + wire_ctor_proto(&world.set_constructor, &world.set_proto); + wire_ctor_proto(&world.map_constructor, &world.map_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.data_view_constructor, &world.data_view_proto); + wire_ctor_proto(&world.int8array_constructor, &world.int8array_proto); + wire_ctor_proto(&world.uint8array_constructor, &world.uint8array_proto); + wire_ctor_proto(&world.uint8clampedarray_constructor, &world.uint8clampedarray_proto); + wire_ctor_proto(&world.int16array_constructor, &world.int16array_proto); + wire_ctor_proto(&world.uint16array_constructor, &world.uint16array_proto); + wire_ctor_proto(&world.int32array_constructor, &world.int32array_proto); + wire_ctor_proto(&world.uint32array_constructor, &world.uint32array_proto); + wire_ctor_proto(&world.float32array_constructor, &world.float32array_proto); + wire_ctor_proto(&world.float64array_constructor, &world.float64array_proto); + wire_ctor_proto(&world.bigint64array_constructor, &world.bigint64array_proto); + wire_ctor_proto(&world.biguint64array_constructor, &world.biguint64array_proto); + wire_ctor_proto(&world.instant_constructor, &world.instant_proto); + wire_ctor_proto(&world.plain_date_constructor, &world.plain_date_proto); + wire_ctor_proto(&world.plain_time_constructor, &world.plain_time_proto); + wire_ctor_proto(&world.duration_constructor, &world.duration_proto); + wire_ctor_proto(&world.zoned_date_time_constructor, &world.zoned_date_time_proto); + wire_ctor_proto(&world.plain_date_time_constructor, &world.plain_date_time_proto); + 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); + + // 所有内置构造器的 [[Prototype]] 指向 %FunctionPrototype%(ECMA-262 §17: + // 标准内置函数对象均继承 Function.prototype;此前仅 TypedArray 构造器设置过)。 + let fn_proto_val = world.fn_proto_val(); + for ctor in [ + &world.object_constructor, + &world.array_constructor, + &world.function_constructor, + &world.string_constructor, + &world.number_constructor, + &world.boolean_constructor, + &world.error_constructor, + &world.symbol_constructor, + &world.date_constructor, + &world.set_constructor, + &world.map_constructor, + &world.regexp_constructor, + &world.array_buffer_constructor, + &world.data_view_constructor, + &world.bigint_constructor, + &world.instant_constructor, + &world.plain_date_constructor, + &world.plain_time_constructor, + &world.duration_constructor, + &world.zoned_date_time_constructor, + &world.plain_date_time_constructor, + &world.plain_month_day_constructor, + &world.plain_year_month_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; 25] = [ + &world.array_proto, + &world.function_proto, + &world.string_proto, + &world.number_proto, + &world.boolean_proto, + &world.error_proto, + &world.symbol_proto, + &world.date_proto, + &world.set_proto, + &world.map_proto, + &world.regexp_proto, + &world.array_buffer_proto, + &world.data_view_proto, + &world.typed_array_proto, + &world.instant_proto, + &world.plain_date_proto, + &world.plain_time_proto, + &world.duration_proto, + &world.zoned_date_time_proto, + &world.plain_date_time_proto, + &world.plain_month_day_proto, + &world.plain_year_month_proto, + &world.bigint_proto, + &world.disposable_stack_proto, + &world.async_disposable_stack_proto, + ]; + for proto in &non_object_protos { + set_proto_if_changed(proto, obj_proto_val); + } + + // Temporal 命名空间对象(非构造器)继承 Object.prototype。 + set_proto_if_changed(&world.temporal_object, obj_proto_val); + set_proto_if_changed(&world.temporal_now_object, obj_proto_val); + + // Console 对象(单例命名空间)继承 Object.prototype。 + set_proto_if_changed(&world.console_object, obj_proto_val); + + // 迭代器原型链:%IteratorPrototype% → Object.prototype;各集合迭代器原型 + // → %IteratorPrototype%(next/@@iterator 方法由绑定层安装到对应原型)。 + 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] = [ + &world.array_iterator_proto, + &world.map_iterator_proto, + &world.set_iterator_proto, + &world.string_iterator_proto, + &world.regexp_string_iterator_proto, + &world.iterator_helper_proto, + ]; + for proto in &iterator_protos { + set_proto_if_changed(proto, iterator_proto_val); + } + + let typed_array_proto_val = JsValue::from_js_object(world.typed_array_proto.as_ptr() as *mut JsObject); + let typed_array_protos: [&P; 11] = [ + &world.int8array_proto, + &world.uint8array_proto, + &world.uint8clampedarray_proto, + &world.int16array_proto, + &world.uint16array_proto, + &world.int32array_proto, + &world.uint32array_proto, + &world.float32array_proto, + &world.float64array_proto, + &world.bigint64array_proto, + &world.biguint64array_proto, + ]; + for proto in &typed_array_protos { + set_proto_if_changed(proto, typed_array_proto_val); + } + + // 共享原型与抽象构造器互指(prototype/constructor);11 个具体构造器的 + // [[Prototype]] 指向 `%TypedArray%`,抽象构造器自身 [[Prototype]] 为 Function.prototype。 + wire_ctor_proto(&world.typed_array_constructor, &world.typed_array_proto); + set_proto_if_changed(&world.typed_array_constructor, world.fn_proto_val()); + let typed_array_ctor_val = JsValue::from_js_object(world.typed_array_constructor.as_ptr() as *mut JsObject); + let typed_array_ctors: [&P; 11] = [ + &world.int8array_constructor, + &world.uint8array_constructor, + &world.uint8clampedarray_constructor, + &world.int16array_constructor, + &world.uint16array_constructor, + &world.int32array_constructor, + &world.uint32array_constructor, + &world.float32array_constructor, + &world.float64array_constructor, + &world.bigint64array_constructor, + &world.biguint64array_constructor, + ]; + for ctor in &typed_array_ctors { + set_proto_if_changed(ctor, typed_array_ctor_val); + } +} + +impl BuiltinWorld { + /// 全量构造一个全新的 builtin world:创建所有原型/构造器对、Error 子类型、 + /// TypedArray 家族与 well-known symbol 对象,并建立原型链链接。 + pub fn new(string_forge: &PermInterner, shape_forge: &ShapeForge) -> Self { + let labels = builtin_labels(string_forge); + + let (object_proto, object_constructor) = make_named_pair(string_forge, shape_forge, labels, "Object"); + let (array_proto, array_constructor) = make_named_pair(string_forge, shape_forge, labels, "Array"); + let (function_proto, function_constructor) = make_named_pair(string_forge, shape_forge, labels, "Function"); + let (string_proto, string_constructor) = make_named_pair(string_forge, shape_forge, labels, "String"); + let (number_proto, number_constructor) = make_named_pair(string_forge, shape_forge, labels, "Number"); + let (boolean_proto, boolean_constructor) = make_named_pair(string_forge, shape_forge, labels, "Boolean"); + let (error_proto, error_constructor) = make_named_pair(string_forge, shape_forge, labels, "Error"); + let (symbol_proto, symbol_constructor) = make_named_pair(string_forge, shape_forge, labels, "Symbol"); + + let error_subtypes = make_error_subtypes(&error_proto); + + let math_object = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + + let json_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"); + let (set_proto, set_constructor) = make_named_pair(string_forge, shape_forge, labels, "Set"); + let (map_proto, map_constructor) = make_named_pair(string_forge, shape_forge, labels, "Map"); + let (regexp_proto, regexp_constructor) = make_named_pair(string_forge, shape_forge, labels, "RegExp"); + let (array_buffer_proto, array_buffer_constructor) = + make_named_pair(string_forge, shape_forge, labels, "ArrayBuffer"); + 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 sym_match = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let sym_replace = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let sym_search = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let sym_split = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let sym_iterator = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let sym_to_primitive = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let sym_has_instance = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let sym_match_all = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let sym_async_iterator = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let sym_to_string_tag = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let sym_species = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let sym_async_dispose = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let sym_dispose = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let temporal_object = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let temporal_now_object = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let (instant_proto, instant_constructor) = make_named_pair(string_forge, shape_forge, labels, "Instant"); + let (plain_date_proto, plain_date_constructor) = + make_named_pair(string_forge, shape_forge, labels, "PlainDate"); + let (plain_time_proto, plain_time_constructor) = + make_named_pair(string_forge, shape_forge, labels, "PlainTime"); + let (duration_proto, duration_constructor) = make_named_pair(string_forge, shape_forge, labels, "Duration"); + let (zoned_date_time_proto, zoned_date_time_constructor) = + make_named_pair(string_forge, shape_forge, labels, "ZonedDateTime"); + let (plain_date_time_proto, plain_date_time_constructor) = + make_named_pair(string_forge, shape_forge, labels, "PlainDateTime"); + let (plain_month_day_proto, plain_month_day_constructor) = + make_named_pair(string_forge, shape_forge, labels, "PlainMonthDay"); + let (plain_year_month_proto, plain_year_month_constructor) = + make_named_pair(string_forge, shape_forge, labels, "PlainYearMonth"); + let (bigint_proto, bigint_constructor) = make_named_pair(string_forge, shape_forge, labels, "BigInt"); + let stub_objects = Vec::new(); + + // 迭代器原型家族:链关系(→ %IteratorPrototype% → Object.prototype)在 + // wire_builtin_world_links 中建立,next/@@iterator 方法由绑定层安装。 + 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())); + let set_iterator_proto = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let string_iterator_proto = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let regexp_string_iterator_proto = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let iterator_helper_proto = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let disposable_stack_proto = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let async_disposable_stack_proto = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + // 默认迭代器指针初值空(绑定层随后经 bind_string 捕获写入)。 + let string_default_iterator = std::cell::Cell::new(std::ptr::null()); + + let world = Self { + object_proto, + string_default_iterator, + array_proto, + function_proto, + string_proto, + number_proto, + boolean_proto, + error_proto, + symbol_proto, + object_constructor, + array_constructor, + function_constructor, + string_constructor, + number_constructor, + boolean_constructor, + error_constructor, + symbol_constructor, + type_error_proto: error_subtypes.type_error_proto, + reference_error_proto: error_subtypes.reference_error_proto, + range_error_proto: error_subtypes.range_error_proto, + syntax_error_proto: error_subtypes.syntax_error_proto, + uri_error_proto: error_subtypes.uri_error_proto, + eval_error_proto: error_subtypes.eval_error_proto, + suppressed_error_proto: error_subtypes.suppressed_error_proto, + math_object, + json_object, + date_constructor, + date_proto, + set_constructor, + set_proto, + map_constructor, + map_proto, + regexp_constructor, + regexp_proto, + array_buffer_constructor, + array_buffer_proto, + data_view_constructor, + data_view_proto, + typed_array_proto: typed_arrays.typed_array_proto, + typed_array_constructor: typed_arrays.typed_array_constructor, + int8array_constructor: typed_arrays.int8array_constructor, + int8array_proto: typed_arrays.int8array_proto, + uint8array_constructor: typed_arrays.uint8array_constructor, + uint8array_proto: typed_arrays.uint8array_proto, + uint8clampedarray_constructor: typed_arrays.uint8clampedarray_constructor, + uint8clampedarray_proto: typed_arrays.uint8clampedarray_proto, + int16array_constructor: typed_arrays.int16array_constructor, + int16array_proto: typed_arrays.int16array_proto, + uint16array_constructor: typed_arrays.uint16array_constructor, + uint16array_proto: typed_arrays.uint16array_proto, + int32array_constructor: typed_arrays.int32array_constructor, + int32array_proto: typed_arrays.int32array_proto, + uint32array_constructor: typed_arrays.uint32array_constructor, + uint32array_proto: typed_arrays.uint32array_proto, + float32array_constructor: typed_arrays.float32array_constructor, + float32array_proto: typed_arrays.float32array_proto, + float64array_constructor: typed_arrays.float64array_constructor, + float64array_proto: typed_arrays.float64array_proto, + bigint64array_constructor: typed_arrays.bigint64array_constructor, + bigint64array_proto: typed_arrays.bigint64array_proto, + biguint64array_constructor: typed_arrays.biguint64array_constructor, + biguint64array_proto: typed_arrays.biguint64array_proto, + sym_match, + sym_replace, + sym_search, + sym_split, + sym_iterator, + sym_to_primitive, + sym_has_instance, + sym_match_all, + sym_async_iterator, + sym_to_string_tag, + sym_species, + sym_async_dispose, + sym_dispose, + temporal_object, + temporal_now_object, + instant_constructor, + instant_proto, + plain_date_constructor, + plain_date_proto, + plain_time_constructor, + plain_time_proto, + duration_constructor, + duration_proto, + zoned_date_time_constructor, + zoned_date_time_proto, + plain_date_time_constructor, + plain_date_time_proto, + plain_month_day_constructor, + plain_month_day_proto, + plain_year_month_constructor, + plain_year_month_proto, + bigint_constructor, + bigint_proto, + iterator_proto, + array_iterator_proto, + map_iterator_proto, + set_iterator_proto, + string_iterator_proto, + regexp_string_iterator_proto, + iterator_helper_proto, + disposable_stack_proto, + async_disposable_stack_proto, + stub_objects, + console_object, + leaked_objects: std::cell::RefCell::new(Vec::new()), + }; + wire_builtin_world_links(&world); + kernel_info!("BuiltinWorld initialized"); + world + } +} diff --git a/crates/oxide_kernel/src/builtin/mod.rs b/crates/oxide_kernel/src/builtin/mod.rs index b44afe9f..1def7ba0 100644 --- a/crates/oxide_kernel/src/builtin/mod.rs +++ b/crates/oxide_kernel/src/builtin/mod.rs @@ -2,15 +2,13 @@ //! 支持按脏标记重建,并提供绑定层的 native 方法指针表。 use oxide_types::mem::P; -use oxide_types::object::{JsObject, NativeFnPtr, PropAttributes}; +use oxide_types::object::{JsObject, NativeFnPtr}; use oxide_types::value::JsValue; use crate::kernel::BuiltinId; -use crate::kernel_info; -use crate::shape_forge::{ShapeForge, EMPTY_SHAPE_ID}; -use crate::string_forge::PermInterner; mod bind; +mod construct; mod methods; mod rebuild; pub use methods::{ArrayMethods, ErrorMethods, FunctionMethods, ObjectMethods, RegExpMethods, StringMethods}; @@ -223,390 +221,6 @@ struct LeakedSlot { key: Option, } -fn intern_label(string_forge: &PermInterner, label: &str) -> u32 { - string_forge.intern(label).0 -} - -fn make_pair( - string_forge: &PermInterner, shape_forge: &ShapeForge, name: &str, si_prototype: u32, si_constructor: u32, - si_name: u32, -) -> (P, P) { - intern_label(string_forge, name); - let name_si = string_forge.intern(name).0; // 同时 intern 构造器名作为属性值 - - let mut proto = JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null()); - let mut ctor = JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null()); - - let proto_shape = shape_forge.make_shape(EMPTY_SHAPE_ID, si_constructor); - proto.set_shape_id(proto_shape); - - let ctor_shape1 = shape_forge.make_shape(EMPTY_SHAPE_ID, si_prototype); - let ctor_shape2 = shape_forge.make_shape(ctor_shape1, si_name); - ctor.set_shape_id(ctor_shape2); - 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])。 - ctor.ensure_hash_props() - .push(JsValue::perm_string(string_forge.string_ptr(name_si))); - // 属性元数据:.prototype(ctor[0])= writable:false, enumerable:false, configurable:false。 - ctor.set_data_meta(0u32, oxide_types::object::PropAttributes::new(false, false, false)); - // .name(ctor[1])= writable:false, enumerable:false, configurable:true。 - ctor.set_data_meta(1u32, oxide_types::object::PropAttributes::new(false, false, true)); - // .constructor(proto[0])= writable:true, enumerable:false, configurable:true。 - // (JS 规范:prototype.constructor 非枚举,避免泄漏进 for-in。) - proto.set_data_meta(0u32, oxide_types::object::PropAttributes::new(true, false, true)); - - (P::new(proto), P::new(ctor)) -} - -#[derive(Clone, Copy)] -struct BuiltinLabels { - prototype: u32, - constructor: u32, - name: u32, -} - -fn builtin_labels(string_forge: &PermInterner) -> BuiltinLabels { - let labels = BuiltinLabels { - prototype: intern_label(string_forge, "prototype"), - constructor: intern_label(string_forge, "constructor"), - name: intern_label(string_forge, "name"), - }; - intern_label(string_forge, "length"); - intern_label(string_forge, "toString"); - intern_label(string_forge, "valueOf"); - labels -} - -fn make_named_pair( - string_forge: &PermInterner, shape_forge: &ShapeForge, labels: BuiltinLabels, name: &str, -) -> (P, P) { - make_pair(string_forge, shape_forge, name, labels.prototype, labels.constructor, labels.name) -} - -fn make_error_subtypes(error_proto: &P) -> ErrorSubtypeProtos { - let error_proto_val = JsValue::from_js_object(error_proto.as_ptr() as *mut JsObject); - ErrorSubtypeProtos { - type_error_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, error_proto_val)), - reference_error_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, error_proto_val)), - range_error_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, error_proto_val)), - syntax_error_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, error_proto_val)), - uri_error_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, error_proto_val)), - eval_error_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, error_proto_val)), - suppressed_error_proto: P::new(JsObject::new_empty(EMPTY_SHAPE_ID, error_proto_val)), - } -} - -struct ErrorSubtypeProtos { - type_error_proto: P, - reference_error_proto: P, - range_error_proto: P, - syntax_error_proto: P, - uri_error_proto: P, - eval_error_proto: P, - suppressed_error_proto: P, -} - -struct TypedArrayFamily { - typed_array_constructor: P, - typed_array_proto: P, - int8array_constructor: P, - int8array_proto: P, - uint8array_constructor: P, - uint8array_proto: P, - uint8clampedarray_constructor: P, - uint8clampedarray_proto: P, - int16array_constructor: P, - int16array_proto: P, - uint16array_constructor: P, - uint16array_proto: P, - int32array_constructor: P, - int32array_proto: P, - uint32array_constructor: P, - uint32array_proto: P, - float32array_constructor: P, - float32array_proto: P, - float64array_constructor: P, - float64array_proto: P, - bigint64array_constructor: P, - bigint64array_proto: P, - biguint64array_constructor: P, - biguint64array_proto: P, -} - -/// 建 `%TypedArray%` 抽象构造器对象:name=`TypedArray`、`prototype` 指向共享原型, -/// 实际 native 实现由绑定层配置为恒抛 TypeError(不可 new 也不可调用)。 -fn make_typed_array_abstract_ctor( - string_forge: &PermInterner, shape_forge: &ShapeForge, labels: BuiltinLabels, typed_array_proto: &P, -) -> P { - let name_si = string_forge.intern("TypedArray").0; - let mut ctor = JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null()); - let ctor_shape1 = shape_forge.make_shape(EMPTY_SHAPE_ID, labels.prototype); - let ctor_shape2 = shape_forge.make_shape(ctor_shape1, labels.name); - ctor.set_shape_id(ctor_shape2); - ctor.set_function(true); - ctor.ensure_hash_props() - .push(JsValue::from_js_object(typed_array_proto.as_ptr() as *mut JsObject)); - ctor.ensure_hash_props() - .push(JsValue::perm_string(string_forge.string_ptr(name_si))); - // .prototype 不可写不可枚举不可配置;.name 不可写不可枚举可配置。 - ctor.set_data_meta(0, PropAttributes::new(false, false, false)); - ctor.set_data_meta(1, PropAttributes::new(false, false, true)); - P::new(ctor) -} - -fn make_typed_array_family( - string_forge: &PermInterner, shape_forge: &ShapeForge, labels: BuiltinLabels, object_proto: &P, -) -> TypedArrayFamily { - let obj_proto_val = JsValue::from_js_object(object_proto.as_ptr() as *mut JsObject); - // 给共享原型开 "constructor" 槽位(占位值在 wire 时填抽象构造器)。 - let mut typed_array_proto_obj = JsObject::new_empty(EMPTY_SHAPE_ID, obj_proto_val); - let ctor_si = labels.constructor; - let proto_shape = shape_forge.make_shape(typed_array_proto_obj.shape_id(), ctor_si); - typed_array_proto_obj.set_shape_id(proto_shape); - typed_array_proto_obj.ensure_hash_props().push(JsValue::undefined()); - typed_array_proto_obj.set_data_meta(0, PropAttributes::new(true, false, true)); - let typed_array_proto = P::new(typed_array_proto_obj); - let typed_array_constructor = make_typed_array_abstract_ctor(string_forge, shape_forge, labels, &typed_array_proto); - let (int8array_proto, int8array_constructor) = make_named_pair(string_forge, shape_forge, labels, "Int8Array"); - let (uint8array_proto, uint8array_constructor) = make_named_pair(string_forge, shape_forge, labels, "Uint8Array"); - let (uint8clampedarray_proto, uint8clampedarray_constructor) = - make_named_pair(string_forge, shape_forge, labels, "Uint8ClampedArray"); - let (int16array_proto, int16array_constructor) = make_named_pair(string_forge, shape_forge, labels, "Int16Array"); - let (uint16array_proto, uint16array_constructor) = - make_named_pair(string_forge, shape_forge, labels, "Uint16Array"); - let (int32array_proto, int32array_constructor) = make_named_pair(string_forge, shape_forge, labels, "Int32Array"); - let (uint32array_proto, uint32array_constructor) = - make_named_pair(string_forge, shape_forge, labels, "Uint32Array"); - let (float32array_proto, float32array_constructor) = - make_named_pair(string_forge, shape_forge, labels, "Float32Array"); - let (float64array_proto, float64array_constructor) = - make_named_pair(string_forge, shape_forge, labels, "Float64Array"); - let (bigint64array_proto, bigint64array_constructor) = - make_named_pair(string_forge, shape_forge, labels, "BigInt64Array"); - let (biguint64array_proto, biguint64array_constructor) = - make_named_pair(string_forge, shape_forge, labels, "BigUint64Array"); - - TypedArrayFamily { - typed_array_constructor, - typed_array_proto, - int8array_constructor, - int8array_proto, - uint8array_constructor, - uint8array_proto, - uint8clampedarray_constructor, - uint8clampedarray_proto, - int16array_constructor, - int16array_proto, - uint16array_constructor, - uint16array_proto, - int32array_constructor, - int32array_proto, - uint32array_constructor, - uint32array_proto, - float32array_constructor, - float32array_proto, - float64array_constructor, - float64array_proto, - bigint64array_constructor, - bigint64array_proto, - biguint64array_constructor, - biguint64array_proto, - } -} - -/// 用真实值覆盖(`make_pair` 设置的)占位槽。 -/// ctor.vec[0] = constructor.prototype → proto。 -/// proto.vec[0] = proto.constructor → ctor。 -fn wire_ctor_proto(ctor: &P, proto: &P) { - let ctor_ptr = ctor.as_ptr() as *mut JsObject; - let ctor = unsafe { &mut *ctor_ptr }; - let vec = ctor.ensure_hash_props(); - if !vec.is_empty() { - vec[0] = JsValue::from_js_object(proto.as_ptr() as *mut JsObject); - } - let proto_ptr = proto.as_ptr() as *mut JsObject; - let proto = unsafe { &mut *proto_ptr }; - let pvec = proto.ensure_hash_props(); - if !pvec.is_empty() { - pvec[0] = JsValue::from_js_object(ctor_ptr); - } -} - -fn set_proto_if_changed(obj: &P, proto: JsValue) { - let ptr = obj.as_ptr() as *mut JsObject; - let obj = unsafe { &mut *ptr }; - if obj.proto() != proto { - obj.set_proto(proto).ok(); - } -} - -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); - wire_ctor_proto(&world.function_constructor, &world.function_proto); - wire_ctor_proto(&world.string_constructor, &world.string_proto); - wire_ctor_proto(&world.number_constructor, &world.number_proto); - wire_ctor_proto(&world.boolean_constructor, &world.boolean_proto); - wire_ctor_proto(&world.error_constructor, &world.error_proto); - wire_ctor_proto(&world.symbol_constructor, &world.symbol_proto); - wire_ctor_proto(&world.date_constructor, &world.date_proto); - wire_ctor_proto(&world.set_constructor, &world.set_proto); - wire_ctor_proto(&world.map_constructor, &world.map_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.data_view_constructor, &world.data_view_proto); - wire_ctor_proto(&world.int8array_constructor, &world.int8array_proto); - wire_ctor_proto(&world.uint8array_constructor, &world.uint8array_proto); - wire_ctor_proto(&world.uint8clampedarray_constructor, &world.uint8clampedarray_proto); - wire_ctor_proto(&world.int16array_constructor, &world.int16array_proto); - wire_ctor_proto(&world.uint16array_constructor, &world.uint16array_proto); - wire_ctor_proto(&world.int32array_constructor, &world.int32array_proto); - wire_ctor_proto(&world.uint32array_constructor, &world.uint32array_proto); - wire_ctor_proto(&world.float32array_constructor, &world.float32array_proto); - wire_ctor_proto(&world.float64array_constructor, &world.float64array_proto); - wire_ctor_proto(&world.bigint64array_constructor, &world.bigint64array_proto); - wire_ctor_proto(&world.biguint64array_constructor, &world.biguint64array_proto); - wire_ctor_proto(&world.instant_constructor, &world.instant_proto); - wire_ctor_proto(&world.plain_date_constructor, &world.plain_date_proto); - wire_ctor_proto(&world.plain_time_constructor, &world.plain_time_proto); - wire_ctor_proto(&world.duration_constructor, &world.duration_proto); - wire_ctor_proto(&world.zoned_date_time_constructor, &world.zoned_date_time_proto); - wire_ctor_proto(&world.plain_date_time_constructor, &world.plain_date_time_proto); - 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); - - // 所有内置构造器的 [[Prototype]] 指向 %FunctionPrototype%(ECMA-262 §17: - // 标准内置函数对象均继承 Function.prototype;此前仅 TypedArray 构造器设置过)。 - let fn_proto_val = world.fn_proto_val(); - for ctor in [ - &world.object_constructor, - &world.array_constructor, - &world.function_constructor, - &world.string_constructor, - &world.number_constructor, - &world.boolean_constructor, - &world.error_constructor, - &world.symbol_constructor, - &world.date_constructor, - &world.set_constructor, - &world.map_constructor, - &world.regexp_constructor, - &world.array_buffer_constructor, - &world.data_view_constructor, - &world.bigint_constructor, - &world.instant_constructor, - &world.plain_date_constructor, - &world.plain_time_constructor, - &world.duration_constructor, - &world.zoned_date_time_constructor, - &world.plain_date_time_constructor, - &world.plain_month_day_constructor, - &world.plain_year_month_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; 25] = [ - &world.array_proto, - &world.function_proto, - &world.string_proto, - &world.number_proto, - &world.boolean_proto, - &world.error_proto, - &world.symbol_proto, - &world.date_proto, - &world.set_proto, - &world.map_proto, - &world.regexp_proto, - &world.array_buffer_proto, - &world.data_view_proto, - &world.typed_array_proto, - &world.instant_proto, - &world.plain_date_proto, - &world.plain_time_proto, - &world.duration_proto, - &world.zoned_date_time_proto, - &world.plain_date_time_proto, - &world.plain_month_day_proto, - &world.plain_year_month_proto, - &world.bigint_proto, - &world.disposable_stack_proto, - &world.async_disposable_stack_proto, - ]; - for proto in &non_object_protos { - set_proto_if_changed(proto, obj_proto_val); - } - - // Temporal 命名空间对象(非构造器)继承 Object.prototype。 - set_proto_if_changed(&world.temporal_object, obj_proto_val); - set_proto_if_changed(&world.temporal_now_object, obj_proto_val); - - // Console 对象(单例命名空间)继承 Object.prototype。 - set_proto_if_changed(&world.console_object, obj_proto_val); - - // 迭代器原型链:%IteratorPrototype% → Object.prototype;各集合迭代器原型 - // → %IteratorPrototype%(next/@@iterator 方法由绑定层安装到对应原型)。 - 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] = [ - &world.array_iterator_proto, - &world.map_iterator_proto, - &world.set_iterator_proto, - &world.string_iterator_proto, - &world.regexp_string_iterator_proto, - &world.iterator_helper_proto, - ]; - for proto in &iterator_protos { - set_proto_if_changed(proto, iterator_proto_val); - } - - let typed_array_proto_val = JsValue::from_js_object(world.typed_array_proto.as_ptr() as *mut JsObject); - let typed_array_protos: [&P; 11] = [ - &world.int8array_proto, - &world.uint8array_proto, - &world.uint8clampedarray_proto, - &world.int16array_proto, - &world.uint16array_proto, - &world.int32array_proto, - &world.uint32array_proto, - &world.float32array_proto, - &world.float64array_proto, - &world.bigint64array_proto, - &world.biguint64array_proto, - ]; - for proto in &typed_array_protos { - set_proto_if_changed(proto, typed_array_proto_val); - } - - // 共享原型与抽象构造器互指(prototype/constructor);11 个具体构造器的 - // [[Prototype]] 指向 `%TypedArray%`,抽象构造器自身 [[Prototype]] 为 Function.prototype。 - wire_ctor_proto(&world.typed_array_constructor, &world.typed_array_proto); - set_proto_if_changed(&world.typed_array_constructor, world.fn_proto_val()); - let typed_array_ctor_val = JsValue::from_js_object(world.typed_array_constructor.as_ptr() as *mut JsObject); - let typed_array_ctors: [&P; 11] = [ - &world.int8array_constructor, - &world.uint8array_constructor, - &world.uint8clampedarray_constructor, - &world.int16array_constructor, - &world.uint16array_constructor, - &world.int32array_constructor, - &world.uint32array_constructor, - &world.float32array_constructor, - &world.float64array_constructor, - &world.bigint64array_constructor, - &world.biguint64array_constructor, - ]; - for ctor in &typed_array_ctors { - set_proto_if_changed(ctor, typed_array_ctor_val); - } -} - impl BuiltinWorld { pub fn fn_proto_val(&self) -> JsValue { JsValue::from_js_object(self.function_proto.as_ptr() as *mut JsObject) @@ -936,202 +550,12 @@ impl BuiltinWorld { BuiltinId::Console => &self.console_object, } } - - /// 全量构造一个全新的 builtin world:创建所有原型/构造器对、Error 子类型、 - /// TypedArray 家族与 well-known symbol 对象,并建立原型链链接。 - pub fn new(string_forge: &PermInterner, shape_forge: &ShapeForge) -> Self { - let labels = builtin_labels(string_forge); - - let (object_proto, object_constructor) = make_named_pair(string_forge, shape_forge, labels, "Object"); - let (array_proto, array_constructor) = make_named_pair(string_forge, shape_forge, labels, "Array"); - let (function_proto, function_constructor) = make_named_pair(string_forge, shape_forge, labels, "Function"); - let (string_proto, string_constructor) = make_named_pair(string_forge, shape_forge, labels, "String"); - let (number_proto, number_constructor) = make_named_pair(string_forge, shape_forge, labels, "Number"); - let (boolean_proto, boolean_constructor) = make_named_pair(string_forge, shape_forge, labels, "Boolean"); - let (error_proto, error_constructor) = make_named_pair(string_forge, shape_forge, labels, "Error"); - let (symbol_proto, symbol_constructor) = make_named_pair(string_forge, shape_forge, labels, "Symbol"); - - let error_subtypes = make_error_subtypes(&error_proto); - - let math_object = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); - - let json_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"); - let (set_proto, set_constructor) = make_named_pair(string_forge, shape_forge, labels, "Set"); - let (map_proto, map_constructor) = make_named_pair(string_forge, shape_forge, labels, "Map"); - let (regexp_proto, regexp_constructor) = make_named_pair(string_forge, shape_forge, labels, "RegExp"); - let (array_buffer_proto, array_buffer_constructor) = - make_named_pair(string_forge, shape_forge, labels, "ArrayBuffer"); - 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 sym_match = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); - let sym_replace = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); - let sym_search = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); - let sym_split = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); - let sym_iterator = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); - let sym_to_primitive = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); - let sym_has_instance = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); - let sym_match_all = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); - let sym_async_iterator = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); - let sym_to_string_tag = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); - let sym_species = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); - let sym_async_dispose = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); - let sym_dispose = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); - let temporal_object = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); - let temporal_now_object = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); - let (instant_proto, instant_constructor) = make_named_pair(string_forge, shape_forge, labels, "Instant"); - let (plain_date_proto, plain_date_constructor) = - make_named_pair(string_forge, shape_forge, labels, "PlainDate"); - let (plain_time_proto, plain_time_constructor) = - make_named_pair(string_forge, shape_forge, labels, "PlainTime"); - let (duration_proto, duration_constructor) = make_named_pair(string_forge, shape_forge, labels, "Duration"); - let (zoned_date_time_proto, zoned_date_time_constructor) = - make_named_pair(string_forge, shape_forge, labels, "ZonedDateTime"); - let (plain_date_time_proto, plain_date_time_constructor) = - make_named_pair(string_forge, shape_forge, labels, "PlainDateTime"); - let (plain_month_day_proto, plain_month_day_constructor) = - make_named_pair(string_forge, shape_forge, labels, "PlainMonthDay"); - let (plain_year_month_proto, plain_year_month_constructor) = - make_named_pair(string_forge, shape_forge, labels, "PlainYearMonth"); - let (bigint_proto, bigint_constructor) = make_named_pair(string_forge, shape_forge, labels, "BigInt"); - let stub_objects = Vec::new(); - - // 迭代器原型家族:链关系(→ %IteratorPrototype% → Object.prototype)在 - // wire_builtin_world_links 中建立,next/@@iterator 方法由绑定层安装。 - 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())); - let set_iterator_proto = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); - let string_iterator_proto = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); - let regexp_string_iterator_proto = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); - let iterator_helper_proto = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); - let disposable_stack_proto = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); - let async_disposable_stack_proto = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); - // 默认迭代器指针初值空(绑定层随后经 bind_string 捕获写入)。 - let string_default_iterator = std::cell::Cell::new(std::ptr::null()); - - let world = Self { - object_proto, - string_default_iterator, - array_proto, - function_proto, - string_proto, - number_proto, - boolean_proto, - error_proto, - symbol_proto, - object_constructor, - array_constructor, - function_constructor, - string_constructor, - number_constructor, - boolean_constructor, - error_constructor, - symbol_constructor, - type_error_proto: error_subtypes.type_error_proto, - reference_error_proto: error_subtypes.reference_error_proto, - range_error_proto: error_subtypes.range_error_proto, - syntax_error_proto: error_subtypes.syntax_error_proto, - uri_error_proto: error_subtypes.uri_error_proto, - eval_error_proto: error_subtypes.eval_error_proto, - suppressed_error_proto: error_subtypes.suppressed_error_proto, - math_object, - json_object, - date_constructor, - date_proto, - set_constructor, - set_proto, - map_constructor, - map_proto, - regexp_constructor, - regexp_proto, - array_buffer_constructor, - array_buffer_proto, - data_view_constructor, - data_view_proto, - typed_array_proto: typed_arrays.typed_array_proto, - typed_array_constructor: typed_arrays.typed_array_constructor, - int8array_constructor: typed_arrays.int8array_constructor, - int8array_proto: typed_arrays.int8array_proto, - uint8array_constructor: typed_arrays.uint8array_constructor, - uint8array_proto: typed_arrays.uint8array_proto, - uint8clampedarray_constructor: typed_arrays.uint8clampedarray_constructor, - uint8clampedarray_proto: typed_arrays.uint8clampedarray_proto, - int16array_constructor: typed_arrays.int16array_constructor, - int16array_proto: typed_arrays.int16array_proto, - uint16array_constructor: typed_arrays.uint16array_constructor, - uint16array_proto: typed_arrays.uint16array_proto, - int32array_constructor: typed_arrays.int32array_constructor, - int32array_proto: typed_arrays.int32array_proto, - uint32array_constructor: typed_arrays.uint32array_constructor, - uint32array_proto: typed_arrays.uint32array_proto, - float32array_constructor: typed_arrays.float32array_constructor, - float32array_proto: typed_arrays.float32array_proto, - float64array_constructor: typed_arrays.float64array_constructor, - float64array_proto: typed_arrays.float64array_proto, - bigint64array_constructor: typed_arrays.bigint64array_constructor, - bigint64array_proto: typed_arrays.bigint64array_proto, - biguint64array_constructor: typed_arrays.biguint64array_constructor, - biguint64array_proto: typed_arrays.biguint64array_proto, - sym_match, - sym_replace, - sym_search, - sym_split, - sym_iterator, - sym_to_primitive, - sym_has_instance, - sym_match_all, - sym_async_iterator, - sym_to_string_tag, - sym_species, - sym_async_dispose, - sym_dispose, - temporal_object, - temporal_now_object, - instant_constructor, - instant_proto, - plain_date_constructor, - plain_date_proto, - plain_time_constructor, - plain_time_proto, - duration_constructor, - duration_proto, - zoned_date_time_constructor, - zoned_date_time_proto, - plain_date_time_constructor, - plain_date_time_proto, - plain_month_day_constructor, - plain_month_day_proto, - plain_year_month_constructor, - plain_year_month_proto, - bigint_constructor, - bigint_proto, - iterator_proto, - array_iterator_proto, - map_iterator_proto, - set_iterator_proto, - string_iterator_proto, - regexp_string_iterator_proto, - iterator_helper_proto, - disposable_stack_proto, - async_disposable_stack_proto, - stub_objects, - console_object, - leaked_objects: std::cell::RefCell::new(Vec::new()), - }; - wire_builtin_world_links(&world); - kernel_info!("BuiltinWorld initialized"); - world - } } #[cfg(test)] mod tests { use super::*; + use crate::shape_forge::EMPTY_SHAPE_ID; /// 选择性重建的释放 + 重指面动态自测:被替换旧 P 对象属性区恰好释放一次 /// (置空可断言,含保活钉住对的属性区、本体钉保留),保留字段指针不变且 diff --git a/crates/oxide_kernel/src/builtin/rebuild.rs b/crates/oxide_kernel/src/builtin/rebuild.rs index 0cbd532e..482e7b2a 100644 --- a/crates/oxide_kernel/src/builtin/rebuild.rs +++ b/crates/oxide_kernel/src/builtin/rebuild.rs @@ -6,10 +6,11 @@ use oxide_types::mem::P; use oxide_types::object::JsObject; use oxide_types::value::JsValue; -use super::{ +use super::construct::{ builtin_labels, make_error_subtypes, make_named_pair, make_typed_array_family, wire_builtin_world_links, - BuiltinWorld, ErrorSubtypeProtos, TypedArrayFamily, + ErrorSubtypeProtos, TypedArrayFamily, }; +use super::BuiltinWorld; use crate::kernel::BuiltinDirtySet; use crate::shape_forge::{ShapeForge, EMPTY_SHAPE_ID}; use crate::string_forge::PermInterner;