Implement postfix ++/--, and use the correct 1 for floats
Change-Id: I0e6e8205998f3058cb59e279704e23989bccc66b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/214192
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/sksl/SkSLByteCodeGenerator.cpp b/src/sksl/SkSLByteCodeGenerator.cpp
index c724483..5c877a7 100644
--- a/src/sksl/SkSLByteCodeGenerator.cpp
+++ b/src/sksl/SkSLByteCodeGenerator.cpp
@@ -6,6 +6,7 @@
*/
#include "src/sksl/SkSLByteCodeGenerator.h"
+#include "src/sksl/SkSLInterpreter.h"
namespace SkSL {
@@ -379,8 +380,7 @@
void ByteCodeGenerator::writeFloatLiteral(const FloatLiteral& f) {
this->align(4, 3);
this->write(ByteCodeInstruction::kPushImmediate);
- union { float f; uint32_t u; } pun = { (float) f.fValue };
- this->write32(pun.u);
+ this->write32(Interpreter::Value((float) f.fValue).fUnsigned);
}
void ByteCodeGenerator::writeFunctionCall(const FunctionCall& f) {
@@ -411,12 +411,13 @@
switch (p.fOperator) {
case Token::Kind::PLUSPLUS: // fall through
case Token::Kind::MINUSMINUS: {
+ SkASSERT(slot_count(p.fOperand->fType) == 1);
std::unique_ptr<LValue> lvalue = this->getLValue(*p.fOperand);
lvalue->load();
this->align(4, 3);
this->write(ByteCodeInstruction::kPushImmediate);
- this->write32(1);
- SkASSERT(slot_count(p.fOperand->fType) == 1);
+ this->write32(type_category(p.fType) == TypeCategory::kFloat
+ ? Interpreter::Value(1.0f).fUnsigned : 1);
if (p.fOperator == Token::Kind::PLUSPLUS) {
this->writeTypedInstruction(p.fType,
ByteCodeInstruction::kAddI,
@@ -448,8 +449,38 @@
}
void ByteCodeGenerator::writePostfixExpression(const PostfixExpression& p) {
- // not yet implemented
- abort();
+ switch (p.fOperator) {
+ case Token::Kind::PLUSPLUS: // fall through
+ case Token::Kind::MINUSMINUS: {
+ SkASSERT(slot_count(p.fOperand->fType) == 1);
+ std::unique_ptr<LValue> lvalue = this->getLValue(*p.fOperand);
+ lvalue->load();
+ this->write(ByteCodeInstruction::kDup);
+ this->align(4, 3);
+ this->write(ByteCodeInstruction::kPushImmediate);
+ this->write32(type_category(p.fType) == TypeCategory::kFloat
+ ? Interpreter::Value(1.0f).fUnsigned : 1);
+ if (p.fOperator == Token::Kind::PLUSPLUS) {
+ this->writeTypedInstruction(p.fType,
+ ByteCodeInstruction::kAddI,
+ ByteCodeInstruction::kAddI,
+ ByteCodeInstruction::kAddF,
+ 1);
+ } else {
+ this->writeTypedInstruction(p.fType,
+ ByteCodeInstruction::kSubtractI,
+ ByteCodeInstruction::kSubtractI,
+ ByteCodeInstruction::kSubtractF,
+ 1);
+ }
+ lvalue->store();
+ this->write(ByteCodeInstruction::kPop);
+ this->write8(1);
+ break;
+ }
+ default:
+ SkASSERT(false);
+ }
}
void ByteCodeGenerator::writeSwizzle(const Swizzle& s) {
diff --git a/tests/SkSLInterpreterTest.cpp b/tests/SkSLInterpreterTest.cpp
index 0fd7418..d513bc9 100644
--- a/tests/SkSLInterpreterTest.cpp
+++ b/tests/SkSLInterpreterTest.cpp
@@ -267,6 +267,11 @@
495, 0, 0, 0);
}
+DEF_TEST(SkSLInterpreterPrefixPostfix, r) {
+ test(r, "void main(inout half4 color) { color.r = ++color.g; }", 1, 2, 3, 4, 3, 3, 3, 4);
+ test(r, "void main(inout half4 color) { color.r = color.g++; }", 1, 2, 3, 4, 2, 3, 3, 4);
+}
+
DEF_TEST(SkSLInterpreterSwizzle, r) {
test(r, "void main(inout half4 color) { color = color.abgr; }", 1, 2, 3, 4, 4, 3, 2, 1);
test(r, "void main(inout half4 color) { color.rgb = half4(5, 6, 7, 8).bbg; }", 1, 2, 3, 4, 7, 7,