mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Merge pull request #3080 from Ms2ger/clone
Structured clone the argument to postMessage; r=larsberg
This commit is contained in:
commit
d2ffbec5ed
19 changed files with 66 additions and 119 deletions
|
@ -24,11 +24,14 @@ use script_task::WorkerPostMessage;
|
||||||
use script_task::StackRootTLS;
|
use script_task::StackRootTLS;
|
||||||
|
|
||||||
use servo_net::resource_task::{ResourceTask, load_whole_resource};
|
use servo_net::resource_task::{ResourceTask, load_whole_resource};
|
||||||
use servo_util::str::DOMString;
|
|
||||||
|
|
||||||
|
use js::glue::JS_STRUCTURED_CLONE_VERSION;
|
||||||
|
use js::jsapi::{JSContext, JS_ReadStructuredClone, JS_WriteStructuredClone};
|
||||||
|
use js::jsval::{JSVal, UndefinedValue};
|
||||||
use js::rust::Cx;
|
use js::rust::Cx;
|
||||||
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use std::ptr;
|
||||||
use std::task::TaskBuilder;
|
use std::task::TaskBuilder;
|
||||||
use native::task::NativeTaskBuilder;
|
use native::task::NativeTaskBuilder;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
@ -117,15 +120,23 @@ impl DedicatedWorkerGlobalScope {
|
||||||
EventTargetCast::from_ref(&*global);
|
EventTargetCast::from_ref(&*global);
|
||||||
loop {
|
loop {
|
||||||
match global.receiver.recv_opt() {
|
match global.receiver.recv_opt() {
|
||||||
Ok(DOMMessage(message)) => {
|
Ok(DOMMessage(data, nbytes)) => {
|
||||||
MessageEvent::dispatch(target, &Worker(*scope), message);
|
let mut message = UndefinedValue();
|
||||||
|
unsafe {
|
||||||
|
assert!(JS_ReadStructuredClone(
|
||||||
|
js_context.ptr, data as *const u64, nbytes,
|
||||||
|
JS_STRUCTURED_CLONE_VERSION, &mut message,
|
||||||
|
ptr::null(), ptr::mut_null()) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageEvent::dispatch_jsval(target, &Worker(*scope), message);
|
||||||
global.delayed_release_worker();
|
global.delayed_release_worker();
|
||||||
},
|
},
|
||||||
Ok(XHRProgressMsg(addr, progress)) => {
|
Ok(XHRProgressMsg(addr, progress)) => {
|
||||||
XMLHttpRequest::handle_xhr_progress(addr, progress)
|
XMLHttpRequest::handle_xhr_progress(addr, progress)
|
||||||
},
|
},
|
||||||
Ok(WorkerPostMessage(addr, message)) => {
|
Ok(WorkerPostMessage(addr, data, nbytes)) => {
|
||||||
Worker::handle_message(addr, message);
|
Worker::handle_message(addr, data, nbytes);
|
||||||
},
|
},
|
||||||
Ok(WorkerRelease(addr)) => {
|
Ok(WorkerRelease(addr)) => {
|
||||||
Worker::handle_release(addr)
|
Worker::handle_release(addr)
|
||||||
|
@ -139,9 +150,16 @@ impl DedicatedWorkerGlobalScope {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DedicatedWorkerGlobalScopeMethods for JSRef<'a, DedicatedWorkerGlobalScope> {
|
impl<'a> DedicatedWorkerGlobalScopeMethods for JSRef<'a, DedicatedWorkerGlobalScope> {
|
||||||
fn PostMessage(&self, message: DOMString) {
|
fn PostMessage(&self, cx: *mut JSContext, message: JSVal) {
|
||||||
|
let mut data = ptr::mut_null();
|
||||||
|
let mut nbytes = 0;
|
||||||
|
unsafe {
|
||||||
|
assert!(JS_WriteStructuredClone(cx, message, &mut data, &mut nbytes,
|
||||||
|
ptr::null(), ptr::mut_null()) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
let ScriptChan(ref sender) = self.parent_sender;
|
let ScriptChan(ref sender) = self.parent_sender;
|
||||||
sender.send(WorkerPostMessage(*self.worker, message));
|
sender.send(WorkerPostMessage(*self.worker, data, nbytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn GetOnmessage(&self) -> Option<EventHandlerNonNull> {
|
fn GetOnmessage(&self) -> Option<EventHandlerNonNull> {
|
||||||
|
|
|
@ -6,7 +6,6 @@ use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
|
||||||
use dom::bindings::codegen::Bindings::MessageEventBinding;
|
use dom::bindings::codegen::Bindings::MessageEventBinding;
|
||||||
use dom::bindings::codegen::Bindings::MessageEventBinding::MessageEventMethods;
|
use dom::bindings::codegen::Bindings::MessageEventBinding::MessageEventMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::{EventCast, MessageEventDerived};
|
use dom::bindings::codegen::InheritTypes::{EventCast, MessageEventDerived};
|
||||||
use dom::bindings::conversions::ToJSValConvertible;
|
|
||||||
use dom::bindings::error::Fallible;
|
use dom::bindings::error::Fallible;
|
||||||
use dom::bindings::global::GlobalRef;
|
use dom::bindings::global::GlobalRef;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::{JSRef, Temporary};
|
||||||
|
@ -68,12 +67,11 @@ impl MessageEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MessageEvent {
|
impl MessageEvent {
|
||||||
pub fn dispatch(target: &JSRef<EventTarget>,
|
pub fn dispatch_jsval(target: &JSRef<EventTarget>,
|
||||||
scope: &GlobalRef,
|
scope: &GlobalRef,
|
||||||
message: DOMString) {
|
message: JSVal) {
|
||||||
let messageevent = MessageEvent::new(
|
let messageevent = MessageEvent::new(
|
||||||
scope, "message".to_string(), false, false,
|
scope, "message".to_string(), false, false, message,
|
||||||
message.to_jsval(scope.get_cx()),
|
|
||||||
"".to_string(), "".to_string()).root();
|
"".to_string(), "".to_string()).root();
|
||||||
let event: &JSRef<Event> = EventCast::from_ref(&*messageevent);
|
let event: &JSRef<Event> = EventCast::from_ref(&*messageevent);
|
||||||
target.dispatch_event_with_target(None, &*event).unwrap();
|
target.dispatch_event_with_target(None, &*event).unwrap();
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
// http://www.whatwg.org/html/#dedicatedworkerglobalscope
|
// http://www.whatwg.org/html/#dedicatedworkerglobalscope
|
||||||
[Global/*=Worker,DedicatedWorker*/]
|
[Global/*=Worker,DedicatedWorker*/]
|
||||||
/*sealed*/ interface DedicatedWorkerGlobalScope : WorkerGlobalScope {
|
/*sealed*/ interface DedicatedWorkerGlobalScope : WorkerGlobalScope {
|
||||||
//void postMessage(any message, optional sequence<Transferable> transfer);
|
void postMessage(any message/*, optional sequence<Transferable> transfer*/);
|
||||||
void postMessage(DOMString message);
|
|
||||||
attribute EventHandler onmessage;
|
attribute EventHandler onmessage;
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,8 +14,7 @@ interface AbstractWorker {
|
||||||
interface Worker : EventTarget {
|
interface Worker : EventTarget {
|
||||||
//void terminate();
|
//void terminate();
|
||||||
|
|
||||||
//void postMessage(any message/*, optional sequence<Transferable> transfer*/);
|
void postMessage(any message/*, optional sequence<Transferable> transfer*/);
|
||||||
void postMessage(DOMString message);
|
|
||||||
attribute EventHandler onmessage;
|
attribute EventHandler onmessage;
|
||||||
};
|
};
|
||||||
Worker implements AbstractWorker;
|
Worker implements AbstractWorker;
|
||||||
|
|
|
@ -17,11 +17,15 @@ use script_task::{ScriptChan, DOMMessage};
|
||||||
|
|
||||||
use servo_util::str::DOMString;
|
use servo_util::str::DOMString;
|
||||||
|
|
||||||
use js::jsapi::{JS_AddObjectRoot, JS_RemoveObjectRoot};
|
use js::glue::JS_STRUCTURED_CLONE_VERSION;
|
||||||
|
use js::jsapi::{JSContext, JS_AddObjectRoot, JS_RemoveObjectRoot};
|
||||||
|
use js::jsapi::{JS_ReadStructuredClone, JS_WriteStructuredClone};
|
||||||
|
use js::jsval::{JSVal, UndefinedValue};
|
||||||
use url::UrlParser;
|
use url::UrlParser;
|
||||||
|
|
||||||
use libc::c_void;
|
use libc::{c_void, size_t};
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
pub struct TrustedWorkerAddress(pub *const c_void);
|
pub struct TrustedWorkerAddress(pub *const c_void);
|
||||||
|
|
||||||
|
@ -73,12 +77,22 @@ impl Worker {
|
||||||
Ok(Temporary::from_rooted(&*worker))
|
Ok(Temporary::from_rooted(&*worker))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_message(address: TrustedWorkerAddress, message: DOMString) {
|
pub fn handle_message(address: TrustedWorkerAddress,
|
||||||
|
data: *mut u64, nbytes: size_t) {
|
||||||
let worker = unsafe { JS::from_trusted_worker_address(address).root() };
|
let worker = unsafe { JS::from_trusted_worker_address(address).root() };
|
||||||
|
|
||||||
let target: &JSRef<EventTarget> = EventTargetCast::from_ref(&*worker);
|
|
||||||
let global = worker.global.root();
|
let global = worker.global.root();
|
||||||
MessageEvent::dispatch(target, &global.root_ref(), message);
|
|
||||||
|
let mut message = UndefinedValue();
|
||||||
|
unsafe {
|
||||||
|
assert!(JS_ReadStructuredClone(
|
||||||
|
global.root_ref().get_cx(), data as *const u64, nbytes,
|
||||||
|
JS_STRUCTURED_CLONE_VERSION, &mut message,
|
||||||
|
ptr::null(), ptr::mut_null()) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
let target: &JSRef<EventTarget> = EventTargetCast::from_ref(&*worker);
|
||||||
|
MessageEvent::dispatch_jsval(target, &global.root_ref(), message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,10 +129,17 @@ impl Worker {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> WorkerMethods for JSRef<'a, Worker> {
|
impl<'a> WorkerMethods for JSRef<'a, Worker> {
|
||||||
fn PostMessage(&self, message: DOMString) {
|
fn PostMessage(&self, cx: *mut JSContext, message: JSVal) {
|
||||||
|
let mut data = ptr::mut_null();
|
||||||
|
let mut nbytes = 0;
|
||||||
|
unsafe {
|
||||||
|
assert!(JS_WriteStructuredClone(cx, message, &mut data, &mut nbytes,
|
||||||
|
ptr::null(), ptr::mut_null()) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
self.addref();
|
self.addref();
|
||||||
let ScriptChan(ref sender) = self.sender;
|
let ScriptChan(ref sender) = self.sender;
|
||||||
sender.send(DOMMessage(message));
|
sender.send(DOMMessage(data, nbytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn GetOnmessage(&self) -> Option<EventHandlerNonNull> {
|
fn GetOnmessage(&self) -> Option<EventHandlerNonNull> {
|
||||||
|
|
|
@ -45,7 +45,6 @@ use servo_msg::constellation_msg;
|
||||||
use servo_net::image_cache_task::ImageCacheTask;
|
use servo_net::image_cache_task::ImageCacheTask;
|
||||||
use servo_net::resource_task::ResourceTask;
|
use servo_net::resource_task::ResourceTask;
|
||||||
use servo_util::geometry::to_frac_px;
|
use servo_util::geometry::to_frac_px;
|
||||||
use servo_util::str::DOMString;
|
|
||||||
use servo_util::task::spawn_named_with_send_on_failure;
|
use servo_util::task::spawn_named_with_send_on_failure;
|
||||||
|
|
||||||
use geom::point::Point2D;
|
use geom::point::Point2D;
|
||||||
|
@ -56,6 +55,7 @@ use js::rust::with_compartment;
|
||||||
use js;
|
use js;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
|
use libc::size_t;
|
||||||
use serialize::{Encoder, Encodable};
|
use serialize::{Encoder, Encodable};
|
||||||
use std::any::{Any, AnyRefExt};
|
use std::any::{Any, AnyRefExt};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
@ -86,9 +86,9 @@ pub enum ScriptMsg {
|
||||||
XHRProgressMsg(TrustedXHRAddress, XHRProgress),
|
XHRProgressMsg(TrustedXHRAddress, XHRProgress),
|
||||||
/// Message sent through Worker.postMessage (only dispatched to
|
/// Message sent through Worker.postMessage (only dispatched to
|
||||||
/// DedicatedWorkerGlobalScope).
|
/// DedicatedWorkerGlobalScope).
|
||||||
DOMMessage(DOMString),
|
DOMMessage(*mut u64, size_t),
|
||||||
/// Posts a message to the Worker object (dispatched to all tasks).
|
/// Posts a message to the Worker object (dispatched to all tasks).
|
||||||
WorkerPostMessage(TrustedWorkerAddress, DOMString),
|
WorkerPostMessage(TrustedWorkerAddress, *mut u64, size_t),
|
||||||
/// Releases one reference to the Worker object (dispatched to all tasks).
|
/// Releases one reference to the Worker object (dispatched to all tasks).
|
||||||
WorkerRelease(TrustedWorkerAddress),
|
WorkerRelease(TrustedWorkerAddress),
|
||||||
}
|
}
|
||||||
|
@ -446,7 +446,7 @@ impl ScriptTask {
|
||||||
FromConstellation(ResizeMsg(..)) => fail!("should have handled ResizeMsg already"),
|
FromConstellation(ResizeMsg(..)) => fail!("should have handled ResizeMsg already"),
|
||||||
FromScript(XHRProgressMsg(addr, progress)) => XMLHttpRequest::handle_xhr_progress(addr, progress),
|
FromScript(XHRProgressMsg(addr, progress)) => XMLHttpRequest::handle_xhr_progress(addr, progress),
|
||||||
FromScript(DOMMessage(..)) => fail!("unexpected message"),
|
FromScript(DOMMessage(..)) => fail!("unexpected message"),
|
||||||
FromScript(WorkerPostMessage(addr, message)) => Worker::handle_message(addr, message),
|
FromScript(WorkerPostMessage(addr, data, nbytes)) => Worker::handle_message(addr, data, nbytes),
|
||||||
FromScript(WorkerRelease(addr)) => Worker::handle_release(addr),
|
FromScript(WorkerRelease(addr)) => Worker::handle_release(addr),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 3104cf76fc0ceffec78bcbf430faabd524864d2c
|
Subproject commit 33bcfb764e9ab2d8b065915764cd0223e43a3770
|
|
@ -1,5 +0,0 @@
|
||||||
[WorkerGlobalScope_EventTarget.htm]
|
|
||||||
type: testharness
|
|
||||||
[Test Description: WorkerGlobalScope implements EventTarget]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[expected-self-properties.html]
|
|
||||||
type: testharness
|
|
||||||
[expected interface objects/constructors]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -3,9 +3,6 @@
|
||||||
[unsupported_scheme]
|
[unsupported_scheme]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[data_url]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[about_blank]
|
[about_blank]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[return-value.html]
|
|
||||||
type: testharness
|
|
||||||
[return value of postMessage]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[second-argument-null.html]
|
|
||||||
type: testharness
|
|
||||||
[Using null in postMessage\'s second argument]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[setting-postMessage.html]
|
|
||||||
type: testharness
|
|
||||||
[setting postMessage]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
[structured-clone-message.html]
|
|
||||||
type: testharness
|
|
||||||
[undefined]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[null]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[false]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[true]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[NaN]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Infinity]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[date]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[regexp]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[self]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[array]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[object]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[error]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[self.html]
|
|
||||||
type: testharness
|
|
||||||
[self]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[005.html]
|
|
||||||
type: testharness
|
|
||||||
[importScripts separate scripts]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
[006.html]
|
[006.html]
|
||||||
type: testharness
|
type: testharness
|
||||||
|
expected: TIMEOUT
|
||||||
[importScripts uncaught exception]
|
[importScripts uncaught exception]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[003.html]
|
|
||||||
type: testharness
|
|
||||||
[URL encoding, dedicated worker]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[001.html]
|
|
||||||
type: testharness
|
|
||||||
[worker global scope, dedicated worker]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue