diff options
Diffstat (limited to 'components/script/dom/messageport.rs')
-rw-r--r-- | components/script/dom/messageport.rs | 115 |
1 files changed, 36 insertions, 79 deletions
diff --git a/components/script/dom/messageport.rs b/components/script/dom/messageport.rs index e8a3b3ac695..f10ba10383e 100644 --- a/components/script/dom/messageport.rs +++ b/components/script/dom/messageport.rs @@ -4,15 +4,15 @@ use std::cell::{Cell, RefCell}; use std::collections::HashMap; -use std::convert::TryInto; use std::num::NonZeroU32; use std::rc::Rc; use base::id::{MessagePortId, MessagePortIndex, PipelineNamespaceId}; use dom_struct::dom_struct; -use js::jsapi::{Heap, JSObject, MutableHandleObject}; +use js::jsapi::{Heap, JSObject}; use js::rust::{CustomAutoRooter, CustomAutoRooterGuard, HandleValue}; use script_traits::PortMessageTask; +use script_traits::transferable::MessagePortImpl; use crate::dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull; use crate::dom::bindings::codegen::Bindings::MessagePortBinding::{ @@ -21,11 +21,11 @@ use crate::dom::bindings::codegen::Bindings::MessagePortBinding::{ use crate::dom::bindings::conversions::root_from_object; use crate::dom::bindings::error::{Error, ErrorResult}; use crate::dom::bindings::inheritance::Castable; -use crate::dom::bindings::reflector::{DomGlobal, DomObject, reflect_dom_object}; +use crate::dom::bindings::reflector::{DomGlobal, reflect_dom_object}; use crate::dom::bindings::root::DomRoot; -use crate::dom::bindings::structuredclone::{self, StructuredDataReader, StructuredDataWriter}; +use crate::dom::bindings::structuredclone::{self, StructuredData, StructuredDataReader}; use crate::dom::bindings::trace::RootedTraceableBox; -use crate::dom::bindings::transferable::Transferable; +use crate::dom::bindings::transferable::{ExtractComponents, IdFromComponents, Transferable}; use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; use crate::script_runtime::{CanGc, JSContext as SafeJSContext}; @@ -160,8 +160,11 @@ impl MessagePort { } impl Transferable for MessagePort { + type Id = MessagePortId; + type Data = MessagePortImpl; + /// <https://html.spec.whatwg.org/multipage/#message-ports:transfer-steps> - fn transfer(&self, sc_writer: &mut StructuredDataWriter) -> Result<u64, ()> { + fn transfer(&self) -> Result<(MessagePortId, MessagePortImpl), ()> { if self.detached.get() { return Err(()); } @@ -172,91 +175,45 @@ impl Transferable for MessagePort { // 1. Run local transfer logic, and return the object to be transferred. let transferred_port = self.global().mark_port_as_transferred(id); - // 2. Store the transferred object at a given key. - if let Some(ports) = sc_writer.ports.as_mut() { - ports.insert(*id, transferred_port); - } else { - let mut ports = HashMap::new(); - ports.insert(*id, transferred_port); - sc_writer.ports = Some(ports); - } - - let PipelineNamespaceId(name_space) = (id).namespace_id; - let MessagePortIndex(index) = (id).index; - let index = index.get(); - - let mut big: [u8; 8] = [0; 8]; - let name_space = name_space.to_ne_bytes(); - let index = index.to_ne_bytes(); - - let (left, right) = big.split_at_mut(4); - left.copy_from_slice(&name_space); - right.copy_from_slice(&index); - - // 3. Return a u64 representation of the key where the object is stored. - Ok(u64::from_ne_bytes(big)) + Ok((*id, transferred_port)) } /// <https://html.spec.whatwg.org/multipage/#message-ports:transfer-receiving-steps> fn transfer_receive( owner: &GlobalScope, - sc_reader: &mut StructuredDataReader, - extra_data: u64, - return_object: MutableHandleObject, - ) -> Result<(), ()> { - // 1. Re-build the key for the storage location - // of the transferred object. - let big: [u8; 8] = extra_data.to_ne_bytes(); - let (name_space, index) = big.split_at(4); - - let namespace_id = PipelineNamespaceId(u32::from_ne_bytes( - name_space - .try_into() - .expect("name_space to be a slice of four."), - )); - let index = MessagePortIndex( - NonZeroU32::new(u32::from_ne_bytes( - index.try_into().expect("index to be a slice of four."), - )) - .expect("Index to be non-zero"), - ); - - let id = MessagePortId { - namespace_id, - index, - }; - - // 2. Get the transferred object from its storage, using the key. - // Assign the transfer-received port-impl, and total number of transferred ports. - let (ports_len, port_impl) = if let Some(ports) = sc_reader.port_impls.as_mut() { - let ports_len = ports.len(); - let port_impl = ports.remove(&id).expect("Transferred port to be stored"); - if ports.is_empty() { - sc_reader.port_impls = None; - } - (ports_len, port_impl) - } else { - panic!( - "A messageport was transfer-received, yet the SC holder does not have any port impls" - ); - }; - + id: MessagePortId, + port_impl: MessagePortImpl, + ) -> Result<DomRoot<Self>, ()> { let transferred_port = MessagePort::new_transferred(owner, id, port_impl.entangled_port_id(), CanGc::note()); owner.track_message_port(&transferred_port, Some(port_impl)); + Ok(transferred_port) + } + + fn serialized_storage(data: StructuredData<'_>) -> &mut Option<HashMap<Self::Id, Self::Data>> { + match data { + StructuredData::Reader(r) => &mut r.port_impls, + StructuredData::Writer(w) => &mut w.ports, + } + } - return_object.set(transferred_port.reflector().rootable().get()); + fn deserialized_storage(reader: &mut StructuredDataReader) -> &mut Option<Vec<DomRoot<Self>>> { + &mut reader.message_ports + } +} - // Store the DOM port where it will be passed along to script in the message-event. - if let Some(ports) = sc_reader.message_ports.as_mut() { - ports.push(transferred_port); - } else { - let mut ports = Vec::with_capacity(ports_len); - ports.push(transferred_port); - sc_reader.message_ports = Some(ports); +impl IdFromComponents for MessagePortId { + fn from(namespace_id: PipelineNamespaceId, index: NonZeroU32) -> MessagePortId { + MessagePortId { + namespace_id, + index: MessagePortIndex(index), } + } +} - Ok(()) +impl ExtractComponents for MessagePortId { + fn components(&self) -> (PipelineNamespaceId, NonZeroU32) { + (self.namespace_id, self.index.0) } } |