Title: [236628] trunk/Tools
Revision
236628
Author
mmaxfi...@apple.com
Date
2018-09-28 17:48:34 -0700 (Fri, 28 Sep 2018)

Log Message

[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:

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/Tools/ChangeLog (236627 => 236628)


--- trunk/Tools/ChangeLog	2018-09-29 00:22:08 UTC (rev 236627)
+++ trunk/Tools/ChangeLog	2018-09-29 00:48:34 UTC (rev 236628)
@@ -1,3 +1,57 @@
+2018-09-28  Myles C. Maxfield  <mmaxfi...@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:
+
 2018-09-28  Jiewen Tan  <jiewen_...@apple.com>
 
         [WebAuthN] Polish WebAuthN auto-test environment

Modified: trunk/Tools/WebGPUShadingLanguageRI/All.js (236627 => 236628)


--- 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)
@@ -108,8 +108,7 @@
 load("IntLiteral.js");
 load("IntLiteralType.js");
 load("Intrinsics.js");
-load("LateCheckAndLayoutBuffers.js");
-load("LateChecker.js");
+load("LayoutBuffers.js");
 load("Lexer.js");
 load("LexerToken.js");
 load("LiteralTypeChecker.js");

Modified: trunk/Tools/WebGPUShadingLanguageRI/AllocateAtEntryPoints.js (236627 => 236628)


--- 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)
@@ -142,7 +142,7 @@
 
             _addVariableDeclaration()
             {
-                this._variableDecl = new VariableDecl(func.origin, null, globalStructTypeRef, null);
+                this._variableDecl = new VariableDecl(func.origin, "global struct", globalStructTypeRef, null);
                 this.makeGlobalStructVariableRef = () => new MakePtrExpression(func.origin, VariableRef.wrap(this._variableDecl));
                 func.body.statements.unshift(this._variableDecl);
             }

Modified: trunk/Tools/WebGPUShadingLanguageRI/CallExpression.js (236627 => 236628)


--- 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)
@@ -102,6 +102,11 @@
             func = this._resolveWithOperatorAnderIndexer(program);
         else if (this.name == "operator.length")
             func = this._resolveWithOperatorLength(program);
+        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);
         else
             return null;
 
@@ -119,17 +124,17 @@
         const addressSpace = arrayRefType.addressSpace;
 
         // The later checkLiteralTypes stage will verify that the literal can be represented as a uint.
-        const uintType = TypeRef.wrap(program.types.get("uint"));
+        const uintType = TypeRef.wrap(program.intrinsics.uint);
         indexType.type = uintType;
 
         const elementType = this.argumentTypes[0].elementType;
-        this.resultType = this._returnType = TypeRef.wrap(new PtrType(this.origin, addressSpace, TypeRef.wrap(elementType)))
+        this.resultType = TypeRef.wrap(new PtrType(this.origin, addressSpace, TypeRef.wrap(elementType)))
 
-        let arrayRefAccessor = new OperatorAnderIndexer(this.returnType.toString(), addressSpace);
+        let arrayRefAccessor = new OperatorAnderIndexer(this.resultType.toString(), addressSpace);
         const func = new NativeFunc(this.origin, "operator&[]", this.resultType, [
             new FuncParameter(this.origin, null, arrayRefType),
             new FuncParameter(this.origin, null, uintType)
-        ], false);
+        ]);
 
         arrayRefAccessor.instantiateImplementation(func);
 
@@ -138,14 +143,14 @@
 
     _resolveWithOperatorLength(program)
     {
-        this.resultType = this._returnType = TypeRef.wrap(program.types.get("uint"));
+        this.resultType = TypeRef.wrap(program.intrinsics.uint);
 
         if (this.argumentTypes[0].isArray) {
             const arrayType = this.argumentTypes[0];
             const func = new NativeFunc(this.origin, "operator.length", this.resultType, [
                 new FuncParameter(this.origin, null, arrayType)
-            ], false);
-            func.implementation = (args, node) => EPtr.box(arrayType.numElementsValue);
+            ]);
+            func.implementation = (args) => EPtr.box(arrayType.numElementsValue);
             return func;
         } else if (this.argumentTypes[0].isArrayRef) {
             const arrayRefType = this.argumentTypes[0];
@@ -153,12 +158,38 @@
             const operatorLength = new OperatorArrayRefLength(arrayRefType.toString(), addressSpace);
             const func = new NativeFunc(this.origin, "operator.length", this.resultType, [
                 new FuncParameter(this.origin, null, arrayRefType)
-            ], false);
+            ]);
             operatorLength.instantiateImplementation(func);
             return func;
         } else
             throw new WTypeError(this.origin.originString, `Expected ${this.argumentTypes[0]} to be array/array ref type for operator.length`);
     }
+
+    _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;
+    }
     
     resolveToOverload(overload)
     {

Modified: trunk/Tools/WebGPUShadingLanguageRI/EArrayRef.js (236627 => 236628)


--- 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)
@@ -33,6 +33,11 @@
     
     get ptr() { return this._ptr; }
     get length() { return this._length; }
