begin messageport, transferable objects, impl

Accept transfer argument for StructuredCloneData::write

Allow structured clone reads to return a boolean

Add Transferable trait

Add basic skeletons to MessagePort

Implement transfer and transfer-receiving steps on MessagePort

Use transfer and transfer_receive in StructuredClone callbacks

Implement MessageChannel

Freeze the array object for the MessageEvent ports attribute

Implement transfer argument on window.postMessage

Use ReentrantMutex instead for MessagePortInternal

Accept origin as a parameter in dispatch_jsval

Fix BorrowMut crash with pending_port_message

Detach port on closure and check for detached during transfer

Enable webmessaging tests

fix webidl

fix
This commit is contained in:
Keith Yeung 2016-12-11 03:52:08 -08:00 committed by Gregory Terzian
parent 605ddbecd4
commit c3b17c1201
37 changed files with 801 additions and 81 deletions

View file

@ -17,6 +17,7 @@ use crate::dom::bindings::codegen::Bindings::WindowBinding::{
};
use crate::dom::bindings::codegen::Bindings::WindowBinding::{ScrollBehavior, ScrollToOptions};
use crate::dom::bindings::codegen::UnionTypes::RequestOrUSVString;
use crate::dom::bindings::conversions::ToJSValConvertible;
use crate::dom::bindings::error::{Error, ErrorResult, Fallible};
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::num::Finite;
@ -43,6 +44,7 @@ use crate::dom::location::Location;
use crate::dom::mediaquerylist::{MediaQueryList, MediaQueryListMatchState};
use crate::dom::mediaquerylistevent::MediaQueryListEvent;
use crate::dom::messageevent::MessageEvent;
use crate::dom::messageport::TRANSFERRED_MESSAGE_PORTS;
use crate::dom::navigator::Navigator;
use crate::dom::node::{document_from_node, from_untrusted_node_address, Node, NodeDamage};
use crate::dom::performance::Performance;
@ -80,12 +82,13 @@ use euclid::{Point2D, Rect, Scale, Size2D, Vector2D};
use ipc_channel::ipc::{channel, IpcSender};
use ipc_channel::router::ROUTER;
use js::jsapi::JSAutoRealm;
use js::jsapi::JSObject;
use js::jsapi::JSPROP_ENUMERATE;
use js::jsapi::{GCReason, JS_GC};
use js::jsval::UndefinedValue;
use js::jsval::{JSVal, NullValue};
use js::rust::wrappers::JS_DefineProperty;
use js::rust::HandleValue;
use js::rust::{CustomAutoRooterGuard, HandleValue};
use media::WindowGLContext;
use msg::constellation_msg::PipelineId;
use net_traits::image_cache::{ImageCache, ImageResponder, ImageResponse};
@ -969,12 +972,18 @@ impl WindowMethods for Window {
}
// https://html.spec.whatwg.org/multipage/#dom-window-postmessage
fn PostMessage(&self, cx: JSContext, message: HandleValue, origin: DOMString) -> ErrorResult {
fn PostMessage(
&self,
cx: JSContext,
message: HandleValue,
origin: USVString,
transfer: CustomAutoRooterGuard<Option<Vec<*mut JSObject>>>,
) -> ErrorResult {
let source_global = GlobalScope::incumbent().expect("no incumbent global??");
let source = source_global.as_window();
// Step 3-5.
let origin = match &origin[..] {
let origin = match &origin.0[..] {
"*" => None,
"/" => Some(source.Document().origin().immutable().clone()),
url => match ServoUrl::parse(&url) {
@ -984,8 +993,10 @@ impl WindowMethods for Window {
};
// Step 1-2, 6-8.
// TODO(#12717): Should implement the `transfer` argument.
let data = StructuredCloneData::write(*cx, message)?;
rooted!(in(*cx) let mut val = UndefinedValue());
(*transfer).as_ref().unwrap_or(&Vec::new()).to_jsval(*cx, val.handle_mut());
let data = StructuredCloneData::write(*cx, message, val.handle())?;
// Step 9.
self.post_message(origin, &*source.window_proxy(), data);
@ -2342,10 +2353,11 @@ impl Window {
let task = task!(post_serialised_message: move || {
let this = this.root();
let source = source.root();
let document = this.Document();
// Step 7.1.
if let Some(target_origin) = target_origin {
if !target_origin.same_origin(this.Document().origin()) {
if let Some(ref target_origin) = target_origin {
if !target_origin.same_origin(document.origin()) {
return;
}
}
@ -2355,13 +2367,15 @@ impl Window {
let obj = this.reflector().get_jsobject();
let _ac = JSAutoRealm::new(*cx, obj.get());
rooted!(in(*cx) let mut message_clone = UndefinedValue());
serialize_with_transfer_result.read(
assert!(serialize_with_transfer_result.read(
this.upcast(),
message_clone.handle_mut(),
);
));
// Step 7.6.
// TODO: MessagePort array.
let new_ports = TRANSFERRED_MESSAGE_PORTS.with(|list| {
mem::replace(&mut *list.borrow_mut(), vec![])
});
// Step 7.7.
// TODO(#12719): Set the other attributes.
@ -2369,8 +2383,9 @@ impl Window {
this.upcast(),
this.upcast(),
message_clone.handle(),
None,
Some(&document.origin().immutable().ascii_serialization()),
Some(&*source),
new_ports,
);
});
// FIXME(nox): Why are errors silenced here?