Title: [222116] trunk/Tools
Revision
222116
Author
[email protected]
Date
2017-09-15 16:44:35 -0700 (Fri, 15 Sep 2017)

Log Message

Rationalize how WSL's operator&[] works
https://bugs.webkit.org/show_bug.cgi?id=176958

Reviewed by Myles Maxfield.
        
This makes operator&[] work with non-array-ref types. The way this works is that if you do base[index]
then we pattern match base's type and proceed accordingly:
        
    If base's type is T^:
        => Reject
            
    If base's type is T[]:
        => Accept
            
    If base's type is T[c]:
        => Wrap it with a MakeArrayRefExpression and accept.
            
    All other cases:
        => Wrap it with a MakePtrExpression and accept.
        
This makes it possible for operator&[] to work with lvalues. It also means that operator&[] gets to
"see" the temporary values we create via snapshot() in the interpreter. We'll have to fix that, and I've
filed bug 176973 for that. Once that's fixed, this will have well-defined behavior, though with the very
peculiar caveat that an _expression_ like this:
        
     totallyNotAnLValue()[42]
        
Could be used to get a pointer to a non-lvalue. But we can be extremely precise about what that means
and prohibit dangling pointers, which is kinda crazy.
        
In order to do this, I had to make MakeArrayRefExpression work, so I did that and added tests for it.

* WebGPUShadingLanguageRI/All.js:
* WebGPUShadingLanguageRI/ArrayRefType.js:
(ArrayRefType.prototype.unifyImpl):
(ArrayRefType.prototype.toString):
(ArrayRefType):
* WebGPUShadingLanguageRI/ArrayType.js:
(ArrayType):
(ArrayType.prototype.get numElementsValue):
(ArrayType.prototype.get size):
(ArrayType.prototype.populateDefaultValue):
(ArrayType.prototype.unifyImpl):
* WebGPUShadingLanguageRI/Checker.js:
* WebGPUShadingLanguageRI/ConvertPtrToArrayRefExpression.js: Added.
(ConvertPtrToArrayRefExpression):
(ConvertPtrToArrayRefExpression.prototype.get lValue):
(ConvertPtrToArrayRefExpression.prototype.toString):
* WebGPUShadingLanguageRI/CreateLiteral.js:
(createLiteral.GenericLiteral.withType):
(createLiteral.GenericLiteral.prototype.get isLiteral):
(createLiteral.GenericLiteral.prototype.unifyImpl):
* WebGPUShadingLanguageRI/DotExpression.js:
(DotExpression.prototype.get addressSpace):
* WebGPUShadingLanguageRI/Evaluator.js:
(Evaluator.prototype.visitMakeArrayRefExpression):
(Evaluator.prototype.visitConvertPtrToArrayRefExpression):
* WebGPUShadingLanguageRI/Intrinsics.js:
(Intrinsics):
* WebGPUShadingLanguageRI/MakeArrayRefExpression.js: Added.
(MakeArrayRefExpression):
(MakeArrayRefExpression.prototype.get lValue):
(MakeArrayRefExpression.prototype.becomeConvertPtrToArrayRefExpression):
(MakeArrayRefExpression.prototype.toString):
* WebGPUShadingLanguageRI/MakePtrExpression.js:
(MakePtrExpression.prototype.toString):
(MakePtrExpression):
* WebGPUShadingLanguageRI/PtrType.js:
(PtrType.prototype.toString):
(PtrType):
* WebGPUShadingLanguageRI/ReferenceType.js:
(ReferenceType):
* WebGPUShadingLanguageRI/Rewriter.js:
(Rewriter.prototype.visitArrayType):
(Rewriter.prototype.visitMakeArrayRefExpression):
(Rewriter.prototype.visitConvertPtrToArrayRefExpression):
* WebGPUShadingLanguageRI/StandardLibrary.js:
* WebGPUShadingLanguageRI/Test.html:
* WebGPUShadingLanguageRI/Test.js:
(TEST_buildArrayThenSumItUsingArrayReference):
(TEST_overrideSubscriptStruct):
(TEST_overrideSubscriptStructAndUsePointers):
(TEST_overrideSubscriptStructAndUsePointersIncorrectly):
(TEST_makeArrayRefFromPointer):
(TEST_makeArrayRefFromArrayRef):
* WebGPUShadingLanguageRI/Visitor.js:
(Visitor.prototype.visitProtocolDecl):

Modified Paths

