From 431b2637901c1a7d841b9d6ee10a668668d10767 Mon Sep 17 00:00:00 2001 From: alajara Date: Sun, 9 Apr 2017 15:50:51 -0400 Subject: Create higher-level APIs for manipulating custom structured clones. --- components/script/dom/bindings/structuredclone.rs | 52 +++++++++++++++++------ 1 file changed, 38 insertions(+), 14 deletions(-) (limited to 'components/script/dom/bindings/structuredclone.rs') diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index b3a9df32695..53f3b63e085 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -67,16 +67,44 @@ unsafe fn read_length(r: *mut JSStructuredCloneReader) return length as usize; } +struct StructuredCloneWriter { + w: *mut JSStructuredCloneWriter, +} + +impl StructuredCloneWriter { + unsafe fn write_slice(&self, v: &[u8]) { + let type_length = v.len(); + write_length(self.w, type_length); + assert!(JS_WriteBytes(self.w, v.as_ptr() as *const raw::c_void, type_length)); + } + unsafe fn write_str(&self, s: &str) { + self.write_slice(s.as_bytes()); + } +} + +struct StructuredCloneReader { + r: *mut JSStructuredCloneReader, +} + +impl StructuredCloneReader { + unsafe fn read_bytes(&self) -> Vec { + let mut bytes = vec![0u8; read_length(self.r)]; + let blob_length = bytes.len(); + assert!(JS_ReadBytes(self.r, bytes.as_mut_ptr() as *mut raw::c_void, blob_length)); + return bytes; + } + unsafe fn read_str(&self) -> String { + let str_buffer = self.read_bytes(); + return String::from_utf8_unchecked(str_buffer); + } +} + unsafe fn read_blob(cx: *mut JSContext, r: *mut JSStructuredCloneReader) -> *mut JSObject { - let blob_length = read_length(r); - let type_str_length = read_length(r); - let mut blob_buffer = vec![0u8; blob_length]; - assert!(JS_ReadBytes(r, blob_buffer.as_mut_ptr() as *mut raw::c_void, blob_length)); - let mut type_str_buffer = vec![0u8; type_str_length]; - assert!(JS_ReadBytes(r, type_str_buffer.as_mut_ptr() as *mut raw::c_void, type_str_length)); - let type_str = String::from_utf8_unchecked(type_str_buffer); + let structured_reader = StructuredCloneReader { r: r }; + let blob_buffer = structured_reader.read_bytes(); + let type_str = structured_reader.read_str(); let target_global = GlobalScope::from_context(cx); let blob = Blob::new(&target_global, BlobImpl::new_from_bytes(blob_buffer), type_str); return blob.reflector().get_jsobject().get() @@ -85,15 +113,11 @@ unsafe fn read_blob(cx: *mut JSContext, unsafe fn write_blob(blob: Root, w: *mut JSStructuredCloneWriter) -> Result<(), ()> { + let structured_writer = StructuredCloneWriter { w: w }; let blob_vec = try!(blob.get_bytes()); - let blob_length = blob_vec.len(); - let type_string_bytes = blob.type_string().as_bytes().to_vec(); - let type_string_length = type_string_bytes.len(); assert!(JS_WriteUint32Pair(w, StructuredCloneTags::DomBlob as u32, 0)); - write_length(w, blob_length); - write_length(w, type_string_length); - assert!(JS_WriteBytes(w, blob_vec.as_ptr() as *const raw::c_void, blob_length)); - assert!(JS_WriteBytes(w, type_string_bytes.as_ptr() as *const raw::c_void, type_string_length)); + structured_writer.write_slice(&blob_vec); + structured_writer.write_str(&blob.type_string()); return Ok(()) } -- cgit v1.2.3 From 7af5a7fd5409ab8db0274eb829136e5953e718ed Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sun, 18 Jun 2017 13:21:32 +0200 Subject: Untry script --- components/script/dom/bindings/structuredclone.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'components/script/dom/bindings/structuredclone.rs') diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index 53f3b63e085..5644784e10c 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -114,7 +114,7 @@ unsafe fn write_blob(blob: Root, w: *mut JSStructuredCloneWriter) -> Result<(), ()> { let structured_writer = StructuredCloneWriter { w: w }; - let blob_vec = try!(blob.get_bytes()); + let blob_vec = blob.get_bytes()?; assert!(JS_WriteUint32Pair(w, StructuredCloneTags::DomBlob as u32, 0)); structured_writer.write_slice(&blob_vec); structured_writer.write_str(&blob.type_string()); -- cgit v1.2.3 From 0e3c54c1911ba2c3bf305ee04f04fcd9bf2fc2fe Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Mon, 25 Sep 2017 23:30:24 +0200 Subject: Rename dom::bindings::js to dom::bindings::root --- components/script/dom/bindings/structuredclone.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'components/script/dom/bindings/structuredclone.rs') diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index 5644784e10c..e23d478e5a8 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -7,8 +7,8 @@ use dom::bindings::conversions::root_from_handleobject; use dom::bindings::error::{Error, Fallible}; -use dom::bindings::js::Root; use dom::bindings::reflector::DomObject; +use dom::bindings::root::Root; use dom::blob::{Blob, BlobImpl}; use dom::globalscope::GlobalScope; use js::jsapi::{Handle, HandleObject, HandleValue, MutableHandleValue, JSAutoCompartment, JSContext}; -- cgit v1.2.3 From f87c2a8d7616112ca924e30292db2d244cf87eec Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Tue, 26 Sep 2017 01:53:40 +0200 Subject: Rename Root to DomRoot In a later PR, DomRoot will become a type alias of Root>, where Root will be able to handle all the things that need to be rooted that have a stable traceable address that doesn't move for the whole lifetime of the root. Stay tuned. --- components/script/dom/bindings/structuredclone.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'components/script/dom/bindings/structuredclone.rs') diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index e23d478e5a8..bdc5348782f 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -8,7 +8,7 @@ use dom::bindings::conversions::root_from_handleobject; use dom::bindings::error::{Error, Fallible}; use dom::bindings::reflector::DomObject; -use dom::bindings::root::Root; +use dom::bindings::root::DomRoot; use dom::blob::{Blob, BlobImpl}; use dom::globalscope::GlobalScope; use js::jsapi::{Handle, HandleObject, HandleValue, MutableHandleValue, JSAutoCompartment, JSContext}; @@ -110,7 +110,7 @@ unsafe fn read_blob(cx: *mut JSContext, return blob.reflector().get_jsobject().get() } -unsafe fn write_blob(blob: Root, +unsafe fn write_blob(blob: DomRoot, w: *mut JSStructuredCloneWriter) -> Result<(), ()> { let structured_writer = StructuredCloneWriter { w: w }; -- cgit v1.2.3 From 356c57e628255ed338b32246ce5e7de75da621f0 Mon Sep 17 00:00:00 2001 From: Marcin Mielniczuk Date: Wed, 28 Mar 2018 21:28:30 +0200 Subject: Adapt Servo for mozjs 0.6 and the changes introduced in servo/rust-mozjs#393 --- components/script/dom/bindings/structuredclone.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'components/script/dom/bindings/structuredclone.rs') diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index bdc5348782f..b2d1d7194a5 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -11,13 +11,17 @@ use dom::bindings::reflector::DomObject; use dom::bindings::root::DomRoot; use dom::blob::{Blob, BlobImpl}; use dom::globalscope::GlobalScope; -use js::jsapi::{Handle, HandleObject, HandleValue, MutableHandleValue, JSAutoCompartment, JSContext}; +use js::jsapi::{JSAutoCompartment, JSContext}; use js::jsapi::{JSStructuredCloneCallbacks, JSStructuredCloneReader, JSStructuredCloneWriter}; -use js::jsapi::{JS_ClearPendingException, JSObject, JS_ReadStructuredClone}; +use js::jsapi::{JS_ClearPendingException, JSObject}; use js::jsapi::{JS_ReadBytes, JS_WriteBytes}; use js::jsapi::{JS_ReadUint32Pair, JS_WriteUint32Pair}; -use js::jsapi::{JS_STRUCTURED_CLONE_VERSION, JS_WriteStructuredClone}; -use js::jsapi::{MutableHandleObject, TransferableOwnership}; +use js::jsapi::HandleObject as RawHandleObject; +use js::jsapi::JS_STRUCTURED_CLONE_VERSION; +use js::jsapi::MutableHandleObject as RawMutableHandleObject; +use js::jsapi::TransferableOwnership; +use js::rust::{Handle, HandleValue, MutableHandleValue}; +use js::rust::wrappers::{JS_WriteStructuredClone, JS_ReadStructuredClone}; use libc::size_t; use std::os::raw; use std::ptr; @@ -137,10 +141,10 @@ unsafe extern "C" fn read_callback(cx: *mut JSContext, unsafe extern "C" fn write_callback(_cx: *mut JSContext, w: *mut JSStructuredCloneWriter, - obj: HandleObject, + obj: RawHandleObject, _closure: *mut raw::c_void) -> bool { - if let Ok(blob) = root_from_handleobject::(obj) { + if let Ok(blob) = root_from_handleobject::(Handle::from_raw(obj)) { return write_blob(blob, w).is_ok() } return false @@ -152,13 +156,13 @@ unsafe extern "C" fn read_transfer_callback(_cx: *mut JSContext, _content: *mut raw::c_void, _extra_data: u64, _closure: *mut raw::c_void, - _return_object: MutableHandleObject) + _return_object: RawMutableHandleObject) -> bool { false } unsafe extern "C" fn write_transfer_callback(_cx: *mut JSContext, - _obj: Handle<*mut JSObject>, + _obj: RawHandleObject, _closure: *mut raw::c_void, _tag: *mut u32, _ownership: *mut TransferableOwnership, -- cgit v1.2.3 From a5d7cd1a7fe8b3f3821afbda6e31762c137be7f9 Mon Sep 17 00:00:00 2001 From: Gregory Terzian Date: Fri, 20 Jul 2018 13:02:02 +0800 Subject: use a structured clone holder to store rooted clones --- components/script/dom/bindings/structuredclone.rs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'components/script/dom/bindings/structuredclone.rs') diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index b2d1d7194a5..db6897a287f 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -104,14 +104,17 @@ impl StructuredCloneReader { } unsafe fn read_blob(cx: *mut JSContext, - r: *mut JSStructuredCloneReader) + r: *mut JSStructuredCloneReader, + sc_holder: &mut StructuredCloneHolder) -> *mut JSObject { let structured_reader = StructuredCloneReader { r: r }; let blob_buffer = structured_reader.read_bytes(); let type_str = structured_reader.read_str(); let target_global = GlobalScope::from_context(cx); let blob = Blob::new(&target_global, BlobImpl::new_from_bytes(blob_buffer), type_str); - return blob.reflector().get_jsobject().get() + let js_object = blob.reflector().get_jsobject().get(); + sc_holder.blob = Some(blob); + js_object } unsafe fn write_blob(blob: DomRoot, @@ -129,12 +132,12 @@ unsafe extern "C" fn read_callback(cx: *mut JSContext, r: *mut JSStructuredCloneReader, tag: u32, _data: u32, - _closure: *mut raw::c_void) + closure: *mut raw::c_void) -> *mut JSObject { assert!(tag < StructuredCloneTags::Max as u32, "tag should be lower than StructuredCloneTags::Max"); assert!(tag > StructuredCloneTags::Min as u32, "tag should be higher than StructuredCloneTags::Min"); if tag == StructuredCloneTags::DomBlob as u32 { - return read_blob(cx, r) + return read_blob(cx, r, &mut *(closure as *mut StructuredCloneHolder)) } return ptr::null_mut() } @@ -191,6 +194,10 @@ static STRUCTURED_CLONE_CALLBACKS: JSStructuredCloneCallbacks = JSStructuredClon freeTransfer: Some(free_transfer_callback), }; +struct StructuredCloneHolder { + blob: Option> +} + /// A buffer for a structured clone. pub enum StructuredCloneData { /// A non-serializable (default) variant @@ -244,6 +251,8 @@ impl StructuredCloneData { let cx = global.get_cx(); let globalhandle = global.reflector().get_jsobject(); let _ac = JSAutoCompartment::new(cx, globalhandle.get()); + let mut sc_holder = StructuredCloneHolder { blob: None }; + let sc_holder_ptr = &mut sc_holder as *mut _; unsafe { assert!(JS_ReadStructuredClone(cx, data, @@ -251,7 +260,7 @@ impl StructuredCloneData { JS_STRUCTURED_CLONE_VERSION, rval, &STRUCTURED_CLONE_CALLBACKS, - ptr::null_mut())); + sc_holder_ptr as *mut raw::c_void)); } } -- cgit v1.2.3 From 74c1e00d8163f255bb4141ff3549bbdedd7ea766 Mon Sep 17 00:00:00 2001 From: Alan Jeffrey Date: Fri, 1 Jun 2018 17:24:25 -0500 Subject: Upgraded to SM 60 --- components/script/dom/bindings/structuredclone.rs | 62 ++++++++++++++++------- 1 file changed, 45 insertions(+), 17 deletions(-) (limited to 'components/script/dom/bindings/structuredclone.rs') 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 { - 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 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); } } -- cgit v1.2.3 From c37a345dc9f4dda6ea29c42f96f6c7201c42cbac Mon Sep 17 00:00:00 2001 From: chansuke Date: Tue, 18 Sep 2018 23:24:15 +0900 Subject: Format script component --- components/script/dom/bindings/structuredclone.rs | 245 ++++++++++++---------- 1 file changed, 140 insertions(+), 105 deletions(-) (limited to 'components/script/dom/bindings/structuredclone.rs') diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index d530a51e7bc..c4a68547247 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -47,35 +47,39 @@ enum StructuredCloneTags { } #[cfg(target_pointer_width = "64")] -unsafe fn write_length(w: *mut JSStructuredCloneWriter, - length: usize) { - let high: u32 = (length >> 32) as u32; - let low: u32 = length as u32; - assert!(JS_WriteUint32Pair(w, high, low)); +unsafe fn write_length(w: *mut JSStructuredCloneWriter, length: usize) { + let high: u32 = (length >> 32) as u32; + let low: u32 = length as u32; + assert!(JS_WriteUint32Pair(w, high, low)); } #[cfg(target_pointer_width = "32")] -unsafe fn write_length(w: *mut JSStructuredCloneWriter, - length: usize) { - assert!(JS_WriteUint32Pair(w, length as u32, 0)); +unsafe fn write_length(w: *mut JSStructuredCloneWriter, length: usize) { + assert!(JS_WriteUint32Pair(w, length as u32, 0)); } #[cfg(target_pointer_width = "64")] -unsafe fn read_length(r: *mut JSStructuredCloneReader) - -> usize { - let mut high: u32 = 0; - let mut low: u32 = 0; - assert!(JS_ReadUint32Pair(r, &mut high as *mut u32, &mut low as *mut u32)); - return (low << high) as usize; +unsafe fn read_length(r: *mut JSStructuredCloneReader) -> usize { + let mut high: u32 = 0; + let mut low: u32 = 0; + assert!(JS_ReadUint32Pair( + r, + &mut high as *mut u32, + &mut low as *mut u32 + )); + return (low << high) as usize; } #[cfg(target_pointer_width = "32")] -unsafe fn read_length(r: *mut JSStructuredCloneReader) - -> usize { - let mut length: u32 = 0; - let mut zero: u32 = 0; - assert!(JS_ReadUint32Pair(r, &mut length as *mut u32, &mut zero as *mut u32)); - return length as usize; +unsafe fn read_length(r: *mut JSStructuredCloneReader) -> usize { + let mut length: u32 = 0; + let mut zero: u32 = 0; + assert!(JS_ReadUint32Pair( + r, + &mut length as *mut u32, + &mut zero as *mut u32 + )); + return length as usize; } struct StructuredCloneWriter { @@ -86,7 +90,11 @@ impl StructuredCloneWriter { unsafe fn write_slice(&self, v: &[u8]) { let type_length = v.len(); write_length(self.w, type_length); - assert!(JS_WriteBytes(self.w, v.as_ptr() as *const raw::c_void, type_length)); + assert!(JS_WriteBytes( + self.w, + v.as_ptr() as *const raw::c_void, + type_length + )); } unsafe fn write_str(&self, s: &str) { self.write_slice(s.as_bytes()); @@ -101,7 +109,11 @@ impl StructuredCloneReader { unsafe fn read_bytes(&self) -> Vec { let mut bytes = vec![0u8; read_length(self.r)]; let blob_length = bytes.len(); - assert!(JS_ReadBytes(self.r, bytes.as_mut_ptr() as *mut raw::c_void, blob_length)); + assert!(JS_ReadBytes( + self.r, + bytes.as_mut_ptr() as *mut raw::c_void, + blob_length + )); return bytes; } unsafe fn read_str(&self) -> String { @@ -110,87 +122,105 @@ impl StructuredCloneReader { } } -unsafe fn read_blob(cx: *mut JSContext, - r: *mut JSStructuredCloneReader, - sc_holder: &mut StructuredCloneHolder) - -> *mut JSObject { +unsafe fn read_blob( + cx: *mut JSContext, + r: *mut JSStructuredCloneReader, + sc_holder: &mut StructuredCloneHolder, +) -> *mut JSObject { let structured_reader = StructuredCloneReader { r: r }; let blob_buffer = structured_reader.read_bytes(); let type_str = structured_reader.read_str(); let target_global = GlobalScope::from_context(cx); - let blob = Blob::new(&target_global, BlobImpl::new_from_bytes(blob_buffer), type_str); + let blob = Blob::new( + &target_global, + BlobImpl::new_from_bytes(blob_buffer), + type_str, + ); let js_object = blob.reflector().get_jsobject().get(); sc_holder.blob = Some(blob); js_object } -unsafe fn write_blob(blob: DomRoot, - w: *mut JSStructuredCloneWriter) - -> Result<(), ()> { +unsafe fn write_blob(blob: DomRoot, w: *mut JSStructuredCloneWriter) -> Result<(), ()> { let structured_writer = StructuredCloneWriter { w: w }; let blob_vec = blob.get_bytes()?; - assert!(JS_WriteUint32Pair(w, StructuredCloneTags::DomBlob as u32, 0)); + assert!(JS_WriteUint32Pair( + w, + StructuredCloneTags::DomBlob as u32, + 0 + )); structured_writer.write_slice(&blob_vec); structured_writer.write_str(&blob.type_string()); - return Ok(()) + return Ok(()); } -unsafe extern "C" fn read_callback(cx: *mut JSContext, - r: *mut JSStructuredCloneReader, - tag: u32, - _data: u32, - closure: *mut raw::c_void) - -> *mut JSObject { - assert!(tag < StructuredCloneTags::Max as u32, "tag should be lower than StructuredCloneTags::Max"); - assert!(tag > StructuredCloneTags::Min as u32, "tag should be higher than StructuredCloneTags::Min"); +unsafe extern "C" fn read_callback( + cx: *mut JSContext, + r: *mut JSStructuredCloneReader, + tag: u32, + _data: u32, + closure: *mut raw::c_void, +) -> *mut JSObject { + assert!( + tag < StructuredCloneTags::Max as u32, + "tag should be lower than StructuredCloneTags::Max" + ); + assert!( + tag > StructuredCloneTags::Min as u32, + "tag should be higher than StructuredCloneTags::Min" + ); if tag == StructuredCloneTags::DomBlob as u32 { - return read_blob(cx, r, &mut *(closure as *mut StructuredCloneHolder)) + return read_blob(cx, r, &mut *(closure as *mut StructuredCloneHolder)); } - return ptr::null_mut() + return ptr::null_mut(); } -unsafe extern "C" fn write_callback(_cx: *mut JSContext, - w: *mut JSStructuredCloneWriter, - obj: RawHandleObject, - _closure: *mut raw::c_void) - -> bool { +unsafe extern "C" fn write_callback( + _cx: *mut JSContext, + w: *mut JSStructuredCloneWriter, + obj: RawHandleObject, + _closure: *mut raw::c_void, +) -> bool { if let Ok(blob) = root_from_handleobject::(Handle::from_raw(obj)) { - return write_blob(blob, w).is_ok() + return write_blob(blob, w).is_ok(); } - return false + return false; } -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) - -> bool { +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, +) -> bool { false } -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) - -> bool { +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, +) -> bool { false } -unsafe extern "C" fn free_transfer_callback(_tag: u32, - _ownership: TransferableOwnership, - _content: *mut raw::c_void, - _extra_data: u64, - _closure: *mut raw::c_void) { +unsafe extern "C" fn free_transfer_callback( + _tag: u32, + _ownership: TransferableOwnership, + _content: *mut raw::c_void, + _extra_data: u64, + _closure: *mut raw::c_void, +) { } -unsafe extern "C" fn report_error_callback(_cx: *mut JSContext, _errorid: u32) { -} +unsafe extern "C" fn report_error_callback(_cx: *mut JSContext, _errorid: u32) {} static STRUCTURED_CLONE_CALLBACKS: JSStructuredCloneCallbacks = JSStructuredCloneCallbacks { read: Some(read_callback), @@ -202,7 +232,7 @@ static STRUCTURED_CLONE_CALLBACKS: JSStructuredCloneCallbacks = JSStructuredClon }; struct StructuredCloneHolder { - blob: Option> + blob: Option>, } /// A buffer for a structured clone. @@ -210,7 +240,7 @@ pub enum StructuredCloneData { /// A non-serializable (default) variant Struct(*mut u64, size_t), /// A variant that can be serialized - Vector(Vec) + Vector(Vec), } impl StructuredCloneData { @@ -218,21 +248,25 @@ impl StructuredCloneData { /// Writes a structured clone. Returns a `DataClone` error if that fails. pub fn write(cx: *mut JSContext, message: HandleValue) -> Fallible { unsafe { - let scbuf = NewJSAutoStructuredCloneBuffer(StructuredCloneScope::DifferentProcess, - &STRUCTURED_CLONE_CALLBACKS); + 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()); + 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); @@ -252,41 +286,40 @@ impl StructuredCloneData { /// Converts a StructuredCloneData to Vec for inter-thread sharing pub fn move_to_arraybuffer(self) -> Vec { match self { - StructuredCloneData::Struct(data, nbytes) => { - unsafe { - slice::from_raw_parts(data as *mut u8, nbytes).to_vec() - } - } - StructuredCloneData::Vector(msg) => msg + StructuredCloneData::Struct(data, nbytes) => unsafe { + slice::from_raw_parts(data as *mut u8, nbytes).to_vec() + }, + StructuredCloneData::Vector(msg) => msg, } } /// 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) { let cx = global.get_cx(); let globalhandle = global.reflector().get_jsobject(); let _ac = JSAutoCompartment::new(cx, globalhandle.get()); 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 scbuf = NewJSAutoStructuredCloneBuffer( + StructuredCloneScope::DifferentProcess, + &STRUCTURED_CLONE_CALLBACKS, + ); let scdata = &mut ((*scbuf).data_); 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)); + assert!(JS_ReadStructuredClone( + cx, + scdata, + JS_STRUCTURED_CLONE_VERSION, + StructuredCloneScope::DifferentProcess, + rval, + &STRUCTURED_CLONE_CALLBACKS, + sc_holder_ptr as *mut raw::c_void + )); DeleteJSAutoStructuredCloneBuffer(scbuf); } @@ -299,8 +332,10 @@ impl StructuredCloneData { let nbytes = vec_msg.len(); let data = vec_msg.as_mut_ptr() as *mut u64; StructuredCloneData::read_clone(global, data, nbytes, rval); - } - StructuredCloneData::Struct(data, nbytes) => StructuredCloneData::read_clone(global, data, nbytes, rval) + }, + StructuredCloneData::Struct(data, nbytes) => { + StructuredCloneData::read_clone(global, data, nbytes, rval) + }, } } } -- cgit v1.2.3 From 45f7199eee82c66637ec68287eafa40a651001c4 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Thu, 1 Nov 2018 23:45:06 +0100 Subject: `cargo fix --edition` --- components/script/dom/bindings/structuredclone.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'components/script/dom/bindings/structuredclone.rs') diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index c4a68547247..094749ff875 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -5,12 +5,12 @@ //! This module implements structured cloning, as defined by [HTML] //! (https://html.spec.whatwg.org/multipage/#safe-passing-of-structured-data). -use dom::bindings::conversions::root_from_handleobject; -use dom::bindings::error::{Error, Fallible}; -use dom::bindings::reflector::DomObject; -use dom::bindings::root::DomRoot; -use dom::blob::{Blob, BlobImpl}; -use dom::globalscope::GlobalScope; +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::blob::{Blob, BlobImpl}; +use crate::dom::globalscope::GlobalScope; use js::glue::CopyJSStructuredCloneData; use js::glue::DeleteJSAutoStructuredCloneBuffer; use js::glue::GetLengthOfJSStructuredCloneData; -- cgit v1.2.3 From 9e92eb205a2a12fe0be883e42cb7f82deebc9031 Mon Sep 17 00:00:00 2001 From: Pyfisch Date: Tue, 6 Nov 2018 20:38:02 +0100 Subject: Reorder imports --- components/script/dom/bindings/structuredclone.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'components/script/dom/bindings/structuredclone.rs') diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index 094749ff875..d4cc8c1cdae 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -16,19 +16,19 @@ 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::jsapi::JS_STRUCTURED_CLONE_VERSION; +use js::jsapi::{JSAutoCompartment, JSContext}; +use js::jsapi::{JSObject, JS_ClearPendingException}; +use js::jsapi::{JSStructuredCloneCallbacks, JSStructuredCloneReader, JSStructuredCloneWriter}; +use js::jsapi::{JS_ReadBytes, JS_WriteBytes}; +use js::jsapi::{JS_ReadUint32Pair, JS_WriteUint32Pair}; +use js::rust::wrappers::{JS_ReadStructuredClone, JS_WriteStructuredClone}; use js::rust::{Handle, HandleValue, MutableHandleValue}; -use js::rust::wrappers::{JS_WriteStructuredClone, JS_ReadStructuredClone}; use libc::size_t; use std::os::raw; use std::ptr; -- cgit v1.2.3 From a1a14459c141afc6ac6771b8a6c9ca374537edf2 Mon Sep 17 00:00:00 2001 From: Jan Andre Ikenmeyer Date: Mon, 19 Nov 2018 14:47:12 +0100 Subject: Update MPL license to https (part 3) --- components/script/dom/bindings/structuredclone.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'components/script/dom/bindings/structuredclone.rs') diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index d4cc8c1cdae..8b6d9c2c1c1 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -1,6 +1,6 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! This module implements structured cloning, as defined by [HTML] //! (https://html.spec.whatwg.org/multipage/#safe-passing-of-structured-data). -- cgit v1.2.3 From 4328713f71d5bc389ecd47e78bfe9b8087b8c104 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Mon, 6 May 2019 11:38:34 -0400 Subject: Update to SpiderMonkey 66. --- components/script/dom/bindings/structuredclone.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'components/script/dom/bindings/structuredclone.rs') diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index 8b6d9c2c1c1..c411dece76b 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -22,7 +22,7 @@ use js::jsapi::MutableHandleObject as RawMutableHandleObject; use js::jsapi::StructuredCloneScope; use js::jsapi::TransferableOwnership; use js::jsapi::JS_STRUCTURED_CLONE_VERSION; -use js::jsapi::{JSAutoCompartment, JSContext}; +use js::jsapi::{JSAutoRealm, JSContext}; use js::jsapi::{JSObject, JS_ClearPendingException}; use js::jsapi::{JSStructuredCloneCallbacks, JSStructuredCloneReader, JSStructuredCloneWriter}; use js::jsapi::{JS_ReadBytes, JS_WriteBytes}; @@ -220,6 +220,14 @@ unsafe extern "C" fn free_transfer_callback( ) { } +unsafe extern "C" fn can_transfer_callback( + _cx: *mut JSContext, + _obj: RawHandleObject, + _closure: *mut raw::c_void, +) -> bool { + false +} + unsafe extern "C" fn report_error_callback(_cx: *mut JSContext, _errorid: u32) {} static STRUCTURED_CLONE_CALLBACKS: JSStructuredCloneCallbacks = JSStructuredCloneCallbacks { @@ -229,6 +237,7 @@ static STRUCTURED_CLONE_CALLBACKS: JSStructuredCloneCallbacks = JSStructuredClon readTransfer: Some(read_transfer_callback), writeTransfer: Some(write_transfer_callback), freeTransfer: Some(free_transfer_callback), + canTransfer: Some(can_transfer_callback), }; struct StructuredCloneHolder { @@ -299,7 +308,7 @@ impl StructuredCloneData { fn read_clone(global: &GlobalScope, data: *mut u64, nbytes: size_t, rval: MutableHandleValue) { let cx = global.get_cx(); let globalhandle = global.reflector().get_jsobject(); - let _ac = JSAutoCompartment::new(cx, globalhandle.get()); + let _ac = JSAutoRealm::new(cx, globalhandle.get()); let mut sc_holder = StructuredCloneHolder { blob: None }; let sc_holder_ptr = &mut sc_holder as *mut _; unsafe { -- cgit v1.2.3 From 63714c90fb5bbad86f28fc188120b2ecfd3337ab Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Sun, 2 Jun 2019 23:38:12 -0400 Subject: Upgrade to Spidermonkey 67. --- components/script/dom/bindings/structuredclone.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'components/script/dom/bindings/structuredclone.rs') diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index c411dece76b..f6f63abbaf7 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -176,12 +176,12 @@ unsafe extern "C" fn read_callback( } unsafe extern "C" fn write_callback( - _cx: *mut JSContext, + cx: *mut JSContext, w: *mut JSStructuredCloneWriter, obj: RawHandleObject, _closure: *mut raw::c_void, ) -> bool { - if let Ok(blob) = root_from_handleobject::(Handle::from_raw(obj)) { + if let Ok(blob) = root_from_handleobject::(Handle::from_raw(obj), cx) { return write_blob(blob, w).is_ok(); } return false; -- cgit v1.2.3 From adb402487e7f8bf2cd0a1db360b16592f5c654ed Mon Sep 17 00:00:00 2001 From: Kamil Niski Date: Sat, 4 May 2019 11:27:21 +0200 Subject: Create a helper API for entering a DOM object's compartment Revert some unnecessary changes Fix fmt errors --- components/script/dom/bindings/structuredclone.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'components/script/dom/bindings/structuredclone.rs') diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index f6f63abbaf7..167b375dbc7 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -5,6 +5,7 @@ //! This module implements structured cloning, as defined by [HTML] //! (https://html.spec.whatwg.org/multipage/#safe-passing-of-structured-data). +use crate::compartments::enter_realm; use crate::dom::bindings::conversions::root_from_handleobject; use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::reflector::DomObject; @@ -18,11 +19,11 @@ use js::glue::NewJSAutoStructuredCloneBuffer; use js::glue::WriteBytesToJSStructuredCloneData; use js::jsapi::CloneDataPolicy; use js::jsapi::HandleObject as RawHandleObject; +use js::jsapi::JSContext; use js::jsapi::MutableHandleObject as RawMutableHandleObject; use js::jsapi::StructuredCloneScope; use js::jsapi::TransferableOwnership; use js::jsapi::JS_STRUCTURED_CLONE_VERSION; -use js::jsapi::{JSAutoRealm, JSContext}; use js::jsapi::{JSObject, JS_ClearPendingException}; use js::jsapi::{JSStructuredCloneCallbacks, JSStructuredCloneReader, JSStructuredCloneWriter}; use js::jsapi::{JS_ReadBytes, JS_WriteBytes}; @@ -307,8 +308,7 @@ impl StructuredCloneData { /// Panics if `JS_ReadStructuredClone` fails. fn read_clone(global: &GlobalScope, data: *mut u64, nbytes: size_t, rval: MutableHandleValue) { let cx = global.get_cx(); - let globalhandle = global.reflector().get_jsobject(); - let _ac = JSAutoRealm::new(cx, globalhandle.get()); + let _ac = enter_realm(&*global); let mut sc_holder = StructuredCloneHolder { blob: None }; let sc_holder_ptr = &mut sc_holder as *mut _; unsafe { -- cgit v1.2.3 From 88cacfb0098e20be70c27bfde6b74cd3290f1fe4 Mon Sep 17 00:00:00 2001 From: marmeladema Date: Mon, 22 Jul 2019 22:14:11 +0100 Subject: Modify *::get_cx methods to return a safe JSContext instead of a raw one --- components/script/dom/bindings/structuredclone.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'components/script/dom/bindings/structuredclone.rs') diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index 167b375dbc7..f35a4af7210 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -321,7 +321,7 @@ impl StructuredCloneData { WriteBytesToJSStructuredCloneData(data as *const u8, nbytes, scdata); assert!(JS_ReadStructuredClone( - cx, + *cx, scdata, JS_STRUCTURED_CLONE_VERSION, StructuredCloneScope::DifferentProcess, -- cgit v1.2.3 From c3b17c1201441c9a24c4b272108aea0196fbf1b9 Mon Sep 17 00:00:00 2001 From: Keith Yeung Date: Sun, 11 Dec 2016 03:52:08 -0800 Subject: 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 --- components/script/dom/bindings/structuredclone.rs | 91 +++++++++++++++-------- 1 file changed, 61 insertions(+), 30 deletions(-) (limited to 'components/script/dom/bindings/structuredclone.rs') 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 { + ::transfer_receive(cx, r, closure, content, extra_data, return_object) + } else { + false + } } +/// 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::(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 { + pub fn write( + cx: *mut JSContext, + message: HandleValue, + transfer: HandleValue, + ) -> Fallible { 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) - }, + } } } } -- cgit v1.2.3 From 2f8932a6a1e2666567435114383b3acd1899aca7 Mon Sep 17 00:00:00 2001 From: Gregory Terzian Date: Wed, 26 Jun 2019 00:25:48 +0800 Subject: continue messageport, transferable, postmessage options --- components/script/dom/bindings/structuredclone.rs | 301 ++++++++++++---------- 1 file changed, 169 insertions(+), 132 deletions(-) (limited to 'components/script/dom/bindings/structuredclone.rs') diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index 2e33613b29d..25c440365c8 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -6,7 +6,7 @@ //! (https://html.spec.whatwg.org/multipage/#safe-passing-of-structured-data). use crate::compartments::enter_realm; -use crate::dom::bindings::conversions::root_from_handleobject; +use crate::dom::bindings::conversions::{root_from_object, ToJSValConvertible}; use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::root::DomRoot; @@ -14,6 +14,7 @@ use crate::dom::bindings::transferable::Transferable; use crate::dom::blob::{Blob, BlobImpl}; use crate::dom::globalscope::GlobalScope; use crate::dom::messageport::MessagePort; +use crate::script_runtime::JSContext as SafeJSContext; use js::glue::CopyJSStructuredCloneData; use js::glue::DeleteJSAutoStructuredCloneBuffer; use js::glue::GetLengthOfJSStructuredCloneData; @@ -30,12 +31,15 @@ use js::jsapi::{JSObject, JS_ClearPendingException}; use js::jsapi::{JSStructuredCloneCallbacks, JSStructuredCloneReader, JSStructuredCloneWriter}; use js::jsapi::{JS_ReadBytes, JS_WriteBytes}; use js::jsapi::{JS_ReadUint32Pair, JS_WriteUint32Pair}; +use js::jsval::UndefinedValue; use js::rust::wrappers::{JS_ReadStructuredClone, JS_WriteStructuredClone}; -use js::rust::{Handle, HandleValue, MutableHandleValue}; -use libc::size_t; +use js::rust::{CustomAutoRooterGuard, HandleValue, MutableHandleValue}; +use msg::constellation_msg::MessagePortId; +use script_traits::transferable::MessagePortImpl; +use script_traits::StructuredSerializedData; +use std::collections::HashMap; use std::os::raw; use std::ptr; -use std::slice; // TODO: Should we add Min and Max const to https://github.com/servo/rust-mozjs/blob/master/src/consts.rs? // TODO: Determine for sure which value Min and Max should have. @@ -129,19 +133,24 @@ impl StructuredCloneReader { unsafe fn read_blob( cx: *mut JSContext, r: *mut JSStructuredCloneReader, - sc_holder: &mut StructuredCloneHolder, + sc_holder: &mut StructuredDataHolder, ) -> *mut JSObject { let structured_reader = StructuredCloneReader { r: r }; let blob_buffer = structured_reader.read_bytes(); let type_str = structured_reader.read_str(); let target_global = GlobalScope::from_context(cx); - let blob = Blob::new( + let read_blob = Blob::new( &target_global, BlobImpl::new_from_bytes(blob_buffer), type_str, ); - let js_object = blob.reflector().get_jsobject().get(); - sc_holder.blob = Some(blob); + let js_object = read_blob.reflector().get_jsobject().get(); + match sc_holder { + StructuredDataHolder::Read { blob, .. } => { + *blob = Some(read_blob); + }, + _ => panic!("Unexpected variant of StructuredDataHolder"), + } js_object } @@ -174,7 +183,7 @@ unsafe extern "C" fn read_callback( "tag should be higher than StructuredCloneTags::Min" ); if tag == StructuredCloneTags::DomBlob as u32 { - return read_blob(cx, r, &mut *(closure as *mut StructuredCloneHolder)); + return read_blob(cx, r, &mut *(closure as *mut StructuredDataHolder)); } return ptr::null_mut(); } @@ -185,7 +194,7 @@ unsafe extern "C" fn write_callback( obj: RawHandleObject, _closure: *mut raw::c_void, ) -> bool { - if let Ok(blob) = root_from_handleobject::(Handle::from_raw(obj), cx) { + if let Ok(blob) = root_from_object::(*obj, cx) { return write_blob(blob, w).is_ok(); } return false; @@ -193,39 +202,44 @@ unsafe extern "C" fn write_callback( unsafe extern "C" fn read_transfer_callback( cx: *mut JSContext, - r: *mut JSStructuredCloneReader, + _r: *mut JSStructuredCloneReader, tag: u32, - content: *mut raw::c_void, + _content: *mut raw::c_void, extra_data: u64, closure: *mut raw::c_void, return_object: RawMutableHandleObject, ) -> bool { if tag == StructuredCloneTags::MessagePort as u32 { - ::transfer_receive(cx, r, closure, content, extra_data, return_object) - } else { - false + let mut sc_holder = &mut *(closure as *mut StructuredDataHolder); + let owner = GlobalScope::from_context(cx); + if let Ok(_) = ::transfer_receive( + &owner, + &mut sc_holder, + extra_data, + return_object, + ) { + return true; + } } + false } /// unsafe extern "C" fn write_transfer_callback( - _cx: *mut JSContext, + cx: *mut JSContext, obj: RawHandleObject, closure: *mut raw::c_void, tag: *mut u32, ownership: *mut TransferableOwnership, - content: *mut *mut raw::c_void, + _content: *mut *mut raw::c_void, extra_data: *mut u64, ) -> bool { - if let Ok(port) = root_from_handleobject::(Handle::from_raw(obj)) { - if let Some(true) = port.detached() { - return false; - } - + if let Ok(port) = root_from_object::(*obj, cx) { *tag = StructuredCloneTags::MessagePort as u32; *ownership = TransferableOwnership::SCTAG_TMO_CUSTOM; - if port.transfer(closure, content, extra_data) { - port.set_detached(true); + let mut sc_holder = &mut *(closure as *mut StructuredDataHolder); + if let Ok(data) = port.transfer(&mut sc_holder) { + *extra_data = data; return true; } } @@ -242,10 +256,13 @@ unsafe extern "C" fn free_transfer_callback( } unsafe extern "C" fn can_transfer_callback( - _cx: *mut JSContext, - _obj: RawHandleObject, + cx: *mut JSContext, + obj: RawHandleObject, _closure: *mut raw::c_void, ) -> bool { + if let Ok(_port) = root_from_object::(*obj, cx) { + return true; + } false } @@ -261,123 +278,143 @@ static STRUCTURED_CLONE_CALLBACKS: JSStructuredCloneCallbacks = JSStructuredClon canTransfer: Some(can_transfer_callback), }; -struct StructuredCloneHolder { - blob: Option>, +/// A data holder for results from, and inputs to, structured-data read/write operations. +/// https://html.spec.whatwg.org/multipage/#safe-passing-of-structured-data +pub enum StructuredDataHolder { + Read { + /// A deserialized blob, stored temporarily here to keep it rooted. + blob: Option>, + /// A vec of transfer-received DOM ports, + /// to be made available to script through a message event. + message_ports: Option>>, + /// A map of port implementations, + /// used as part of the "transfer-receiving" steps of ports, + /// to produce the DOM ports stored in `message_ports` above. + port_impls: Option>, + }, + /// A data holder into which transferred ports + /// can be written as part of their transfer steps. + Write(Option>), } -/// A buffer for a structured clone. -pub enum StructuredCloneData { - /// A non-serializable (default) variant - Struct(*mut u64, size_t), - /// A variant that can be serialized - Vector(Vec), -} +/// Writes a structured clone. Returns a `DataClone` error if that fails. +pub fn write( + cx: SafeJSContext, + message: HandleValue, + transfer: Option>>, +) -> Fallible { + unsafe { + rooted!(in(*cx) let mut val = UndefinedValue()); + if let Some(transfer) = transfer { + transfer.to_jsval(*cx, val.handle_mut()); + } -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, - transfer: HandleValue, - ) -> Fallible { - 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(), - transfer, - ); - if !result { - JS_ClearPendingException(cx); - return Err(Error::DataClone); - } + let mut sc_holder = StructuredDataHolder::Write(None); + let sc_holder_ptr = &mut sc_holder as *mut _; - let nbytes = GetLengthOfJSStructuredCloneData(scdata); - let mut data = Vec::with_capacity(nbytes); - CopyJSStructuredCloneData(scdata, data.as_mut_ptr()); - data.set_len(nbytes); + 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, + sc_holder_ptr as *mut raw::c_void, + val.handle(), + ); + if !result { + JS_ClearPendingException(*cx); + return Err(Error::DataClone); + } - DeleteJSAutoStructuredCloneBuffer(scbuf); + let nbytes = GetLengthOfJSStructuredCloneData(scdata); + let mut data = Vec::with_capacity(nbytes); + CopyJSStructuredCloneData(scdata, data.as_mut_ptr()); + data.set_len(nbytes); - Ok(StructuredCloneData::Vector(data)) - } - } + DeleteJSAutoStructuredCloneBuffer(scbuf); - /// Converts a StructuredCloneData to Vec for inter-thread sharing - pub fn move_to_arraybuffer(self) -> Vec { - match self { - StructuredCloneData::Struct(data, nbytes) => unsafe { - slice::from_raw_parts(data as *mut u8, nbytes).to_vec() - }, - StructuredCloneData::Vector(msg) => msg, - } - } + let mut port_impls = match sc_holder { + StructuredDataHolder::Write(port_impls) => port_impls, + _ => panic!("Unexpected variant of StructuredDataHolder"), + }; - /// Reads a structured clone. - /// - /// Panics if `JS_ReadStructuredClone` fails. - 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 }; - 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); - - 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 - } + let data = StructuredSerializedData { + serialized: data, + ports: port_impls.take(), + }; + + Ok(data) } +} - /// Thunk for the actual `read_clone` method. Resolves proper variant for read_clone. - 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::Struct(data, nbytes) => { - StructuredCloneData::read_clone(global, data, nbytes, rval) +/// Read structured serialized data, possibly containing transferred objects. +/// Returns a vec of rooted transfer-received ports, or an error. +pub fn read( + global: &GlobalScope, + mut data: StructuredSerializedData, + rval: MutableHandleValue, +) -> Result>, ()> { + let cx = global.get_cx(); + let _ac = enter_realm(&*global); + let mut sc_holder = StructuredDataHolder::Read { + blob: None, + message_ports: None, + port_impls: data.ports.take(), + }; + 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.serialized.as_mut_ptr() as *const u8, + data.serialized.len(), + scdata, + ); + + 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); + + if result { + let (mut message_ports, port_impls) = match sc_holder { + StructuredDataHolder::Read { + message_ports, + port_impls, + .. + } => (message_ports, port_impls), + _ => panic!("Unexpected variant of StructuredDataHolder"), + }; + + // Any transfer-received port-impls should have been taken out. + assert!(port_impls.is_none()); + + match message_ports.take() { + Some(ports) => return Ok(ports), + None => return Ok(Vec::with_capacity(0)), } } + Err(()) } } - -unsafe impl Send for StructuredCloneData {} -- cgit v1.2.3 From 6e8a85482c2068d4dbccb992954271f725570f91 Mon Sep 17 00:00:00 2001 From: Gregory Terzian Date: Sun, 1 Sep 2019 03:18:42 +0800 Subject: re-structure blob, structured serialization --- components/script/dom/bindings/structuredclone.rs | 201 +++++++++------------- 1 file changed, 84 insertions(+), 117 deletions(-) (limited to 'components/script/dom/bindings/structuredclone.rs') diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index 25c440365c8..a61cdb0630c 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -10,8 +10,9 @@ use crate::dom::bindings::conversions::{root_from_object, ToJSValConvertible}; use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::root::DomRoot; +use crate::dom::bindings::serializable::{Serializable, StorageKey}; use crate::dom::bindings::transferable::Transferable; -use crate::dom::blob::{Blob, BlobImpl}; +use crate::dom::blob::Blob; use crate::dom::globalscope::GlobalScope; use crate::dom::messageport::MessagePort; use crate::script_runtime::JSContext as SafeJSContext; @@ -29,12 +30,12 @@ use js::jsapi::TransferableOwnership; use js::jsapi::JS_STRUCTURED_CLONE_VERSION; use js::jsapi::{JSObject, JS_ClearPendingException}; use js::jsapi::{JSStructuredCloneCallbacks, JSStructuredCloneReader, JSStructuredCloneWriter}; -use js::jsapi::{JS_ReadBytes, JS_WriteBytes}; use js::jsapi::{JS_ReadUint32Pair, JS_WriteUint32Pair}; use js::jsval::UndefinedValue; use js::rust::wrappers::{JS_ReadStructuredClone, JS_WriteStructuredClone}; use js::rust::{CustomAutoRooterGuard, HandleValue, MutableHandleValue}; -use msg::constellation_msg::MessagePortId; +use msg::constellation_msg::{BlobId, MessagePortId}; +use script_traits::serializable::BlobImpl; use script_traits::transferable::MessagePortImpl; use script_traits::StructuredSerializedData; use std::collections::HashMap; @@ -54,117 +55,62 @@ enum StructuredCloneTags { Max = 0xFFFFFFFF, } -#[cfg(target_pointer_width = "64")] -unsafe fn write_length(w: *mut JSStructuredCloneWriter, length: usize) { - let high: u32 = (length >> 32) as u32; - let low: u32 = length as u32; - assert!(JS_WriteUint32Pair(w, high, low)); -} - -#[cfg(target_pointer_width = "32")] -unsafe fn write_length(w: *mut JSStructuredCloneWriter, length: usize) { - assert!(JS_WriteUint32Pair(w, length as u32, 0)); -} - -#[cfg(target_pointer_width = "64")] -unsafe fn read_length(r: *mut JSStructuredCloneReader) -> usize { - let mut high: u32 = 0; - let mut low: u32 = 0; - assert!(JS_ReadUint32Pair( - r, - &mut high as *mut u32, - &mut low as *mut u32 - )); - return (low << high) as usize; -} - -#[cfg(target_pointer_width = "32")] -unsafe fn read_length(r: *mut JSStructuredCloneReader) -> usize { - let mut length: u32 = 0; - let mut zero: u32 = 0; +unsafe fn read_blob( + owner: &DomRoot, + r: *mut JSStructuredCloneReader, + mut sc_holder: &mut StructuredDataHolder, +) -> *mut JSObject { + let mut name_space: u32 = 0; + let mut index: u32 = 0; assert!(JS_ReadUint32Pair( r, - &mut length as *mut u32, - &mut zero as *mut u32 + &mut name_space as *mut u32, + &mut index as *mut u32 )); - return length as usize; + let storage_key = StorageKey { index, name_space }; + if ::deserialize(&owner, &mut sc_holder, storage_key.clone()).is_ok() { + let blobs = match sc_holder { + StructuredDataHolder::Read { blobs, .. } => blobs, + _ => panic!("Unexpected variant of StructuredDataHolder"), + }; + if let Some(blobs) = blobs { + let blob = blobs + .get(&storage_key) + .expect("No blob found at storage key."); + return blob.reflector().get_jsobject().get(); + } + } + warn!( + "Reading structured data for a blob failed in {:?}.", + owner.get_url() + ); + ptr::null_mut() } -struct StructuredCloneWriter { +unsafe fn write_blob( + owner: &DomRoot, + blob: DomRoot, w: *mut JSStructuredCloneWriter, -} - -impl StructuredCloneWriter { - unsafe fn write_slice(&self, v: &[u8]) { - let type_length = v.len(); - write_length(self.w, type_length); - assert!(JS_WriteBytes( - self.w, - v.as_ptr() as *const raw::c_void, - type_length + sc_holder: &mut StructuredDataHolder, +) -> bool { + if let Ok(storage_key) = blob.serialize(sc_holder) { + assert!(JS_WriteUint32Pair( + w, + StructuredCloneTags::DomBlob as u32, + 0 )); - } - unsafe fn write_str(&self, s: &str) { - self.write_slice(s.as_bytes()); - } -} - -struct StructuredCloneReader { - r: *mut JSStructuredCloneReader, -} - -impl StructuredCloneReader { - unsafe fn read_bytes(&self) -> Vec { - let mut bytes = vec![0u8; read_length(self.r)]; - let blob_length = bytes.len(); - assert!(JS_ReadBytes( - self.r, - bytes.as_mut_ptr() as *mut raw::c_void, - blob_length + assert!(JS_WriteUint32Pair( + w, + storage_key.name_space, + storage_key.index )); - return bytes; - } - unsafe fn read_str(&self) -> String { - let str_buffer = self.read_bytes(); - return String::from_utf8_unchecked(str_buffer); + return true; } -} - -unsafe fn read_blob( - cx: *mut JSContext, - r: *mut JSStructuredCloneReader, - sc_holder: &mut StructuredDataHolder, -) -> *mut JSObject { - let structured_reader = StructuredCloneReader { r: r }; - let blob_buffer = structured_reader.read_bytes(); - let type_str = structured_reader.read_str(); - let target_global = GlobalScope::from_context(cx); - let read_blob = Blob::new( - &target_global, - BlobImpl::new_from_bytes(blob_buffer), - type_str, + warn!( + "Writing structured data for a blob failed in {:?}.", + owner.get_url() ); - let js_object = read_blob.reflector().get_jsobject().get(); - match sc_holder { - StructuredDataHolder::Read { blob, .. } => { - *blob = Some(read_blob); - }, - _ => panic!("Unexpected variant of StructuredDataHolder"), - } - js_object -} - -unsafe fn write_blob(blob: DomRoot, w: *mut JSStructuredCloneWriter) -> Result<(), ()> { - let structured_writer = StructuredCloneWriter { w: w }; - let blob_vec = blob.get_bytes()?; - assert!(JS_WriteUint32Pair( - w, - StructuredCloneTags::DomBlob as u32, - 0 - )); - structured_writer.write_slice(&blob_vec); - structured_writer.write_str(&blob.type_string()); - return Ok(()); + return false; } unsafe extern "C" fn read_callback( @@ -183,7 +129,11 @@ unsafe extern "C" fn read_callback( "tag should be higher than StructuredCloneTags::Min" ); if tag == StructuredCloneTags::DomBlob as u32 { - return read_blob(cx, r, &mut *(closure as *mut StructuredDataHolder)); + return read_blob( + &GlobalScope::from_context(cx), + r, + &mut *(closure as *mut StructuredDataHolder), + ); } return ptr::null_mut(); } @@ -192,10 +142,15 @@ unsafe extern "C" fn write_callback( cx: *mut JSContext, w: *mut JSStructuredCloneWriter, obj: RawHandleObject, - _closure: *mut raw::c_void, + closure: *mut raw::c_void, ) -> bool { if let Ok(blob) = root_from_object::(*obj, cx) { - return write_blob(blob, w).is_ok(); + return write_blob( + &GlobalScope::from_context(cx), + blob, + w, + &mut *(closure as *mut StructuredDataHolder), + ); } return false; } @@ -282,8 +237,8 @@ static STRUCTURED_CLONE_CALLBACKS: JSStructuredCloneCallbacks = JSStructuredClon /// https://html.spec.whatwg.org/multipage/#safe-passing-of-structured-data pub enum StructuredDataHolder { Read { - /// A deserialized blob, stored temporarily here to keep it rooted. - blob: Option>, + /// A map of deserialized blobs, stored temporarily here to keep them rooted. + blobs: Option>>, /// A vec of transfer-received DOM ports, /// to be made available to script through a message event. message_ports: Option>>, @@ -291,10 +246,18 @@ pub enum StructuredDataHolder { /// used as part of the "transfer-receiving" steps of ports, /// to produce the DOM ports stored in `message_ports` above. port_impls: Option>, + /// A map of blob implementations, + /// used as part of the "deserialize" steps of blobs, + /// to produce the DOM blobs stored in `blobs` above. + blob_impls: Option>, + }, + /// A data holder for transferred and serialized objects. + Write { + /// Transferred ports. + ports: Option>, + /// Serialized blobs. + blobs: Option>, }, - /// A data holder into which transferred ports - /// can be written as part of their transfer steps. - Write(Option>), } /// Writes a structured clone. Returns a `DataClone` error if that fails. @@ -308,8 +271,10 @@ pub fn write( if let Some(transfer) = transfer { transfer.to_jsval(*cx, val.handle_mut()); } - - let mut sc_holder = StructuredDataHolder::Write(None); + let mut sc_holder = StructuredDataHolder::Write { + ports: None, + blobs: None, + }; let sc_holder_ptr = &mut sc_holder as *mut _; let scbuf = NewJSAutoStructuredCloneBuffer( @@ -343,14 +308,15 @@ pub fn write( DeleteJSAutoStructuredCloneBuffer(scbuf); - let mut port_impls = match sc_holder { - StructuredDataHolder::Write(port_impls) => port_impls, + let (mut blob_impls, mut port_impls) = match sc_holder { + StructuredDataHolder::Write { blobs, ports } => (blobs, ports), _ => panic!("Unexpected variant of StructuredDataHolder"), }; let data = StructuredSerializedData { serialized: data, ports: port_impls.take(), + blobs: blob_impls.take(), }; Ok(data) @@ -367,9 +333,10 @@ pub fn read( let cx = global.get_cx(); let _ac = enter_realm(&*global); let mut sc_holder = StructuredDataHolder::Read { - blob: None, + blobs: None, message_ports: None, port_impls: data.ports.take(), + blob_impls: data.blobs.take(), }; let sc_holder_ptr = &mut sc_holder as *mut _; unsafe { -- cgit v1.2.3 From cd9195056c7a83b44ed439ef607b94ed4824431d Mon Sep 17 00:00:00 2001 From: lberrymage Date: Sat, 21 Dec 2019 12:44:34 -0900 Subject: Add lint check for `&DomRoot` `&DomRoot is strictly less expressive than `&T`, so using it is pointless. --- components/script/dom/bindings/structuredclone.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'components/script/dom/bindings/structuredclone.rs') diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index a61cdb0630c..4bbb320ac5c 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -56,7 +56,7 @@ enum StructuredCloneTags { } unsafe fn read_blob( - owner: &DomRoot, + owner: &GlobalScope, r: *mut JSStructuredCloneReader, mut sc_holder: &mut StructuredDataHolder, ) -> *mut JSObject { @@ -88,7 +88,7 @@ unsafe fn read_blob( } unsafe fn write_blob( - owner: &DomRoot, + owner: &GlobalScope, blob: DomRoot, w: *mut JSStructuredCloneWriter, sc_holder: &mut StructuredDataHolder, -- cgit v1.2.3 From 5a3e1b8e6903c825e50597a218532d417f1dfef9 Mon Sep 17 00:00:00 2001 From: Kunal Mohan Date: Fri, 24 Jan 2020 13:29:09 +0530 Subject: rename compartment to realm --- components/script/dom/bindings/structuredclone.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'components/script/dom/bindings/structuredclone.rs') diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index 4bbb320ac5c..82f7a4a7989 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -5,7 +5,6 @@ //! This module implements structured cloning, as defined by [HTML] //! (https://html.spec.whatwg.org/multipage/#safe-passing-of-structured-data). -use crate::compartments::enter_realm; use crate::dom::bindings::conversions::{root_from_object, ToJSValConvertible}; use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::reflector::DomObject; @@ -15,6 +14,7 @@ use crate::dom::bindings::transferable::Transferable; use crate::dom::blob::Blob; use crate::dom::globalscope::GlobalScope; use crate::dom::messageport::MessagePort; +use crate::realms::enter_realm; use crate::script_runtime::JSContext as SafeJSContext; use js::glue::CopyJSStructuredCloneData; use js::glue::DeleteJSAutoStructuredCloneBuffer; -- cgit v1.2.3 From 403ffcf1eb5c659626f70dec72f76aaf7782986d Mon Sep 17 00:00:00 2001 From: CYBAI Date: Fri, 24 Jan 2020 12:43:49 +0900 Subject: Always pass InRealm to GlobalScope::from_context to avoid getting null global --- components/script/dom/bindings/structuredclone.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'components/script/dom/bindings/structuredclone.rs') diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index 82f7a4a7989..dbf852907a8 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -14,7 +14,7 @@ use crate::dom::bindings::transferable::Transferable; use crate::dom::blob::Blob; use crate::dom::globalscope::GlobalScope; use crate::dom::messageport::MessagePort; -use crate::realms::enter_realm; +use crate::realms::{enter_realm, AlreadyInRealm, InRealm}; use crate::script_runtime::JSContext as SafeJSContext; use js::glue::CopyJSStructuredCloneData; use js::glue::DeleteJSAutoStructuredCloneBuffer; @@ -129,8 +129,9 @@ unsafe extern "C" fn read_callback( "tag should be higher than StructuredCloneTags::Min" ); if tag == StructuredCloneTags::DomBlob as u32 { + let in_realm_proof = AlreadyInRealm::assert_for_cx(SafeJSContext::from_ptr(cx)); return read_blob( - &GlobalScope::from_context(cx), + &GlobalScope::from_context(cx, InRealm::Already(&in_realm_proof)), r, &mut *(closure as *mut StructuredDataHolder), ); @@ -145,8 +146,9 @@ unsafe extern "C" fn write_callback( closure: *mut raw::c_void, ) -> bool { if let Ok(blob) = root_from_object::(*obj, cx) { + let in_realm_proof = AlreadyInRealm::assert_for_cx(SafeJSContext::from_ptr(cx)); return write_blob( - &GlobalScope::from_context(cx), + &GlobalScope::from_context(cx, InRealm::Already(&in_realm_proof)), blob, w, &mut *(closure as *mut StructuredDataHolder), @@ -166,7 +168,8 @@ unsafe extern "C" fn read_transfer_callback( ) -> bool { if tag == StructuredCloneTags::MessagePort as u32 { let mut sc_holder = &mut *(closure as *mut StructuredDataHolder); - let owner = GlobalScope::from_context(cx); + let in_realm_proof = AlreadyInRealm::assert_for_cx(SafeJSContext::from_ptr(cx)); + let owner = GlobalScope::from_context(cx, InRealm::Already(&in_realm_proof)); if let Ok(_) = ::transfer_receive( &owner, &mut sc_holder, -- cgit v1.2.3 From 5a4f8cf93f9f674a164a0a3cfc586accef3d06f9 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Mon, 2 Mar 2020 11:16:46 +0100 Subject: Update SpiderMonkey --- components/script/dom/bindings/structuredclone.rs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'components/script/dom/bindings/structuredclone.rs') diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index dbf852907a8..511b8d1650e 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -361,6 +361,9 @@ pub fn read( JS_STRUCTURED_CLONE_VERSION, StructuredCloneScope::DifferentProcess, rval, + CloneDataPolicy { + sharedArrayBuffer_: false, + }, &STRUCTURED_CLONE_CALLBACKS, sc_holder_ptr as *mut raw::c_void, ); -- cgit v1.2.3 From 5c4939599e2793154569b19db87be8cc05ca9269 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Sun, 24 Jan 2021 14:07:10 -0500 Subject: Update mozjs. --- components/script/dom/bindings/structuredclone.rs | 31 ++++++++++++++++++----- 1 file changed, 25 insertions(+), 6 deletions(-) (limited to 'components/script/dom/bindings/structuredclone.rs') diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index 511b8d1650e..132f3f78222 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -116,6 +116,7 @@ unsafe fn write_blob( unsafe extern "C" fn read_callback( cx: *mut JSContext, r: *mut JSStructuredCloneReader, + _policy: *const CloneDataPolicy, tag: u32, _data: u32, closure: *mut raw::c_void, @@ -143,6 +144,7 @@ unsafe extern "C" fn write_callback( cx: *mut JSContext, w: *mut JSStructuredCloneWriter, obj: RawHandleObject, + _same_process_scope_required: *mut bool, closure: *mut raw::c_void, ) -> bool { if let Ok(blob) = root_from_object::(*obj, cx) { @@ -216,6 +218,7 @@ unsafe extern "C" fn free_transfer_callback( unsafe extern "C" fn can_transfer_callback( cx: *mut JSContext, obj: RawHandleObject, + _same_process_scope_required: *mut bool, _closure: *mut raw::c_void, ) -> bool { if let Ok(_port) = root_from_object::(*obj, cx) { @@ -224,7 +227,21 @@ unsafe extern "C" fn can_transfer_callback( false } -unsafe extern "C" fn report_error_callback(_cx: *mut JSContext, _errorid: u32) {} +unsafe extern "C" fn report_error_callback( + _cx: *mut JSContext, + _errorid: u32, + _closure: *mut ::std::os::raw::c_void, + _error_message: *const ::std::os::raw::c_char, +) { +} + +unsafe extern "C" fn sab_cloned_callback( + _cx: *mut JSContext, + _receiving: bool, + _closure: *mut ::std::os::raw::c_void, +) -> bool { + false +} static STRUCTURED_CLONE_CALLBACKS: JSStructuredCloneCallbacks = JSStructuredCloneCallbacks { read: Some(read_callback), @@ -234,6 +251,7 @@ static STRUCTURED_CLONE_CALLBACKS: JSStructuredCloneCallbacks = JSStructuredClon writeTransfer: Some(write_transfer_callback), freeTransfer: Some(free_transfer_callback), canTransfer: Some(can_transfer_callback), + sabCloned: Some(sab_cloned_callback), }; /// A data holder for results from, and inputs to, structured-data read/write operations. @@ -286,15 +304,15 @@ pub fn write( ); let scdata = &mut ((*scbuf).data_); let policy = CloneDataPolicy { - // TODO: SAB? - sharedArrayBuffer_: false, + allowIntraClusterClonableSharedObjects_: false, + allowSharedMemoryObjects_: false, }; let result = JS_WriteStructuredClone( *cx, message, scdata, StructuredCloneScope::DifferentProcess, - policy, + &policy, &STRUCTURED_CLONE_CALLBACKS, sc_holder_ptr as *mut raw::c_void, val.handle(), @@ -361,8 +379,9 @@ pub fn read( JS_STRUCTURED_CLONE_VERSION, StructuredCloneScope::DifferentProcess, rval, - CloneDataPolicy { - sharedArrayBuffer_: false, + &CloneDataPolicy { + allowIntraClusterClonableSharedObjects_: false, + allowSharedMemoryObjects_: false, }, &STRUCTURED_CLONE_CALLBACKS, sc_holder_ptr as *mut raw::c_void, -- cgit v1.2.3