Reland "Interpreter: Bounds check array access, add bool return from run"
This is a reland of f42de9e1e535af7e1700e4758d22751ff6a4982e
Original change's description:
> Interpreter: Bounds check array access, add bool return from run
>
> Out of bounds access with constant indices is a compile error.
> At runtime, causes the interpreter to fail. Made several other
> conditions trigger the same failure logic, and updated all
> uses of the interpreter to validate success.
>
> Change-Id: I3720b3c83903220b010ec574121fc64dbe102378
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/228256
> Commit-Queue: Brian Osman <brianosman@google.com>
> Reviewed-by: Mike Reed <reed@google.com>
Change-Id: I8849de815f7efb730ac9c55b6edd296cb9ca7599
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/228353
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/src/sksl/SkSLByteCodeGenerator.cpp b/src/sksl/SkSLByteCodeGenerator.cpp
index 8893ddb..f1fdbdd 100644
--- a/src/sksl/SkSLByteCodeGenerator.cpp
+++ b/src/sksl/SkSLByteCodeGenerator.cpp
@@ -208,6 +208,7 @@
case ByteCodeInstruction::kInverse3x3:
case ByteCodeInstruction::kInverse4x4: return 0;
+ case ByteCodeInstruction::kClampIndex: return 0;
case ByteCodeInstruction::kNotB: return 0;
case ByteCodeInstruction::kNegateFN: return 0;
@@ -459,9 +460,16 @@
case Expression::kIndex_Kind: {
const IndexExpression& i = (const IndexExpression&)expr;
int stride = SlotCount(i.fType);
+ int length = i.fBase->fType.columns();
+ SkASSERT(length <= 255);
int offset = -1;
if (i.fIndex->isConstant()) {
- offset = i.fIndex->getConstantInt() * stride;
+ int64_t index = i.fIndex->getConstantInt();
+ if (index < 0 || index >= length) {
+ fErrors.error(i.fIndex->fOffset, "Array index out of bounds.");
+ return 0;
+ }
+ offset = index * stride;
} else {
if (i.fIndex->hasSideEffects()) {
// Having a side-effect in an indexer is technically safe for an rvalue,
@@ -471,6 +479,8 @@
return 0;
}
this->writeExpression(*i.fIndex);
+ this->write(ByteCodeInstruction::kClampIndex);
+ this->write8(length);
if (stride != 1) {
this->write(ByteCodeInstruction::kPushImmediate);
this->write32(stride);
@@ -829,7 +839,7 @@
}
void ByteCodeGenerator::writeVariableExpression(const Expression& expr) {
- Variable::Storage storage;
+ Variable::Storage storage = Variable::kLocal_Storage;
int location = this->getLocation(expr, &storage);
bool isGlobal = storage == Variable::kGlobal_Storage;
int count = SlotCount(expr.fType);
@@ -1230,7 +1240,7 @@
if (!discard) {
fGenerator.write(vector_instruction(ByteCodeInstruction::kDup, count));
}
- Variable::Storage storage;
+ Variable::Storage storage = Variable::kLocal_Storage;
int location = fGenerator.getLocation(*fSwizzle.fBase, &storage);
bool isGlobal = storage == Variable::kGlobal_Storage;
if (location < 0) {
@@ -1275,7 +1285,7 @@
fGenerator.write(vector_instruction(ByteCodeInstruction::kDup, count));
}
}
- Variable::Storage storage;
+ Variable::Storage storage = Variable::kLocal_Storage;
int location = fGenerator.getLocation(fExpression, &storage);
bool isGlobal = storage == Variable::kGlobal_Storage;
if (location < 0 || count > 4) {