<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[247254] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/247254">247254</a></dd>
<dt>Author</dt> <dd>sbarati@apple.com</dd>
<dt>Date</dt> <dd>2019-07-08 22:32:26 -0700 (Mon, 08 Jul 2019)</dd>
</dl>

<h3>Log Message</h3>
<pre>[WHLSL Import 23 new JS reference spec tests
https://bugs.webkit.org/show_bug.cgi?id=199604

Reviewed by Myles C. Maxfield.

Source/WebCore:

This patch imports a bunch of JS reference spec tests on our way to
completing https://bugs.webkit.org/show_bug.cgi?id=199595

It also fixes the recursion checker phase. That phase had two bugs:
1. We'd assert after visiting the function declaration that it was
still in the set. However, it will not be in the set when we actually
detect recursion.
2. We would not visit the arguments to a call, so if they contained other
calls which were recursive, we would not detect such recursive calls.

Tests: webgpu/whlsl-int-literal-compare.html
       webgpu/whlsl-simple-tests.html
       webgpu/whlsl-type-mismatch.html
       webgpu/whlsl-uint-bitwise.html

* Modules/webgpu/WHLSL/WHLSLRecursionChecker.cpp:

LayoutTests:

This moves some stuff down into whlsl-test-harness which are needed by
all tests. This also adds a new checkFail that ensures the program never
runs (e.g, it has a compile error).

* webgpu/js/whlsl-test-harness.js:
(async.checkFail):
(const.webGPUPromiseTest):
* webgpu/whlsl-bitwise-bool-ops-expected.txt:
* webgpu/whlsl-bitwise-bool-ops.html:
* webgpu/whlsl-int-literal-compare-expected.txt: Added.
* webgpu/whlsl-int-literal-compare.html: Added.
* webgpu/whlsl-simple-tests-expected.txt: Added.
* webgpu/whlsl-simple-tests.html: Added.
* webgpu/whlsl-type-mismatch-expected.txt: Added.
* webgpu/whlsl-type-mismatch.html: Added.
* webgpu/whlsl-uint-bitwise-expected.txt: Added.
* webgpu/whlsl-uint-bitwise.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestswebgpujswhlsltestharnessjs">trunk/LayoutTests/webgpu/js/whlsl-test-harness.js</a></li>
<li><a href="#trunkLayoutTestswebgpumslharnesstesthtml">trunk/LayoutTests/webgpu/msl-harness-test.html</a></li>
<li><a href="#trunkLayoutTestswebgpuwhlslbitwiseboolopsexpectedtxt">trunk/LayoutTests/webgpu/whlsl-bitwise-bool-ops-expected.txt</a></li>
<li><a href="#trunkLayoutTestswebgpuwhlslbitwiseboolopshtml">trunk/LayoutTests/webgpu/whlsl-bitwise-bool-ops.html</a></li>
<li><a href="#trunkLayoutTestswebgpuwhlsltestharnesstesthtml">trunk/LayoutTests/webgpu/whlsl-test-harness-test.html</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModuleswebgpuWHLSLWHLSLRecursionCheckercpp">trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLRecursionChecker.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestswebgpuwhlslintliteralcompareexpectedtxt">trunk/LayoutTests/webgpu/whlsl-int-literal-compare-expected.txt</a></li>
<li><a href="#trunkLayoutTestswebgpuwhlslintliteralcomparehtml">trunk/LayoutTests/webgpu/whlsl-int-literal-compare.html</a></li>
<li><a href="#trunkLayoutTestswebgpuwhlslsimpletestsexpectedtxt">trunk/LayoutTests/webgpu/whlsl-simple-tests-expected.txt</a></li>
<li><a href="#trunkLayoutTestswebgpuwhlslsimpletestshtml">trunk/LayoutTests/webgpu/whlsl-simple-tests.html</a></li>
<li><a href="#trunkLayoutTestswebgpuwhlsltypemismatchexpectedtxt">trunk/LayoutTests/webgpu/whlsl-type-mismatch-expected.txt</a></li>
<li><a href="#trunkLayoutTestswebgpuwhlsltypemismatchhtml">trunk/LayoutTests/webgpu/whlsl-type-mismatch.html</a></li>
<li><a href="#trunkLayoutTestswebgpuwhlsluintbitwiseexpectedtxt">trunk/LayoutTests/webgpu/whlsl-uint-bitwise-expected.txt</a></li>
<li><a href="#trunkLayoutTestswebgpuwhlsluintbitwisehtml">trunk/LayoutTests/webgpu/whlsl-uint-bitwise.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (247253 => 247254)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog      2019-07-09 03:30:12 UTC (rev 247253)
+++ trunk/LayoutTests/ChangeLog 2019-07-09 05:32:26 UTC (rev 247254)
</span><span class="lines">@@ -1,3 +1,28 @@
</span><ins>+2019-07-08  Saam Barati  <sbarati@apple.com>
+
+        [WHLSL Import 23 new JS reference spec tests
+        https://bugs.webkit.org/show_bug.cgi?id=199604
+
+        Reviewed by Myles C. Maxfield.
+
+        This moves some stuff down into whlsl-test-harness which are needed by
+        all tests. This also adds a new checkFail that ensures the program never
+        runs (e.g, it has a compile error).
+
+        * webgpu/js/whlsl-test-harness.js:
+        (async.checkFail):
+        (const.webGPUPromiseTest):
+        * webgpu/whlsl-bitwise-bool-ops-expected.txt:
+        * webgpu/whlsl-bitwise-bool-ops.html:
+        * webgpu/whlsl-int-literal-compare-expected.txt: Added.
+        * webgpu/whlsl-int-literal-compare.html: Added.
+        * webgpu/whlsl-simple-tests-expected.txt: Added.
+        * webgpu/whlsl-simple-tests.html: Added.
+        * webgpu/whlsl-type-mismatch-expected.txt: Added.
+        * webgpu/whlsl-type-mismatch.html: Added.
+        * webgpu/whlsl-uint-bitwise-expected.txt: Added.
+        * webgpu/whlsl-uint-bitwise.html: Added.
+
</ins><span class="cx"> 2019-07-08  Wenson Hsieh  <wenson_hsieh@apple.com>
</span><span class="cx"> 
</span><span class="cx">         [iOS 13] paste-does-not-fire-promises-while-sanitizing-web-content.html times out when run with multiple iterations
</span></span></pre></div>
<a id="trunkLayoutTestswebgpujswhlsltestharnessjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/webgpu/js/whlsl-test-harness.js (247253 => 247254)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webgpu/js/whlsl-test-harness.js        2019-07-09 03:30:12 UTC (rev 247253)
+++ trunk/LayoutTests/webgpu/js/whlsl-test-harness.js   2019-07-09 05:32:26 UTC (rev 247254)
</span><span class="lines">@@ -509,6 +509,63 @@
</span><span class="cx">     return (await harness.callTypedFunction(Types.FLOAT4X4, functions, name, args)).subarray(0, 16);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+async function checkFail(source) {
+    // FIXME: Make this handle errors with proper messages once we implement the API for that.
+    const name = "____test_name____";
+    const program = `
+        ${source}
+
+        [numthreads(1, 1, 1)]
+        compute void ${name}(device int[] buffer : register(u0), float3 threadID : SV_DispatchThreadID) {
+            buffer[0] = 1;
+        }
+    `;
+    const device = await getBasicDevice();
+    const shaderModule = device.createShaderModule({code: program, isWHLSL: true});
+    const computeStage = {module: shaderModule, entryPoint: name};
+
+    const bindGroupLayoutDescriptor = {bindings: [{binding: 0, visibility: 7, type: "storage-buffer"}]};
+    const bindGroupLayout = device.createBindGroupLayout(bindGroupLayoutDescriptor);
+    const pipelineLayoutDescriptor = {bindGroupLayouts: [bindGroupLayout]};
+    const pipelineLayout = device.createPipelineLayout(pipelineLayoutDescriptor);
+
+    const computePipelineDescriptor = {computeStage, layout: pipelineLayout};
+    const computePipeline = device.createComputePipeline(computePipelineDescriptor);
+
+    const size = Int32Array.BYTES_PER_ELEMENT * 1;
+
+    const bufferDescriptor = {size, usage: GPUBufferUsage.MAP_WRITE | GPUBufferUsage.TRANSFER_SRC};
+    const buffer = device.createBuffer(bufferDescriptor);
+    const bufferArrayBuffer = await buffer.mapWriteAsync();
+    const bufferInt32Array = new Int32Array(bufferArrayBuffer);
+    bufferInt32Array[0] = 0;
+    buffer.unmap();
+
+    const resultsBufferDescriptor = {size, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.TRANSFER_DST | GPUBufferUsage.MAP_READ};
+    const resultsBuffer = device.createBuffer(resultsBufferDescriptor);
+
+    const bufferBinding = {buffer: resultsBuffer, size};
+    const bindGroupBinding = {binding: 0, resource: bufferBinding};
+    const bindGroupDescriptor = {layout: bindGroupLayout, bindings: [bindGroupBinding]};
+    const bindGroup = device.createBindGroup(bindGroupDescriptor);
+
+    const commandEncoder = device.createCommandEncoder(); // {}
+    commandEncoder.copyBufferToBuffer(buffer, 0, resultsBuffer, 0, size);
+    const computePassEncoder = commandEncoder.beginComputePass();
+    computePassEncoder.setPipeline(computePipeline);
+    computePassEncoder.setBindGroup(0, bindGroup);
+    computePassEncoder.dispatch(1, 1, 1);
+    computePassEncoder.endPass();
+    const commandBuffer = commandEncoder.finish();
+    device.getQueue().submit([commandBuffer]);
+
+    const resultsArrayBuffer = await resultsBuffer.mapReadAsync();
+    let resultsInt32Array = new Int32Array(resultsArrayBuffer);
+    if (resultsInt32Array[0] !== 0)
+        throw new Error("program did not fail to compile");
+    resultsBuffer.unmap();
+}
+
</ins><span class="cx"> /**
</span><span class="cx">  * Does not return a Promise. To observe the results of a call, 
</span><span class="cx">  * call 'getArrayBuffer' on the Data object retaining your output buffer.
</span><span class="lines">@@ -517,3 +574,29 @@
</span><span class="cx"> {
</span><span class="cx">     harness.callVoidFunction(functions, name, args);
</span><span class="cx"> }
</span><ins>+
+const webGPUPromiseTest = (testFunc, msg) => {
+    promise_test(async () => { 
+        return testFunc().catch(e => {
+        if (!(e instanceof WebGPUUnsupportedError))
+            throw e;
+        });
+    }, msg);
+}
+
+function runTests(obj) {
+    window.addEventListener("load", async () => {
+        try {
+            for (const name in obj) {
+                if (!name.startsWith("_")) 
+                    await webGPUPromiseTest(obj[name], name);
+            }
+        } catch (e) {
+            if (window.testRunner)
+                testRunner.notifyDone();
+            
+            throw e;
+        }
+    });
+}
+
</ins></span></pre></div>
<a id="trunkLayoutTestswebgpumslharnesstesthtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/webgpu/msl-harness-test.html (247253 => 247254)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webgpu/msl-harness-test.html   2019-07-09 03:30:12 UTC (rev 247253)
+++ trunk/LayoutTests/webgpu/msl-harness-test.html      2019-07-09 05:32:26 UTC (rev 247254)
</span><span class="lines">@@ -205,14 +205,5 @@
</span><span class="cx">         });
</span><span class="cx">     }, "Return an expected float4 value.");
</span><span class="cx"> }
</span><del>-
-const webGPUPromiseTest = (testFunc, msg) => {
-    promise_test(async () => { 
-        return testFunc().catch(e => {
-        if (!(e instanceof WebGPUUnsupportedError))
-            throw e;
-        });
-    }, msg);
-}
</del><span class="cx"> </script>
</span><del>-</html>
</del><span class="cx">\ No newline at end of file
</span><ins>+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestswebgpuwhlslbitwiseboolopsexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/webgpu/whlsl-bitwise-bool-ops-expected.txt (247253 => 247254)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webgpu/whlsl-bitwise-bool-ops-expected.txt     2019-07-09 03:30:12 UTC (rev 247253)
+++ trunk/LayoutTests/webgpu/whlsl-bitwise-bool-ops-expected.txt        2019-07-09 05:32:26 UTC (rev 247254)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> 
</span><del>-PASS Bool bit and 
-PASS Bool bit or 
-PASS Bool bit or 
-PASS Bool bit not 
</del><ins>+PASS boolBitAnd 
+PASS boolBitOr 
+PASS boolBitXor 
+PASS boolBitNot 
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestswebgpuwhlslbitwiseboolopshtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/webgpu/whlsl-bitwise-bool-ops.html (247253 => 247254)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webgpu/whlsl-bitwise-bool-ops.html     2019-07-09 03:30:12 UTC (rev 247253)
+++ trunk/LayoutTests/webgpu/whlsl-bitwise-bool-ops.html        2019-07-09 05:32:26 UTC (rev 247254)
</span><span class="lines">@@ -11,7 +11,7 @@
</span><span class="cx"> 
</span><span class="cx"> const whlslTests = {};
</span><span class="cx"> 
</span><del>-whlslTests.boolBitAnd = () => {
</del><ins>+whlslTests.boolBitAnd = async () => {
</ins><span class="cx">     const source = `
</span><span class="cx">         bool foo(bool a, bool b)
</span><span class="cx">         {
</span><span class="lines">@@ -19,35 +19,28 @@
</span><span class="cx">         }
</span><span class="cx">     `;
</span><span class="cx"> 
</span><del>-    webGPUPromiseTest(async () => {
-        try {
-            {
-                let result = await callBoolFunction(source, "foo", [makeBool(true), makeBool(true)]);
-                assert_equals(result, true, "Test returned expected value.");
-            }
</del><ins>+    {
+        let result = await callBoolFunction(source, "foo", [makeBool(true), makeBool(true)]);
+        assert_equals(result, true, "Test returned expected value.");
+    }
</ins><span class="cx"> 
</span><del>-            {
-                let result = await callBoolFunction(source, "foo", [makeBool(false), makeBool(false)]);
-                assert_equals(result, false, "Test returned expected value.");
-            }
</del><ins>+    {
+        let result = await callBoolFunction(source, "foo", [makeBool(false), makeBool(false)]);
+        assert_equals(result, false, "Test returned expected value.");
+    }
</ins><span class="cx"> 
</span><del>-            {
-                let result = await callBoolFunction(source, "foo", [makeBool(true), makeBool(false)]);
-                assert_equals(result, false, "Test returned expected value.");
-            }
</del><ins>+    {
+        let result = await callBoolFunction(source, "foo", [makeBool(true), makeBool(false)]);
+        assert_equals(result, false, "Test returned expected value.");
+    }
</ins><span class="cx"> 
</span><del>-            {
-                let result = await callBoolFunction(source, "foo", [makeBool(false), makeBool(true)]);
-                assert_equals(result, false, "Test returned expected value.");
-            }
-        } catch(e) {
-            if (!(e instanceof WebGPUUnsupportedError))
-                throw e;
-        }
-    }, "Bool bit and");
</del><ins>+    {
+        let result = await callBoolFunction(source, "foo", [makeBool(false), makeBool(true)]);
+        assert_equals(result, false, "Test returned expected value.");
+    }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-whlslTests.boolBitOr = () => {
</del><ins>+whlslTests.boolBitOr = async () => {
</ins><span class="cx">     const source = `
</span><span class="cx">         bool foo(bool a, bool b)
</span><span class="cx">         {
</span><span class="lines">@@ -55,35 +48,28 @@
</span><span class="cx">         }
</span><span class="cx">     `;
</span><span class="cx"> 
</span><del>-    webGPUPromiseTest(async () => {
-        try {
-            {
-                let result = await callBoolFunction(source, "foo", [makeBool(true), makeBool(true)]);
-                assert_equals(result, true, "Test returned expected value.");
-            }
</del><ins>+    {
+        let result = await callBoolFunction(source, "foo", [makeBool(true), makeBool(true)]);
+        assert_equals(result, true, "Test returned expected value.");
+    }
</ins><span class="cx"> 
</span><del>-            {
-                let result = await callBoolFunction(source, "foo", [makeBool(false), makeBool(false)]);
-                assert_equals(result, false, "Test returned expected value.");
-            }
</del><ins>+    {
+        let result = await callBoolFunction(source, "foo", [makeBool(false), makeBool(false)]);
+        assert_equals(result, false, "Test returned expected value.");
+    }
</ins><span class="cx"> 
</span><del>-            {
-                let result = await callBoolFunction(source, "foo", [makeBool(true), makeBool(false)]);
-                assert_equals(result, true, "Test returned expected value.");
-            }
</del><ins>+    {
+        let result = await callBoolFunction(source, "foo", [makeBool(true), makeBool(false)]);
+        assert_equals(result, true, "Test returned expected value.");
+    }
</ins><span class="cx"> 
</span><del>-            {
-                let result = await callBoolFunction(source, "foo", [makeBool(false), makeBool(true)]);
-                assert_equals(result, true, "Test returned expected value.");
-            }
-        } catch(e) {
-            if (!(e instanceof WebGPUUnsupportedError))
-                throw e;
-        }
-    }, "Bool bit or");
</del><ins>+    {
+        let result = await callBoolFunction(source, "foo", [makeBool(false), makeBool(true)]);
+        assert_equals(result, true, "Test returned expected value.");
+    }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-whlslTests.boolBitXor = () => {
</del><ins>+whlslTests.boolBitXor = async () => {
</ins><span class="cx">     const source = `
</span><span class="cx">         bool foo(bool a, bool b)
</span><span class="cx">         {
</span><span class="lines">@@ -91,35 +77,28 @@
</span><span class="cx">         }
</span><span class="cx">     `;
</span><span class="cx"> 
</span><del>-    webGPUPromiseTest(async () => {
-        try {
-            {
-                let result = await callBoolFunction(source, "foo", [makeBool(true), makeBool(true)]);
-                assert_equals(result, false, "Test returned expected value.");
-            }
</del><ins>+    {
+        let result = await callBoolFunction(source, "foo", [makeBool(true), makeBool(true)]);
+        assert_equals(result, false, "Test returned expected value.");
+    }
</ins><span class="cx"> 
</span><del>-            {
-                let result = await callBoolFunction(source, "foo", [makeBool(false), makeBool(false)]);
-                assert_equals(result, false, "Test returned expected value.");
-            }
</del><ins>+    {
+        let result = await callBoolFunction(source, "foo", [makeBool(false), makeBool(false)]);
+        assert_equals(result, false, "Test returned expected value.");
+    }
</ins><span class="cx"> 
</span><del>-            {
-                let result = await callBoolFunction(source, "foo", [makeBool(true), makeBool(false)]);
-                assert_equals(result, true, "Test returned expected value.");
-            }
</del><ins>+    {
+        let result = await callBoolFunction(source, "foo", [makeBool(true), makeBool(false)]);
+        assert_equals(result, true, "Test returned expected value.");
+    }
</ins><span class="cx"> 
</span><del>-            {
-                let result = await callBoolFunction(source, "foo", [makeBool(false), makeBool(true)]);
-                assert_equals(result, true, "Test returned expected value.");
-            }
-        } catch(e) {
-            if (!(e instanceof WebGPUUnsupportedError))
-                throw e;
-        }
-    }, "Bool bit or");
</del><ins>+    {
+        let result = await callBoolFunction(source, "foo", [makeBool(false), makeBool(true)]);
+        assert_equals(result, true, "Test returned expected value.");
+    }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-whlslTests.boolBitNot = () => {
</del><ins>+whlslTests.boolBitNot = async () => {
</ins><span class="cx">     const source = `
</span><span class="cx">         bool foo(bool a)
</span><span class="cx">         {
</span><span class="lines">@@ -127,49 +106,17 @@
</span><span class="cx">         }
</span><span class="cx">     `;
</span><span class="cx"> 
</span><del>-    webGPUPromiseTest(async () => {
-        try {
-            {
-                let result = await callBoolFunction(source, "foo", [makeBool(true)]);
-                assert_equals(result, false, "Test returned expected value.");
-            }
</del><ins>+    {
+        let result = await callBoolFunction(source, "foo", [makeBool(true)]);
+        assert_equals(result, false, "Test returned expected value.");
+    }
</ins><span class="cx"> 
</span><del>-            {
-                let result = await callBoolFunction(source, "foo", [makeBool(false)]);
-                assert_equals(result, true, "Test returned expected value.");
-            }
-        } catch(e) {
-            if (!(e instanceof WebGPUUnsupportedError))
-                throw e;
-        }
-    }, "Bool bit not");
</del><ins>+    {
+        let result = await callBoolFunction(source, "foo", [makeBool(false)]);
+        assert_equals(result, true, "Test returned expected value.");
+    }
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-function runTests(obj) {
-    window.addEventListener("load", () => {
-        try {
-            for (const name in obj) {
-                if (!name.startsWith("_"))
-                    obj[name]();
-            }
-        } catch (e) {
-            if (window.testRunner)
-                testRunner.notifyDone();
-            
-            throw e;
-        }
-    });
-}
-
</del><span class="cx"> runTests(whlslTests);
</span><del>-
-const webGPUPromiseTest = (testFunc, msg) => {
-    promise_test(async () => { 
-        return testFunc().catch(e => {
-        if (!(e instanceof WebGPUUnsupportedError))
-            throw e;
-        });
-    }, msg);
-}
</del><span class="cx"> </script>
</span><span class="cx"> </html>
</span></span></pre></div>
<a id="trunkLayoutTestswebgpuwhlslintliteralcompareexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/webgpu/whlsl-int-literal-compare-expected.txt (0 => 247254)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webgpu/whlsl-int-literal-compare-expected.txt                          (rev 0)
+++ trunk/LayoutTests/webgpu/whlsl-int-literal-compare-expected.txt     2019-07-09 05:32:26 UTC (rev 247254)
</span><span class="lines">@@ -0,0 +1,3 @@
</span><ins>+
+PASS twoIntLiterals 
+
</ins></span></pre></div>
<a id="trunkLayoutTestswebgpuwhlslintliteralcomparehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/webgpu/whlsl-int-literal-compare.html (0 => 247254)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webgpu/whlsl-int-literal-compare.html                          (rev 0)
+++ trunk/LayoutTests/webgpu/whlsl-int-literal-compare.html     2019-07-09 05:32:26 UTC (rev 247254)
</span><span class="lines">@@ -0,0 +1,24 @@
</span><ins>+<!DOCTYPE html><!-- webkit-test-runner [ experimental:WebGPUEnabled=true ] -->
+<html>
+<meta charset=utf-8>
+<meta name="timeout" content="long">
+<title>Test the WHLSL test harness.</title>
+<script src="js/whlsl-test-harness.js"></script>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<script>
+const whlslTests = {};
+
+whlslTests.twoIntLiterals = async () => {
+    let program = `
+        bool foo()
+        {
+            return 42 == 42;
+        }
+    `;
+    assert_equals(await callBoolFunction(program, "foo", []), true);
+}
+
+runTests(whlslTests);
+</script>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestswebgpuwhlslsimpletestsexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/webgpu/whlsl-simple-tests-expected.txt (0 => 247254)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webgpu/whlsl-simple-tests-expected.txt                         (rev 0)
+++ trunk/LayoutTests/webgpu/whlsl-simple-tests-expected.txt    2019-07-09 05:32:26 UTC (rev 247254)
</span><span class="lines">@@ -0,0 +1,7 @@
</span><ins>+
+PASS simpleUnreachableCode 
+PASS simpleNoReturn 
+PASS simpleRecursiveStruct 
+PASS simpleRecursion 
+PASS simpleRecursion2 
+
</ins></span></pre></div>
<a id="trunkLayoutTestswebgpuwhlslsimpletestshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/webgpu/whlsl-simple-tests.html (0 => 247254)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webgpu/whlsl-simple-tests.html                         (rev 0)
+++ trunk/LayoutTests/webgpu/whlsl-simple-tests.html    2019-07-09 05:32:26 UTC (rev 247254)
</span><span class="lines">@@ -0,0 +1,63 @@
</span><ins>+<!DOCTYPE html><!-- webkit-test-runner [ experimental:WebGPUEnabled=true ] -->
+<html>
+<meta charset=utf-8>
+<meta name="timeout" content="long">
+<title>Test the WHLSL test harness.</title>
+<script src="js/whlsl-test-harness.js"></script>
+<script src="js/webgpu-functions.js"></script>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<script>
+const whlslTests = {};
+
+whlslTests.simpleUnreachableCode = async () => {
+    await checkFail(
+        `
+            void foo()
+            {
+                return;
+                int x;
+            }
+        `);
+}
+
+whlslTests.simpleNoReturn = async () => {
+    await checkFail("int foo() { }");
+}
+
+whlslTests.simpleRecursiveStruct = async () => {
+    await checkFail(
+        `
+            struct Foo {
+                Foo foo;
+            }
+        `);
+}
+
+whlslTests.simpleRecursion = async () => {
+    await checkFail(
+        `
+            void foo(int x)
+            {
+                foo(x);
+            }
+        `);
+}
+
+whlslTests.simpleRecursion2 = async () => {
+    await checkFail(
+        `
+            int bar(int x) {
+                foo(x);
+                return x;
+            }
+            void foo(int x)
+            {
+                foo(bar(x));
+            }
+        `);
+}
+
+runTests(whlslTests);
+</script>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestswebgpuwhlsltestharnesstesthtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/webgpu/whlsl-test-harness-test.html (247253 => 247254)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webgpu/whlsl-test-harness-test.html    2019-07-09 03:30:12 UTC (rev 247253)
+++ trunk/LayoutTests/webgpu/whlsl-test-harness-test.html       2019-07-09 05:32:26 UTC (rev 247254)
</span><span class="lines">@@ -262,14 +262,5 @@
</span><span class="cx">     
</span><span class="cx">     return [src, name, values];
</span><span class="cx"> };
</span><del>-
-const webGPUPromiseTest = (testFunc, msg) => {
-    promise_test(async () => { 
-        return testFunc().catch(e => {
-        if (!(e instanceof WebGPUUnsupportedError))
-            throw e;
-        });
-    }, msg);
-}
</del><span class="cx"> </script>
</span><span class="cx"> </html>
</span></span></pre></div>
<a id="trunkLayoutTestswebgpuwhlsltypemismatchexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/webgpu/whlsl-type-mismatch-expected.txt (0 => 247254)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webgpu/whlsl-type-mismatch-expected.txt                                (rev 0)
+++ trunk/LayoutTests/webgpu/whlsl-type-mismatch-expected.txt   2019-07-09 05:32:26 UTC (rev 247254)
</span><span class="lines">@@ -0,0 +1,6 @@
</span><ins>+
+PASS typeMismatchReturn 
+PASS typeMismatchVariableDecl 
+PASS typeMismatchAssignment 
+PASS typeMismatchReturnParam 
+
</ins></span></pre></div>
<a id="trunkLayoutTestswebgpuwhlsltypemismatchhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/webgpu/whlsl-type-mismatch.html (0 => 247254)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webgpu/whlsl-type-mismatch.html                                (rev 0)
+++ trunk/LayoutTests/webgpu/whlsl-type-mismatch.html   2019-07-09 05:32:26 UTC (rev 247254)
</span><span class="lines">@@ -0,0 +1,62 @@
</span><ins>+<!DOCTYPE html><!-- webkit-test-runner [ experimental:WebGPUEnabled=true ] -->
+<html>
+<meta charset=utf-8>
+<meta name="timeout" content="long">
+<title>Test the WHLSL test harness.</title>
+<script src="js/whlsl-test-harness.js"></script>
+<script src="js/webgpu-functions.js"></script>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<script>
+
+const whlslTests = {};
+
+whlslTests.typeMismatchReturn = async () =>
+{
+    await checkFail(
+        `
+            int foo()
+            {
+                return 10.5;
+            }
+        `);
+}
+
+whlslTests.typeMismatchVariableDecl = async () =>
+{
+    await checkFail(
+        `
+            void foo(uint x)
+            {
+                int y = x;
+            }
+        `);
+}
+
+whlslTests.typeMismatchAssignment = async () =>
+{
+    await checkFail(
+        `
+            void foo(uint x)
+            {
+                int y;
+                y = x;
+            }
+        `);
+}
+
+whlslTests.typeMismatchReturnParam = async () =>
+{
+    await checkFail(
+        `
+            int foo(uint x)
+            {
+                return x;
+            }
+        `);
+}
+
+runTests(whlslTests);
+
+</script>
+</html>
</ins></span></pre></div>
<a id="trunkLayoutTestswebgpuwhlsluintbitwiseexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/webgpu/whlsl-uint-bitwise-expected.txt (0 => 247254)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webgpu/whlsl-uint-bitwise-expected.txt                         (rev 0)
+++ trunk/LayoutTests/webgpu/whlsl-uint-bitwise-expected.txt    2019-07-09 05:32:26 UTC (rev 247254)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+
+PASS uintBitAnd 
+PASS uintBitOr 
+PASS uintBitXor 
+PASS uintBitNot 
+PASS uintLShift 
+PASS uintRShift 
+PASS uintSimpleMath 
+
</ins></span></pre></div>
<a id="trunkLayoutTestswebgpuwhlsluintbitwisehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/webgpu/whlsl-uint-bitwise.html (0 => 247254)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/webgpu/whlsl-uint-bitwise.html                         (rev 0)
+++ trunk/LayoutTests/webgpu/whlsl-uint-bitwise.html    2019-07-09 05:32:26 UTC (rev 247254)
</span><span class="lines">@@ -0,0 +1,108 @@
</span><ins>+<!DOCTYPE html><!-- webkit-test-runner [ experimental:WebGPUEnabled=true ] -->
+<html>
+<meta charset=utf-8>
+<meta name="timeout" content="long">
+<title>Test the WHLSL test harness.</title>
+<script src="js/whlsl-test-harness.js"></script>
+<script src="../resources/testharness.js"></script>
+<script src="../resources/testharnessreport.js"></script>
+<script>
+const whlslTests = {};
+
+whlslTests.uintBitAnd = async () => {
+    let program = `
+        uint foo(uint a, uint b)
+        {
+            return a & b;
+        }
+    `;
+    assert_equals(await callUintFunction(program, "foo", [makeUint(1), makeUint(7)]), 1);
+    assert_equals(await callUintFunction(program, "foo", [makeUint(65535), makeUint(42)]), 42);
+    assert_equals(await callUintFunction(program, "foo", [makeUint(Math.pow(2, 32) - 1), makeUint(Math.pow(2, 32) - 7)]), 4294967289);
+    assert_equals(await callUintFunction(program, "foo", [makeUint(0), makeUint(85732)]), 0);
+}
+
+whlslTests.uintBitOr = async () => {
+    let program = `
+        uint foo(uint a, uint b)
+        {
+            return a | b;
+        }
+    `;
+    assert_equals(await callUintFunction(program, "foo", [makeUint(1), makeUint(7)]), 7);
+    assert_equals(await callUintFunction(program, "foo", [makeUint(65535), makeUint(42)]), 65535);
+    assert_equals(await callUintFunction(program, "foo", [makeUint(Math.pow(2, 32) - 1), makeUint(Math.pow(2, 32)  - 7)]), 4294967295);
+    assert_equals(await callUintFunction(program, "foo", [makeUint(0), makeUint(85732)]), 85732);
+}
+
+whlslTests.uintBitXor = async () => {
+    let program = `
+        uint foo(uint a, uint b)
+        {
+            return a ^ b;
+        }
+    `;
+    assert_equals(await callUintFunction(program, "foo", [makeUint(1), makeUint(7)]), 6);
+    assert_equals(await callUintFunction(program, "foo", [makeUint(65535), makeUint(42)]), 65493);
+    assert_equals(await callUintFunction(program, "foo", [makeUint(Math.pow(2, 32) - 1), makeUint(Math.pow(2, 32) - 7)]), 6);
+    assert_equals(await callUintFunction(program, "foo", [makeUint(0), makeUint(85732)]), 85732);
+}
+
+whlslTests.uintBitNot = async () => { 
+    let program = `
+        uint foo(uint a)
+        {
+            return ~a;
+        }
+    `;
+    assert_equals(await callUintFunction(program, "foo", [makeUint(1)]), 4294967294);
+    assert_equals(await callUintFunction(program, "foo", [makeUint(65535)]), 4294901760);
+    assert_equals(await callUintFunction(program, "foo", [makeUint(Math.pow(2, 32) - 1)]), 0);
+    assert_equals(await callUintFunction(program, "foo", [makeUint(0)]), 4294967295);
+}
+
+whlslTests.uintLShift = async () => {
+    let program = `
+        uint foo(uint a, uint b)
+        {
+            return a << b;
+        }
+    `;
+    assert_equals(await callUintFunction(program, "foo", [makeUint(1), makeUint(7)]), 128);
+    assert_equals(await callUintFunction(program, "foo", [makeUint(65535), makeUint(2)]), 262140);
+    assert_equals(await callUintFunction(program, "foo", [makeUint(Math.pow(2, 32) - 1), makeUint(5)]), 4294967264);
+    assert_equals(await callUintFunction(program, "foo", [makeUint(0), makeUint(3)]), 0);
+};
+
+whlslTests.uintRShift = async () => {
+    let program = `
+        uint foo(uint a, uint b)
+        {
+            return a >> b;
+        }
+    `;
+    assert_equals(await callUintFunction(program, "foo", [makeUint(1), makeUint(7)]), 0);
+    assert_equals(await callUintFunction(program, "foo", [makeUint(65535), makeUint(2)]), 16383);
+    assert_equals(await callUintFunction(program, "foo", [makeUint(Math.pow(2, 32) - 1), makeUint(5)]), 134217727);
+    assert_equals(await callUintFunction(program, "foo", [makeUint(0), makeUint(3)]), 0);
+};
+
+whlslTests.uintSimpleMath = async () => {
+    let program = "uint foo(uint x, uint y) { return x + y; }";
+    assert_equals(await callUintFunction(program, "foo", [makeUint(7), makeUint(5)]), 12);
+
+    program = "uint foo(uint x, uint y) { return x - y; }";
+    assert_equals(await callUintFunction(program, "foo", [makeUint(7), makeUint(5)]), 2);
+    assert_equals(await callUintFunction(program, "foo", [makeUint(5), makeUint(7)]), 4294967294);
+
+    program = "uint foo(uint x, uint y) { return x * y; }";
+    assert_equals(await callUintFunction(program, "foo", [makeUint(7), makeUint(5)]), 35);
+
+    // FIXME: make this work: https://bugs.webkit.org/show_bug.cgi?id=199602
+    // program = "uint foo(uint x, uint y) { return x / y; }";
+    // assert_equals(await callUintFunction(program, "foo", [makeUint(7), makeUint(2)]), 3);
+}
+
+runTests(whlslTests);
+</script>
+</html>
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (247253 => 247254)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2019-07-09 03:30:12 UTC (rev 247253)
+++ trunk/Source/WebCore/ChangeLog      2019-07-09 05:32:26 UTC (rev 247254)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2019-07-08  Saam Barati  <sbarati@apple.com>
+
+        [WHLSL Import 23 new JS reference spec tests
+        https://bugs.webkit.org/show_bug.cgi?id=199604
+
+        Reviewed by Myles C. Maxfield.
+
+        This patch imports a bunch of JS reference spec tests on our way to
+        completing https://bugs.webkit.org/show_bug.cgi?id=199595
+        
+        It also fixes the recursion checker phase. That phase had two bugs:
+        1. We'd assert after visiting the function declaration that it was
+        still in the set. However, it will not be in the set when we actually
+        detect recursion.
+        2. We would not visit the arguments to a call, so if they contained other
+        calls which were recursive, we would not detect such recursive calls.
+
+        Tests: webgpu/whlsl-int-literal-compare.html
+               webgpu/whlsl-simple-tests.html
+               webgpu/whlsl-type-mismatch.html
+               webgpu/whlsl-uint-bitwise.html
+
+        * Modules/webgpu/WHLSL/WHLSLRecursionChecker.cpp:
+
</ins><span class="cx"> 2019-07-08  Chris Dumez  <cdumez@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Make Document::postTask() safe to call from a background thread
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebgpuWHLSLWHLSLRecursionCheckercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLRecursionChecker.cpp (247253 => 247254)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLRecursionChecker.cpp      2019-07-09 03:30:12 UTC (rev 247253)
+++ trunk/Source/WebCore/Modules/webgpu/WHLSL/WHLSLRecursionChecker.cpp 2019-07-09 05:32:26 UTC (rev 247254)
</span><span class="lines">@@ -49,6 +49,8 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         Visitor::visit(functionDefinition);
</span><ins>+        if (error())
+            return;
</ins><span class="cx"> 
</span><span class="cx">         auto success = m_visitingSet.remove(&functionDefinition);
</span><span class="cx">         ASSERT_UNUSED(success, success);
</span><span class="lines">@@ -56,7 +58,9 @@
</span><span class="cx"> 
</span><span class="cx">     void visit(AST::CallExpression& callExpression) override
</span><span class="cx">     {
</span><del>-        Visitor::visit(callExpression.function());
</del><ins>+        Visitor::visit(callExpression);
+        if (is<AST::FunctionDefinition>(callExpression.function()))
+            checkErrorAndVisit(downcast<AST::FunctionDefinition>(callExpression.function()));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     HashSet<AST::FunctionDefinition*> m_visitingSet;
</span></span></pre>
</div>
</div>

</body>
</html>