+
+    equals(other)
+    {
+        return this.ptr.equals(other.ptr) && this.length == other.length;
+    }
     
     toString()
     {

Modified: trunk/Tools/WebGPUShadingLanguageRI/EPtr.js (236627 => 236628)


--- 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)
@@ -79,6 +79,11 @@
         for (let i = size; i--;)
             this.set(i, other.get(i));
     }
+
+    equals(other)
+    {
+        return this.buffer == other.buffer && this.offset == other.offset;
+    }
     
     toString()
     {

Deleted: trunk/Tools/WebGPUShadingLanguageRI/LateCheckAndLayoutBuffers.js (236627 => 236628)


--- 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)
@@ -1,37 +0,0 @@
-/*
- * 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());
-        }
-    }
-}
\ No newline at end of file

Deleted: trunk/Tools/WebGPUShadingLanguageRI/LateChecker.js (236627 => 236628)


--- 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)
@@ -1,37 +0,0 @@
-/*
- * 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);
-    }
-}
-

Copied: trunk/Tools/WebGPUShadingLanguageRI/LayoutBuffers.js (from rev 236627, trunk/Tools/WebGPUShadingLanguageRI/LateCheckAndLayoutBuffers.js) (0 => 236628)


--- trunk/Tools/WebGPUShadingLanguageRI/LayoutBuffers.js	                        (rev 0)
+++ trunk/Tools/WebGPUShadingLanguageRI/LayoutBuffers.js	2018-09-29 00:48:34 UTC (rev 236628)
@@ -0,0 +1,36 @@
+/*
+ * 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());
+        }
+    }
+}

Modified: trunk/Tools/WebGPUShadingLanguageRI/Metal/WHLSL Tests/WHLSL Tests.xcodeproj/project.pbxproj (236627 => 236628)


--- 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)
@@ -83,7 +83,6 @@
 		E92D115A20F7060E00D776B2 /* IntLiteral.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D0FE420F56DDD00D776B2 /* IntLiteral.js */; };
 		E92D115B20F7060E00D776B2 /* IntLiteralType.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D0FE520F56DDD00D776B2 /* IntLiteralType.js */; };
 		E92D115C20F7060E00D776B2 /* Intrinsics.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D0FE720F56DDD00D776B2 /* Intrinsics.js */; };
-		E92D115D20F7060E00D776B2 /* LateChecker.js in Resources */ = {isa = PBXBuildFile; fileRef = E9FCEB6420F56DA5009B3629 /* LateChecker.js */; };
 		E92D115E20F7060E00D776B2 /* Lexer.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D0FF120F56DEC00D776B2 /* Lexer.js */; };
 		E92D115F20F7060E00D776B2 /* LexerToken.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D0FF020F56DEB00D776B2 /* LexerToken.js */; };
 		E92D116020F7060E00D776B2 /* LiteralTypeChecker.js in Resources */ = {isa = PBXBuildFile; fileRef = E92D0FF220F56DEC00D776B2 /* LiteralTypeChecker.js */; };
@@ -186,7 +185,7 @@
 		E9D7CB98214B824200F1C918 /* MSLBackend.js in Resources */ = {isa = PBXBuildFile; fileRef = E9D7CB95214B824200F1C918 /* MSLBackend.js */; };
 		E9D7CB99214B824200F1C918 /* MSLConstexprEmitter.js in Resources */ = {isa = PBXBuildFile; fileRef = E9D7CB96214B824200F1C918 /* MSLConstexprEmitter.js */; };
 		E9D7CBA0214B82B800F1C918 /* Texture.js in Resources */ = {isa = PBXBuildFile; fileRef = E9D7CB9A214B82B700F1C918 /* Texture.js */; };
-		E9D7CBA1214B82B800F1C918 /* LateCheckAndLayoutBuffers.js in Resources */ = {isa = PBXBuildFile; fileRef = E9D7CB9B214B82B700F1C918 /* LateCheckAndLayoutBuffers.js */; };
+		E9D7CBA1214B82B800F1C918 /* LayoutBuffers.js in Resources */ = {isa = PBXBuildFile; fileRef = E9D7CB9B214B82B700F1C918 /* LayoutBuffers.js */; };
 		E9D7CBA2214B82B800F1C918 /* Casts.js in Resources */ = {isa = PBXBuildFile; fileRef = E9D7CB9C214B82B700F1C918 /* Casts.js */; };
 		E9D7CBA3214B82B800F1C918 /* Sampler.js in Resources */ = {isa = PBXBuildFile; fileRef = E9D7CB9D214B82B800F1C918 /* Sampler.js */; };
 		E9D7CBA4214B82B800F1C918 /* TextureOperations.js in Resources */ = {isa = PBXBuildFile; fileRef = E9D7CB9E214B82B800F1C918 /* TextureOperations.js */; };
