Add a reference to the ErrorReporter to the SkSL Context.

This will allow errors to be reported outside of the IRGenerator more
easily (without passing around an ErrorReporter object).

Change-Id: I4bcb59fcd526599fa593fcb3b1de0a5ae64ab901
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/352737
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
John Stiles 2021-01-11 16:13:08 -05:00 committed by Skia Commit-Bot
parent c92df39de0
commit b30151eb73
10 changed files with 269 additions and 214 deletions

View File

@ -85,7 +85,7 @@ public:
};
Compiler::Compiler(const ShaderCapsClass* caps, Flags flags)
: fContext(std::make_shared<Context>())
: fContext(std::make_shared<Context>(/*errors=*/*this))
, fCaps(caps)
, fInliner(fContext.get())
, fFlags(flags)
@ -93,7 +93,7 @@ Compiler::Compiler(const ShaderCapsClass* caps, Flags flags)
SkASSERT(fCaps);
fRootSymbolTable = std::make_shared<SymbolTable>(this, /*builtin=*/true);
fPrivateSymbolTable = std::make_shared<SymbolTable>(fRootSymbolTable, /*builtin=*/true);
fIRGenerator = std::make_unique<IRGenerator>(fContext.get(), fCaps, *this);
fIRGenerator = std::make_unique<IRGenerator>(fContext.get(), fCaps);
#define TYPE(t) fContext->fTypes.f ## t .get()

View File

