[WHLSL] Call expressions shouldn't have type arguments
authormmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 21 Aug 2018 23:28:35 +0000 (23:28 +0000)
committermmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 21 Aug 2018 23:28:35 +0000 (23:28 +0000)
https://bugs.webkit.org/show_bug.cgi?id=188770

Reviewed by Filip Pizlo.

Call expressions only had type arguments for casts, becuase native types can have type arguments.
However, instead of putting those type arguments on the CallExpression, we should parse the casted
type as a real type and not as an identifier, which puts the type arguments in the TypeRef.

Test: casts

* WebGPUShadingLanguageRI/CallExpression.js:
(CallExpression):
(CallExpression.prototype.get name):
(CallExpression.resolve):
(CallExpression.prototype.get typeArguments): Deleted.
(CallExpression.prototype.becomeCast): Deleted.
* WebGPUShadingLanguageRI/NameResolver.js:
(NameResolver.prototype.visitCallExpression):
* WebGPUShadingLanguageRI/Parse.js:
(parseConstexpr):
(parseTypeDef):
(parseLeftOperatorCall):
(parseCallExpression.let.parseArguments):
(parsePossiblePrefix):
(parsePossibleRelationalEquality):
(parseLeftLogicalExpression):
(parseIfStatement):
(parseWhile):
(parseFor):
(parseDo):
* WebGPUShadingLanguageRI/RemoveTypeArguments.js:
* WebGPUShadingLanguageRI/Rewriter.js:
(Rewriter.prototype.visitCallExpression):

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

Tools/ChangeLog
Tools/WebGPUShadingLanguageRI/CallExpression.js
Tools/WebGPUShadingLanguageRI/NameResolver.js
Tools/WebGPUShadingLanguageRI/Parse.js
Tools/WebGPUShadingLanguageRI/RemoveTypeArguments.js
Tools/WebGPUShadingLanguageRI/Rewriter.js
Tools/WebGPUShadingLanguageRI/Test.js

index 57da8bf..c1dd1f5 100644 (file)
@@ -1,3 +1,40 @@
+2018-08-21  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [WHLSL] Call expressions shouldn't have type arguments
+        https://bugs.webkit.org/show_bug.cgi?id=188770
+
+        Reviewed by Filip Pizlo.
+
+        Call expressions only had type arguments for casts, becuase native types can have type arguments.
+        However, instead of putting those type arguments on the CallExpression, we should parse the casted
+        type as a real type and not as an identifier, which puts the type arguments in the TypeRef.
+
+        Test: casts
+
+        * WebGPUShadingLanguageRI/CallExpression.js:
+        (CallExpression):
+        (CallExpression.prototype.get name):
+        (CallExpression.resolve):
+        (CallExpression.prototype.get typeArguments): Deleted.
+        (CallExpression.prototype.becomeCast): Deleted.
+        * WebGPUShadingLanguageRI/NameResolver.js:
+        (NameResolver.prototype.visitCallExpression):
+        * WebGPUShadingLanguageRI/Parse.js:
+        (parseConstexpr):
+        (parseTypeDef):
+        (parseLeftOperatorCall):
+        (parseCallExpression.let.parseArguments):
+        (parsePossiblePrefix):
+        (parsePossibleRelationalEquality):
+        (parseLeftLogicalExpression):
+        (parseIfStatement):
+        (parseWhile):
+        (parseFor):
+        (parseDo):
+        * WebGPUShadingLanguageRI/RemoveTypeArguments.js:
+        * WebGPUShadingLanguageRI/Rewriter.js:
+        (Rewriter.prototype.visitCallExpression):
+
 2018-08-21  Alex Christensen  <achristensen@webkit.org>
 
         Translate WebKit.LimitTitleSize API test into ObjC
 2018-08-21  Alex Christensen  <achristensen@webkit.org>
 
         Translate WebKit.LimitTitleSize API test into ObjC
