diff options
author | bors-servo <metajack+bors@gmail.com> | 2015-01-10 09:18:45 -0700 |
---|---|---|
committer | bors-servo <metajack+bors@gmail.com> | 2015-01-10 09:18:45 -0700 |
commit | a07c3eadb33eca1fbb2209d168c63c5ec3db23df (patch) | |
tree | 59adff84613e3f1bc801f202ede840f6cf22798f | |
parent | 1834359f1661fe504e5b8ff3ee2bc0cb8d744d21 (diff) | |
parent | 14ff55443fc872f0806a6267655689d48002a3b3 (diff) | |
download | servo-a07c3eadb33eca1fbb2209d168c63c5ec3db23df.tar.gz servo-a07c3eadb33eca1fbb2209d168c63c5ec3db23df.zip |
auto merge of #4607 : Ms2ger/servo/clone, r=jdm
-rw-r--r-- | components/script/dom/bindings/structuredclone.rs | 54 | ||||
-rw-r--r-- | components/script/dom/dedicatedworkerglobalscope.rs | 36 | ||||
-rw-r--r-- | components/script/dom/worker.rs | 46 | ||||
-rw-r--r-- | components/script/lib.rs | 1 | ||||
-rw-r--r-- | components/script/script_task.rs | 4 |
5 files changed, 76 insertions, 65 deletions
diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs new file mode 100644 index 00000000000..843b7bea30c --- /dev/null +++ b/components/script/dom/bindings/structuredclone.rs @@ -0,0 +1,54 @@ +/* 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/. */ + +use dom::bindings::error::Fallible; +use dom::bindings::error::Error::DataClone; +use dom::bindings::global::GlobalRef; + +use js::glue::JS_STRUCTURED_CLONE_VERSION; +use js::jsapi::JSContext; +use js::jsapi::{JS_WriteStructuredClone, JS_ClearPendingException}; +use js::jsapi::JS_ReadStructuredClone; +use js::jsval::{JSVal, UndefinedValue}; + +use libc::size_t; +use std::ptr; + +#[allow(raw_pointer_deriving)] +#[deriving(Copy)] +pub struct StructuredCloneData { + pub data: *mut u64, + pub nbytes: size_t, +} + +impl StructuredCloneData { + pub fn write(cx: *mut JSContext, message: JSVal) + -> Fallible<StructuredCloneData> { + let mut data = ptr::null_mut(); + let mut nbytes = 0; + let result = unsafe { + JS_WriteStructuredClone(cx, message, &mut data, &mut nbytes, + ptr::null(), ptr::null_mut()) + }; + if result == 0 { + unsafe { JS_ClearPendingException(cx); } + return Err(DataClone); + } + Ok(StructuredCloneData { + data: data, + nbytes: nbytes, + }) + } + + pub fn read(self, global: GlobalRef) -> JSVal { + let mut message = UndefinedValue(); + unsafe { + assert!(JS_ReadStructuredClone( + global.get_cx(), self.data as *const u64, self.nbytes, + JS_STRUCTURED_CLONE_VERSION, &mut message, + ptr::null(), ptr::null_mut()) != 0); + } + message + } +} diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs index 6f8242086f0..1403344dad2 100644 --- a/components/script/dom/dedicatedworkerglobalscope.rs +++ b/components/script/dom/dedicatedworkerglobalscope.rs @@ -9,10 +9,10 @@ use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull; use dom::bindings::codegen::InheritTypes::DedicatedWorkerGlobalScopeDerived; use dom::bindings::codegen::InheritTypes::{EventTargetCast, WorkerGlobalScopeCast}; use dom::bindings::error::ErrorResult; -use dom::bindings::error::Error::DataClone; use dom::bindings::global::GlobalRef; use dom::bindings::js::{JSRef, Temporary, RootCollection}; use dom::bindings::refcounted::LiveDOMReferences; +use dom::bindings::structuredclone::StructuredCloneData; use dom::bindings::utils::Reflectable; use dom::eventtarget::{EventTarget, EventTargetHelpers, EventTargetTypeId}; use dom::messageevent::MessageEvent; @@ -27,13 +27,11 @@ use servo_util::task::spawn_named; use servo_util::task_state; use servo_util::task_state::{SCRIPT, IN_WORKER}; -use js::glue::JS_STRUCTURED_CLONE_VERSION; -use js::jsapi::{JSContext, JS_ReadStructuredClone, JS_WriteStructuredClone, JS_ClearPendingException}; -use js::jsval::{JSVal, UndefinedValue}; +use js::jsapi::JSContext; +use js::jsval::JSVal; use js::rust::Cx; use std::rc::Rc; -use std::ptr; use url::Url; /// A ScriptChan that can be cloned freely and will silently send a TrustedWorkerAddress with @@ -197,20 +195,12 @@ trait PrivateDedicatedWorkerGlobalScopeHelpers { } impl<'a> PrivateDedicatedWorkerGlobalScopeHelpers for JSRef<'a, DedicatedWorkerGlobalScope> { - #[allow(unsafe_blocks)] fn handle_event(self, msg: ScriptMsg) { match msg { - ScriptMsg::DOMMessage(data, nbytes) => { - let mut message = UndefinedValue(); + ScriptMsg::DOMMessage(data) => { let scope: JSRef<WorkerGlobalScope> = WorkerGlobalScopeCast::from_ref(self); - unsafe { - assert!(JS_ReadStructuredClone( - scope.get_cx(), data as *const u64, nbytes, - JS_STRUCTURED_CLONE_VERSION, &mut message, - ptr::null(), ptr::null_mut()) != 0); - } - let target: JSRef<EventTarget> = EventTargetCast::from_ref(self); + let message = data.read(GlobalRef::Worker(scope)); MessageEvent::dispatch_jsval(target, GlobalRef::Worker(scope), message); }, ScriptMsg::RunnableMsg(runnable) => { @@ -230,21 +220,11 @@ impl<'a> PrivateDedicatedWorkerGlobalScopeHelpers for JSRef<'a, DedicatedWorkerG } impl<'a> DedicatedWorkerGlobalScopeMethods for JSRef<'a, DedicatedWorkerGlobalScope> { - #[allow(unsafe_blocks)] fn PostMessage(self, cx: *mut JSContext, message: JSVal) -> ErrorResult { - let mut data = ptr::null_mut(); - let mut nbytes = 0; - let result = unsafe { - JS_WriteStructuredClone(cx, message, &mut data, &mut nbytes, - ptr::null(), ptr::null_mut()) - }; - if result == 0 { - unsafe { JS_ClearPendingException(cx); } - return Err(DataClone); - } - + let data = try!(StructuredCloneData::write(cx, message)); let worker = self.worker.borrow().as_ref().unwrap().clone(); - self.parent_sender.send(ScriptMsg::RunnableMsg(box WorkerMessageHandler::new(worker, data, nbytes))); + self.parent_sender.send(ScriptMsg::RunnableMsg( + box WorkerMessageHandler::new(worker, data))); Ok(()) } diff --git a/components/script/dom/worker.rs b/components/script/dom/worker.rs index d3681900db3..3822e4e538c 100644 --- a/components/script/dom/worker.rs +++ b/components/script/dom/worker.rs @@ -7,10 +7,11 @@ use dom::bindings::codegen::Bindings::WorkerBinding::WorkerMethods; use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull; use dom::bindings::codegen::InheritTypes::EventTargetCast; use dom::bindings::error::{Fallible, ErrorResult}; -use dom::bindings::error::Error::{Syntax, DataClone}; +use dom::bindings::error::Error::Syntax; use dom::bindings::global::{GlobalRef, GlobalField}; use dom::bindings::js::{JSRef, Temporary}; use dom::bindings::refcounted::Trusted; +use dom::bindings::structuredclone::StructuredCloneData; use dom::bindings::trace::JSTraceable; use dom::bindings::utils::{Reflectable, reflect_dom_object}; use dom::dedicatedworkerglobalscope::DedicatedWorkerGlobalScope; @@ -20,15 +21,11 @@ use script_task::{ScriptChan, ScriptMsg, Runnable}; use servo_util::str::DOMString; -use js::glue::JS_STRUCTURED_CLONE_VERSION; use js::jsapi::JSContext; -use js::jsapi::{JS_ReadStructuredClone, JS_WriteStructuredClone, JS_ClearPendingException}; -use js::jsval::{JSVal, UndefinedValue}; +use js::jsval::JSVal; use url::UrlParser; -use libc::size_t; use std::cell::Cell; -use std::ptr; pub type TrustedWorkerAddress = Trusted<Worker>; @@ -80,42 +77,23 @@ impl Worker { Ok(Temporary::from_rooted(worker.r())) } - #[allow(unsafe_blocks)] pub fn handle_message(address: TrustedWorkerAddress, - data: *mut u64, nbytes: size_t) { + data: StructuredCloneData) { let worker = address.to_temporary().root(); let global = worker.r().global.root(); - - let mut message = UndefinedValue(); - unsafe { - assert!(JS_ReadStructuredClone( - global.r().get_cx(), data as *const u64, nbytes, - JS_STRUCTURED_CLONE_VERSION, &mut message, - ptr::null(), ptr::null_mut()) != 0); - } - let target: JSRef<EventTarget> = EventTargetCast::from_ref(worker.r()); + + let message = data.read(global.r()); MessageEvent::dispatch_jsval(target, global.r(), message); } } impl<'a> WorkerMethods for JSRef<'a, Worker> { - #[allow(unsafe_blocks)] fn PostMessage(self, cx: *mut JSContext, message: JSVal) -> ErrorResult { - let mut data = ptr::null_mut(); - let mut nbytes = 0; - let result = unsafe { - JS_WriteStructuredClone(cx, message, &mut data, &mut nbytes, - ptr::null(), ptr::null_mut()) - }; - if result == 0 { - unsafe { JS_ClearPendingException(cx); } - return Err(DataClone); - } - + let data = try!(StructuredCloneData::write(cx, message)); let address = Trusted::new(cx, self, self.global.root().r().script_chan().clone()); - self.sender.send((address, ScriptMsg::DOMMessage(data, nbytes))); + self.sender.send((address, ScriptMsg::DOMMessage(data))); Ok(()) } @@ -124,22 +102,20 @@ impl<'a> WorkerMethods for JSRef<'a, Worker> { pub struct WorkerMessageHandler { addr: TrustedWorkerAddress, - data: *mut u64, - nbytes: size_t + data: StructuredCloneData, } impl WorkerMessageHandler { - pub fn new(addr: TrustedWorkerAddress, data: *mut u64, nbytes: size_t) -> WorkerMessageHandler { + pub fn new(addr: TrustedWorkerAddress, data: StructuredCloneData) -> WorkerMessageHandler { WorkerMessageHandler { addr: addr, data: data, - nbytes: nbytes, } } } impl Runnable for WorkerMessageHandler { fn handler(&self){ - Worker::handle_message(self.addr.clone(), self.data, self.nbytes); + Worker::handle_message(self.addr.clone(), self.data); } } diff --git a/components/script/lib.rs b/components/script/lib.rs index bd4b19745a4..50661a60ca1 100644 --- a/components/script/lib.rs +++ b/components/script/lib.rs @@ -64,6 +64,7 @@ pub mod dom { pub mod conversions; mod proxyhandler; pub mod str; + pub mod structuredclone; pub mod trace; /// Generated JS-Rust bindings. diff --git a/components/script/script_task.rs b/components/script/script_task.rs index 1c4af120334..4783d8539f4 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -19,6 +19,7 @@ use dom::bindings::global::GlobalRef; use dom::bindings::js::{JS, JSRef, Temporary, OptionalRootable}; use dom::bindings::js::{RootCollection, RootCollectionPtr}; use dom::bindings::refcounted::{LiveDOMReferences, Trusted}; +use dom::bindings::structuredclone::StructuredCloneData; use dom::bindings::trace::JSTraceable; use dom::bindings::utils::{wrap_for_same_compartment, pre_wrap}; use dom::document::{Document, IsHTMLDocument, DocumentHelpers, DocumentSource}; @@ -77,7 +78,6 @@ use js; use url::Url; use libc; -use libc::size_t; use std::any::{Any, AnyRefExt}; use std::cell::Cell; use std::comm::{channel, Sender, Receiver, Select}; @@ -120,7 +120,7 @@ pub enum ScriptMsg { ExitWindow(PipelineId), /// Message sent through Worker.postMessage (only dispatched to /// DedicatedWorkerGlobalScope). - DOMMessage(*mut u64, size_t), + DOMMessage(StructuredCloneData), /// Generic message that encapsulates event handling. RunnableMsg(Box<Runnable+Send>), /// A DOM object's last pinned reference was removed (dispatched to all tasks). |