diff options
-rw-r--r-- | Cargo.lock | 8 | ||||
-rw-r--r-- | components/compositing/webview_manager.rs | 8 | ||||
-rw-r--r-- | components/constellation/webview_manager.rs | 8 | ||||
-rw-r--r-- | components/script/dom/bindings/serializable.rs | 29 | ||||
-rw-r--r-- | components/script/dom/bindings/structuredclone.rs | 24 | ||||
-rw-r--r-- | components/script/dom/bindings/transferable.rs | 26 | ||||
-rw-r--r-- | components/script/dom/blob.rs | 31 | ||||
-rw-r--r-- | components/script/dom/domexception.rs | 34 | ||||
-rw-r--r-- | components/script/dom/dompoint.rs | 10 | ||||
-rw-r--r-- | components/script/dom/dompointreadonly.rs | 34 | ||||
-rw-r--r-- | components/script/dom/messageport.rs | 26 | ||||
-rw-r--r-- | components/script/dom/readablestream.rs | 10 | ||||
-rw-r--r-- | components/script/dom/writablestream.rs | 8 | ||||
-rw-r--r-- | components/shared/base/id.rs | 259 |
14 files changed, 174 insertions, 341 deletions
diff --git a/Cargo.lock b/Cargo.lock index f027c1db8da..30347b741a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -971,18 +971,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.36" +version = "4.5.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2df961d8c8a0d08aa9945718ccf584145eee3f3aa06cddbeac12933781102e04" +checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.36" +version = "4.5.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "132dbda40fb6753878316a489d5a1242a8ef2f0d9e47ba01c951ea8aa7d013a5" +checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2" dependencies = [ "anstyle", "clap_lex", diff --git a/components/compositing/webview_manager.rs b/components/compositing/webview_manager.rs index 42e9bfe1cb7..201f9d1c5c5 100644 --- a/components/compositing/webview_manager.rs +++ b/components/compositing/webview_manager.rs @@ -111,11 +111,7 @@ impl<WebView> WebViewManager<WebView> { #[cfg(test)] mod test { - use std::num::NonZeroU32; - - use base::id::{ - BrowsingContextId, BrowsingContextIndex, PipelineNamespace, PipelineNamespaceId, WebViewId, - }; + use base::id::{BrowsingContextId, Index, PipelineNamespace, PipelineNamespaceId, WebViewId}; use crate::webview_manager::WebViewManager; use crate::webview_renderer::UnknownWebView; @@ -123,7 +119,7 @@ mod test { fn top_level_id(namespace_id: u32, index: u32) -> WebViewId { WebViewId(BrowsingContextId { namespace_id: PipelineNamespaceId(namespace_id), - index: BrowsingContextIndex(NonZeroU32::new(index).unwrap()), + index: Index::new(index).unwrap(), }) } diff --git a/components/constellation/webview_manager.rs b/components/constellation/webview_manager.rs index e5e427d40a1..7d6e98a54ea 100644 --- a/components/constellation/webview_manager.rs +++ b/components/constellation/webview_manager.rs @@ -81,18 +81,14 @@ impl<WebView> WebViewManager<WebView> { #[cfg(test)] mod test { - use std::num::NonZeroU32; - - use base::id::{ - BrowsingContextId, BrowsingContextIndex, PipelineNamespace, PipelineNamespaceId, WebViewId, - }; + use base::id::{BrowsingContextId, Index, PipelineNamespace, PipelineNamespaceId, WebViewId}; use crate::webview_manager::WebViewManager; fn id(namespace_id: u32, index: u32) -> WebViewId { WebViewId(BrowsingContextId { namespace_id: PipelineNamespaceId(namespace_id), - index: BrowsingContextIndex(NonZeroU32::new(index).expect("Incorrect test case")), + index: Index::new(index).expect("Incorrect test case"), }) } diff --git a/components/script/dom/bindings/serializable.rs b/components/script/dom/bindings/serializable.rs index b791b0ebc1a..4aa1a94a0a4 100644 --- a/components/script/dom/bindings/serializable.rs +++ b/components/script/dom/bindings/serializable.rs @@ -6,9 +6,8 @@ //! (<https://html.spec.whatwg.org/multipage/#serializable-objects>). use std::collections::HashMap; -use std::num::NonZeroU32; -use base::id::PipelineNamespaceId; +use base::id::{Index, NamespaceIndex, PipelineNamespaceId}; use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::root::DomRoot; @@ -25,9 +24,9 @@ pub(crate) struct StorageKey { } impl StorageKey { - pub(crate) fn new(name_space: PipelineNamespaceId, index: NonZeroU32) -> StorageKey { - let name_space = name_space.0.to_ne_bytes(); - let index = index.get().to_ne_bytes(); + pub(crate) fn new<T>(index: NamespaceIndex<T>) -> StorageKey { + let name_space = index.namespace_id.0.to_ne_bytes(); + let index = index.index.0.get().to_ne_bytes(); StorageKey { index: u32::from_ne_bytes(index), name_space: u32::from_ne_bytes(name_space), @@ -35,11 +34,13 @@ impl StorageKey { } } -pub(crate) trait IntoStorageKey -where - Self: Sized, -{ - fn into_storage_key(self) -> StorageKey; +impl<T> From<StorageKey> for NamespaceIndex<T> { + fn from(key: StorageKey) -> NamespaceIndex<T> { + NamespaceIndex { + namespace_id: PipelineNamespaceId(key.name_space), + index: Index::new(key.index).expect("Index must not be zero"), + } + } } /// Interface for serializable platform objects. @@ -48,11 +49,11 @@ pub(crate) trait Serializable: DomObject where Self: Sized, { - type Id: Copy + Eq + std::hash::Hash + IntoStorageKey + From<StorageKey>; + type Index: Copy + Eq + std::hash::Hash; type Data; /// <https://html.spec.whatwg.org/multipage/#serialization-steps> - fn serialize(&self) -> Result<(Self::Id, Self::Data), ()>; + fn serialize(&self) -> Result<(NamespaceIndex<Self::Index>, Self::Data), ()>; /// <https://html.spec.whatwg.org/multipage/#deserialization-steps> fn deserialize( owner: &GlobalScope, @@ -64,7 +65,9 @@ where /// Returns the field of [StructuredDataReader]/[StructuredDataWriter] that /// should be used to read/store serialized instances of this type. - fn serialized_storage(data: StructuredData<'_>) -> &mut Option<HashMap<Self::Id, Self::Data>>; + fn serialized_storage( + data: StructuredData<'_>, + ) -> &mut Option<HashMap<NamespaceIndex<Self::Index>, Self::Data>>; /// Returns the field of [StructuredDataReader] that should be used to store /// deserialized instances of this type. diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index ebd881a04f5..915a4951bb5 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -6,11 +6,12 @@ use std::collections::HashMap; use std::ffi::CStr; -use std::num::NonZeroU32; use std::os::raw; use std::ptr; -use base::id::{BlobId, DomExceptionId, DomPointId, MessagePortId, PipelineNamespaceId}; +use base::id::{ + BlobId, DomExceptionId, DomPointId, Index, MessagePortId, NamespaceIndex, PipelineNamespaceId, +}; use constellation_traits::{ BlobImpl, DomException, DomPoint, MessagePortImpl, Serializable as SerializableInterface, StructuredSerializedData, Transferrable as TransferrableInterface, @@ -34,8 +35,8 @@ use strum::IntoEnumIterator; use crate::dom::bindings::conversions::{ToJSValConvertible, root_from_object}; use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::root::DomRoot; -use crate::dom::bindings::serializable::{IntoStorageKey, Serializable, StorageKey}; -use crate::dom::bindings::transferable::{ExtractComponents, IdFromComponents, Transferable}; +use crate::dom::bindings::serializable::{Serializable, StorageKey}; +use crate::dom::bindings::transferable::Transferable; use crate::dom::blob::Blob; use crate::dom::dompoint::DOMPoint; use crate::dom::dompointreadonly::DOMPointReadOnly; @@ -120,7 +121,7 @@ unsafe fn read_object<T: Serializable>( // 1. Re-build the key for the storage location // of the serialized object. - let id = T::Id::from(storage_key); + let id: NamespaceIndex<T::Index> = storage_key.into(); // 2. Get the transferred object from its storage, using the key. let objects = T::serialized_storage(StructuredData::Reader(sc_reader)); @@ -155,7 +156,7 @@ unsafe fn write_object<T: Serializable>( let objects = T::serialized_storage(StructuredData::Writer(sc_writer)) .get_or_insert_with(HashMap::new); objects.insert(new_id, serialized); - let storage_key = new_id.into_storage_key(); + let storage_key = StorageKey::new(new_id); assert!(JS_WriteUint32Pair( w, @@ -282,13 +283,13 @@ fn receive_object<T: Transferable>( .try_into() .expect("name_space to be a slice of four."), )); - let id = <T::Id as IdFromComponents>::from( + let id: NamespaceIndex<T::Index> = NamespaceIndex { namespace_id, - NonZeroU32::new(u32::from_ne_bytes( + index: Index::new(u32::from_ne_bytes( index.try_into().expect("index to be a slice of four."), )) .expect("Index to be non-zero"), - ); + }; // 2. Get the transferred object from its storage, using the key. let storage = T::serialized_storage(StructuredData::Reader(sc_reader)); @@ -356,11 +357,10 @@ unsafe fn try_transfer<T: Transferable + IDLInterface>( .get_or_insert_with(HashMap::new); objects.insert(id, object); - let (PipelineNamespaceId(name_space), index) = id.components(); - let index = index.get(); + let index = id.index.0.get(); let mut big: [u8; 8] = [0; 8]; - let name_space = name_space.to_ne_bytes(); + let name_space = id.namespace_id.0.to_ne_bytes(); let index = index.to_ne_bytes(); let (left, right) = big.split_at_mut(4); diff --git a/components/script/dom/bindings/transferable.rs b/components/script/dom/bindings/transferable.rs index 7c052e41294..b720c05ae37 100644 --- a/components/script/dom/bindings/transferable.rs +++ b/components/script/dom/bindings/transferable.rs @@ -6,44 +6,34 @@ //! (<https://html.spec.whatwg.org/multipage/#transferable-objects>). use std::collections::HashMap; -use std::num::NonZeroU32; +use std::hash::Hash; -use base::id::PipelineNamespaceId; +use base::id::NamespaceIndex; use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::structuredclone::{StructuredData, StructuredDataReader}; use crate::dom::globalscope::GlobalScope; - -pub(crate) trait IdFromComponents -where - Self: Sized, -{ - fn from(namespace_id: PipelineNamespaceId, index: NonZeroU32) -> Self; -} - -pub(crate) trait ExtractComponents { - fn components(&self) -> (PipelineNamespaceId, NonZeroU32); -} - pub(crate) trait Transferable: DomObject where Self: Sized, { - type Id: Eq + std::hash::Hash + Copy + IdFromComponents + ExtractComponents; + type Index: Copy + Eq + Hash; type Data; fn can_transfer(&self) -> bool { true } - fn transfer(&self) -> Result<(Self::Id, Self::Data), ()>; + fn transfer(&self) -> Result<(NamespaceIndex<Self::Index>, Self::Data), ()>; fn transfer_receive( owner: &GlobalScope, - id: Self::Id, + id: NamespaceIndex<Self::Index>, serialized: Self::Data, ) -> Result<DomRoot<Self>, ()>; - fn serialized_storage(data: StructuredData<'_>) -> &mut Option<HashMap<Self::Id, Self::Data>>; + fn serialized_storage( + data: StructuredData<'_>, + ) -> &mut Option<HashMap<NamespaceIndex<Self::Index>, Self::Data>>; fn deserialized_storage(reader: &mut StructuredDataReader) -> &mut Option<Vec<DomRoot<Self>>>; } diff --git a/components/script/dom/blob.rs b/components/script/dom/blob.rs index 5f9d4052929..df2afafd698 100644 --- a/components/script/dom/blob.rs +++ b/components/script/dom/blob.rs @@ -3,11 +3,10 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use std::collections::HashMap; -use std::num::NonZeroU32; use std::ptr; use std::rc::Rc; -use base::id::{BlobId, BlobIndex, PipelineNamespaceId}; +use base::id::{BlobId, BlobIndex}; use constellation_traits::BlobImpl; use dom_struct::dom_struct; use encoding_rs::UTF_8; @@ -25,7 +24,7 @@ use crate::dom::bindings::codegen::UnionTypes::ArrayBufferOrArrayBufferViewOrBlo use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object_with_proto}; use crate::dom::bindings::root::DomRoot; -use crate::dom::bindings::serializable::{IntoStorageKey, Serializable, StorageKey}; +use crate::dom::bindings::serializable::{Serializable, StorageKey}; use crate::dom::bindings::str::DOMString; use crate::dom::bindings::structuredclone::{StructuredData, StructuredDataReader}; use crate::dom::globalscope::GlobalScope; @@ -94,7 +93,7 @@ impl Blob { } impl Serializable for Blob { - type Id = BlobId; + type Index = BlobIndex; type Data = BlobImpl; /// <https://w3c.github.io/FileAPI/#ref-for-serialization-steps> @@ -120,9 +119,7 @@ impl Serializable for Blob { Ok(deserialized_blob) } - fn serialized_storage( - reader: StructuredData<'_>, - ) -> &mut Option<HashMap<Self::Id, Self::Data>> { + fn serialized_storage(reader: StructuredData<'_>) -> &mut Option<HashMap<BlobId, Self::Data>> { match reader { StructuredData::Reader(r) => &mut r.blob_impls, StructuredData::Writer(w) => &mut w.blobs, @@ -136,26 +133,6 @@ impl Serializable for Blob { } } -impl From<StorageKey> for BlobId { - fn from(storage_key: StorageKey) -> BlobId { - let namespace_id = PipelineNamespaceId(storage_key.name_space); - let index = - BlobIndex(NonZeroU32::new(storage_key.index).expect("Deserialized blob index is zero")); - - BlobId { - namespace_id, - index, - } - } -} - -impl IntoStorageKey for BlobId { - fn into_storage_key(self) -> StorageKey { - let BlobIndex(index) = self.index; - StorageKey::new(self.namespace_id, index) - } -} - /// Extract bytes from BlobParts, used by Blob and File constructor /// <https://w3c.github.io/FileAPI/#constructorBlob> #[allow(unsafe_code)] diff --git a/components/script/dom/domexception.rs b/components/script/dom/domexception.rs index 35a21556a2d..e63c3ff1f53 100644 --- a/components/script/dom/domexception.rs +++ b/components/script/dom/domexception.rs @@ -3,9 +3,8 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use std::collections::HashMap; -use std::num::NonZeroU32; -use base::id::{DomExceptionId, DomExceptionIndex, PipelineNamespaceId}; +use base::id::{DomExceptionId, DomExceptionIndex}; use constellation_traits::DomException; use dom_struct::dom_struct; use js::rust::HandleObject; @@ -18,7 +17,7 @@ use crate::dom::bindings::reflector::{ Reflector, reflect_dom_object, reflect_dom_object_with_proto, }; use crate::dom::bindings::root::DomRoot; -use crate::dom::bindings::serializable::{IntoStorageKey, Serializable, StorageKey}; +use crate::dom::bindings::serializable::{Serializable, StorageKey}; use crate::dom::bindings::str::DOMString; use crate::dom::bindings::structuredclone::{StructuredData, StructuredDataReader}; use crate::dom::globalscope::GlobalScope; @@ -224,11 +223,11 @@ impl DOMExceptionMethods<crate::DomTypeHolder> for DOMException { } impl Serializable for DOMException { - type Id = DomExceptionId; + type Index = DomExceptionIndex; type Data = DomException; // https://webidl.spec.whatwg.org/#idl-DOMException - fn serialize(&self) -> Result<(Self::Id, Self::Data), ()> { + fn serialize(&self) -> Result<(DomExceptionId, Self::Data), ()> { let serialized = DomException { message: self.message.to_string(), name: self.name.to_string(), @@ -253,7 +252,9 @@ impl Serializable for DOMException { )) } - fn serialized_storage(data: StructuredData<'_>) -> &mut Option<HashMap<Self::Id, Self::Data>> { + fn serialized_storage( + data: StructuredData<'_>, + ) -> &mut Option<HashMap<DomExceptionId, Self::Data>> { match data { StructuredData::Reader(reader) => &mut reader.exceptions, StructuredData::Writer(writer) => &mut writer.exceptions, @@ -266,24 +267,3 @@ impl Serializable for DOMException { &mut reader.dom_exceptions } } - -impl From<StorageKey> for DomExceptionId { - fn from(storage_key: StorageKey) -> DomExceptionId { - let namespace_id = PipelineNamespaceId(storage_key.name_space); - let index = DomExceptionIndex( - NonZeroU32::new(storage_key.index).expect("Deserialized exception index is zero"), - ); - - DomExceptionId { - namespace_id, - index, - } - } -} - -impl IntoStorageKey for DomExceptionId { - fn into_storage_key(self) -> StorageKey { - let DomExceptionIndex(index) = self.index; - StorageKey::new(self.namespace_id, index) - } -} diff --git a/components/script/dom/dompoint.rs b/components/script/dom/dompoint.rs index c6323b28cf7..006abb50def 100644 --- a/components/script/dom/dompoint.rs +++ b/components/script/dom/dompoint.rs @@ -4,7 +4,7 @@ use std::collections::HashMap; -use base::id::DomPointId; +use base::id::{DomPointId, DomPointIndex}; use constellation_traits::DomPoint; use dom_struct::dom_struct; use js::rust::HandleObject; @@ -132,10 +132,10 @@ impl DOMPointMethods<crate::DomTypeHolder> for DOMPoint { } impl Serializable for DOMPoint { - type Id = DomPointId; + type Index = DomPointIndex; type Data = DomPoint; - fn serialize(&self) -> Result<(Self::Id, Self::Data), ()> { + fn serialize(&self) -> Result<(DomPointId, Self::Data), ()> { let serialized = DomPoint { x: self.X(), y: self.Y(), @@ -163,7 +163,9 @@ impl Serializable for DOMPoint { )) } - fn serialized_storage(data: StructuredData<'_>) -> &mut Option<HashMap<Self::Id, Self::Data>> { + fn serialized_storage( + data: StructuredData<'_>, + ) -> &mut Option<HashMap<DomPointId, Self::Data>> { match data { StructuredData::Reader(reader) => &mut reader.points, StructuredData::Writer(writer) => &mut writer.points, diff --git a/components/script/dom/dompointreadonly.rs b/components/script/dom/dompointreadonly.rs index 0bd6d5742c7..44e4a70b680 100644 --- a/components/script/dom/dompointreadonly.rs +++ b/components/script/dom/dompointreadonly.rs @@ -4,9 +4,8 @@ use std::cell::Cell; use std::collections::HashMap; -use std::num::NonZeroU32; -use base::id::{DomPointId, DomPointIndex, PipelineNamespaceId}; +use base::id::{DomPointId, DomPointIndex}; use constellation_traits::DomPoint; use dom_struct::dom_struct; use js::rust::HandleObject; @@ -16,7 +15,7 @@ use crate::dom::bindings::codegen::Bindings::DOMPointReadOnlyBinding::DOMPointRe use crate::dom::bindings::error::Fallible; use crate::dom::bindings::reflector::{Reflector, reflect_dom_object_with_proto}; use crate::dom::bindings::root::DomRoot; -use crate::dom::bindings::serializable::{IntoStorageKey, Serializable, StorageKey}; +use crate::dom::bindings::serializable::{Serializable, StorageKey}; use crate::dom::bindings::structuredclone::{StructuredData, StructuredDataReader}; use crate::dom::globalscope::GlobalScope; use crate::script_runtime::CanGc; @@ -142,10 +141,10 @@ impl DOMPointWriteMethods for DOMPointReadOnly { } impl Serializable for DOMPointReadOnly { - type Id = DomPointId; + type Index = DomPointIndex; type Data = DomPoint; - fn serialize(&self) -> Result<(Self::Id, Self::Data), ()> { + fn serialize(&self) -> Result<(DomPointId, Self::Data), ()> { let serialized = DomPoint { x: self.x.get(), y: self.y.get(), @@ -173,7 +172,9 @@ impl Serializable for DOMPointReadOnly { )) } - fn serialized_storage(data: StructuredData<'_>) -> &mut Option<HashMap<Self::Id, Self::Data>> { + fn serialized_storage( + data: StructuredData<'_>, + ) -> &mut Option<HashMap<DomPointId, Self::Data>> { match data { StructuredData::Reader(r) => &mut r.points, StructuredData::Writer(w) => &mut w.points, @@ -186,24 +187,3 @@ impl Serializable for DOMPointReadOnly { &mut reader.points_read_only } } - -impl From<StorageKey> for DomPointId { - fn from(storage_key: StorageKey) -> DomPointId { - let namespace_id = PipelineNamespaceId(storage_key.name_space); - let index = DomPointIndex( - NonZeroU32::new(storage_key.index).expect("Deserialized point index is zero"), - ); - - DomPointId { - namespace_id, - index, - } - } -} - -impl IntoStorageKey for DomPointId { - fn into_storage_key(self) -> StorageKey { - let DomPointIndex(index) = self.index; - StorageKey::new(self.namespace_id, index) - } -} diff --git a/components/script/dom/messageport.rs b/components/script/dom/messageport.rs index c3904dbb19a..fe590052db4 100644 --- a/components/script/dom/messageport.rs +++ b/components/script/dom/messageport.rs @@ -4,11 +4,10 @@ use std::cell::{Cell, RefCell}; use std::collections::HashMap; -use std::num::NonZeroU32; use std::ptr; use std::rc::Rc; -use base::id::{MessagePortId, MessagePortIndex, PipelineNamespaceId}; +use base::id::{MessagePortId, MessagePortIndex}; use constellation_traits::{MessagePortImpl, PortMessageTask}; use dom_struct::dom_struct; use js::jsapi::{Heap, JS_NewObject, JSObject}; @@ -26,7 +25,7 @@ use crate::dom::bindings::reflector::{DomGlobal, reflect_dom_object}; use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::structuredclone::{self, StructuredData, StructuredDataReader}; use crate::dom::bindings::trace::RootedTraceableBox; -use crate::dom::bindings::transferable::{ExtractComponents, IdFromComponents, Transferable}; +use crate::dom::bindings::transferable::Transferable; use crate::dom::bindings::utils::set_dictionary_property; use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; @@ -239,7 +238,7 @@ impl MessagePort { } impl Transferable for MessagePort { - type Id = MessagePortId; + type Index = MessagePortIndex; type Data = MessagePortImpl; /// <https://html.spec.whatwg.org/multipage/#message-ports:transfer-steps> @@ -269,7 +268,9 @@ impl Transferable for MessagePort { Ok(transferred_port) } - fn serialized_storage(data: StructuredData<'_>) -> &mut Option<HashMap<Self::Id, Self::Data>> { + fn serialized_storage( + data: StructuredData<'_>, + ) -> &mut Option<HashMap<MessagePortId, Self::Data>> { match data { StructuredData::Reader(r) => &mut r.port_impls, StructuredData::Writer(w) => &mut w.ports, @@ -281,21 +282,6 @@ impl Transferable for MessagePort { } } -impl IdFromComponents for MessagePortId { - fn from(namespace_id: PipelineNamespaceId, index: NonZeroU32) -> MessagePortId { - MessagePortId { - namespace_id, - index: MessagePortIndex(index), - } - } -} - -impl ExtractComponents for MessagePortId { - fn components(&self) -> (PipelineNamespaceId, NonZeroU32) { - (self.namespace_id, self.index.0) - } -} - impl MessagePortMethods<crate::DomTypeHolder> for MessagePort { /// <https://html.spec.whatwg.org/multipage/#dom-messageport-postmessage> fn PostMessage( diff --git a/components/script/dom/readablestream.rs b/components/script/dom/readablestream.rs index 49e740c6d6e..b445fb4b9fc 100644 --- a/components/script/dom/readablestream.rs +++ b/components/script/dom/readablestream.rs @@ -8,6 +8,8 @@ use std::ptr::{self}; use std::rc::Rc; use std::collections::HashMap; +use base::id::{MessagePortId, MessagePortIndex}; +use constellation_traits::MessagePortImpl; use dom_struct::dom_struct; use js::conversions::ToJSValConvertible; use js::jsapi::{Heap, JSObject}; @@ -56,8 +58,6 @@ use crate::js::conversions::FromJSValConvertible; use crate::realms::{enter_realm, InRealm}; use crate::script_runtime::{CanGc, JSContext as SafeJSContext}; use crate::dom::promisenativehandler::{Callback, PromiseNativeHandler}; -use base::id::MessagePortId; -use constellation_traits::MessagePortImpl; use crate::dom::bindings::transferable::Transferable; use crate::dom::bindings::structuredclone::{StructuredData, StructuredDataReader}; @@ -2179,7 +2179,7 @@ pub(crate) fn get_read_promise_bytes( /// <https://streams.spec.whatwg.org/#rs-transfer> impl Transferable for ReadableStream { - type Id = MessagePortId; + type Index = MessagePortIndex; type Data = MessagePortImpl; /// <https://streams.spec.whatwg.org/#ref-for-readablestream%E2%91%A1%E2%91%A0> @@ -2247,7 +2247,9 @@ impl Transferable for ReadableStream { } /// Note: we are relying on the port transfer, so the data returned here are related to the port. - fn serialized_storage(data: StructuredData<'_>) -> &mut Option<HashMap<Self::Id, Self::Data>> { + fn serialized_storage( + data: StructuredData<'_>, + ) -> &mut Option<HashMap<MessagePortId, Self::Data>> { match data { StructuredData::Reader(r) => &mut r.port_impls, StructuredData::Writer(w) => &mut w.ports, diff --git a/components/script/dom/writablestream.rs b/components/script/dom/writablestream.rs index da0fe3b5957..1490fc694ef 100644 --- a/components/script/dom/writablestream.rs +++ b/components/script/dom/writablestream.rs @@ -8,7 +8,7 @@ use std::mem; use std::ptr::{self}; use std::rc::Rc; -use base::id::MessagePortId; +use base::id::{MessagePortId, MessagePortIndex}; use constellation_traits::MessagePortImpl; use dom_struct::dom_struct; use js::jsapi::{Heap, JSObject}; @@ -1114,7 +1114,7 @@ impl CrossRealmTransformWritable { /// <https://streams.spec.whatwg.org/#ws-transfer> impl Transferable for WritableStream { - type Id = MessagePortId; + type Index = MessagePortIndex; type Data = MessagePortImpl; /// <https://streams.spec.whatwg.org/#ref-for-writablestream%E2%91%A0%E2%91%A4> @@ -1182,7 +1182,9 @@ impl Transferable for WritableStream { } /// Note: we are relying on the port transfer, so the data returned here are related to the port. - fn serialized_storage(data: StructuredData<'_>) -> &mut Option<HashMap<Self::Id, Self::Data>> { + fn serialized_storage( + data: StructuredData<'_>, + ) -> &mut Option<HashMap<MessagePortId, Self::Data>> { match data { StructuredData::Reader(r) => &mut r.port_impls, StructuredData::Writer(w) => &mut w.ports, diff --git a/components/shared/base/id.rs b/components/shared/base/id.rs index c59a541b214..cc4ad947494 100644 --- a/components/shared/base/id.rs +++ b/components/shared/base/id.rs @@ -8,11 +8,12 @@ use std::cell::Cell; use std::fmt; +use std::marker::PhantomData; use std::num::NonZeroU32; use std::sync::{Arc, LazyLock}; use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; -use malloc_size_of::malloc_size_of_is_0; +use malloc_size_of::MallocSizeOfOps; use malloc_size_of_derive::MallocSizeOf; use parking_lot::Mutex; use serde::{Deserialize, Serialize}; @@ -26,44 +27,88 @@ macro_rules! size_of_test { }; } -macro_rules! namespace_id_method { - ($func_name:ident, $func_return_data_type:ident, $self:ident, $index_name:ident) => { - fn $func_name(&mut $self) -> $func_return_data_type { - $func_return_data_type { - namespace_id: $self.id, - index: $index_name($self.next_index()), - } - } - }; +/// A type that implements this trait is expected to be used as part of +/// the [NamespaceIndex] type. +pub trait Indexable { + /// The string prefix to display when debug printing an instance of + /// this type. + const DISPLAY_PREFIX: &'static str; +} + +#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)] +/// A non-zero index, associated with a particular type. +pub struct Index<T>(pub NonZeroU32, pub PhantomData<T>); + +#[derive(Debug)] +/// An attempt to create a new [Index] value failed because the index value +/// was zero. +pub struct ZeroIndex; + +impl<T> Index<T> { + /// Creates a new instance of [Index] with the given value. + /// Returns an error if the value is zero. + pub fn new(value: u32) -> Result<Index<T>, ZeroIndex> { + Ok(Index(NonZeroU32::new(value).ok_or(ZeroIndex)?, PhantomData)) + } +} + +impl<T> malloc_size_of::MallocSizeOf for Index<T> { + fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize { + 0 + } +} + +#[derive( + Clone, Copy, Deserialize, Eq, Hash, MallocSizeOf, Ord, PartialEq, PartialOrd, Serialize, +)] +/// A pipeline-namespaced index associated with a particular type. +pub struct NamespaceIndex<T> { + pub namespace_id: PipelineNamespaceId, + pub index: Index<T>, +} + +impl<T> fmt::Debug for NamespaceIndex<T> { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + let PipelineNamespaceId(namespace_id) = self.namespace_id; + let Index(index, _) = self.index; + write!(fmt, "({},{})", namespace_id, index.get()) + } +} + +impl<T: Indexable> fmt::Display for NamespaceIndex<T> { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + write!(fmt, "{}{:?}", T::DISPLAY_PREFIX, self) + } } macro_rules! namespace_id { ($id_name:ident, $index_name:ident, $display_prefix:literal) => { #[derive( - Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize, + Clone, + Copy, + Debug, + Deserialize, + Eq, + Hash, + Ord, + PartialEq, + PartialOrd, + Serialize, + MallocSizeOf, )] - pub struct $index_name(pub NonZeroU32); - malloc_size_of_is_0!($index_name); - - #[derive( - Clone, Copy, Deserialize, Eq, Hash, MallocSizeOf, Ord, PartialEq, PartialOrd, Serialize, - )] - pub struct $id_name { - pub namespace_id: PipelineNamespaceId, - pub index: $index_name, - } - - impl fmt::Debug for $id_name { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - let PipelineNamespaceId(namespace_id) = self.namespace_id; - let $index_name(index) = self.index; - write!(fmt, "({},{})", namespace_id, index.get()) - } + pub struct $index_name; + impl Indexable for $index_name { + const DISPLAY_PREFIX: &'static str = $display_prefix; } - - impl fmt::Display for $id_name { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - write!(fmt, "{}{:?}", $display_prefix, self) + pub type $id_name = NamespaceIndex<$index_name>; + impl $id_name { + pub fn new() -> $id_name { + PIPELINE_NAMESPACE.with(|tls| { + let mut namespace = tls.get().expect("No namespace set for this thread!"); + let next_id = namespace.next_namespace_index(); + tls.set(Some(namespace)); + next_id + }) } } }; @@ -185,18 +230,12 @@ impl PipelineNamespace { NonZeroU32::new(self.index).expect("pipeline id index wrapped!") } - namespace_id_method! {next_pipeline_id, PipelineId, self, PipelineIndex} - namespace_id_method! {next_browsing_context_id, BrowsingContextId, self, BrowsingContextIndex} - namespace_id_method! {next_history_state_id, HistoryStateId, self, HistoryStateIndex} - namespace_id_method! {next_message_port_id, MessagePortId, self, MessagePortIndex} - namespace_id_method! {next_message_port_router_id, MessagePortRouterId, self, MessagePortRouterIndex} - namespace_id_method! {next_broadcast_channel_router_id, BroadcastChannelRouterId, self, BroadcastChannelRouterIndex} - namespace_id_method! {next_service_worker_id, ServiceWorkerId, self, ServiceWorkerIndex} - namespace_id_method! {next_service_worker_registration_id, ServiceWorkerRegistrationId, - self, ServiceWorkerRegistrationIndex} - namespace_id_method! {next_blob_id, BlobId, self, BlobIndex} - namespace_id_method! {next_dom_point_id, DomPointId, self, DomPointIndex} - namespace_id_method! {next_dom_exception_id, DomExceptionId, self, DomExceptionIndex} + fn next_namespace_index<T>(&mut self) -> NamespaceIndex<T> { + NamespaceIndex { + namespace_id: self.id, + index: Index(self.next_index(), PhantomData), + } + } } thread_local!(pub static PIPELINE_NAMESPACE: Cell<Option<PipelineNamespace>> = const { Cell::new(None) }); @@ -212,15 +251,6 @@ size_of_test!(PipelineId, 8); size_of_test!(Option<PipelineId>, 8); impl PipelineId { - pub fn new() -> PipelineId { - PIPELINE_NAMESPACE.with(|tls| { - let mut namespace = tls.get().expect("No namespace set for this thread!"); - let new_pipeline_id = namespace.next_pipeline_id(); - tls.set(Some(namespace)); - new_pipeline_id - }) - } - pub fn root_scroll_id(&self) -> webrender_api::ExternalScrollId { ExternalScrollId(0, self.into()) } @@ -233,7 +263,7 @@ impl From<WebRenderPipelineId> for PipelineId { unsafe { PipelineId { namespace_id: PipelineNamespaceId(namespace_id), - index: PipelineIndex(NonZeroU32::new_unchecked(index)), + index: Index(NonZeroU32::new_unchecked(index), PhantomData), } } } @@ -242,7 +272,7 @@ impl From<WebRenderPipelineId> for PipelineId { impl From<PipelineId> for WebRenderPipelineId { fn from(value: PipelineId) -> Self { let PipelineNamespaceId(namespace_id) = value.namespace_id; - let PipelineIndex(index) = value.index; + let Index(index, _) = value.index; WebRenderPipelineId(namespace_id, index.get()) } } @@ -258,17 +288,6 @@ namespace_id! {BrowsingContextId, BrowsingContextIndex, "BrowsingContext"} size_of_test!(BrowsingContextId, 8); size_of_test!(Option<BrowsingContextId>, 8); -impl BrowsingContextId { - pub fn new() -> Self { - PIPELINE_NAMESPACE.with(|tls| { - let mut namespace = tls.get().expect("No namespace set for this thread!"); - let new_browsing_context_id = namespace.next_browsing_context_id(); - tls.set(Some(namespace)); - new_browsing_context_id - }) - } -} - #[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)] pub struct BrowsingContextGroupId(pub u32); impl fmt::Display for BrowsingContextGroupId { @@ -336,134 +355,34 @@ impl PartialEq<BrowsingContextId> for WebViewId { namespace_id! {MessagePortId, MessagePortIndex, "MessagePort"} -impl MessagePortId { - pub fn new() -> MessagePortId { - PIPELINE_NAMESPACE.with(|tls| { - let mut namespace = tls.get().expect("No namespace set for this thread!"); - let next_message_port_id = namespace.next_message_port_id(); - tls.set(Some(namespace)); - next_message_port_id - }) - } -} - namespace_id! {MessagePortRouterId, MessagePortRouterIndex, "MessagePortRouter"} -impl MessagePortRouterId { - pub fn new() -> MessagePortRouterId { - PIPELINE_NAMESPACE.with(|tls| { - let mut namespace = tls.get().expect("No namespace set for this thread!"); - let next_message_port_router_id = namespace.next_message_port_router_id(); - tls.set(Some(namespace)); - next_message_port_router_id - }) - } -} - namespace_id! {BroadcastChannelRouterId, BroadcastChannelRouterIndex, "BroadcastChannelRouter"} -impl BroadcastChannelRouterId { - pub fn new() -> BroadcastChannelRouterId { - PIPELINE_NAMESPACE.with(|tls| { - let mut namespace = tls.get().expect("No namespace set for this thread!"); - let next_broadcast_channel_router_id = namespace.next_broadcast_channel_router_id(); - tls.set(Some(namespace)); - next_broadcast_channel_router_id - }) - } -} - namespace_id! {ServiceWorkerId, ServiceWorkerIndex, "ServiceWorker"} -impl ServiceWorkerId { - pub fn new() -> ServiceWorkerId { - PIPELINE_NAMESPACE.with(|tls| { - let mut namespace = tls.get().expect("No namespace set for this thread!"); - let next_service_worker_id = namespace.next_service_worker_id(); - tls.set(Some(namespace)); - next_service_worker_id - }) - } -} - namespace_id! {ServiceWorkerRegistrationId, ServiceWorkerRegistrationIndex, "ServiceWorkerRegistration"} -impl ServiceWorkerRegistrationId { - pub fn new() -> ServiceWorkerRegistrationId { - PIPELINE_NAMESPACE.with(|tls| { - let mut namespace = tls.get().expect("No namespace set for this thread!"); - let next_service_worker_registration_id = - namespace.next_service_worker_registration_id(); - tls.set(Some(namespace)); - next_service_worker_registration_id - }) - } -} - namespace_id! {BlobId, BlobIndex, "Blob"} -impl BlobId { - pub fn new() -> BlobId { - PIPELINE_NAMESPACE.with(|tls| { - let mut namespace = tls.get().expect("No namespace set for this thread!"); - let next_blob_id = namespace.next_blob_id(); - tls.set(Some(namespace)); - next_blob_id - }) - } -} - namespace_id! {DomPointId, DomPointIndex, "DomPoint"} -impl DomPointId { - pub fn new() -> DomPointId { - PIPELINE_NAMESPACE.with(|tls| { - let mut namespace = tls.get().expect("No namespace set for this thread!"); - let next_point_id = namespace.next_dom_point_id(); - tls.set(Some(namespace)); - next_point_id - }) - } -} - namespace_id! {DomExceptionId, DomExceptionIndex, "DomException"} -impl DomExceptionId { - pub fn new() -> DomExceptionId { - PIPELINE_NAMESPACE.with(|tls| { - let mut namespace = tls.get().expect("No namespace set for this thread!"); - let next_exception_id = namespace.next_dom_exception_id(); - tls.set(Some(namespace)); - next_exception_id - }) - } -} - namespace_id! {HistoryStateId, HistoryStateIndex, "HistoryState"} -impl HistoryStateId { - pub fn new() -> HistoryStateId { - PIPELINE_NAMESPACE.with(|tls| { - let mut namespace = tls.get().expect("No namespace set for this thread!"); - let next_history_state_id = namespace.next_history_state_id(); - tls.set(Some(namespace)); - next_history_state_id - }) - } -} - // We provide ids just for unit testing. pub const TEST_NAMESPACE: PipelineNamespaceId = PipelineNamespaceId(1234); #[allow(unsafe_code)] -pub const TEST_PIPELINE_INDEX: PipelineIndex = - unsafe { PipelineIndex(NonZeroU32::new_unchecked(5678)) }; +pub const TEST_PIPELINE_INDEX: Index<PipelineIndex> = + unsafe { Index(NonZeroU32::new_unchecked(5678), PhantomData) }; pub const TEST_PIPELINE_ID: PipelineId = PipelineId { namespace_id: TEST_NAMESPACE, index: TEST_PIPELINE_INDEX, }; #[allow(unsafe_code)] -pub const TEST_BROWSING_CONTEXT_INDEX: BrowsingContextIndex = - unsafe { BrowsingContextIndex(NonZeroU32::new_unchecked(8765)) }; +pub const TEST_BROWSING_CONTEXT_INDEX: Index<BrowsingContextIndex> = + unsafe { Index(NonZeroU32::new_unchecked(8765), PhantomData) }; pub const TEST_BROWSING_CONTEXT_ID: BrowsingContextId = BrowsingContextId { namespace_id: TEST_NAMESPACE, index: TEST_BROWSING_CONTEXT_INDEX, |