aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/globalscope.rs
diff options
context:
space:
mode:
authorCYBAI <cyb.ai.815@gmail.com>2018-05-07 20:36:18 +0800
committerCYBAI <cyb.ai.815@gmail.com>2018-10-18 19:13:22 +0800
commit924a78c6c678e9448df9983bb370ff40910465bd (patch)
tree75cf0eaf67c0894536e2a54ce33b3469cf5931ba /components/script/dom/globalscope.rs
parent8b2892113693e6d2eddfc29dd49bbf7d54954912 (diff)
downloadservo-924a78c6c678e9448df9983bb370ff40910465bd.tar.gz
servo-924a78c6c678e9448df9983bb370ff40910465bd.zip
Implement unhandledrejection event
Diffstat (limited to 'components/script/dom/globalscope.rs')
-rw-r--r--components/script/dom/globalscope.rs58
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.