Interpreter: Add bitwise operators

Also, negation is unary, not binary.

Change-Id: Ic7c5a6f2ee0b2bbda89eef62999e4ebbc97dca12
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/243161
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 bb8caf1..b035596 100644
--- a/src/sksl/SkSLByteCodeGenerator.cpp
+++ b/src/sksl/SkSLByteCodeGenerator.cpp
@@ -628,9 +628,10 @@
         }
     }
     int count = std::max(SlotCount(lType), SlotCount(rType));
+    SkDEBUGCODE(TypeCategory tc = type_category(lType));
     switch (op) {
         case Token::Kind::LOGICALAND: {
-            SkASSERT(type_category(lType) == SkSL::TypeCategory::kBool && count == 1);
+            SkASSERT(tc == SkSL::TypeCategory::kBool && count == 1);
             this->write(ByteCodeInstruction::kDup);
             this->write8(1);
             this->write(ByteCodeInstruction::kMaskPush);
@@ -643,7 +644,7 @@
             return false;
         }
         case Token::Kind::LOGICALOR: {
-            SkASSERT(type_category(lType) == SkSL::TypeCategory::kBool && count == 1);
+            SkASSERT(tc == SkSL::TypeCategory::kBool && count == 1);
             this->write(ByteCodeInstruction::kDup);
             this->write8(1);
             this->write(ByteCodeInstruction::kNotB);
@@ -761,12 +762,24 @@
                                             count);
                 break;
 
-            case Token::Kind::LOGICALNOT:
-                SkASSERT(type_category(lType) == SkSL::TypeCategory::kBool && count == 1);
-                this->write(ByteCodeInstruction::kNotB);
-                break;
             case Token::Kind::LOGICALXOR:
-                SkASSERT(type_category(lType) == SkSL::TypeCategory::kBool && count == 1);
+                SkASSERT(tc == SkSL::TypeCategory::kBool && count == 1);
+                this->write(ByteCodeInstruction::kXorB);
+                break;
+
+            case Token::Kind::BITWISEAND:
+                SkASSERT(count == 1 && (tc == SkSL::TypeCategory::kSigned ||
+                                        tc == SkSL::TypeCategory::kUnsigned));
+                this->write(ByteCodeInstruction::kAndB);
+                break;
+            case Token::Kind::BITWISEOR:
+                SkASSERT(count == 1 && (tc == SkSL::TypeCategory::kSigned ||
+                                        tc == SkSL::TypeCategory::kUnsigned));
+                this->write(ByteCodeInstruction::kOrB);
+                break;
+            case Token::Kind::BITWISEXOR:
+                SkASSERT(count == 1 && (tc == SkSL::TypeCategory::kSigned ||
+                                        tc == SkSL::TypeCategory::kUnsigned));
                 this->write(ByteCodeInstruction::kXorB);
                 break;
 
@@ -1085,6 +1098,17 @@
                                         false);
             break;
         }
+        case Token::Kind::LOGICALNOT:
+        case Token::Kind::BITWISENOT: {
+            SkASSERT(SlotCount(p.fOperand->fType) == 1);
+            SkDEBUGCODE(TypeCategory tc = type_category(p.fOperand->fType));
+            SkASSERT((p.fOperator == Token::Kind::LOGICALNOT && tc == TypeCategory::kBool) ||
+                     (p.fOperator == Token::Kind::BITWISENOT && (tc == TypeCategory::kSigned ||
+                                                                 tc == TypeCategory::kUnsigned)));
+            this->writeExpression(*p.fOperand);
+            this->write(ByteCodeInstruction::kNotB);
+            break;
+        }
         default:
             SkASSERT(false);
     }