feat: Worker 事件处理器改原型访问器加 postMessage transfer 解析

This commit is contained in:
2026-10-11 08:49:17 +00:00
parent c4b441a1a8
commit 0ae232c3f5
6 changed files with 214 additions and 82 deletions
+1 -33
View File
@@ -5,7 +5,6 @@
//! 端口载荷盒(mpsc 双端与对端端口边)存于对象 `native_fn` 槽,向 GC 家族表
//! 暴露 edges/size/drop 三自由函数。
use std::collections::HashSet;
use std::mem;
use oxide_kernel::message_queue;
@@ -15,7 +14,7 @@ use oxide_types::value::JsValue;
use oxide_runtime_api::{NativeResult, ProtoKind, VmHost};
use crate::message_value::{detach_message, rehydrate_message, MessageValue};
use crate::message_value::{detach_message, parse_transfer_list, rehydrate_message, MessageValue};
/// MessagePort 载荷盒:存于对象 `native_fn` 槽(`Box::into_raw`,realm 局部
/// 单线程)。`peer` 是发往对端的 mpsc 发送端(无 GC 边),`rx` 是收自对端的
@@ -169,37 +168,6 @@ fn make_port_object<H: VmHost>(
(ptr, inner)
}
/// 解析 postMessage 的 transfer 参数为 ArrayBuffer 指针集合。
///
/// # 步骤
/// 1. undefined 返空集
/// 2. ToList 迭代一切可迭代(数组 / 字符串 / 生成器 / Map / Set)
/// 3. 每元素须为 ArrayBuffer,重复元素报 DataCloneError
///
/// # 边界
/// - 不可迭代对象经 GetIterator 抛 TypeError(原值透传);
/// - 迭代中途抛错经 IteratorClose 后透传原异常;
/// - 非 AB 元素 / 重复元素报 DataCloneError(与 structuredClone 口径统一)。
fn parse_transfer_list<H: VmHost>(vm: &mut H, transfer: JsValue) -> Result<HashSet<*const JsObject>, JsValue> {
let mut set = HashSet::new();
if transfer.is_undefined() {
return Ok(set);
}
crate::iterator::iterate_elements(vm, transfer, |vm, e| {
if !e.is_object() || !unsafe { &*e.as_js_object_ptr() }.is_array_buffer_obj() {
return Err(crate::structured_clone::data_clone_error(
vm,
"transfer list element is not an ArrayBuffer",
));
}
if !set.insert(e.as_js_object_ptr() as *const JsObject) {
return Err(crate::structured_clone::data_clone_error(vm, "duplicate buffer in transfer list"));
}
Ok(())
})?;
Ok(set)
}
/// MessagePort.postMessage(message, transfer):detach 消息、入队对端 mpsc、
/// 同步 `drain_port` 排空对端队列触发对端 onmessage。
///
@@ -84,6 +84,37 @@ impl DetachState {
}
}
/// 解析 postMessage 的 transfer 参数为 ArrayBuffer 指针集合。
///
/// # 步骤
/// 1. undefined 返空集
/// 2. ToList 迭代一切可迭代(数组 / 字符串 / 生成器 / Map / Set)
/// 3. 每元素须为 ArrayBuffer,重复元素报 DataCloneError
///
/// # 边界
/// - 不可迭代对象经 GetIterator 抛 TypeError(原值透传);
/// - 迭代中途抛错经 IteratorClose 后透传原异常;
/// - 非 AB 元素 / 重复元素报 DataCloneError(与 structuredClone 口径统一)。
pub fn parse_transfer_list<H: VmHost>(vm: &mut H, transfer: JsValue) -> Result<HashSet<*const JsObject>, JsValue> {
let mut set = HashSet::new();
if transfer.is_undefined() {
return Ok(set);
}
crate::iterator::iterate_elements(vm, transfer, |vm, e| {
if !e.is_object() || !unsafe { &*e.as_js_object_ptr() }.is_array_buffer_obj() {
return Err(crate::structured_clone::data_clone_error(
vm,
"transfer list element is not an ArrayBuffer",
));
}
if !set.insert(e.as_js_object_ptr() as *const JsObject) {
return Err(crate::structured_clone::data_clone_error(vm, "duplicate buffer in transfer list"));
}
Ok(())
})?;
Ok(set)
}
/// 源 realm 侧:遍历源值产出 `MessageValue`。
///
/// # 步骤