From 9ecd5735265be72cd9e972a5982ac8c544187c62 Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Sat, 10 Oct 2026 08:02:05 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20Event=20=E4=BD=93=E7=B3=BB=E5=86=85?= =?UTF-8?q?=E6=A0=B8=E6=8E=A5=E7=BA=BF=E4=B9=9D=20P=20=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E5=8A=A0=20BuiltinId=20=E5=8A=A0=E8=84=8F=E4=BD=8D=E5=8A=A0=20?= =?UTF-8?q?ProtoKind?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 38 +++++++-------- Cargo.toml | 2 +- crates/oxide_kernel/src/builtin/construct.rs | 23 +++++++++ crates/oxide_kernel/src/builtin/rebuild.rs | 46 ++++++++++++++++++ crates/oxide_kernel/src/builtin/world.rs | 51 ++++++++++++++++++-- crates/oxide_kernel/src/kernel/builtin_id.rs | 40 +++++++++++++-- crates/oxide_kernel/src/kernel/session.rs | 9 ++++ crates/oxide_runtime_api/src/host.rs | 6 +++ crates/oxide_vm/src/bindings/bind_event.rs | 28 +++++++++++ crates/oxide_vm/src/bindings/mod.rs | 5 ++ crates/oxide_vm/src/vm/vmhost.rs | 4 ++ 11 files changed, 224 insertions(+), 28 deletions(-) create mode 100644 crates/oxide_vm/src/bindings/bind_event.rs diff --git a/Cargo.lock b/Cargo.lock index 224829dd..d9b150b3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1160,7 +1160,7 @@ dependencies = [ [[package]] name = "oxide_builtins" -version = "0.14.6" +version = "0.14.7" dependencies = [ "chrono", "fast-float", @@ -1185,7 +1185,7 @@ dependencies = [ [[package]] name = "oxide_bytecode" -version = "0.14.6" +version = "0.14.7" dependencies = [ "num-bigint", "oxide_log", @@ -1193,7 +1193,7 @@ dependencies = [ [[package]] name = "oxide_cfg" -version = "0.14.6" +version = "0.14.7" dependencies = [ "oxide_bytecode", "oxide_emit", @@ -1204,7 +1204,7 @@ dependencies = [ [[package]] name = "oxide_cli" -version = "0.14.6" +version = "0.14.7" dependencies = [ "ansi_term", "bumpalo", @@ -1226,7 +1226,7 @@ dependencies = [ [[package]] name = "oxide_code_cache" -version = "0.14.6" +version = "0.14.7" dependencies = [ "lru", "oxide_bytecode", @@ -1235,7 +1235,7 @@ dependencies = [ [[package]] name = "oxide_compiler" -version = "0.14.6" +version = "0.14.7" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1255,7 +1255,7 @@ dependencies = [ [[package]] name = "oxide_dce" -version = "0.14.6" +version = "0.14.7" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1269,7 +1269,7 @@ dependencies = [ [[package]] name = "oxide_emit" -version = "0.14.6" +version = "0.14.7" dependencies = [ "num-bigint", "oxc_allocator", @@ -1284,7 +1284,7 @@ dependencies = [ [[package]] name = "oxide_engine" -version = "0.14.6" +version = "0.14.7" dependencies = [ "oxide_bytecode", "oxide_compiler", @@ -1296,7 +1296,7 @@ dependencies = [ [[package]] name = "oxide_ir" -version = "0.14.6" +version = "0.14.7" dependencies = [ "oxide_bytecode", "oxide_log", @@ -1305,7 +1305,7 @@ dependencies = [ [[package]] name = "oxide_kernel" -version = "0.14.6" +version = "0.14.7" dependencies = [ "bumpalo", "dashmap", @@ -1319,7 +1319,7 @@ dependencies = [ [[package]] name = "oxide_liveness" -version = "0.14.6" +version = "0.14.7" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1331,7 +1331,7 @@ dependencies = [ [[package]] name = "oxide_log" -version = "0.14.6" +version = "0.14.7" dependencies = [ "tracing", "tracing-appender", @@ -1340,7 +1340,7 @@ dependencies = [ [[package]] name = "oxide_parser" -version = "0.14.6" +version = "0.14.7" dependencies = [ "oxc_allocator", "oxc_ast", @@ -1355,7 +1355,7 @@ dependencies = [ [[package]] name = "oxide_regalloc" -version = "0.14.6" +version = "0.14.7" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1371,7 +1371,7 @@ dependencies = [ [[package]] name = "oxide_runtime_api" -version = "0.14.6" +version = "0.14.7" dependencies = [ "num-bigint", "num-traits", @@ -1384,7 +1384,7 @@ dependencies = [ [[package]] name = "oxide_test262" -version = "0.14.6" +version = "0.14.7" dependencies = [ "oxide_bytecode", "oxide_compiler", @@ -1402,7 +1402,7 @@ dependencies = [ [[package]] name = "oxide_types" -version = "0.14.6" +version = "0.14.7" dependencies = [ "bumpalo", "dashmap", @@ -1415,7 +1415,7 @@ dependencies = [ [[package]] name = "oxide_vm" -version = "0.14.6" +version = "0.14.7" dependencies = [ "bumpalo", "chrono", diff --git a/Cargo.toml b/Cargo.toml index 2bab266e..a5dca1b3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ members = [ ] [workspace.package] -version = "0.14.6" +version = "0.14.7" edition = "2021" license = "MIT" rust-version = "1.80" diff --git a/crates/oxide_kernel/src/builtin/construct.rs b/crates/oxide_kernel/src/builtin/construct.rs index c4f9d050..0941a938 100644 --- a/crates/oxide_kernel/src/builtin/construct.rs +++ b/crates/oxide_kernel/src/builtin/construct.rs @@ -514,6 +514,20 @@ impl BuiltinWorld { let broadcast_channel_proto = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); let broadcast_channel_constructor = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + // Event 体系九个内核接线占位(空对象):Event / MessageEvent / + // ErrorEvent / CustomEvent 四枚原型与构造器对加 EventTarget 原型, + // 真实本体与原型链连线由绑定层后续任务填充,本处只预留槽位使快照/ + // 脏检查/收尾枚举覆盖到这九枚 P 字段。 + let event_proto = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let event_constructor = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let message_event_proto = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let message_event_constructor = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let error_event_proto = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let error_event_constructor = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let custom_event_proto = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let custom_event_constructor = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let event_target_proto = 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"); @@ -665,6 +679,15 @@ impl BuiltinWorld { message_channel_constructor, broadcast_channel_proto, broadcast_channel_constructor, + event_proto, + event_constructor, + message_event_proto, + message_event_constructor, + error_event_proto, + error_event_constructor, + custom_event_proto, + custom_event_constructor, + event_target_proto, leaked_objects: std::cell::RefCell::new(Vec::new()), }; wire_builtin_world_links(&world); diff --git a/crates/oxide_kernel/src/builtin/rebuild.rs b/crates/oxide_kernel/src/builtin/rebuild.rs index a4f5519a..c0d4b5a2 100644 --- a/crates/oxide_kernel/src/builtin/rebuild.rs +++ b/crates/oxide_kernel/src/builtin/rebuild.rs @@ -418,6 +418,43 @@ impl BuiltinWorld { (current.broadcast_channel_proto.clone(), current.broadcast_channel_constructor.clone()) }; + // Event 体系九个占位:脏则换新空对象(与全量构造同形),未脏沿用旧指针。 + let ( + event_proto, + event_constructor, + message_event_proto, + message_event_constructor, + error_event_proto, + error_event_constructor, + custom_event_proto, + custom_event_constructor, + event_target_proto, + ) = if dirty.event { + ( + 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())), + 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 { + ( + current.event_proto.clone(), + current.event_constructor.clone(), + current.message_event_proto.clone(), + current.message_event_constructor.clone(), + current.error_event_proto.clone(), + current.error_event_constructor.clone(), + current.custom_event_proto.clone(), + current.custom_event_constructor.clone(), + current.event_target_proto.clone(), + ) + }; + // 迭代器原型与资源栈原型依赖 Object.prototype(链到其上):object 家族重建时 // 一并重建,否则旧原型链指向已释放的 object_proto。 let ( @@ -572,6 +609,15 @@ impl BuiltinWorld { message_channel_constructor, broadcast_channel_proto, broadcast_channel_constructor, + event_proto, + event_constructor, + message_event_proto, + message_event_constructor, + error_event_proto, + error_event_constructor, + custom_event_proto, + custom_event_constructor, + event_target_proto, leaked_objects: std::cell::RefCell::new(Vec::new()), }; wire_builtin_world_links(&world); diff --git a/crates/oxide_kernel/src/builtin/world.rs b/crates/oxide_kernel/src/builtin/world.rs index 80f8dd53..c9d1405b 100644 --- a/crates/oxide_kernel/src/builtin/world.rs +++ b/crates/oxide_kernel/src/builtin/world.rs @@ -1,5 +1,5 @@ -//! 注册表职责:BuiltinWorld 结构(99 固定 P 字段 + stub 族 + Box::into_raw -//! 登记表)、get_by_id 派发、all_p_fields 99 元组枚举(新增 P 字段四处同步 +//! 注册表职责:BuiltinWorld 结构(108 固定 P 字段 + stub 族 + Box::into_raw +//! 登记表)、get_by_id 派发、all_p_fields 108 元组枚举(新增 P 字段四处同步 //! 约束载体)与登记表 track/find/inherit/teardown。 use oxide_types::mem::P; @@ -150,6 +150,33 @@ pub struct BuiltinWorld { /// `BroadcastChannel` 构造器槽位:纯内核接线占位(空对象),真实构造器 /// 本体由绑定层后续任务填充。 pub broadcast_channel_constructor: P, + /// `Event.prototype` 槽位:纯内核接线占位(空对象),真实原型本体 + /// 与构造器对由绑定层后续任务填充;脏家族位为 `event`。 + pub event_proto: P, + /// `Event` 构造器槽位:纯内核接线占位(空对象),真实构造器本体由 + /// 绑定层后续任务填充。 + pub event_constructor: P, + /// `MessageEvent.prototype` 槽位:纯内核接线占位(空对象),真实原型 + /// 本体与构造器对由绑定层后续任务填充。 + pub message_event_proto: P, + /// `MessageEvent` 构造器槽位:纯内核接线占位(空对象),真实构造器 + /// 本体由绑定层后续任务填充。 + pub message_event_constructor: P, + /// `ErrorEvent.prototype` 槽位:纯内核接线占位(空对象),真实原型 + /// 本体与构造器对由绑定层后续任务填充。 + pub error_event_proto: P, + /// `ErrorEvent` 构造器槽位:纯内核接线占位(空对象),真实构造器 + /// 本体由绑定层后续任务填充。 + pub error_event_constructor: P, + /// `CustomEvent.prototype` 槽位:纯内核接线占位(空对象),真实原型 + /// 本体与构造器对由绑定层后续任务填充。 + pub custom_event_proto: P, + /// `CustomEvent` 构造器槽位:纯内核接线占位(空对象),真实构造器 + /// 本体由绑定层后续任务填充。 + pub custom_event_constructor: P, + /// `EventTarget.prototype` 槽位:纯内核接线占位(空对象),真实原型 + /// 本体由绑定层后续任务填充(EventTarget 无构造器,仅暴露原型)。 + pub event_target_proto: P, /// 释放登记表(`Box::into_raw` 对象的清单,session 收尾统一释放,非内存泄漏): /// 绑定层经 `Box::into_raw` 持有的函数/宿主对象(方法 wrapper、访问器、 /// 错误构造器、Reflect/Iterator、内建原型构造器、`$262` 宿主等)。 @@ -380,7 +407,7 @@ impl BuiltinWorld { /// session 收尾(`teardown_heap_data`)与选择性重建收尾(`retire_replaced`) /// 的 P 字段枚举唯一入口:`BuiltinWorld` 新增 P 字段须在此同步补一行,否则 /// 收尾时该字段属性区无法释放、重建原型槽改写/释放漏掉该字段。 - pub(crate) fn all_p_fields(&self) -> [&P; 99] { + pub(crate) fn all_p_fields(&self) -> [&P; 108] { [ &self.object_proto, &self.array_proto, @@ -481,6 +508,15 @@ impl BuiltinWorld { &self.message_channel_constructor, &self.broadcast_channel_proto, &self.broadcast_channel_constructor, + &self.event_proto, + &self.event_constructor, + &self.message_event_proto, + &self.message_event_constructor, + &self.error_event_proto, + &self.error_event_constructor, + &self.custom_event_proto, + &self.custom_event_constructor, + &self.event_target_proto, ] } @@ -618,6 +654,15 @@ impl BuiltinWorld { BuiltinId::MessageChannelCtor => &self.message_channel_constructor, BuiltinId::BroadcastChannelProto => &self.broadcast_channel_proto, BuiltinId::BroadcastChannelCtor => &self.broadcast_channel_constructor, + BuiltinId::EventProto => &self.event_proto, + BuiltinId::EventCtor => &self.event_constructor, + BuiltinId::MessageEventProto => &self.message_event_proto, + BuiltinId::MessageEventCtor => &self.message_event_constructor, + BuiltinId::ErrorEventProto => &self.error_event_proto, + BuiltinId::ErrorEventCtor => &self.error_event_constructor, + BuiltinId::CustomEventProto => &self.custom_event_proto, + BuiltinId::CustomEventCtor => &self.custom_event_constructor, + BuiltinId::EventTargetProto => &self.event_target_proto, } } } diff --git a/crates/oxide_kernel/src/kernel/builtin_id.rs b/crates/oxide_kernel/src/kernel/builtin_id.rs index 3b32bfd8..9df26521 100644 --- a/crates/oxide_kernel/src/kernel/builtin_id.rs +++ b/crates/oxide_kernel/src/kernel/builtin_id.rs @@ -1,4 +1,4 @@ -//! 内置对象 id 枚举(`BuiltinId` 89 变体 + `ALL` 顺序钉表)、世代快照 +//! 内置对象 id 枚举(`BuiltinId` 98 变体 + `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 = 89; +pub const NUM_BUILTINS: usize = 98; /// 内置对象枚举 id,与 `BuiltinWorld` 中的存储槽一一对应。 /// @@ -109,6 +109,15 @@ pub enum BuiltinId { MessageChannelCtor = 86, BroadcastChannelProto = 87, BroadcastChannelCtor = 88, + EventProto = 89, + EventCtor = 90, + MessageEventProto = 91, + MessageEventCtor = 92, + ErrorEventProto = 93, + ErrorEventCtor = 94, + CustomEventProto = 95, + CustomEventCtor = 96, + EventTargetProto = 97, } impl BuiltinId { @@ -205,6 +214,15 @@ impl BuiltinId { BuiltinId::MessageChannelCtor, BuiltinId::BroadcastChannelProto, BuiltinId::BroadcastChannelCtor, + BuiltinId::EventProto, + BuiltinId::EventCtor, + BuiltinId::MessageEventProto, + BuiltinId::MessageEventCtor, + BuiltinId::ErrorEventProto, + BuiltinId::ErrorEventCtor, + BuiltinId::CustomEventProto, + BuiltinId::CustomEventCtor, + BuiltinId::EventTargetProto, ]; } @@ -282,6 +300,7 @@ pub struct BuiltinDirtySet { pub console: bool, pub message_channel: bool, pub broadcast_channel: bool, + pub event: bool, } impl BuiltinDirtySet { @@ -317,6 +336,7 @@ impl BuiltinDirtySet { console: true, message_channel: true, broadcast_channel: true, + event: true, } } @@ -346,6 +366,7 @@ impl BuiltinDirtySet { || self.console || self.message_channel || self.broadcast_channel + || self.event } /// 是否存在任何污染(builtin world 或 global object)。 @@ -358,13 +379,13 @@ impl BuiltinDirtySet { mod tests { use super::*; - /// 槽对齐面:ALL 表与判别值 0..88 严格同序,快照数组随 NUM_BUILTINS + /// 槽对齐面:ALL 表与判别值 0..97 严格同序,快照数组随 NUM_BUILTINS /// 自动扩维、逐槽对齐。 #[test] fn builtin_snapshot_all_slots_aligned() { - assert_eq!(NUM_BUILTINS, 89); + assert_eq!(NUM_BUILTINS, 98); assert_eq!(BuiltinId::ALL.len(), NUM_BUILTINS); - for i in 0..88usize { + for i in 0..97usize { assert_eq!(BuiltinId::ALL[i] as usize, i); } assert_eq!(BuiltinId::ALL[81], BuiltinId::SharedArrayBufferProto); @@ -375,6 +396,15 @@ mod tests { assert_eq!(BuiltinId::ALL[86], BuiltinId::MessageChannelCtor); assert_eq!(BuiltinId::ALL[87], BuiltinId::BroadcastChannelProto); assert_eq!(BuiltinId::ALL[88], BuiltinId::BroadcastChannelCtor); + assert_eq!(BuiltinId::ALL[89], BuiltinId::EventProto); + assert_eq!(BuiltinId::ALL[90], BuiltinId::EventCtor); + assert_eq!(BuiltinId::ALL[91], BuiltinId::MessageEventProto); + assert_eq!(BuiltinId::ALL[92], BuiltinId::MessageEventCtor); + assert_eq!(BuiltinId::ALL[93], BuiltinId::ErrorEventProto); + assert_eq!(BuiltinId::ALL[94], BuiltinId::ErrorEventCtor); + assert_eq!(BuiltinId::ALL[95], BuiltinId::CustomEventProto); + assert_eq!(BuiltinId::ALL[96], BuiltinId::CustomEventCtor); + assert_eq!(BuiltinId::ALL[97], BuiltinId::EventTargetProto); // 快照经 session 全量构造路径采集,generations 数组维度 = 槽数。 use crate::kernel::{KernelConfig, KernelCore, KernelSession}; diff --git a/crates/oxide_kernel/src/kernel/session.rs b/crates/oxide_kernel/src/kernel/session.rs index e5bd65a6..4e1481cc 100644 --- a/crates/oxide_kernel/src/kernel/session.rs +++ b/crates/oxide_kernel/src/kernel/session.rs @@ -200,6 +200,15 @@ impl KernelSession { || gen(BuiltinId::MessageChannelCtor) != snap(BuiltinId::MessageChannelCtor), broadcast_channel: gen(BuiltinId::BroadcastChannelProto) != snap(BuiltinId::BroadcastChannelProto) || gen(BuiltinId::BroadcastChannelCtor) != snap(BuiltinId::BroadcastChannelCtor), + event: gen(BuiltinId::EventProto) != snap(BuiltinId::EventProto) + || gen(BuiltinId::EventCtor) != snap(BuiltinId::EventCtor) + || gen(BuiltinId::MessageEventProto) != snap(BuiltinId::MessageEventProto) + || gen(BuiltinId::MessageEventCtor) != snap(BuiltinId::MessageEventCtor) + || gen(BuiltinId::ErrorEventProto) != snap(BuiltinId::ErrorEventProto) + || gen(BuiltinId::ErrorEventCtor) != snap(BuiltinId::ErrorEventCtor) + || gen(BuiltinId::CustomEventProto) != snap(BuiltinId::CustomEventProto) + || gen(BuiltinId::CustomEventCtor) != snap(BuiltinId::CustomEventCtor) + || gen(BuiltinId::EventTargetProto) != snap(BuiltinId::EventTargetProto), }; // wrapper 本体被写不落在任何家族位上(写的是 wrapper 自身而非所属 P // 对象):收缩为全脏,强制重建全部家族与 global,使被写的可复用 diff --git a/crates/oxide_runtime_api/src/host.rs b/crates/oxide_runtime_api/src/host.rs index b74003df..55026d4a 100644 --- a/crates/oxide_runtime_api/src/host.rs +++ b/crates/oxide_runtime_api/src/host.rs @@ -104,6 +104,12 @@ pub enum ProtoKind { MessagePortProto, // 广播通道原型 BroadcastChannelProto, + // 事件体系原型(EventTarget 原型不占 ProtoKind:builtins 不读它, + // 绑定层直接访问 world 的 event_target_proto 槽) + EventProto, + MessageEventProto, + ErrorEventProto, + CustomEventProto, } /// builtins 依赖的 `Vm` 能力集合。 diff --git a/crates/oxide_vm/src/bindings/bind_event.rs b/crates/oxide_vm/src/bindings/bind_event.rs new file mode 100644 index 00000000..22391974 --- /dev/null +++ b/crates/oxide_vm/src/bindings/bind_event.rs @@ -0,0 +1,28 @@ +//! Event 体系绑定:本文件是内核接线占位(零行为变化)。九枚 P 字段 +//! (Event / MessageEvent / ErrorEvent / CustomEvent 四枚原型与构造器对加 +//! EventTarget 原型)当前是空对象,本函数为它们的绑定入口预留,真实构造器 / +//! 原型方法 / 原型链连线由后续任务就地填充(不新建对象——P 字段本身就是槽位, +//! 快照 / 脏检查 / 收尾枚举已覆盖)。 + +use std::sync::Arc; + +use oxide_kernel::kernel::{KernelCore, KernelSession}; +use oxide_types::object::JsObject; + +/// Event 体系绑定入口(当前为空占位)。 +/// +/// # 幂等 +/// 本函数从三条路径到达:`init_kernel_builtins`(占位是空对象)、 +/// `rebind_dirty_builtins` 的 `event` 分支(占位是重建后的空对象)、 +/// global-dirty 路径(占位可能已填满)。本函数当前不写任何槽位,空操作天然 +/// 幂等;后续任务就地填充时,各槽写须沿用 `lookup_position` 前置守卫 +/// (有槽即跳过),保持与 `bind_broadcast_channel` 同型的幂等契约。 +/// +/// # 边界 +/// 九枚 P 字段是空对象占位,本函数不读不写,行为与未调用一致; +/// EventTarget 原型不占 ProtoKind(builtins 不读它),绑定层后续直接访问 +/// `world.event_target_proto` 槽。 +/// +/// `core` / `session` / `global` / `realm_id` 当前未使用,保留签名与其他 +/// 绑定函数一致,供后续任务就地填充时直接取用。 +pub fn bind_event(_core: &Arc, _session: &KernelSession, _global: &mut JsObject, _realm_id: u32) {} diff --git a/crates/oxide_vm/src/bindings/mod.rs b/crates/oxide_vm/src/bindings/mod.rs index aafe22d9..29695725 100644 --- a/crates/oxide_vm/src/bindings/mod.rs +++ b/crates/oxide_vm/src/bindings/mod.rs @@ -26,6 +26,8 @@ pub mod bind_date; pub mod bind_disposable_stack; /// Error 家族构造器与原型的 native 方法绑定(含各子类型构造器创建)。 pub mod bind_error; +/// Event 体系绑定入口(当前为空占位,九枚 P 字段由后续任务就地填充)。 +pub mod bind_event; /// Function 构造器与原型的 native 方法绑定。 pub mod bind_function; /// global 对象上的普通全局函数(parseInt、isNaN 等)绑定。 @@ -1343,6 +1345,9 @@ pub fn rebind_dirty_builtins( if dirty.map_or(true, |d| d.broadcast_channel) { bind_broadcast_channel::bind_broadcast_channel(core, session, global, realm_id); } + if dirty.map_or(true, |d| d.event) { + bind_event::bind_event(core, session, global, realm_id); + } if dirty.map_or(true, |d| d.console) { bind_console::bind_console(core, session, global); } diff --git a/crates/oxide_vm/src/vm/vmhost.rs b/crates/oxide_vm/src/vm/vmhost.rs index 313cbdba..cb4b1e87 100644 --- a/crates/oxide_vm/src/vm/vmhost.rs +++ b/crates/oxide_vm/src/vm/vmhost.rs @@ -144,6 +144,10 @@ impl oxide_runtime_api::VmHost for Vm { ProtoKind::BigUint64ArrayConstructor => &world.biguint64array_constructor, ProtoKind::MessagePortProto => &world.message_port_proto, ProtoKind::BroadcastChannelProto => &world.broadcast_channel_proto, + ProtoKind::EventProto => &world.event_proto, + ProtoKind::MessageEventProto => &world.message_event_proto, + ProtoKind::ErrorEventProto => &world.error_event_proto, + ProtoKind::CustomEventProto => &world.custom_event_proto, }; P::as_ptr(p) as *mut JsObject }