From d1f5a44d371ac72e988ac616b21958fd36d8b739 Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Sun, 16 Aug 2026 19:14:48 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20DisposableStack/AsyncDisposableStack=20?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1=E7=B1=BB=E5=9E=8B=E6=A0=87=E7=AD=BE=E4=B8=8E?= =?UTF-8?q?=E4=B8=A4=E6=A0=88=E5=8E=9F=E5=9E=8B=E5=AD=97=E6=AE=B5=E5=85=A5?= =?UTF-8?q?=E4=B8=96=E7=95=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_kernel/src/builtin.rs | 25 ++++++++++++++++++++++--- crates/oxide_types/src/object.rs | 16 ++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/crates/oxide_kernel/src/builtin.rs b/crates/oxide_kernel/src/builtin.rs index ea684e9..b554bed 100644 --- a/crates/oxide_kernel/src/builtin.rs +++ b/crates/oxide_kernel/src/builtin.rs @@ -288,6 +288,11 @@ pub struct BuiltinWorld { pub regexp_string_iterator_proto: P, /// `%IteratorHelperPrototype%`:Iterator helpers 结果对象的共享原型,链到 %IteratorPrototype%。 pub iterator_helper_proto: P, + /// `DisposableStack.prototype`:同步资源栈原型(链到 Object.prototype), + /// 方法/别名/@@toStringTag 由绑定层安装。 + pub disposable_stack_proto: P, + /// `AsyncDisposableStack.prototype`:异步资源栈原型(步3 用,形状与同步栈一致)。 + pub async_disposable_stack_proto: P, pub stub_objects: Vec>, } @@ -576,7 +581,7 @@ 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; 21] = [ + let non_object_protos: [&P; 23] = [ &world.array_proto, &world.function_proto, &world.string_proto, @@ -598,6 +603,8 @@ fn wire_builtin_world_links(world: &BuiltinWorld) { &world.zoned_date_time_proto, &world.plain_date_time_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); @@ -830,6 +837,8 @@ impl BuiltinWorld { 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())); let world = Self { object_proto, @@ -929,6 +938,8 @@ impl BuiltinWorld { string_iterator_proto, regexp_string_iterator_proto, iterator_helper_proto, + disposable_stack_proto, + async_disposable_stack_proto, stub_objects, }; wire_builtin_world_links(&world); @@ -1195,8 +1206,8 @@ impl BuiltinWorld { }; let stub_objects = if dirty.stubs { Vec::new() } else { current.stub_objects.clone() }; - // 迭代器原型依赖 Object.prototype(链到其上):object 家族重建时一并重建, - // 否则旧原型链指向已释放的 object_proto。 + // 迭代器原型与资源栈原型依赖 Object.prototype(链到其上):object 家族重建时 + // 一并重建,否则旧原型链指向已释放的 object_proto。 let ( iterator_proto, array_iterator_proto, @@ -1205,6 +1216,8 @@ impl BuiltinWorld { string_iterator_proto, regexp_string_iterator_proto, iterator_helper_proto, + disposable_stack_proto, + async_disposable_stack_proto, ) = if dirty.object { ( P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())), @@ -1214,6 +1227,8 @@ impl BuiltinWorld { P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())), P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())), P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())), + P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())), + P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())), ) } else { ( @@ -1224,6 +1239,8 @@ impl BuiltinWorld { current.string_iterator_proto.clone(), current.regexp_string_iterator_proto.clone(), current.iterator_helper_proto.clone(), + current.disposable_stack_proto.clone(), + current.async_disposable_stack_proto.clone(), ) }; @@ -1325,6 +1342,8 @@ impl BuiltinWorld { string_iterator_proto, regexp_string_iterator_proto, iterator_helper_proto, + disposable_stack_proto, + async_disposable_stack_proto, stub_objects, }; wire_builtin_world_links(&world); diff --git a/crates/oxide_types/src/object.rs b/crates/oxide_types/src/object.rs index 0238172..89c4c43 100644 --- a/crates/oxide_types/src/object.rs +++ b/crates/oxide_types/src/object.rs @@ -657,6 +657,10 @@ impl JsObject { /// [[BoundThis]] / [[BoundArguments]] 存于 dense 槽 4/5/6+,构造与 instanceof /// 语义转发到 target。 pub const OBJ_TYPE_BOUND: u8 = 23; + /// DisposableStack 对象:状态盒(Pending/Disposed + entries)存于 `native_data`。 + pub const OBJ_TYPE_DISPOSABLE_STACK: u8 = 24; + /// AsyncDisposableStack 对象(步3 用):状态盒与同步栈同构,预留 type_tag。 + pub const OBJ_TYPE_ASYNC_DISPOSABLE_STACK: u8 = 25; /// `is_session_epoch` 字段中的 session 标记位。 pub const SESSION_EPOCH_BIT: u8 = 0x01; /// `is_session_epoch` 字段中的 GC 标记位。 @@ -770,6 +774,18 @@ impl JsObject { self.type_tag == Self::OBJ_TYPE_ERROR } + /// 是否 DisposableStack 对象(同步资源栈)。 + #[inline] + pub fn is_disposable_stack_obj(&self) -> bool { + self.type_tag == Self::OBJ_TYPE_DISPOSABLE_STACK + } + + /// 是否 AsyncDisposableStack 对象(异步资源栈,步3 用)。 + #[inline] + pub fn is_async_disposable_stack_obj(&self) -> bool { + self.type_tag == Self::OBJ_TYPE_ASYNC_DISPOSABLE_STACK + } + /// 构造无属性、可扩展的空对象(`new Object()` 的基础对象)。 pub fn new_empty(shape_id: ShapeId, proto: JsValue) -> Self { Self {