@@ -405,7 +404,7 @@
 		E9D7CB95214B824200F1C918 /* MSLBackend.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; name = MSLBackend.js; path = ../../MSLBackend.js; sourceTree = "<group>"; };
 		E9D7CB96214B824200F1C918 /* MSLConstexprEmitter.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; name = MSLConstexprEmitter.js; path = ../../MSLConstexprEmitter.js; sourceTree = "<group>"; };
 		E9D7CB9A214B82B700F1C918 /* Texture.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; name = Texture.js; path = ../../../Texture.js; sourceTree = "<group>"; };
-		E9D7CB9B214B82B700F1C918 /* LateCheckAndLayoutBuffers.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; name = LateCheckAndLayoutBuffers.js; path = ../../../LateCheckAndLayoutBuffers.js; sourceTree = "<group>"; };
+		E9D7CB9B214B82B700F1C918 /* LayoutBuffers.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; name = LayoutBuffers.js; path = ../../../LayoutBuffers.js; sourceTree = "<group>"; };
 		E9D7CB9C214B82B700F1C918 /* Casts.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; name = Casts.js; path = ../../../Casts.js; sourceTree = "<group>"; };
 		E9D7CB9D214B82B800F1C918 /* Sampler.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; name = Sampler.js; path = ../../../Sampler.js; sourceTree = "<group>"; };
 		E9D7CB9E214B82B800F1C918 /* TextureOperations.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; name = TextureOperations.js; path = ../../../TextureOperations.js; sourceTree = "<group>"; };
@@ -416,7 +415,6 @@
 		E9FCEB5A20F56D93009B3629 /* ForLoop.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; name = ForLoop.js; path = ../../../ForLoop.js; sourceTree = "<group>"; };
 		E9FCEB5B20F56D93009B3629 /* Field.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; name = Field.js; path = ../../../Field.js; sourceTree = "<group>"; };
 		E9FCEB6320F56DA4009B3629 /* IndexExpression.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode._javascript_; name = IndexExpression.js; path = ../../../IndexExpression.js; sourceTree = "<group>"; };
-		E9FCEB6420F56DA5009B3629 /* LateChecker.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode._javascript_; name = LateChecker.js; path = ../../../LateChecker.js; sourceTree = "<group>"; };
 		E9FCEB6520F56DA5009B3629 /* InferTypesForCall.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode._javascript_; name = InferTypesForCall.js; path = ../../../InferTypesForCall.js; sourceTree = "<group>"; };
 		E9FCEB6620F56DA5009B3629 /* Inline.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode._javascript_; name = Inline.js; path = ../../../Inline.js; sourceTree = "<group>"; };
 /* End PBXFileReference section */
@@ -628,8 +626,7 @@
 				E92D0FE420F56DDD00D776B2 /* IntLiteral.js */,
 				E92D0FE520F56DDD00D776B2 /* IntLiteralType.js */,
 				E92D0FE720F56DDD00D776B2 /* Intrinsics.js */,
-				E9D7CB9B214B82B700F1C918 /* LateCheckAndLayoutBuffers.js */,
-				E9FCEB6420F56DA5009B3629 /* LateChecker.js */,
+				E9D7CB9B214B82B700F1C918 /* LayoutBuffers.js */,
 				E92D0FF120F56DEC00D776B2 /* Lexer.js */,
 				E92D0FF020F56DEB00D776B2 /* LexerToken.js */,
 				E92D0FF220F56DEC00D776B2 /* LiteralTypeChecker.js */,
@@ -885,8 +882,7 @@
 				E92D115B20F7060E00D776B2 /* IntLiteralType.js in Resources */,
 				E92D115C20F7060E00D776B2 /* Intrinsics.js in Resources */,
 				E906B04621139B7700AD1C5E /* Julia.whlsl in Resources */,
-				E9D7CBA1214B82B800F1C918 /* LateCheckAndLayoutBuffers.js in Resources */,
-				E92D115D20F7060E00D776B2 /* LateChecker.js in Resources */,
+				E9D7CBA1214B82B800F1C918 /* LayoutBuffers.js in Resources */,
 				E92D115E20F7060E00D776B2 /* Lexer.js in Resources */,
 				E92D115F20F7060E00D776B2 /* LexerToken.js in Resources */,
 				E92D116020F7060E00D776B2 /* LiteralTypeChecker.js in Resources */,

Modified: trunk/Tools/WebGPUShadingLanguageRI/NativeFunc.js (236627 => 236628)


--- 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)
@@ -25,7 +25,7 @@
 "use strict";
 
 class NativeFunc extends Func {
-    constructor(origin, name, returnType, parameters, isCast, stage = null)
+    constructor(origin, name, returnType, parameters, isCast = false, stage = null)
     {
         super(origin, name, returnType, parameters, isCast);
         this._stage = stage;

Modified: trunk/Tools/WebGPUShadingLanguageRI/OperatorArrayRefLength.js (236627 => 236628)


--- 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)
@@ -41,7 +41,7 @@
 
     instantiateImplementation(func)
     {
-        func.implementation = ([ref], node) => {
+        func.implementation = ([ref]) => {
             ref = ref.loadValue();
             if (!ref)
                 return EPtr.box(0);
@@ -49,4 +49,4 @@
         };
         func.implementationData = this;
     }
-}
\ No newline at end of file
+}

