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:
parent
c92df39de0
commit
b30151eb73
@ -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()
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user