Added Paths

Diff

Modified: trunk/Tools/ChangeLog (222115 => 222116)


--- trunk/Tools/ChangeLog	2017-09-15 23:27:56 UTC (rev 222115)
+++ trunk/Tools/ChangeLog	2017-09-15 23:44:35 UTC (rev 222116)
@@ -1,5 +1,95 @@
 2017-09-14  Filip Pizlo  <[email protected]>
 
+        Rationalize how WSL's operator&[] works
+        https://bugs.webkit.org/show_bug.cgi?id=176958
+
+        Reviewed by Myles Maxfield.
+        
+        This makes operator&[] work with non-array-ref types. The way this works is that if you do base[index]
+        then we pattern match base's type and proceed accordingly:
+        
+            If base's type is T^:
+                => Reject
+            
+            If base's type is T[]:
+                => Accept
+            
+            If base's type is T[c]:
+                => Wrap it with a MakeArrayRefExpression and accept.
+            
+            All other cases:
+                => Wrap it with a MakePtrExpression and accept.
+        
+        This makes it possible for operator&[] to work with lvalues. It also means that operator&[] gets to
+        "see" the temporary values we create via snapshot() in the interpreter. We'll have to fix that, and I've
+        filed bug 176973 for that. Once that's fixed, this will have well-defined behavior, though with the very
+        peculiar caveat that an _expression_ like this:
+        
+             totallyNotAnLValue()[42]
+        
+        Could be used to get a pointer to a non-lvalue. But we can be extremely precise about what that means
+        and prohibit dangling pointers, which is kinda crazy.
+        
+        In order to do this, I had to make MakeArrayRefExpression work, so I did that and added tests for it.
+
+        * WebGPUShadingLanguageRI/All.js:
+        * WebGPUShadingLanguageRI/ArrayRefType.js:
+        (ArrayRefType.prototype.unifyImpl):
+        (ArrayRefType.prototype.toString):
+        (ArrayRefType):
+        * WebGPUShadingLanguageRI/ArrayType.js:
+        (ArrayType):
+        (ArrayType.prototype.get numElementsValue):
+        (ArrayType.prototype.get size):
+        (ArrayType.prototype.populateDefaultValue):
+        (ArrayType.prototype.unifyImpl):
+        * WebGPUShadingLanguageRI/Checker.js:
+        * WebGPUShadingLanguageRI/ConvertPtrToArrayRefExpression.js: Added.
+        (ConvertPtrToArrayRefExpression):
+        (ConvertPtrToArrayRefExpression.prototype.get lValue):
+        (ConvertPtrToArrayRefExpression.prototype.toString):
+        * WebGPUShadingLanguageRI/CreateLiteral.js:
+        (createLiteral.GenericLiteral.withType):
+        (createLiteral.GenericLiteral.prototype.get isLiteral):
+        (createLiteral.GenericLiteral.prototype.unifyImpl):
+        * WebGPUShadingLanguageRI/DotExpression.js:
+        (DotExpression.prototype.get addressSpace):
+        * WebGPUShadingLanguageRI/Evaluator.js:
+        (Evaluator.prototype.visitMakeArrayRefExpression):
+        (Evaluator.prototype.visitConvertPtrToArrayRefExpression):
+        * WebGPUShadingLanguageRI/Intrinsics.js:
+        (Intrinsics):
+        * WebGPUShadingLanguageRI/MakeArrayRefExpression.js: Added.
+        (MakeArrayRefExpression):
+        (MakeArrayRefExpression.prototype.get lValue):
+        (MakeArrayRefExpression.prototype.becomeConvertPtrToArrayRefExpression):
+        (MakeArrayRefExpression.prototype.toString):
+        * WebGPUShadingLanguageRI/MakePtrExpression.js:
+        (MakePtrExpression.prototype.toString):
+        (MakePtrExpression):
+        * WebGPUShadingLanguageRI/PtrType.js:
+        (PtrType.prototype.toString):
+        (PtrType):
+        * WebGPUShadingLanguageRI/ReferenceType.js:
+        (ReferenceType):
+        * WebGPUShadingLanguageRI/Rewriter.js:
+        (Rewriter.prototype.visitArrayType):
+        (Rewriter.prototype.visitMakeArrayRefExpression):
+        (Rewriter.prototype.visitConvertPtrToArrayRefExpression):
+        * WebGPUShadingLanguageRI/StandardLibrary.js:
+        * WebGPUShadingLanguageRI/Test.html:
+        * WebGPUShadingLanguageRI/Test.js:
+        (TEST_buildArrayThenSumItUsingArrayReference):
+        (TEST_overrideSubscriptStruct):
+        (TEST_overrideSubscriptStructAndUsePointers):
+        (TEST_overrideSubscriptStructAndUsePointersIncorrectly):
+        (TEST_makeArrayRefFromPointer):
+        (TEST_makeArrayRefFromArrayRef):
+        * WebGPUShadingLanguageRI/Visitor.js:
+        (Visitor.prototype.visitProtocolDecl):
+
+2017-09-14  Filip Pizlo  <[email protected]>
+
         WSL should support ++, --, +=, and all of those things
         https://bugs.webkit.org/show_bug.cgi?id=176975
 

