aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <metajack+bors@gmail.com>2015-01-10 09:18:45 -0700
committerbors-servo <metajack+bors@gmail.com>2015-01-10 09:18:45 -0700
commita07c3eadb33eca1fbb2209d168c63c5ec3db23df (patch)
tree59adff84613e3f1bc801f202ede840f6cf22798f
parent1834359f1661fe504e5b8ff3ee2bc0cb8d744d21 (diff)
parent14ff55443fc872f0806a6267655689d48002a3b3 (diff)
downloadservo-a07c3eadb33eca1fbb2209d168c63c5ec3db23df.tar.gz
servo-a07c3eadb33eca1fbb2209d168c63c5ec3db23df.zip
auto merge of #4607 : Ms2ger/servo/clone, r=jdm
-rw-r--r--components/script/dom/bindings/structuredclone.rs54
-rw-r--r--components/script/dom/dedicatedworkerglobalscope.rs36
-rw-r--r--components/script/dom/worker.rs46
-rw-r--r--components/script/lib.rs1
-rw-r--r--components/script/script_task.rs4
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).