From 314dedb96fdea9d7656a3be166aec7749d2b85da Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Wed, 7 Sep 2016 11:25:03 +0530 Subject: [PATCH] make structured clone an enum --- .../script/dom/bindings/structuredclone.rs | 54 ++++++++++--------- components/script/dom/serviceworker.rs | 36 +++++-------- .../script/dom/serviceworkercontainer.rs | 3 +- .../script/dom/serviceworkerregistration.rs | 8 +-- components/script/serviceworker_manager.rs | 4 +- components/script_traits/script_msg.rs | 2 +- 6 files changed, 51 insertions(+), 56 deletions(-) diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index 1078ffcacc8e..21963eec1723 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -11,14 +11,15 @@ use js::jsapi::{HandleValue, MutableHandleValue}; use js::jsapi::{JSContext, JS_ReadStructuredClone, JS_STRUCTURED_CLONE_VERSION}; use js::jsapi::{JS_ClearPendingException, JS_WriteStructuredClone}; use libc::size_t; -use script_traits::DOMMessage; use std::ptr; use std::slice; /// A buffer for a structured clone. -pub struct StructuredCloneData { - data: *mut u64, - nbytes: size_t, +pub enum StructuredCloneData { + /// A non-serializable (default) variant + Struct(*mut u64, size_t), + /// A variant that can be serialized + Vector(Vec) } impl StructuredCloneData { @@ -41,44 +42,47 @@ impl StructuredCloneData { } return Err(Error::DataClone); } - Ok(StructuredCloneData { - data: data, - nbytes: nbytes, - }) + Ok(StructuredCloneData::Struct(data, nbytes)) } /// Converts a StructuredCloneData to Vec for inter-thread sharing - pub fn move_to_arraybuffer(self) -> DOMMessage { - unsafe { - DOMMessage(slice::from_raw_parts(self.data as *mut u8, self.nbytes).to_vec()) - } - } - - /// Converts back to StructuredCloneData - pub fn make_structured_clone(data: DOMMessage) -> StructuredCloneData { - let DOMMessage(mut data) = data; - let nbytes = data.len(); - let data = data.as_mut_ptr() as *mut u64; - StructuredCloneData { - data: data, - nbytes: nbytes + 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 } } /// Reads a structured clone. /// /// Panics if `JS_ReadStructuredClone` fails. - pub fn read(self, global: GlobalRef, rval: MutableHandleValue) { + fn read_clone(global: GlobalRef, data: *mut u64, nbytes: size_t, rval: MutableHandleValue) { unsafe { assert!(JS_ReadStructuredClone(global.get_cx(), - self.data, - self.nbytes, + data, + nbytes, JS_STRUCTURED_CLONE_VERSION, rval, ptr::null(), ptr::null_mut())); } } + + /// Thunk for the actual `read_clone` method. Resolves proper variant for read_clone. + pub fn read(self, global: GlobalRef, rval: MutableHandleValue) { + 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) + } + } } unsafe impl Send for StructuredCloneData {} diff --git a/components/script/dom/serviceworker.rs b/components/script/dom/serviceworker.rs index e966173921f0..9c37d73bd9e1 100644 --- a/components/script/dom/serviceworker.rs +++ b/components/script/dom/serviceworker.rs @@ -11,13 +11,13 @@ use dom::bindings::global::GlobalRef; use dom::bindings::inheritance::Castable; use dom::bindings::js::Root; use dom::bindings::refcounted::Trusted; -use dom::bindings::reflector::reflect_dom_object; +use dom::bindings::reflector::{Reflectable, reflect_dom_object}; use dom::bindings::str::USVString; use dom::bindings::structuredclone::StructuredCloneData; use dom::eventtarget::EventTarget; use js::jsapi::{HandleValue, JSContext}; use script_thread::Runnable; -use script_traits::ScriptMsg; +use script_traits::{ScriptMsg, DOMMessage}; use std::cell::Cell; use url::Url; @@ -27,7 +27,7 @@ pub type TrustedServiceWorkerAddress = Trusted; pub struct ServiceWorker { eventtarget: EventTarget, script_url: DOMRefCell, - scope_url: DOMRefCell, + scope_url: Url, state: Cell, skip_waiting: Cell } @@ -35,21 +35,23 @@ pub struct ServiceWorker { impl ServiceWorker { fn new_inherited(script_url: &str, skip_waiting: bool, - scope_url: &str) -> ServiceWorker { + scope_url: Url) -> ServiceWorker { ServiceWorker { eventtarget: EventTarget::new_inherited(), script_url: DOMRefCell::new(String::from(script_url)), state: Cell::new(ServiceWorkerState::Installing), - scope_url: DOMRefCell::new(String::from(scope_url)), + scope_url: scope_url, skip_waiting: Cell::new(skip_waiting) } } - pub fn new(global: GlobalRef, - script_url: &str, - scope_url: &str, + pub fn install_serviceworker(global: GlobalRef, + script_url: Url, + scope_url: Url, skip_waiting: bool) -> Root { - reflect_dom_object(box ServiceWorker::new_inherited(script_url, skip_waiting, scope_url), global, Wrap) + reflect_dom_object(box ServiceWorker::new_inherited(script_url.as_str(), + skip_waiting, + scope_url), global, Wrap) } pub fn dispatch_simple_error(address: TrustedServiceWorkerAddress) { @@ -65,16 +67,6 @@ impl ServiceWorker { pub fn get_script_url(&self) -> Url { Url::parse(&self.script_url.borrow().clone()).unwrap() } - - pub fn install_serviceworker(global: GlobalRef, - script_url: Url, - scope_url: &str, - skip_waiting: bool) -> Root { - ServiceWorker::new(global, - script_url.as_str(), - scope_url, - skip_waiting) - } } impl ServiceWorkerMethods for ServiceWorker { @@ -96,9 +88,9 @@ impl ServiceWorkerMethods for ServiceWorker { } // Step 7 let data = try!(StructuredCloneData::write(cx, message)); - let msg_vec = data.move_to_arraybuffer(); - let scope_url = Url::parse(&*self.scope_url.borrow()).unwrap(); - let _ = self.global().r().constellation_chan().send(ScriptMsg::ForwardDOMMessage(msg_vec, scope_url)); + let msg_vec = DOMMessage(data.move_to_arraybuffer()); + let _ = self.global().r().constellation_chan().send(ScriptMsg::ForwardDOMMessage(msg_vec, + self.scope_url.clone())); Ok(()) } diff --git a/components/script/dom/serviceworkercontainer.rs b/components/script/dom/serviceworkercontainer.rs index 4487c064fe12..90e2fe1da8f2 100644 --- a/components/script/dom/serviceworkercontainer.rs +++ b/components/script/dom/serviceworkercontainer.rs @@ -95,10 +95,9 @@ impl ServiceWorkerContainerMethods for ServiceWorkerContainer { return Err(Error::Type("Scope URL contains forbidden characters".to_owned())); } - let scope_str = scope.as_str().to_owned(); let worker_registration = ServiceWorkerRegistration::new(self.global().r(), script_url, - scope_str.clone(), + scope.clone(), self); ScriptThread::set_registration(scope, &*worker_registration, self.global().r().pipeline()); Ok(worker_registration) diff --git a/components/script/dom/serviceworkerregistration.rs b/components/script/dom/serviceworkerregistration.rs index c95d68856e81..a885681f629c 100644 --- a/components/script/dom/serviceworkerregistration.rs +++ b/components/script/dom/serviceworkerregistration.rs @@ -25,21 +25,21 @@ pub struct ServiceWorkerRegistration { } impl ServiceWorkerRegistration { - fn new_inherited(active_sw: &ServiceWorker, scope: String) -> ServiceWorkerRegistration { + fn new_inherited(active_sw: &ServiceWorker, scope: Url) -> ServiceWorkerRegistration { ServiceWorkerRegistration { eventtarget: EventTarget::new_inherited(), active: Some(JS::from_ref(active_sw)), installing: None, waiting: None, - scope: scope, + scope: scope.as_str().to_owned(), } } #[allow(unrooted_must_root)] pub fn new(global: GlobalRef, script_url: Url, - scope: String, + scope: Url, container: &Controllable) -> Root { - let active_worker = ServiceWorker::install_serviceworker(global, script_url.clone(), &scope, true); + let active_worker = ServiceWorker::install_serviceworker(global, script_url.clone(), scope.clone(), true); active_worker.set_transition_state(ServiceWorkerState::Installed); container.set_controller(&*active_worker.clone()); reflect_dom_object(box ServiceWorkerRegistration::new_inherited(&*active_worker, scope), global, Wrap) diff --git a/components/script/serviceworker_manager.rs b/components/script/serviceworker_manager.rs index 2fb97b35b85b..3ce26a7693e0 100644 --- a/components/script/serviceworker_manager.rs +++ b/components/script/serviceworker_manager.rs @@ -123,9 +123,9 @@ impl ServiceWorkerManager { } } - #[inline(always)] fn forward_message(&self, msg: DOMMessage, sender: &Sender) { - let data = StructuredCloneData::make_structured_clone(msg); + let DOMMessage(data) = msg; + let data = StructuredCloneData::Vector(data); let _ = sender.send(ServiceWorkerScriptMsg::CommonWorker(WorkerScriptMsg::DOMMessage(data))); } diff --git a/components/script_traits/script_msg.rs b/components/script_traits/script_msg.rs index 446aa1b186bd..0f8c37b60c50 100644 --- a/components/script_traits/script_msg.rs +++ b/components/script_traits/script_msg.rs @@ -180,7 +180,7 @@ pub enum ServiceWorkerMsg { RegisterServiceWorker(ScopeThings, Url), /// Timeout message sent by active service workers Timeout(Url), - /// Backup message + /// Message sent by constellation to forward to a running service worker ForwardDOMMessage(DOMMessage, Url), /// Exit the service worker manager Exit,