Unreviewed, rolling out r247493.
https://bugs.webkit.org/show_bug.cgi?id=199841
"The new whlsl-for-loop.html test is failing on the bots"
(Requested by rmorisset on #webkit).
Reverted changeset:
"[WHLSL] Desugar for loops and while loops"
https://bugs.webkit.org/show_bug.cgi?id=199726
https://trac.webkit.org/changeset/247493
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@247499 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index bd651a8..024f569 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,17 @@
+2019-07-16 Commit Queue <commit-queue@webkit.org>
+
+ Unreviewed, rolling out r247493.
+ https://bugs.webkit.org/show_bug.cgi?id=199841
+
+ "The new whlsl-for-loop.html test is failing on the bots"
+ (Requested by rmorisset on #webkit).
+
+ Reverted changeset:
+
+ "[WHLSL] Desugar for loops and while loops"
+ https://bugs.webkit.org/show_bug.cgi?id=199726
+ https://trac.webkit.org/changeset/247493
+
2019-07-16 Robin Morisset <rmorisset@apple.com>
[WHLSL] Desugar for loops and while loops
diff --git a/LayoutTests/webgpu/whlsl-for-loop-expected.txt b/LayoutTests/webgpu/whlsl-for-loop-expected.txt
deleted file mode 100644
index ae67e5f..0000000
--- a/LayoutTests/webgpu/whlsl-for-loop-expected.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-
-PASS forLoop
-
diff --git a/LayoutTests/webgpu/whlsl-for-loop.html b/LayoutTests/webgpu/whlsl-for-loop.html
deleted file mode 100644
index 299a9cf..0000000
--- a/LayoutTests/webgpu/whlsl-for-loop.html
+++ /dev/null
@@ -1,153 +0,0 @@
-<!DOCTYPE html>
-<html>
-<meta charset=utf-8>
-<meta name="timeout" content="long">
-<title>Lvalues.</title>
-<script src="js/whlsl-test-harness.js"></script>
-<script src="js/webgpu-functions.js"></script>
-<script src="../resources/testharness.js"></script>
-<script src="../resources/testharnessreport.js"></script>
-<script>
-const whlslTests = {};
-
-whlslTests.forLoop = async () =>
-{
- let program = `
- int foo1(int x)
- {
- int sum = 0;
- int i;
- for (i = 0; i < x; i = i + 1) {
- sum = sum + i;
- }
- return sum;
- }
- int foo2(int x)
- {
- int sum = 0;
- for (int i = 0; i < x; i = i + 1) {
- sum = sum + i;
- }
- return sum;
- }
- int foo3(int x)
- {
- int sum = 0;
- int i = 100;
- for (int i = 0; i < x; i = i + 1) {
- sum = sum + i;
- }
- return sum;
- }
- int foo4(int x)
- {
- int sum = 0;
- for (int i = 0; i < x; i = i + 1) {
- if (i == 4)
- continue;
- sum = sum + i;
- }
- return sum;
- }
- int foo5(int x)
- {
- int sum = 0;
- for (int i = 0; i < x; i = i + 1) {
- if (i == 5)
- break;
- sum = sum + i;
- }
- return sum;
- }
- int foo6(int x)
- {
- int sum = 0;
- for (int i = 0; ; i = i + 1) {
- if (i >= x)
- break;
- sum = sum + i;
- }
- return sum;
- }
- int foo7(int x)
- {
- int sum = 0;
- int i = 0;
- for ( ; ; i = i + 1) {
- if (i >= x)
- break;
- sum = sum + i;
- }
- return sum;
- }
- int foo8(int x)
- {
- int sum = 0;
- int i = 0;
- for ( ; ; ) {
- if (i >= x)
- break;
- sum = sum + i;
- i = i + 1;
- }
- return sum;
- }
- `;
- assert_equals(await callIntFunction(program, "foo1", [makeInt(3)]), 3);
- assert_equals(await callIntFunction(program, "foo1", [makeInt(4)]), 6);
- assert_equals(await callIntFunction(program, "foo1", [makeInt(5)]), 10);
- assert_equals(await callIntFunction(program, "foo2", [makeInt(3)]), 3);
- assert_equals(await callIntFunction(program, "foo2", [makeInt(4)]), 6);
- assert_equals(await callIntFunction(program, "foo2", [makeInt(5)]), 10);
- assert_equals(await callIntFunction(program, "foo3", [makeInt(3)]), 3);
- assert_equals(await callIntFunction(program, "foo3", [makeInt(4)]), 6);
- assert_equals(await callIntFunction(program, "foo3", [makeInt(5)]), 10);
- assert_equals(await callIntFunction(program, "foo4", [makeInt(3)]), 3);
- assert_equals(await callIntFunction(program, "foo4", [makeInt(4)]), 6);
- assert_equals(await callIntFunction(program, "foo4", [makeInt(5)]), 6);
- assert_equals(await callIntFunction(program, "foo4", [makeInt(6)]), 11);
- assert_equals(await callIntFunction(program, "foo5", [makeInt(3)]), 3);
- assert_equals(await callIntFunction(program, "foo5", [makeInt(4)]), 6);
- assert_equals(await callIntFunction(program, "foo5", [makeInt(5)]), 10);
- assert_equals(await callIntFunction(program, "foo5", [makeInt(6)]), 10);
- assert_equals(await callIntFunction(program, "foo5", [makeInt(7)]), 10);
- assert_equals(await callIntFunction(program, "foo6", [makeInt(3)]), 3);
- assert_equals(await callIntFunction(program, "foo6", [makeInt(4)]), 6);
- assert_equals(await callIntFunction(program, "foo6", [makeInt(5)]), 10);
- assert_equals(await callIntFunction(program, "foo6", [makeInt(6)]), 15);
- assert_equals(await callIntFunction(program, "foo6", [makeInt(7)]), 21);
- assert_equals(await callIntFunction(program, "foo7", [makeInt(3)]), 3);
- assert_equals(await callIntFunction(program, "foo7", [makeInt(4)]), 6);
- assert_equals(await callIntFunction(program, "foo7", [makeInt(5)]), 10);
- assert_equals(await callIntFunction(program, "foo7", [makeInt(6)]), 15);
- assert_equals(await callIntFunction(program, "foo7", [makeInt(7)]), 21);
- assert_equals(await callIntFunction(program, "foo8", [makeInt(3)]), 3);
- assert_equals(await callIntFunction(program, "foo8", [makeInt(4)]), 6);
- assert_equals(await callIntFunction(program, "foo8", [makeInt(5)]), 10);
- assert_equals(await callIntFunction(program, "foo8", [makeInt(6)]), 15);
- assert_equals(await callIntFunction(program, "foo8", [makeInt(7)]), 21);
- await checkFail(
- `
- void foo(int x)
- {
- for (int i = 0; ; i = i + 1) {
- break;
- x = i;
- }
- }
- `);
- await checkFail(
- `
- int foo(int x)
- {
- for ( ; x < 10; ) {
- return 7;
- }
- }
- `);
-}
-
-runTests(whlslTests);
-</script>
-</html>
-
diff --git a/LayoutTests/webgpu/whlsl-return-spec-tests.html b/LayoutTests/webgpu/whlsl-return-spec-tests.html
index e12c309..2621a40 100644
--- a/LayoutTests/webgpu/whlsl-return-spec-tests.html
+++ b/LayoutTests/webgpu/whlsl-return-spec-tests.html
@@ -111,16 +111,17 @@
return 11;
}
`);
- await checkFail(
- `
- int foo(int x)
- {
- int y = 6;
- if (x == 7)
- int y = 8;
- return y;
- }
- `);
+
+ program = `
+ int foo(int x)
+ {
+ int y = 6;
+ if (x == 7)
+ int y = 8;
+ return y;
+ }
+ `;
+ assert_equals(await callIntFunction(program, "foo", [makeInt(7)]), 6);
};
whlslTests.returnReferenceToSameParameter = async () => {
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 03a8fa7..dd316b6 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,17 @@
+2019-07-16 Commit Queue <commit-queue@webkit.org>
+
+ Unreviewed, rolling out r247493.
+ https://bugs.webkit.org/show_bug.cgi?id=199841
+
+ "The new whlsl-for-loop.html test is failing on the bots"
+ (Requested by rmorisset on #webkit).
+
+ Reverted changeset:
+
+ "[WHLSL] Desugar for loops and while loops"
+ https://bugs.webkit.org/show_bug.cgi?id=199726
+ https://trac.webkit.org/changeset/247493
+
2019-07-16 Per Arne Vollan <pvollan@apple.com>
Prewarm font cache with more fonts
diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAST.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAST.h
index 0e44612..5794d4e 100644
--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAST.h
+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLAST.h
@@ -101,5 +101,6 @@
#include "WHLSLVariableDeclaration.h"
#include "WHLSLVariableDeclarationsStatement.h"
#include "WHLSLVariableReference.h"
+#include "WHLSLWhileLoop.h"
#endif
diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLForLoop.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLForLoop.h
index fe5936c..f45b974 100644
--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLForLoop.h
+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLForLoop.h
@@ -44,28 +44,33 @@
class ForLoop : public Statement {
public:
- ForLoop(CodeLocation location, UniqueRef<Expression>&& condition, UniqueRef<Expression>&& increment, UniqueRef<Statement>&& body)
+ ForLoop(CodeLocation location, Variant<UniqueRef<Statement>, UniqueRef<Expression>>&& initialization, std::unique_ptr<Expression>&& condition, std::unique_ptr<Expression>&& increment, UniqueRef<Statement>&& body)
: Statement(location)
+ , m_initialization(WTFMove(initialization))
, m_condition(WTFMove(condition))
, m_increment(WTFMove(increment))
, m_body(WTFMove(body))
{
}
- virtual ~ForLoop() = default;
+ virtual ~ForLoop()
+ {
+ }
ForLoop(const ForLoop&) = delete;
ForLoop(ForLoop&&) = default;
bool isForLoop() const override { return true; }
- Expression& condition() { return m_condition; }
- Expression& increment() { return m_increment; }
+ Variant<UniqueRef<Statement>, UniqueRef<Expression>>& initialization() { return m_initialization; }
+ Expression* condition() { return m_condition.get(); }
+ Expression* increment() { return m_increment.get(); }
Statement& body() { return m_body; }
private:
- UniqueRef<Expression> m_condition;
- UniqueRef<Expression> m_increment;
+ Variant<UniqueRef<Statement>, UniqueRef<Expression>> m_initialization;
+ std::unique_ptr<Expression> m_condition;
+ std::unique_ptr<Expression> m_increment;
UniqueRef<Statement> m_body;
};
diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStatement.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStatement.h
index bad93ed..278ad2b 100644
--- a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStatement.h
+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLStatement.h
@@ -62,6 +62,7 @@
virtual bool isSwitchStatement() const { return false; }
virtual bool isTrap() const { return false; }
virtual bool isVariableDeclarationsStatement() const { return false; }
+ virtual bool isWhileLoop() const { return false; }
CodeLocation codeLocation() const { return m_codeLocation; }
void updateCodeLocation(CodeLocation location) { m_codeLocation = location; }
diff --git a/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLWhileLoop.h b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLWhileLoop.h
new file mode 100644
index 0000000..55c0377
--- /dev/null
+++ b/Source/WebCore/Modules/webgpu/WHLSL/AST/WHLSLWhileLoop.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2019 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#pragma once
+
+#if ENABLE(WEBGPU)
+
+#include "WHLSLExpression.h"
+#include "WHLSLLexer.h"
+#include "WHLSLStatement.h"
+#include <wtf/UniqueRef.h>
+
+namespace WebCore {
+
+namespace WHLSL {
+
+namespace AST {
+
+class WhileLoop : public Statement {
+public:
+ WhileLoop(CodeLocation location, UniqueRef<Expression>&& conditional, UniqueRef<Statement>&& body)
+ : Statement(location)
+ , m_conditional(WTFMove(conditional))
+ , m_body(WTFMove(body))
+ {
+ }
+
+ virtual ~WhileLoop() = default;
+
+ WhileLoop(const WhileLoop&) = delete;
+ WhileLoop(WhileLoop&&) = default;
+
+ bool isWhileLoop() const override { return true; }
+
+ Expression& conditional() { return m_conditional; }
+ Statement& body() { return m_body; }
+
+private:
+ UniqueRef<Expression> m_conditional;
+ UniqueRef<Statement> m_body;
+};
+
+} // namespace AST
+
+}
+
+}
+
+SPECIALIZE_TYPE_TRAITS_WHLSL_STATEMENT(WhileLoop, isWhileLoop())
+
+#endif
diff --git a/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp b/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp
index a206b45..2b57933 100644
--- a/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp
+++ b/Source/WebCore/Modules/webgpu/WHLSL/Metal/WHLSLFunctionWriter.cpp
@@ -128,6 +128,7 @@
void visit(AST::SwitchCase&) override;
void visit(AST::Trap&) override;
void visit(AST::VariableDeclarationsStatement&) override;
+ void visit(AST::WhileLoop&) override;
void visit(AST::IntegerLiteral&) override;
void visit(AST::UnsignedIntegerLiteral&) override;
void visit(AST::FloatLiteral&) override;
@@ -349,9 +350,24 @@
emitLoop(LoopConditionLocation::AfterBody, &doWhileLoop.conditional(), nullptr, doWhileLoop.body());
}
+void FunctionDefinitionWriter::visit(AST::WhileLoop& whileLoop)
+{
+ emitLoop(LoopConditionLocation::BeforeBody, &whileLoop.conditional(), nullptr, whileLoop.body());
+}
+
void FunctionDefinitionWriter::visit(AST::ForLoop& forLoop)
{
- emitLoop(LoopConditionLocation::BeforeBody, &forLoop.condition(), &forLoop.increment(), forLoop.body());
+ m_stringBuilder.append("{\n");
+
+ WTF::visit(WTF::makeVisitor([&](AST::Statement& statement) {
+ checkErrorAndVisit(statement);
+ }, [&](UniqueRef<AST::Expression>& expression) {
+ checkErrorAndVisit(expression);
+ takeLastValue(); // We don't need to do anything with the result.
+ }), forLoop.initialization());
+
+ emitLoop(LoopConditionLocation::BeforeBody, forLoop.condition(), forLoop.increment(), forLoop.body());
+ m_stringBuilder.append("}\n");
}
void FunctionDefinitionWriter::visit(AST::IfStatement& ifStatement)
diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.cpp
index 362a862..5cfc8e2 100644
--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.cpp
+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.cpp
@@ -393,6 +393,14 @@
m_out.print("continue");
}
+void ASTDumper::visit(AST::WhileLoop& whileLoop)
+{
+ m_out.print("while (");
+ visit(whileLoop.conditional());
+ m_out.print(")");
+ visit(whileLoop.body());
+}
+
void ASTDumper::visit(AST::DoWhileLoop& doWhileLoop)
{
m_out.print("do ");
@@ -404,10 +412,18 @@
void ASTDumper::visit(AST::ForLoop& forLoop)
{
- m_out.print("for (; ");
- visit(forLoop.condition());
+ m_out.print("for (");
+ WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::Statement>& statement) {
+ visit(statement);
+ }, [&](UniqueRef<AST::Expression>& expression) {
+ visit(expression);
+ }), forLoop.initialization());
m_out.print("; ");
- visit(forLoop.increment());
+ if (forLoop.condition())
+ visit(*forLoop.condition());
+ m_out.print("; ");
+ if (forLoop.increment())
+ visit(*forLoop.increment());
m_out.print(") ");
visit(forLoop.body());
}
diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.h
index cb3e110..0ab09ff 100644
--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.h
+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLASTDumper.h
@@ -100,6 +100,7 @@
void visit(AST::SwitchStatement&) override;
void visit(AST::Trap&) override;
void visit(AST::VariableDeclarationsStatement&) override;
+ void visit(AST::WhileLoop&) override;
void visit(AST::VariableDeclaration&) override;
void visit(AST::AssignmentExpression&) override;
void visit(AST::CallExpression&) override;
diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp
index 721e0ba..06997bf 100644
--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp
+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLChecker.cpp
@@ -57,6 +57,7 @@
#include "WHLSLSwitchStatement.h"
#include "WHLSLTernaryExpression.h"
#include "WHLSLVisitor.h"
+#include "WHLSLWhileLoop.h"
#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
#include <wtf/Ref.h>
@@ -500,6 +501,7 @@
void visit(AST::LogicalNotExpression&) override;
void visit(AST::LogicalExpression&) override;
void visit(AST::IfStatement&) override;
+ void visit(AST::WhileLoop&) override;
void visit(AST::DoWhileLoop&) override;
void visit(AST::ForLoop&) override;
void visit(AST::SwitchStatement&) override;
@@ -1245,6 +1247,13 @@
checkErrorAndVisit(*ifStatement.elseBody());
}
+void Checker::visit(AST::WhileLoop& whileLoop)
+{
+ if (!recurseAndRequireBoolType(whileLoop.conditional()))
+ return;
+ checkErrorAndVisit(whileLoop.body());
+}
+
void Checker::visit(AST::DoWhileLoop& doWhileLoop)
{
checkErrorAndVisit(doWhileLoop.body());
@@ -1253,9 +1262,19 @@
void Checker::visit(AST::ForLoop& forLoop)
{
- if (!recurseAndRequireBoolType(forLoop.condition()))
+ WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::Statement>& statement) {
+ checkErrorAndVisit(statement);
+ }, [&](UniqueRef<AST::Expression>& expression) {
+ checkErrorAndVisit(expression);
+ }), forLoop.initialization());
+ if (error())
return;
- checkErrorAndVisit(forLoop.increment());
+ if (forLoop.condition()) {
+ if (!recurseAndRequireBoolType(*forLoop.condition()))
+ return;
+ }
+ if (forLoop.increment())
+ checkErrorAndVisit(*forLoop.increment());
checkErrorAndVisit(forLoop.body());
}
@@ -1415,7 +1434,7 @@
void Checker::visit(AST::CommaExpression& commaExpression)
{
- ASSERT(!commaExpression.list().isEmpty());
+ ASSERT(commaExpression.list().size() > 0);
Visitor::visit(commaExpression);
if (error())
return;
diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.cpp
index 6991fb3..3660439 100644
--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.cpp
+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.cpp
@@ -43,6 +43,7 @@
#include "WHLSLTypeReference.h"
#include "WHLSLVariableDeclaration.h"
#include "WHLSLVariableReference.h"
+#include "WHLSLWhileLoop.h"
namespace WebCore {
@@ -119,33 +120,48 @@
if (error())
return;
- checkErrorAndVisit(ifStatement.body());
+ {
+ NameContext nameContext(&m_nameContext);
+ NameResolver newNameResolver(*this, nameContext);
+ newNameResolver.checkErrorAndVisit(ifStatement.body());
+ }
if (error())
return;
- if (ifStatement.elseBody())
- checkErrorAndVisit(*ifStatement.elseBody());
+ if (ifStatement.elseBody()) {
+ NameContext nameContext(&m_nameContext);
+ NameResolver newNameResolver(*this, nameContext);
+ newNameResolver.checkErrorAndVisit(*ifStatement.elseBody());
+ }
+}
+
+void NameResolver::visit(AST::WhileLoop& whileLoop)
+{
+ checkErrorAndVisit(whileLoop.conditional());
+ if (error())
+ return;
+
+ NameContext nameContext(&m_nameContext);
+ NameResolver newNameResolver(*this, nameContext);
+ newNameResolver.checkErrorAndVisit(whileLoop.body());
}
void NameResolver::visit(AST::DoWhileLoop& whileLoop)
{
- checkErrorAndVisit(whileLoop.body());
- if (error())
- return;
+ {
+ NameContext nameContext(&m_nameContext);
+ NameResolver newNameResolver(*this, nameContext);
+ newNameResolver.checkErrorAndVisit(whileLoop.body());
+ }
checkErrorAndVisit(whileLoop.conditional());
}
void NameResolver::visit(AST::ForLoop& forLoop)
{
- checkErrorAndVisit(forLoop.condition());
- if (error())
- return;
- checkErrorAndVisit(forLoop.increment());
- if (error())
- return;
-
- checkErrorAndVisit(forLoop.body());
+ NameContext nameContext(&m_nameContext);
+ NameResolver newNameResolver(*this, nameContext);
+ newNameResolver.Visitor::visit(forLoop);
}
void NameResolver::visit(AST::VariableDeclaration& variableDeclaration)
diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.h
index 14cfb65..3acdadf 100644
--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.h
+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLNameResolver.h
@@ -50,6 +50,7 @@
void visit(AST::TypeReference&) override;
void visit(AST::Block&) override;
void visit(AST::IfStatement&) override;
+ void visit(AST::WhileLoop&) override;
void visit(AST::DoWhileLoop&) override;
void visit(AST::ForLoop&) override;
void visit(AST::VariableDeclaration&) override;
diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.cpp
index 2be1217..20cb939 100644
--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.cpp
+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.cpp
@@ -1063,8 +1063,7 @@
AST::Statements statements;
while (!peekTypes<Token::Type::RightCurlyBracket, Token::Type::Case, Token::Type::Default>()) {
- bool allowVariableDeclarations = true;
- PARSE(statement, Statement, allowVariableDeclarations);
+ PARSE(statement, Statement);
statements.append(WTFMove(*statement));
}
@@ -1143,52 +1142,51 @@
}
}
-auto Parser::parseForLoop() -> Expected<AST::Block, Error>
+auto Parser::parseForLoop() -> Expected<AST::ForLoop, Error>
{
CONSUME_TYPE(origin, For);
CONSUME_TYPE(leftParenthesis, LeftParenthesis);
+ auto parseRemainder = [&](Variant<UniqueRef<AST::Statement>, UniqueRef<AST::Expression>>&& initialization) -> Expected<AST::ForLoop, Error> {
+ CONSUME_TYPE(semicolon, Semicolon);
+
+ std::unique_ptr<AST::Expression> condition(nullptr);
+ if (!tryType(Token::Type::Semicolon)) {
+ if (auto expression = parseExpression())
+ condition = (*expression).moveToUniquePtr();
+ else
+ return Unexpected<Error>(expression.error());
+ CONSUME_TYPE(secondSemicolon, Semicolon);
+ }
+
+ std::unique_ptr<AST::Expression> increment(nullptr);
+ if (!tryType(Token::Type::RightParenthesis)) {
+ if (auto expression = parseExpression())
+ increment = (*expression).moveToUniquePtr();
+ else
+ return Unexpected<Error>(expression.error());
+ CONSUME_TYPE(rightParenthesis, RightParenthesis);
+ }
+
+ PARSE(body, Statement);
+ AST::CodeLocation location(origin->codeLocation, (*body)->codeLocation());
+ return AST::ForLoop(location, WTFMove(initialization), WTFMove(condition), WTFMove(increment), WTFMove(*body));
+ };
auto variableDeclarations = backtrackingScope<Expected<AST::VariableDeclarationsStatement, Error>>([&]() {
return parseVariableDeclarations();
});
- Optional<UniqueRef<AST::Statement>> initialization;
- if (variableDeclarations)
- initialization = static_cast<UniqueRef<AST::Statement>>(makeUniqueRef<AST::VariableDeclarationsStatement>(WTFMove(*variableDeclarations)));
- else {
- PARSE(effectfulExpression, EffectfulExpression);
- initialization = WTFMove(*effectfulExpression);
+ if (variableDeclarations) {
+ UniqueRef<AST::Statement> declarationStatement = makeUniqueRef<AST::VariableDeclarationsStatement>(WTFMove(*variableDeclarations));
+ return parseRemainder(WTFMove(declarationStatement));
}
- CONSUME_TYPE(semicolon, Semicolon);
+ PARSE(effectfulExpression, EffectfulExpression);
- Optional<UniqueRef<AST::Expression>> condition;
- auto secondSemicolon = tryType(Token::Type::Semicolon);
- if (!secondSemicolon) {
- PARSE(expression, Expression);
- condition = WTFMove(*expression);
- CONSUME_TYPE(secondSemicolon, Semicolon);
- } else
- condition = static_cast<UniqueRef<AST::Expression>>(makeUniqueRef<AST::BooleanLiteral>(*secondSemicolon, true));
-
- Optional<UniqueRef<AST::Expression>> increment;
- auto rightParenthesis = tryType(Token::Type::RightParenthesis);
- if (!rightParenthesis) {
- PARSE(expression, Expression);
- increment = WTFMove(*expression);
- CONSUME_TYPE(rightParenthesis, RightParenthesis);
- } else
- increment = static_cast<UniqueRef<AST::Expression>>(makeUniqueRef<AST::BooleanLiteral>(*origin, true)); // FIXME: NullLiteral would make more sense, but is buggy right now. Anything side-effect free is fine.
-
- PARSE(body, Statement);
- AST::CodeLocation location(origin->codeLocation, (*body)->codeLocation());
-
- auto forLoop = makeUniqueRef<AST::ForLoop>(location, WTFMove(*condition), WTFMove(*increment), WTFMove(*body));
- AST::Statements statements = Vector<UniqueRef<AST::Statement>>::from(WTFMove(*initialization), WTFMove(forLoop));
- return AST::Block(location, WTFMove(statements));
+ return parseRemainder(WTFMove(*effectfulExpression));
}
-auto Parser::parseWhileLoop() -> Expected<AST::ForLoop, Error>
+auto Parser::parseWhileLoop() -> Expected<AST::WhileLoop, Error>
{
CONSUME_TYPE(origin, While);
CONSUME_TYPE(leftParenthesis, LeftParenthesis);
@@ -1197,8 +1195,7 @@
PARSE(body, Statement);
AST::CodeLocation location(origin->codeLocation, (*body)->codeLocation());
- auto increment = makeUniqueRef<AST::BooleanLiteral>(*origin, true); // FIXME: NullLiteral would make more sense, but is buggy right now. Anything side-effect free is fine.
- return AST::ForLoop(location, WTFMove(*conditional), WTFMove(increment), WTFMove(*body));
+ return AST::WhileLoop(location, WTFMove(*conditional), WTFMove(*body));
}
auto Parser::parseDoWhileLoop() -> Expected<AST::DoWhileLoop, Error>
@@ -1257,7 +1254,7 @@
return AST::VariableDeclarationsStatement({ origin->startOffset(), endOffset }, WTFMove(result));
}
-auto Parser::parseStatement(bool allowVariableDeclarations) -> Expected<UniqueRef<AST::Statement>, Error>
+auto Parser::parseStatement() -> Expected<UniqueRef<AST::Statement>, Error>
{
PEEK(token);
switch (token->type) {
@@ -1275,11 +1272,11 @@
}
case Token::Type::For: {
PARSE(forLoop, ForLoop);
- return { makeUniqueRef<AST::Block>(WTFMove(*forLoop)) };
+ return { makeUniqueRef<AST::ForLoop>(WTFMove(*forLoop)) };
}
case Token::Type::While: {
PARSE(whileLoop, WhileLoop);
- return { makeUniqueRef<AST::ForLoop>(WTFMove(*whileLoop)) };
+ return { makeUniqueRef<AST::WhileLoop>(WTFMove(*whileLoop)) };
}
case Token::Type::Do: {
PARSE(doWhileLoop, DoWhileLoop);
@@ -1349,33 +1346,27 @@
}
{
- auto effectfulExpressionStatement = backtrackingScope<Expected<UniqueRef<AST::Statement>, Error>>([&]() -> Expected<UniqueRef<AST::Statement>, Error> {
+ auto effectfulExpression = backtrackingScope<Expected<UniqueRef<AST::Expression>, Error>>([&]() -> Expected<UniqueRef<AST::Expression>, Error> {
PARSE(result, EffectfulExpression);
CONSUME_TYPE(semicolon, Semicolon);
return result;
});
- if (effectfulExpressionStatement)
- return effectfulExpressionStatement;
+ if (effectfulExpression)
+ return { makeUniqueRef<AST::EffectfulExpressionStatement>(WTFMove(*effectfulExpression)) };
}
- if (allowVariableDeclarations) {
- PARSE(variableDeclarations, VariableDeclarations);
- CONSUME_TYPE(semicolon, Semicolon);
- return { makeUniqueRef<AST::VariableDeclarationsStatement>(WTFMove(*variableDeclarations)) };
- }
-
- return Unexpected<Error>("A variable declaration is only valid inside a block");
+ PARSE(variableDeclarations, VariableDeclarations);
+ CONSUME_TYPE(semicolon, Semicolon);
+ return { makeUniqueRef<AST::VariableDeclarationsStatement>(WTFMove(*variableDeclarations)) };
}
-auto Parser::parseEffectfulExpression() -> Expected<UniqueRef<AST::Statement>, Error>
+auto Parser::parseEffectfulExpression() -> Expected<UniqueRef<AST::Expression>, Error>
{
PEEK(origin);
- if (origin->type == Token::Type::Semicolon) {
- AST::Statements statements;
- return { makeUniqueRef<AST::Block>(*origin, WTFMove(statements)) };
- }
-
Vector<UniqueRef<AST::Expression>> expressions;
+ if (origin->type == Token::Type::Semicolon)
+ return { makeUniqueRef<AST::CommaExpression>(*origin, WTFMove(expressions)) };
+
PARSE(effectfulExpression, EffectfulAssignment);
expressions.append(WTFMove(*effectfulExpression));
@@ -1385,11 +1376,10 @@
}
if (expressions.size() == 1)
- return { makeUniqueRef<AST::EffectfulExpressionStatement>(WTFMove(expressions[0])) };
+ return WTFMove(expressions[0]);
unsigned endOffset = m_lexer.peek().startOffset();
AST::CodeLocation location(origin->startOffset(), endOffset);
- auto expression = makeUniqueRef<AST::CommaExpression>(location, WTFMove(expressions));
- return { makeUniqueRef<AST::EffectfulExpressionStatement>(WTFMove(expression)) };
+ return { makeUniqueRef<AST::CommaExpression>(location, WTFMove(expressions)) };
}
auto Parser::parseEffectfulAssignment() -> Expected<UniqueRef<AST::Expression>, Error>
diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.h
index 901097d..400ce66 100644
--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.h
+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLParser.h
@@ -91,6 +91,7 @@
#include "WHLSLVariableDeclaration.h"
#include "WHLSLVariableDeclarationsStatement.h"
#include "WHLSLVariableReference.h"
+#include "WHLSLWhileLoop.h"
#include <wtf/Expected.h>
#include <wtf/Optional.h>
#include <wtf/PrintStream.h>
@@ -202,14 +203,14 @@
Expected<AST::IfStatement, Error> parseIfStatement();
Expected<AST::SwitchStatement, Error> parseSwitchStatement();
Expected<AST::SwitchCase, Error> parseSwitchCase();
- Expected<AST::Block, Error> parseForLoop();
- Expected<AST::ForLoop, Error> parseWhileLoop();
+ Expected<AST::ForLoop, Error> parseForLoop();
+ Expected<AST::WhileLoop, Error> parseWhileLoop();
Expected<AST::DoWhileLoop, Error> parseDoWhileLoop();
Expected<AST::VariableDeclaration, Error> parseVariableDeclaration(UniqueRef<AST::UnnamedType>&&);
Expected<AST::VariableDeclarationsStatement, Error> parseVariableDeclarations();
- Expected<UniqueRef<AST::Statement>, Error> parseStatement(bool allowVariableDeclaration = false);
+ Expected<UniqueRef<AST::Statement>, Error> parseStatement();
- Expected<UniqueRef<AST::Statement>, Error> parseEffectfulExpression();
+ Expected<UniqueRef<AST::Expression>, Error> parseEffectfulExpression();
Expected<UniqueRef<AST::Expression>, Error> parseEffectfulAssignment();
struct SuffixExpression {
SuffixExpression(UniqueRef<AST::Expression>&& result, bool success)
diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLStatementBehaviorChecker.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLStatementBehaviorChecker.cpp
index 474fc80..b4bcd61 100644
--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLStatementBehaviorChecker.cpp
+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLStatementBehaviorChecker.cpp
@@ -44,6 +44,7 @@
#include "WHLSLTrap.h"
#include "WHLSLVariableDeclarationsStatement.h"
#include "WHLSLVisitor.h"
+#include "WHLSLWhileLoop.h"
#include <cstdint>
#include <wtf/OptionSet.h>
#include <wtf/Vector.h>
@@ -108,6 +109,9 @@
void visit(AST::ForLoop& forLoop) override
{
+ // The initialization always has a behavior of Nothing, which we already add unconditionally below,
+ // so we can just ignore the initialization.
+
checkErrorAndVisit(forLoop.body());
if (error())
return;
@@ -118,6 +122,18 @@
m_stack.append(b);
}
+ void visit(AST::WhileLoop& whileLoop) override
+ {
+ checkErrorAndVisit(whileLoop.body());
+ if (error())
+ return;
+ auto b = m_stack.takeLast();
+ b.remove(Behavior::Break);
+ b.remove(Behavior::Continue);
+ b.add(Behavior::Nothing);
+ m_stack.append(b);
+ }
+
void visit(AST::SwitchCase& switchCase) override
{
Visitor::visit(switchCase);
diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.cpp b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.cpp
index 372e661..bf12e63 100644
--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.cpp
+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.cpp
@@ -331,10 +331,10 @@
checkErrorAndVisit(downcast<AST::SwitchStatement>(statement));
else if (is<AST::Trap>(statement))
checkErrorAndVisit(downcast<AST::Trap>(statement));
- else {
- ASSERT(is<AST::VariableDeclarationsStatement>(statement));
+ else if (is<AST::VariableDeclarationsStatement>(statement))
checkErrorAndVisit(downcast<AST::VariableDeclarationsStatement>(statement));
- }
+ else
+ checkErrorAndVisit(downcast<AST::WhileLoop>(statement));
}
void Visitor::visit(AST::Break&)
@@ -427,8 +427,15 @@
void Visitor::visit(AST::ForLoop& forLoop)
{
- checkErrorAndVisit(forLoop.condition());
- checkErrorAndVisit(forLoop.increment());
+ WTF::visit(WTF::makeVisitor([&](UniqueRef<AST::Statement>& statement) {
+ checkErrorAndVisit(statement);
+ }, [&](UniqueRef<AST::Expression>& expression) {
+ checkErrorAndVisit(expression);
+ }), forLoop.initialization());
+ if (forLoop.condition())
+ checkErrorAndVisit(*forLoop.condition());
+ if (forLoop.increment())
+ checkErrorAndVisit(*forLoop.increment());
checkErrorAndVisit(forLoop.body());
}
@@ -470,6 +477,12 @@
checkErrorAndVisit(variableDeclaration.get());
}
+void Visitor::visit(AST::WhileLoop& whileLoop)
+{
+ checkErrorAndVisit(whileLoop.conditional());
+ checkErrorAndVisit(whileLoop.body());
+}
+
void Visitor::visit(AST::VariableDeclaration& variableDeclaration)
{
if (variableDeclaration.type())
diff --git a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.h b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.h
index a3fa247..ec396fd 100644
--- a/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.h
+++ b/Source/WebCore/Modules/webgpu/WHLSL/WHLSLVisitor.h
@@ -85,6 +85,7 @@
class SwitchStatement;
class Trap;
class VariableDeclarationsStatement;
+class WhileLoop;
class VariableDeclaration;
class AssignmentExpression;
class CallExpression;
@@ -165,6 +166,7 @@
virtual void visit(AST::SwitchStatement&);
virtual void visit(AST::Trap&);
virtual void visit(AST::VariableDeclarationsStatement&);
+ virtual void visit(AST::WhileLoop&);
virtual void visit(AST::VariableDeclaration&);
virtual void visit(AST::AssignmentExpression&);
virtual void visit(AST::CallExpression&);
diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
index 2674e46..70ef35a 100644
--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -13256,6 +13256,7 @@
C21BF70121CD89C400227979 /* WHLSLDereferenceExpression.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLDereferenceExpression.h; sourceTree = "<group>"; };
C21BF70221CD89C400227979 /* WHLSLEnumerationMemberLiteral.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLEnumerationMemberLiteral.h; sourceTree = "<group>"; };
C21BF70321CD89C500227979 /* WHLSLReturn.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLReturn.h; sourceTree = "<group>"; };
+ C21BF70421CD89C600227979 /* WHLSLWhileLoop.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLWhileLoop.h; sourceTree = "<group>"; };
C21BF70521CD89C700227979 /* WHLSLFunctionAttribute.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLFunctionAttribute.h; sourceTree = "<group>"; };
C21BF70621CD89C700227979 /* WHLSLCommaExpression.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLCommaExpression.h; sourceTree = "<group>"; };
C21BF70721CD89C800227979 /* WHLSLNullLiteral.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WHLSLNullLiteral.h; sourceTree = "<group>"; };
@@ -17131,6 +17132,7 @@
C21BF71021CD89D000227979 /* WHLSLVariableDeclaration.h */,
C21BF71421CD89D300227979 /* WHLSLVariableDeclarationsStatement.h */,
C21BF71321CD89D200227979 /* WHLSLVariableReference.h */,
+ C21BF70421CD89C600227979 /* WHLSLWhileLoop.h */,
);
path = AST;
sourceTree = "<group>";