aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/bindings')
-rw-r--r--components/script/dom/bindings/error.rs1
-rw-r--r--components/script/dom/bindings/serializable.rs14
-rw-r--r--components/script/dom/bindings/structuredclone.rs78
-rw-r--r--components/script/dom/bindings/transferable.rs9
4 files changed, 42 insertions, 60 deletions
diff --git a/components/script/dom/bindings/error.rs b/components/script/dom/bindings/error.rs
index b0fd301df6a..f5bd03cd8d7 100644
--- a/components/script/dom/bindings/error.rs
+++ b/components/script/dom/bindings/error.rs
@@ -93,6 +93,7 @@ pub(crate) fn throw_dom_exception(
Error::NotReadable => DOMErrorName::NotReadableError,
Error::Data => DOMErrorName::DataError,
Error::Operation => DOMErrorName::OperationError,
+ Error::NotAllowed => DOMErrorName::NotAllowedError,
Error::Type(message) => unsafe {
assert!(!JS_IsExceptionPending(*cx));
throw_type_error(*cx, &message);
diff --git a/components/script/dom/bindings/serializable.rs b/components/script/dom/bindings/serializable.rs
index 4aa1a94a0a4..d0e851b4799 100644
--- a/components/script/dom/bindings/serializable.rs
+++ b/components/script/dom/bindings/serializable.rs
@@ -11,7 +11,7 @@ use base::id::{Index, NamespaceIndex, PipelineNamespaceId};
use crate::dom::bindings::reflector::DomObject;
use crate::dom::bindings::root::DomRoot;
-use crate::dom::bindings::structuredclone::{StructuredData, StructuredDataReader};
+use crate::dom::bindings::structuredclone::StructuredData;
use crate::dom::globalscope::GlobalScope;
use crate::script_runtime::CanGc;
@@ -65,13 +65,7 @@ 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<NamespaceIndex<Self::Index>, Self::Data>>;
-
- /// Returns the field of [StructuredDataReader] that should be used to store
- /// deserialized instances of this type.
- fn deserialized_storage(
- reader: &mut StructuredDataReader,
- ) -> &mut Option<HashMap<StorageKey, DomRoot<Self>>>;
+ fn serialized_storage<'a>(
+ data: StructuredData<'a, '_>,
+ ) -> &'a mut Option<HashMap<NamespaceIndex<Self::Index>, Self::Data>>;
}
diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs
index 915a4951bb5..c9a49ba00c9 100644
--- a/components/script/dom/bindings/structuredclone.rs
+++ b/components/script/dom/bindings/structuredclone.rs
@@ -16,13 +16,14 @@ use constellation_traits::{
BlobImpl, DomException, DomPoint, MessagePortImpl, Serializable as SerializableInterface,
StructuredSerializedData, Transferrable as TransferrableInterface,
};
+use js::gc::RootedVec;
use js::glue::{
CopyJSStructuredCloneData, DeleteJSAutoStructuredCloneBuffer, GetLengthOfJSStructuredCloneData,
NewJSAutoStructuredCloneBuffer, WriteBytesToJSStructuredCloneData,
};
use js::jsapi::{
- CloneDataPolicy, HandleObject as RawHandleObject, JS_ClearPendingException, JS_ReadUint32Pair,
- JS_STRUCTURED_CLONE_VERSION, JS_WriteUint32Pair, JSContext, JSObject,
+ CloneDataPolicy, HandleObject as RawHandleObject, Heap, JS_ClearPendingException,
+ JS_ReadUint32Pair, JS_STRUCTURED_CLONE_VERSION, JS_WriteUint32Pair, JSContext, JSObject,
JSStructuredCloneCallbacks, JSStructuredCloneReader, JSStructuredCloneWriter,
MutableHandleObject as RawMutableHandleObject, StructuredCloneScope, TransferableOwnership,
};
@@ -93,7 +94,7 @@ fn reader_for_type(
) -> unsafe fn(
&GlobalScope,
*mut JSStructuredCloneReader,
- &mut StructuredDataReader,
+ &mut StructuredDataReader<'_>,
CanGc,
) -> *mut JSObject {
match val {
@@ -107,7 +108,7 @@ fn reader_for_type(
unsafe fn read_object<T: Serializable>(
owner: &GlobalScope,
r: *mut JSStructuredCloneReader,
- sc_reader: &mut StructuredDataReader,
+ sc_reader: &mut StructuredDataReader<'_>,
can_gc: CanGc,
) -> *mut JSObject {
let mut name_space: u32 = 0;
@@ -136,9 +137,8 @@ unsafe fn read_object<T: Serializable>(
}
if let Ok(obj) = T::deserialize(owner, serialized, can_gc) {
- let destination = T::deserialized_storage(sc_reader).get_or_insert_with(HashMap::new);
let reflector = obj.reflector().get_jsobject().get();
- destination.insert(storage_key, obj);
+ sc_reader.roots.push(Heap::boxed(reflector));
return reflector;
}
warn!("Reading structured data failed in {:?}.", owner.get_url());
@@ -191,7 +191,7 @@ unsafe extern "C" fn read_callback(
"tag should be higher than StructuredCloneTags::Min"
);
- let sc_reader = &mut *(closure as *mut StructuredDataReader);
+ let sc_reader = &mut *(closure as *mut StructuredDataReader<'_>);
let in_realm_proof = AlreadyInRealm::assert_for_cx(SafeJSContext::from_ptr(cx));
let global = GlobalScope::from_context(cx, InRealm::Already(&in_realm_proof));
for serializable in SerializableInterface::iter() {
@@ -259,7 +259,8 @@ unsafe extern "C" fn write_callback(
fn receiver_for_type(
val: TransferrableInterface,
-) -> fn(&GlobalScope, &mut StructuredDataReader, u64, RawMutableHandleObject) -> Result<(), ()> {
+) -> fn(&GlobalScope, &mut StructuredDataReader<'_>, u64, RawMutableHandleObject) -> Result<(), ()>
+{
match val {
TransferrableInterface::MessagePort => receive_object::<MessagePort>,
TransferrableInterface::ReadableStream => receive_object::<ReadableStream>,
@@ -269,7 +270,7 @@ fn receiver_for_type(
fn receive_object<T: Transferable>(
owner: &GlobalScope,
- sc_reader: &mut StructuredDataReader,
+ sc_reader: &mut StructuredDataReader<'_>,
extra_data: u64,
return_object: RawMutableHandleObject,
) -> Result<(), ()> {
@@ -305,13 +306,12 @@ fn receive_object<T: Transferable>(
);
};
- if let Ok(received) = T::transfer_receive(owner, id, serialized) {
- return_object.set(received.reflector().rootable().get());
- let storage = T::deserialized_storage(sc_reader).get_or_insert_with(Vec::new);
- storage.push(received);
- return Ok(());
- }
- Err(())
+ let Ok(received) = T::transfer_receive(owner, id, serialized) else {
+ return Err(());
+ };
+ return_object.set(received.reflector().rootable().get());
+ sc_reader.roots.push(Heap::boxed(return_object.get()));
+ Ok(())
}
unsafe extern "C" fn read_transfer_callback(
@@ -324,7 +324,7 @@ unsafe extern "C" fn read_transfer_callback(
closure: *mut raw::c_void,
return_object: RawMutableHandleObject,
) -> bool {
- let sc_reader = &mut *(closure as *mut StructuredDataReader);
+ let sc_reader = &mut *(closure as *mut StructuredDataReader<'_>);
let in_realm_proof = AlreadyInRealm::assert_for_cx(SafeJSContext::from_ptr(cx));
let owner = GlobalScope::from_context(cx, InRealm::Already(&in_realm_proof));
@@ -489,8 +489,8 @@ static STRUCTURED_CLONE_CALLBACKS: JSStructuredCloneCallbacks = JSStructuredClon
sabCloned: Some(sab_cloned_callback),
};
-pub(crate) enum StructuredData<'a> {
- Reader(&'a mut StructuredDataReader),
+pub(crate) enum StructuredData<'a, 'b> {
+ Reader(&'a mut StructuredDataReader<'b>),
Writer(&'a mut StructuredDataWriter),
}
@@ -503,19 +503,11 @@ pub(crate) struct DOMErrorRecord {
/// Reader and writer structs for results from, and inputs to, structured-data read/write operations.
/// <https://html.spec.whatwg.org/multipage/#safe-passing-of-structured-data>
#[repr(C)]
-pub(crate) struct StructuredDataReader {
+pub(crate) struct StructuredDataReader<'a> {
/// A struct of error message.
- pub(crate) errors: DOMErrorRecord,
- /// A map of deserialized blobs, stored temporarily here to keep them rooted.
- pub(crate) blobs: Option<HashMap<StorageKey, DomRoot<Blob>>>,
- /// A map of deserialized points, stored temporarily here to keep them rooted.
- pub(crate) points_read_only: Option<HashMap<StorageKey, DomRoot<DOMPointReadOnly>>>,
- pub(crate) dom_points: Option<HashMap<StorageKey, DomRoot<DOMPoint>>>,
- /// A map of deserialized exceptions, stored temporarily here to keep them rooted.
- pub(crate) dom_exceptions: Option<HashMap<StorageKey, DomRoot<DOMException>>>,
- /// A vec of transfer-received DOM ports,
- /// to be made available to script through a message event.
- pub(crate) message_ports: Option<Vec<DomRoot<MessagePort>>>,
+ errors: DOMErrorRecord,
+ /// Rooted copies of every deserialized object to ensure they are not garbage collected.
+ roots: RootedVec<'a, Box<Heap<*mut JSObject>>>,
/// A map of port implementations,
/// used as part of the "transfer-receiving" steps of ports,
/// to produce the DOM ports stored in `message_ports` above.
@@ -528,12 +520,6 @@ pub(crate) struct StructuredDataReader {
pub(crate) points: Option<HashMap<DomPointId, DomPoint>>,
/// A map of serialized exceptions.
pub(crate) exceptions: Option<HashMap<DomExceptionId, DomException>>,
-
- /// <https://streams.spec.whatwg.org/#rs-transfer>
- pub(crate) readable_streams: Option<Vec<DomRoot<ReadableStream>>>,
-
- /// <https://streams.spec.whatwg.org/#ws-transfer>
- pub(crate) writable_streams: Option<Vec<DomRoot<WritableStream>>>,
}
/// A data holder for transferred and serialized objects.
@@ -618,19 +604,14 @@ pub(crate) fn read(
) -> Fallible<Vec<DomRoot<MessagePort>>> {
let cx = GlobalScope::get_cx();
let _ac = enter_realm(global);
+ rooted_vec!(let mut roots);
let mut sc_reader = StructuredDataReader {
- blobs: None,
- message_ports: None,
- points_read_only: None,
- dom_points: None,
- dom_exceptions: None,
+ roots,
port_impls: data.ports.take(),
blob_impls: data.blobs.take(),
points: data.points.take(),
exceptions: data.exceptions.take(),
errors: DOMErrorRecord { message: None },
- readable_streams: None,
- writable_streams: None,
};
let sc_reader_ptr = &mut sc_reader as *mut _;
unsafe {
@@ -666,8 +647,15 @@ pub(crate) fn read(
DeleteJSAutoStructuredCloneBuffer(scbuf);
+ let mut message_ports = vec![];
+ for reflector in sc_reader.roots.iter() {
+ let Ok(message_port) = root_from_object::<MessagePort>(reflector.get(), *cx) else {
+ continue;
+ };
+ message_ports.push(message_port);
+ }
// Any transfer-received port-impls should have been taken out.
assert!(sc_reader.port_impls.is_none());
- Ok(sc_reader.message_ports.take().unwrap_or_default())
+ Ok(message_ports)
}
}
diff --git a/components/script/dom/bindings/transferable.rs b/components/script/dom/bindings/transferable.rs
index b720c05ae37..e6b2f000f3a 100644
--- a/components/script/dom/bindings/transferable.rs
+++ b/components/script/dom/bindings/transferable.rs
@@ -12,7 +12,7 @@ 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::bindings::structuredclone::StructuredData;
use crate::dom::globalscope::GlobalScope;
pub(crate) trait Transferable: DomObject
where
@@ -32,8 +32,7 @@ where
serialized: Self::Data,
) -> Result<DomRoot<Self>, ()>;
- fn serialized_storage(
- data: StructuredData<'_>,
- ) -> &mut Option<HashMap<NamespaceIndex<Self::Index>, Self::Data>>;
- fn deserialized_storage(reader: &mut StructuredDataReader) -> &mut Option<Vec<DomRoot<Self>>>;
+ fn serialized_storage<'a>(
+ data: StructuredData<'a, '_>,
+ ) -> &'a mut Option<HashMap<NamespaceIndex<Self::Index>, Self::Data>>;
}