feat: 事件目标弱引用注册表加三方法加原型链

This commit is contained in:
2026-10-10 09:06:08 +00:00
parent 8a8c3e9b9c
commit 6ecd3aed89
20 changed files with 890 additions and 123 deletions
+17 -16
View File
@@ -287,42 +287,43 @@ pub(crate) fn self_location(vm: &mut Vm, _args: &[u8]) -> NativeResult {
NativeResult::Ok(vm.new_string(""))
}
/// 事件构造辅助:建事件对象(`data` + `type` + `message` 属性)。
/// 事件构造辅助:建真实 Event 盒(`type` 字段)加 `data` / `message` 普通属性。
///
/// 消息事件与错误事件同型,共用本辅助:消息事件 `message` 为 undefined,
/// 错误事件 `data` 为 undefined、`message` 为错误串。
///
/// # 步骤
/// 1. 建 PLAIN 对象(`[[Prototype]]` → `%Object.prototype%`)。
/// 2. define `data` 属性(rehydrate 后的消息值,可枚举)。
/// 3. define `type` 属性(事件类型串,可枚举)。
/// 4. define `message` 属性(错误消息串,可枚举;消息事件为 undefined)。
/// 5. 返回对象。
/// 1. 经 `create_event_box` 建真实 Event 盒(`type` 取 `type_val` 的字符串形态,
/// `[[Prototype]]` → `Event.prototype`),使 `dispatchEvent` 品牌守卫通过。
/// 2. define `data` 属性(rehydrate 后的消息值,可枚举;GC 边)。
/// 3. `message` 非 undefined 时 define `message` 属性(错误消息串,可枚举)。
/// 4. 返回对象。
///
/// # 边界与前提
/// - `data` 是 rehydrate 后的消息值(GC 边,经 `alloc_object` 入对象表即成根)。
/// - `data` 是 rehydrate 后的消息值(GC 边,经属性区入 mark)。
/// - `type` 是事件类型串(`"message"`/`"error"`/`"messageerror"`)。
/// - `message` 是错误消息串(仅错误事件定义,消息事件为 undefined)。
/// - Event 盒无 `data` 字段(8.4 的 MessageEvent 才补),`data` 作盒对象普通属性。
///
/// # 副作用
/// - 新建一个事件对象(经 `alloc_object` 入对象表)。
/// - 新建一个 Event 盒对象(经 `alloc_object` 入对象表)。
pub(crate) fn message_event_constructor(vm: &mut Vm, args: &[u8]) -> NativeResult {
let data_val = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() };
let type_val = if args.len() > 2 { vm.reg(args[2]) } else { JsValue::undefined() };
let message_val = if args.len() > 3 { vm.reg(args[3]) } else { JsValue::undefined() };
let object_proto = JsValue::from_js_object(vm.builtin_proto(ProtoKind::ObjectProto));
let obj = JsObject::new_empty(EMPTY_SHAPE_ID, object_proto);
let ptr = vm.alloc_object(obj);
// SAFETY: ptr 是本函数刚 alloc_object 的对象,存活且本段无别名。
// 建真实 Event 盒(type 取 type_val 的字符串形态)。
let type_text = vm.lookup_str(type_val).unwrap_or_default();
let ptr = oxide_builtins::event::create_event_box(vm, &type_text);
// SAFETY: ptr 是 create_event_box 刚 alloc_object 的对象,存活且本段无别名。
let event_obj = unsafe { &mut *ptr };
let si_data = vm.perm_intern("data");
let _ = vm.define_data_property(event_obj, si_data, data_val, PropAttributes::DEFAULT_DATA);
let si_type = vm.perm_intern("type");
let _ = vm.define_data_property(event_obj, si_type, type_val, PropAttributes::DEFAULT_DATA);
let si_message = vm.perm_intern("message");
let _ = vm.define_data_property(event_obj, si_message, message_val, PropAttributes::DEFAULT_DATA);
if !message_val.is_undefined() {
let si_message = vm.perm_intern("message");
let _ = vm.define_data_property(event_obj, si_message, message_val, PropAttributes::DEFAULT_DATA);
}
NativeResult::Ok(JsValue::from_js_object(ptr))
}