Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement MessagePort and MessageChannel #16622

Closed
wants to merge 15 commits into from
Closed
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Use transfer and transfer_receive in StructuredClone callbacks

  • Loading branch information
KiChjang committed Jun 9, 2019
commit f0233857a4fa25c92fa0846baabb527d3a311f25
@@ -9,8 +9,10 @@ use crate::dom::bindings::conversions::root_from_handleobject;
use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::reflector::DomObject;
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::transferable::Transferable;
use crate::dom::blob::{Blob, BlobImpl};
use crate::dom::globalscope::GlobalScope;
use crate::dom::messageport::MessagePort;
use js::glue::CopyJSStructuredCloneData;
use js::glue::DeleteJSAutoStructuredCloneBuffer;
use js::glue::GetLengthOfJSStructuredCloneData;
@@ -43,6 +45,7 @@ enum StructuredCloneTags {
/// To support additional types, add new tags with values incremented from the last one before Max.
Min = 0xFFFF8000,
DomBlob = 0xFFFF8001,
MessagePort = 0xFFFF8002,
Max = 0xFFFFFFFF,
}

@@ -188,26 +191,39 @@ unsafe extern "C" fn write_callback(
}

unsafe extern "C" fn read_transfer_callback(
_cx: *mut JSContext,
_r: *mut JSStructuredCloneReader,
_tag: u32,
_content: *mut raw::c_void,
_extra_data: u64,
_closure: *mut raw::c_void,
_return_object: RawMutableHandleObject,
cx: *mut JSContext,
r: *mut JSStructuredCloneReader,
tag: u32,
content: *mut raw::c_void,
extra_data: u64,
closure: *mut raw::c_void,
return_object: RawMutableHandleObject,
) -> bool {
false
if tag == StructuredCloneTags::MessagePort as u32 {
<MessagePort as Transferable>::transfer_receive(cx, r, closure, content, extra_data, return_object)
} else {
false
}
}

/// <https://html.spec.whatwg.org/multipage/#structuredserializewithtransfer>
unsafe extern "C" fn write_transfer_callback(
_cx: *mut JSContext,
_obj: RawHandleObject,
_closure: *mut raw::c_void,
_tag: *mut u32,
_ownership: *mut TransferableOwnership,
_content: *mut *mut raw::c_void,
_extra_data: *mut u64,
obj: RawHandleObject,
closure: *mut raw::c_void,
tag: *mut u32,
ownership: *mut TransferableOwnership,
content: *mut *mut raw::c_void,
extra_data: *mut u64,
) -> bool {
if let Ok(port) = root_from_handleobject::<MessagePort>(Handle::from_raw(obj)) {
*tag = StructuredCloneTags::MessagePort as u32;
*ownership = TransferableOwnership::SCTAG_TMO_CUSTOM;
if port.transfer(closure, content, extra_data) {
port.set_detached(true);
return true;
}
}
false
}

@@ -4,7 +4,7 @@

//! Trait representing the concept of [transferable objects]
//! (https://html.spec.whatwg.org/multipage/#transferable-objects).
use dom::bindings::reflector::DomObject;
use crate::dom::bindings::reflector::DomObject;
use js::jsapi::{JSContext, JSStructuredCloneReader, MutableHandleObject};
use std::os::raw;

@@ -465,7 +465,7 @@ impl DedicatedWorkerGlobalScope {
let _ac = JSAutoRealm::new(scope.get_cx(), scope.reflector().get_jsobject().get());
rooted!(in(scope.get_cx()) let mut message = UndefinedValue());
assert!(data.read(scope.upcast(), message.handle_mut()));
MessageEvent::dispatch_jsval(target, scope.upcast(), message.handle(), None, None);
MessageEvent::dispatch_jsval(target, scope.upcast(), message.handle(), None, None, vec![]);
},
WorkerScriptMsg::Common(msg) => {
self.upcast::<WorkerGlobalScope>().process_event(msg);
@@ -240,6 +240,7 @@ impl EventSourceContext {
DOMString::from(self.origin.clone()),
None,
event_source.last_event_id.borrow().clone(),
vec![],
)
};
// Step 7
@@ -14,10 +14,12 @@ use crate::dom::bindings::trace::RootedTraceableBox;
use crate::dom::event::Event;
use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope;
use crate::dom::messageport::MessagePort;
use crate::dom::windowproxy::WindowProxy;
use dom_struct::dom_struct;
use js::conversions::ToJSValConvertible;
use js::jsapi::{Heap, JSContext, JSObject};
use js::jsval::JSVal;
use js::jsval::{JSVal, UndefinedValue};
use js::rust::HandleValue;
use servo_atoms::Atom;
use std::ptr::NonNull;
@@ -30,6 +32,7 @@ pub struct MessageEvent {
origin: DOMString,
source: Option<Dom<WindowProxy>>,
lastEventId: DOMString,
ports: Vec<DomRoot<MessagePort>>,
}

