aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Matthews <josh@joshmatthews.net>2017-01-12 12:53:53 -0500
committerJosh Matthews <josh@joshmatthews.net>2017-02-01 12:54:33 -0500
commitb5d2bd757b45aa7f1e61c947d883eb977c6ad7af (patch)
treea43aaa5c69190004106f8fb49a29a06326cc77d4
parent32d4f84a30035b6b1094f7e68adbe1e6a883bb9b (diff)
downloadservo-b5d2bd757b45aa7f1e61c947d883eb977c6ad7af.tar.gz
servo-b5d2bd757b45aa7f1e61c947d883eb977c6ad7af.zip
Perform a microtask checkpoint after executing classic scripts and callbacks.
-rw-r--r--components/script/dom/bindings/settings_stack.rs16
-rw-r--r--components/script/dom/globalscope.rs11
-rw-r--r--components/script/dom/htmlscriptelement.rs24
-rw-r--r--components/script/script_thread.rs7
-rw-r--r--tests/wpt/metadata/html/webappapis/scripting/event-loops/microtask_after_raf.html.ini6
-rw-r--r--tests/wpt/metadata/html/webappapis/scripting/event-loops/microtask_after_script.html.ini5
-rw-r--r--tests/wpt/metadata/html/webappapis/scripting/event-loops/task_microtask_ordering.html.ini5
7 files changed, 49 insertions, 25 deletions
diff --git a/components/script/dom/bindings/settings_stack.rs b/components/script/dom/bindings/settings_stack.rs
index 10afc833cb4..dec63924915 100644
--- a/components/script/dom/bindings/settings_stack.rs
+++ b/components/script/dom/bindings/settings_stack.rs
@@ -11,6 +11,7 @@ use js::jsapi::JSTracer;
use js::jsapi::UnhideScriptedCaller;
use js::rust::Runtime;
use std::cell::RefCell;
+use std::thread;
thread_local!(static STACK: RefCell<Vec<StackEntry>> = RefCell::new(Vec::new()));
@@ -36,7 +37,7 @@ pub unsafe fn trace(tracer: *mut JSTracer) {
/// RAII struct that pushes and pops entries from the script settings stack.
pub struct AutoEntryScript {
- global: usize,
+ global: Root<GlobalScope>,
}
impl AutoEntryScript {
@@ -50,7 +51,7 @@ impl AutoEntryScript {
kind: StackEntryKind::Entry,
});
AutoEntryScript {
- global: global as *const _ as usize,
+ global: Root::from_ref(global),
}
})
}
@@ -62,12 +63,17 @@ impl Drop for AutoEntryScript {
STACK.with(|stack| {
let mut stack = stack.borrow_mut();
let entry = stack.pop().unwrap();
- assert_eq!(&*entry.global as *const GlobalScope as usize,
- self.global,
+ assert_eq!(&*entry.global as *const GlobalScope,
+ &*self.global as *const GlobalScope,
"Dropped AutoEntryScript out of order.");
assert_eq!(entry.kind, StackEntryKind::Entry);
trace!("Clean up after running script with {:p}", &*entry.global);
- })
+ });
+
+ // Step 5
+ if !thread::panicking() && incumbent_global().is_none() {
+ self.global.perform_a_microtask_checkpoint();
+ }
}
}
diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs
index aaebf091c6d..cc42ef18d06 100644
--- a/components/script/dom/globalscope.rs
+++ b/components/script/dom/globalscope.rs
@@ -449,6 +449,17 @@ impl GlobalScope {
unreachable!();
}
+ /// Perform a microtask checkpoint.
+ pub fn perform_a_microtask_checkpoint(&self) {
+ if self.is::<Window>() {
+ return ScriptThread::invoke_perform_a_microtask_checkpoint();
+ }
+ if let Some(worker) = self.downcast::<WorkerGlobalScope>() {
+ return worker.perform_a_microtask_checkpoint();
+ }
+ unreachable!();
+ }
+
/// Enqueue a microtask for subsequent execution.
pub fn enqueue_microtask(&self, job: Microtask) {
if self.is::<Window>() {
diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs
index e1e8dabac7b..8703a45ea82 100644
--- a/components/script/dom/htmlscriptelement.rs
+++ b/components/script/dom/htmlscriptelement.rs
@@ -486,11 +486,7 @@ impl HTMLScriptElement {
document.set_current_script(Some(self));
// Step 5.a.2.
- let window = window_from_node(self);
- let line_number = if script.external { 1 } else { self.line_number as u32 };
- rooted!(in(window.get_cx()) let mut rval = UndefinedValue());
- window.upcast::<GlobalScope>().evaluate_script_on_global_with_result(
- &script.text, script.url.as_str(), rval.handle_mut(), line_number);
+ self.run_a_classic_script(&script);
// Step 6.
document.set_current_script(old_script.r());
@@ -506,6 +502,24 @@ impl HTMLScriptElement {
}
}
+ // https://html.spec.whatwg.org/multipage/#run-a-classic-script
+ pub fn run_a_classic_script(&self, script: &ClassicScript) {
+ // TODO use a settings object rather than this element's document/window
+ // Step 2
+ let document = document_from_node(self);
+ if !document.is_fully_active() || !document.is_scripting_enabled() {
+ return;
+ }
+
+ // Steps 4-10
+ let window = window_from_node(self);
+ let line_number = if script.external { 1 } else { self.line_number as u32 };
+ rooted!(in(window.get_cx()) let mut rval = UndefinedValue());
+ let global = window.upcast::<GlobalScope>();
+ global.evaluate_script_on_global_with_result(
+ &script.text, script.url.as_str(), rval.handle_mut(), line_number);
+ }
+
pub fn queue_error_event(&self) {
let window = window_from_node(self);
window.dom_manipulation_task_source().queue_simple_event(self.upcast(), atom!("error"), &window);
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index d204ab776b8..f54ff2ca097 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -567,6 +567,13 @@ impl ScriptThreadFactory for ScriptThread {
}
impl ScriptThread {
+ pub fn invoke_perform_a_microtask_checkpoint() {
+ SCRIPT_THREAD_ROOT.with(|root| {
+ let script_thread = unsafe { &*root.get().unwrap() };
+ script_thread.perform_a_microtask_checkpoint()
+ })
+ }
+
pub fn page_headers_available(id: &PipelineId, metadata: Option<Metadata>)
-> Option<Root<ServoParser>> {
SCRIPT_THREAD_ROOT.with(|root| {
diff --git a/tests/wpt/metadata/html/webappapis/scripting/event-loops/microtask_after_raf.html.ini b/tests/wpt/metadata/html/webappapis/scripting/event-loops/microtask_after_raf.html.ini
deleted file mode 100644
index 9ebe79a9879..00000000000
--- a/tests/wpt/metadata/html/webappapis/scripting/event-loops/microtask_after_raf.html.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-[microtask_after_raf.html]
- type: testharness
- disabled: https://github.com/servo/servo/issues/13501
- [Microtask execute immediately after script]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/html/webappapis/scripting/event-loops/microtask_after_script.html.ini b/tests/wpt/metadata/html/webappapis/scripting/event-loops/microtask_after_script.html.ini
deleted file mode 100644
index 49871c85772..00000000000
--- a/tests/wpt/metadata/html/webappapis/scripting/event-loops/microtask_after_script.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[microtask_after_script.html]
- type: testharness
- [Microtask immediately after script]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/html/webappapis/scripting/event-loops/task_microtask_ordering.html.ini b/tests/wpt/metadata/html/webappapis/scripting/event-loops/task_microtask_ordering.html.ini
index 8d063ebb67f..a9a640fee27 100644
--- a/tests/wpt/metadata/html/webappapis/scripting/event-loops/task_microtask_ordering.html.ini
+++ b/tests/wpt/metadata/html/webappapis/scripting/event-loops/task_microtask_ordering.html.ini
@@ -1,8 +1,5 @@
[task_microtask_ordering.html]
type: testharness
- [Basic task and microtask ordering]
- expected: FAIL
-
[Level 1 bossfight (synthetic click)]
expected: FAIL
-
+ bug: https://github.com/servo/servo/issues/1980