Modified: trunk/Tools/WebGPUShadingLanguageRI/Prepare.js (236627 => 236628)


--- 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)
@@ -32,13 +32,13 @@
             let firstLineOfStandardLibrary = 28; // See StandardLibrary.js.
             parse(standardProgram, "/internal/stdlib", "native", firstLineOfStandardLibrary - 1, standardLibrary);
         }
-        
+
         let program = cloneProgram(standardProgram);
         if (arguments.length) {
             parse(program, origin, "user", lineNumberOffset, text);
             program = programWithUnnecessaryThingsRemoved(program);
         }
-        
+
         foldConstexprs(program);
 
         let nameResolver = createNameResolver(program);
@@ -69,7 +69,7 @@
         findHighZombies(program);
         allocateAtEntryPoints(program);
         program.visit(new StructLayoutBuilder());
-        lateCheckAndLayoutBuffers(program);
+        layoutBuffers(program);
         checkNativeFuncStages(program);
         if (shouldInline)
             inline(program);

Modified: trunk/Tools/WebGPUShadingLanguageRI/SPIRV.html (236627 => 236628)


--- 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)
@@ -91,8 +91,7 @@
     <script src=""
     <script src=""
     <script src=""
-    <script src=""
-    <script src=""
+    <script src=""
     <script src=""
     <script src=""
     <script src=""

Modified: trunk/Tools/WebGPUShadingLanguageRI/Test.html (236627 => 236628)


--- 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)
@@ -85,8 +85,7 @@
 <script src=""
 <script src=""
 <script src=""
-<script src=""
-<script src=""
+<script src=""
 <script src=""
 <script src=""
 <script src=""

Modified: trunk/Tools/WebGPUShadingLanguageRI/Test.js (236627 => 236628)


--- 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)
@@ -343,11 +343,11 @@
         {
             return x < 3 ? 4 : 5;
         }
-        test int baz(int x)
+        test int bar(int x)
         {
             return x < 10 ? 11 : x < 12 ? 14 : 15;
         }
-        test int quux(int x)
+        test int baz(int x)
         {
             return 3 < 4 ? x : 5;
         }
@@ -354,13 +354,13 @@
     `);
     checkInt(program, callFunction(program, "foo", [makeInt(program, 767)]), 5);
     checkInt(program, callFunction(program, "foo", [makeInt(program, 2)]), 4);
-    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);
+    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);
     checkFail(
         () => doPrep(`
             int foo()
@@ -1384,7 +1384,7 @@
 tests.break = function()
 {
     let program = doPrep(`
-        test int foo(int x)
+        test int foo1(int x)
         {
             while (true) {
                 x = x * 2;
@@ -1393,11 +1393,7 @@
             }
             return x;
         }
-    `);
-    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)
+        test int foo2(int x)
         {
             while (true) {
                 while (true) {
@@ -1409,11 +1405,38 @@
                 break;
             }
             return x;
-
         }
+        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;
+            }
+        }
     `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), 7);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 10)]), 19);
+    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);
     checkFail(
         () => doPrep(`
             int foo(int x)
@@ -1437,38 +1460,6 @@
             }
         `),
         (e) => e instanceof WTypeError);
-    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);
     checkFail(
         () => doPrep(`
             test int foo(int x)
@@ -1513,7 +1504,7 @@
 tests.doWhile = function()
 {
     let program = doPrep(`
-        test int foo(int x)
+        test int foo1(int x)
         {
             int y = 7;
             do {
@@ -1522,11 +1513,7 @@
             } while (x < 10);
             return y;
         }
-    `);
-    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)
+        test int foo2(int x)
         {
             int y = 7;
             do {
@@ -1535,10 +1522,7 @@
             } while (y == 7);
             return y;
         }
-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 1)]), 8);
-    program = doPrep(`
-        test int foo(int x)
+        test int foo3(int x)
         {
             int sum = 0;
             do {
@@ -1552,13 +1536,16 @@
             return sum;
         }
     `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 9)]), 19);
+    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);
 }
 
 tests.forLoop = function()
 {
     let program = doPrep(`
-        test int foo(int x)
+        test int foo1(int x)
         {
             int sum = 0;
             int i;
@@ -1567,12 +1554,7 @@
             }
             return sum;
         }
-    `);
-    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)
+        test int foo2(int x)
         {
             int sum = 0;
             for (int i = 0; i < x; i = i + 1) {
@@ -1580,12 +1562,7 @@
             }
             return sum;
         }
