aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings/structuredclone.rs
diff options
context:
space:
mode:
authorKeith Yeung <kungfukeith11@gmail.com>2016-12-11 03:52:08 -0800
committerGregory Terzian <gterzian@users.noreply.github.com>2019-10-19 14:12:22 +0800
commitc3b17c1201441c9a24c4b272108aea0196fbf1b9 (patch)
tree0de5b1ba2b8579338ffcf5639e3e06797b9d95ff /components/script/dom/bindings/structuredclone.rs
parent605ddbecd4dfbbb67849cf63774b2d7635fc3601 (diff)
downloadservo-c3b17c1201441c9a24c4b272108aea0196fbf1b9.tar.gz
servo-c3b17c1201441c9a24c4b272108aea0196fbf1b9.zip
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
Diffstat (limited to 'components/script/dom/bindings/structuredclone.rs')
-rw-r--r--components/script/dom/bindings/structuredclone.rs91
1 files changed, 61 insertions, 30 deletions
diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs
index f35a4af7210..2e33613b29d 100644
--- a/components/script/dom/bindings/structuredclone.rs
+++ b/components/script/dom/bindings/structuredclone.rs
@@ -10,8 +10,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;
@@ -44,6 +46,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,
}
@@ -189,26 +192,43 @@ 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)) {
+ if let Some(true) = port.detached() {
+ return false;
+ }
+
+ *tag = StructuredCloneTags::MessagePort as u32;
+ *ownership = TransferableOwnership::SCTAG_TMO_CUSTOM;
+ if port.transfer(closure, content, extra_data) {
+ port.set_detached(true);
+ return true;
+ }
+ }
false
}
@@ -256,7 +276,11 @@ pub enum StructuredCloneData {
impl StructuredCloneData {
// TODO: should this be unsafe?
/// Writes a structured clone. Returns a `DataClone` error if that fails.
- pub fn write(cx: *mut JSContext, message: HandleValue) -> Fallible<StructuredCloneData> {
+ pub fn write(
+ cx: *mut JSContext,
+ message: HandleValue,
+ transfer: HandleValue,
+ ) -> Fallible<StructuredCloneData> {
unsafe {
let scbuf = NewJSAutoStructuredCloneBuffer(
StructuredCloneScope::DifferentProcess,
@@ -275,7 +299,7 @@ impl StructuredCloneData {
policy,
&STRUCTURED_CLONE_CALLBACKS,
ptr::null_mut(),
- HandleValue::undefined(),
+ transfer,
);
if !result {
JS_ClearPendingException(cx);
@@ -306,7 +330,12 @@ impl StructuredCloneData {
/// Reads a structured clone.
///
/// Panics if `JS_ReadStructuredClone` fails.
- fn read_clone(global: &GlobalScope, data: *mut u64, nbytes: size_t, rval: MutableHandleValue) {
+ fn read_clone(
+ global: &GlobalScope,
+ data: *mut u64,
+ nbytes: size_t,
+ rval: MutableHandleValue,
+ ) -> bool {
let cx = global.get_cx();
let _ac = enter_realm(&*global);
let mut sc_holder = StructuredCloneHolder { blob: None };
@@ -320,31 +349,33 @@ impl StructuredCloneData {
WriteBytesToJSStructuredCloneData(data as *const u8, nbytes, scdata);
- assert!(JS_ReadStructuredClone(
- *cx,
- scdata,
- JS_STRUCTURED_CLONE_VERSION,
- StructuredCloneScope::DifferentProcess,
- rval,
- &STRUCTURED_CLONE_CALLBACKS,
- sc_holder_ptr as *mut raw::c_void
- ));
+ let result = JS_ReadStructuredClone(
+ *cx,
+ scdata,
+ JS_STRUCTURED_CLONE_VERSION,
+ StructuredCloneScope::DifferentProcess,
+ rval,
+ &STRUCTURED_CLONE_CALLBACKS,
+ sc_holder_ptr as *mut raw::c_void
+ );
DeleteJSAutoStructuredCloneBuffer(scbuf);
+
+ result
}
}
/// Thunk for the actual `read_clone` method. Resolves proper variant for read_clone.
- pub fn read(self, global: &GlobalScope, rval: MutableHandleValue) {
+ pub fn read(self, global: &GlobalScope, rval: MutableHandleValue) -> bool {
match self {
StructuredCloneData::Vector(mut vec_msg) => {
let nbytes = vec_msg.len();
let data = vec_msg.as_mut_ptr() as *mut u64;
- StructuredCloneData::read_clone(global, data, nbytes, rval);
- },
+ StructuredCloneData::read_clone(global, data, nbytes, rval)
+ }
StructuredCloneData::Struct(data, nbytes) => {
StructuredCloneData::read_clone(global, data, nbytes, rval)
- },
+ }
}
}
}