Implement self.queueMicrotask in Workers
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 6 Aug 2018 07:59:13 +0000 (07:59 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 6 Aug 2018 07:59:13 +0000 (07:59 +0000)
https://bugs.webkit.org/show_bug.cgi?id=188247

Reviewed by Ryosuke Niwa.

Source/WebCore:

This patch adds support for self.queueMicrotask to workers.

Tests: http/wpt/workers/queue-microtask.any.html
       http/wpt/workers/queue-microtask.any.worker.html

* bindings/js/JSWorkerGlobalScopeCustom.cpp:
(WebCore::JSWorkerGlobalScope::queueMicrotask):
* page/DOMWindow.idl:
Move queueMicrotask declaration to WindowOrWorkerGlobalScope.idl.
* page/WindowOrWorkerGlobalScope.idl:

LayoutTests:

* http/wpt/workers/queue-microtask.any-expected.txt: Added.
* http/wpt/workers/queue-microtask.any.html: Added.
* http/wpt/workers/queue-microtask.any.js: Added.
(promise_test):
(promise_test.):
(queueMicrotask.promise_test):
(test):
* http/wpt/workers/queue-microtask.any.worker-expected.txt: Added.
* http/wpt/workers/queue-microtask.any.worker.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@234588 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/http/wpt/workers/queue-microtask.any-expected.txt [new file with mode: 0644]
LayoutTests/http/wpt/workers/queue-microtask.any.html [new file with mode: 0644]
LayoutTests/http/wpt/workers/queue-microtask.any.js [new file with mode: 0644]
LayoutTests/http/wpt/workers/queue-microtask.any.worker-expected.txt [new file with mode: 0644]
LayoutTests/http/wpt/workers/queue-microtask.any.worker.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/JSWorkerGlobalScopeCustom.cpp
Source/WebCore/page/DOMWindow.idl
Source/WebCore/page/WindowOrWorkerGlobalScope.idl

index 8c01403..00532fe 100644 (file)
@@ -1,3 +1,20 @@
+2018-08-05  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Implement self.queueMicrotask in Workers
+        https://bugs.webkit.org/show_bug.cgi?id=188247
+
+        Reviewed by Ryosuke Niwa.
+
+        * http/wpt/workers/queue-microtask.any-expected.txt: Added.
+        * http/wpt/workers/queue-microtask.any.html: Added.
+        * http/wpt/workers/queue-microtask.any.js: Added.
+        (promise_test):
+        (promise_test.):
+        (queueMicrotask.promise_test):
+        (test):
+        * http/wpt/workers/queue-microtask.any.worker-expected.txt: Added.
+        * http/wpt/workers/queue-microtask.any.worker.html: Added.
+
 2018-08-05  Rob Buis  <rbuis@igalia.com>
 
         [GTK][WPE] Fetch tests assert in SubresourceLoader::didReceiveResponse()
diff --git a/LayoutTests/http/wpt/workers/queue-microtask.any-expected.txt b/LayoutTests/http/wpt/workers/queue-microtask.any-expected.txt
new file mode 100644 (file)
index 0000000..38dcdde
--- /dev/null
@@ -0,0 +1,6 @@
+
+PASS Queued microtasks should be drained before executing macrotasks 
+PASS queueMicrotask's callback has zero arguments and self as |this| 
+PASS queueMicrotask and Promise uses the same Microtask queue 
+PASS queueMicrotask should reject non-function arguments 
+
diff --git a/LayoutTests/http/wpt/workers/queue-microtask.any.html b/LayoutTests/http/wpt/workers/queue-microtask.any.html
new file mode 100644 (file)
index 0000000..2382913
--- /dev/null
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
diff --git a/LayoutTests/http/wpt/workers/queue-microtask.any.js b/LayoutTests/http/wpt/workers/queue-microtask.any.js
new file mode 100644 (file)
index 0000000..07327c0
--- /dev/null
@@ -0,0 +1,93 @@
+promise_test(() => {
+    var counter = 0;
+    self.queueMicrotask(() => {
+        assert_equals(counter++, 1);
+        self.queueMicrotask(() => {
+            assert_equals(counter++, 2);
+        });
+    });
+    var promise = new Promise((resolve, reject) => {
+        setTimeout(() => {
+            assert_equals(counter++, 3);
+            resolve();
+        }, 0);
+    });
+    assert_equals(counter++, 0);
+    return promise;
+}, `Queued microtasks should be drained before executing macrotasks`);
+
+promise_test(() => {
+    return new Promise((resolve, reject) => {
+        self.queueMicrotask(function () {
+            try {
+                assert_equals(arguments.length, 0);
+                assert_equals(this, self);
+                self.queueMicrotask(function () {
+                    try {
+                        assert_equals(this, self);
+                        self.queueMicrotask(function () {
+                            'use strict';
+                            try {
+                                assert_equals(this, undefined);
+                                resolve();
+                            } catch (e) {
+                                reject(e);
+                            }
+                        });
+                    } catch (e) {
+                        reject(e);
+                    }
+                });
+            } catch (e) {
+                reject(e);
+            }
+        });
+    });
+}, `queueMicrotask's callback has zero arguments and self as |this|`);
+
+promise_test(() => {
+    return new Promise((resolve ,reject) => {
+        var counter = 0;
+        Promise.resolve().then(() => {
+            assert_equals(counter++, 1);
+            self.queueMicrotask(() => {
+                assert_equals(counter++, 3);
+                resolve();
+            });
+        });
+        self.queueMicrotask(() => {
+            assert_equals(counter++, 2);
+        });
+        assert_equals(counter++, 0);
+    });
+}, `queueMicrotask and Promise uses the same Microtask queue`);
+
+test(() => {
+    assert_throws(new TypeError, () => {
+        self.queueMicrotask();
+    });
+    assert_throws(new TypeError, () => {
+        self.queueMicrotask(null);
+    });
+    assert_throws(new TypeError, () => {
+        self.queueMicrotask(undefined);
+    });
+    assert_throws(new TypeError, () => {
+        self.queueMicrotask(42);
+    });
+    assert_throws(new TypeError, () => {
+        self.queueMicrotask("42");
+    });
+    assert_throws(new TypeError, () => {
+        self.queueMicrotask(true);
+    });
+    assert_throws(new TypeError, () => {
+        self.queueMicrotask(Symbol("42"));
+    });
+    assert_throws(new TypeError, () => {
+        self.queueMicrotask({});
+    });
+    assert_throws(new TypeError, () => {
+        self.queueMicrotask({ handleEvent() { } });
+    });
+}, `queueMicrotask should reject non-function arguments`);
diff --git a/LayoutTests/http/wpt/workers/queue-microtask.any.worker-expected.txt b/LayoutTests/http/wpt/workers/queue-microtask.any.worker-expected.txt
new file mode 100644 (file)
index 0000000..38dcdde
--- /dev/null
@@ -0,0 +1,6 @@
+
+PASS Queued microtasks should be drained before executing macrotasks 
+PASS queueMicrotask's callback has zero arguments and self as |this| 
+PASS queueMicrotask and Promise uses the same Microtask queue 
+PASS queueMicrotask should reject non-function arguments 
+
diff --git a/LayoutTests/http/wpt/workers/queue-microtask.any.worker.html b/LayoutTests/http/wpt/workers/queue-microtask.any.worker.html
new file mode 100644 (file)
index 0000000..2382913
--- /dev/null
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file
index b798755..448b9b6 100644 (file)
@@ -1,3 +1,21 @@
+2018-08-05  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        Implement self.queueMicrotask in Workers
+        https://bugs.webkit.org/show_bug.cgi?id=188247
+
+        Reviewed by Ryosuke Niwa.
+
+        This patch adds support for self.queueMicrotask to workers.
+
+        Tests: http/wpt/workers/queue-microtask.any.html
+               http/wpt/workers/queue-microtask.any.worker.html
+
+        * bindings/js/JSWorkerGlobalScopeCustom.cpp:
+        (WebCore::JSWorkerGlobalScope::queueMicrotask):
+        * page/DOMWindow.idl:
+        Move queueMicrotask declaration to WindowOrWorkerGlobalScope.idl.
+        * page/WindowOrWorkerGlobalScope.idl:
+
 2018-08-05  Rob Buis  <rbuis@igalia.com>
 
         [GTK][WPE] Fetch tests assert in SubresourceLoader::didReceiveResponse()
index 56b37c6..0b7345a 100644 (file)
@@ -27,6 +27,7 @@
 #include "JSWorkerGlobalScope.h"
 
 #include "WorkerGlobalScope.h"
+#include <JavaScriptCore/JSMicrotask.h>
 
 
 namespace WebCore {
@@ -47,4 +48,21 @@ void JSWorkerGlobalScope::visitAdditionalChildren(SlotVisitor& visitor)
     wrapped().visitJSEventListeners(visitor);
 }
 
+JSValue JSWorkerGlobalScope::queueMicrotask(ExecState& state)
+{
+    VM& vm = state.vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    if (UNLIKELY(state.argumentCount() < 1))
+        return throwException(&state, scope, createNotEnoughArgumentsError(&state));
+
+    JSValue functionValue = state.uncheckedArgument(0);
+    if (UNLIKELY(!functionValue.isFunction(vm)))
+        return JSValue::decode(throwArgumentMustBeFunctionError(state, scope, 0, "callback", "WorkerGlobalScope", "queueMicrotask"));
+
+    scope.release();
+    Base::queueMicrotask(JSC::createJSMicrotask(vm, functionValue));
+    return jsUndefined();
+}
+
 } // namespace WebCore
index ff4d957..14c392d 100644 (file)
@@ -89,8 +89,6 @@ typedef USVString CSSOMString;
     DOMString? prompt(optional DOMString message = "", optional DOMString defaultValue = "");
     void print();
 
-    [Custom] void queueMicrotask(VoidCallback callback);
-
     long requestAnimationFrame(RequestAnimationFrameCallback callback); // FIXME: Should return an unsigned long.
     void cancelAnimationFrame(long handle); // FIXME: handle should be an unsigned long.
 
index a24f426..74db0b1 100644 (file)
@@ -46,6 +46,8 @@ typedef (CanvasImageSource or Blob or ImageData) ImageBitmapSource;
     [CallWith=ScriptState, MayThrowException] long setInterval(ScheduledAction handler, optional long timeout = 0, any... arguments);
     void clearInterval(optional long handle = 0);
 
+    [Custom] void queueMicrotask(VoidCallback callback);
+
     // Base64 utility methods.
     [MayThrowException] DOMString atob(DOMString string);
     [MayThrowException] DOMString btoa(DOMString string);