Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement queueMicrotask #25510

Merged
merged 1 commit into from Jan 14, 2020
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

queueMicrotask added

  • Loading branch information
pshaughn committed Jan 13, 2020
commit b01b2d3d2e816f90af883e003a53db8bd3536a48
@@ -4,6 +4,7 @@

use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::EventSourceBinding::EventSourceBinding::EventSourceMethods;
use crate::dom::bindings::codegen::Bindings::VoidFunctionBinding::VoidFunction;
use crate::dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use crate::dom::bindings::codegen::Bindings::WorkerGlobalScopeBinding::WorkerGlobalScopeMethods;
use crate::dom::bindings::conversions::{root_from_object, root_from_object_static};
@@ -32,7 +33,7 @@ use crate::dom::performance::Performance;
use crate::dom::window::Window;
use crate::dom::workerglobalscope::WorkerGlobalScope;
use crate::dom::workletglobalscope::WorkletGlobalScope;
use crate::microtask::{Microtask, MicrotaskQueue};
use crate::microtask::{Microtask, MicrotaskQueue, UserMicrotask};
use crate::script_module::ModuleTree;
use crate::script_runtime::{CommonScriptMsg, JSContext as SafeJSContext, ScriptChan, ScriptPort};
use crate::script_thread::{MainThreadScriptChan, ScriptThread};
@@ -1772,6 +1773,13 @@ impl GlobalScope {
self.timers.clear_timeout_or_interval(self, handle);
}

pub fn queue_function_as_microtask(&self, callback: Rc<VoidFunction>) {
self.enqueue_microtask(Microtask::User(UserMicrotask {
callback: callback,
pipeline: self.pipeline_id(),
}))
}

pub fn fire_timer(&self, handle: TimerEventId) {
self.timers.fire_timer(handle, self);
}
@@ -20,6 +20,9 @@ interface mixin WindowOrWorkerGlobalScope {
long setInterval(TimerHandler handler, optional long timeout = 0, any... arguments);
void clearInterval(optional long handle = 0);

// microtask queuing
void queueMicrotask(VoidFunction callback);

// ImageBitmap
// Promise<ImageBitmap> createImageBitmap(ImageBitmapSource image, optional ImageBitmapOptions options);
// Promise<ImageBitmap> createImageBitmap(
@@ -11,6 +11,7 @@ use crate::dom::bindings::codegen::Bindings::HistoryBinding::HistoryBinding::His
use crate::dom::bindings::codegen::Bindings::MediaQueryListBinding::MediaQueryListBinding::MediaQueryListMethods;
use crate::dom::bindings::codegen::Bindings::PermissionStatusBinding::PermissionState;
use crate::dom::bindings::codegen::Bindings::RequestBinding::RequestInit;
use crate::dom::bindings::codegen::Bindings::VoidFunctionBinding::VoidFunction;
use crate::dom::bindings::codegen::Bindings::WindowBinding::{
self, FrameRequestCallback, WindowMethods, WindowPostMessageOptions,
};
@@ -871,6 +872,12 @@ impl WindowMethods for Window {
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-window
fn Window(&self) -> DomRoot<WindowProxy> {
self.window_proxy()
@@ -5,6 +5,7 @@
use crate::compartments::InCompartment;
use crate::dom::bindings::cell::{DomRefCell, Ref};
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};
@@ -341,6 +342,12 @@ 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);
}

