diff options
author | yvt <i@yvt.jp> | 2021-07-10 17:24:27 +0900 |
---|---|---|
committer | yvt <i@yvt.jp> | 2021-07-10 17:55:42 +0900 |
commit | 01a7de50ab1843d85295f9dccad7f4c099e7208c (patch) | |
tree | ee53fb6e8889deb7b880ee969e6c662e6128d210 /components/script/dom/workerglobalscope.rs | |
parent | ff8d2cdbbfc7a9dc7f38b7dd47cb350fde39388f (diff) | |
parent | 94b613fbdaa2b98f2179fc0bbda13c64e6fa0d38 (diff) | |
download | servo-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.rs | 528 |
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); } } |