impl MessageEvent {
@@ -40,6 +43,7 @@ impl MessageEvent {
DOMString::new(),
None,
DOMString::new(),
vec![],
)
}

@@ -49,13 +53,15 @@ impl MessageEvent {
origin: DOMString,
source: Option<&WindowProxy>,
lastEventId: DOMString,
ports: Vec<DomRoot<MessagePort>>,
) -> DomRoot<MessageEvent> {
let ev = Box::new(MessageEvent {
event: Event::new_inherited(),
data: Heap::default(),
origin: origin,
source: source.map(Dom::from_ref),
lastEventId: lastEventId,
origin,
lastEventId,
ports,
});
let ev = reflect_dom_object(ev, global, MessageEventBinding::Wrap);
ev.data.set(data.get());
@@ -72,8 +78,9 @@ impl MessageEvent {
origin: DOMString,
source: Option<&WindowProxy>,
lastEventId: DOMString,
ports: Vec<DomRoot<MessagePort>>,
) -> DomRoot<MessageEvent> {
let ev = MessageEvent::new_initialized(global, data, origin, source, lastEventId);
let ev = MessageEvent::new_initialized(global, data, origin, source, lastEventId, ports);
{
let event = ev.upcast::<Event>();
event.init_event(type_, bubbles, cancelable);
@@ -99,6 +106,7 @@ impl MessageEvent {
init.origin.clone(),
source.as_ref().map(|source| &**source),
init.lastEventId.clone(),
init.ports.clone().unwrap_or(vec![])
);
Ok(ev)
}
@@ -111,6 +119,7 @@ impl MessageEvent {
message: HandleValue,
origin: Option<&str>,
source: Option<&WindowProxy>,
ports: Vec<DomRoot<MessagePort>>,
) {
let messageevent = MessageEvent::new(
scope,
@@ -121,19 +130,20 @@ impl MessageEvent {
DOMString::from(origin.unwrap_or("")),
source,
DOMString::new(),
ports,
);
messageevent.upcast::<Event>().fire(target);
}
}

impl MessageEventMethods for MessageEvent {
#[allow(unsafe_code)]
// https://html.spec.whatwg.org/multipage/#dom-messageevent-data
/// <https://html.spec.whatwg.org/multipage/#dom-messageevent-data>
unsafe fn Data(&self, _cx: *mut JSContext) -> JSVal {
self.data.get()
}

// https://html.spec.whatwg.org/multipage/#dom-messageevent-origin
/// <https://html.spec.whatwg.org/multipage/#dom-messageevent-origin>
fn Origin(&self) -> DOMString {
self.origin.clone()
}
@@ -146,13 +156,21 @@ impl MessageEventMethods for MessageEvent {
.and_then(|source| NonNull::new(source.reflector().get_jsobject().get()))
}

// https://html.spec.whatwg.org/multipage/#dom-messageevent-lasteventid
/// <https://html.spec.whatwg.org/multipage/#dom-messageevent-lasteventid>
fn LastEventId(&self) -> DOMString {
self.lastEventId.clone()
}

// https://dom.spec.whatwg.org/#dom-event-istrusted
/// <https://dom.spec.whatwg.org/#dom-event-istrusted>
fn IsTrusted(&self) -> bool {
self.event.IsTrusted()
}

#[allow(unsafe_code)]
/// <https://html.spec.whatwg.org/multipage/#dom-messageevent-ports>
unsafe fn Ports(&self, cx: *mut JSContext) -> JSVal {
rooted!(in(cx) let mut ports = UndefinedValue());
self.ports.to_jsval(cx, ports.handle_mut());
*ports
}
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.