-    `);
-    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)
+        test int foo3(int x)
         {
             int sum = 0;
             int i = 100;
@@ -1594,12 +1571,7 @@
             }
             return sum;
         }
-    `);
-    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)
+        test int foo4(int x)
         {
             int sum = 0;
             for (int i = 0; i < x; i = i + 1) {
@@ -1609,13 +1581,7 @@
             }
             return sum;
         }
-    `);
-    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)
+        test int foo5(int x)
         {
             int sum = 0;
             for (int i = 0; i < x; i = i + 1) {
@@ -1625,14 +1591,7 @@
             }
             return sum;
         }
-    `);
-    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)
+        test int foo6(int x)
         {
             int sum = 0;
             for (int i = 0; ; i = i + 1) {
@@ -1642,14 +1601,7 @@
             }
             return sum;
         }
-    `);
-    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)
+        test int foo7(int x)
         {
             int sum = 0;
             int i = 0;
@@ -1660,14 +1612,7 @@
             }
             return sum;
         }
-    `);
-    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)
+        test int foo8(int x)
         {
             int sum = 0;
             int i = 0;
@@ -1679,12 +1624,62 @@
             }
             return sum;
         }
+        test int foo9(int x)
+        {
+            for ( ; ; ) {
+                return 7;
+            }
+        }
+        test int foo10(int x)
+        {
+            for ( ; true; ) {
+                return 7;
+            }
+        }
     `);
-    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);
+    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);
     checkFail(
         () => doPrep(`
             void foo(int x)
@@ -1696,19 +1691,6 @@
             }
         `),
         (e) => e instanceof WTypeError);
-    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);
     checkFail(
         () => doPrep(`
             int foo(int x)
@@ -1719,19 +1701,6 @@
             }
         `),
         (e) => e instanceof WTypeError);
-    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);
 }
 
 tests.prefixPlusPlus = function()
@@ -5828,42 +5797,6 @@
     checkInt(program, callFunction(program, "foo", []), 13);
 }
 
-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);
-}
-
 tests.andReturnedArrayRef = function()
 {
     let program = doPrep(`
@@ -6056,16 +5989,13 @@
 tests.atomics = function()
 {
     let program = doPrep(`
-        test int foo(int z) {
+        test int foo1(int z) {
             atomic_int x;
             int result;
             InterlockedAdd(&x, z, &result);
             return result;
         }
-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 0);
-    program = doPrep(`
-        test int foo(int z) {
+        test int foo2(int z) {
             atomic_int x;
             int result;
             InterlockedAdd(&x, z, &result);
@@ -6072,19 +6002,13 @@
             InterlockedAdd(&x, z, &result);
             return result;
         }
-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 6);
-    program = doPrep(`
-        test int foo(int z) {
+        test int foo3(int z) {
             atomic_int x;
             int result;
             InterlockedAdd(&x, z, &result);
             return int(x);
         }
-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 6);
-    program = doPrep(`
-        test int foo(int z) {
+        test int foo4(int z) {
             atomic_int x;
             int result;
             InterlockedAdd(&x, z, &result);
@@ -6091,19 +6015,13 @@
             InterlockedAdd(&x, z, &result);
             return int(x);
         }
-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 12);
-    program = doPrep(`
-        test uint foo(uint z) {
+        test uint foo5(uint z) {
             atomic_uint x;
             uint result;
             InterlockedAdd(&x, z, &result);
             return result;
         }
-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 6)]), 0);
-    program = doPrep(`
-        test uint foo(uint z) {
+        test uint foo6(uint z) {
             atomic_uint x;
             uint result;
             InterlockedAdd(&x, z, &result);
@@ -6110,19 +6028,13 @@
             InterlockedAdd(&x, z, &result);
             return result;
         }
-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 6)]), 6);
-    program = doPrep(`
-        test uint foo(uint z) {
+        test uint foo7(uint z) {
             atomic_uint x;
             uint result;
             InterlockedAdd(&x, z, &result);
             return uint(x);
         }
-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 6)]), 6);
-    program = doPrep(`
-        test uint foo(uint z) {
+        test uint foo8(uint z) {
             atomic_uint x;
             uint result;
             InterlockedAdd(&x, z, &result);
@@ -6129,10 +6041,7 @@
             InterlockedAdd(&x, z, &result);
             return uint(x);
         }
-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 6)]), 12);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
+        test uint foo9(uint x, uint y) {
             atomic_uint z;
             uint result;
             InterlockedAdd(&z, x, &result);
@@ -6139,10 +6048,7 @@
             InterlockedAnd(&z, y, &result);
             return uint(z);
         }
-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 1);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
+        test uint foo10(uint x, uint y) {
             atomic_uint z;
             uint result;
             InterlockedAdd(&z, x, &result);
@@ -6149,10 +6055,7 @@
             InterlockedAnd(&z, y, &result);
             return result;
         }