index 6dba153..b25398f 100644 (file)
 "use strict";
 
 class CallExpression extends Expression {
 "use strict";
 
 class CallExpression extends Expression {
-    constructor(origin, name, typeArguments, argumentList)
+    constructor(origin, name, argumentList)
     {
         super(origin);
         this._name = name;
     {
         super(origin);
         this._name = name;
-        this._typeArguments = typeArguments;
         this._argumentList = argumentList;
         this.func = null;
         this._isCast = false;
         this._argumentList = argumentList;
         this.func = null;
         this._isCast = false;
@@ -37,14 +36,13 @@ class CallExpression extends Expression {
     }
     
     get name() { return this._name; }
     }
     
     get name() { return this._name; }
-    get typeArguments() { return this._typeArguments; }
     get argumentList() { return this._argumentList; }
     get isCast() { return this._isCast; }
     get returnType() { return this._returnType; }
     
     static resolve(origin, possibleOverloads, name, argumentList, argumentTypes, returnType, program)
     {
     get argumentList() { return this._argumentList; }
     get isCast() { return this._isCast; }
     get returnType() { return this._returnType; }
     
     static resolve(origin, possibleOverloads, name, argumentList, argumentTypes, returnType, program)
     {
-        let call = new CallExpression(origin, name, [], argumentList);
+        let call = new CallExpression(origin, name, argumentList);
         call.argumentTypes = argumentTypes.map(argument => argument.visit(new AutoWrapper()));
         call.possibleOverloads = possibleOverloads;
         if (returnType)
         call.argumentTypes = argumentTypes.map(argument => argument.visit(new AutoWrapper()));
         call.possibleOverloads = possibleOverloads;
         if (returnType)
@@ -164,14 +162,6 @@ class CallExpression extends Expression {
         return result;
     }
     
         return result;
     }
     
-    becomeCast(returnType)
-    {
-        this._returnType = new TypeRef(this.origin, this.name);
-        this._returnType.type = returnType;
-        this._name = "operator cast";
-        this._isCast = true;
-    }
-    
     setCastData(returnType)
     {
         this._returnType = returnType;
     setCastData(returnType)
     {
         this._returnType = returnType;
index a2af1d9..f615a2f 100644 (file)
@@ -198,15 +198,13 @@ class NameResolver extends Visitor {
         let funcs = this._nameContext.get(Func, node.name);
         if (funcs)
             node.possibleOverloads = funcs;
         let funcs = this._nameContext.get(Func, node.name);
         if (funcs)
             node.possibleOverloads = funcs;
-        else {
-            let type = this._nameContext.get(Type, node.name);
-            if (!type)
-                throw new WTypeError(node.origin.originString, "Cannot find any function or type named \"" + node.name + "\"");
-            node.becomeCast(type);
+        else if (node.name != "operator cast"){
+            node.setCastData(new TypeRef(node.origin, node.name));
             node.possibleOverloads = this._nameContext.get(Func, "operator cast");
             node.possibleOverloads = this._nameContext.get(Func, "operator cast");
-            if (!node.possibleOverloads)
-                throw new WTypeError(node.origin.originString, "Cannot find any operator cast implementations in cast to " + type);
         }
         }
+
+        if (!node.possibleOverloads)
+            throw new WTypeError(node.origin.originString, "Cannot find any possible overloads for " + node);
         
         super.visitCallExpression(node);
     }
         
         super.visitCallExpression(node);
     }
index c4ae9de..3be30ee 100644 (file)
@@ -188,7 +188,7 @@ function parse(program, origin, originKind, lineNumberOffset, text)
     {
         let token;
         if (token = tryConsume("-"))
     {
         let token;
         if (token = tryConsume("-"))
-            return new CallExpression(token, "operator" + token.text, [], [parseTerm()]);
+            return new CallExpression(token, "operator" + token.text, [parseTerm()]);
         let left = parseTerm();
         if (token = tryConsume("."))
             left = new DotExpression(token, left, consumeKind("identifier").text);
         let left = parseTerm();
         if (token = tryConsume("."))
             left = new DotExpression(token, left, consumeKind("identifier").text);
@@ -285,7 +285,7 @@ function parse(program, origin, originKind, lineNumberOffset, text)
         let origin = consume("typedef");
         let name = consumeKind("identifier").text;
         consume("=");
         let origin = consume("typedef");
         let name = consumeKind("identifier").text;
         consume("=");
-        let type = parseType(true);
+        let type = parseType();
         consume(";");
         return new TypeDef(origin, name, type);
     }
         consume(";");
         return new TypeDef(origin, name, type);
     }
@@ -304,33 +304,50 @@ function parse(program, origin, originKind, lineNumberOffset, text)
         return genericParseLeft(
             texts, nextParser,
             (token, left, right) =>
         return genericParseLeft(
             texts, nextParser,
             (token, left, right) =>
-                new CallExpression(token, "operator" + token.text, [], [left, right]));
+                new CallExpression(token, "operator" + token.text, [left, right]));
     }
     
     function parseCallExpression()
     {
     }
     
     function parseCallExpression()
     {
-        let name = consumeKind("identifier");
-        let typeArguments = parseTypeArguments();
-        consume("(");
-        let argumentList = [];
-        while (!test(")")) {
-            let argument = parsePossibleAssignment();
-            argumentList.push(argument);
-            if (!tryConsume(","))
-                break;
+        let parseArguments = function(origin, callName) {
+            let argumentList = [];
+            while (!test(")")) {
+                let argument = parsePossibleAssignment();
+                argumentList.push(argument);
+                if (!tryConsume(","))
+                    break;
+            }
+            consume(")");
+            return new CallExpression(origin, callName, argumentList);
+        }
+
+        let name = lexer.backtrackingScope(() => {
+            let name = consumeKind("identifier");
+            consume("(");
+            return name;
+        });
+
+        if (name) {
+            let result = parseArguments(name, name.text);
+            return result;
+        } else {
+            let returnType = parseType();
+            consume("(");
+            let result = parseArguments(returnType.origin, "operator cast");
+            result.setCastData(returnType);
+            return result;
         }
         }
-        consume(")");
-        let result = new CallExpression(name, name.text, typeArguments, argumentList);
-        return result;
     }
     
     function isCallExpression()
     {
         return lexer.testScope(() => {
     }
     
     function isCallExpression()
     {
         return lexer.testScope(() => {
-            consumeKind("identifier");
-            parseTypeArguments();
-            consume("(");
-        });
+                consumeKind("identifier");
+                consume("(");
+            }) || lexer.testScope(() => {
+                parseType();
+                consume("(");
+            });
     }
     
     function emitIncrement(token, old, extraArg)
     }
     
     function emitIncrement(token, old, extraArg)
@@ -346,7 +363,7 @@ function parse(program, origin, originKind, lineNumberOffset, text)
         if (name == "operator")
             throw new Error("Invalid name: " + name);
         
         if (name == "operator")
             throw new Error("Invalid name: " + name);
         
-        return new CallExpression(token, name, [], args);
+        return new CallExpression(token, name, args);
     }
     
     function finishParsingPostIncrement(token, left)
     }
     
     function finishParsingPostIncrement(token, left)
@@ -419,7 +436,7 @@ function parse(program, origin, originKind, lineNumberOffset, text)
         if (test("++", "--"))
             return parsePreIncrement();
         if (token = tryConsume("+", "-", "~"))
         if (test("++", "--"))
             return parsePreIncrement();
         if (token = tryConsume("+", "-", "~"))
-            return new CallExpression(token, "operator" + token.text, [], [parsePossiblePrefix()]);
+            return new CallExpression(token, "operator" + token.text, [parsePossiblePrefix()]);
         if (token = tryConsume("*"))
             return new DereferenceExpression(token, parsePossiblePrefix());
         if (token = tryConsume("&"))
         if (token = tryConsume("*"))
             return new DereferenceExpression(token, parsePossiblePrefix());
         if (token = tryConsume("&"))
@@ -428,7 +445,7 @@ function parse(program, origin, originKind, lineNumberOffset, text)
             return new MakeArrayRefExpression(token, parsePossiblePrefix());
         if (token = tryConsume("!")) {
             let remainder = parsePossiblePrefix();
             return new MakeArrayRefExpression(token, parsePossiblePrefix());
         if (token = tryConsume("!")) {
             let remainder = parsePossiblePrefix();
-            return new LogicalNot(token, new CallExpression(remainder.origin, "bool", [], [remainder]));
+            return new LogicalNot(token, new CallExpression(remainder.origin, "bool", [remainder]));
         }
         return parsePossibleSuffix();
     }
         }
         return parsePossibleSuffix();
     }
@@ -458,7 +475,7 @@ function parse(program, origin, originKind, lineNumberOffset, text)
         return genericParseLeft(
             ["==", "!="], parsePossibleRelationalInequality,
             (token, left, right) => {
         return genericParseLeft(
             ["==", "!="], parsePossibleRelationalInequality,
             (token, left, right) => {
-                let result = new CallExpression(token, "operator==", [], [left, right]);
+                let result = new CallExpression(token, "operator==", [left, right]);
                 if (token.text == "!=")
                     result = new LogicalNot(token, result);
                 return result;
                 if (token.text == "!=")
                     result = new LogicalNot(token, result);
                 return result;
@@ -484,7 +501,7 @@ function parse(program, origin, originKind, lineNumberOffset, text)
     {
         return genericParseLeft(
             texts, nextParser,
     {
         return genericParseLeft(
             texts, nextParser,
-            (token, left, right) => new LogicalExpression(token, token.text, new CallExpression(left.origin, "bool", [], [left]), new CallExpression(right.origin, "bool", [], [right])));
+            (token, left, right) => new LogicalExpression(token, token.text, new CallExpression(left.origin, "bool", [left]), new CallExpression(right.origin, "bool", [right])));
     }
     
     function parsePossibleLogicalAnd()
     }
     
     function parsePossibleLogicalAnd()
@@ -621,7 +638,7 @@ function parse(program, origin, originKind, lineNumberOffset, text)
         let elseBody;
         if (tryConsume("else"))
             elseBody = parseStatement();
         let elseBody;
         if (tryConsume("else"))
             elseBody = parseStatement();
-        return new IfStatement(origin, new CallExpression(conditional.origin, "bool", [], [conditional]), body, elseBody);
+        return new IfStatement(origin, new CallExpression(conditional.origin, "bool", [conditional]), body, elseBody);
     }
 
     function parseWhile()
     }
 
     function parseWhile()
@@ -631,7 +648,7 @@ function parse(program, origin, originKind, lineNumberOffset, text)
         let conditional = parseExpression();
         consume(")");
         let body = parseStatement();
         let conditional = parseExpression();
         consume(")");
         let body = parseStatement();
-        return new WhileLoop(origin, new CallExpression(conditional.origin, "bool", [], [conditional]), body);
+        return new WhileLoop(origin, new CallExpression(conditional.origin, "bool", [conditional]), body);
     }
 
     function parseFor()
     }
 
     function parseFor()
@@ -652,7 +669,7 @@ function parse(program, origin, originKind, lineNumberOffset, text)
         else {
             condition = parseExpression();
             consume(";");
         else {
             condition = parseExpression();
             consume(";");
-            condition = new CallExpression(condition.origin, "bool", [], [condition]);
+            condition = new CallExpression(condition.origin, "bool", [condition]);
         }
         let increment;
         if (tryConsume(")"))
         }
         let increment;
         if (tryConsume(")"))
@@ -673,7 +690,7 @@ function parse(program, origin, originKind, lineNumberOffset, text)
         consume("(");
         let conditional = parseExpression();
         consume(")");
         consume("(");
         let conditional = parseExpression();
         consume(")");
-        return new DoWhileLoop(origin, body, new CallExpression(conditional.origin, "bool", [], [conditional]));
+        return new DoWhileLoop(origin, body, new CallExpression(conditional.origin, "bool", [conditional]));
     }
     
     function parseVariableDecls()
     }
     
     function parseVariableDecls()
index 7f90870..93db9e6 100644 (file)
@@ -59,15 +59,7 @@ function removeTypeArguments(program)
             node._name = RemoveTypeArguments.resolveNameAndArguments(node);
             node._typeArguments = null;
         }
             node._name = RemoveTypeArguments.resolveNameAndArguments(node);
             node._typeArguments = null;
         }
-
-        visitCallExpression(node)
-        {
-            node._name = RemoveTypeArguments.resolveNameAndArguments(node);
-            if (!node._name || !node._name.length)
-                throw new Error("lazy");
-            node._typeArguments = null;
-        }
     }
 
     program.visit(new RemoveTypeArguments());
     }
 
     program.visit(new RemoveTypeArguments());
-}
\ No newline at end of file
+}
index b56cd60..d547d20 100644 (file)
@@ -298,7 +298,7 @@ class Rewriter {
     visitCallExpression(node)
     {
         let result = new CallExpression(
     visitCallExpression(node)
     {
         let result = new CallExpression(
-            node.origin, node.name, null,
+            node.origin, node.name,
             node.argumentList.map(argument => Node.visit(argument, this)));
         return this.processDerivedCallData(node, result);
     }
             node.argumentList.map(argument => Node.visit(argument, this)));
         return this.processDerivedCallData(node, result);
     }
index 5d07d9b..df417da 100644 (file)
@@ -5197,6 +5197,50 @@ tests.andReturnedArrayRef = function()
     checkInt(program, callFunction(program, "foo", []), 354);
 }
 
     checkInt(program, callFunction(program, "foo", []), 354);
 }
 
+tests.casts = function()
+{
+    let program = doPrep(`
+        struct Foo {
+            int x;
+        }
+        struct Bar {
+            int y;
+        }
+        operator Bar(Foo foo) {
+            Bar b;
+            b.y = foo.x + 7;
+            return b;
+        }
+        int baz(int z) {
+            Foo foo;
+            foo.x = z;
+            Bar b = Bar(foo);
+            return b.y;
+        }
+    `);
+    checkInt(program, callFunction(program, "baz", [makeInt(program, 6)]), 13);
+    program = doPrep(`
+        struct Foo {
+            int x;
+        }
+        struct Bar {
+            int y;
+        }
+        operator thread Bar*(thread Foo* foo) {
+            Bar b;
+            b.y = (*foo).x + 8;
+            return &b;
+        }
+        int baz(int z) {
+            Foo foo;
+            foo.x = z;
+            thread Bar* b = thread Bar*(&foo);
+            return (*b).y;
+        }
+    `);
+    checkInt(program, callFunction(program, "baz", [makeInt(program, 6)]), 14);
+}
+
 okToTest = true;
 
 let testFilter = /.*/; // run everything by default
 okToTest = true;
 
 let testFilter = /.*/; // run everything by default