SkSL interpreter now properly short-circuits boolean operators

Bug: skia:
Change-Id: If7acf4107498cabc049ad130814a3814383bd14b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/243418
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/sksl/SkSLByteCodeGenerator.cpp b/src/sksl/SkSLByteCodeGenerator.cpp
index 6977ea4..bb8caf1 100644
--- a/src/sksl/SkSLByteCodeGenerator.cpp
+++ b/src/sksl/SkSLByteCodeGenerator.cpp
@@ -627,6 +627,38 @@
             }
         }
     }
+    int count = std::max(SlotCount(lType), SlotCount(rType));
+    switch (op) {
+        case Token::Kind::LOGICALAND: {
+            SkASSERT(type_category(lType) == SkSL::TypeCategory::kBool && count == 1);
+            this->write(ByteCodeInstruction::kDup);
+            this->write8(1);
+            this->write(ByteCodeInstruction::kMaskPush);
+            this->write(ByteCodeInstruction::kBranchIfAllFalse);
+            DeferredLocation falseLocation(this);
+            this->writeExpression(*b.fRight);
+            this->write(ByteCodeInstruction::kAndB);
+            falseLocation.set();
+            this->write(ByteCodeInstruction::kMaskPop);
+            return false;
+        }
+        case Token::Kind::LOGICALOR: {
+            SkASSERT(type_category(lType) == SkSL::TypeCategory::kBool && count == 1);
+            this->write(ByteCodeInstruction::kDup);
+            this->write8(1);
+            this->write(ByteCodeInstruction::kNotB);
+            this->write(ByteCodeInstruction::kMaskPush);
+            this->write(ByteCodeInstruction::kBranchIfAllFalse);
+            DeferredLocation falseLocation(this);
+            this->writeExpression(*b.fRight);
+            this->write(ByteCodeInstruction::kOrB);
+            falseLocation.set();
+            this->write(ByteCodeInstruction::kMaskPop);
+            return false;
+        }
+        default:
+            break;
+    }
     this->writeExpression(*b.fRight);
     if (lVecOrMtx && !rVecOrMtx) {
         for (int i = SlotCount(lType); i > 1; --i) {
@@ -653,7 +685,6 @@
         this->write8(lRows);
         this->write8(rCols);
     } else {
-        int count = std::max(SlotCount(lType), SlotCount(rType));
         switch (op) {
             case Token::Kind::EQEQ:
                 this->writeTypedInstruction(lType, ByteCodeInstruction::kCompareIEQ,
@@ -730,18 +761,10 @@
                                             count);
                 break;
 
-            case Token::Kind::LOGICALAND:
-                SkASSERT(type_category(lType) == SkSL::TypeCategory::kBool && count == 1);
-                this->write(ByteCodeInstruction::kAndB);
-                break;
             case Token::Kind::LOGICALNOT:
                 SkASSERT(type_category(lType) == SkSL::TypeCategory::kBool && count == 1);
                 this->write(ByteCodeInstruction::kNotB);
                 break;
-            case Token::Kind::LOGICALOR:
-                SkASSERT(type_category(lType) == SkSL::TypeCategory::kBool && count == 1);
-                this->write(ByteCodeInstruction::kOrB);
-                break;
             case Token::Kind::LOGICALXOR:
                 SkASSERT(type_category(lType) == SkSL::TypeCategory::kBool && count == 1);
                 this->write(ByteCodeInstruction::kXorB);