-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 3);
-    program = doPrep(`
-        test int foo(int x, int y) {
+        test int foo11(int x, int y) {
             atomic_int z;
             int result;
             InterlockedAdd(&z, x, &result);
@@ -6159,10 +6062,7 @@
             InterlockedAnd(&z, y, &result);
             return int(z);
         }
-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 1);
-    program = doPrep(`
-        test int foo(int x, int y) {
+        test int foo12(int x, int y) {
             atomic_int z;
             int result;
             InterlockedAdd(&z, x, &result);
@@ -6169,10 +6069,7 @@
             InterlockedAnd(&z, y, &result);
             return result;
         }
-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 3);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
+        test uint foo13(uint x, uint y) {
             atomic_uint z;
             uint result;
             InterlockedAdd(&z, x, &result);
@@ -6179,10 +6076,7 @@
             InterlockedExchange(&z, y, &result);
             return uint(z);
         }
-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 5);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
+        test uint foo14(uint x, uint y) {
             atomic_uint z;
             uint result;
             InterlockedAdd(&z, x, &result);
@@ -6189,10 +6083,7 @@
             InterlockedExchange(&z, y, &result);
             return result;
         }
-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 3);
-    program = doPrep(`
-        test int foo(int x, int y) {
+        test int foo15(int x, int y) {
             atomic_int z;
             int result;
             InterlockedAdd(&z, x, &result);
@@ -6199,10 +6090,7 @@
             InterlockedExchange(&z, y, &result);
             return int(z);
         }
-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 5);
-    program = doPrep(`
-        test int foo(int x, int y) {
+        test int foo16(int x, int y) {
             atomic_int z;
             int result;
             InterlockedAdd(&z, x, &result);
@@ -6209,10 +6097,7 @@
             InterlockedExchange(&z, y, &result);
             return result;
         }
-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 3);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
+        test uint foo17(uint x, uint y) {
             atomic_uint z;
             uint result;
             InterlockedAdd(&z, x, &result);
@@ -6219,11 +6104,7 @@
             InterlockedMax(&z, y, &result);
             return uint(z);
         }
-    `);
-    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) {
+        test uint foo18(uint x, uint y) {
             atomic_uint z;
             uint result;
             InterlockedAdd(&z, x, &result);
@@ -6230,11 +6111,7 @@
             InterlockedMax(&z, y, &result);
             return result;
         }
-    `);
-    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) {
+        test int foo19(int x, int y) {
             atomic_int z;
             int result;
             InterlockedAdd(&z, x, &result);
@@ -6241,11 +6118,7 @@
             InterlockedMax(&z, y, &result);
             return int(z);
         }
-    `);
-    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) {
+        test int foo20(int x, int y) {
             atomic_int z;
             int result;
             InterlockedAdd(&z, x, &result);
@@ -6252,11 +6125,7 @@
             InterlockedMax(&z, y, &result);
             return result;
         }
-    `);
-    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) {
+        test uint foo21(uint x, uint y) {
             atomic_uint z;
             uint result;
             InterlockedAdd(&z, x, &result);
@@ -6263,11 +6132,7 @@
             InterlockedMin(&z, y, &result);
             return uint(z);
         }
-    `);
-    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) {
+        test uint foo22(uint x, uint y) {
             atomic_uint z;
             uint result;
             InterlockedAdd(&z, x, &result);
@@ -6274,11 +6139,7 @@
             InterlockedMin(&z, y, &result);
             return result;
         }
-    `);
-    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) {
+        test int foo23(int x, int y) {
             atomic_int z;
             int result;
             InterlockedAdd(&z, x, &result);
@@ -6285,11 +6146,7 @@
             InterlockedMin(&z, y, &result);
             return int(z);
         }
-    `);
-    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) {
+        test int foo24(int x, int y) {
             atomic_int z;
             int result;
             InterlockedAdd(&z, x, &result);
@@ -6296,11 +6153,7 @@
             InterlockedMin(&z, y, &result);
             return result;
         }
-    `);
-    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) {
+        test uint foo25(uint x, uint y) {
             atomic_uint z;
             uint result;
             InterlockedAdd(&z, x, &result);
@@ -6307,10 +6160,7 @@
             InterlockedOr(&z, y, &result);
             return uint(z);
         }
-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 7);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
+        test uint foo26(uint x, uint y) {
             atomic_uint z;
             uint result;
             InterlockedAdd(&z, x, &result);
@@ -6317,10 +6167,7 @@
             InterlockedOr(&z, y, &result);
             return result;
         }
-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 3);
-    program = doPrep(`
-        test int foo(int x, int y) {
+        test int foo27(int x, int y) {
             atomic_int z;
             int result;
             InterlockedAdd(&z, x, &result);
@@ -6327,10 +6174,7 @@
             InterlockedOr(&z, y, &result);
             return int(z);
         }
-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 7);
-    program = doPrep(`
-        test int foo(int x, int y) {
+        test int foo28(int x, int y) {
             atomic_int z;
             int result;
             InterlockedAdd(&z, x, &result);
@@ -6337,10 +6181,7 @@
             InterlockedOr(&z, y, &result);
             return result;
         }
-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 3);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
+        test uint foo29(uint x, uint y) {
             atomic_uint z;
             uint result;
             InterlockedAdd(&z, x, &result);
@@ -6347,10 +6188,7 @@
             InterlockedXor(&z, y, &result);
             return uint(z);
         }
-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 6);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
+        test uint foo30(uint x, uint y) {
             atomic_uint z;
             uint result;
             InterlockedAdd(&z, x, &result);
@@ -6357,10 +6195,7 @@
             InterlockedXor(&z, y, &result);
             return result;
         }
