aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/workerglobalscope.rs
diff options
context:
space:
mode:
authoryvt <i@yvt.jp>2021-07-10 17:24:27 +0900
committeryvt <i@yvt.jp>2021-07-10 17:55:42 +0900
commit01a7de50ab1843d85295f9dccad7f4c099e7208c (patch)
treeee53fb6e8889deb7b880ee969e6c662e6128d210 /components/script/dom/workerglobalscope.rs
parentff8d2cdbbfc7a9dc7f38b7dd47cb350fde39388f (diff)
parent94b613fbdaa2b98f2179fc0bbda13c64e6fa0d38 (diff)
downloadservo-01a7de50ab1843d85295f9dccad7f4c099e7208c.tar.gz
servo-01a7de50ab1843d85295f9dccad7f4c099e7208c.zip
Merge remote-tracking branch 'upstream/master' into feat-cow-infra
`tests/wpt/web-platform-tests/html/browsers/origin/cross-origin-objects/cross-origin-objects.html` was reverted to the upstream version.
Diffstat (limited to 'components/script/dom/workerglobalscope.rs')
-rw-r--r--components/script/dom/workerglobalscope.rs528
1 files changed, 324 insertions, 204 deletions
diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs
index fd1f03db1e3..6092b3c4c3e 100644
--- a/components/script/dom/workerglobalscope.rs
+++ b/components/script/dom/workerglobalscope.rs
@@ -1,66 +1,90 @@
/* 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/. */
+
+use crate::dom::bindings::cell::{DomRefCell, Ref};
+use crate::dom::bindings::codegen::Bindings::ImageBitmapBinding::{
+ ImageBitmapOptions, ImageBitmapSource,
+};
+use crate::dom::bindings::codegen::Bindings::RequestBinding::RequestInit;
+use crate::dom::bindings::codegen::Bindings::VoidFunctionBinding::VoidFunction;
+use crate::dom::bindings::codegen::Bindings::WorkerBinding::WorkerType;
+use crate::dom::bindings::codegen::Bindings::WorkerGlobalScopeBinding::WorkerGlobalScopeMethods;
+use crate::dom::bindings::codegen::UnionTypes::{RequestOrUSVString, StringOrFunction};
+use crate::dom::bindings::error::{report_pending_exception, Error, ErrorResult, Fallible};
+use crate::dom::bindings::inheritance::Castable;
+use crate::dom::bindings::reflector::DomObject;
+use crate::dom::bindings::root::{DomRoot, MutNullableDom};
+use crate::dom::bindings::settings_stack::AutoEntryScript;
+use crate::dom::bindings::str::{DOMString, USVString};
+use crate::dom::bindings::trace::RootedTraceableBox;
+use crate::dom::crypto::Crypto;
+use crate::dom::dedicatedworkerglobalscope::DedicatedWorkerGlobalScope;
+use crate::dom::globalscope::GlobalScope;
+use crate::dom::identityhub::Identities;
+use crate::dom::performance::Performance;
+use crate::dom::promise::Promise;
+use crate::dom::serviceworkerglobalscope::ServiceWorkerGlobalScope;
+use crate::dom::window::{base64_atob, base64_btoa};
+use crate::dom::workerlocation::WorkerLocation;
+use crate::dom::workernavigator::WorkerNavigator;
+use crate::fetch;
+use crate::realms::{enter_realm, InRealm};
+use crate::script_runtime::JSContext;
+use crate::script_runtime::{get_reports, CommonScriptMsg, Runtime, ScriptChan, ScriptPort};
+use crate::task::TaskCanceller;
+use crate::task_source::dom_manipulation::DOMManipulationTaskSource;
+use crate::task_source::file_reading::FileReadingTaskSource;
+use crate::task_source::networking::NetworkingTaskSource;
+use crate::task_source::performance_timeline::PerformanceTimelineTaskSource;
+use crate::task_source::port_message::PortMessageQueue;
+use crate::task_source::remote_event::RemoteEventTaskSource;
+use crate::task_source::timer::TimerTaskSource;
+use crate::task_source::websocket::WebsocketTaskSource;
+use crate::timers::{IsInterval, TimerCallback};
+use crossbeam_channel::Receiver;
use devtools_traits::{DevtoolScriptControlMsg, WorkerId};
-use dom::bindings::codegen::Bindings::EventHandlerBinding::OnErrorEventHandlerNonNull;
-use dom::bindings::codegen::Bindings::FunctionBinding::Function;
-use dom::bindings::codegen::Bindings::RequestBinding::RequestInit;
-use dom::bindings::codegen::Bindings::WorkerGlobalScopeBinding::WorkerGlobalScopeMethods;
-use dom::bindings::codegen::UnionTypes::RequestOrUSVString;
-use dom::bindings::error::{Error, ErrorResult, Fallible, report_pending_exception};
-use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{MutNullableJS, Root};
-use dom::bindings::reflector::DomObject;
-use dom::bindings::settings_stack::AutoEntryScript;
-use dom::bindings::str::DOMString;
-use dom::bindings::trace::RootedTraceableBox;
-use dom::crypto::Crypto;
-use dom::dedicatedworkerglobalscope::DedicatedWorkerGlobalScope;
-use dom::globalscope::GlobalScope;
-use dom::promise::Promise;
-use dom::serviceworkerglobalscope::ServiceWorkerGlobalScope;
-use dom::window::{base64_atob, base64_btoa};
-use dom::workerlocation::WorkerLocation;
-use dom::workernavigator::WorkerNavigator;
use dom_struct::dom_struct;
-use fetch;
use ipc_channel::ipc::IpcSender;
-use js::jsapi::{HandleValue, JSAutoCompartment, JSContext, JSRuntime};
use js::jsval::UndefinedValue;
use js::panic::maybe_resume_unwind;
-use js::rust::Runtime;
-use microtask::{MicrotaskQueue, Microtask};
-use net_traits::{IpcSend, load_whole_resource};
-use net_traits::request::{CredentialsMode, Destination, RequestInit as NetRequestInit, Type as RequestType};
-use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort};
-use script_thread::RunnableWrapper;
-use script_traits::{TimerEvent, TimerEventId};
+use js::rust::{HandleValue, ParentRuntime};
+use msg::constellation_msg::{PipelineId, PipelineNamespace};
+use net_traits::request::{
+ CredentialsMode, Destination, ParserMetadata, RequestBuilder as NetRequestInit,
+};
+use net_traits::IpcSend;
+use parking_lot::Mutex;
use script_traits::WorkerGlobalScopeInit;
use servo_url::{MutableOrigin, ServoUrl};
use std::default::Default;
use std::rc::Rc;
-use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
-use std::sync::mpsc::Receiver;
-use task_source::file_reading::FileReadingTaskSource;
-use task_source::networking::NetworkingTaskSource;
-use timers::{IsInterval, TimerCallback};
-
-pub fn prepare_workerscope_init(global: &GlobalScope,
- devtools_sender: Option<IpcSender<DevtoolScriptControlMsg>>) -> WorkerGlobalScopeInit {
+use std::sync::Arc;
+use time::precise_time_ns;
+use uuid::Uuid;
+
+pub fn prepare_workerscope_init(
+ global: &GlobalScope,
+ devtools_sender: Option<IpcSender<DevtoolScriptControlMsg>>,
+ worker_id: Option<WorkerId>,
+) -> WorkerGlobalScopeInit {
let init = WorkerGlobalScopeInit {
- resource_threads: global.resource_threads().clone(),
- mem_profiler_chan: global.mem_profiler_chan().clone(),
- to_devtools_sender: global.devtools_chan().cloned(),
- time_profiler_chan: global.time_profiler_chan().clone(),
- from_devtools_sender: devtools_sender,
- constellation_chan: global.constellation_chan().clone(),
- scheduler_chan: global.scheduler_chan().clone(),
- worker_id: global.get_next_worker_id(),
- pipeline_id: global.pipeline_id(),
- origin: global.origin().immutable().clone(),
- };
+ resource_threads: global.resource_threads().clone(),
+ mem_profiler_chan: global.mem_profiler_chan().clone(),
+ to_devtools_sender: global.devtools_chan().cloned(),
+ time_profiler_chan: global.time_profiler_chan().clone(),
+ from_devtools_sender: devtools_sender,
+ script_to_constellation_chan: global.script_to_constellation_chan().clone(),
+ scheduler_chan: global.scheduler_chan().clone(),
+ worker_id: worker_id.unwrap_or_else(|| WorkerId(Uuid::new_v4())),
+ pipeline_id: global.pipeline_id(),
+ origin: global.origin().immutable().clone(),
+ creation_url: global.creation_url().clone(),
+ is_headless: global.is_headless(),
+ user_agent: global.get_user_agent(),
+ inherited_secure_context: Some(global.is_secure_context()),
+ };
init
}
@@ -70,60 +94,95 @@ pub fn prepare_workerscope_init(global: &GlobalScope,
pub struct WorkerGlobalScope {
globalscope: GlobalScope,
+ worker_name: DOMString,
+ worker_type: WorkerType,
+
worker_id: WorkerId,
- worker_url: ServoUrl,
- #[ignore_heap_size_of = "Arc"]
- closing: Option<Arc<AtomicBool>>,
- #[ignore_heap_size_of = "Defined in js"]
- runtime: Runtime,
- location: MutNullableJS<WorkerLocation>,
- navigator: MutNullableJS<WorkerNavigator>,
-
- #[ignore_heap_size_of = "Defined in ipc-channel"]
+ worker_url: DomRefCell<ServoUrl>,
+ #[ignore_malloc_size_of = "Arc"]
+ closing: Arc<AtomicBool>,
+ #[ignore_malloc_size_of = "Defined in js"]
+ runtime: DomRefCell<Option<Runtime>>,
+ location: MutNullableDom<WorkerLocation>,
+ navigator: MutNullableDom<WorkerNavigator>,
+
+ #[ignore_malloc_size_of = "Defined in ipc-channel"]
/// Optional `IpcSender` for sending the `DevtoolScriptControlMsg`
/// to the server from within the worker
from_devtools_sender: Option<IpcSender<DevtoolScriptControlMsg>>,
- #[ignore_heap_size_of = "Defined in std"]
+ #[ignore_malloc_size_of = "Defined in std"]
/// This `Receiver` will be ignored later if the corresponding
/// `IpcSender` doesn't exist
from_devtools_receiver: Receiver<DevtoolScriptControlMsg>,
- microtask_queue: MicrotaskQueue,
+ navigation_start_precise: u64,
+ performance: MutNullableDom<Performance>,
}
impl WorkerGlobalScope {
- pub fn new_inherited(init: WorkerGlobalScopeInit,
- worker_url: ServoUrl,
- runtime: Runtime,
- from_devtools_receiver: Receiver<DevtoolScriptControlMsg>,
- timer_event_chan: IpcSender<TimerEvent>,
- closing: Option<Arc<AtomicBool>>)
- -> WorkerGlobalScope {
- WorkerGlobalScope {
- globalscope:
- GlobalScope::new_inherited(
- init.pipeline_id,
- init.to_devtools_sender,
- init.mem_profiler_chan,
- init.time_profiler_chan,
- init.constellation_chan,
- init.scheduler_chan,
- init.resource_threads,
- timer_event_chan,
- MutableOrigin::new(init.origin)),
+ pub fn new_inherited(
+ init: WorkerGlobalScopeInit,
+ worker_name: DOMString,
+ worker_type: WorkerType,
+ worker_url: ServoUrl,
+ runtime: Runtime,
+ from_devtools_receiver: Receiver<DevtoolScriptControlMsg>,
+ closing: Arc<AtomicBool>,
+ gpu_id_hub: Arc<Mutex<Identities>>,
+ ) -> Self {
+ // Install a pipeline-namespace in the current thread.
+ PipelineNamespace::auto_install();
+ Self {
+ globalscope: GlobalScope::new_inherited(
+ init.pipeline_id,
+ init.to_devtools_sender,
+ init.mem_profiler_chan,
+ init.time_profiler_chan,
+ init.script_to_constellation_chan,
+ init.scheduler_chan,
+ init.resource_threads,
+ MutableOrigin::new(init.origin),
+ init.creation_url,
+ runtime.microtask_queue.clone(),
+ init.is_headless,
+ init.user_agent,
+ gpu_id_hub,
+ init.inherited_secure_context,
+ ),
worker_id: init.worker_id,
- worker_url: worker_url,
- closing: closing,
- runtime: runtime,
+ worker_name,
+ worker_type,
+ worker_url: DomRefCell::new(worker_url),
+ closing,
+ runtime: DomRefCell::new(Some(runtime)),
location: Default::default(),
navigator: Default::default(),
from_devtools_sender: init.from_devtools_sender,
- from_devtools_receiver: from_devtools_receiver,
- microtask_queue: MicrotaskQueue::default(),
+ from_devtools_receiver,
+ navigation_start_precise: precise_time_ns(),
+ performance: Default::default(),
}
}
+ /// Clear various items when the worker event-loop shuts-down.
+ pub fn clear_js_runtime(&self) {
+ self.upcast::<GlobalScope>()
+ .remove_web_messaging_and_dedicated_workers_infra();
+
+ // Drop the runtime.
+ let runtime = self.runtime.borrow_mut().take();
+ drop(runtime);
+ }
+
+ pub fn runtime_handle(&self) -> ParentRuntime {
+ self.runtime
+ .borrow()
+ .as_ref()
+ .unwrap()
+ .prepare_for_new_child()
+ }
+
pub fn from_devtools_sender(&self) -> Option<IpcSender<DevtoolScriptControlMsg>> {
self.from_devtools_sender.clone()
}
@@ -132,60 +191,48 @@ impl WorkerGlobalScope {
&self.from_devtools_receiver
}
- pub fn runtime(&self) -> *mut JSRuntime {
- self.runtime.rt()
+ #[allow(unsafe_code)]
+ pub fn get_cx(&self) -> JSContext {
+ unsafe { JSContext::from_ptr(self.runtime.borrow().as_ref().unwrap().cx()) }
}
- pub fn get_cx(&self) -> *mut JSContext {
- self.runtime.cx()
+ pub fn is_closing(&self) -> bool {
+ self.closing.load(Ordering::SeqCst)
}
- pub fn is_closing(&self) -> bool {
- if let Some(ref closing) = self.closing {
- closing.load(Ordering::SeqCst)
- } else {
- false
- }
+ pub fn get_url(&self) -> Ref<ServoUrl> {
+ self.worker_url.borrow()
}
- pub fn get_url(&self) -> &ServoUrl {
- &self.worker_url
+ pub fn set_url(&self, url: ServoUrl) {
+ *self.worker_url.borrow_mut() = url;
}
pub fn get_worker_id(&self) -> WorkerId {
self.worker_id.clone()
}
- pub fn get_runnable_wrapper(&self) -> RunnableWrapper {
- RunnableWrapper {
+ pub fn task_canceller(&self) -> TaskCanceller {
+ TaskCanceller {
cancelled: self.closing.clone(),
}
}
- pub fn enqueue_microtask(&self, job: Microtask) {
- self.microtask_queue.enqueue(job);
- }
-
- pub fn perform_a_microtask_checkpoint(&self) {
- self.microtask_queue.checkpoint(|id| {
- let global = self.upcast::<GlobalScope>();
- assert_eq!(global.pipeline_id(), id);
- Some(Root::from_ref(global))
- });
+ pub fn pipeline_id(&self) -> PipelineId {
+ self.globalscope.pipeline_id()
}
}
impl WorkerGlobalScopeMethods for WorkerGlobalScope {
// https://html.spec.whatwg.org/multipage/#dom-workerglobalscope-self
- fn Self_(&self) -> Root<WorkerGlobalScope> {
- Root::from_ref(self)
+ fn Self_(&self) -> DomRoot<WorkerGlobalScope> {
+ DomRoot::from_ref(self)
}
// https://html.spec.whatwg.org/multipage/#dom-workerglobalscope-location
- fn Location(&self) -> Root<WorkerLocation> {
- self.location.or_init(|| {
- WorkerLocation::new(self, self.worker_url.clone())
- })
+ fn Location(&self) -> DomRoot<WorkerLocation> {
+ self.location
+ .or_init(|| WorkerLocation::new(self, self.worker_url.borrow().clone()))
}
// https://html.spec.whatwg.org/multipage/#handler-workerglobalscope-onerror
@@ -195,38 +242,41 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope {
fn ImportScripts(&self, url_strings: Vec<DOMString>) -> ErrorResult {
let mut urls = Vec::with_capacity(url_strings.len());
for url in url_strings {
- let url = self.worker_url.join(&url);
+ let url = self.worker_url.borrow().join(&url);
match url {
Ok(url) => urls.push(url),
Err(_) => return Err(Error::Syntax),
};
}
- rooted!(in(self.runtime.cx()) let mut rval = UndefinedValue());
+ rooted!(in(self.runtime.borrow().as_ref().unwrap().cx()) let mut rval = UndefinedValue());
for url in urls {
let global_scope = self.upcast::<GlobalScope>();
- let request = NetRequestInit {
- url: url.clone(),
- type_: RequestType::Script,
- destination: Destination::Script,
- credentials_mode: CredentialsMode::Include,
- use_url_credentials: true,
- origin: self.worker_url.clone(),
- pipeline_id: Some(self.upcast::<GlobalScope>().pipeline_id()),
- referrer_url: None,
- referrer_policy: None,
- .. NetRequestInit::default()
- };
- let (url, source) = match load_whole_resource(request,
- &global_scope.resource_threads().sender()) {
+ let request = NetRequestInit::new(url.clone(), global_scope.get_referrer())
+ .destination(Destination::Script)
+ .credentials_mode(CredentialsMode::Include)
+ .parser_metadata(ParserMetadata::NotParserInserted)
+ .use_url_credentials(true)
+ .origin(global_scope.origin().immutable().clone())
+ .pipeline_id(Some(self.upcast::<GlobalScope>().pipeline_id()))
+ .referrer_policy(None);
+
+ let (url, source) = match fetch::load_whole_resource(
+ request,
+ &global_scope.resource_threads().sender(),
+ &global_scope,
+ ) {
Err(_) => return Err(Error::Network),
- Ok((metadata, bytes)) => {
- (metadata.final_url, String::from_utf8(bytes).unwrap())
- }
+ Ok((metadata, bytes)) => (metadata.final_url, String::from_utf8(bytes).unwrap()),
};
- let result = self.runtime.evaluate_script(
- self.reflector().get_jsobject(), &source, url.as_str(), 1, rval.handle_mut());
+ let result = self.runtime.borrow().as_ref().unwrap().evaluate_script(
+ self.reflector().get_jsobject(),
+ &source,
+ url.as_str(),
+ 1,
+ rval.handle_mut(),
+ );
maybe_resume_unwind();
@@ -235,7 +285,7 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope {
Err(_) => {
println!("evaluate_script failed");
return Err(Error::JSFailed);
- }
+ },
}
}
@@ -243,12 +293,12 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope {
}
// https://html.spec.whatwg.org/multipage/#dom-worker-navigator
- fn Navigator(&self) -> Root<WorkerNavigator> {
+ fn Navigator(&self) -> DomRoot<WorkerNavigator> {
self.navigator.or_init(|| WorkerNavigator::new(self))
}
// https://html.spec.whatwg.org/multipage/#dfn-Crypto
- fn Crypto(&self) -> Root<Crypto> {
+ fn Crypto(&self) -> DomRoot<Crypto> {
self.upcast::<GlobalScope>().crypto()
}
@@ -262,53 +312,50 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope {
base64_atob(atob)
}
- #[allow(unsafe_code)]
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-settimeout
- unsafe fn SetTimeout(&self, _cx: *mut JSContext, callback: Rc<Function>,
- timeout: i32, args: Vec<HandleValue>) -> i32 {
- self.upcast::<GlobalScope>().set_timeout_or_interval(
- TimerCallback::FunctionTimerCallback(callback),
- args,
- timeout,
- IsInterval::NonInterval)
- }
-
- #[allow(unsafe_code)]
- // https://html.spec.whatwg.org/multipage/#dom-windowtimers-settimeout
- unsafe fn SetTimeout_(&self, _cx: *mut JSContext, callback: DOMString,
- timeout: i32, args: Vec<HandleValue>) -> i32 {
+ fn SetTimeout(
+ &self,
+ _cx: JSContext,
+ callback: StringOrFunction,
+ timeout: i32,
+ args: Vec<HandleValue>,
+ ) -> i32 {
+ let callback = match callback {
+ StringOrFunction::String(i) => TimerCallback::StringTimerCallback(i),
+ StringOrFunction::Function(i) => TimerCallback::FunctionTimerCallback(i),
+ };
self.upcast::<GlobalScope>().set_timeout_or_interval(
- TimerCallback::StringTimerCallback(callback),
+ callback,
args,
timeout,
- IsInterval::NonInterval)
+ IsInterval::NonInterval,
+ )
}
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-cleartimeout
fn ClearTimeout(&self, handle: i32) {
- self.upcast::<GlobalScope>().clear_timeout_or_interval(handle);
+ self.upcast::<GlobalScope>()
+ .clear_timeout_or_interval(handle);
}
- #[allow(unsafe_code)]
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-setinterval
- unsafe fn SetInterval(&self, _cx: *mut JSContext, callback: Rc<Function>,
- timeout: i32, args: Vec<HandleValue>) -> i32 {
- self.upcast::<GlobalScope>().set_timeout_or_interval(
- TimerCallback::FunctionTimerCallback(callback),
- args,
- timeout,
- IsInterval::Interval)
- }
-
- #[allow(unsafe_code)]
- // https://html.spec.whatwg.org/multipage/#dom-windowtimers-setinterval
- unsafe fn SetInterval_(&self, _cx: *mut JSContext, callback: DOMString,
- timeout: i32, args: Vec<HandleValue>) -> i32 {
+ fn SetInterval(
+ &self,
+ _cx: JSContext,
+ callback: StringOrFunction,
+ timeout: i32,
+ args: Vec<HandleValue>,
+ ) -> i32 {
+ let callback = match callback {
+ StringOrFunction::String(i) => TimerCallback::StringTimerCallback(i),
+ StringOrFunction::Function(i) => TimerCallback::FunctionTimerCallback(i),
+ };
self.upcast::<GlobalScope>().set_timeout_or_interval(
- TimerCallback::StringTimerCallback(callback),
+ callback,
args,
timeout,
- IsInterval::Interval)
+ IsInterval::Interval,
+ )
}
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-clearinterval
@@ -316,21 +363,72 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope {
self.ClearTimeout(handle);
}
+ // https://html.spec.whatwg.org/multipage/#dom-queuemicrotask
+ fn QueueMicrotask(&self, callback: Rc<VoidFunction>) {
+ self.upcast::<GlobalScope>()
+ .queue_function_as_microtask(callback);
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-createimagebitmap
+ fn CreateImageBitmap(
+ &self,
+ image: ImageBitmapSource,
+ options: &ImageBitmapOptions,
+ ) -> Rc<Promise> {
+ let p = self
+ .upcast::<GlobalScope>()
+ .create_image_bitmap(image, options);
+ p
+ }
+
#[allow(unrooted_must_root)]
// https://fetch.spec.whatwg.org/#fetch-method
- fn Fetch(&self, input: RequestOrUSVString, init: RootedTraceableBox<RequestInit>) -> Rc<Promise> {
- fetch::Fetch(self.upcast(), input, init)
+ fn Fetch(
+ &self,
+ input: RequestOrUSVString,
+ init: RootedTraceableBox<RequestInit>,
+ comp: InRealm,
+ ) -> Rc<Promise> {
+ fetch::Fetch(self.upcast(), input, init, comp)
+ }
+
+ // https://w3c.github.io/hr-time/#the-performance-attribute
+ fn Performance(&self) -> DomRoot<Performance> {
+ self.performance.or_init(|| {
+ let global_scope = self.upcast::<GlobalScope>();
+ Performance::new(global_scope, self.navigation_start_precise)
+ })
}
-}
+ // https://html.spec.whatwg.org/multipage/#dom-origin
+ fn Origin(&self) -> USVString {
+ USVString(
+ self.upcast::<GlobalScope>()
+ .origin()
+ .immutable()
+ .ascii_serialization(),
+ )
+ }
+
+ // https://w3c.github.io/webappsec-secure-contexts/#dom-windoworworkerglobalscope-issecurecontext
+ fn IsSecureContext(&self) -> bool {
+ self.upcast::<GlobalScope>().is_secure_context()
+ }
+}
impl WorkerGlobalScope {
#[allow(unsafe_code)]
pub fn execute_script(&self, source: DOMString) {
let _aes = AutoEntryScript::new(self.upcast());
- rooted!(in(self.runtime.cx()) let mut rval = UndefinedValue());
- match self.runtime.evaluate_script(
- self.reflector().get_jsobject(), &source, self.worker_url.as_str(), 1, rval.handle_mut()) {
+ let cx = self.runtime.borrow().as_ref().unwrap().cx();
+ rooted!(in(cx) let mut rval = UndefinedValue());
+ match self.runtime.borrow().as_ref().unwrap().evaluate_script(
+ self.reflector().get_jsobject(),
+ &source,
+ self.worker_url.borrow().as_str(),
+ 1,
+ rval.handle_mut(),
+ ) {
Ok(_) => (),
Err(_) => {
if self.is_closing() {
@@ -340,16 +438,15 @@ impl WorkerGlobalScope {
// https://github.com/servo/servo/issues/6422
println!("evaluate_script failed");
unsafe {
- let _ac = JSAutoCompartment::new(self.runtime.cx(),
- self.reflector().get_jsobject().get());
- report_pending_exception(self.runtime.cx(), true);
+ let ar = enter_realm(&*self);
+ report_pending_exception(cx, true, InRealm::Entered(&ar));
}
}
- }
+ },
}
}
- pub fn script_chan(&self) -> Box<ScriptChan + Send> {
+ pub fn script_chan(&self) -> Box<dyn ScriptChan + Send> {
let dedicated = self.downcast::<DedicatedWorkerGlobalScope>();
let service_worker = self.downcast::<ServiceWorkerGlobalScope>();
if let Some(dedicated) = dedicated {
@@ -361,15 +458,39 @@ impl WorkerGlobalScope {
}
}
+ pub fn dom_manipulation_task_source(&self) -> DOMManipulationTaskSource {
+ DOMManipulationTaskSource(self.script_chan(), self.pipeline_id())
+ }
+
pub fn file_reading_task_source(&self) -> FileReadingTaskSource {
- FileReadingTaskSource(self.script_chan())
+ FileReadingTaskSource(self.script_chan(), self.pipeline_id())
}
pub fn networking_task_source(&self) -> NetworkingTaskSource {
- NetworkingTaskSource(self.script_chan())
+ NetworkingTaskSource(self.script_chan(), self.pipeline_id())
+ }
+
+ pub fn performance_timeline_task_source(&self) -> PerformanceTimelineTaskSource {
+ PerformanceTimelineTaskSource(self.script_chan(), self.pipeline_id())
}
- pub fn new_script_pair(&self) -> (Box<ScriptChan + Send>, Box<ScriptPort + Send>) {
+ pub fn port_message_queue(&self) -> PortMessageQueue {
+ PortMessageQueue(self.script_chan(), self.pipeline_id())
+ }
+
+ pub fn timer_task_source(&self) -> TimerTaskSource {
+ TimerTaskSource(self.script_chan(), self.pipeline_id())
+ }
+
+ pub fn remote_event_task_source(&self) -> RemoteEventTaskSource {
+ RemoteEventTaskSource(self.script_chan(), self.pipeline_id())
+ }
+
+ pub fn websocket_task_source(&self) -> WebsocketTaskSource {
+ WebsocketTaskSource(self.script_chan(), self.pipeline_id())
+ }
+
+ pub fn new_script_pair(&self) -> (Box<dyn ScriptChan + Send>, Box<dyn ScriptPort + Send>) {
let dedicated = self.downcast::<DedicatedWorkerGlobalScope>();
if let Some(dedicated) = dedicated {
return dedicated.new_script_pair();
@@ -378,27 +499,26 @@ impl WorkerGlobalScope {
}
}
- pub fn process_event(&self, msg: CommonScriptMsg) {
- let dedicated = self.downcast::<DedicatedWorkerGlobalScope>();
- let service_worker = self.downcast::<ServiceWorkerGlobalScope>();
- if let Some(dedicated) = dedicated {
- return dedicated.process_event(msg);
- } else if let Some(service_worker) = service_worker {
- return service_worker.process_event(msg);
- } else {
- panic!("need to implement a sender for SharedWorker")
+ /// Process a single event as if it were the next event
+ /// in the queue for this worker event-loop.
+ /// Returns a boolean indicating whether further events should be processed.
+ pub fn process_event(&self, msg: CommonScriptMsg) -> bool {
+ if self.is_closing() {
+ return false;
}
-
- //XXXjdm should we do a microtask checkpoint here?
- }
-
- pub fn handle_fire_timer(&self, timer_id: TimerEventId) {
- self.upcast::<GlobalScope>().fire_timer(timer_id);
+ match msg {
+ CommonScriptMsg::Task(_, task, _, _) => task.run_box(),
+ CommonScriptMsg::CollectReports(reports_chan) => {
+ let cx = self.get_cx();
+ let path_seg = format!("url({})", self.get_url());
+ let reports = get_reports(*cx, path_seg);
+ reports_chan.send(reports);
+ },
+ }
+ true
}
pub fn close(&self) {
- if let Some(ref closing) = self.closing {
- closing.store(true, Ordering::SeqCst);
- }
+ self.closing.store(true, Ordering::SeqCst);
}
}