#[allow(unrooted_must_root)]
// https://fetch.spec.whatwg.org/#fetch-method
fn Fetch(
@@ -9,6 +9,7 @@
use crate::dom::bindings::callback::ExceptionHandling;
use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::PromiseBinding::PromiseJobCallback;
use crate::dom::bindings::codegen::Bindings::VoidFunctionBinding::VoidFunction;
use crate::dom::bindings::root::DomRoot;
use crate::dom::globalscope::GlobalScope;
use crate::dom::htmlimageelement::ImageElementMicrotask;
@@ -34,6 +35,7 @@ pub struct MicrotaskQueue {
#[derive(JSTraceable, MallocSizeOf)]
pub enum Microtask {
Promise(EnqueuedPromiseCallback),
User(UserMicrotask),
MediaElement(MediaElementMicrotask),
ImageElement(ImageElementMicrotask),
CustomElementReaction,
@@ -52,6 +54,15 @@ pub struct EnqueuedPromiseCallback {
pub pipeline: PipelineId,
}

/// A microtask that comes from a queueMicrotask() Javascript call,
/// identical to EnqueuedPromiseCallback once it's on the queue
#[derive(JSTraceable, MallocSizeOf)]
pub struct UserMicrotask {
#[ignore_malloc_size_of = "Rc has unclear ownership"]
pub callback: Rc<VoidFunction>,
pub pipeline: PipelineId,
}

impl MicrotaskQueue {
/// Add a new microtask to this queue. It will be invoked as part of the next
/// microtask checkpoint.
@@ -95,6 +106,11 @@ impl MicrotaskQueue {
let _ = job.callback.Call_(&*target, ExceptionHandling::Report);
}
},
Microtask::User(ref job) => {
if let Some(target) = target_provider(job.pipeline) {
let _ = job.callback.Call_(&*target, ExceptionHandling::Report);
}
},
Microtask::MediaElement(ref task) => {
task.handler();
},
@@ -53,6 +53,3 @@
[Window method: createImageBitmap]
expected: FAIL

[Window method: queueMicrotask]
expected: FAIL

@@ -1501,9 +1501,6 @@
[Document interface: attribute all]
expected: FAIL

[Window interface: window must inherit property "queueMicrotask(VoidFunction)" with the proper type]
expected: FAIL

[Document interface: calling execCommand(DOMString, boolean, DOMString) on new Document() with too few arguments must throw TypeError]
expected: FAIL

@@ -1570,9 +1567,6 @@
[Window interface: window must inherit property "scrollbars" with the proper type]
expected: FAIL

[Window interface: calling queueMicrotask(VoidFunction) on window with too few arguments must throw TypeError]
expected: FAIL

[Window interface: attribute personalbar]
expected: FAIL

@@ -1711,9 +1705,6 @@
[Document interface: iframe.contentDocument must inherit property "queryCommandState(DOMString)" with the proper type]
expected: FAIL

[Window interface: operation queueMicrotask(VoidFunction)]
expected: FAIL

[Window interface: internal [[SetPrototypeOf\]\] method of interface prototype object - setting to a new value via Object.setPrototypeOf should throw a TypeError]
expected: FAIL

@@ -98,9 +98,6 @@
[OffscreenCanvasRenderingContext2D interface: attribute shadowColor]
expected: FAIL
[WorkerGlobalScope interface: self must inherit property "queueMicrotask(VoidFunction)" with the proper type]
expected: FAIL
[DedicatedWorkerGlobalScope interface: attribute name]
expected: FAIL
@@ -125,9 +122,6 @@
[OffscreenCanvasRenderingContext2D interface: operation translate(unrestricted double, unrestricted double)]
expected: FAIL

[WorkerGlobalScope interface: operation queueMicrotask(VoidFunction)]
expected: FAIL

[Path2D interface: operation moveTo(unrestricted double, unrestricted double)]
expected: FAIL

@@ -158,9 +152,6 @@
[WorkerGlobalScope interface: self must inherit property "createImageBitmap(ImageBitmapSource, ImageBitmapOptions)" with the proper type]
expected: FAIL

[WorkerGlobalScope interface: calling queueMicrotask(VoidFunction) on self with too few arguments must throw TypeError]
expected: FAIL

[DedicatedWorkerGlobalScope interface: self must inherit property "cancelAnimationFrame(unsigned long)" with the proper type]
expected: FAIL

@@ -1,8 +1,3 @@
[queue-microtask-exceptions.any.html]
[It rethrows exceptions]
expected: FAIL


[queue-microtask-exceptions.any.serviceworker.html]
expected: ERROR
[queue-microtask-exceptions]
@@ -18,9 +13,3 @@
expected: ERROR
[queue-microtask-exceptions]
expected: FAIL


[queue-microtask-exceptions.any.worker.html]
[It rethrows exceptions]
expected: FAIL

@@ -1,20 +1,3 @@
[queue-microtask.any.html]
[It exists and is a function]
expected: FAIL

[It does not pass any arguments]
expected: FAIL

[It calls the callback asynchronously]
expected: FAIL

[It throws when given non-functions]
expected: FAIL

[It interleaves with promises as expected]
expected: FAIL


[queue-microtask.any.serviceworker.html]
expected: ERROR
[queue-microtask]
@@ -31,21 +14,3 @@
expected: TIMEOUT
[queue-microtask]
expected: FAIL


[queue-microtask.any.worker.html]
[It exists and is a function]
expected: FAIL

[It does not pass any arguments]
expected: FAIL

[It calls the callback asynchronously]
expected: FAIL

[It throws when given non-functions]
expected: FAIL

[It interleaves with promises as expected]
expected: FAIL

This file was deleted.

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.