Modified: trunk/Tools/WebGPUShadingLanguageRI/All.js (222115 => 222116)


--- trunk/Tools/WebGPUShadingLanguageRI/All.js	2017-09-15 23:27:56 UTC (rev 222115)
+++ trunk/Tools/WebGPUShadingLanguageRI/All.js	2017-09-15 23:44:35 UTC (rev 222116)
@@ -57,6 +57,7 @@
 load("CommaExpression.js");
 load("ConstexprTypeParameter.js");
 load("Continue.js");
+load("ConvertPtrToArrayRefExpression.js");
 load("DereferenceExpression.js");
 load("DoWhileLoop.js");
 load("DotExpression.js");
@@ -89,6 +90,7 @@
 load("LiteralTypeChecker.js");
 load("LogicalNot.js");
 load("LoopChecker.js");
+load("MakeArrayRefExpression.js");
 load("MakePtrExpression.js");
 load("NameContext.js");
 load("NameResolver.js");

Modified: trunk/Tools/WebGPUShadingLanguageRI/ArrayRefType.js (222115 => 222116)


--- trunk/Tools/WebGPUShadingLanguageRI/ArrayRefType.js	2017-09-15 23:27:56 UTC (rev 222115)
+++ trunk/Tools/WebGPUShadingLanguageRI/ArrayRefType.js	2017-09-15 23:44:35 UTC (rev 222116)
@@ -29,15 +29,12 @@
 class ArrayRefType extends ReferenceType {
     unifyImpl(unificationContext, other)
     {
-        if (other instanceof ArrayRefType) {
-            if (this.addressSpace != other.addressSpace)
-                return false;
-        } else {
-            if (!(other instanceof ArrayType))
-                return false;
-            if (this.addressSpace != "thread")
-                return false;
-        }
+        if (!(other instanceof ArrayRefType))
+            return false;
+        
+        if (this.addressSpace != other.addressSpace)
+            return false;
+        
         return this.elementType.unify(unificationContext, other.elementType);
     }
     
@@ -45,7 +42,7 @@
 
     toString()
     {
-        return this.addressSpace + " " + this.elementType + "[]";
+        return this.elementType + "[] " + this.addressSpace;
     }
 }
 

Modified: trunk/Tools/WebGPUShadingLanguageRI/ArrayType.js (222115 => 222116)