-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 3);
-    program = doPrep(`
-        test int foo(int x, int y) {
+        test int foo31(int x, int y) {
             atomic_int z;
             int result;
             InterlockedAdd(&z, x, &result);
@@ -6367,10 +6202,7 @@
             InterlockedXor(&z, y, &result);
             return int(z);
         }
-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 6);
-    program = doPrep(`
-        test int foo(int x, int y) {
+        test int foo32(int x, int y) {
             atomic_int z;
             int result;
             InterlockedAdd(&z, x, &result);
@@ -6377,10 +6209,7 @@
             InterlockedXor(&z, y, &result);
             return result;
         }
-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 3);
-    program = doPrep(`
-        test uint foo(uint x, uint y, uint z) {
+        test uint foo33(uint x, uint y, uint z) {
             atomic_uint w;
             uint result;
             InterlockedAdd(&w, x, &result);
@@ -6387,11 +6216,7 @@
             InterlockedCompareExchange(&w, y, z, &result);
             return uint(w);
         }
-    `);
-    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) {
+        test uint foo34(uint x, uint y, uint z) {
             atomic_uint w;
             uint result;
             InterlockedAdd(&w, x, &result);
@@ -6398,11 +6223,7 @@
             InterlockedCompareExchange(&w, y, z, &result);
             return result;
         }
-    `);
-    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) {
+        test int foo35(int x, int y, int z) {
             atomic_int w;
             int result;
             InterlockedAdd(&w, x, &result);
@@ -6409,11 +6230,7 @@
             InterlockedCompareExchange(&w, y, z, &result);
             return int(w);
         }
-    `);
-    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) {
+        test int foo36(int x, int y, int z) {
             atomic_int w;
             int result;
             InterlockedAdd(&w, x, &result);
@@ -6421,322 +6238,286 @@
             return result;
         }
     `);
-    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);
+    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);
 }
 
 tests.atomicsNull = function()
 {
     let program = doPrep(`
-        test int foo(int z) {
+        test int foo1(int z) {
             atomic_int x;
             InterlockedAdd(&x, z, null);
             return int(x);
         }
-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 6);
-    program = doPrep(`
-        test int foo(int z) {
+        test int foo2(int z) {
             atomic_int x;
             InterlockedAdd(&x, z, null);
             InterlockedAdd(&x, z, null);
             return int(x);
         }
-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 6)]), 12);
-    program = doPrep(`
-        test uint foo(uint z) {
+        test uint foo3(uint z) {
             atomic_uint x;
             InterlockedAdd(&x, z, null);
             return uint(x);
         }
-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 6)]), 6);
-    program = doPrep(`
-        test uint foo(uint z) {
+        test uint foo4(uint z) {
             atomic_uint x;
             InterlockedAdd(&x, z, null);
             InterlockedAdd(&x, z, null);
             return uint(x);
         }
-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 6)]), 12);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
+        test uint foo5(uint x, uint y) {
             atomic_uint z;
             InterlockedAdd(&z, x, null);
             InterlockedAnd(&z, y, null);
             return uint(z);
         }
-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 1);
-    program = doPrep(`
-        test int foo(int x, int y) {
+        test int foo6(int x, int y) {
             atomic_int z;
             InterlockedAdd(&z, x, null);
             InterlockedAnd(&z, y, null);
             return int(z);
         }
-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 1);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
+        test uint foo7(uint x, uint y) {
             atomic_uint z;
             InterlockedAdd(&z, x, null);
             InterlockedExchange(&z, y, null);
             return uint(z);
         }
-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 5);
-    program = doPrep(`
-        test int foo(int x, int y) {
+        test int foo8(int x, int y) {
             atomic_int z;
             InterlockedAdd(&z, x, null);
             InterlockedExchange(&z, y, null);
             return int(z);
         }
-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 5);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
+        test uint foo9(uint x, uint y) {
             atomic_uint z;
             InterlockedAdd(&z, x, null);
             InterlockedMax(&z, y, null);
             return uint(z);
         }
-    `);
-    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) {
+        test int foo10(int x, int y) {
             atomic_int z;
             InterlockedAdd(&z, x, null);
             InterlockedMax(&z, y, null);
             return int(z);
         }
-    `);
-    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) {
+        test uint foo11(uint x, uint y) {
             atomic_uint z;
             InterlockedAdd(&z, x, null);
             InterlockedMin(&z, y, null);
             return uint(z);
         }
-    `);
-    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) {
+        test int foo12(int x, int y) {
             atomic_int z;
             InterlockedAdd(&z, x, null);
             InterlockedMin(&z, y, null);
             return int(z);
         }
-    `);
-    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) {
+        test uint foo13(uint x, uint y) {
             atomic_uint z;
             InterlockedAdd(&z, x, null);
             InterlockedOr(&z, y, null);
             return uint(z);
         }
-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 7);
-    program = doPrep(`
-        test int foo(int x, int y) {
+        test int foo14(int x, int y) {
             atomic_int z;
             InterlockedAdd(&z, x, null);
             InterlockedOr(&z, y, null);
             return int(z);
         }
-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 7);
-    program = doPrep(`
-        test uint foo(uint x, uint y) {
+        test uint foo15(uint x, uint y) {
             atomic_uint z;
             InterlockedAdd(&z, x, null);
             InterlockedXor(&z, y, null);
             return uint(z);
         }
-    `);
-    checkUint(program, callFunction(program, "foo", [makeUint(program, 3), makeUint(program, 5)]), 6);
-    program = doPrep(`
-        test int foo(int x, int y) {
+        test int foo16(int x, int y) {
             atomic_int z;
             InterlockedAdd(&z, x, null);
             InterlockedXor(&z, y, null);
             return int(z);
         }
-    `);
-    checkInt(program, callFunction(program, "foo", [makeInt(program, 3), makeInt(program, 5)]), 6);
-    program = doPrep(`
-        test uint foo(uint x, uint y, uint z) {
+        test uint foo17(uint x, uint y, uint z) {
             atomic_uint w;
             InterlockedAdd(&w, x, null);
             InterlockedCompareExchange(&w, y, z, null);
             return uint(w);
         }
-    `);
-    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) {
+        test int foo18(int x, int y, int z) {
             atomic_int w;
             InterlockedAdd(&w, x, null);
             InterlockedCompareExchange(&w, y, z, null);
             return int(w);
         }
-    `);
-    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() {
+        test int foo19() {
             thread atomic_int* x = null;
             InterlockedAdd(x, 1, null);
             return 1;
         }
-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
+        test int foo20() {
             thread atomic_uint* x = null;
             InterlockedAdd(x, 1, null);
             return 1;
         }
-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
+        test int foo21() {
             thread atomic_int* x = null;
             InterlockedAnd(x, 1, null);
             return 1;
         }
-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
+        test int foo22() {
             thread atomic_uint* x = null;
             InterlockedAnd(x, 1, null);
             return 1;
         }
-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
+        test int foo23() {
             thread atomic_int* x = null;
             InterlockedExchange(x, 1, null);
             return 1;
         }
-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
+        test int foo24() {
             thread atomic_uint* x = null;
             InterlockedExchange(x, 1, null);
             return 1;
         }
-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
+        test int foo25() {
             thread atomic_int* x = null;
             InterlockedMax(x, 1, null);
             return 1;
         }
-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
+        test int foo26() {
             thread atomic_uint* x = null;
             InterlockedMax(x, 1, null);
             return 1;
         }
-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
+        test int foo27() {
             thread atomic_int* x = null;
             InterlockedMin(x, 1, null);
             return 1;
         }
-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
+        test int foo28() {
             thread atomic_uint* x = null;
             InterlockedMin(x, 1, null);
             return 1;
         }
-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
+        test int foo29() {
             thread atomic_int* x = null;
             InterlockedOr(x, 1, null);
             return 1;
         }
-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
+        test int foo30() {
             thread atomic_uint* x = null;
             InterlockedOr(x, 1, null);
             return 1;
         }
-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
+        test int foo31() {
             thread atomic_int* x = null;
             InterlockedXor(x, 1, null);
             return 1;
         }
-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
+        test int foo32() {
             thread atomic_uint* x = null;
             InterlockedXor(x, 1, null);
             return 1;
         }
-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
+        test int foo33() {
             thread atomic_int* x = null;
             InterlockedCompareExchange(x, 1, 2, null);
             return 1;
         }
-    `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
-
-    program = doPrep(`
-        test int foo() {
+        test int foo34() {
             thread atomic_uint* x = null;
             InterlockedCompareExchange(x, 1, 2, null);
             return 1;
         }
     `);
-    checkTrap(program, () => callFunction(program, "foo", []), checkInt);
+    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);
 }
 
 tests.selfCasts = function()
@@ -9088,7 +8869,304 @@
     // FIXME: Gather other components
 }
 
+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);
+}
 
+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);
+}
+
 tests.commentParsing = function() {
     let program = doPrep(`
         /* this comment

Modified: trunk/Tools/WebGPUShadingLanguageRI/index.html (236627 => 236628)


--- 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)
@@ -85,8 +85,7 @@
 <script src=""
 <script src=""
 <script src=""
-<script src=""
-<script src=""
+<script src=""
 <script src=""
 <script src=""
 <script src=""
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to