Added first pass of verifier and supporting changes.

The verifier still needs to make a second pass through the code where it
checks the code flow. A TODO marks where it will be added.

Change-Id: I0abea5bad563776186df342d8132fb1ca8869652
diff --git a/src/dex_instruction.h b/src/dex_instruction.h
index 617f818..8cf645d 100644
--- a/src/dex_instruction.h
+++ b/src/dex_instruction.h
@@ -19,7 +19,7 @@
   };
 
   enum Code {
-#define INSTRUCTION_ENUM(opcode, cname, p, f, r, i, a) cname = opcode,
+#define INSTRUCTION_ENUM(opcode, cname, p, f, r, i, a, v) cname = opcode,
 #include "dex_instruction_list.h"
     DEX_INSTRUCTION_LIST(INSTRUCTION_ENUM)
 #undef DEX_INSTRUCTION_LIST
@@ -63,6 +63,33 @@
     // TODO: kUnconditional
   };
 
+  enum VerifyFlag {
+    kVerifyNone            = 0x00000,
+    kVerifyRegA            = 0x00001,
+    kVerifyRegAWide        = 0x00002,
+    kVerifyRegB            = 0x00004,
+    kVerifyRegBField       = 0x00008,
+    kVerifyRegBMethod      = 0x00010,
+    kVerifyRegBNewInstance = 0x00020,
+    kVerifyRegBString      = 0x00040,
+    kVerifyRegBType        = 0x00080,
+    kVerifyRegBWide        = 0x00100,
+    kVerifyRegC            = 0x00200,
+    kVerifyRegCField       = 0x00400,
+    kVerifyRegCNewArray    = 0x00800,
+    kVerifyRegCType        = 0x01000,
+    kVerifyRegCWide        = 0x02000,
+    kVerifyArrayData       = 0x04000,
+    kVerifyBranchTarget    = 0x08000,
+    kVerifySwitchTargets   = 0x10000,
+    kVerifyVarArg          = 0x20000,
+    kVerifyVarArgRange     = 0x40000,
+    kVerifyError           = 0x80000,
+  };
+
+  // Decodes this instruction, populating its arguments.
+  void Decode(uint32_t &vA, uint32_t &vB, uint64_t &vB_wide, uint32_t &vC, uint32_t arg[]) const;
+
   // Returns the size in bytes of this instruction.
   size_t Size() const;
 
@@ -78,9 +105,9 @@
   Code Opcode() const;
 
   // Reads an instruction out of the stream at the specified address.
-  static Instruction* At(byte* code) {
+  static const Instruction* At(const byte* code) {
     CHECK(code != NULL);
-    return reinterpret_cast<Instruction*>(code);
+    return reinterpret_cast<const Instruction*>(code);
   }
 
   // Returns the format of the current instruction.
@@ -93,6 +120,16 @@
     return (kInstructionFlags[Opcode()] & kBranch) != 0;
   }
 
+  // Returns true if this instruction is a switch.
+  bool IsSwitch() const {
+    return (kInstructionFlags[Opcode()] & kSwitch) != 0;
+  }
+
+  // Returns true if this instruction can throw.
+  bool IsThrow() const {
+    return (kInstructionFlags[Opcode()] & kThrow) != 0;
+  }
+
   // Determine if the instruction is any of 'return' instructions.
   bool IsReturn() const {
     return (kInstructionFlags[Opcode()] & kReturn) != 0;
@@ -108,10 +145,30 @@
     return (kInstructionFlags[Opcode()] & kInvoke) != 0;
   }
 
+  int GetVerifyTypeArgumentA() const {
+    return (kInstructionVerifyFlags[Opcode()] & (kVerifyRegA | kVerifyRegAWide));
+  }
+
+  int GetVerifyTypeArgumentB() const {
+    return (kInstructionVerifyFlags[Opcode()] & (kVerifyRegB | kVerifyRegBField | kVerifyRegBMethod |
+             kVerifyRegBNewInstance | kVerifyRegBString | kVerifyRegBType | kVerifyRegBWide));
+  }
+
+  int GetVerifyTypeArgumentC() const {
+    return (kInstructionVerifyFlags[Opcode()] & (kVerifyRegC | kVerifyRegCField |
+             kVerifyRegCNewArray | kVerifyRegBType | kVerifyRegBWide));
+  }
+
+  int GetVerifyExtraFlags() const {
+    return (kInstructionVerifyFlags[Opcode()] & (kVerifyArrayData | kVerifyBranchTarget |
+             kVerifySwitchTargets | kVerifyVarArg | kVerifyVarArgRange | kVerifyError));
+  }
+
  private:
   static const char* const kInstructionNames[];
   static InstructionFormat const kInstructionFormats[];
   static int const kInstructionFlags[];
+  static int const kInstructionVerifyFlags[];
   DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction);
 };