--- trunk/Tools/WebGPUShadingLanguageRI/ArrayType.js	2017-09-15 23:27:56 UTC (rev 222115)
+++ trunk/Tools/WebGPUShadingLanguageRI/ArrayType.js	2017-09-15 23:44:35 UTC (rev 222116)
@@ -27,6 +27,8 @@
 class ArrayType extends Type {
     constructor(origin, elementType, numElements)
     {
+        if (!numElements)
+            throw new Error("null numElements");
         super();
         this._origin = origin;
         this._elementType = elementType;
@@ -38,6 +40,13 @@
     get numElements() { return this._numElements; }
     get isPrimitive() { return this.elementType.isPrimitive; }
     
+    get numElementsValue()
+    {
+        if (!(this.numElements.isLiteral))
+            throw new Error("numElements is not a literal: " + this.numElements);
+        return this.numElements.value;
+    }
+
     toString()
     {
         return this.elementType + "[" + this.numElements + "]";
@@ -45,22 +54,23 @@
     
     get size()
     {
-        return this.elementType.size * this.numElements;
+        return this.elementType.size * this.numElementsValue;
     }
     
-    unifyImpl(unificatonContext, other)
+    populateDefaultValue(buffer, offset)
     {
-        if (other instanceof ArrayRefType) {
-            if (other.addressSpace != "thread")
-                return false;
-        } else {
-            if (!(other instanceof ArrayType))
-                return false;
-            
-            if (!this.numElements.unify(unificationContext, other.numElements))
-                return false;
-        }
+        for (let i = 0; i < this.numElementsValue; ++i)
+            this.elementType.populateDefaultValue(buffer, offset + i * this.elementType.size);
+    }
+    
+    unifyImpl(unificationContext, other)
+    {
+        if (!(other instanceof ArrayType))
+            return false;
         
+        if (!this.numElements.unify(unificationContext, other.numElements))
+            return false;
+        
         return this.elementType.unify(unificationContext, other.elementType);
     }
 }

Modified: trunk/Tools/WebGPUShadingLanguageRI/Checker.js (222115 => 222116)


--- trunk/Tools/WebGPUShadingLanguageRI/Checker.js	2017-09-15 23:27:56 UTC (rev 222115)
+++ trunk/Tools/WebGPUShadingLanguageRI/Checker.js	2017-09-15 23:44:35 UTC (rev 222116)
@@ -107,8 +107,15 @@
     
     visitArrayType(node)
     {
+        node.elementType.visit(this);
+        
         if (!node.numElements.isConstexpr)
             throw new WTypeError(node.origin.originString, "Array length must be constexpr");
+        
+        let type = node.numElements.visit(this);
+        
+        if (!type.equalsWithCommit(this._program.intrinsics.uint32))
+            throw new WTypeError(node.origin.originString, "Array length must be a uint32");
     }
     
     visitVariableDecl(node)
@@ -147,7 +154,7 @@
     visitMakePtrExpression(node)
     {
         if (!node.lValue.isLValue)
-            throw new WTypeError(node.origin.originString, "Operand to \\ is not an LValue: " + node.lValue);
+            throw new WTypeError(node.origin.originString, "Operand to & is not an LValue: " + node.lValue);
         
         let elementType = node.lValue.visit(this).unifyNode;
         
@@ -154,6 +161,34 @@
         return new PtrType(node.origin, node.lValue.addressSpace, elementType);
     }
     
+    visitMakeArrayRefExpression(node)
+    {
+        let elementType = node.lValue.visit(this).unifyNode;
+        if (elementType instanceof PtrType) {
+            node.becomeConvertPtrToArrayRefExpression();
+            return new ArrayRefType(node.origin, elementType.addressSpace, elementType.elementType);
+        }
+        
+        if (!node.lValue.isLValue)
+            throw new WTypeError(node.origin.originString, "Operand to @ is not an LValue: " + node.lValue);
+        
+        if (elementType instanceof ArrayRefType)
+            throw new WTypeError(node.origin.originStrimg, "Operand to @ is an array reference: " + elementType);
+        
+        if (elementType instanceof ArrayType) {
+            node.numElements = elementType.numElements;
+            elementType = elementType.elementType;
+        } else
+            node.numElements = UintLiteral.withType(node.origin, 1, this._program.intrinsics.uint32);
+            
+        return new ArrayRefType(node.origin, node.lValue.addressSpace, elementType);
+    }
+    
+    visitConvertToArrayRefExpression(node)
+    {
+        throw new Error("Should not exist yet.");
+    }
+    
     visitDotExpression(node)
     {
         let structType = node.struct.visit(this).unifyNode;
@@ -297,6 +332,24 @@
                 throw new Error("visitor returned null for " + argument);
             return TypeRef.wrap(newArgument);
         });
+        
+        // Here we need to handle the cases where operator&[] is called with a type that isn't sufficiently
+        // referencey.
+        if (node.name == "operator&[]") {
+            let argType = argumentTypes[0].unifyNode;
+            if (argType instanceof PtrType)
+                throw new WTypeError(node.origin.originString, "Pointer subscript is not valid");
+            
+            if (argType instanceof ArrayType) {
+                node.argumentList[0] = new MakeArrayRefExpression(node.origin, node.argumentList[0]);
+                node.argumentList[0].numElements = argType.numElements;
+                argumentTypes[0] = new ArrayRefType(node.origin, "thread", argType.elementType);
+            } else if (!(argType instanceof ArrayRefType)) {
+                node.argumentList[0] = new MakePtrExpression(node.origin, node.argumentList[0]);
+                argumentTypes[0] = new PtrType(node.origin, "thread", argumentTypes[0]);
+            }
+        }
+        
         node.argumentTypes = argumentTypes;
         if (node.returnType)
             node.returnType.visit(this);

Added: trunk/Tools/WebGPUShadingLanguageRI/ConvertPtrToArrayRefExpression.js (0 => 222116)


--- trunk/Tools/WebGPUShadingLanguageRI/ConvertPtrToArrayRefExpression.js	                        (rev 0)
+++ trunk/Tools/WebGPUShadingLanguageRI/ConvertPtrToArrayRefExpression.js	2017-09-15 23:44:35 UTC (rev 222116)
@@ -0,0 +1,41 @@
+/*
+ * 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 ConvertPtrToArrayRefExpression extends _expression_ {
+    constructor(origin, lValue)
+    {
+        super(origin);
+        this._lValue = lValue;
+    }
+    
+    get lValue() { return this._lValue; }
+    
+    toString()
+    {
+        return "@(" + this.lValue + ")";
+    }
+}
+

Modified: trunk/Tools/WebGPUShadingLanguageRI/CreateLiteral.js (222115 => 222116)


--- trunk/Tools/WebGPUShadingLanguageRI/CreateLiteral.js	2017-09-15 23:27:56 UTC (rev 222115)
+++ trunk/Tools/WebGPUShadingLanguageRI/CreateLiteral.js	2017-09-15 23:44:35 UTC (rev 222116)
@@ -34,9 +34,24 @@
             this.type = config.createType.call(this, origin, value);
         }
         
+        static withType(origin, value, type)
+        {
+            let result = new GenericLiteral(origin, value);
+            result.type = TypeRef.wrap(type);
+            return result;
+        }
+        
         get value() { return this._value; }
         get isConstexpr() { return true; }
+        get isLiteral() { return true; }
         
+        unifyImpl(unificationContext, other)
+        {
+            if (!(other instanceof GenericLiteral))
+                return false;
+            return this.value == other.value;
+        }
+        
         toString()
         {
             return config.preferredTypeName + "Literal<" + this.value + ">";

Modified: trunk/Tools/WebGPUShadingLanguageRI/DotExpression.js (222115 => 222116)


--- trunk/Tools/WebGPUShadingLanguageRI/DotExpression.js	2017-09-15 23:27:56 UTC (rev 222115)
+++ trunk/Tools/WebGPUShadingLanguageRI/DotExpression.js	2017-09-15 23:44:35 UTC (rev 222116)
@@ -35,6 +35,7 @@
     get struct() { return this._struct; }
     get fieldName() { return this._fieldName; }
     get isLValue() { return this.struct.isLValue; }
+    get addressSpace() { return this.struct.addressSpace; }
     
     toString()
     {

Modified: trunk/Tools/WebGPUShadingLanguageRI/Evaluator.js (222115 => 222116)


--- trunk/Tools/WebGPUShadingLanguageRI/Evaluator.js	2017-09-15 23:27:56 UTC (rev 222115)
+++ trunk/Tools/WebGPUShadingLanguageRI/Evaluator.js	2017-09-15 23:44:35 UTC (rev 222116)
@@ -106,6 +106,16 @@
         return EPtr.box(node.lValue.visit(this));
     }
     
+    visitMakeArrayRefExpression(node)
+    {
+        return EPtr.box(new EArrayRef(node.lValue.visit(this), node.numElements.visit(this).loadValue()));
+    }
+    
+    visitConvertPtrToArrayRefExpression(node)
+    {
+        return EPtr.box(new EArrayRef(node.lValue.visit(this).loadValue(), 1));
+    }
+    
     visitDotExpression(node)
     {
         let structPtr = node.struct.visit(this);

Modified: trunk/Tools/WebGPUShadingLanguageRI/Intrinsics.js (222115 => 222116)


--- trunk/Tools/WebGPUShadingLanguageRI/Intrinsics.js	2017-09-15 23:27:56 UTC (rev 222115)
+++ trunk/Tools/WebGPUShadingLanguageRI/Intrinsics.js	2017-09-15 23:44:35 UTC (rev 222116)
@@ -104,6 +104,18 @@
             });
         
         this._map.set(
+            "native operator int32<>(uint32)",
+            func => {
+                func.implementation = ([value]) => EPtr.box(value.loadValue() | 0);
+            });
+        
+        this._map.set(
+            "native operator uint32<>(int32)",
+            func => {
+                func.implementation = ([value]) => EPtr.box(value.loadValue() >>> 0);
+            });
+        
+        this._map.set(
             "native int operator+<>(int,int)",
             func => {
                 func.implementation = ([left, right]) =>
@@ -249,16 +261,16 @@
         };
         
         this._map.set(
-            "native thread T^ operator&[]<T>(thread T[],uint)",
+            "native T^ thread operator&[]<T>(T[] thread,uint)",
             arrayElementPtr);
         this._map.set(
-            "native threadgroup T^ operator&[]<T:primitive>(threadgroup T[],uint)",
+            "native T^ threadgroup operator&[]<T:primitive>(T[] threadgroup,uint)",
             arrayElementPtr);
         this._map.set(
-            "native device T^ operator&[]<T:primitive>(device T[],uint)",
+            "native T^ device operator&[]<T:primitive>(T[] device,uint)",
             arrayElementPtr);
         this._map.set(
-            "native constant T^ operator&[]<T:primitive>(constant T[],uint)",
+            "native T^ constant operator&[]<T:primitive>(T[] constant,uint)",
             arrayElementPtr);
     }
     

Added: trunk/Tools/WebGPUShadingLanguageRI/MakeArrayRefExpression.js (0 => 222116)


--- trunk/Tools/WebGPUShadingLanguageRI/MakeArrayRefExpression.js	                        (rev 0)
+++ trunk/Tools/WebGPUShadingLanguageRI/MakeArrayRefExpression.js	2017-09-15 23:44:35 UTC (rev 222116)
@@ -0,0 +1,46 @@
+/*
+ * 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 MakeArrayRefExpression extends _expression_ {
+    constructor(origin, lValue)
+    {
+        super(origin);
+        this._lValue = lValue;
+    }
+    
+    get lValue() { return this._lValue; }
+    
+    becomeConvertPtrToArrayRefExpression()
+    {
+        this.__proto__ = ConvertPtrToArrayRefExpression.prototype;
+    }
+    
+    toString()
+    {
+        return "@" + (this.numElements ? "<<" + this.numElements + ">>" : "") + "(" + this.lValue + ")";
+    }
+}
+

Modified: trunk/Tools/WebGPUShadingLanguageRI/MakePtrExpression.js (222115 => 222116)


--- trunk/Tools/WebGPUShadingLanguageRI/MakePtrExpression.js	2017-09-15 23:27:56 UTC (rev 222115)
+++ trunk/Tools/WebGPUShadingLanguageRI/MakePtrExpression.js	2017-09-15 23:44:35 UTC (rev 222116)
@@ -35,6 +35,6 @@
     
     toString()
     {
-        return "&(" + this.ptr + ")";
+        return "&(" + this.lValue + ")";
     }
 }

Modified: trunk/Tools/WebGPUShadingLanguageRI/PtrType.js (222115 => 222116)


--- trunk/Tools/WebGPUShadingLanguageRI/PtrType.js	2017-09-15 23:27:56 UTC (rev 222115)
+++ trunk/Tools/WebGPUShadingLanguageRI/PtrType.js	2017-09-15 23:44:35 UTC (rev 222116)
@@ -38,7 +38,7 @@
     
     toString()
     {
-        return this.addressSpace + " " + this.elementType + "^";
+        return this.elementType + "^ " + this.addressSpace;
     }
 }
 

Modified: trunk/Tools/WebGPUShadingLanguageRI/ReferenceType.js (222115 => 222116)


--- trunk/Tools/WebGPUShadingLanguageRI/ReferenceType.js	2017-09-15 23:27:56 UTC (rev 222115)
+++ trunk/Tools/WebGPUShadingLanguageRI/ReferenceType.js	2017-09-15 23:44:35 UTC (rev 222116)
@@ -27,6 +27,8 @@
 class ReferenceType extends Type {
     constructor(origin, addressSpace, elementType)
     {
+        if (!elementType)
+            throw new Error("Null elementType");
         super();
         validateAddressSpace(addressSpace);
         this._origin = origin;

Modified: trunk/Tools/WebGPUShadingLanguageRI/Rewriter.js (222115 => 222116)


--- trunk/Tools/WebGPUShadingLanguageRI/Rewriter.js	2017-09-15 23:27:56 UTC (rev 222115)
+++ trunk/Tools/WebGPUShadingLanguageRI/Rewriter.js	2017-09-15 23:44:35 UTC (rev 222116)
@@ -157,7 +157,7 @@
     
     visitArrayType(node)
     {
-        return new ArrayType(node.origin, node.elementType.visit(this));
+        return new ArrayType(node.origin, node.elementType.visit(this), node.numElements.visit(this));
     }
     
     visitAssignment(node)
@@ -189,6 +189,19 @@
         return new MakePtrExpression(node.origin, node.lValue.visit(this));
     }
     
+    visitMakeArrayRefExpression(node)
+    {
+        let result = new MakeArrayRefExpression(node.origin, node.lValue.visit(this));
+        if (node.numElements)
+            result.numElements = node.numElements.visit(this);
+        return result;
+    }
+    
+    visitConvertPtrToArrayRefExpression(node)
+    {
+        return new ConvertPtrToArrayRefExpression(node.origin, node.lValue.visit(this));
+    }
+    
     visitVariableRef(node)
     {
         let result = new VariableRef(node.origin, node.name);

Modified: trunk/Tools/WebGPUShadingLanguageRI/StandardLibrary.js (222115 => 222116)


--- trunk/Tools/WebGPUShadingLanguageRI/StandardLibrary.js	2017-09-15 23:27:56 UTC (rev 222115)
+++ trunk/Tools/WebGPUShadingLanguageRI/StandardLibrary.js	2017-09-15 23:44:35 UTC (rev 222116)
@@ -41,6 +41,9 @@
 
 native primitive typedef double;
 
+native operator int32(uint32);
+native operator uint32(int32);
+
 native int operator+(int, int);
 native uint operator+(uint, uint);
 int operator++(int value) { return value + 1; }

Modified: trunk/Tools/WebGPUShadingLanguageRI/Test.html (222115 => 222116)


--- trunk/Tools/WebGPUShadingLanguageRI/Test.html	2017-09-15 23:27:56 UTC (rev 222115)
+++ trunk/Tools/WebGPUShadingLanguageRI/Test.html	2017-09-15 23:44:35 UTC (rev 222116)
@@ -34,6 +34,7 @@
 <script src=""
 <script src=""
 <script src=""
+<script src=""
 <script src=""
 <script src=""
 <script src=""
@@ -66,6 +67,7 @@
 <script src=""
 <script src=""
 <script src=""
+<script src=""
 <script src=""
 <script src=""
 <script src=""

Modified: trunk/Tools/WebGPUShadingLanguageRI/Test.js (222115 => 222116)


--- trunk/Tools/WebGPUShadingLanguageRI/Test.js	2017-09-15 23:27:56 UTC (rev 222115)
+++ trunk/Tools/WebGPUShadingLanguageRI/Test.js	2017-09-15 23:44:35 UTC (rev 222116)
@@ -2358,6 +2358,214 @@
         (e) => e instanceof WTypeError && e.message.indexOf("Type mismatch in variable initialization") != -1);
 }
 
+function TEST_buildArrayThenSumIt()
+{
+    let program = doPrep(`
+        int foo()
+        {
+            int[42] array;
+            for (uint i = 0; i < 42; i = i + 1)
+                array[i] = int(i + 5);
+            int result;
+            for (uint i = 0; i < 42; i = i + 1)
+                result = result + array[i];
+            return result;
+        }
+    `);
+    checkInt(program, callFunction(program, "foo", [], []), 42 * 5 + 42 * 41 / 2);
+}
+
+function TEST_buildArrayThenSumItUsingArrayReference()
+{
+    let program = doPrep(`
+        int bar(thread int[] array)
+        {
+            for (uint i = 0; i < 42; i = i + 1)
+                array[i] = int(i + 5);
+            int result;
+            for (uint i = 0; i < 42; i = i + 1)
+                result = result + array[i];
+            return result;
+        }
+        int foo()
+        {
+            int[42] array;
+            return bar(@array);
+        }
+    `);
+    checkInt(program, callFunction(program, "foo", [], []), 42 * 5 + 42 * 41 / 2);
+}
+
+function TEST_overrideSubscriptStruct()
+{
+    let program = doPrep(`
+        struct Foo {
+            int x;
+            int y;
+        }
+        thread int^ operator&[](thread Foo^ foo, uint index)
+        {
+            if (index == 0)
+                return &foo->x;
+            if (index == 1)
+                return &foo->y;
+            return null;
+        }
+        int foo()
+        {
+            Foo foo;
+            foo.x = 498;
+            foo.y = 19;
+            return foo[0] + foo[1] * 3;
+        }
+    `);
+    checkInt(program, callFunction(program, "foo", [], []), 498 + 19 * 3);
+}
+
+function TEST_overrideSubscriptStructAndDoStores()
+{
+    let program = doPrep(`
+        struct Foo {
+            int x;
+            int y;
+        }
+        thread int^ operator&[](thread Foo^ foo, uint index)
+        {
+            if (index == 0)
+                return &foo->x;
+            if (index == 1)
+                return &foo->y;
+            return null;
+        }
+        int foo()
+        {
+            Foo foo;
+            foo[0] = 498;
+            foo[1] = 19;
+            return foo.x + foo.y;
+        }
+    `);
+    checkInt(program, callFunction(program, "foo", [], []), 498 + 19);
+}
+
+function TEST_overrideSubscriptStructAndUsePointers()
+{
+    let program = doPrep(`
+        struct Foo {
+            int x;
+            int y;
+        }
+        thread int^ operator&[](thread Foo^ foo, uint index)
+        {
+            if (index == 0)
+                return &foo->x;
+            if (index == 1)
+                return &foo->y;
+            return null;
+        }
+        int bar(thread Foo^ foo)
+        {
+            return (^foo)[0] + (^foo)[1];
+        }
+        int foo()
+        {
+            Foo foo;
+            foo.x = 498;
+            foo.y = 19;
+            return bar(&foo);
+        }
+    `);
+    checkInt(program, callFunction(program, "foo", [], []), 498 + 19);
+}
+
+function TEST_overrideSubscriptStructAndUsePointersIncorrectly()
+{
+    checkFail(
+        () => doPrep(`
+            struct Foo {
+                int x;
+                int y;
+            }
+            thread int^ operator&[](thread Foo^ foo, uint index)
+            {
+                if (index == 0)
+                    return &foo->x;
+                if (index == 1)
+                    return &foo->y;
+                return null;
+            }
+            int bar(thread Foo^ foo)
+            {
+                return foo[0] + foo[1];
+            }
+            int foo()
+            {
+                Foo foo;
+                foo.x = 498;
+                foo.y = 19;
+                return bar(&foo);
+            }
+        `),
+        (e) => e instanceof WTypeError);
+}
+
+function TEST_makeArrayRefFromLocal()
+{
+    let program = doPrep(`
+        int bar(thread int[] ref)
+        {
+            return ref[0];
+        }
+        int foo()
+        {
+            int x = 48;
+            return bar(@x);
+        }
+    `);
+    checkInt(program, callFunction(program, "foo", [], []), 48);
+}
+
+function TEST_makeArrayRefFromPointer()
+{
+    let program = doPrep(`
+        int bar(thread int[] ref)
+        {
+            return ref[0];
+        }
+        int baz(thread int^ ptr)
+        {
+            return bar(@ptr);
+        }
+        int foo()
+        {
+            int x = 48;
+            return baz(&x);
+        }
+    `);
+    checkInt(program, callFunction(program, "foo", [], []), 48);
+}
+
+function TEST_makeArrayRefFromArrayRef()
+{
+    checkFail(
+        () => doPrep(`
+            int bar(thread int[] ref)
+            {
+                return ref[0];
+            }
+            int baz(thread int[] ptr)
+            {
+                return bar(@ptr);
+            }
+            int foo()
+            {
+                int x = 48;
+                return baz(@x);
+            }
+        `),
+        (e) => e instanceof WTypeError);
+}
+
 let filter = /.*/; // run everything by default
 if (this["arguments"]) {
     for (let i = 0; i < arguments.length; i++) {

Modified: trunk/Tools/WebGPUShadingLanguageRI/Visitor.js (222115 => 222116)


--- trunk/Tools/WebGPUShadingLanguageRI/Visitor.js	2017-09-15 23:27:56 UTC (rev 222115)
+++ trunk/Tools/WebGPUShadingLanguageRI/Visitor.js	2017-09-15 23:44:35 UTC (rev 222116)
@@ -204,6 +204,18 @@
         node.lValue.visit(this);
     }
     
+    visitMakeArrayRefExpression(node)
+    {
+        node.lValue.visit(this);
+        if (node.numElements)
+            node.numElements.visit(this);
+    }
+    
+    visitConvertPtrToArrayRefExpression(node)
+    {
+        node.lValue.visit(this);
+    }
+    
     visitVariableRef(node)
     {
     }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to