aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings/structuredclone.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/bindings/structuredclone.rs')
-rw-r--r--components/script/dom/bindings/structuredclone.rs62
1 files changed, 45 insertions, 17 deletions
diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs
index db6897a287f..d530a51e7bc 100644
--- a/components/script/dom/bindings/structuredclone.rs
+++ b/components/script/dom/bindings/structuredclone.rs
@@ -11,14 +11,21 @@ use dom::bindings::reflector::DomObject;
use dom::bindings::root::DomRoot;
use dom::blob::{Blob, BlobImpl};
use dom::globalscope::GlobalScope;
+use js::glue::CopyJSStructuredCloneData;
+use js::glue::DeleteJSAutoStructuredCloneBuffer;
+use js::glue::GetLengthOfJSStructuredCloneData;
+use js::glue::NewJSAutoStructuredCloneBuffer;
+use js::glue::WriteBytesToJSStructuredCloneData;
use js::jsapi::{JSAutoCompartment, JSContext};
use js::jsapi::{JSStructuredCloneCallbacks, JSStructuredCloneReader, JSStructuredCloneWriter};
use js::jsapi::{JS_ClearPendingException, JSObject};
use js::jsapi::{JS_ReadBytes, JS_WriteBytes};
use js::jsapi::{JS_ReadUint32Pair, JS_WriteUint32Pair};
+use js::jsapi::CloneDataPolicy;
use js::jsapi::HandleObject as RawHandleObject;
use js::jsapi::JS_STRUCTURED_CLONE_VERSION;
use js::jsapi::MutableHandleObject as RawMutableHandleObject;
+use js::jsapi::StructuredCloneScope;
use js::jsapi::TransferableOwnership;
use js::rust::{Handle, HandleValue, MutableHandleValue};
use js::rust::wrappers::{JS_WriteStructuredClone, JS_ReadStructuredClone};
@@ -207,26 +214,39 @@ 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> {
- let mut data = ptr::null_mut();
- let mut nbytes = 0;
- let result = unsafe {
- JS_WriteStructuredClone(cx,
- message,
- &mut data,
- &mut nbytes,
- &STRUCTURED_CLONE_CALLBACKS,
- ptr::null_mut(),
- HandleValue::undefined())
- };
- if !result {
- unsafe {
+ unsafe {
+ let scbuf = NewJSAutoStructuredCloneBuffer(StructuredCloneScope::DifferentProcess,
+ &STRUCTURED_CLONE_CALLBACKS);
+ let scdata = &mut ((*scbuf).data_);
+ let policy = CloneDataPolicy {
+ // TODO: SAB?
+ sharedArrayBuffer_: false,
+ };
+ let result = JS_WriteStructuredClone(cx,
+ message,
+ scdata,
+ StructuredCloneScope::DifferentProcess,
+ policy,
+ &STRUCTURED_CLONE_CALLBACKS,
+ ptr::null_mut(),
+ HandleValue::undefined());
+ if !result {
JS_ClearPendingException(cx);
+ return Err(Error::DataClone);
}
- return Err(Error::DataClone);
+
+ let nbytes = GetLengthOfJSStructuredCloneData(scdata);
+ let mut data = Vec::with_capacity(nbytes);
+ CopyJSStructuredCloneData(scdata, data.as_mut_ptr());
+ data.set_len(nbytes);
+
+ DeleteJSAutoStructuredCloneBuffer(scbuf);
+
+ Ok(StructuredCloneData::Vector(data))
}
- Ok(StructuredCloneData::Struct(data, nbytes))
}
/// Converts a StructuredCloneData to Vec<u8> for inter-thread sharing
@@ -254,13 +274,21 @@ impl StructuredCloneData {
let mut sc_holder = StructuredCloneHolder { blob: None };
let sc_holder_ptr = &mut sc_holder as *mut _;
unsafe {
+ let scbuf = NewJSAutoStructuredCloneBuffer(StructuredCloneScope::DifferentProcess,
+ &STRUCTURED_CLONE_CALLBACKS);
+ let scdata = &mut ((*scbuf).data_);
+
+ WriteBytesToJSStructuredCloneData(data as *const u8, nbytes, scdata);
+
assert!(JS_ReadStructuredClone(cx,
- data,
- nbytes,
+ scdata,
JS_STRUCTURED_CLONE_VERSION,
+ StructuredCloneScope::DifferentProcess,
rval,
&STRUCTURED_CLONE_CALLBACKS,
sc_holder_ptr as *mut raw::c_void));
+
+ DeleteJSAutoStructuredCloneBuffer(scbuf);
}
}