mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
refactor: merge cross_realm_transform_*
fields into one (#37102)
In https://github.com/servo/servo/pull/36977, when transferring `TransformStream`, `CrossRealmTransform::Writable` and `CrossRealmTransform::Readable` are set to different message ports. The message port will not be readable and writable at the same time when transferring the stream, so we can now merge `cross_realm_transform_readable` and `cross_realm_transform_writable` into a single field `cross_realm_transform`. Testing: WPT ([passed on try branch](https://github.com/pewsheen/servo/actions/runs/15209389525/job/42784179519)) Fixes: https://github.com/servo/servo/issues/37084 --------- Signed-off-by: Jason Tsai <git@pews.dev>
This commit is contained in:
parent
983bfb2518
commit
d76b4a14df
2 changed files with 68 additions and 61 deletions
|
@ -74,6 +74,7 @@ use super::bindings::codegen::Bindings::WebGPUBinding::GPUDeviceLostReason;
|
||||||
use super::bindings::error::Fallible;
|
use super::bindings::error::Fallible;
|
||||||
use super::bindings::trace::{HashMapTracedValues, RootedTraceableBox};
|
use super::bindings::trace::{HashMapTracedValues, RootedTraceableBox};
|
||||||
use super::serviceworkerglobalscope::ServiceWorkerGlobalScope;
|
use super::serviceworkerglobalscope::ServiceWorkerGlobalScope;
|
||||||
|
use super::transformstream::CrossRealmTransform;
|
||||||
use crate::dom::bindings::cell::{DomRefCell, RefMut};
|
use crate::dom::bindings::cell::{DomRefCell, RefMut};
|
||||||
use crate::dom::bindings::codegen::Bindings::BroadcastChannelBinding::BroadcastChannelMethods;
|
use crate::dom::bindings::codegen::Bindings::BroadcastChannelBinding::BroadcastChannelMethods;
|
||||||
use crate::dom::bindings::codegen::Bindings::EventSourceBinding::EventSource_Binding::EventSourceMethods;
|
use crate::dom::bindings::codegen::Bindings::EventSourceBinding::EventSource_Binding::EventSourceMethods;
|
||||||
|
@ -458,13 +459,9 @@ pub(crate) struct ManagedMessagePort {
|
||||||
/// Whether the port has been closed by script in this global,
|
/// Whether the port has been closed by script in this global,
|
||||||
/// so it can be removed.
|
/// so it can be removed.
|
||||||
explicitly_closed: bool,
|
explicitly_closed: bool,
|
||||||
/// Note: it may seem strange to use a pair of options, versus for example an enum.
|
/// The handler for `message` or `messageerror` used in the cross realm transform,
|
||||||
/// But it looks like tranform streams will require both of those in their transfer.
|
/// if any was setup with this port.
|
||||||
/// This will be resolved when we reach that point of the implementation.
|
cross_realm_transform: Option<CrossRealmTransform>,
|
||||||
/// <https://streams.spec.whatwg.org/#abstract-opdef-setupcrossrealmtransformreadable>
|
|
||||||
cross_realm_transform_readable: Option<CrossRealmTransformReadable>,
|
|
||||||
/// <https://streams.spec.whatwg.org/#abstract-opdef-setupcrossrealmtransformwritable>
|
|
||||||
cross_realm_transform_writable: Option<CrossRealmTransformWritable>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// State representing whether this global is currently managing broadcast channels.
|
/// State representing whether this global is currently managing broadcast channels.
|
||||||
|
@ -1345,7 +1342,9 @@ impl GlobalScope {
|
||||||
unreachable!("Cross realm transform readable must match a managed port");
|
unreachable!("Cross realm transform readable must match a managed port");
|
||||||
};
|
};
|
||||||
|
|
||||||
managed_port.cross_realm_transform_readable = Some(cross_realm_transform_readable.clone());
|
managed_port.cross_realm_transform = Some(CrossRealmTransform::Readable(
|
||||||
|
cross_realm_transform_readable.clone(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://streams.spec.whatwg.org/#abstract-opdef-setupcrossrealmtransformwritable>
|
/// <https://streams.spec.whatwg.org/#abstract-opdef-setupcrossrealmtransformwritable>
|
||||||
|
@ -1368,7 +1367,9 @@ impl GlobalScope {
|
||||||
unreachable!("Cross realm transform writable must match a managed port");
|
unreachable!("Cross realm transform writable must match a managed port");
|
||||||
};
|
};
|
||||||
|
|
||||||
managed_port.cross_realm_transform_writable = Some(cross_realm_transform_writable.clone());
|
managed_port.cross_realm_transform = Some(CrossRealmTransform::Writable(
|
||||||
|
cross_realm_transform_writable.clone(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Custom routing logic, followed by the task steps of
|
/// Custom routing logic, followed by the task steps of
|
||||||
|
@ -1380,8 +1381,7 @@ impl GlobalScope {
|
||||||
can_gc: CanGc,
|
can_gc: CanGc,
|
||||||
) {
|
) {
|
||||||
let cx = GlobalScope::get_cx();
|
let cx = GlobalScope::get_cx();
|
||||||
rooted!(in(*cx) let mut cross_realm_transform_readable = None);
|
rooted!(in(*cx) let mut cross_realm_transform = None);
|
||||||
rooted!(in(*cx) let mut cross_realm_transform_writable = None);
|
|
||||||
|
|
||||||
let should_dispatch = if let MessagePortState::Managed(_id, message_ports) =
|
let should_dispatch = if let MessagePortState::Managed(_id, message_ports) =
|
||||||
&mut *self.message_port_state.borrow_mut()
|
&mut *self.message_port_state.borrow_mut()
|
||||||
|
@ -1399,10 +1399,7 @@ impl GlobalScope {
|
||||||
let to_dispatch = port_impl.handle_incoming(task).map(|to_dispatch| {
|
let to_dispatch = port_impl.handle_incoming(task).map(|to_dispatch| {
|
||||||
(DomRoot::from_ref(&*managed_port.dom_port), to_dispatch)
|
(DomRoot::from_ref(&*managed_port.dom_port), to_dispatch)
|
||||||
});
|
});
|
||||||
cross_realm_transform_readable
|
cross_realm_transform.set(managed_port.cross_realm_transform.clone());
|
||||||
.set(managed_port.cross_realm_transform_readable.clone());
|
|
||||||
cross_realm_transform_writable
|
|
||||||
.set(managed_port.cross_realm_transform_writable.clone());
|
|
||||||
to_dispatch
|
to_dispatch
|
||||||
} else {
|
} else {
|
||||||
panic!("managed-port has no port-impl.");
|
panic!("managed-port has no port-impl.");
|
||||||
|
@ -1429,10 +1426,6 @@ impl GlobalScope {
|
||||||
// Re-ordered because we need to pass it to `structuredclone::read`.
|
// Re-ordered because we need to pass it to `structuredclone::read`.
|
||||||
rooted!(in(*cx) let mut message_clone = UndefinedValue());
|
rooted!(in(*cx) let mut message_clone = UndefinedValue());
|
||||||
|
|
||||||
// Note: if this port is used to transfer a stream, we handle the events in Rust.
|
|
||||||
let has_cross_realm_tansform = cross_realm_transform_readable.is_some() ||
|
|
||||||
cross_realm_transform_writable.is_some();
|
|
||||||
|
|
||||||
let realm = enter_realm(self);
|
let realm = enter_realm(self);
|
||||||
let comp = InRealm::Entered(&realm);
|
let comp = InRealm::Entered(&realm);
|
||||||
|
|
||||||
|
@ -1447,26 +1440,28 @@ impl GlobalScope {
|
||||||
// if any, maintaining their relative order.
|
// if any, maintaining their relative order.
|
||||||
// Note: both done in `structuredclone::read`.
|
// Note: both done in `structuredclone::read`.
|
||||||
if let Ok(ports) = structuredclone::read(self, data, message_clone.handle_mut()) {
|
if let Ok(ports) = structuredclone::read(self, data, message_clone.handle_mut()) {
|
||||||
// Add a handler for port’s message event with the following steps:
|
// Note: if this port is used to transfer a stream, we handle the events in Rust.
|
||||||
// from <https://streams.spec.whatwg.org/#abstract-opdef-setupcrossrealmtransformreadable>
|
if let Some(transform) = cross_realm_transform.as_ref() {
|
||||||
if let Some(transform) = cross_realm_transform_readable.as_ref() {
|
match transform {
|
||||||
transform.handle_message(
|
// Add a handler for port’s message event with the following steps:
|
||||||
cx,
|
// from <https://streams.spec.whatwg.org/#abstract-opdef-setupcrossrealmtransformreadable>
|
||||||
self,
|
CrossRealmTransform::Readable(readable) => {
|
||||||
&dom_port,
|
readable.handle_message(
|
||||||
message_clone.handle(),
|
cx,
|
||||||
comp,
|
self,
|
||||||
can_gc,
|
&dom_port,
|
||||||
);
|
message_clone.handle(),
|
||||||
}
|
comp,
|
||||||
|
can_gc,
|
||||||
// Add a handler for port’s message event with the following steps:
|
);
|
||||||
// from <https://streams.spec.whatwg.org/#abstract-opdef-setupcrossrealmtransformwritable>
|
},
|
||||||
if let Some(transform) = cross_realm_transform_writable.as_ref() {
|
// Add a handler for port’s message event with the following steps:
|
||||||
transform.handle_message(cx, self, message_clone.handle(), comp, can_gc);
|
// from <https://streams.spec.whatwg.org/#abstract-opdef-setupcrossrealmtransformwritable>
|
||||||
}
|
CrossRealmTransform::Writable(writable) => {
|
||||||
|
writable.handle_message(cx, self, message_clone.handle(), comp, can_gc);
|
||||||
if !has_cross_realm_tansform {
|
},
|
||||||
|
}
|
||||||
|
} else {
|
||||||
// Fire an event named message at messageEventTarget,
|
// Fire an event named message at messageEventTarget,
|
||||||
// using MessageEvent,
|
// using MessageEvent,
|
||||||
// with the data attribute initialized to messageClone
|
// with the data attribute initialized to messageClone
|
||||||
|
@ -1481,25 +1476,24 @@ impl GlobalScope {
|
||||||
can_gc,
|
can_gc,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
} else if let Some(transform) = cross_realm_transform.as_ref() {
|
||||||
|
match transform {
|
||||||
|
// Add a handler for port’s messageerror event with the following steps:
|
||||||
|
// from <https://streams.spec.whatwg.org/#abstract-opdef-setupcrossrealmtransformreadable>
|
||||||
|
CrossRealmTransform::Readable(readable) => {
|
||||||
|
readable.handle_error(cx, self, &dom_port, comp, can_gc);
|
||||||
|
},
|
||||||
|
// Add a handler for port’s messageerror event with the following steps:
|
||||||
|
// from <https://streams.spec.whatwg.org/#abstract-opdef-setupcrossrealmtransformwritable>
|
||||||
|
CrossRealmTransform::Writable(writable) => {
|
||||||
|
writable.handle_error(cx, self, &dom_port, comp, can_gc);
|
||||||
|
},
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Add a handler for port’s messageerror event with the following steps:
|
// If this throws an exception, catch it,
|
||||||
// from <https://streams.spec.whatwg.org/#abstract-opdef-setupcrossrealmtransformreadable>
|
// fire an event named messageerror at messageEventTarget,
|
||||||
if let Some(transform) = cross_realm_transform_readable.as_ref() {
|
// using MessageEvent, and then return.
|
||||||
transform.handle_error(cx, self, &dom_port, comp, can_gc);
|
MessageEvent::dispatch_error(message_event_target, self, can_gc);
|
||||||
}
|
|
||||||
|
|
||||||
// Add a handler for port’s messageerror event with the following steps:
|
|
||||||
// from <https://streams.spec.whatwg.org/#abstract-opdef-setupcrossrealmtransformwritable>
|
|
||||||
if let Some(transform) = cross_realm_transform_writable.as_ref() {
|
|
||||||
transform.handle_error(cx, self, &dom_port, comp, can_gc);
|
|
||||||
}
|
|
||||||
|
|
||||||
if !has_cross_realm_tansform {
|
|
||||||
// If this throws an exception, catch it,
|
|
||||||
// fire an event named messageerror at messageEventTarget,
|
|
||||||
// using MessageEvent, and then return.
|
|
||||||
MessageEvent::dispatch_error(message_event_target, self, can_gc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1689,8 +1683,7 @@ impl GlobalScope {
|
||||||
dom_port: Dom::from_ref(dom_port),
|
dom_port: Dom::from_ref(dom_port),
|
||||||
pending: true,
|
pending: true,
|
||||||
explicitly_closed: false,
|
explicitly_closed: false,
|
||||||
cross_realm_transform_readable: None,
|
cross_realm_transform: None,
|
||||||
cross_realm_transform_writable: None,
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1713,8 +1706,7 @@ impl GlobalScope {
|
||||||
dom_port: Dom::from_ref(dom_port),
|
dom_port: Dom::from_ref(dom_port),
|
||||||
pending: false,
|
pending: false,
|
||||||
explicitly_closed: false,
|
explicitly_closed: false,
|
||||||
cross_realm_transform_readable: None,
|
cross_realm_transform: None,
|
||||||
cross_realm_transform_writable: None,
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
let _ = self.script_to_constellation_chan().send(
|
let _ = self.script_to_constellation_chan().send(
|
||||||
|
|
|
@ -21,7 +21,9 @@ use super::bindings::structuredclone::StructuredData;
|
||||||
use super::bindings::transferable::Transferable;
|
use super::bindings::transferable::Transferable;
|
||||||
use super::messageport::MessagePort;
|
use super::messageport::MessagePort;
|
||||||
use super::promisenativehandler::Callback;
|
use super::promisenativehandler::Callback;
|
||||||
|
use super::readablestream::CrossRealmTransformReadable;
|
||||||
use super::types::{TransformStreamDefaultController, WritableStream};
|
use super::types::{TransformStreamDefaultController, WritableStream};
|
||||||
|
use super::writablestream::CrossRealmTransformWritable;
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
use crate::dom::bindings::cell::DomRefCell;
|
||||||
use crate::dom::bindings::codegen::Bindings::QueuingStrategyBinding::QueuingStrategy;
|
use crate::dom::bindings::codegen::Bindings::QueuingStrategyBinding::QueuingStrategy;
|
||||||
use crate::dom::bindings::codegen::Bindings::TransformStreamBinding::TransformStreamMethods;
|
use crate::dom::bindings::codegen::Bindings::TransformStreamBinding::TransformStreamMethods;
|
||||||
|
@ -368,6 +370,19 @@ impl Callback for FlushPromiseRejection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl js::gc::Rootable for CrossRealmTransform {}
|
||||||
|
|
||||||
|
/// A wrapper to handle `message` and `messageerror` events
|
||||||
|
/// for the message port used by the transfered stream.
|
||||||
|
#[derive(Clone, JSTraceable, MallocSizeOf)]
|
||||||
|
#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)]
|
||||||
|
pub(crate) enum CrossRealmTransform {
|
||||||
|
/// <https://streams.spec.whatwg.org/#abstract-opdef-setupcrossrealmtransformreadable>
|
||||||
|
Readable(CrossRealmTransformReadable),
|
||||||
|
/// <https://streams.spec.whatwg.org/#abstract-opdef-setupcrossrealmtransformwritable>
|
||||||
|
Writable(CrossRealmTransformWritable),
|
||||||
|
}
|
||||||
|
|
||||||
/// <https://streams.spec.whatwg.org/#ts-class>
|
/// <https://streams.spec.whatwg.org/#ts-class>
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
pub struct TransformStream {
|
pub struct TransformStream {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue