<!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>[236628] trunk/Tools</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/236628">236628</a></dd>
<dt>Author</dt> <dd>mmaxfield@apple.com</dd>
<dt>Date</dt> <dd>2018-09-28 17:48:34 -0700 (Fri, 28 Sep 2018)</dd>
</dl>

<h3>Log Message</h3>
<pre>[WHLSL] Pointers should have automatically-generated equality checks
https://bugs.webkit.org/show_bug.cgi?id=189986

Reviewed by Filip Pizlo.

C allows for pointer equality, and we need it so people can do null checks.
This is generated the same way all our other NativeFuncs are generated - by Checker
creating NativeFuncs inside CallExpression.resolve().

This patch also does some general cleanup.

* WebGPUShadingLanguageRI/All.js: Everything the late checker does is no longer necessary.
The last thing it was doing was making sure that only primitive types are in resources, but
it's totally reasonable to put structs and arrays in resources, so I removed this pass. We
still have to add a check to make sure resources can't live within resources, but I expect
that will be done in the same place that semantics are checked.
* WebGPUShadingLanguageRI/AllocateAtEntryPoints.js:
(allocateAtEntryPoints.updateFunction.UpdateFunctions.prototype._addVariableDeclaration):
Name the global struct for debugging purposes.
* WebGPUShadingLanguageRI/CallExpression.js:
(CallExpression.prototype._resolveByInstantiation): Cleanup
(CallExpression.prototype._resolveWithOperatorAnderIndexer): Ditto
(CallExpression.prototype._resolveWithOperatorLength): Ditto
(CallExpression.prototype._resolveWithReferenceComparator): Add support to automatically
generate pointer equality NativeFuncs.
* WebGPUShadingLanguageRI/EPtr.js: Implement pointer equality in the interpreter.
* WebGPUShadingLanguageRI/LateChecker.js: Removed.
* WebGPUShadingLanguageRI/LayoutBuffers.js: Renamed from Tools/WebGPUShadingLanguageRI/LateCheckAndLayoutBuffers.js.
(layoutBuffers):
* WebGPUShadingLanguageRI/Metal/WHLSL Tests/WHLSL Tests.xcodeproj/project.pbxproj:
* WebGPUShadingLanguageRI/NativeFunc.js:
* WebGPUShadingLanguageRI/OperatorArrayRefLength.js:
(OperatorArrayRefLength.prototype.instantiateImplementation):
(OperatorArrayRefLength):
* WebGPUShadingLanguageRI/Prepare.js:
(let.prepare):
* WebGPUShadingLanguageRI/SPIRV.html:
* WebGPUShadingLanguageRI/Test.html:
* WebGPUShadingLanguageRI/Test.js:
(tests.ternaryExpression):
(tests.break): Speed up testing time
(tests.doWhile): Ditto
(tests.forLoop): Ditto
(tests.atomics): Ditto
(tests.atomicsNull): Ditto
(tests.pointerEquality): Test pointer equality
(tests.standardLibraryDevicePointers):
(tests.devicePtrPtr): Deleted.
(tests.threadgroupPtrPtr): Deleted.
(tests.constantPtrPtr): Deleted.
* WebGPUShadingLanguageRI/index.html:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsWebGPUShadingLanguageRIAlljs">trunk/Tools/WebGPUShadingLanguageRI/All.js</a></li>
<li><a href="#trunkToolsWebGPUShadingLanguageRIAllocateAtEntryPointsjs">trunk/Tools/WebGPUShadingLanguageRI/AllocateAtEntryPoints.js</a></li>
<li><a href="#trunkToolsWebGPUShadingLanguageRICallExpressionjs">trunk/Tools/WebGPUShadingLanguageRI/CallExpression.js</a></li>
<li><a href="#trunkToolsWebGPUShadingLanguageRIEArrayRefjs">trunk/Tools/WebGPUShadingLanguageRI/EArrayRef.js</a></li>
<li><a href="#trunkToolsWebGPUShadingLanguageRIEPtrjs">trunk/Tools/WebGPUShadingLanguageRI/EPtr.js</a></li>
<li><a href="#trunkToolsWebGPUShadingLanguageRIMetalWHLSLTestsWHLSLTestsxcodeprojprojectpbxproj">trunk/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/WHLSL Tests.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkToolsWebGPUShadingLanguageRINativeFuncjs">trunk/Tools/WebGPUShadingLanguageRI/NativeFunc.js</a></li>
<li><a href="#trunkToolsWebGPUShadingLanguageRIOperatorArrayRefLengthjs">trunk/Tools/WebGPUShadingLanguageRI/OperatorArrayRefLength.js</a></li>
<li><a href="#trunkToolsWebGPUShadingLanguageRIPreparejs">trunk/Tools/WebGPUShadingLanguageRI/Prepare.js</a></li>
<li><a href="#trunkToolsWebGPUShadingLanguageRISPIRVhtml">trunk/Tools/WebGPUShadingLanguageRI/SPIRV.html</a></li>
<li><a href="#trunkToolsWebGPUShadingLanguageRITesthtml">trunk/Tools/WebGPUShadingLanguageRI/Test.html</a></li>
<li><a href="#trunkToolsWebGPUShadingLanguageRITestjs">trunk/Tools/WebGPUShadingLanguageRI/Test.js</a></li>
<li><a href="#trunkToolsWebGPUShadingLanguageRIindexhtml">trunk/Tools/WebGPUShadingLanguageRI/index.html</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkToolsWebGPUShadingLanguageRILayoutBuffersjs">trunk/Tools/WebGPUShadingLanguageRI/LayoutBuffers.js</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkToolsWebGPUShadingLanguageRILateCheckAndLayoutBuffersjs">trunk/Tools/WebGPUShadingLanguageRI/LateCheckAndLayoutBuffers.js</a></li>
<li><a href="#trunkToolsWebGPUShadingLanguageRILateCheckerjs">trunk/Tools/WebGPUShadingLanguageRI/LateChecker.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (236627 => 236628)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog    2018-09-29 00:22:08 UTC (rev 236627)
+++ trunk/Tools/ChangeLog       2018-09-29 00:48:34 UTC (rev 236628)
</span><span class="lines">@@ -1,3 +1,57 @@
</span><ins>+2018-09-28  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [WHLSL] Pointers should have automatically-generated equality checks
+        https://bugs.webkit.org/show_bug.cgi?id=189986
+
+        Reviewed by Filip Pizlo.
+
+        C allows for pointer equality, and we need it so people can do null checks.
+        This is generated the same way all our other NativeFuncs are generated - by Checker
+        creating NativeFuncs inside CallExpression.resolve().
+
+        This patch also does some general cleanup.
+
+        * WebGPUShadingLanguageRI/All.js: Everything the late checker does is no longer necessary.
+        The last thing it was doing was making sure that only primitive types are in resources, but
+        it's totally reasonable to put structs and arrays in resources, so I removed this pass. We
+        still have to add a check to make sure resources can't live within resources, but I expect
+        that will be done in the same place that semantics are checked.
+        * WebGPUShadingLanguageRI/AllocateAtEntryPoints.js:
+        (allocateAtEntryPoints.updateFunction.UpdateFunctions.prototype._addVariableDeclaration):
+        Name the global struct for debugging purposes.
+        * WebGPUShadingLanguageRI/CallExpression.js: 
+        (CallExpression.prototype._resolveByInstantiation): Cleanup
+        (CallExpression.prototype._resolveWithOperatorAnderIndexer): Ditto
+        (CallExpression.prototype._resolveWithOperatorLength): Ditto
+        (CallExpression.prototype._resolveWithReferenceComparator): Add support to automatically
+        generate pointer equality NativeFuncs.
+        * WebGPUShadingLanguageRI/EPtr.js: Implement pointer equality in the interpreter.
+        * WebGPUShadingLanguageRI/LateChecker.js: Removed.
+        * WebGPUShadingLanguageRI/LayoutBuffers.js: Renamed from Tools/WebGPUShadingLanguageRI/LateCheckAndLayoutBuffers.js.
+        (layoutBuffers):
+        * WebGPUShadingLanguageRI/Metal/WHLSL Tests/WHLSL Tests.xcodeproj/project.pbxproj:
+        * WebGPUShadingLanguageRI/NativeFunc.js:
+        * WebGPUShadingLanguageRI/OperatorArrayRefLength.js:
+        (OperatorArrayRefLength.prototype.instantiateImplementation):
+        (OperatorArrayRefLength):
+        * WebGPUShadingLanguageRI/Prepare.js:
+        (let.prepare):
+        * WebGPUShadingLanguageRI/SPIRV.html:
+        * WebGPUShadingLanguageRI/Test.html:
+        * WebGPUShadingLanguageRI/Test.js:
+        (tests.ternaryExpression):
+        (tests.break): Speed up testing time
+        (tests.doWhile): Ditto
+        (tests.forLoop): Ditto
+        (tests.atomics): Ditto
+        (tests.atomicsNull): Ditto
+        (tests.pointerEquality): Test pointer equality
+        (tests.standardLibraryDevicePointers):
+        (tests.devicePtrPtr): Deleted.
+        (tests.threadgroupPtrPtr): Deleted.
+        (tests.constantPtrPtr): Deleted.
+        * WebGPUShadingLanguageRI/index.html:
+
</ins><span class="cx"> 2018-09-28  Jiewen Tan  <jiewen_tan@apple.com>
</span><span class="cx"> 
</span><span class="cx">         [WebAuthN] Polish WebAuthN auto-test environment
</span></span></pre></div>
<a id="trunkToolsWebGPUShadingLanguageRIAlljs"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebGPUShadingLanguageRI/All.js (236627 => 236628)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebGPUShadingLanguageRI/All.js       2018-09-29 00:22:08 UTC (rev 236627)
+++ trunk/Tools/WebGPUShadingLanguageRI/All.js  2018-09-29 00:48:34 UTC (rev 236628)
</span><span class="lines">@@ -108,8 +108,7 @@
</span><span class="cx"> load("IntLiteral.js");
</span><span class="cx"> load("IntLiteralType.js");
</span><span class="cx"> load("Intrinsics.js");
</span><del>-load("LateCheckAndLayoutBuffers.js");
-load("LateChecker.js");
</del><ins>+load("LayoutBuffers.js");
</ins><span class="cx"> load("Lexer.js");
</span><span class="cx"> load("LexerToken.js");
</span><span class="cx"> load("LiteralTypeChecker.js");
</span></span></pre></div>
<a id="trunkToolsWebGPUShadingLanguageRIAllocateAtEntryPointsjs"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebGPUShadingLanguageRI/AllocateAtEntryPoints.js (236627 => 236628)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebGPUShadingLanguageRI/AllocateAtEntryPoints.js     2018-09-29 00:22:08 UTC (rev 236627)
+++ trunk/Tools/WebGPUShadingLanguageRI/AllocateAtEntryPoints.js        2018-09-29 00:48:34 UTC (rev 236628)
</span><span class="lines">@@ -142,7 +142,7 @@
</span><span class="cx"> 
</span><span class="cx">             _addVariableDeclaration()
</span><span class="cx">             {
</span><del>-                this._variableDecl = new VariableDecl(func.origin, null, globalStructTypeRef, null);
</del><ins>+                this._variableDecl = new VariableDecl(func.origin, "global struct", globalStructTypeRef, null);
</ins><span class="cx">                 this.makeGlobalStructVariableRef = () => new MakePtrExpression(func.origin, VariableRef.wrap(this._variableDecl));
</span><span class="cx">                 func.body.statements.unshift(this._variableDecl);
</span><span class="cx">             }
</span></span></pre></div>
<a id="trunkToolsWebGPUShadingLanguageRICallExpressionjs"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebGPUShadingLanguageRI/CallExpression.js (236627 => 236628)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebGPUShadingLanguageRI/CallExpression.js    2018-09-29 00:22:08 UTC (rev 236627)
+++ trunk/Tools/WebGPUShadingLanguageRI/CallExpression.js       2018-09-29 00:48:34 UTC (rev 236628)
</span><span class="lines">@@ -102,6 +102,11 @@
</span><span class="cx">             func = this._resolveWithOperatorAnderIndexer(program);
</span><span class="cx">         else if (this.name == "operator.length")
</span><span class="cx">             func = this._resolveWithOperatorLength(program);
</span><ins>+        else if (this.name == "operator==" && this.argumentTypes.length == 2
+            && (this.argumentTypes[0] instanceof NullType || this.argumentTypes[0] instanceof ReferenceType)
+            && (this.argumentTypes[1] instanceof NullType || this.argumentTypes[1] instanceof ReferenceType)
+            && this.argumentTypes[0].equals(this.argumentTypes[1]))
+                func = this._resolveWithReferenceComparator(program);
</ins><span class="cx">         else
</span><span class="cx">             return null;
</span><span class="cx"> 
</span><span class="lines">@@ -119,17 +124,17 @@
</span><span class="cx">         const addressSpace = arrayRefType.addressSpace;
</span><span class="cx"> 
</span><span class="cx">         // The later checkLiteralTypes stage will verify that the literal can be represented as a uint.
</span><del>-        const uintType = TypeRef.wrap(program.types.get("uint"));
</del><ins>+        const uintType = TypeRef.wrap(program.intrinsics.uint);
</ins><span class="cx">         indexType.type = uintType;
</span><span class="cx"> 
</span><span class="cx">         const elementType = this.argumentTypes[0].elementType;
</span><del>-        this.resultType = this._returnType = TypeRef.wrap(new PtrType(this.origin, addressSpace, TypeRef.wrap(elementType)))
</del><ins>+        this.resultType = TypeRef.wrap(new PtrType(this.origin, addressSpace, TypeRef.wrap(elementType)))
</ins><span class="cx"> 
</span><del>-        let arrayRefAccessor = new OperatorAnderIndexer(this.returnType.toString(), addressSpace);
</del><ins>+        let arrayRefAccessor = new OperatorAnderIndexer(this.resultType.toString(), addressSpace);
</ins><span class="cx">         const func = new NativeFunc(this.origin, "operator&[]", this.resultType, [
</span><span class="cx">             new FuncParameter(this.origin, null, arrayRefType),
</span><span class="cx">             new FuncParameter(this.origin, null, uintType)
</span><del>-        ], false);
</del><ins>+        ]);
</ins><span class="cx"> 
</span><span class="cx">         arrayRefAccessor.instantiateImplementation(func);
</span><span class="cx"> 
</span><span class="lines">@@ -138,14 +143,14 @@
</span><span class="cx"> 
</span><span class="cx">     _resolveWithOperatorLength(program)
</span><span class="cx">     {
</span><del>-        this.resultType = this._returnType = TypeRef.wrap(program.types.get("uint"));
</del><ins>+        this.resultType = TypeRef.wrap(program.intrinsics.uint);
</ins><span class="cx"> 
</span><span class="cx">         if (this.argumentTypes[0].isArray) {
</span><span class="cx">             const arrayType = this.argumentTypes[0];
</span><span class="cx">             const func = new NativeFunc(this.origin, "operator.length", this.resultType, [
</span><span class="cx">                 new FuncParameter(this.origin, null, arrayType)
</span><del>-            ], false);
-            func.implementation = (args, node) => EPtr.box(arrayType.numElementsValue);
</del><ins>+            ]);
+            func.implementation = (args) => EPtr.box(arrayType.numElementsValue);
</ins><span class="cx">             return func;
</span><span class="cx">         } else if (this.argumentTypes[0].isArrayRef) {
</span><span class="cx">             const arrayRefType = this.argumentTypes[0];
</span><span class="lines">@@ -153,12 +158,38 @@
</span><span class="cx">             const operatorLength = new OperatorArrayRefLength(arrayRefType.toString(), addressSpace);
</span><span class="cx">             const func = new NativeFunc(this.origin, "operator.length", this.resultType, [
</span><span class="cx">                 new FuncParameter(this.origin, null, arrayRefType)
</span><del>-            ], false);
</del><ins>+            ]);
</ins><span class="cx">             operatorLength.instantiateImplementation(func);
</span><span class="cx">             return func;
</span><span class="cx">         } else
</span><span class="cx">             throw new WTypeError(this.origin.originString, `Expected ${this.argumentTypes[0]} to be array/array ref type for operator.length`);
</span><span class="cx">     }
</span><ins>+
+    _resolveWithReferenceComparator(program)
+    {
+        let argumentType = this.argumentTypes[0];
+        if (argumentType instanceof NullType)
+            argumentType = this.argumentTypes[1];
+        if (argumentType instanceof NullType) {
+            // We encountered "null == null".
+            // The type isn't observable, so we can pick whatever we want.
+            // FIXME: This can probably be generalized, using the "preferred type" infrastructure used by generic literals
+            argumentType = new PtrType(this.origin, "thread", program.intrinsics.int);
+        }
+        this.resultType = TypeRef.wrap(program.intrinsics.bool);
+        const func = new NativeFunc(this.origin, "operator==", this.resultType, [
+            new FuncParameter(this.origin, null, argumentType),
+            new FuncParameter(this.origin, null, argumentType)
+        ]);
+        func.implementation = ([lhs, rhs]) => {
+            let left = lhs.loadValue();
+            let right = rhs.loadValue();
+            if (left && right)
+                return EPtr.box(left.equals(right));
+            return EPtr.box(left == right);
+        };
+        return func;
+    }
</ins><span class="cx">     
</span><span class="cx">     resolveToOverload(overload)
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkToolsWebGPUShadingLanguageRIEArrayRefjs"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebGPUShadingLanguageRI/EArrayRef.js (236627 => 236628)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebGPUShadingLanguageRI/EArrayRef.js 2018-09-29 00:22:08 UTC (rev 236627)
+++ trunk/Tools/WebGPUShadingLanguageRI/EArrayRef.js    2018-09-29 00:48:34 UTC (rev 236628)
</span><span class="lines">@@ -33,6 +33,11 @@
</span><span class="cx">     
</span><span class="cx">     get ptr() { return this._ptr; }
</span><span class="cx">     get length() { return this._length; }
</span><ins>+
+    equals(other)
+    {
+        return this.ptr.equals(other.ptr) && this.length == other.length;
+    }
</ins><span class="cx">     
</span><span class="cx">     toString()
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkToolsWebGPUShadingLanguageRIEPtrjs"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebGPUShadingLanguageRI/EPtr.js (236627 => 236628)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebGPUShadingLanguageRI/EPtr.js      2018-09-29 00:22:08 UTC (rev 236627)
+++ trunk/Tools/WebGPUShadingLanguageRI/EPtr.js 2018-09-29 00:48:34 UTC (rev 236628)
</span><span class="lines">@@ -79,6 +79,11 @@
</span><span class="cx">         for (let i = size; i--;)
</span><span class="cx">             this.set(i, other.get(i));
</span><span class="cx">     }
</span><ins>+
+    equals(other)
+    {
+        return this.buffer == other.buffer && this.offset == other.offset;
+    }
</ins><span class="cx">     
</span><span class="cx">     toString()
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkToolsWebGPUShadingLanguageRILateCheckAndLayoutBuffersjs"></a>
<div class="delfile"><h4>Deleted: trunk/Tools/WebGPUShadingLanguageRI/LateCheckAndLayoutBuffers.js (236627 => 236628)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebGPUShadingLanguageRI/LateCheckAndLayoutBuffers.js 2018-09-29 00:22:08 UTC (rev 236627)
+++ trunk/Tools/WebGPUShadingLanguageRI/LateCheckAndLayoutBuffers.js    2018-09-29 00:48:34 UTC (rev 236628)
</span><span class="lines">@@ -1,37 +0,0 @@
</span><del>-/*
- * Copyright (C) 2018 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-"use strict";
-
-function lateCheckAndLayoutBuffers(program)
-{
-    for (let funcList of program.functions.values()) {
-        for (let func of funcList) {
-            if (func.isNative)
-                continue;
-            func.visit(new LateChecker());
-            func.visit(new EBufferBuilder());
-        }
-    }
-}
</del><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkToolsWebGPUShadingLanguageRILateCheckerjs"></a>
<div class="delfile"><h4>Deleted: trunk/Tools/WebGPUShadingLanguageRI/LateChecker.js (236627 => 236628)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebGPUShadingLanguageRI/LateChecker.js       2018-09-29 00:22:08 UTC (rev 236627)
+++ trunk/Tools/WebGPUShadingLanguageRI/LateChecker.js  2018-09-29 00:48:34 UTC (rev 236628)
</span><span class="lines">@@ -1,37 +0,0 @@
</span><del>-/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
- */
-"use strict";
-
-class LateChecker extends Visitor {
-    visitReferenceType(node)
-    {
-        if (node.addressSpace == "thread")
-            return;
-        
-        if (!node.elementType.isPrimitive)
-            throw new WTypeError(node.origin.originString, "Illegal pointer to non-primitive type: " + node);
-    }
-}
-
</del></span></pre></div>
<a id="trunkToolsWebGPUShadingLanguageRILayoutBuffersjsfromrev236627trunkToolsWebGPUShadingLanguageRILateCheckAndLayoutBuffersjs"></a>
<div class="copfile"><h4>Copied: trunk/Tools/WebGPUShadingLanguageRI/LayoutBuffers.js (from rev 236627, trunk/Tools/WebGPUShadingLanguageRI/LateCheckAndLayoutBuffers.js) (0 => 236628)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebGPUShadingLanguageRI/LayoutBuffers.js                             (rev 0)
+++ trunk/Tools/WebGPUShadingLanguageRI/LayoutBuffers.js        2018-09-29 00:48:34 UTC (rev 236628)
</span><span class="lines">@@ -0,0 +1,36 @@
</span><ins>+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+"use strict";
+
+function layoutBuffers(program)
+{
+    for (let funcList of program.functions.values()) {
+        for (let func of funcList) {
+            if (func.isNative)
+                continue;
+            func.visit(new EBufferBuilder());
+        }
+    }
+}
</ins></span></pre></div>
<a id="trunkToolsWebGPUShadingLanguageRIMetalWHLSLTestsWHLSLTestsxcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/WHLSL Tests.xcodeproj/project.pbxproj (236627 => 236628)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/WHLSL Tests.xcodeproj/project.pbxproj      2018-09-29 00:22:08 UTC (rev 236627)
+++ trunk/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/WHLSL Tests.xcodeproj/project.pbxproj 2018-09-29 00:48:34 UTC (rev 236628)
</span><span class="lines">@@ -83,7 +83,6 @@
</span><span class="cx">          E92D115A20F7060E00D776B2 /* IntLiteral.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D0FE420F56DDD00D776B2 /* IntLiteral.js */; };
</span><span class="cx">          E92D115B20F7060E00D776B2 /* IntLiteralType.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D0FE520F56DDD00D776B2 /* IntLiteralType.js */; };
</span><span class="cx">          E92D115C20F7060E00D776B2 /* Intrinsics.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D0FE720F56DDD00D776B2 /* Intrinsics.js */; };
</span><del>-               E92D115D20F7060E00D776B2 /* LateChecker.js in Resources */ = {isa = PBXBuildFile; fileRef = E9FCEB6420F56DA5009B3629 /* LateChecker.js */; };
</del><span class="cx">           E92D115E20F7060E00D776B2 /* Lexer.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D0FF120F56DEC00D776B2 /* Lexer.js */; };
</span><span class="cx">          E92D115F20F7060E00D776B2 /* LexerToken.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D0FF020F56DEB00D776B2 /* LexerToken.js */; };
</span><span class="cx">          E92D116020F7060E00D776B2 /* LiteralTypeChecker.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D0FF220F56DEC00D776B2 /* LiteralTypeChecker.js */; };
</span><span class="lines">@@ -186,7 +185,7 @@
</span><span class="cx">          E9D7CB98214B824200F1C918 /* MSLBackend.js in Resources */ = {isa = PBXBuildFile; fileRef = E9D7CB95214B824200F1C918 /* MSLBackend.js */; };
</span><span class="cx">          E9D7CB99214B824200F1C918 /* MSLConstexprEmitter.js in Resources */ = {isa = PBXBuildFile; fileRef = E9D7CB96214B824200F1C918 /* MSLConstexprEmitter.js */; };
</span><span class="cx">          E9D7CBA0214B82B800F1C918 /* Texture.js in Resources */ = {isa = PBXBuildFile; fileRef = E9D7CB9A214B82B700F1C918 /* Texture.js */; };
</span><del>-               E9D7CBA1214B82B800F1C918 /* LateCheckAndLayoutBuffers.js in Resources */ = {isa = PBXBuildFile; fileRef = E9D7CB9B214B82B700F1C918 /* LateCheckAndLayoutBuffers.js */; };
</del><ins>+                E9D7CBA1214B82B800F1C918 /* LayoutBuffers.js in Resources */ = {isa = PBXBuildFile; fileRef = E9D7CB9B214B82B700F1C918 /* LayoutBuffers.js */; };
</ins><span class="cx">           E9D7CBA2214B82B800F1C918 /* Casts.js in Resources */ = {isa = PBXBuildFile; fileRef = E9D7CB9C214B82B700F1C918 /* Casts.js */; };
</span><span class="cx">          E9D7CBA3214B82B800F1C918 /* Sampler.js in Resources */ = {isa = PBXBuildFile; fileRef = E9D7CB9D214B82B800F1C918 /* Sampler.js */; };
</span><span class="cx">          E9D7CBA4214B82B800F1C918 /* TextureOperations.js in Resources */ = {isa = PBXBuildFile; fileRef = E9D7CB9E214B82B800F1C918 /* TextureOperations.js */; };
</span><span class="lines">@@ -405,7 +404,7 @@
</span><span class="cx">          E9D7CB95214B824200F1C918 /* MSLBackend.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = MSLBackend.js; path = ../../MSLBackend.js; sourceTree = "<group>"; };
</span><span class="cx">          E9D7CB96214B824200F1C918 /* MSLConstexprEmitter.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = MSLConstexprEmitter.js; path = ../../MSLConstexprEmitter.js; sourceTree = "<group>"; };
</span><span class="cx">          E9D7CB9A214B82B700F1C918 /* Texture.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Texture.js; path = ../../../Texture.js; sourceTree = "<group>"; };
</span><del>-               E9D7CB9B214B82B700F1C918 /* LateCheckAndLayoutBuffers.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = LateCheckAndLayoutBuffers.js; path = ../../../LateCheckAndLayoutBuffers.js; sourceTree = "<group>"; };
</del><ins>+                E9D7CB9B214B82B700F1C918 /* LayoutBuffers.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = LayoutBuffers.js; path = ../../../LayoutBuffers.js; sourceTree = "<group>"; };
</ins><span class="cx">           E9D7CB9C214B82B700F1C918 /* Casts.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Casts.js; path = ../../../Casts.js; sourceTree = "<group>"; };
</span><span class="cx">          E9D7CB9D214B82B800F1C918 /* Sampler.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Sampler.js; path = ../../../Sampler.js; sourceTree = "<group>"; };
</span><span class="cx">          E9D7CB9E214B82B800F1C918 /* TextureOperations.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = TextureOperations.js; path = ../../../TextureOperations.js; sourceTree = "<group>"; };
</span><span class="lines">@@ -416,7 +415,6 @@
</span><span class="cx">          E9FCEB5A20F56D93009B3629 /* ForLoop.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = ForLoop.js; path = ../../../ForLoop.js; sourceTree = "<group>"; };
</span><span class="cx">          E9FCEB5B20F56D93009B3629 /* Field.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = Field.js; path = ../../../Field.js; sourceTree = "<group>"; };
</span><span class="cx">          E9FCEB6320F56DA4009B3629 /* IndexExpression.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = IndexExpression.js; path = ../../../IndexExpression.js; sourceTree = "<group>"; };
</span><del>-               E9FCEB6420F56DA5009B3629 /* LateChecker.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = LateChecker.js; path = ../../../LateChecker.js; sourceTree = "<group>"; };
</del><span class="cx">           E9FCEB6520F56DA5009B3629 /* InferTypesForCall.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = InferTypesForCall.js; path = ../../../InferTypesForCall.js; sourceTree = "<group>"; };
</span><span class="cx">          E9FCEB6620F56DA5009B3629 /* Inline.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; name = Inline.js; path = ../../../Inline.js; sourceTree = "<group>"; };
</span><span class="cx"> /* End PBXFileReference section */
</span><span class="lines">@@ -628,8 +626,7 @@
</span><span class="cx">                          E92D0FE420F56DDD00D776B2 /* IntLiteral.js */,
</span><span class="cx">                          E92D0FE520F56DDD00D776B2 /* IntLiteralType.js */,
</span><span class="cx">                          E92D0FE720F56DDD00D776B2 /* Intrinsics.js */,
</span><del>-                               E9D7CB9B214B82B700F1C918 /* LateCheckAndLayoutBuffers.js */,
-                               E9FCEB6420F56DA5009B3629 /* LateChecker.js */,
</del><ins>+                                E9D7CB9B214B82B700F1C918 /* LayoutBuffers.js */,
</ins><span class="cx">                           E92D0FF120F56DEC00D776B2 /* Lexer.js */,
</span><span class="cx">                          E92D0FF020F56DEB00D776B2 /* LexerToken.js */,
</span><span class="cx">                          E92D0FF220F56DEC00D776B2 /* LiteralTypeChecker.js */,
</span><span class="lines">@@ -885,8 +882,7 @@
</span><span class="cx">                          E92D115B20F7060E00D776B2 /* IntLiteralType.js in Resources */,
</span><span class="cx">                          E92D115C20F7060E00D776B2 /* Intrinsics.js in Resources */,
</span><span class="cx">                          E906B04621139B7700AD1C5E /* Julia.whlsl in Resources */,
</span><del>-                               E9D7CBA1214B82B800F1C918 /* LateCheckAndLayoutBuffers.js in Resources */,
-                               E92D115D20F7060E00D776B2 /* LateChecker.js in Resources */,
</del><ins>+                                E9D7CBA1214B82B800F1C918 /* LayoutBuffers.js in Resources */,
</ins><span class="cx">                           E92D115E20F7060E00D776B2 /* Lexer.js in Resources */,
</span><span class="cx">                          E92D115F20F7060E00D776B2 /* LexerToken.js in Resources */,
</span><span class="cx">                          E92D116020F7060E00D776B2 /* LiteralTypeChecker.js in Resources */,
</span></span></pre></div>
<a id="trunkToolsWebGPUShadingLanguageRINativeFuncjs"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebGPUShadingLanguageRI/NativeFunc.js (236627 => 236628)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebGPUShadingLanguageRI/NativeFunc.js        2018-09-29 00:22:08 UTC (rev 236627)
+++ trunk/Tools/WebGPUShadingLanguageRI/NativeFunc.js   2018-09-29 00:48:34 UTC (rev 236628)
</span><span class="lines">@@ -25,7 +25,7 @@
</span><span class="cx"> "use strict";
</span><span class="cx"> 
</span><span class="cx"> class NativeFunc extends Func {
</span><del>-    constructor(origin, name, returnType, parameters, isCast, stage = null)
</del><ins>+    constructor(origin, name, returnType, parameters, isCast = false, stage = null)
</ins><span class="cx">     {
</span><span class="cx">         super(origin, name, returnType, parameters, isCast);
</span><span class="cx">         this._stage = stage;
</span></span></pre></div>
<a id="trunkToolsWebGPUShadingLanguageRIOperatorArrayRefLengthjs"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebGPUShadingLanguageRI/OperatorArrayRefLength.js (236627 => 236628)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebGPUShadingLanguageRI/OperatorArrayRefLength.js    2018-09-29 00:22:08 UTC (rev 236627)
+++ trunk/Tools/WebGPUShadingLanguageRI/OperatorArrayRefLength.js       2018-09-29 00:48:34 UTC (rev 236628)
</span><span class="lines">@@ -41,7 +41,7 @@
</span><span class="cx"> 
</span><span class="cx">     instantiateImplementation(func)
</span><span class="cx">     {
</span><del>-        func.implementation = ([ref], node) => {
</del><ins>+        func.implementation = ([ref]) => {
</ins><span class="cx">             ref = ref.loadValue();
</span><span class="cx">             if (!ref)
</span><span class="cx">                 return EPtr.box(0);
</span><span class="lines">@@ -49,4 +49,4 @@
</span><span class="cx">         };
</span><span class="cx">         func.implementationData = this;
</span><span class="cx">     }
</span><del>-}
</del><span class="cx">\ No newline at end of file
</span><ins>+}
</ins></span></pre></div>
<a id="trunkToolsWebGPUShadingLanguageRIPreparejs"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebGPUShadingLanguageRI/Prepare.js (236627 => 236628)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebGPUShadingLanguageRI/Prepare.js   2018-09-29 00:22:08 UTC (rev 236627)
+++ trunk/Tools/WebGPUShadingLanguageRI/Prepare.js      2018-09-29 00:48:34 UTC (rev 236628)
</span><span class="lines">@@ -32,13 +32,13 @@
</span><span class="cx">             let firstLineOfStandardLibrary = 28; // See StandardLibrary.js.
</span><span class="cx">             parse(standardProgram, "/internal/stdlib", "native", firstLineOfStandardLibrary - 1, standardLibrary);
</span><span class="cx">         }
</span><del>-        
</del><ins>+
</ins><span class="cx">         let program = cloneProgram(standardProgram);
</span><span class="cx">         if (arguments.length) {
</span><span class="cx">             parse(program, origin, "user", lineNumberOffset, text);
</span><span class="cx">             program = programWithUnnecessaryThingsRemoved(program);
</span><span class="cx">         }
</span><del>-        
</del><ins>+
</ins><span class="cx">         foldConstexprs(program);
</span><span class="cx"> 
</span><span class="cx">         let nameResolver = createNameResolver(program);
</span><span class="lines">@@ -69,7 +69,7 @@
</span><span class="cx">         findHighZombies(program);
</span><span class="cx">         allocateAtEntryPoints(program);
</span><span class="cx">         program.visit(new StructLayoutBuilder());
</span><del>-        lateCheckAndLayoutBuffers(program);
</del><ins>+        layoutBuffers(program);
</ins><span class="cx">         checkNativeFuncStages(program);
</span><span class="cx">         if (shouldInline)
</span><span class="cx">             inline(program);
</span></span></pre></div>
<a id="trunkToolsWebGPUShadingLanguageRISPIRVhtml"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebGPUShadingLanguageRI/SPIRV.html (236627 => 236628)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebGPUShadingLanguageRI/SPIRV.html   2018-09-29 00:22:08 UTC (rev 236627)
+++ trunk/Tools/WebGPUShadingLanguageRI/SPIRV.html      2018-09-29 00:48:34 UTC (rev 236628)
</span><span class="lines">@@ -91,8 +91,7 @@
</span><span class="cx">     <script src="IntLiteral.js"></script>
</span><span class="cx">     <script src="IntLiteralType.js"></script>
</span><span class="cx">     <script src="Intrinsics.js"></script>
</span><del>-    <script src="LateCheckAndLayoutBuffers.js"></script>
-    <script src="LateChecker.js"></script>
</del><ins>+    <script src="LayoutBuffers.js"></script>
</ins><span class="cx">     <script src="Lexer.js"></script>
</span><span class="cx">     <script src="LexerToken.js"></script>
</span><span class="cx">     <script src="LiteralTypeChecker.js"></script>
</span></span></pre></div>
<a id="trunkToolsWebGPUShadingLanguageRITesthtml"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebGPUShadingLanguageRI/Test.html (236627 => 236628)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebGPUShadingLanguageRI/Test.html    2018-09-29 00:22:08 UTC (rev 236627)
+++ trunk/Tools/WebGPUShadingLanguageRI/Test.html       2018-09-29 00:48:34 UTC (rev 236628)
</span><span class="lines">@@ -85,8 +85,7 @@
</span><span class="cx"> <script src="IntLiteral.js"></script>
</span><span class="cx"> <script src="IntLiteralType.js"></script>
</span><span class="cx"> <script src="Intrinsics.js"></script>
</span><del>-<script src="LateChecker.js"></script>
-<script src="LateCheckAndLayoutBuffers.js"></script>
</del><ins>+<script src="LayoutBuffers.js"></script>
</ins><span class="cx"> <script src="Lexer.js"></script>
</span><span class="cx"> <script src="LexerToken.js"></script>
</span><span class="cx"> <script src="LiteralTypeChecker.js"></script>
</span></span></pre></div>
<a id="trunkToolsWebGPUShadingLanguageRITestjs"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebGPUShadingLanguageRI/Test.js (236627 => 236628)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebGPUShadingLanguageRI/Test.js      2018-09-29 00:22:08 UTC (rev 236627)
+++ trunk/Tools/WebGPUShadingLanguageRI/Test.js 2018-09-29 00:48:34 UTC (rev 236628)
</span><span class="lines">@@ -343,11 +343,11 @@
</span><span class="cx">         {
</span><span class="cx">             return x < 3 ? 4 : 5;
</span><span class="cx">         }
</span><del>-        test int baz(int x)
</del><ins>+        test int bar(int x)
</ins><span class="cx">         {
</span><span class="cx">             return x < 10 ? 11 : x < 12 ? 14 : 15;
</span><span class="cx">         }
</span><del>-        test int quux(int x)
</del><ins>+        test int baz(int x)
</ins><span class="cx">         {
</span><span class="cx">             return 3 < 4 ? x : 5;
</span><span class="cx">         }
</span><span class="lines">@@ -354,13 +354,13 @@
</span><span class="cx">     `);
</span><span class="cx">     checkInt(program, callFunction(program, "foo", [makeInt(program, 767)]), 5);
</span><span class="cx">     checkInt(program, callFunction(program, "foo", [makeInt(program, 2)]), 4);
</span><del>-    checkInt(program, callFunction(program, "baz", [makeInt(program, 8)]), 11);
-    checkInt(program, callFunction(program, "baz", [makeInt(program, 9)]), 11);
-    checkInt(program, callFunction(program, "baz", [makeInt(program, 10)]), 14);
-    checkInt(program, callFunction(program, "baz", [makeInt(program, 11)]), 14);
-    checkInt(program, callFunction(program, "baz", [makeInt(program, 12)]), 15);
-    checkInt(program, callFunction(program, "baz", [makeInt(program, 13)]), 15);
-    checkInt(program, callFunction(program, "quux", [makeInt(program, 14)]), 14);
</del><ins>+    checkInt(program, callFunction(program, "bar", [makeInt(program, 8)]), 11);
+    checkInt(program, callFunction(program, "bar", [makeInt(program, 9)]), 11);
+    checkInt(program, callFunction(program, "bar", [makeInt(program, 10)]), 14);
+    checkInt(program, callFunction(program, "bar", [makeInt(program, 11)]), 14);
+    checkInt(program, callFunction(program, "bar", [makeInt(program, 12)]), 15);
+    checkInt(program, callFunction(program, "bar", [makeInt(program, 13)]), 15);
+    checkInt(program, callFunction(program, "baz", [makeInt(program, 14)]), 14);
</ins><span class="cx">     checkFail(
</span><span class="cx">         () => doPrep(`
</span><span class="cx">             int foo()
</span><span class="lines">@@ -1384,7 +1384,7 @@
</span><span class="cx"> tests.break = function()
</span><span class="cx"> {
</span><span class="cx">     let program = doPrep(`
</span><del>-        test int foo(int x)
</del><ins>+        test int foo1(int x)
</ins><span class="cx">         {
</span><span class="cx">             while (true) {
</span><span class="cx">                 x = x * 2;
</span><span class="lines">@@ -1393,11 +1393,7 @@
</span><span class="cx">             }
</span><span class="cx">             return x;
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), 8);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 10)]), 20);
-    program = doPrep(`
-        test int foo(int x)
</del><ins>+        test int foo2(int x)
</ins><span class="cx">         {
</span><span class="cx">             while (true) {
</span><span class="cx">                 while (true) {
</span><span class="lines">@@ -1409,11 +1405,38 @@
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">             return x;
</span><del>-
</del><span class="cx">         }
</span><ins>+        test int foo3(int x)
+        {
+            while (true) {
+                if (x == 7) {
+                    break;
+                }
+                x = x + 1;
+            }
+            return x;
+        }
+        test int foo4(int x)
+        {
+            while (true) {
+                break;
+            }
+            return x;
+        }
+        test int foo5()
+        {
+            while (true) {
+                return 7;
+            }
+        }
</ins><span class="cx">     `);
</span><del>-    checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), 7);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 10)]), 19);
</del><ins>+    checkInt(program, callFunction(program, "foo1", [makeInt(program, 1)]), 8);
+    checkInt(program, callFunction(program, "foo1", [makeInt(program, 10)]), 20);
+    checkInt(program, callFunction(program, "foo2", [makeInt(program, 1)]), 7);
+    checkInt(program, callFunction(program, "foo2", [makeInt(program, 10)]), 19);
+    checkInt(program, callFunction(program, "foo3", [makeInt(program, 1)]), 7);
+    checkInt(program, callFunction(program, "foo4", [makeInt(program, 1)]), 1);
+    checkInt(program, callFunction(program, "foo5", []), 7);
</ins><span class="cx">     checkFail(
</span><span class="cx">         () => doPrep(`
</span><span class="cx">             int foo(int x)
</span><span class="lines">@@ -1437,38 +1460,6 @@
</span><span class="cx">             }
</span><span class="cx">         `),
</span><span class="cx">         (e) => e instanceof WTypeError);
</span><del>-    program = doPrep(`
-            test int foo(int x)
-            {
-                while (true) {
-                    if (x == 7) {
-                        break;
-                    }
-                    x = x + 1;
-                }
-                return x;
-            }
-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), 7);
-    program = doPrep(`
-            test int foo(int x)
-            {
-                while (true) {
-                    break;
-                }
-                return x;
-            }
-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), 1);
-    program = doPrep(`
-            test int foo()
-            {
-                while (true) {
-                    return 7;
-                }
-            }
-    `);
-    checkInt(program, callFunction(program, "foo", []), 7);
</del><span class="cx">     checkFail(
</span><span class="cx">         () => doPrep(`
</span><span class="cx">             test int foo(int x)
</span><span class="lines">@@ -1513,7 +1504,7 @@
</span><span class="cx"> tests.doWhile = function()
</span><span class="cx"> {
</span><span class="cx">     let program = doPrep(`
</span><del>-        test int foo(int x)
</del><ins>+        test int foo1(int x)
</ins><span class="cx">         {
</span><span class="cx">             int y = 7;
</span><span class="cx">             do {
</span><span class="lines">@@ -1522,11 +1513,7 @@
</span><span class="cx">             } while (x < 10);
</span><span class="cx">             return y;
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), 8);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 11)]), 8);
-    program = doPrep(`
-        test int foo(int x)
</del><ins>+        test int foo2(int x)
</ins><span class="cx">         {
</span><span class="cx">             int y = 7;
</span><span class="cx">             do {
</span><span class="lines">@@ -1535,10 +1522,7 @@
</span><span class="cx">             } while (y == 7);
</span><span class="cx">             return y;
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), 8);
-    program = doPrep(`
-        test int foo(int x)
</del><ins>+        test int foo3(int x)
</ins><span class="cx">         {
</span><span class="cx">             int sum = 0;
</span><span class="cx">             do {
</span><span class="lines">@@ -1552,13 +1536,16 @@
</span><span class="cx">             return sum;
</span><span class="cx">         }
</span><span class="cx">     `);
</span><del>-    checkInt(program, callFunction(program, "foo", [makeInt(program, 9)]), 19);
</del><ins>+    checkInt(program, callFunction(program, "foo1", [makeInt(program, 1)]), 8);
+    checkInt(program, callFunction(program, "foo1", [makeInt(program, 11)]), 8);
+    checkInt(program, callFunction(program, "foo2", [makeInt(program, 1)]), 8);
+    checkInt(program, callFunction(program, "foo3", [makeInt(program, 9)]), 19);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> tests.forLoop = function()
</span><span class="cx"> {
</span><span class="cx">     let program = doPrep(`
</span><del>-        test int foo(int x)
</del><ins>+        test int foo1(int x)
</ins><span class="cx">         {
</span><span class="cx">             int sum = 0;
</span><span class="cx">             int i;
</span><span class="lines">@@ -1567,12 +1554,7 @@
</span><span class="cx">             }
</span><span class="cx">             return sum;
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 3);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 6);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 10);
-    program = doPrep(`
-        test int foo(int x)
</del><ins>+        test int foo2(int x)
</ins><span class="cx">         {
</span><span class="cx">             int sum = 0;
</span><span class="cx">             for (int i = 0; i < x; i = i + 1) {
</span><span class="lines">@@ -1580,12 +1562,7 @@
</span><span class="cx">             }
</span><span class="cx">             return sum;
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 3);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 6);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 10);
-    program = doPrep(`
-        test int foo(int x)
</del><ins>+        test int foo3(int x)
</ins><span class="cx">         {
</span><span class="cx">             int sum = 0;
</span><span class="cx">             int i = 100;
</span><span class="lines">@@ -1594,12 +1571,7 @@
</span><span class="cx">             }
</span><span class="cx">             return sum;
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 3);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 6);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 10);
-    program = doPrep(`
-        test int foo(int x)
</del><ins>+        test int foo4(int x)
</ins><span class="cx">         {
</span><span class="cx">             int sum = 0;
</span><span class="cx">             for (int i = 0; i < x; i = i + 1) {
</span><span class="lines">@@ -1609,13 +1581,7 @@
</span><span class="cx">             }
</span><span class="cx">             return sum;
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 3);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 6);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 6);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 11);
-    program = doPrep(`
-        test int foo(int x)
</del><ins>+        test int foo5(int x)
</ins><span class="cx">         {
</span><span class="cx">             int sum = 0;
</span><span class="cx">             for (int i = 0; i < x; i = i + 1) {
</span><span class="lines">@@ -1625,14 +1591,7 @@
</span><span class="cx">             }
</span><span class="cx">             return sum;
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 3);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 6);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 10);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 10);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 10);
-    program = doPrep(`
-        test int foo(int x)
</del><ins>+        test int foo6(int x)
</ins><span class="cx">         {
</span><span class="cx">             int sum = 0;
</span><span class="cx">             for (int i = 0; ; i = i + 1) {
</span><span class="lines">@@ -1642,14 +1601,7 @@
</span><span class="cx">             }
</span><span class="cx">             return sum;
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 3);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 6);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 10);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 15);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 21);
-    program = doPrep(`
-        test int foo(int x)
</del><ins>+        test int foo7(int x)
</ins><span class="cx">         {
</span><span class="cx">             int sum = 0;
</span><span class="cx">             int i = 0;
</span><span class="lines">@@ -1660,14 +1612,7 @@
</span><span class="cx">             }
</span><span class="cx">             return sum;
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 3);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 6);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 10);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 15);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 21);
-    program = doPrep(`
-        test int foo(int x)
</del><ins>+        test int foo8(int x)
</ins><span class="cx">         {
</span><span class="cx">             int sum = 0;
</span><span class="cx">             int i = 0;
</span><span class="lines">@@ -1679,12 +1624,62 @@
</span><span class="cx">             }
</span><span class="cx">             return sum;
</span><span class="cx">         }
</span><ins>+        test int foo9(int x)
+        {
+            for ( ; ; ) {
+                return 7;
+            }
+        }
+        test int foo10(int x)
+        {
+            for ( ; true; ) {
+                return 7;
+            }
+        }
</ins><span class="cx">     `);
</span><del>-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 3);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 6);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 10);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 15);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 21);
</del><ins>+    checkInt(program, callFunction(program, "foo1", [makeInt(program, 3)]), 3);
+    checkInt(program, callFunction(program, "foo1", [makeInt(program, 4)]), 6);
+    checkInt(program, callFunction(program, "foo1", [makeInt(program, 5)]), 10);
+    checkInt(program, callFunction(program, "foo2", [makeInt(program, 3)]), 3);
+    checkInt(program, callFunction(program, "foo2", [makeInt(program, 4)]), 6);
+    checkInt(program, callFunction(program, "foo2", [makeInt(program, 5)]), 10);
+    checkInt(program, callFunction(program, "foo3", [makeInt(program, 3)]), 3);
+    checkInt(program, callFunction(program, "foo3", [makeInt(program, 4)]), 6);
+    checkInt(program, callFunction(program, "foo3", [makeInt(program, 5)]), 10);
+    checkInt(program, callFunction(program, "foo4", [makeInt(program, 3)]), 3);
+    checkInt(program, callFunction(program, "foo4", [makeInt(program, 4)]), 6);
+    checkInt(program, callFunction(program, "foo4", [makeInt(program, 5)]), 6);
+    checkInt(program, callFunction(program, "foo4", [makeInt(program, 6)]), 11);
+    checkInt(program, callFunction(program, "foo5", [makeInt(program, 3)]), 3);
+    checkInt(program, callFunction(program, "foo5", [makeInt(program, 4)]), 6);
+    checkInt(program, callFunction(program, "foo5", [makeInt(program, 5)]), 10);
+    checkInt(program, callFunction(program, "foo5", [makeInt(program, 6)]), 10);
+    checkInt(program, callFunction(program, "foo5", [makeInt(program, 7)]), 10);
+    checkInt(program, callFunction(program, "foo6", [makeInt(program, 3)]), 3);
+    checkInt(program, callFunction(program, "foo6", [makeInt(program, 4)]), 6);
+    checkInt(program, callFunction(program, "foo6", [makeInt(program, 5)]), 10);
+    checkInt(program, callFunction(program, "foo6", [makeInt(program, 6)]), 15);
+    checkInt(program, callFunction(program, "foo6", [makeInt(program, 7)]), 21);
+    checkInt(program, callFunction(program, "foo7", [makeInt(program, 3)]), 3);
+    checkInt(program, callFunction(program, "foo7", [makeInt(program, 4)]), 6);
+    checkInt(program, callFunction(program, "foo7", [makeInt(program, 5)]), 10);
+    checkInt(program, callFunction(program, "foo7", [makeInt(program, 6)]), 15);
+    checkInt(program, callFunction(program, "foo7", [makeInt(program, 7)]), 21);
+    checkInt(program, callFunction(program, "foo8", [makeInt(program, 3)]), 3);
+    checkInt(program, callFunction(program, "foo8", [makeInt(program, 4)]), 6);
+    checkInt(program, callFunction(program, "foo8", [makeInt(program, 5)]), 10);
+    checkInt(program, callFunction(program, "foo8", [makeInt(program, 6)]), 15);
+    checkInt(program, callFunction(program, "foo8", [makeInt(program, 7)]), 21);
+    checkInt(program, callFunction(program, "foo9", [makeInt(program, 3)]), 7);
+    checkInt(program, callFunction(program, "foo9", [makeInt(program, 4)]), 7);
+    checkInt(program, callFunction(program, "foo9", [makeInt(program, 5)]), 7);
+    checkInt(program, callFunction(program, "foo9", [makeInt(program, 6)]), 7);
+    checkInt(program, callFunction(program, "foo9", [makeInt(program, 7)]), 7);
+    checkInt(program, callFunction(program, "foo10", [makeInt(program, 3)]), 7);
+    checkInt(program, callFunction(program, "foo10", [makeInt(program, 4)]), 7);
+    checkInt(program, callFunction(program, "foo10", [makeInt(program, 5)]), 7);
+    checkInt(program, callFunction(program, "foo10", [makeInt(program, 6)]), 7);
+    checkInt(program, callFunction(program, "foo10", [makeInt(program, 7)]), 7);
</ins><span class="cx">     checkFail(
</span><span class="cx">         () => doPrep(`
</span><span class="cx">             void foo(int x)
</span><span class="lines">@@ -1696,19 +1691,6 @@
</span><span class="cx">             }
</span><span class="cx">         `),
</span><span class="cx">         (e) => e instanceof WTypeError);
</span><del>-    program = doPrep(`
-        test int foo(int x)
-        {
-            for ( ; ; ) {
-                return 7;
-            }
-        }
-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 7);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 7);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 7);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 7);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 7);
</del><span class="cx">     checkFail(
</span><span class="cx">         () => doPrep(`
</span><span class="cx">             int foo(int x)
</span><span class="lines">@@ -1719,19 +1701,6 @@
</span><span class="cx">             }
</span><span class="cx">         `),
</span><span class="cx">         (e) => e instanceof WTypeError);
</span><del>-    program = doPrep(`
-        test int foo(int x)
-        {
-            for ( ; true; ) {
-                return 7;
-            }
-        }
-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3)]), 7);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 4)]), 7);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 5)]), 7);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 7);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 7)]), 7);
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> tests.prefixPlusPlus = function()
</span><span class="lines">@@ -5828,42 +5797,6 @@
</span><span class="cx">     checkInt(program, callFunction(program, "foo", []), 13);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-tests.devicePtrPtr = function()
-{
-    checkFail(
-        () => doPrep(`
-            void foo()
-            {
-                device int** p;
-            }
-        `),
-        e => e instanceof WTypeError && e.message.indexOf("Illegal pointer to non-primitive type: int* device* device") != -1);
-}
-
-tests.threadgroupPtrPtr = function()
-{
-    checkFail(
-        () => doPrep(`
-            void foo()
-            {
-                threadgroup int** p;
-            }
-        `),
-        e => e instanceof WTypeError && e.message.indexOf("Illegal pointer to non-primitive type: int* threadgroup* threadgroup") != -1);
-}
-
-tests.constantPtrPtr = function()
-{
-    checkFail(
-        () => doPrep(`
-            void foo()
-            {
-                constant int** p;
-            }
-        `),
-        e => e instanceof WTypeError && e.message.indexOf("Illegal pointer to non-primitive type: int* constant* constant") != -1);
-}
-
</del><span class="cx"> tests.andReturnedArrayRef = function()
</span><span class="cx"> {
</span><span class="cx">     let program = doPrep(`
</span><span class="lines">@@ -6056,16 +5989,13 @@
</span><span class="cx"> tests.atomics = function()
</span><span class="cx"> {
</span><span class="cx">     let program = doPrep(`
</span><del>-        test int foo(int z) {
</del><ins>+        test int foo1(int z) {
</ins><span class="cx">             atomic_int x;
</span><span class="cx">             int result;
</span><span class="cx">             InterlockedAdd(&x, z, &result);
</span><span class="cx">             return result;
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 0);
-    program = doPrep(`
-        test int foo(int z) {
</del><ins>+        test int foo2(int z) {
</ins><span class="cx">             atomic_int x;
</span><span class="cx">             int result;
</span><span class="cx">             InterlockedAdd(&x, z, &result);
</span><span class="lines">@@ -6072,19 +6002,13 @@
</span><span class="cx">             InterlockedAdd(&x, z, &result);
</span><span class="cx">             return result;
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 6);
-    program = doPrep(`
-        test int foo(int z) {
</del><ins>+        test int foo3(int z) {
</ins><span class="cx">             atomic_int x;
</span><span class="cx">             int result;
</span><span class="cx">             InterlockedAdd(&x, z, &result);
</span><span class="cx">             return int(x);
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 6);
-    program = doPrep(`
-        test int foo(int z) {
</del><ins>+        test int foo4(int z) {
</ins><span class="cx">             atomic_int x;
</span><span class="cx">             int result;
</span><span class="cx">             InterlockedAdd(&x, z, &result);
</span><span class="lines">@@ -6091,19 +6015,13 @@
</span><span class="cx">             InterlockedAdd(&x, z, &result);
</span><span class="cx">             return int(x);
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 12);
-    program = doPrep(`
-        test uint foo(uint z) {
</del><ins>+        test uint foo5(uint z) {
</ins><span class="cx">             atomic_uint x;
</span><span class="cx">             uint result;
</span><span class="cx">             InterlockedAdd(&x, z, &result);
</span><span class="cx">             return result;
</span><span class="cx">         }
</span><del>-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 6)]), 0);
-    program = doPrep(`
-        test uint foo(uint z) {
</del><ins>+        test uint foo6(uint z) {
</ins><span class="cx">             atomic_uint x;
</span><span class="cx">             uint result;
</span><span class="cx">             InterlockedAdd(&x, z, &result);
</span><span class="lines">@@ -6110,19 +6028,13 @@
</span><span class="cx">             InterlockedAdd(&x, z, &result);
</span><span class="cx">             return result;
</span><span class="cx">         }
</span><del>-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 6)]), 6);
-    program = doPrep(`
-        test uint foo(uint z) {
</del><ins>+        test uint foo7(uint z) {
</ins><span class="cx">             atomic_uint x;
</span><span class="cx">             uint result;
</span><span class="cx">             InterlockedAdd(&x, z, &result);
</span><span class="cx">             return uint(x);
</span><span class="cx">         }
</span><del>-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 6)]), 6);
-    program = doPrep(`
-        test uint foo(uint z) {
</del><ins>+        test uint foo8(uint z) {
</ins><span class="cx">             atomic_uint x;
</span><span class="cx">             uint result;
</span><span class="cx">             InterlockedAdd(&x, z, &result);
</span><span class="lines">@@ -6129,10 +6041,7 @@
</span><span class="cx">             InterlockedAdd(&x, z, &result);
</span><span class="cx">             return uint(x);
</span><span class="cx">         }
</span><del>-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 6)]), 12);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
</del><ins>+        test uint foo9(uint x, uint y) {
</ins><span class="cx">             atomic_uint z;
</span><span class="cx">             uint result;
</span><span class="cx">             InterlockedAdd(&z, x, &result);
</span><span class="lines">@@ -6139,10 +6048,7 @@
</span><span class="cx">             InterlockedAnd(&z, y, &result);
</span><span class="cx">             return uint(z);
</span><span class="cx">         }
</span><del>-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 1);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
</del><ins>+        test uint foo10(uint x, uint y) {
</ins><span class="cx">             atomic_uint z;
</span><span class="cx">             uint result;
</span><span class="cx">             InterlockedAdd(&z, x, &result);
</span><span class="lines">@@ -6149,10 +6055,7 @@
</span><span class="cx">             InterlockedAnd(&z, y, &result);
</span><span class="cx">             return result;
</span><span class="cx">         }
</span><del>-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 3);
-    program = doPrep(`
-        test int foo(int x, int y) {
</del><ins>+        test int foo11(int x, int y) {
</ins><span class="cx">             atomic_int z;
</span><span class="cx">             int result;
</span><span class="cx">             InterlockedAdd(&z, x, &result);
</span><span class="lines">@@ -6159,10 +6062,7 @@
</span><span class="cx">             InterlockedAnd(&z, y, &result);
</span><span class="cx">             return int(z);
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 1);
-    program = doPrep(`
-        test int foo(int x, int y) {
</del><ins>+        test int foo12(int x, int y) {
</ins><span class="cx">             atomic_int z;
</span><span class="cx">             int result;
</span><span class="cx">             InterlockedAdd(&z, x, &result);
</span><span class="lines">@@ -6169,10 +6069,7 @@
</span><span class="cx">             InterlockedAnd(&z, y, &result);
</span><span class="cx">             return result;
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 3);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
</del><ins>+        test uint foo13(uint x, uint y) {
</ins><span class="cx">             atomic_uint z;
</span><span class="cx">             uint result;
</span><span class="cx">             InterlockedAdd(&z, x, &result);
</span><span class="lines">@@ -6179,10 +6076,7 @@
</span><span class="cx">             InterlockedExchange(&z, y, &result);
</span><span class="cx">             return uint(z);
</span><span class="cx">         }
</span><del>-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 5);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
</del><ins>+        test uint foo14(uint x, uint y) {
</ins><span class="cx">             atomic_uint z;
</span><span class="cx">             uint result;
</span><span class="cx">             InterlockedAdd(&z, x, &result);
</span><span class="lines">@@ -6189,10 +6083,7 @@
</span><span class="cx">             InterlockedExchange(&z, y, &result);
</span><span class="cx">             return result;
</span><span class="cx">         }
</span><del>-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 3);
-    program = doPrep(`
-        test int foo(int x, int y) {
</del><ins>+        test int foo15(int x, int y) {
</ins><span class="cx">             atomic_int z;
</span><span class="cx">             int result;
</span><span class="cx">             InterlockedAdd(&z, x, &result);
</span><span class="lines">@@ -6199,10 +6090,7 @@
</span><span class="cx">             InterlockedExchange(&z, y, &result);
</span><span class="cx">             return int(z);
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 5);
-    program = doPrep(`
-        test int foo(int x, int y) {
</del><ins>+        test int foo16(int x, int y) {
</ins><span class="cx">             atomic_int z;
</span><span class="cx">             int result;
</span><span class="cx">             InterlockedAdd(&z, x, &result);
</span><span class="lines">@@ -6209,10 +6097,7 @@
</span><span class="cx">             InterlockedExchange(&z, y, &result);
</span><span class="cx">             return result;
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 3);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
</del><ins>+        test uint foo17(uint x, uint y) {
</ins><span class="cx">             atomic_uint z;
</span><span class="cx">             uint result;
</span><span class="cx">             InterlockedAdd(&z, x, &result);
</span><span class="lines">@@ -6219,11 +6104,7 @@
</span><span class="cx">             InterlockedMax(&z, y, &result);
</span><span class="cx">             return uint(z);
</span><span class="cx">         }
</span><del>-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 5);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 5), makeUint(program, 3)]), 5);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
</del><ins>+        test uint foo18(uint x, uint y) {
</ins><span class="cx">             atomic_uint z;
</span><span class="cx">             uint result;
</span><span class="cx">             InterlockedAdd(&z, x, &result);
</span><span class="lines">@@ -6230,11 +6111,7 @@
</span><span class="cx">             InterlockedMax(&z, y, &result);
</span><span class="cx">             return result;
</span><span class="cx">         }
</span><del>-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 3);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 5), makeUint(program, 3)]), 5);
-    program = doPrep(`
-        test int foo(int x, int y) {
</del><ins>+        test int foo19(int x, int y) {
</ins><span class="cx">             atomic_int z;
</span><span class="cx">             int result;
</span><span class="cx">             InterlockedAdd(&z, x, &result);
</span><span class="lines">@@ -6241,11 +6118,7 @@
</span><span class="cx">             InterlockedMax(&z, y, &result);
</span><span class="cx">             return int(z);
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 5);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 5), makeInt(program, 3)]), 5);
-    program = doPrep(`
-        test int foo(int x, int y) {
</del><ins>+        test int foo20(int x, int y) {
</ins><span class="cx">             atomic_int z;
</span><span class="cx">             int result;
</span><span class="cx">             InterlockedAdd(&z, x, &result);
</span><span class="lines">@@ -6252,11 +6125,7 @@
</span><span class="cx">             InterlockedMax(&z, y, &result);
</span><span class="cx">             return result;
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 3);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 5), makeInt(program, 3)]), 5);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
</del><ins>+        test uint foo21(uint x, uint y) {
</ins><span class="cx">             atomic_uint z;
</span><span class="cx">             uint result;
</span><span class="cx">             InterlockedAdd(&z, x, &result);
</span><span class="lines">@@ -6263,11 +6132,7 @@
</span><span class="cx">             InterlockedMin(&z, y, &result);
</span><span class="cx">             return uint(z);
</span><span class="cx">         }
</span><del>-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 3);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 5), makeUint(program, 3)]), 3);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
</del><ins>+        test uint foo22(uint x, uint y) {
</ins><span class="cx">             atomic_uint z;
</span><span class="cx">             uint result;
</span><span class="cx">             InterlockedAdd(&z, x, &result);
</span><span class="lines">@@ -6274,11 +6139,7 @@
</span><span class="cx">             InterlockedMin(&z, y, &result);
</span><span class="cx">             return result;
</span><span class="cx">         }
</span><del>-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 3);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 5), makeUint(program, 3)]), 5);
-    program = doPrep(`
-        test int foo(int x, int y) {
</del><ins>+        test int foo23(int x, int y) {
</ins><span class="cx">             atomic_int z;
</span><span class="cx">             int result;
</span><span class="cx">             InterlockedAdd(&z, x, &result);
</span><span class="lines">@@ -6285,11 +6146,7 @@
</span><span class="cx">             InterlockedMin(&z, y, &result);
</span><span class="cx">             return int(z);
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 3);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 5), makeInt(program, 3)]), 3);
-    program = doPrep(`
-        test int foo(int x, int y) {
</del><ins>+        test int foo24(int x, int y) {
</ins><span class="cx">             atomic_int z;
</span><span class="cx">             int result;
</span><span class="cx">             InterlockedAdd(&z, x, &result);
</span><span class="lines">@@ -6296,11 +6153,7 @@
</span><span class="cx">             InterlockedMin(&z, y, &result);
</span><span class="cx">             return result;
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 3);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 5), makeInt(program, 3)]), 5);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
</del><ins>+        test uint foo25(uint x, uint y) {
</ins><span class="cx">             atomic_uint z;
</span><span class="cx">             uint result;
</span><span class="cx">             InterlockedAdd(&z, x, &result);
</span><span class="lines">@@ -6307,10 +6160,7 @@
</span><span class="cx">             InterlockedOr(&z, y, &result);
</span><span class="cx">             return uint(z);
</span><span class="cx">         }
</span><del>-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 7);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
</del><ins>+        test uint foo26(uint x, uint y) {
</ins><span class="cx">             atomic_uint z;
</span><span class="cx">             uint result;
</span><span class="cx">             InterlockedAdd(&z, x, &result);
</span><span class="lines">@@ -6317,10 +6167,7 @@
</span><span class="cx">             InterlockedOr(&z, y, &result);
</span><span class="cx">             return result;
</span><span class="cx">         }
</span><del>-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 3);
-    program = doPrep(`
-        test int foo(int x, int y) {
</del><ins>+        test int foo27(int x, int y) {
</ins><span class="cx">             atomic_int z;
</span><span class="cx">             int result;
</span><span class="cx">             InterlockedAdd(&z, x, &result);
</span><span class="lines">@@ -6327,10 +6174,7 @@
</span><span class="cx">             InterlockedOr(&z, y, &result);
</span><span class="cx">             return int(z);
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 7);
-    program = doPrep(`
-        test int foo(int x, int y) {
</del><ins>+        test int foo28(int x, int y) {
</ins><span class="cx">             atomic_int z;
</span><span class="cx">             int result;
</span><span class="cx">             InterlockedAdd(&z, x, &result);
</span><span class="lines">@@ -6337,10 +6181,7 @@
</span><span class="cx">             InterlockedOr(&z, y, &result);
</span><span class="cx">             return result;
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 3);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
</del><ins>+        test uint foo29(uint x, uint y) {
</ins><span class="cx">             atomic_uint z;
</span><span class="cx">             uint result;
</span><span class="cx">             InterlockedAdd(&z, x, &result);
</span><span class="lines">@@ -6347,10 +6188,7 @@
</span><span class="cx">             InterlockedXor(&z, y, &result);
</span><span class="cx">             return uint(z);
</span><span class="cx">         }
</span><del>-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 6);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
</del><ins>+        test uint foo30(uint x, uint y) {
</ins><span class="cx">             atomic_uint z;
</span><span class="cx">             uint result;
</span><span class="cx">             InterlockedAdd(&z, x, &result);
</span><span class="lines">@@ -6357,10 +6195,7 @@
</span><span class="cx">             InterlockedXor(&z, y, &result);
</span><span class="cx">             return result;
</span><span class="cx">         }
</span><del>-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 3);
-    program = doPrep(`
-        test int foo(int x, int y) {
</del><ins>+        test int foo31(int x, int y) {
</ins><span class="cx">             atomic_int z;
</span><span class="cx">             int result;
</span><span class="cx">             InterlockedAdd(&z, x, &result);
</span><span class="lines">@@ -6367,10 +6202,7 @@
</span><span class="cx">             InterlockedXor(&z, y, &result);
</span><span class="cx">             return int(z);
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 6);
-    program = doPrep(`
-        test int foo(int x, int y) {
</del><ins>+        test int foo32(int x, int y) {
</ins><span class="cx">             atomic_int z;
</span><span class="cx">             int result;
</span><span class="cx">             InterlockedAdd(&z, x, &result);
</span><span class="lines">@@ -6377,10 +6209,7 @@
</span><span class="cx">             InterlockedXor(&z, y, &result);
</span><span class="cx">             return result;
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 3);
-    program = doPrep(`
-        test uint foo(uint x, uint y, uint z) {
</del><ins>+        test uint foo33(uint x, uint y, uint z) {
</ins><span class="cx">             atomic_uint w;
</span><span class="cx">             uint result;
</span><span class="cx">             InterlockedAdd(&w, x, &result);
</span><span class="lines">@@ -6387,11 +6216,7 @@
</span><span class="cx">             InterlockedCompareExchange(&w, y, z, &result);
</span><span class="cx">             return uint(w);
</span><span class="cx">         }
</span><del>-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 3), makeUint(program, 5)]), 5);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 4), makeUint(program, 5)]), 3);
-    program = doPrep(`
-        test uint foo(uint x, uint y, uint z) {
</del><ins>+        test uint foo34(uint x, uint y, uint z) {
</ins><span class="cx">             atomic_uint w;
</span><span class="cx">             uint result;
</span><span class="cx">             InterlockedAdd(&w, x, &result);
</span><span class="lines">@@ -6398,11 +6223,7 @@
</span><span class="cx">             InterlockedCompareExchange(&w, y, z, &result);
</span><span class="cx">             return result;
</span><span class="cx">         }
</span><del>-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 3), makeUint(program, 5)]), 3);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 4), makeUint(program, 5)]), 3);
-    program = doPrep(`
-        test int foo(int x, int y, int z) {
</del><ins>+        test int foo35(int x, int y, int z) {
</ins><span class="cx">             atomic_int w;
</span><span class="cx">             int result;
</span><span class="cx">             InterlockedAdd(&w, x, &result);
</span><span class="lines">@@ -6409,11 +6230,7 @@
</span><span class="cx">             InterlockedCompareExchange(&w, y, z, &result);
</span><span class="cx">             return int(w);
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 3), makeInt(program, 5)]), 5);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 4), makeInt(program, 5)]), 3);
-    program = doPrep(`
-        test int foo(int x, int y, int z) {
</del><ins>+        test int foo36(int x, int y, int z) {
</ins><span class="cx">             atomic_int w;
</span><span class="cx">             int result;
</span><span class="cx">             InterlockedAdd(&w, x, &result);
</span><span class="lines">@@ -6421,322 +6238,286 @@
</span><span class="cx">             return result;
</span><span class="cx">         }
</span><span class="cx">     `);
</span><del>-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 3), makeInt(program, 5)]), 3);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 4), makeInt(program, 5)]), 3);
</del><ins>+    checkInt(program, callFunction(program, "foo1", [makeInt(program, 6)]), 0);
+    checkInt(program, callFunction(program, "foo2", [makeInt(program, 6)]), 6);
+    checkInt(program, callFunction(program, "foo3", [makeInt(program, 6)]), 6);
+    checkInt(program, callFunction(program, "foo4", [makeInt(program, 6)]), 12);
+    checkUint(program, callFunction(program, "foo5", [makeUint(program, 6)]), 0);
+    checkUint(program, callFunction(program, "foo6", [makeUint(program, 6)]), 6);
+    checkUint(program, callFunction(program, "foo7", [makeUint(program, 6)]), 6);
+    checkUint(program, callFunction(program, "foo8", [makeUint(program, 6)]), 12);
+    checkUint(program, callFunction(program, "foo9", [makeUint(program, 3), makeUint(program, 5)]), 1);
+    checkUint(program, callFunction(program, "foo10", [makeUint(program, 3), makeUint(program, 5)]), 3);
+    checkInt(program, callFunction(program, "foo11", [makeInt(program, 3), makeInt(program, 5)]), 1);
+    checkInt(program, callFunction(program, "foo12", [makeInt(program, 3), makeInt(program, 5)]), 3);
+    checkUint(program, callFunction(program, "foo13", [makeUint(program, 3), makeUint(program, 5)]), 5);
+    checkUint(program, callFunction(program, "foo14", [makeUint(program, 3), makeUint(program, 5)]), 3);
+    checkInt(program, callFunction(program, "foo15", [makeInt(program, 3), makeInt(program, 5)]), 5);
+    checkInt(program, callFunction(program, "foo16", [makeInt(program, 3), makeInt(program, 5)]), 3);
+    checkUint(program, callFunction(program, "foo17", [makeUint(program, 3), makeUint(program, 5)]), 5);
+    checkUint(program, callFunction(program, "foo17", [makeUint(program, 5), makeUint(program, 3)]), 5);
+    checkUint(program, callFunction(program, "foo18", [makeUint(program, 3), makeUint(program, 5)]), 3);
+    checkUint(program, callFunction(program, "foo18", [makeUint(program, 5), makeUint(program, 3)]), 5);
+    checkInt(program, callFunction(program, "foo19", [makeInt(program, 3), makeInt(program, 5)]), 5);
+    checkInt(program, callFunction(program, "foo19", [makeInt(program, 5), makeInt(program, 3)]), 5);
+    checkInt(program, callFunction(program, "foo20", [makeInt(program, 3), makeInt(program, 5)]), 3);
+    checkInt(program, callFunction(program, "foo20", [makeInt(program, 5), makeInt(program, 3)]), 5);
+    checkUint(program, callFunction(program, "foo21", [makeUint(program, 3), makeUint(program, 5)]), 3);
+    checkUint(program, callFunction(program, "foo21", [makeUint(program, 5), makeUint(program, 3)]), 3);
+    checkUint(program, callFunction(program, "foo22", [makeUint(program, 3), makeUint(program, 5)]), 3);
+    checkUint(program, callFunction(program, "foo22", [makeUint(program, 5), makeUint(program, 3)]), 5);
+    checkInt(program, callFunction(program, "foo23", [makeInt(program, 3), makeInt(program, 5)]), 3);
+    checkInt(program, callFunction(program, "foo23", [makeInt(program, 5), makeInt(program, 3)]), 3);
+    checkInt(program, callFunction(program, "foo24", [makeInt(program, 3), makeInt(program, 5)]), 3);
+    checkInt(program, callFunction(program, "foo24", [makeInt(program, 5), makeInt(program, 3)]), 5);
+    checkUint(program, callFunction(program, "foo25", [makeUint(program, 3), makeUint(program, 5)]), 7);
+    checkUint(program, callFunction(program, "foo26", [makeUint(program, 3), makeUint(program, 5)]), 3);
+    checkInt(program, callFunction(program, "foo27", [makeInt(program, 3), makeInt(program, 5)]), 7);
+    checkInt(program, callFunction(program, "foo28", [makeInt(program, 3), makeInt(program, 5)]), 3);
+    checkUint(program, callFunction(program, "foo29", [makeUint(program, 3), makeUint(program, 5)]), 6);
+    checkUint(program, callFunction(program, "foo30", [makeUint(program, 3), makeUint(program, 5)]), 3);
+    checkInt(program, callFunction(program, "foo31", [makeInt(program, 3), makeInt(program, 5)]), 6);
+    checkInt(program, callFunction(program, "foo32", [makeInt(program, 3), makeInt(program, 5)]), 3);
+    checkUint(program, callFunction(program, "foo33", [makeUint(program, 3), makeUint(program, 3), makeUint(program, 5)]), 5);
+    checkUint(program, callFunction(program, "foo33", [makeUint(program, 3), makeUint(program, 4), makeUint(program, 5)]), 3);
+    checkUint(program, callFunction(program, "foo34", [makeUint(program, 3), makeUint(program, 3), makeUint(program, 5)]), 3);
+    checkUint(program, callFunction(program, "foo34", [makeUint(program, 3), makeUint(program, 4), makeUint(program, 5)]), 3);
+    checkInt(program, callFunction(program, "foo35", [makeInt(program, 3), makeInt(program, 3), makeInt(program, 5)]), 5);
+    checkInt(program, callFunction(program, "foo35", [makeInt(program, 3), makeInt(program, 4), makeInt(program, 5)]), 3);
+    checkInt(program, callFunction(program, "foo36", [makeInt(program, 3), makeInt(program, 3), makeInt(program, 5)]), 3);
+    checkInt(program, callFunction(program, "foo36", [makeInt(program, 3), makeInt(program, 4), makeInt(program, 5)]), 3);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> tests.atomicsNull = function()
</span><span class="cx"> {
</span><span class="cx">     let program = doPrep(`
</span><del>-        test int foo(int z) {
</del><ins>+        test int foo1(int z) {
</ins><span class="cx">             atomic_int x;
</span><span class="cx">             InterlockedAdd(&x, z, null);
</span><span class="cx">             return int(x);
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 6);
-    program = doPrep(`
-        test int foo(int z) {
</del><ins>+        test int foo2(int z) {
</ins><span class="cx">             atomic_int x;
</span><span class="cx">             InterlockedAdd(&x, z, null);
</span><span class="cx">             InterlockedAdd(&x, z, null);
</span><span class="cx">             return int(x);
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 12);
-    program = doPrep(`
-        test uint foo(uint z) {
</del><ins>+        test uint foo3(uint z) {
</ins><span class="cx">             atomic_uint x;
</span><span class="cx">             InterlockedAdd(&x, z, null);
</span><span class="cx">             return uint(x);
</span><span class="cx">         }
</span><del>-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 6)]), 6);
-    program = doPrep(`
-        test uint foo(uint z) {
</del><ins>+        test uint foo4(uint z) {
</ins><span class="cx">             atomic_uint x;
</span><span class="cx">             InterlockedAdd(&x, z, null);
</span><span class="cx">             InterlockedAdd(&x, z, null);
</span><span class="cx">             return uint(x);
</span><span class="cx">         }
</span><del>-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 6)]), 12);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
</del><ins>+        test uint foo5(uint x, uint y) {
</ins><span class="cx">             atomic_uint z;
</span><span class="cx">             InterlockedAdd(&z, x, null);
</span><span class="cx">             InterlockedAnd(&z, y, null);
</span><span class="cx">             return uint(z);
</span><span class="cx">         }
</span><del>-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 1);
-    program = doPrep(`
-        test int foo(int x, int y) {
</del><ins>+        test int foo6(int x, int y) {
</ins><span class="cx">             atomic_int z;
</span><span class="cx">             InterlockedAdd(&z, x, null);
</span><span class="cx">             InterlockedAnd(&z, y, null);
</span><span class="cx">             return int(z);
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 1);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
</del><ins>+        test uint foo7(uint x, uint y) {
</ins><span class="cx">             atomic_uint z;
</span><span class="cx">             InterlockedAdd(&z, x, null);
</span><span class="cx">             InterlockedExchange(&z, y, null);
</span><span class="cx">             return uint(z);
</span><span class="cx">         }
</span><del>-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 5);
-    program = doPrep(`
-        test int foo(int x, int y) {
</del><ins>+        test int foo8(int x, int y) {
</ins><span class="cx">             atomic_int z;
</span><span class="cx">             InterlockedAdd(&z, x, null);
</span><span class="cx">             InterlockedExchange(&z, y, null);
</span><span class="cx">             return int(z);
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 5);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
</del><ins>+        test uint foo9(uint x, uint y) {
</ins><span class="cx">             atomic_uint z;
</span><span class="cx">             InterlockedAdd(&z, x, null);
</span><span class="cx">             InterlockedMax(&z, y, null);
</span><span class="cx">             return uint(z);
</span><span class="cx">         }
</span><del>-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 5);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 5), makeUint(program, 3)]), 5);
-    program = doPrep(`
-        test int foo(int x, int y) {
</del><ins>+        test int foo10(int x, int y) {
</ins><span class="cx">             atomic_int z;
</span><span class="cx">             InterlockedAdd(&z, x, null);
</span><span class="cx">             InterlockedMax(&z, y, null);
</span><span class="cx">             return int(z);
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 5);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 5), makeInt(program, 3)]), 5);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
</del><ins>+        test uint foo11(uint x, uint y) {
</ins><span class="cx">             atomic_uint z;
</span><span class="cx">             InterlockedAdd(&z, x, null);
</span><span class="cx">             InterlockedMin(&z, y, null);
</span><span class="cx">             return uint(z);
</span><span class="cx">         }
</span><del>-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 3);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 5), makeUint(program, 3)]), 3);
-    program = doPrep(`
-        test int foo(int x, int y) {
</del><ins>+        test int foo12(int x, int y) {
</ins><span class="cx">             atomic_int z;
</span><span class="cx">             InterlockedAdd(&z, x, null);
</span><span class="cx">             InterlockedMin(&z, y, null);
</span><span class="cx">             return int(z);
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 3);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 5), makeInt(program, 3)]), 3);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
</del><ins>+        test uint foo13(uint x, uint y) {
</ins><span class="cx">             atomic_uint z;
</span><span class="cx">             InterlockedAdd(&z, x, null);
</span><span class="cx">             InterlockedOr(&z, y, null);
</span><span class="cx">             return uint(z);
</span><span class="cx">         }
</span><del>-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 7);
-    program = doPrep(`
-        test int foo(int x, int y) {
</del><ins>+        test int foo14(int x, int y) {
</ins><span class="cx">             atomic_int z;
</span><span class="cx">             InterlockedAdd(&z, x, null);
</span><span class="cx">             InterlockedOr(&z, y, null);
</span><span class="cx">             return int(z);
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 7);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
</del><ins>+        test uint foo15(uint x, uint y) {
</ins><span class="cx">             atomic_uint z;
</span><span class="cx">             InterlockedAdd(&z, x, null);
</span><span class="cx">             InterlockedXor(&z, y, null);
</span><span class="cx">             return uint(z);
</span><span class="cx">         }
</span><del>-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 6);
-    program = doPrep(`
-        test int foo(int x, int y) {
</del><ins>+        test int foo16(int x, int y) {
</ins><span class="cx">             atomic_int z;
</span><span class="cx">             InterlockedAdd(&z, x, null);
</span><span class="cx">             InterlockedXor(&z, y, null);
</span><span class="cx">             return int(z);
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 6);
-    program = doPrep(`
-        test uint foo(uint x, uint y, uint z) {
</del><ins>+        test uint foo17(uint x, uint y, uint z) {
</ins><span class="cx">             atomic_uint w;
</span><span class="cx">             InterlockedAdd(&w, x, null);
</span><span class="cx">             InterlockedCompareExchange(&w, y, z, null);
</span><span class="cx">             return uint(w);
</span><span class="cx">         }
</span><del>-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 3), makeUint(program, 5)]), 5);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 4), makeUint(program, 5)]), 3);
-    program = doPrep(`
-        test int foo(int x, int y, int z) {
</del><ins>+        test int foo18(int x, int y, int z) {
</ins><span class="cx">             atomic_int w;
</span><span class="cx">             InterlockedAdd(&w, x, null);
</span><span class="cx">             InterlockedCompareExchange(&w, y, z, null);
</span><span class="cx">             return int(w);
</span><span class="cx">         }
</span><del>-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 3), makeInt(program, 5)]), 5);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 4), makeInt(program, 5)]), 3);
-
-    program = doPrep(`
-        test int foo() {
</del><ins>+        test int foo19() {
</ins><span class="cx">             thread atomic_int* x = null;
</span><span class="cx">             InterlockedAdd(x, 1, null);
</span><span class="cx">             return 1;
</span><span class="cx">         }
</span><del>-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
</del><ins>+        test int foo20() {
</ins><span class="cx">             thread atomic_uint* x = null;
</span><span class="cx">             InterlockedAdd(x, 1, null);
</span><span class="cx">             return 1;
</span><span class="cx">         }
</span><del>-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
</del><ins>+        test int foo21() {
</ins><span class="cx">             thread atomic_int* x = null;
</span><span class="cx">             InterlockedAnd(x, 1, null);
</span><span class="cx">             return 1;
</span><span class="cx">         }
</span><del>-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
</del><ins>+        test int foo22() {
</ins><span class="cx">             thread atomic_uint* x = null;
</span><span class="cx">             InterlockedAnd(x, 1, null);
</span><span class="cx">             return 1;
</span><span class="cx">         }
</span><del>-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
</del><ins>+        test int foo23() {
</ins><span class="cx">             thread atomic_int* x = null;
</span><span class="cx">             InterlockedExchange(x, 1, null);
</span><span class="cx">             return 1;
</span><span class="cx">         }
</span><del>-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
</del><ins>+        test int foo24() {
</ins><span class="cx">             thread atomic_uint* x = null;
</span><span class="cx">             InterlockedExchange(x, 1, null);
</span><span class="cx">             return 1;
</span><span class="cx">         }
</span><del>-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
</del><ins>+        test int foo25() {
</ins><span class="cx">             thread atomic_int* x = null;
</span><span class="cx">             InterlockedMax(x, 1, null);
</span><span class="cx">             return 1;
</span><span class="cx">         }
</span><del>-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
</del><ins>+        test int foo26() {
</ins><span class="cx">             thread atomic_uint* x = null;
</span><span class="cx">             InterlockedMax(x, 1, null);
</span><span class="cx">             return 1;
</span><span class="cx">         }
</span><del>-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
</del><ins>+        test int foo27() {
</ins><span class="cx">             thread atomic_int* x = null;
</span><span class="cx">             InterlockedMin(x, 1, null);
</span><span class="cx">             return 1;
</span><span class="cx">         }
</span><del>-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
</del><ins>+        test int foo28() {
</ins><span class="cx">             thread atomic_uint* x = null;
</span><span class="cx">             InterlockedMin(x, 1, null);
</span><span class="cx">             return 1;
</span><span class="cx">         }
</span><del>-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
</del><ins>+        test int foo29() {
</ins><span class="cx">             thread atomic_int* x = null;
</span><span class="cx">             InterlockedOr(x, 1, null);
</span><span class="cx">             return 1;
</span><span class="cx">         }
</span><del>-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
</del><ins>+        test int foo30() {
</ins><span class="cx">             thread atomic_uint* x = null;
</span><span class="cx">             InterlockedOr(x, 1, null);
</span><span class="cx">             return 1;
</span><span class="cx">         }
</span><del>-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
</del><ins>+        test int foo31() {
</ins><span class="cx">             thread atomic_int* x = null;
</span><span class="cx">             InterlockedXor(x, 1, null);
</span><span class="cx">             return 1;
</span><span class="cx">         }
</span><del>-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
</del><ins>+        test int foo32() {
</ins><span class="cx">             thread atomic_uint* x = null;
</span><span class="cx">             InterlockedXor(x, 1, null);
</span><span class="cx">             return 1;
</span><span class="cx">         }
</span><del>-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
</del><ins>+        test int foo33() {
</ins><span class="cx">             thread atomic_int* x = null;
</span><span class="cx">             InterlockedCompareExchange(x, 1, 2, null);
</span><span class="cx">             return 1;
</span><span class="cx">         }
</span><del>-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
</del><ins>+        test int foo34() {
</ins><span class="cx">             thread atomic_uint* x = null;
</span><span class="cx">             InterlockedCompareExchange(x, 1, 2, null);
</span><span class="cx">             return 1;
</span><span class="cx">         }
</span><span class="cx">     `);
</span><del>-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
</del><ins>+    checkInt(program, callFunction(program, "foo1", [makeInt(program, 6)]), 6);
+    checkInt(program, callFunction(program, "foo2", [makeInt(program, 6)]), 12);
+    checkUint(program, callFunction(program, "foo3", [makeUint(program, 6)]), 6);
+    checkUint(program, callFunction(program, "foo4", [makeUint(program, 6)]), 12);
+    checkUint(program, callFunction(program, "foo5", [makeUint(program, 3), makeUint(program, 5)]), 1);
+    checkInt(program, callFunction(program, "foo6", [makeInt(program, 3), makeInt(program, 5)]), 1);
+    checkUint(program, callFunction(program, "foo7", [makeUint(program, 3), makeUint(program, 5)]), 5);
+    checkInt(program, callFunction(program, "foo8", [makeInt(program, 3), makeInt(program, 5)]), 5);
+    checkUint(program, callFunction(program, "foo9", [makeUint(program, 3), makeUint(program, 5)]), 5);
+    checkUint(program, callFunction(program, "foo9", [makeUint(program, 5), makeUint(program, 3)]), 5);
+    checkInt(program, callFunction(program, "foo10", [makeInt(program, 3), makeInt(program, 5)]), 5);
+    checkInt(program, callFunction(program, "foo10", [makeInt(program, 5), makeInt(program, 3)]), 5);
+    checkUint(program, callFunction(program, "foo11", [makeUint(program, 3), makeUint(program, 5)]), 3);
+    checkUint(program, callFunction(program, "foo11", [makeUint(program, 5), makeUint(program, 3)]), 3);
+    checkInt(program, callFunction(program, "foo12", [makeInt(program, 3), makeInt(program, 5)]), 3);
+    checkInt(program, callFunction(program, "foo12", [makeInt(program, 5), makeInt(program, 3)]), 3);
+    checkUint(program, callFunction(program, "foo13", [makeUint(program, 3), makeUint(program, 5)]), 7);
+    checkInt(program, callFunction(program, "foo14", [makeInt(program, 3), makeInt(program, 5)]), 7);
+    checkUint(program, callFunction(program, "foo15", [makeUint(program, 3), makeUint(program, 5)]), 6);
+    checkInt(program, callFunction(program, "foo16", [makeInt(program, 3), makeInt(program, 5)]), 6);
+    checkUint(program, callFunction(program, "foo17", [makeUint(program, 3), makeUint(program, 3), makeUint(program, 5)]), 5);
+    checkUint(program, callFunction(program, "foo17", [makeUint(program, 3), makeUint(program, 4), makeUint(program, 5)]), 3);
+    checkInt(program, callFunction(program, "foo18", [makeInt(program, 3), makeInt(program, 3), makeInt(program, 5)]), 5);
+    checkInt(program, callFunction(program, "foo18", [makeInt(program, 3), makeInt(program, 4), makeInt(program, 5)]), 3);
+    checkTrap(program, () => callFunction(program, "foo19", []), checkInt);
+    checkTrap(program, () => callFunction(program, "foo20", []), checkInt);
+    checkTrap(program, () => callFunction(program, "foo21", []), checkInt);
+    checkTrap(program, () => callFunction(program, "foo22", []), checkInt);
+    checkTrap(program, () => callFunction(program, "foo23", []), checkInt);
+    checkTrap(program, () => callFunction(program, "foo24", []), checkInt);
+    checkTrap(program, () => callFunction(program, "foo25", []), checkInt);
+    checkTrap(program, () => callFunction(program, "foo26", []), checkInt);
+    checkTrap(program, () => callFunction(program, "foo27", []), checkInt);
+    checkTrap(program, () => callFunction(program, "foo28", []), checkInt);
+    checkTrap(program, () => callFunction(program, "foo29", []), checkInt);
+    checkTrap(program, () => callFunction(program, "foo30", []), checkInt);
+    checkTrap(program, () => callFunction(program, "foo31", []), checkInt);
+    checkTrap(program, () => callFunction(program, "foo32", []), checkInt);
+    checkTrap(program, () => callFunction(program, "foo33", []), checkInt);
+    checkTrap(program, () => callFunction(program, "foo34", []), checkInt);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> tests.selfCasts = function()
</span><span class="lines">@@ -9088,7 +8869,304 @@
</span><span class="cx">     // FIXME: Gather other components
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+tests.referenceEquality = function() {
+    let program = doPrep(`
+        test bool foo1() {
+            int x;
+            thread int* y = &x;
+            thread int* z = &x;
+            return y == z;
+        }
+        test bool foo2() {
+            int x;
+            thread int* z = &x;
+            return &x == z;
+        }
+        test bool foo3() {
+            int x;
+            thread int* y = &x;
+            return y == &x;
+        }
+        test bool foo4() {
+            int x;
+            return &x == &x;
+        }
+        test bool foo5() {
+            int x;
+            return &x != &x;
+        }
+        test bool foo6() {
+            int x = 7;
+            int y = 7;
+            return &x == &y;
+        }
+        test bool foo7() {
+            return null == null;
+        }
+        test bool foo8() {
+            int x;
+            thread int* y = &x;
+            thread int* z = &x;
+            return &y == &z;
+        }
+        test bool foo9() {
+            int x;
+            thread int* y = &x;
+            return &y == &y;
+        }
+        test bool foo10() {
+            thread int* y;
+            return null == y;
+        }
+        test bool foo11() {
+            thread int* y;
+            return y == null;
+        }
+        test bool foo12() {
+            int x;
+            thread int* y = &x;
+            return null == y;
+        }
+        test bool foo13() {
+            int x;
+            thread int* y = &x;
+            return y == null;
+        }
+        test bool foo14() {
+            int x;
+            thread int[] y = @x;
+            thread int[] z = @x;
+            return y == z;
+        }
+        test bool foo15() {
+            int x;
+            thread int[] z = @x;
+            return @x == z;
+        }
+        test bool foo16() {
+            int x;
+            thread int[] y = @x;
+            return y == @x;
+        }
+        test bool foo17() {
+            int x;
+            return @x == @x;
+        }
+        test bool foo18() {
+            int x;
+            return @x != @x;
+        }
+        test bool foo19() {
+            int x = 7;
+            int y = 7;
+            return @x == @y;
+        }
+        test bool foo21() {
+            int x;
+            thread int[] y = @x;
+            thread int[] z = @x;
+            return @y == @z;
+        }
+        test bool foo22() {
+            int x;
+            thread int[] y = @x;
+            return @y == @y;
+        }
+        test bool foo23() {
+            thread int[] y;
+            return null == y;
+        }
+        test bool foo24() {
+            thread int[] y;
+            return y == null;
+        }
+        test bool foo25() {
+            int x;
+            thread int[] y = @x;
+            return null == y;
+        }
+        test bool foo26() {
+            int x;
+            thread int[] y = @x;
+            return y == null;
+        }
+        test bool foo27() {
+            int[3] x;
+            thread int[] y = @x;
+            thread int[] z = @x;
+            return y == z;
+        }
+        test bool foo28() {
+            int[3] x;
+            thread int[] z = @x;
+            return @x == z;
+        }
+        test bool foo29() {
+            int[3] x;
+            thread int[] y = @x;
+            return y == @x;
+        }
+        test bool foo30() {
+            int[3] x;
+            return @x == @x;
+        }
+        test bool foo31() {
+            int[3] x;
+            return @x != @x;
+        }
+        test bool foo32() {
+            int[3] x;
+            x[0] = 7;
+            x[1] = 8;
+            x[2] = 9;
+            int[3] y;
+            y[0] = 7;
+            y[1] = 8;
+            y[2] = 9;
+            return @x == @y;
+        }
+        test bool foo33() {
+            int[3] x;
+            thread int[] y = @x;
+            thread int[] z = @x;
+            return @y == @z;
+        }
+        test bool foo34() {
+            int[3] x;
+            thread int[] y = @x;
+            return @y == @y;
+        }
+        test bool foo35() {
+            thread int[] y;
+            return null == y;
+        }
+        test bool foo36() {
+            thread int[] y;
+            return y == null;
+        }
+        test bool foo37() {
+            int[3] x;
+            thread int[] y = @x;
+            return null == y;
+        }
+        test bool foo38() {
+            int[3] x;
+            thread int[] y = @x;
+            return y == null;
+        }
+    `);
+    checkBool(program, callFunction(program, "foo1", []), true);
+    checkBool(program, callFunction(program, "foo2", []), true);
+    checkBool(program, callFunction(program, "foo3", []), true);
+    checkBool(program, callFunction(program, "foo4", []), true);
+    checkBool(program, callFunction(program, "foo5", []), false);
+    checkBool(program, callFunction(program, "foo6", []), false);
+    checkBool(program, callFunction(program, "foo7", []), true);
+    checkBool(program, callFunction(program, "foo8", []), false);
+    checkBool(program, callFunction(program, "foo9", []), true);
+    checkBool(program, callFunction(program, "foo10", []), true);
+    checkBool(program, callFunction(program, "foo11", []), true);
+    checkBool(program, callFunction(program, "foo12", []), false);
+    checkBool(program, callFunction(program, "foo13", []), false);
+    checkBool(program, callFunction(program, "foo14", []), true);
+    checkBool(program, callFunction(program, "foo15", []), true);
+    checkBool(program, callFunction(program, "foo16", []), true);
+    checkBool(program, callFunction(program, "foo17", []), true);
+    checkBool(program, callFunction(program, "foo18", []), false);
+    checkBool(program, callFunction(program, "foo19", []), false);
+    checkBool(program, callFunction(program, "foo21", []), false);
+    checkBool(program, callFunction(program, "foo22", []), true);
+    checkBool(program, callFunction(program, "foo23", []), true);
+    checkBool(program, callFunction(program, "foo24", []), true);
+    checkBool(program, callFunction(program, "foo25", []), false);
+    checkBool(program, callFunction(program, "foo26", []), false);
+    checkBool(program, callFunction(program, "foo27", []), true);
+    checkBool(program, callFunction(program, "foo28", []), true);
+    checkBool(program, callFunction(program, "foo29", []), true);
+    checkBool(program, callFunction(program, "foo30", []), true);
+    checkBool(program, callFunction(program, "foo31", []), false);
+    checkBool(program, callFunction(program, "foo32", []), false);
+    checkBool(program, callFunction(program, "foo33", []), false);
+    checkBool(program, callFunction(program, "foo34", []), true);
+    checkBool(program, callFunction(program, "foo35", []), true);
+    checkBool(program, callFunction(program, "foo36", []), true);
+    checkBool(program, callFunction(program, "foo37", []), false);
+    checkBool(program, callFunction(program, "foo38", []), false);
+    checkFail(
+        () => doPrep(`
+            void foo()
+            {
+                int x;
+                float y;
+                bool z = (&x == &y);
+            }
+        `),
+        (e) => e instanceof WTypeError);
+    checkFail(
+        () => doPrep(`
+            void foo()
+            {
+                int x;
+                thread int* y = &x;
+                bool z = (&x == &y);
+            }
+        `),
+        (e) => e instanceof WTypeError);
+    checkFail(
+        () => doPrep(`
+            void foo()
+            {
+                int x;
+                float y;
+                bool z = (@x == @y);
+            }
+        `),
+        (e) => e instanceof WTypeError);
+    checkFail(
+        () => doPrep(`
+            void foo()
+            {
+                int x;
+                thread int[] y = @x;
+                bool z = (@x == @y);
+            }
+        `),
+        (e) => e instanceof WTypeError);
+}
</ins><span class="cx"> 
</span><ins>+tests.standardLibraryDevicePointers = function() {
+    let program = doPrep(`
+        test float foo1() {
+            float s;
+            float c;
+            sincos(0, &s, &c);
+            return c;
+        }
+        test float foo2() {
+            float s;
+            float c;
+            sincos(0, &s, &c);
+            return s;
+        }
+        test float foo3() {
+            thread float* s = null;
+            float c;
+            sincos(0, s, &c);
+            return c;
+        }
+        test float foo4() {
+            float s;
+            thread float* c = null;
+            sincos(0, &s, c);
+            return s;
+        }
+    `);
+    checkFloat(program, callFunction(program, "foo1", []), 1);
+    checkFloat(program, callFunction(program, "foo2", []), 0);
+    checkFloat(program, callFunction(program, "foo3", []), 1);
+    checkFloat(program, callFunction(program, "foo4", []), 0);
+}
+
</ins><span class="cx"> tests.commentParsing = function() {
</span><span class="cx">     let program = doPrep(`
</span><span class="cx">         /* this comment
</span></span></pre></div>
<a id="trunkToolsWebGPUShadingLanguageRIindexhtml"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebGPUShadingLanguageRI/index.html (236627 => 236628)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebGPUShadingLanguageRI/index.html   2018-09-29 00:22:08 UTC (rev 236627)
+++ trunk/Tools/WebGPUShadingLanguageRI/index.html      2018-09-29 00:48:34 UTC (rev 236628)
</span><span class="lines">@@ -85,8 +85,7 @@
</span><span class="cx"> <script src="IntLiteral.js"></script>
</span><span class="cx"> <script src="IntLiteralType.js"></script>
</span><span class="cx"> <script src="Intrinsics.js"></script>
</span><del>-<script src="LateCheckAndLayoutBuffers.js"></script>
-<script src="LateChecker.js"></script>
</del><ins>+<script src="LayoutBuffers.js"></script>
</ins><span class="cx"> <script src="Lexer.js"></script>
</span><span class="cx"> <script src="LexerToken.js"></script>
</span><span class="cx"> <script src="LiteralTypeChecker.js"></script>
</span></span></pre>
</div>
</div>

</body>
</html>