@ -49,7 +49,6 @@ static std::unique_ptr<Expression> short_circuit_boolean(const Expression& left,
template <typename T>
static std::unique_ptr<Expression> simplify_vector(const Context& context,
ErrorReporter& errors,
const Expression& left,
Token::Kind op,
const Expression& right) {
@ -101,7 +100,7 @@ static std::unique_ptr<Expression> simplify_vector(const Context& context,
case Token::Kind::TK_STAR: return vectorComponentwiseFold([](T a, T b) { return a * b; });
case Token::Kind::TK_SLASH: {
if (isVectorDivisionByZero()) {
errors.error(right.fOffset, "division by zero");
context.fErrors.error(right.fOffset, "division by zero");
return nullptr;
}
return vectorComponentwiseFold([](T a, T b) { return a / b; });
@ -122,7 +121,6 @@ static Constructor splat_scalar(const Expression& scalar, const Type& type) {
}
std::unique_ptr<Expression> ConstantFolder::Simplify(const Context& context,
ErrorReporter& errors,
const Expression& left,
Token::Kind op,
const Expression& right) {
@ -175,21 +173,21 @@ std::unique_ptr<Expression> ConstantFolder::Simplify(const Context& context,
case Token::Kind::TK_STAR: return URESULT(Int, *);
case Token::Kind::TK_SLASH:
if (leftVal == std::numeric_limits<SKSL_INT>::min() && rightVal == -1) {
errors.error(right.fOffset, "arithmetic overflow");
context.fErrors.error(right.fOffset, "arithmetic overflow");
return nullptr;
}
if (!rightVal) {
errors.error(right.fOffset, "division by zero");
context.fErrors.error(right.fOffset, "division by zero");
return nullptr;
}
return RESULT(Int, /);
case Token::Kind::TK_PERCENT:
if (leftVal == std::numeric_limits<SKSL_INT>::min() && rightVal == -1) {
errors.error(right.fOffset, "arithmetic overflow");
context.fErrors.error(right.fOffset, "arithmetic overflow");
return nullptr;
}
if (!rightVal) {
errors.error(right.fOffset, "division by zero");
context.fErrors.error(right.fOffset, "division by zero");
return nullptr;
}
return RESULT(Int, %);
@ -206,13 +204,13 @@ std::unique_ptr<Expression> ConstantFolder::Simplify(const Context& context,
if (rightVal >= 0 && rightVal <= 31) {
return RESULT(Int, <<);
}
errors.error(right.fOffset, "shift value out of range");
context.fErrors.error(right.fOffset, "shift value out of range");
return nullptr;
case Token::Kind::TK_SHR:
if (rightVal >= 0 && rightVal <= 31) {
return RESULT(Int, >>);
}
errors.error(right.fOffset, "shift value out of range");
context.fErrors.error(right.fOffset, "shift value out of range");
return nullptr;
default:
@ -232,7 +230,7 @@ std::unique_ptr<Expression> ConstantFolder::Simplify(const Context& context,
if (rightVal) {
return RESULT(Float, /);
}
errors.error(right.fOffset, "division by zero");
context.fErrors.error(right.fOffset, "division by zero");
return nullptr;
case Token::Kind::TK_EQEQ: return RESULT(Bool, ==);
case Token::Kind::TK_NEQ: return RESULT(Bool, !=);
@ -249,10 +247,10 @@ std::unique_ptr<Expression> ConstantFolder::Simplify(const Context& context,
const Type& rightType = right.type();
if (leftType.isVector() && leftType == rightType) {
if (leftType.componentType().isFloat()) {
return simplify_vector<SKSL_FLOAT>(context, errors, left, op, right);
return simplify_vector<SKSL_FLOAT>(context, left, op, right);
}
if (leftType.componentType().isInteger()) {
return simplify_vector<SKSL_INT>(context, errors, left, op, right);
return simplify_vector<SKSL_INT>(context, left, op, right);
}
return nullptr;
}
@ -260,12 +258,10 @@ std::unique_ptr<Expression> ConstantFolder::Simplify(const Context& context,
// Perform constant folding on vectors against scalars, e.g.: half4(2) + 2
if (leftType.isVector() && leftType.componentType() == rightType) {
if (rightType.isFloat()) {
return simplify_vector<SKSL_FLOAT>(context, errors,
left, op, splat_scalar(right, left.type()));
return simplify_vector<SKSL_FLOAT>(context, left, op, splat_scalar(right, left.type()));
}
if (rightType.isInteger()) {
return simplify_vector<SKSL_INT>(context, errors,
left, op, splat_scalar(right, left.type()));
return simplify_vector<SKSL_INT>(context, left, op, splat_scalar(right, left.type()));
}
return nullptr;
}
@ -273,12 +269,11 @@ std::unique_ptr<Expression> ConstantFolder::Simplify(const Context& context,
// Perform constant folding on scalars against vectors, e.g.: 2 + half4(2)
if (rightType.isVector() && rightType.componentType() == leftType) {
if (leftType.isFloat()) {
return simplify_vector<SKSL_FLOAT>(context, errors,
splat_scalar(left, right.type()), op, right);
return simplify_vector<SKSL_FLOAT>(context, splat_scalar(left, right.type()), op,
right);
}
if (leftType.isInteger()) {
return simplify_vector<SKSL_INT>(context, errors,
splat_scalar(left, right.type()), op, right);
return simplify_vector<SKSL_INT>(context, splat_scalar(left, right.type()), op, right);
}
return nullptr;
}

View File

@ -26,7 +26,6 @@ class ConstantFolder {
public:
/** Simplifies the binary expression `left OP right`. Returns null if it can't be simplified. */
static std::unique_ptr<Expression> Simplify(const Context& context,
ErrorReporter& errors,
const Expression& left,
Token::Kind op,
const Expression& right);

View File

@ -236,8 +236,9 @@ public:
using INHERITED = Expression;
};
Context::Context()
: fDefined_Expression(std::make_unique<DefinedExpression>(fTypes.fInvalid.get())) {}
Context::Context(ErrorReporter& errors)
: fErrors(errors)
, fDefined_Expression(std::make_unique<DefinedExpression>(fTypes.fInvalid.get())) {}
} // namespace SkSL

View File

@ -10,6 +10,7 @@
#include <memory>
#include "src/sksl/SkSLErrorReporter.h"
#include "src/sksl/ir/SkSLExpression.h"
#include "src/sksl/ir/SkSLType.h"
@ -147,11 +148,14 @@ struct BuiltinTypes {
*/
class Context {
public:
Context();
Context(ErrorReporter& errors);
// The Context holds all of the built-in types.
BuiltinTypes fTypes;
// The Context holds a reference to our error reporter.
ErrorReporter& fErrors;
// A sentinel expression used to mark that a variable has a value during dataflow analysis (when
// it could have several different values, or the analyzer is otherwise unable to assign it a
// specific expression)

View File

@ -28,6 +28,15 @@ public:
virtual int errorCount() = 0;
};
/**
* Error reporter for tests that need an SkSL context; aborts immediately if an error is reported.
*/
class TestingOnly_AbortErrorReporter : public ErrorReporter {
public:
void error(int offset, String msg) override { ABORT("%s", msg.c_str()); }
int errorCount() override { return 0; }
};
} // namespace SkSL
#endif

File diff suppressed because it is too large Load Diff

View File

@ -102,8 +102,7 @@ private:
class IRGenerator {
public:
IRGenerator(const Context* context,
const ShaderCapsClass* caps,
ErrorReporter& errorReporter);
const ShaderCapsClass* caps);
struct IRBundle {
std::vector<std::unique_ptr<ProgramElement>> fElements;
@ -132,7 +131,7 @@ public:
const Program::Settings* settings() const { return fSettings; }
ErrorReporter& errorReporter() const { return fErrors; }
ErrorReporter& errorReporter() const { return fContext.fErrors; }
std::shared_ptr<SymbolTable>& symbolTable() {
return fSymbolTable;
@ -268,7 +267,6 @@ private:
std::unordered_set<const FunctionDeclaration*> fReferencedIntrinsics;
int fLoopLevel = 0;
int fSwitchLevel = 0;
ErrorReporter& fErrors;
int fInvocations;
std::vector<std::unique_ptr<ProgramElement>>* fProgramElements = nullptr;
std::vector<const ProgramElement*>* fSharedElements = nullptr;

View File

@ -85,8 +85,8 @@ public:
std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
const DefinitionMap& definitions) override {
return ConstantFolder::Simplify(irGenerator.fContext, irGenerator.errorReporter(),
*this->left(), this->getOperator(), *this->right());
return ConstantFolder::Simplify(irGenerator.fContext, *this->left(), this->getOperator(),
*this->right());
}
bool hasProperty(Property property) const override {

View File

@ -6,12 +6,14 @@
*/
#include "src/sksl/SkSLContext.h"
#include "src/sksl/SkSLErrorReporter.h"
#include "src/sksl/SkSLMemoryLayout.h"
#include "tests/Test.h"
DEF_TEST(SkSLMemoryLayout140Test, r) {
SkSL::Context context;
SkSL::TestingOnly_AbortErrorReporter errors;
SkSL::Context context(errors);
SkSL::MemoryLayout layout(SkSL::MemoryLayout::k140_Standard);
// basic types
@ -96,7 +98,8 @@ DEF_TEST(SkSLMemoryLayout140Test, r) {
}
DEF_TEST(SkSLMemoryLayout430Test, r) {
SkSL::Context context;
SkSL::TestingOnly_AbortErrorReporter errors;
SkSL::Context context(errors);
SkSL::MemoryLayout layout(SkSL::MemoryLayout::k430_Standard);
// basic types