diff options
author | CYBAI <cyb.ai.815@gmail.com> | 2018-05-07 20:36:18 +0800 |
---|---|---|
committer | CYBAI <cyb.ai.815@gmail.com> | 2018-10-18 19:13:22 +0800 |
commit | 924a78c6c678e9448df9983bb370ff40910465bd (patch) | |
tree | 75cf0eaf67c0894536e2a54ce33b3469cf5931ba /components/script/dom/globalscope.rs | |
parent | 8b2892113693e6d2eddfc29dd49bbf7d54954912 (diff) | |
download | servo-924a78c6c678e9448df9983bb370ff40910465bd.tar.gz servo-924a78c6c678e9448df9983bb370ff40910465bd.zip |
Implement unhandledrejection event
Diffstat (limited to 'components/script/dom/globalscope.rs')
-rw-r--r-- | components/script/dom/globalscope.rs | 58 |
1 files changed, 57 insertions, 1 deletions
diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index 62eae2dedae..c38a5869d61 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -30,6 +30,7 @@ use ipc_channel::ipc::IpcSender; use js::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL}; use js::glue::{IsWrapper, UnwrapObject}; use js::jsapi::{CurrentGlobalOrNull, GetGlobalForObjectCrossCompartment}; +use js::jsapi::{Heap, HandleObject}; use js::jsapi::{JSAutoCompartment, JSContext}; use js::jsapi::JSObject; use js::panic::maybe_resume_unwind; @@ -135,6 +136,23 @@ pub struct GlobalScope { /// Vector storing references of all eventsources. event_source_tracker: DOMTracker<EventSource>, + + /// Storage for watching rejected promises waiting for some client to + /// consume their rejection. + /// Promises in this list have been rejected in the last turn of the + /// event loop without the rejection being handled. + /// Note that this can contain nullptrs in place of promises removed because + /// they're consumed before it'd be reported. + /// + /// <https://html.spec.whatwg.org/multipage/#about-to-be-notified-rejected-promises-list> + uncaught_rejections: DomRefCell<Vec<Box<Heap<*mut JSObject>>>>, + + /// Promises in this list have previously been reported as rejected + /// (because they were in the above list), but the rejection was handled + /// in the last turn of the event loop. + /// + /// <https://html.spec.whatwg.org/multipage/#outstanding-rejected-promises-weak-set> + consumed_rejections: DomRefCell<Vec<Box<Heap<*mut JSObject>>>>, } impl GlobalScope { @@ -169,6 +187,8 @@ impl GlobalScope { microtask_queue, list_auto_close_worker: Default::default(), event_source_tracker: DOMTracker::new(), + uncaught_rejections: Default::default(), + consumed_rejections: Default::default(), } } @@ -230,6 +250,39 @@ impl GlobalScope { GlobalScope::from_object(obj) } + pub fn add_uncaught_rejection(&self, rejection: HandleObject) { + self.uncaught_rejections.borrow_mut().push(Heap::boxed(rejection.get())); + } + + pub fn remove_uncaught_rejection(&self, rejection: HandleObject) { + let mut uncaught_rejections = self.uncaught_rejections.borrow_mut(); + + if let Some(index) = uncaught_rejections.iter().position(|promise| *promise == Heap::boxed(rejection.get())) { + uncaught_rejections.remove(index); + } + } + + pub fn get_uncaught_rejections(&self) -> &DomRefCell<Vec<Box<Heap<*mut JSObject>>>> { + &self.uncaught_rejections + } + + pub fn add_consumed_rejection(&self, rejection: HandleObject) { + self.consumed_rejections.borrow_mut().push(Heap::boxed(rejection.get())); + } + + pub fn remove_consumed_rejection(&self, rejection: HandleObject) { + let mut consumed_rejections = self.consumed_rejections.borrow_mut(); + + if let Some(index) = consumed_rejections.iter().position(|promise| *promise == Heap::boxed(rejection.get())) { + consumed_rejections.remove(index); + } + } + + pub fn get_consumed_rejections(&self) -> &DomRefCell<Vec<Box<Heap<*mut JSObject>>>> { + &self.consumed_rejections + } + + #[allow(unsafe_code)] pub fn get_cx(&self) -> *mut JSContext { Runtime::get() } @@ -586,7 +639,10 @@ impl GlobalScope { /// Perform a microtask checkpoint. pub fn perform_a_microtask_checkpoint(&self) { self.microtask_queue - .checkpoint(|_| Some(DomRoot::from_ref(self))); + .checkpoint( + |_| Some(DomRoot::from_ref(self)), + vec![DomRoot::from_ref(self)] + ); } /// Enqueue a microtask for subsequent execution. |