mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Transfer ReadableStream (#36181)
<!-- Please describe your changes on the following line: --> Add transfer support to ReadableStream. Part of https://github.com/servo/servo/issues/34676 --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [ ] `./mach build -d` does not report any errors - [ ] `./mach test-tidy` does not report any errors - [ ] These changes fix #___ (GitHub issue number if applicable) <!-- Either: --> - [ ] There are tests for these changes OR - [ ] These changes do not require tests because ___ <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> --------- Signed-off-by: gterzian <2792687+gterzian@users.noreply.github.com>
This commit is contained in:
parent
c9489ca04f
commit
f8b6b9f7b6
22 changed files with 983 additions and 75 deletions
|
@ -5,12 +5,14 @@
|
|||
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 constellation_traits::{MessagePortImpl, PortMessageTask};
|
||||
use dom_struct::dom_struct;
|
||||
use js::jsapi::{Heap, JSObject};
|
||||
use js::jsapi::{Heap, JS_NewObject, JSObject};
|
||||
use js::jsval::UndefinedValue;
|
||||
use js::rust::{CustomAutoRooter, CustomAutoRooterGuard, HandleValue};
|
||||
|
||||
use crate::dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
|
||||
|
@ -25,8 +27,10 @@ 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::utils::set_dictionary_property;
|
||||
use crate::dom::eventtarget::EventTarget;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::js::conversions::ToJSValConvertible;
|
||||
use crate::script_runtime::{CanGc, JSContext as SafeJSContext};
|
||||
|
||||
#[dom_struct]
|
||||
|
@ -57,7 +61,7 @@ impl MessagePort {
|
|||
}
|
||||
|
||||
/// Create a new port for an incoming transfer-received one.
|
||||
fn new_transferred(
|
||||
pub(crate) fn new_transferred(
|
||||
owner: &GlobalScope,
|
||||
transferred_port: MessagePortId,
|
||||
entangled_port: Option<MessagePortId>,
|
||||
|
@ -156,6 +160,83 @@ impl MessagePort {
|
|||
.post_messageport_msg(*self.message_port_id(), task);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// <https://streams.spec.whatwg.org/#abstract-opdef-crossrealmtransformsenderror>
|
||||
pub(crate) fn cross_realm_transform_send_error(&self, error: HandleValue, can_gc: CanGc) {
|
||||
// Perform PackAndPostMessage(port, "error", error),
|
||||
// discarding the result.
|
||||
let _ = self.pack_and_post_message("error", error, can_gc);
|
||||
}
|
||||
|
||||
/// <https://streams.spec.whatwg.org/#abstract-opdef-packandpostmessagehandlingerror>
|
||||
#[allow(unsafe_code)]
|
||||
pub(crate) fn pack_and_post_message_handling_error(
|
||||
&self,
|
||||
type_: &str,
|
||||
value: HandleValue,
|
||||
can_gc: CanGc,
|
||||
) -> ErrorResult {
|
||||
// Let result be PackAndPostMessage(port, type, value).
|
||||
let result = self.pack_and_post_message(type_, value, can_gc);
|
||||
|
||||
// If result is an abrupt completion,
|
||||
if result.is_err() {
|
||||
// Perform ! CrossRealmTransformSendError(port, result.[[Value]]).
|
||||
// Note: we send UndefinedValue across,
|
||||
// because somehow sending an error results in another error.
|
||||
// The Error::DataClone, which is the only one that is sent across,
|
||||
// will be created upon receipt.
|
||||
let cx = GlobalScope::get_cx();
|
||||
rooted!(in(*cx) let mut rooted_error = UndefinedValue());
|
||||
self.cross_realm_transform_send_error(rooted_error.handle(), can_gc);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
/// <https://streams.spec.whatwg.org/#abstract-opdef-packandpostmessage>
|
||||
#[allow(unsafe_code)]
|
||||
pub(crate) fn pack_and_post_message(
|
||||
&self,
|
||||
type_: &str,
|
||||
value: HandleValue,
|
||||
_can_gc: CanGc,
|
||||
) -> ErrorResult {
|
||||
let cx = GlobalScope::get_cx();
|
||||
|
||||
// Let message be OrdinaryObjectCreate(null).
|
||||
rooted!(in(*cx) let mut message = unsafe { JS_NewObject(*cx, ptr::null()) });
|
||||
rooted!(in(*cx) let mut type_string = UndefinedValue());
|
||||
unsafe {
|
||||
type_.to_jsval(*cx, type_string.handle_mut());
|
||||
}
|
||||
|
||||
// Perform ! CreateDataProperty(message, "type", type).
|
||||
unsafe {
|
||||
set_dictionary_property(*cx, message.handle(), "type", type_string.handle())
|
||||
.expect("Setting the message type should not fail.");
|
||||
}
|
||||
|
||||
// Perform ! CreateDataProperty(message, "value", value).
|
||||
unsafe {
|
||||
set_dictionary_property(*cx, message.handle(), "value", value)
|
||||
.expect("Setting the message value should not fail.");
|
||||
}
|
||||
|
||||
// Let targetPort be the port with which port is entangled, if any; otherwise let it be null.
|
||||
// Done in `global.post_messageport_msg`.
|
||||
|
||||
// Let options be «[ "transfer" → « » ]».
|
||||
let mut rooted = CustomAutoRooter::new(vec![]);
|
||||
let transfer = CustomAutoRooterGuard::new(*cx, &mut rooted);
|
||||
|
||||
// Run the message port post message steps providing targetPort, message, and options.
|
||||
rooted!(in(*cx) let mut message_val = UndefinedValue());
|
||||
unsafe {
|
||||
message.to_jsval(*cx, message_val.handle_mut());
|
||||
}
|
||||
self.post_message_impl(cx, message_val.handle(), transfer)
|
||||
}
|
||||
}
|
||||
|
||||
impl Transferable for MessagePort {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue