Diff
Modified: trunk/Tools/ChangeLog (235248 => 235249)
--- trunk/Tools/ChangeLog 2018-08-23 21:36:40 UTC (rev 235248)
+++ trunk/Tools/ChangeLog 2018-08-23 21:43:03 UTC (rev 235249)
@@ -1,3 +1,36 @@
+2018-08-23 Myles C. Maxfield <[email protected]>
+
+ [WSL] Ternary expressions appear to be unimplemented
+ https://bugs.webkit.org/show_bug.cgi?id=178981
+
+ Reviewed by Saam Barati.
+
+ Implement ternary statements. These can be both lvalues and rvalues. (a ? b : c ? d : e)
+ is parsed as (a ? b : (c ? d : e)).
+
+ * WebGPUShadingLanguageRI/All.js:
+ * WebGPUShadingLanguageRI/Checker.js:
+ (Checker.prototype.visitTernaryExpression):
+ * WebGPUShadingLanguageRI/Evaluator.js:
+ (Evaluator.prototype.visitTernaryExpression):
+ * WebGPUShadingLanguageRI/NormalUsePropertyResolver.js:
+ (NormalUsePropertyResolver.prototype.visitTernaryExpression):
+ (NormalUsePropertyResolver):
+ * WebGPUShadingLanguageRI/Parse.js:
+ (parsePossibleTernaryConditional):
+ * WebGPUShadingLanguageRI/PropertyResolver.js:
+ (PropertyResolver.prototype._visitRValuesWithinLValue.RValueFinder.prototype.visitTernaryExpression):
+ (PropertyResolver.prototype._visitRValuesWithinLValue.RValueFinder):
+ (PropertyResolver.prototype._visitRValuesWithinLValue):
+ * WebGPUShadingLanguageRI/Rewriter.js:
+ (Rewriter.prototype.visitTernaryExpression):
+ * WebGPUShadingLanguageRI/SPIRV.html:
+ * WebGPUShadingLanguageRI/Test.html:
+ * WebGPUShadingLanguageRI/Test.js:
+ * WebGPUShadingLanguageRI/Visitor.js:
+ (Visitor.prototype.visitProtocolDecl):
+ * WebGPUShadingLanguageRI/index.html:
+
2018-08-22 Ryosuke Niwa <[email protected]>
Assert in NetworkBlobRegistry::unregisterBlobURL after network process had terminated
Modified: trunk/Tools/WebGPUShadingLanguageRI/All.js (235248 => 235249)
--- trunk/Tools/WebGPUShadingLanguageRI/All.js 2018-08-23 21:36:40 UTC (rev 235248)
+++ trunk/Tools/WebGPUShadingLanguageRI/All.js 2018-08-23 21:43:03 UTC (rev 235249)
@@ -153,6 +153,7 @@
load("SynthesizeOperatorBool.js");
load("SynthesizeCopyConstructorOperator.js");
load("SynthesizeDefaultConstructorOperator.js");
+load("TernaryExpression.js");
load("TrapStatement.js");
load("TypeDef.js");
load("TypeDefResolver.js");
Modified: trunk/Tools/WebGPUShadingLanguageRI/Checker.js (235248 => 235249)
--- trunk/Tools/WebGPUShadingLanguageRI/Checker.js 2018-08-23 21:36:40 UTC (rev 235248)
+++ trunk/Tools/WebGPUShadingLanguageRI/Checker.js 2018-08-23 21:43:03 UTC (rev 235249)
@@ -648,6 +648,21 @@
result = _expression_.visit(this);
return result;
}
+
+ visitTernaryExpression(node)
+ {
+ this._requireBool(node.predicate);
+ let bodyType = node.bodyExpression.visit(this);
+ let elseType = node.elseExpression.visit(this);
+ if (!bodyType)
+ throw new Error("Ternary _expression_ body has no type: " + node.bodyExpression);
+ if (!elseType)
+ throw new Error("Ternary _expression_ else has no type: " + node.elseExpression);
+ if (!bodyType.equalsWithCommit(elseType))
+ throw new WTypeError("Body and else clause of ternary statement don't have the same type: " + node);
+ node.isLValue = node.bodyExpression.isLValue && node.elseExpression.isLValue;
+ return bodyType;
+ }
visitCallExpression(node)
{
Modified: trunk/Tools/WebGPUShadingLanguageRI/Evaluator.js (235248 => 235249)
--- trunk/Tools/WebGPUShadingLanguageRI/Evaluator.js 2018-08-23 21:36:40 UTC (rev 235248)
+++ trunk/Tools/WebGPUShadingLanguageRI/Evaluator.js 2018-08-23 21:43:03 UTC (rev 235249)
@@ -142,6 +142,14 @@
// This should almost snapshot, except that tail-returning a pointer is totally OK.
return result;
}
+
+ visitTernaryExpression(node)
+ {
+ if (node.predicate.visit(this).loadValue())
+ return node.bodyExpression.visit(this);
+ return node.elseExpression.visit(this);
+
+ }
visitVariableRef(node)
{
Modified: trunk/Tools/WebGPUShadingLanguageRI/NormalUsePropertyResolver.js (235248 => 235249)
--- trunk/Tools/WebGPUShadingLanguageRI/NormalUsePropertyResolver.js 2018-08-23 21:36:40 UTC (rev 235248)
+++ trunk/Tools/WebGPUShadingLanguageRI/NormalUsePropertyResolver.js 2018-08-23 21:43:03 UTC (rev 235249)
@@ -34,5 +34,12 @@
{
return super.visitIndexExpression(node).rewriteAfterCloning();
}
+
+ visitTernaryExpression(node)
+ {
+ let result = super.visitTernaryExpression(node);
+ result.isLValue = node.isLValue;
+ return result;
+ }
}
Modified: trunk/Tools/WebGPUShadingLanguageRI/Parse.js (235248 => 235249)
--- trunk/Tools/WebGPUShadingLanguageRI/Parse.js 2018-08-23 21:36:40 UTC (rev 235248)
+++ trunk/Tools/WebGPUShadingLanguageRI/Parse.js 2018-08-23 21:43:03 UTC (rev 235249)
@@ -520,7 +520,10 @@
let operator = tryConsume("?");
if (!operator)
return predicate;
- return new TernaryExpression(operator, predicate, parsePossibleAssignment(), parsePossibleAssignment());
+ let bodyExpression = parsePossibleAssignment();
+ consume(":");
+ let elseExpression = parsePossibleAssignment();
+ return new TernaryExpression(operator, predicate, bodyExpression, elseExpression);
}
function parsePossibleAssignment(mode)
Modified: trunk/Tools/WebGPUShadingLanguageRI/PropertyResolver.js (235248 => 235249)
--- trunk/Tools/WebGPUShadingLanguageRI/PropertyResolver.js 2018-08-23 21:36:40 UTC (rev 235248)
+++ trunk/Tools/WebGPUShadingLanguageRI/PropertyResolver.js 2018-08-23 21:43:03 UTC (rev 235249)
@@ -59,6 +59,10 @@
{
visit(node.lValue);
}
+
+ visitTernaryExpression(node)
+ {
+ }
}
node.visit(new RValueFinder());
Modified: trunk/Tools/WebGPUShadingLanguageRI/Rewriter.js (235248 => 235249)
--- trunk/Tools/WebGPUShadingLanguageRI/Rewriter.js 2018-08-23 21:36:40 UTC (rev 235248)
+++ trunk/Tools/WebGPUShadingLanguageRI/Rewriter.js 2018-08-23 21:43:03 UTC (rev 235249)
@@ -164,6 +164,11 @@
result.addressSpace = node.addressSpace;
return result;
}
+
+ visitTernaryExpression(node)
+ {
+ return new TernaryExpression(node.origin, node.predicate.visit(this), node.bodyExpression.visit(this), node.elseExpression.visit(this));
+ }
_handlePropertyAccessExpression(result, node)
{
Modified: trunk/Tools/WebGPUShadingLanguageRI/SPIRV.html (235248 => 235249)
--- trunk/Tools/WebGPUShadingLanguageRI/SPIRV.html 2018-08-23 21:36:40 UTC (rev 235248)
+++ trunk/Tools/WebGPUShadingLanguageRI/SPIRV.html 2018-08-23 21:43:03 UTC (rev 235249)
@@ -136,6 +136,7 @@
<script src=""
<script src=""
<script src=""
+ <script src=""
<script src=""
<script src=""
<script src=""
Copied: trunk/Tools/WebGPUShadingLanguageRI/TernaryExpression.js (from rev 235248, trunk/Tools/WebGPUShadingLanguageRI/NormalUsePropertyResolver.js) (0 => 235249)
--- trunk/Tools/WebGPUShadingLanguageRI/TernaryExpression.js (rev 0)
+++ trunk/Tools/WebGPUShadingLanguageRI/TernaryExpression.js 2018-08-23 21:43:03 UTC (rev 235249)
@@ -0,0 +1,47 @@
+/*
+ * 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";
+
+class TernaryExpression extends _expression_ {
+ constructor(origin, predicate, bodyExpression, elseExpression)
+ {
+ super(origin);
+ this._predicate = predicate;
+ this._bodyExpression = bodyExpression;
+ this._elseExpression = elseExpression;
+ this._isLValue = null; // We use null to indicate that we don't know yet.
+ }
+
+ get predicate() { return this._predicate; }
+ get bodyExpression() { return this._bodyExpression; }
+ get elseExpression() { return this._elseExpression; }
+ get isLValue() { return this._isLValue; }
+ set isLValue(value) { this._isLValue = value; }
+
+ toString()
+ {
+ return "(" + this.predicate + ") ? (" + this.bodyExpression + ") : (" + this.elseExpression + ")";
+ }
+}
Modified: trunk/Tools/WebGPUShadingLanguageRI/Test.html (235248 => 235249)
--- trunk/Tools/WebGPUShadingLanguageRI/Test.html 2018-08-23 21:36:40 UTC (rev 235248)
+++ trunk/Tools/WebGPUShadingLanguageRI/Test.html 2018-08-23 21:43:03 UTC (rev 235249)
@@ -130,6 +130,7 @@
<script src=""
<script src=""
<script src=""
+<script src=""
<script src=""
<script src=""
<script src=""
Modified: trunk/Tools/WebGPUShadingLanguageRI/Test.js (235248 => 235249)
--- trunk/Tools/WebGPUShadingLanguageRI/Test.js 2018-08-23 21:36:40 UTC (rev 235248)
+++ trunk/Tools/WebGPUShadingLanguageRI/Test.js 2018-08-23 21:43:03 UTC (rev 235249)
@@ -198,6 +198,68 @@
(e) => e instanceof WSyntaxError);
}
+tests.ternaryExpression = function() {
+ let program = doPrep(`
+ int foo(int x)
+ {
+ return x < 3 ? 4 : 5;
+ }
+ int bar(int x)
+ {
+ int y = 1;
+ int z = 2;
+ (x < 3 ? y : z) = 7;
+ return y;
+ }
+ int baz(int x)
+ {
+ return x < 10 ? 11 : x < 12 ? 14 : 15;
+ }
+ int quux(int x)
+ {
+ return 3 < 4 ? x : 5;
+ }
+ `);
+ checkInt(program, callFunction(program, "foo", [], [makeInt(program, 767)]), 5);
+ checkInt(program, callFunction(program, "foo", [], [makeInt(program, 2)]), 4);
+ checkInt(program, callFunction(program, "bar", [], [makeInt(program, 2)]), 7);
+ checkInt(program, callFunction(program, "bar", [], [makeInt(program, 8)]), 1);
+ 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);
+ checkFail(
+ () => doPrep(`
+ int foo()
+ {
+ int x;
+ (4 < 5 ? x : 7) = 8;
+ }
+ `),
+ (e) => e instanceof WTypeError);
+ checkFail(
+ () => doPrep(`
+ int foo()
+ {
+ int x;
+ float y;
+ return 4 < 5 ? x : y;
+ }
+ `),
+ (e) => e instanceof WTypeError);
+ checkFail(
+ () => doPrep(`
+ int foo()
+ {
+ return 4 < 5 ? 6 : 7.0;
+ }
+ `),
+ (e) => e instanceof WTypeError);
+}
+
tests.literalBool = function() {
let program = doPrep("bool foo() { return true; }");
checkBool(program, callFunction(program, "foo", []), true);
Modified: trunk/Tools/WebGPUShadingLanguageRI/Visitor.js (235248 => 235249)
--- trunk/Tools/WebGPUShadingLanguageRI/Visitor.js 2018-08-23 21:36:40 UTC (rev 235248)
+++ trunk/Tools/WebGPUShadingLanguageRI/Visitor.js 2018-08-23 21:43:03 UTC (rev 235249)
@@ -162,6 +162,13 @@
{
node.ptr.visit(this);
}
+
+ visitTernaryExpression(node)
+ {
+ node.predicate.visit(this);
+ node.bodyExpression.visit(this);
+ node.elseExpression.visit(this);
+ }
_handlePropertyAccessExpression(node)
{
Modified: trunk/Tools/WebGPUShadingLanguageRI/index.html (235248 => 235249)
--- trunk/Tools/WebGPUShadingLanguageRI/index.html 2018-08-23 21:36:40 UTC (rev 235248)
+++ trunk/Tools/WebGPUShadingLanguageRI/index.html 2018-08-23 21:43:03 UTC (rev 235249)
@@ -130,6 +130,7 @@
<script src=""
<script src=""
<script src=""
+<script src=""
<script src=""
<script src=""
<script src=""