Convert IRGenerator::convertDo to DoStatement::Make.
We currently don't have any optimizations for do-statements so the
primary benefit is moving code out of IRGenerator.
Change-Id: Ibc4d1ecd87ebef572e742dfdb15821cf4ac0f047
Bug: skia:11342
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/376179
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/gn/sksl.gni b/gn/sksl.gni
index 37fb4c1..99b3743 100644
--- a/gn/sksl.gni
+++ b/gn/sksl.gni
@@ -90,6 +90,7 @@
"$_src/sksl/ir/SkSLConstructor.h",
"$_src/sksl/ir/SkSLContinueStatement.h",
"$_src/sksl/ir/SkSLDiscardStatement.h",
+ "$_src/sksl/ir/SkSLDoStatement.cpp",
"$_src/sksl/ir/SkSLDoStatement.h",
"$_src/sksl/ir/SkSLEnum.h",
"$_src/sksl/ir/SkSLExpression.h",
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index d0ecf78..35caf01 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -634,23 +634,6 @@
fSymbolTable);
}
-std::unique_ptr<Statement> IRGenerator::convertDo(std::unique_ptr<Statement> stmt,
- std::unique_ptr<Expression> test) {
- if (this->strictES2Mode()) {
- this->errorReporter().error(stmt->fOffset, "do-while loops are not supported");
- return nullptr;
- }
-
- test = this->coerce(std::move(test), *fContext.fTypes.fBool);
- if (!test) {
- return nullptr;
- }
- if (this->detectVarDeclarationWithoutScope(*stmt)) {
- return nullptr;
- }
- return std::make_unique<DoStatement>(stmt->fOffset, std::move(stmt), std::move(test));
-}
-
std::unique_ptr<Statement> IRGenerator::convertDo(const ASTNode& d) {
SkASSERT(d.fKind == ASTNode::Kind::kDo);
auto iter = d.begin();
@@ -662,7 +645,10 @@
if (!test) {
return nullptr;
}
- return this->convertDo(std::move(statement), std::move(test));
+ if (this->detectVarDeclarationWithoutScope(*statement)) {
+ return nullptr;
+ }
+ return DoStatement::Make(fContext, std::move(statement), std::move(test));
}
std::unique_ptr<Statement> IRGenerator::convertSwitch(const ASTNode& s) {
diff --git a/src/sksl/SkSLIRGenerator.h b/src/sksl/SkSLIRGenerator.h
index 8a18349..ce1c6b3 100644
--- a/src/sksl/SkSLIRGenerator.h
+++ b/src/sksl/SkSLIRGenerator.h
@@ -194,8 +194,6 @@
std::unique_ptr<Statement> convertBreak(const ASTNode& b);
std::unique_ptr<Statement> convertContinue(const ASTNode& c);
std::unique_ptr<Statement> convertDiscard(const ASTNode& d);
- std::unique_ptr<Statement> convertDo(std::unique_ptr<Statement> stmt,
- std::unique_ptr<Expression> test);
std::unique_ptr<Statement> convertDo(const ASTNode& d);
std::unique_ptr<Statement> convertSwitch(const ASTNode& s);
std::unique_ptr<Expression> convertBinaryExpression(const ASTNode& expression);
diff --git a/src/sksl/SkSLInliner.cpp b/src/sksl/SkSLInliner.cpp
index 098185f..7899ca4 100644
--- a/src/sksl/SkSLInliner.cpp
+++ b/src/sksl/SkSLInliner.cpp
@@ -450,7 +450,7 @@
case Statement::Kind::kDo: {
const DoStatement& d = statement.as<DoStatement>();
- return std::make_unique<DoStatement>(offset, stmt(d.statement()), expr(d.test()));
+ return DoStatement::Make(*fContext, stmt(d.statement()), expr(d.test()));
}
case Statement::Kind::kExpression: {
const ExpressionStatement& e = statement.as<ExpressionStatement>();
@@ -473,6 +473,7 @@
case Statement::Kind::kInlineMarker:
case Statement::Kind::kNop:
return statement.clone();
+
case Statement::Kind::kReturn: {
const ReturnStatement& r = statement.as<ReturnStatement>();
if (!r.expression()) {
diff --git a/src/sksl/SkSLRehydrator.cpp b/src/sksl/SkSLRehydrator.cpp
index 781827c..95d9f5d 100644
--- a/src/sksl/SkSLRehydrator.cpp
+++ b/src/sksl/SkSLRehydrator.cpp
@@ -363,8 +363,7 @@
case Rehydrator::kDo_Command: {
std::unique_ptr<Statement> stmt = this->statement();
std::unique_ptr<Expression> expr = this->expression();
- return std::unique_ptr<Statement>(new DoStatement(-1, std::move(stmt),
- std::move(expr)));
+ return DoStatement::Make(fContext, std::move(stmt), std::move(expr));
}
case Rehydrator::kExpressionStatement_Command: {
std::unique_ptr<Expression> expr = this->expression();
diff --git a/src/sksl/dsl/DSLCore.cpp b/src/sksl/dsl/DSLCore.cpp
index 7b98cb2..069bc87 100644
--- a/src/sksl/dsl/DSLCore.cpp
+++ b/src/sksl/dsl/DSLCore.cpp
@@ -88,7 +88,7 @@
}
static DSLPossibleStatement Do(DSLStatement stmt, DSLExpression test) {
- return DSLWriter::IRGenerator().convertDo(stmt.release(), test.release());
+ return DoStatement::Make(DSLWriter::Context(), stmt.release(), test.release());
}
static DSLPossibleStatement For(DSLStatement initializer, DSLExpression test,
diff --git a/src/sksl/ir/SkSLDoStatement.cpp b/src/sksl/ir/SkSLDoStatement.cpp
new file mode 100644
index 0000000..cf92764
--- /dev/null
+++ b/src/sksl/ir/SkSLDoStatement.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 Google LLC
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "src/sksl/SkSLContext.h"
+#include "src/sksl/SkSLProgramSettings.h"
+#include "src/sksl/ir/SkSLDoStatement.h"
+
+namespace SkSL {
+
+std::unique_ptr<Statement> DoStatement::Make(const Context& context,
+ std::unique_ptr<Statement> stmt,
+ std::unique_ptr<Expression> test) {
+ if (context.fConfig->strictES2Mode()) {
+ context.fErrors.error(stmt->fOffset, "do-while loops are not supported");
+ return nullptr;
+ }
+ test = context.fTypes.fBool->coerceExpression(std::move(test), context);
+ if (!test) {
+ return nullptr;
+ }
+ return std::make_unique<DoStatement>(stmt->fOffset, std::move(stmt), std::move(test));
+}
+
+std::unique_ptr<Statement> DoStatement::clone() const {
+ return std::make_unique<DoStatement>(fOffset, this->statement()->clone(),
+ this->test()->clone());
+}
+
+String DoStatement::description() const {
+ return "do " + this->statement()->description() +
+ " while (" + this->test()->description() + ");";
+}
+
+} // namespace SkSL
+
diff --git a/src/sksl/ir/SkSLDoStatement.h b/src/sksl/ir/SkSLDoStatement.h
index 231abba..0c22165 100644
--- a/src/sksl/ir/SkSLDoStatement.h
+++ b/src/sksl/ir/SkSLDoStatement.h
@@ -20,12 +20,16 @@
public:
static constexpr Kind kStatementKind = Kind::kDo;
- DoStatement(int offset, std::unique_ptr<Statement> statement,
- std::unique_ptr<Expression> test)
+ DoStatement(int offset, std::unique_ptr<Statement> statement, std::unique_ptr<Expression> test)
: INHERITED(offset, kStatementKind)
, fStatement(std::move(statement))
, fTest(std::move(test)) {}
+ // Creates an SkSL do loop.
+ static std::unique_ptr<Statement> Make(const Context& context,
+ std::unique_ptr<Statement> stmt,
+ std::unique_ptr<Expression> test);
+
std::unique_ptr<Statement>& statement() {
return fStatement;
}
@@ -42,15 +46,9 @@
return fTest;
}
- std::unique_ptr<Statement> clone() const override {
- return std::unique_ptr<Statement>(new DoStatement(fOffset, this->statement()->clone(),
- this->test()->clone()));
- }
+ std::unique_ptr<Statement> clone() const override;
- String description() const override {
- return "do " + this->statement()->description() + " while (" + this->test()->description() +
- ");";
- }
+ String description() const override;
private:
std::unique_ptr<Statement> fStatement;