diff --git a/src/class_linker.cc b/src/class_linker.cc
index f312556..14f4883 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -1193,7 +1193,7 @@
       CHECK(klass->GetStatus() == Class::kStatusResolved);
 
       klass->SetStatus(Class::kStatusVerifying);
-      if (!DexVerify::VerifyClass(klass)) {
+      if (!DexVerifier::VerifyClass(klass)) {
         LG << "Verification failed";  // TODO: ThrowVerifyError
         Object* exception = self->GetException();
         klass->SetVerifyErrorClass(exception->GetClass());
@@ -1592,6 +1592,8 @@
     for (size_t i = 0; i < count; ++i) {
       klass->GetVirtualMethodDuringLinking(i)->SetMethodIndex(i);
     }
+    // Link interface method tables
+    LinkInterfaceMethods(klass);
   } else {
     // Link virtual method tables
     LinkVirtualMethods(klass);
@@ -2103,7 +2105,9 @@
 
   const char* name = dex_file.dexStringById(method_id.name_idx_);
   std::string signature(dex_file.CreateMethodDescriptor(method_id.proto_idx_, NULL));
-  if (is_direct) {
+  if (klass->IsInterface()) {
+    resolved = klass->FindInterfaceMethod(name, signature);
+  } else if (is_direct) {
     resolved = klass->FindDirectMethod(name, signature);
   } else {
     resolved = klass->FindVirtualMethod(name, signature);
diff --git a/src/dex_instruction.h b/src/dex_instruction.h
index 8cf645d..3934d7d 100644
--- a/src/dex_instruction.h
+++ b/src/dex_instruction.h
@@ -87,6 +87,23 @@
     kVerifyError           = 0x80000,
   };
 
+  /*
+   * Holds the contents of a decoded instruction.
+   */
+  struct DecodedInstruction {
+    uint32_t vA_;
+    uint32_t vB_;
+    uint64_t vB_wide_;        /* for kFmt51l */
+    uint32_t vC_;
+    uint32_t arg_[5];         /* vC/D/E/F/G in invoke or filled-new-array */
+    Code     opcode_;
+
+    DecodedInstruction(const Instruction* inst) {
+      inst->Decode(vA_, vB_, vB_wide_, vC_, arg_);
+      opcode_ = inst->Opcode();
+    }
+  };
+
   // 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;
 
@@ -115,6 +132,11 @@
     return kInstructionFormats[Opcode()];
   }
 
+  // Returns the flags for the current instruction.
+  int Flag() const {
+    return kInstructionFlags[Opcode()];
+  }
+
   // Returns true if this instruction is a branch.
   bool IsBranch() const {
     return (kInstructionFlags[Opcode()] & kBranch) != 0;
diff --git a/src/dex_verifier.cc b/src/dex_verifier.cc
index f257e78..86b119b 100644
--- a/src/dex_verifier.cc
+++ b/src/dex_verifier.cc
@@ -8,100 +8,448 @@
 #include "dex_file.h"
 #include "dex_instruction.h"
 #include "dex_instruction_visitor.h"
+#include "dex_verifier.h"
 #include "logging.h"
 #include "runtime.h"
 #include "stringpiece.h"
+#include "UniquePtr.h"
 
 namespace art {
 
-/*
- * Returns "true" if the flags indicate that this address holds the start
- * of an instruction.
- */
-inline bool InsnIsOpcode(const uint32_t insn_flags[], int addr) {
-  return (insn_flags[addr] & DexVerify::kInsnFlagWidthMask) != 0;
+#define k_  kRegTypeUnknown
+#define kU  kRegTypeUninit
+#define kX  kRegTypeConflict
+#define k0  kRegTypeZero
+#define k1  kRegTypeOne
+#define kZ  kRegTypeBoolean
+#define ky  kRegTypeConstPosByte
+#define kY  kRegTypeConstByte
+#define kh  kRegTypeConstPosShort
+#define kH  kRegTypeConstShort
+#define kc  kRegTypeConstChar
+#define ki  kRegTypeConstInteger
+#define kb  kRegTypePosByte
+#define kB  kRegTypeByte
+#define ks  kRegTypePosShort
+#define kS  kRegTypeShort
+#define kC  kRegTypeChar
+#define kI  kRegTypeInteger
+#define kF  kRegTypeFloat
+#define kN  kRegTypeConstLo
+#define kn  kRegTypeConstHi
+#define kJ  kRegTypeLongLo
+#define kj  kRegTypeLongHi
+#define kD  kRegTypeDoubleLo
+#define kd  kRegTypeDoubleHi
+
+const char DexVerifier::merge_table_[kRegTypeMAX][kRegTypeMAX] =
+  {
+    /* chk:  _  U  X  0  1  Z  y  Y  h  H  c  i  b  B  s  S  C  I  F  N  n  J  j  D  d */
+    { /*_*/ k_,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX },
+    { /*U*/ kX,kU,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX },
+    { /*X*/ kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX },
+    { /*0*/ kX,kX,kX,k0,kZ,kZ,ky,kY,kh,kH,kc,ki,kb,kB,ks,kS,kC,kI,kF,kX,kX,kX,kX,kX,kX },
+    { /*1*/ kX,kX,kX,kZ,k1,kZ,ky,kY,kh,kH,kc,ki,kb,kB,ks,kS,kC,kI,kF,kX,kX,kX,kX,kX,kX },
+    { /*Z*/ kX,kX,kX,kZ,kZ,kZ,ky,kY,kh,kH,kc,ki,kb,kB,ks,kS,kC,kI,kF,kX,kX,kX,kX,kX,kX },
+    { /*y*/ kX,kX,kX,ky,ky,ky,ky,kY,kh,kH,kc,ki,kb,kB,ks,kS,kC,kI,kF,kX,kX,kX,kX,kX,kX },
+    { /*Y*/ kX,kX,kX,kY,kY,kY,kY,kY,kh,kH,kc,ki,kB,kB,kS,kS,kI,kI,kF,kX,kX,kX,kX,kX,kX },
+    { /*h*/ kX,kX,kX,kh,kh,kh,kh,kh,kh,kH,kc,ki,ks,kS,ks,kS,kC,kI,kF,kX,kX,kX,kX,kX,kX },
+    { /*H*/ kX,kX,kX,kH,kH,kH,kH,kH,kH,kH,kc,ki,kS,kS,kS,kS,kI,kI,kF,kX,kX,kX,kX,kX,kX },
+    { /*c*/ kX,kX,kX,kc,kc,kc,kc,kc,kc,kc,kc,ki,kC,kI,kC,kI,kC,kI,kF,kX,kX,kX,kX,kX,kX },
+    { /*i*/ kX,kX,kX,ki,ki,ki,ki,ki,ki,ki,ki,ki,kI,kI,kI,kI,kI,kI,kF,kX,kX,kX,kX,kX,kX },
+    { /*b*/ kX,kX,kX,kb,kb,kb,kb,kB,ks,kS,kC,kI,kb,kB,ks,kS,kC,kI,kX,kX,kX,kX,kX,kX,kX },
+    { /*B*/ kX,kX,kX,kB,kB,kB,kB,kB,kS,kS,kI,kI,kB,kB,kS,kS,kI,kI,kX,kX,kX,kX,kX,kX,kX },
+    { /*s*/ kX,kX,kX,ks,ks,ks,ks,kS,ks,kS,kC,kI,ks,kS,ks,kS,kC,kI,kX,kX,kX,kX,kX,kX,kX },
+    { /*S*/ kX,kX,kX,kS,kS,kS,kS,kS,kS,kS,kI,kI,kS,kS,kS,kS,kI,kI,kX,kX,kX,kX,kX,kX,kX },
+    { /*C*/ kX,kX,kX,kC,kC,kC,kC,kI,kC,kI,kC,kI,kC,kI,kC,kI,kC,kI,kX,kX,kX,kX,kX,kX,kX },
+    { /*I*/ kX,kX,kX,kI,kI,kI,kI,kI,kI,kI,kI,kI,kI,kI,kI,kI,kI,kI,kX,kX,kX,kX,kX,kX,kX },
+    { /*F*/ kX,kX,kX,kF,kF,kF,kF,kF,kF,kF,kF,kF,kX,kX,kX,kX,kX,kX,kF,kX,kX,kX,kX,kX,kX },
+    { /*N*/ kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kN,kX,kJ,kX,kD,kX },
+    { /*n*/ kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kn,kX,kj,kX,kd },
+    { /*J*/ kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kJ,kX,kJ,kX,kX,kX },
+    { /*j*/ kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kj,kX,kj,kX,kX },
+    { /*D*/ kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kD,kX,kX,kX,kD,kX },
+    { /*d*/ kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kX,kd,kX,kX,kX,kd },
+  };
+
+#undef k_
+#undef kU
+#undef kX
+#undef k0
+#undef k1
+#undef kZ
+#undef ky
+#undef kY
+#undef kh
+#undef kH
+#undef kc
+#undef ki
+#undef kb
+#undef kB
+#undef ks
+#undef kS
+#undef kC
+#undef kI
+#undef kF
+#undef kN
+#undef kn
+#undef kJ
+#undef kj
+#undef kD
+#undef kd
+
+bool DexVerifier::VerifyClass(Class* klass) {
+  if (klass->IsVerified()) {
+    return true;
+  }
+  for (size_t i = 0; i < klass->NumDirectMethods(); ++i) {
+    Method* method = klass->GetDirectMethod(i);
+    if (!VerifyMethod(method)) {
+        LOG(ERROR) << "Verifier rejected class "
+                   << klass->GetDescriptor()->ToModifiedUtf8();
+      return false;
+    }
+  }
+  for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
+    Method* method = klass->GetVirtualMethod(i);
+    if (!VerifyMethod(method)) {
+        LOG(ERROR) << "Verifier rejected class "
+                   << klass->GetDescriptor()->ToModifiedUtf8();
+      return false;
+    }
+  }
+  return true;
 }
 
-/*
- * Extract the unsigned 16-bit instruction width from "flags".
- */
-inline int InsnGetWidth(const uint32_t insn_flags[], int addr) {
-  return insn_flags[addr] & DexVerify::kInsnFlagWidthMask;
+bool DexVerifier::VerifyMethod(Method* method) {
+  const DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
+  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+  const DexFile& dex_file = class_linker->FindDexFile(dex_cache);
+  const DexFile::CodeItem *code_item =
+      dex_file.GetCodeItem(method->GetCodeItemOffset());
+
+  /*
+   * Construct the verifier state container object.
+   */
+  VerifierData vdata(method, &dex_file, code_item);
+
+  /*
+   * If there aren't any instructions, make sure that's expected, then
+   * exit successfully.
+   */
+  if (code_item == NULL) {
+    if (!method->IsNative() && !method->IsAbstract()) {
+      LOG(ERROR) << "VFY: zero-length code in concrete non-native method";
+      return false;
+    }
+    return true;
+  }
+
+  /*
+   * Sanity-check the register counts.  ins + locals = registers, so make
+   * sure that ins <= registers.
+   */
+  if (code_item->ins_size_ > code_item->registers_size_) {
+    LOG(ERROR) << "VFY: bad register counts (ins=" << code_item->ins_size_
+               << " regs=" << code_item->registers_size_;
+    return false;
+  }
+
+  /*
+   * Allocate and initialize an array to hold instruction data.
+   */
+  UniquePtr<InsnFlags> insn_flags(new InsnFlags[code_item->insns_size_]());
+  vdata.insn_flags_ = insn_flags.get();
+
+  /*
+   * Run through the instructions and see if the width checks out.
+   */
+  if (!ComputeWidthsAndCountOps(&vdata)) {
+    return false;
+  }
+
+  /*
+   * Flag instructions guarded by a "try" block and check exception handlers.
+   */
+  if (!ScanTryCatchBlocks(&vdata)) {
+    return false;
+  }
+
+  /*
+   * Perform static instruction verification.
+   */
+  if (!VerifyInstructions(&vdata)) {
+    return false;
+  }
+
+  /*
+   * Perform code flow analysis.
+   */
+  if (!VerifyCodeFlow(&vdata)) {
+    return false;
+  }
+
+  return true;
 }
 
-/*
- * Changed?
- */
-inline bool InsnIsChanged(const uint32_t insn_flags[], int addr) {
-    return (insn_flags[addr] & DexVerify::kInsnFlagChanged) != 0;
-}
-inline void InsnSetChanged(uint32_t insn_flags[], int addr, bool changed) {
-  if (changed)
-    insn_flags[addr] |= DexVerify::kInsnFlagChanged;
-  else
-    insn_flags[addr] &= ~DexVerify::kInsnFlagChanged;
+bool DexVerifier::VerifyInstructions(VerifierData* vdata) {
+  const DexFile::CodeItem* code_item = vdata->code_item_;
+  InsnFlags* insn_flags = vdata->insn_flags_;
+  const byte* ptr = reinterpret_cast<const byte*>(code_item->insns_);
+  const Instruction* inst = Instruction::At(ptr);
+
+  /* Flag the start of the method as a branch target. */
+  InsnSetBranchTarget(insn_flags, 0);
+
+  uint32_t width = 0;
+  uint32_t insns_size = code_item->insns_size_;
+
+  while (width < insns_size) {
+    if (!VerifyInstruction(vdata, inst, width)) {
+      LOG(ERROR) << "VFY:  rejecting opcode 0x" << std::hex
+                 << (int) inst->Opcode() << " at 0x" << width << std::dec;
+      return false;
+    }
+
+    /* Flag instructions that are garbage collection points */
+    if (inst->IsBranch() || inst->IsSwitch() || inst->IsThrow() ||
+        inst->IsReturn()) {
+      InsnSetGcPoint(insn_flags, width);
+    }
+
+    width += inst->Size();
+    inst = inst->Next();
+  }
+  return true;
 }
 
-/*
- * Visited?
- */
-inline bool InsnIsVisited(const uint32_t insn_flags[], int addr) {
-    return (insn_flags[addr] & DexVerify::kInsnFlagVisited) != 0;
-}
-inline void InsnSetVisited(uint32_t insn_flags[], int addr, bool changed) {
-  if (changed)
-    insn_flags[addr] |= DexVerify::kInsnFlagVisited;
-  else
-    insn_flags[addr] &= ~DexVerify::kInsnFlagVisited;
+bool DexVerifier::VerifyInstruction(VerifierData* vdata,
+    const Instruction* inst, uint32_t code_offset) {
+  const DexFile* dex_file = vdata->dex_file_;
+  const DexFile::CodeItem* code_item = vdata->code_item_;
+  InsnFlags* insn_flags = vdata->insn_flags_;
+  Instruction::DecodedInstruction dec_insn(inst);
+  bool result = true;
+
+  int argumentA = inst->GetVerifyTypeArgumentA();
+  int argumentB = inst->GetVerifyTypeArgumentB();
+  int argumentC = inst->GetVerifyTypeArgumentC();
+  int extra_flags = inst->GetVerifyExtraFlags();
+
+  switch (argumentA) {
+    case Instruction::kVerifyRegA:
+      result &= CheckRegisterIndex(code_item, dec_insn.vA_);
+      break;
+    case Instruction::kVerifyRegAWide:
+      result &= CheckWideRegisterIndex(code_item, dec_insn.vA_);
+      break;
+  }
+
+  switch (argumentB) {
+    case Instruction::kVerifyRegB:
+      result &= CheckRegisterIndex(code_item, dec_insn.vB_);
+      break;
+    case Instruction::kVerifyRegBField:
+      result &= CheckFieldIndex(dex_file, dec_insn.vB_);
+      break;
+    case Instruction::kVerifyRegBMethod:
+      result &= CheckMethodIndex(dex_file, dec_insn.vB_);
+      break;
+    case Instruction::kVerifyRegBNewInstance:
+      result &= CheckNewInstance(dex_file, dec_insn.vB_);
+      break;
+    case Instruction::kVerifyRegBString:
+      result &= CheckStringIndex(dex_file, dec_insn.vB_);
+      break;
+    case Instruction::kVerifyRegBType:
+      result &= CheckTypeIndex(dex_file, dec_insn.vB_);
+      break;
+    case Instruction::kVerifyRegBWide:
+      result &= CheckWideRegisterIndex(code_item, dec_insn.vB_);
+      break;
+  }
+
+  switch (argumentC) {
+    case Instruction::kVerifyRegC:
+      result &= CheckRegisterIndex(code_item, dec_insn.vC_);
+      break;
+    case Instruction::kVerifyRegCField:
+      result &= CheckFieldIndex(dex_file, dec_insn.vC_);
+      break;
+    case Instruction::kVerifyRegCNewArray:
+      result &= CheckNewArray(dex_file, dec_insn.vC_);
+      break;
+    case Instruction::kVerifyRegCType:
+      result &= CheckTypeIndex(dex_file, dec_insn.vC_);
+      break;
+    case Instruction::kVerifyRegCWide:
+      result &= CheckWideRegisterIndex(code_item, dec_insn.vC_);
+      break;
+  }
+
+  switch (extra_flags) {
+    case Instruction::kVerifyArrayData:
+      result &= CheckArrayData(code_item, code_offset);
+      break;
+    case Instruction::kVerifyBranchTarget:
+      result &= CheckBranchTarget(code_item, insn_flags, code_offset);
+      break;
+    case Instruction::kVerifySwitchTargets:
+      result &= CheckSwitchTargets(code_item, insn_flags, code_offset);
+      break;
+    case Instruction::kVerifyVarArg:
+      result &= CheckVarArgRegs(code_item, dec_insn.vA_, dec_insn.arg_);
+      break;
+    case Instruction::kVerifyVarArgRange:
+      result &= CheckVarArgRangeRegs(code_item, dec_insn.vA_, dec_insn.vC_);
+      break;
+    case Instruction::kVerifyError:
+      LOG(ERROR) << "VFY: unexpected opcode " << std::hex
+                 << (int) dec_insn.opcode_ << std::dec;
+      result = false;
+      break;
+  }
+
+  return result;
 }
 
-/*
- * Visited or changed?
- */
-inline bool InsnIsVisitedOrChanged(const uint32_t insn_flags[], int addr) {
-  return (insn_flags[addr] & (DexVerify::kInsnFlagVisited |
-                              DexVerify::kInsnFlagChanged)) != 0;
-}
+bool DexVerifier::VerifyCodeFlow(VerifierData* vdata) {
+  Method* method = vdata->method_;
+  const DexFile::CodeItem* code_item = vdata->code_item_;
+  uint16_t registers_size = code_item->registers_size_;
+  uint32_t insns_size = code_item->insns_size_;
+  RegisterTable reg_table;
 
-/*
- * In a "try" block?
- */
-inline bool InsnIsInTry(const uint32_t insn_flags[], int addr) {
-  return (insn_flags[addr] & DexVerify::kInsnFlagInTry) != 0;
-}
-inline void InsnSetInTry(uint32_t insn_flags[], int addr, bool inTry) {
-  insn_flags[addr] |= DexVerify::kInsnFlagInTry;
-}
+  if (registers_size * insns_size > 4*1024*1024) {
+    LOG(ERROR) << "VFY: warning: method is huge (regs=" << registers_size
+               << " insns_size=" << insns_size << ")";
+  }
 
-/*
- * Instruction is a branch target or exception handler?
- */
-inline bool InsnIsBranchTarget(const uint32_t insn_flags[], int addr) {
-  return (insn_flags[addr] & DexVerify::kInsnFlagBranchTarget) != 0;
-}
-inline void InsnSetBranchTarget(uint32_t insn_flags[], int addr, bool isBranch)
-{
-  insn_flags[addr] |= DexVerify::kInsnFlagBranchTarget;
-}
+  /* Create and initialize register lists. */
+  if (!InitRegisterTable(vdata, &reg_table, kTrackRegsGcPoints)) {
+    return false;
+  }
 
-/*
- * Instruction is a GC point?
- */
-inline bool InsnIsGcPoint(const uint32_t insn_flags[], int addr) {
-  return (insn_flags[addr] & DexVerify::kInsnFlagGcPoint) != 0;
-}
-inline void InsnSetGcPoint(uint32_t insn_flags[], int addr, bool isGcPoint) {
-  insn_flags[addr] |= DexVerify::kInsnFlagGcPoint;
-}
+  vdata->register_lines_ = reg_table.register_lines_;
+
+  /* Allocate a map to hold the classes of uninitialized instances. */
+  UniquePtr<UninitInstanceMap> uninit_map(CreateUninitInstanceMap(vdata));
+  vdata->uninit_map_ = uninit_map.get();
+
+  /* Initialize register types of method arguments. */
+  if (!SetTypesFromSignature(vdata, reg_table.register_lines_[0].reg_types_)) {
+    LOG(ERROR) << "VFY: bad signature '"
+               << method->GetSignature()->ToModifiedUtf8() << "' for "
+               << method->GetDeclaringClass()->GetDescriptor()->ToModifiedUtf8()
+               << "." << method->GetName()->ToModifiedUtf8();
+    return false;
+  }
+
+  /* Perform code flow verification. */
+  if (!CodeFlowVerifyMethod(vdata, &reg_table)) {
+    return false;
+  }
+
+  /* TODO: Generate a register map. */
 
 
-/*
- * Extract the relative offset from a branch instruction.
- *
- * Returns "false" on failure (e.g. this isn't a branch instruction).
- */
-bool GetBranchOffset(const DexFile::CodeItem* code_item,
-    const uint32_t insn_flags[], int cur_offset, int32_t* pOffset,
+  return true;
+}
+
+bool DexVerifier::ComputeWidthsAndCountOps(VerifierData* vdata) {
+  const uint16_t* insns = vdata->code_item_->insns_;
+  uint32_t insns_size = vdata->code_item_->insns_size_;
+  InsnFlags* insn_flags = vdata->insn_flags_;
+  const byte* ptr = reinterpret_cast<const byte*>(insns);
+  const Instruction* inst = Instruction::At(ptr);
+  size_t new_instance_count = 0;
+  size_t monitor_enter_count = 0;
+  size_t width = 0;
+
+  while (width < insns_size) {
+    Instruction::Code opcode = inst->Opcode();
+    if (opcode == Instruction::NEW_INSTANCE) {
+      new_instance_count++;
+    } else if (opcode == Instruction::MONITOR_ENTER) {
+      monitor_enter_count++;
+    }
+
+    insn_flags[width] |= inst->Size();
+    width += inst->Size();
+    inst = inst->Next();
+  }
+
+  if (width != insns_size) {
+    LOG(ERROR) << "VFY: code did not end where expected (" << width << " vs. "
+               << insns_size << ")";
+    return false;
+  }
+
+  vdata->new_instance_count_ = new_instance_count;
+  vdata->monitor_enter_count_ = monitor_enter_count;
+  return true;
+}
+
+bool DexVerifier::ScanTryCatchBlocks(VerifierData* vdata) {
+  const DexFile::CodeItem* code_item = vdata->code_item_;
+  InsnFlags* insn_flags = vdata->insn_flags_;
+  uint32_t insns_size = code_item->insns_size_;
+  uint32_t tries_size = code_item->tries_size_;
+
+  if (tries_size == 0) {
+    return true;
+  }
+
+  const DexFile::TryItem* tries = DexFile::dexGetTryItems(*code_item, 0);
+
+  for (uint32_t idx = 0; idx < tries_size; idx++) {
+    const DexFile::TryItem* try_item = &tries[idx];
+    uint32_t start = try_item->start_addr_;
+    uint32_t end = start + try_item->insn_count_;
+
+    if ((start >= end) || (start >= insns_size) || (end > insns_size)) {
+      LOG(ERROR) << "VFY: bad exception entry: startAddr=" << start
+                 << " endAddr=" << end << " (size=" << insns_size << ")";
+      return false;
+    }
+
+    if (InsnGetWidth(insn_flags, start) == 0) {
+      LOG(ERROR) << "VFY: 'try' block starts inside an instruction ("
+                 << start << ")";
+      return false;
+    }
+
+    uint32_t addr;
+    for (addr = start; addr < end; addr += InsnGetWidth(insn_flags, addr)) {
+      InsnSetInTry(insn_flags, addr);
+    }
+  }
+
+  /* Iterate over each of the handlers to verify target addresses. */
+  const byte* handlers_ptr = DexFile::dexGetCatchHandlerData(*code_item, 0);
+  uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr);
+  for (uint32_t idx = 0; idx < handlers_size; idx++) {
+    DexFile::CatchHandlerIterator iterator(handlers_ptr);
+
+    for (; !iterator.HasNext(); iterator.Next()) {
+      uint32_t addr = iterator.Get().address_;
+      if (InsnGetWidth(insn_flags, addr) == 0) {
+        LOG(ERROR) << "VFY: exception handler starts at bad address ("
+                   << addr << ")";
+        return false;
+      }
+
+      InsnSetBranchTarget(insn_flags, addr);
+    }
+
+    handlers_ptr = iterator.GetData();
+  }
+
+  return true;
+}
+
+bool DexVerifier::GetBranchOffset(const DexFile::CodeItem* code_item,
+    const InsnFlags insn_flags[], uint32_t cur_offset, int32_t* pOffset,
     bool* pConditional, bool* selfOkay) {
   const uint16_t* insns = code_item->insns_ + cur_offset;
 
@@ -145,12 +493,7 @@
   return true;
 }
 
-
-/*
- * Verify an array data table.  "cur_offset" is the offset of the
- * fill-array-data instruction.
- */
-static bool CheckArrayData(const DexFile::CodeItem* code_item,
+bool DexVerifier::CheckArrayData(const DexFile::CodeItem* code_item,
     uint32_t cur_offset) {
   const uint32_t insn_count = code_item->insns_size_;
   const uint16_t* insns = code_item->insns_ + cur_offset;
@@ -196,13 +539,7 @@
   return true;
 }
 
-/*
- * Perform static checks on a "new-instance" instruction.  Specifically,
- * make sure the class reference isn't for an array class.
- *
- * We don't need the actual class, just a pointer to the class name.
- */
-static bool CheckNewInstance(const DexFile* dex_file, uint32_t idx) {
+bool DexVerifier::CheckNewInstance(const DexFile* dex_file, uint32_t idx) {
   if (idx >= dex_file->GetHeader().type_ids_size_) {
     LOG(ERROR) << "VFY: bad type index " << idx << " (max "
                << dex_file->GetHeader().type_ids_size_ << ")";
@@ -219,12 +556,7 @@
   return true;
 }
 
-/*
- * Perform static checks on a "new-array" instruction.  Specifically, make
- * sure they aren't creating an array of arrays that causes the number of
- * dimensions to exceed 255.
- */
-static bool CheckNewArray(const DexFile* dex_file, uint32_t idx) {
+bool DexVerifier::CheckNewArray(const DexFile* dex_file, uint32_t idx) {
   if (idx >= dex_file->GetHeader().type_ids_size_) {
     LOG(ERROR) << "VFY: bad type index " << idx << " (max "
                << dex_file->GetHeader().type_ids_size_ << ")";
@@ -252,11 +584,7 @@
   return true;
 }
 
-/*
- * Perform static checks on an instruction that takes a class constant.
- * Ensure that the class index is in the valid range.
- */
-static bool CheckTypeIndex(const DexFile* dex_file, uint32_t idx) {
+bool DexVerifier::CheckTypeIndex(const DexFile* dex_file, uint32_t idx) {
   if (idx >= dex_file->GetHeader().type_ids_size_) {
     LOG(ERROR) << "VFY: bad type index " << idx << " (max "
                << dex_file->GetHeader().type_ids_size_ << ")";
@@ -265,11 +593,7 @@
   return true;
 }
 
-/*
- * Perform static checks on a field get or set instruction.  All we do
- * here is ensure that the field index is in the valid range.
- */
-static bool CheckFieldIndex(const DexFile* dex_file, uint32_t idx) {
+bool DexVerifier::CheckFieldIndex(const DexFile* dex_file, uint32_t idx) {
   if (idx >= dex_file->GetHeader().field_ids_size_) {
     LOG(ERROR) << "VFY: bad field index " << idx << " (max "
                << dex_file->GetHeader().field_ids_size_ << ")";
@@ -278,11 +602,7 @@
   return true;
 }
 
-/*
- * Perform static checks on a method invocation instruction.  All we do
- * here is ensure that the method index is in the valid range.
- */
-static bool CheckMethodIndex(const DexFile* dex_file, uint32_t idx) {
+bool DexVerifier::CheckMethodIndex(const DexFile* dex_file, uint32_t idx) {
   if (idx >= dex_file->GetHeader().method_ids_size_) {
     LOG(ERROR) << "VFY: bad method index " << idx << " (max "
                << dex_file->GetHeader().method_ids_size_ << ")";
@@ -291,10 +611,7 @@
   return true;
 }
 
-/*
- * Ensure that the string index is in the valid range.
- */
-static bool CheckStringIndex(const DexFile* dex_file, uint32_t idx) {
+bool DexVerifier::CheckStringIndex(const DexFile* dex_file, uint32_t idx) {
   if (idx >= dex_file->GetHeader().string_ids_size_) {
     LOG(ERROR) << "VFY: bad string index " << idx << " (max "
                << dex_file->GetHeader().string_ids_size_ << ")";
@@ -303,11 +620,8 @@
   return true;
 }
 
-/*
- * Ensure that the register index is valid for this code item.
- */
-static bool CheckRegisterIndex(const DexFile::CodeItem* code_item, uint32_t idx)
-{
+bool DexVerifier::CheckRegisterIndex(const DexFile::CodeItem* code_item,
+    uint32_t idx) {
   if (idx >= code_item->registers_size_) {
     LOG(ERROR) << "VFY: register index out of range (" << idx << " >= "
                << code_item->registers_size_ << ")";
@@ -316,10 +630,7 @@
   return true;
 }
 
-/*
- * Ensure that the wide register index is valid for this code item.
- */
-static bool CheckWideRegisterIndex(const DexFile::CodeItem* code_item,
+bool DexVerifier::CheckWideRegisterIndex(const DexFile::CodeItem* code_item,
     uint32_t idx) {
   if (idx + 1 >= code_item->registers_size_) {
     LOG(ERROR) << "VFY: wide register index out of range (" << idx
@@ -329,19 +640,8 @@
   return true;
 }
 
-/*
- * Check the register indices used in a "vararg" instruction, such as
- * invoke-virtual or filled-new-array.
- *
- * vA holds word count (0-5), args[] have values.
- *
- * There are some tests we don't do here, e.g. we don't try to verify
- * that invoking a method that takes a double is done with consecutive
- * registers.  This requires parsing the target method signature, which
- * we will be doing later on during the code flow analysis.
- */
-static bool CheckVarArgRegs(const DexFile::CodeItem* code_item, uint32_t vA,
-    uint32_t arg[]) {
+bool DexVerifier::CheckVarArgRegs(const DexFile::CodeItem* code_item,
+    uint32_t vA, uint32_t arg[]) {
   uint16_t registers_size = code_item->registers_size_;
   uint32_t idx;
 
@@ -361,13 +661,7 @@
   return true;
 }
 
-/*
- * Check the register indices used in a "vararg/range" instruction, such as
- * invoke-virtual/range or filled-new-array/range.
- *
- * vA holds word count, vC holds index of first reg.
- */
-static bool CheckVarArgRangeRegs(const DexFile::CodeItem* code_item,
+bool DexVerifier::CheckVarArgRangeRegs(const DexFile::CodeItem* code_item,
     uint32_t vA, uint32_t vC) {
   uint16_t registers_size = code_item->registers_size_;
 
@@ -384,13 +678,8 @@
   return true;
 }
 
-/*
- * Verify a switch table. "cur_offset" is the offset of the switch instruction.
- *
- * Updates "insnFlags", setting the "branch target" flag.
- */
-static bool CheckSwitchTargets(const DexFile::CodeItem* code_item,
-    uint32_t insn_flags[], uint32_t cur_offset) {
+bool DexVerifier::CheckSwitchTargets(const DexFile::CodeItem* code_item,
+    InsnFlags insn_flags[], uint32_t cur_offset) {
   const uint32_t insn_count = code_item->insns_size_;
   const uint16_t* insns = code_item->insns_ + cur_offset;
   const uint16_t* switch_insns;
@@ -436,8 +725,9 @@
   table_size = targets_offset + switch_count * 2;
 
   if (switch_insns[0] != expected_signature) {
-    LOG(ERROR) << "VFY: wrong signature for switch table (0x" << switch_insns[0]
-               << ", wanted 0x" << expected_signature << ")";
+    LOG(ERROR) << "VFY: wrong signature for switch table (0x" << std::hex
+               << switch_insns[0] << ", wanted 0x" << expected_signature << ")"
+               << std::dec;
     return false;
   }
 
@@ -478,30 +768,19 @@
     if (abs_offset < 0 || abs_offset >= (int32_t) insn_count ||
         !InsnIsOpcode(insn_flags, abs_offset)) {
       LOG(ERROR) << "VFY: invalid switch target " << offset << " (-> "
-                 << abs_offset << ") at " << cur_offset << "[" << targ << "]";
+                 << std::hex << abs_offset << ") at " << cur_offset << std::dec
+                 << "[" << targ << "]";
       return false;
     }
-    InsnSetBranchTarget(insn_flags, abs_offset, true);
+    InsnSetBranchTarget(insn_flags, abs_offset);
   }
 
   return true;
 }
 
-/*
- * Verify that the target of a branch instruction is valid.
- *
- * We don't expect code to jump directly into an exception handler, but
- * it's valid to do so as long as the target isn't a "move-exception"
- * instruction.  We verify that in a later stage.
- *
- * The VM spec doesn't forbid an instruction from branching to itself,
- * but the Dalvik spec declares that only certain instructions can do so.
- *
- * Updates "insnFlags", setting the "branch target" flag.
- */
-static bool CheckBranchTarget(const DexFile::CodeItem* code_item,
-    uint32_t insn_flags[], int cur_offset) {
-  const int insn_count = code_item->insns_size_;
+bool DexVerifier::CheckBranchTarget(const DexFile::CodeItem* code_item,
+    InsnFlags insn_flags[], uint32_t cur_offset) {
+  const uint32_t insn_count = code_item->insns_size_;
   int32_t offset, abs_offset;
   bool isConditional, selfOkay;
 
@@ -510,7 +789,8 @@
     return false;
 
   if (!selfOkay && offset == 0) {
-    LOG(ERROR) << "VFY: branch offset of zero not allowed at" << cur_offset;
+    LOG(ERROR) << "VFY: branch offset of zero not allowed at" << std::hex
+               << cur_offset << std::dec;
     return false;
   }
 
@@ -520,318 +800,4435 @@
    * it's unwise to depend on that.
    */
   if (((int64_t) cur_offset + (int64_t) offset) !=
-      (int64_t)(cur_offset + offset)) {
-    LOG(ERROR) << "VFY: branch target overflow " << cur_offset << " +"
-               << offset;
+      (int64_t) (cur_offset + offset)) {
+    LOG(ERROR) << "VFY: branch target overflow " << std::hex << cur_offset
+               << std::dec << " +" << offset;
     return false;
   }
   abs_offset = cur_offset + offset;
-  if (abs_offset < 0 || abs_offset >= insn_count ||
+  if (abs_offset < 0 || (uint32_t) abs_offset >= insn_count ||
       !InsnIsOpcode(insn_flags, abs_offset))
   {
     LOG(ERROR) << "VFY: invalid branch target " << offset << " (-> "
-               << abs_offset << ") at " << cur_offset;
+               << std::hex << abs_offset << ") at " << cur_offset << std::dec;
     return false;
   }
-  InsnSetBranchTarget(insn_flags, abs_offset, true);
+  InsnSetBranchTarget(insn_flags, abs_offset);
 
   return true;
 }
 
-bool CheckInsnWidth(const uint16_t* insns, uint32_t insns_size,
-    uint32_t insn_flags[]) {
-  const byte* ptr = reinterpret_cast<const byte*>(insns);
+bool DexVerifier::InitRegisterTable(VerifierData* vdata,
+    RegisterTable* reg_table, RegisterTrackingMode track_regs_for) {
+  const DexFile::CodeItem* code_item = vdata->code_item_;
+  InsnFlags* insn_flags = vdata->insn_flags_;
+  uint16_t registers_size = code_item->registers_size_;
+  uint32_t insns_size = code_item->insns_size_;
+  uint32_t i;
+
+  /*
+   * Every address gets a RegisterLine struct.  This is wasteful, but
+   * not so much that it's worth chasing through an extra level of
+   * indirection.
+   */
+  reg_table->insn_reg_count_plus_ = registers_size + kExtraRegs;
+  reg_table->register_lines_ = new RegisterLine[insns_size]();
+
+  assert(insns_size > 0);
+
+  bool track_monitors;
+  //if (gDvm.monitorVerification) {
+    //track_monitors = (vdata->monitor_enter_count_ != 0);
+  //} else {
+    track_monitors = false;
+  //}
+
+  /*
+   * Allocate entries in the sparse register line table.
+   *
+   * There is a RegisterLine associated with every address, but not
+   * every RegisterLine has non-NULL pointers to storage for its fields.
+   */
+  for (i = 0; i < insns_size; i++) {
+    bool interesting;
+
+    switch (track_regs_for) {
+      case kTrackRegsAll:
+        interesting = InsnIsOpcode(insn_flags, i);
+        break;
+      case kTrackRegsGcPoints:
+        interesting = InsnIsGcPoint(insn_flags, i) ||
+                      InsnIsBranchTarget(insn_flags, i);
+        break;
+      case kTrackRegsBranches:
+        interesting = InsnIsBranchTarget(insn_flags, i);
+        break;
+      default:
+        return false;
+    }
+
+    if (interesting) {
+      reg_table->register_lines_[i].Alloc(reg_table->insn_reg_count_plus_,
+          track_monitors);
+    }
+  }
+
+  /*
+   * Allocate space for our "temporary" register lines.
+   */
+  reg_table->work_line_.Alloc(reg_table->insn_reg_count_plus_, track_monitors);
+  reg_table->saved_line_.Alloc(reg_table->insn_reg_count_plus_, track_monitors);
+
+  return true;
+}
+
+DexVerifier::UninitInstanceMap* DexVerifier::CreateUninitInstanceMap(
+    VerifierData* vdata) {
+  Method* method = vdata->method_;
+  const DexFile::CodeItem* code_item = vdata->code_item_;
+  size_t new_instance_count = vdata->new_instance_count_;
+
+  if (IsInitMethod(method)) {
+    new_instance_count++;
+  }
+
+  /*
+   * Allocate the header and map as a single unit.
+   *
+   * TODO: consider having a static instance so we can avoid allocations.
+   * I don't think the verifier is guaranteed to be single-threaded when
+   * running in the VM (rather than dexopt), so that must be taken into
+   * account.
+   */
+  UninitInstanceMap* uninit_map = new UninitInstanceMap(new_instance_count);
+
+  size_t idx = 0;
+  if (IsInitMethod(method)) {
+    uninit_map->map_[idx++].addr_ = kUninitThisArgAddr;
+  }
+
+  /*
+   * Run through and find the new-instance instructions.
+   */
+  uint32_t addr = 0;
+  uint32_t insns_size = code_item->insns_size_;
+  const byte* ptr = reinterpret_cast<const byte*>(code_item->insns_);
   const Instruction* inst = Instruction::At(ptr);
+  while (addr < insns_size) {
+    Instruction::Code opcode = inst->Opcode();
+    if (opcode == Instruction::NEW_INSTANCE) {
+      uninit_map->map_[idx++].addr_ = addr;
+    }
 
-  size_t width = 0;
-
-  while (width < insns_size) {
-    insn_flags[width] |= inst->Size();
-    width += inst->Size();
+    addr += inst->Size();
     inst = inst->Next();
   }
 
-  if (width != insns_size) {
-    LOG(ERROR) << "VFY: code did not end where expected (" << width << " vs. "
-               << insns_size << ")";
+  assert(idx == new_instance_count);
+  return uninit_map;
+}
+
+bool DexVerifier::IsInitMethod(const Method* method) {
+  return (method->GetName()->Equals("<init>"));
+}
+
+Class* DexVerifier::LookupClassByDescriptor(const Method* method,
+    const char* descriptor, VerifyError* failure) {
+  /*
+   * The compiler occasionally puts references to nonexistent
+   * classes in signatures.  For example, if you have a non-static
+   * inner class with no constructor, the compiler provides
+   * a private <init> for you.  Constructing the class
+   * requires <init>(parent), but the outer class can't call
+   * that because the method is private.  So the compiler
+   * generates a package-scope <init>(parent,bogus) method that
+   * just calls the regular <init> (the "bogus" part being necessary
+   * to distinguish the signature of the synthetic method).
+   * Treating the bogus class as an instance of java.lang.Object
+   * allows the verifier to process the class successfully.
+   */
+  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+  const ClassLoader* class_loader =
+      method->GetDeclaringClass()->GetClassLoader();
+  Class* klass = class_linker->FindClass(descriptor, class_loader);
+
+  if (klass == NULL) {
+    Thread::Current()->ClearException();
+    if (strchr(descriptor, '$') != NULL) {
+      LOG(INFO) << "VFY: unable to find class referenced in signature ("
+                << descriptor << ")";
+    } else {
+      LOG(ERROR) << "VFY: unable to find class referenced in signature ("
+                 << descriptor << ")";
+    }
+
+    /* Check if the descriptor is an array. */
+    if (descriptor[0] == '[') {
+      /*
+       * There should never be a problem loading primitive arrays.
+       */
+      if (descriptor[1] != 'L' && descriptor[1] != '[') {
+        LOG(ERROR) << "VFY: invalid char in signature in '" << descriptor
+                   << "'";
+        *failure = VERIFY_ERROR_GENERIC;
+      }
+
+      /*
+       * Try to continue with base array type.  This will let
+       * us pass basic stuff (e.g. get array len) that wouldn't
+       * fly with an Object.  This is NOT correct if the
+       * missing type is a primitive array, but we should never
+       * have a problem loading those.  (I'm not convinced this
+       * is correct or even useful.  Just use Object here?)
+       */
+      klass = class_linker->FindClass("[Ljava/lang/Object;", class_loader);
+    } else if (descriptor[0] == 'L') {
+      /*
+       * We are looking at a non-array reference descriptor;
+       * try to continue with base reference type.
+       */
+      klass = class_linker->FindSystemClass("Ljava/lang/Object;");
+    } else {
+      /* We are looking at a primitive type. */
+      LOG(ERROR) << "VFY: invalid char in signature in '" << descriptor << "'";
+      *failure = VERIFY_ERROR_GENERIC;
+    }
+
+    if (klass == NULL) {
+      *failure = VERIFY_ERROR_GENERIC;
+    }
+  }
+
+  if (klass->IsPrimitive()) {
+    LOG(ERROR) << "VFY: invalid use of primitive type '" << descriptor << "'";
+    *failure = VERIFY_ERROR_GENERIC;
+    klass = NULL;
+  }
+
+  return klass;
+}
+
+Class* DexVerifier::LookupSignatureClass(const Method* method, std::string sig,
+    VerifyError* failure) {
+  assert(sig[0] == 'L');
+  size_t end = sig.find(';');
+
+  if (end == std::string::npos) {
+    LOG(ERROR) << "VFY: bad signature component '" << sig << "' (missing ';')";
+    *failure = VERIFY_ERROR_GENERIC;
+    return NULL;
+  }
+
+  return LookupClassByDescriptor(method, sig.substr(0, end + 1).c_str(),
+      failure);
+}
+
+Class* DexVerifier::LookupSignatureArrayClass(const Method* method,
+    std::string sig, VerifyError* failure) {
+  assert(sig[0] == '[');
+  size_t end = 0;
+
+  while (sig[end] == '[')
+    end++;
+
+  if (sig[end] == 'L') {
+    end = sig.find(';');
+    if (end == std::string::npos) {
+      LOG(ERROR) << "VFY: bad signature component '" << sig
+                 << "' (missing ';')";
+      *failure = VERIFY_ERROR_GENERIC;
+      return NULL;
+    }
+  }
+
+  return LookupClassByDescriptor(method, sig.substr(0, end + 1).c_str(),
+      failure);
+}
+
+bool DexVerifier::SetTypesFromSignature(VerifierData* vdata, RegType* reg_types)
+{
+  Method* method = vdata->method_;
+  const DexFile* dex_file = vdata->dex_file_;
+  const DexFile::CodeItem* code_item = vdata->code_item_;
+  UninitInstanceMap* uninit_map = vdata->uninit_map_;
+
+  int arg_start = code_item->registers_size_ - code_item->ins_size_;
+  int expected_args = code_item->ins_size_;   /* long/double count as two */
+  int actual_args = 0;
+
+  assert(arg_start >= 0);      /* should have been verified earlier */
+
+  /*
+   * Include the "this" pointer.
+   */
+  if (!method->IsStatic()) {
+    /*
+     * If this is a constructor for a class other than java.lang.Object,
+     * mark the first ("this") argument as uninitialized.  This restricts
+     * field access until the superclass constructor is called.
+     */
+    ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+    Class* klass_object = class_linker->FindSystemClass("Ljava/lang/Object;");
+    if (IsInitMethod(method) && method->GetDeclaringClass() != klass_object) {
+      int idx = SetUninitInstance(uninit_map, kUninitThisArgAddr,
+          method->GetDeclaringClass());
+      assert(idx == 0);
+      reg_types[arg_start + actual_args] = RegTypeFromUninitIndex(idx);
+    } else {
+      reg_types[arg_start + actual_args] =
+          RegTypeFromClass(method->GetDeclaringClass());
+    }
+    actual_args++;
+  }
+
+  const DexFile::ProtoId& proto_id =
+      dex_file->GetProtoId(method->GetProtoIdx());
+  DexFile::ParameterIterator iterator(*dex_file, proto_id);
+  VerifyError failure = VERIFY_ERROR_NONE;
+
+  for (; iterator.HasNext(); iterator.Next()) {
+    const char* descriptor = iterator.GetDescriptor();
+
+    if (descriptor == NULL) {
+      break;
+    }
+
+    if (actual_args >= expected_args) {
+      LOG(ERROR) << "VFY: expected " << expected_args << " args, found more ("
+                 << descriptor << ")";
+      return false;
+    }
+
+    switch (*descriptor) {
+      case 'L':
+      case '[':
+        /*
+         * We assume that reference arguments are initialized.  The
+         * only way it could be otherwise (assuming the caller was
+         * verified) is if the current method is <init>, but in that
+         * case it's effectively considered initialized the instant
+         * we reach here (in the sense that we can return without
+         * doing anything or call virtual methods).
+         */
+        {
+          Class* klass =
+              LookupClassByDescriptor(method, descriptor, &failure);
+          if (failure != VERIFY_ERROR_NONE)
+            return false;
+          reg_types[arg_start + actual_args] = RegTypeFromClass(klass);
+        }
+        actual_args++;
+        break;
+      case 'Z':
+        reg_types[arg_start + actual_args] = kRegTypeBoolean;
+        actual_args++;
+        break;
+      case 'C':
+        reg_types[arg_start + actual_args] = kRegTypeChar;
+        actual_args++;
+        break;
+      case 'B':
+        reg_types[arg_start + actual_args] = kRegTypeByte;
+        actual_args++;
+        break;
+      case 'I':
+        reg_types[arg_start + actual_args] = kRegTypeInteger;
+        actual_args++;
+        break;
+      case 'S':
+        reg_types[arg_start + actual_args] = kRegTypeShort;
+        actual_args++;
+        break;
+      case 'F':
+        reg_types[arg_start + actual_args] = kRegTypeFloat;
+        actual_args++;
+        break;
+      case 'D':
+        reg_types[arg_start + actual_args] = kRegTypeDoubleLo;
+        reg_types[arg_start + actual_args +1] = kRegTypeDoubleHi;
+        actual_args += 2;
+        break;
+      case 'J':
+        reg_types[arg_start + actual_args] = kRegTypeLongLo;
+        reg_types[arg_start + actual_args +1] = kRegTypeLongHi;
+        actual_args += 2;
+        break;
+      default:
+        LOG(ERROR) << "VFY: unexpected signature type char '" << descriptor
+                   << "'";
+        return false;
+    }
+  }
+
+  if (actual_args != expected_args) {
+    LOG(ERROR) << "VFY: expected " << expected_args << " args, found "
+               << actual_args;
     return false;
   }
 
+  const char* descriptor = dex_file->GetReturnTypeDescriptor(proto_id);
+
+  /*
+   * Validate return type.  We don't do the type lookup; just want to make
+   * sure that it has the right format.  Only major difference from the
+   * method argument format is that 'V' is supported.
+   */
+  switch (*descriptor) {
+    case 'I':
+    case 'C':
+    case 'S':
+    case 'B':
+    case 'Z':
+    case 'V':
+    case 'F':
+    case 'D':
+    case 'J':
+      if (*(descriptor + 1) != '\0')
+        return false;
+      break;
+    case '[':
+      /* single/multi, object/primitive */
+      while (*++descriptor == '[')
+        ;
+      if (*descriptor == 'L') {
+        while (*++descriptor != ';' && *descriptor != '\0')
+          ;
+        if (*descriptor != ';')
+          return false;
+      } else {
+        if (*(descriptor+1) != '\0')
+          return false;
+      }
+      break;
+    case 'L':
+      /* could be more thorough here, but shouldn't be required */
+      while (*++descriptor != ';' && *descriptor != '\0')
+        ;
+      if (*descriptor != ';')
+        return false;
+      break;
+    default:
+      return false;
+  }
+
   return true;
 }
 
-/*
- * Set the "in try" flags for all instructions protected by "try" statements.
- * Also sets the "branch target" flags for exception handlers.
- *
- * Call this after widths have been set in "insn_flags".
- *
- * Returns "false" if something in the exception table looks fishy, but
- * we're expecting the exception table to be somewhat sane.
- */
-static bool ScanTryCatchBlocks(const DexFile::CodeItem* code_item,
-    uint32_t insn_flags[]) {
+int DexVerifier::SetUninitInstance(UninitInstanceMap* uninit_map, int addr,
+    Class* klass) {
+  int idx;
+  assert(klass != NULL);
+
+  /* TODO: binary search when numEntries > 8 */
+  for (idx = uninit_map->num_entries_ - 1; idx >= 0; idx--) {
+    if (uninit_map->map_[idx].addr_ == addr) {
+      if (uninit_map->map_[idx].klass_ != NULL &&
+          uninit_map->map_[idx].klass_ != klass) {
+        LOG(ERROR) << "VFY: addr " << addr << " already set to "
+                   << (int) uninit_map->map_[idx].klass_ << ", not setting to "
+                   << (int) klass;
+        return -1;          // already set to something else??
+      }
+      uninit_map->map_[idx].klass_ = klass;
+      return idx;
+    }
+  }
+
+  LOG(ERROR) << "VFY: addr " << addr << " not found in uninit map";
+  assert(false);      // shouldn't happen
+  return -1;
+}
+
+bool DexVerifier::CodeFlowVerifyMethod(VerifierData* vdata,
+    RegisterTable* reg_table) {
+  const Method* method = vdata->method_;
+  const DexFile::CodeItem* code_item = vdata->code_item_;
+  InsnFlags* insn_flags = vdata->insn_flags_;
+  const uint16_t* insns = code_item->insns_;
   uint32_t insns_size = code_item->insns_size_;
-  uint32_t tries_size = code_item->tries_size_;
+  size_t insn_idx, start_guess;
 
-  if (tries_size == 0) {
-    return true;
-  }
+  /* Begin by marking the first instruction as "changed". */
+  InsnSetChanged(insn_flags, 0, true);
 
-  const DexFile::TryItem* tries = DexFile::dexGetTryItems(*code_item, 0);
+  start_guess = 0;
 
-  for (uint32_t idx = 0; idx < tries_size; idx++) {
-    const DexFile::TryItem* try_item = &tries[idx];
-    uint32_t start = try_item->start_addr_;
-    uint32_t end = start + try_item->insn_count_;
+  /* Continue until no instructions are marked "changed". */
+  while (true) {
+    /*
+     * Find the first marked one.  Use "start_guess" as a way to find
+     * one quickly.
+     */
+    for (insn_idx = start_guess; insn_idx < insns_size; insn_idx++) {
+      if (InsnIsChanged(insn_flags, insn_idx))
+        break;
+    }
 
-    if ((start >= end) || (start >= insns_size) || (end > insns_size)) {
-      LOG(ERROR) << "VFY: bad exception entry: startAddr=" << start
-                 << " endAddr=" << end << " (size=" << insns_size << ")";
+    if (insn_idx == insns_size) {
+      if (start_guess != 0) {
+        /* try again, starting from the top */
+        start_guess = 0;
+        continue;
+      } else {
+        /* all flags are clear */
+        break;
+      }
+    }
+
+    /*
+     * We carry the working set of registers from instruction to
+     * instruction.  If this address can be the target of a branch
+     * (or throw) instruction, or if we're skipping around chasing
+     * "changed" flags, we need to load the set of registers from
+     * the table.
+     *
+     * Because we always prefer to continue on to the next instruction,
+     * we should never have a situation where we have a stray
+     * "changed" flag set on an instruction that isn't a branch target.
+     */
+    if (InsnIsBranchTarget(insn_flags, insn_idx)) {
+      RegisterLine* work_line = &reg_table->work_line_;
+      CopyLineFromTable(work_line, reg_table, insn_idx);
+    } else {
+#ifndef NDEBUG
+      /*
+       * Sanity check: retrieve the stored register line (assuming
+       * a full table) and make sure it actually matches.
+       */
+      RegisterLine* register_line = GetRegisterLine(reg_table, insn_idx);
+      if (register_line->reg_types_ != NULL && CompareLineToTable(reg_table,
+          insn_idx, &reg_table->work_line_) != 0) {
+        Class* klass = method->GetDeclaringClass();
+        LOG(ERROR) << "HUH? work_line diverged in "
+                   << klass->GetDescriptor()->ToModifiedUtf8() << "."
+                   << method->GetName()->ToModifiedUtf8() << " "
+                   << method->GetSignature()->ToModifiedUtf8();
+      }
+#endif
+    }
+
+    if (!CodeFlowVerifyInstruction(vdata, reg_table, insn_idx, &start_guess)) {
+      Class* klass = method->GetDeclaringClass();
+      LOG(ERROR) << "VFY: failure to verify "
+                 << klass->GetDescriptor()->ToModifiedUtf8() << "."
+                << method->GetName()->ToModifiedUtf8() << " "
+                << method->GetSignature()->ToModifiedUtf8();
       return false;
     }
 
-    if (InsnGetWidth(insn_flags, start) == 0) {
-      LOG(ERROR) << "VFY: 'try' block starts inside an instruction ("
-                 << start << ")";
-      return false;
-    }
+    /* Clear "changed" and mark as visited. */
+    InsnSetVisited(insn_flags, insn_idx, true);
+    InsnSetChanged(insn_flags, insn_idx, false);
+  }
 
-    uint32_t addr;
-    for (addr = start; addr < end; addr += InsnGetWidth(insn_flags, addr)) {
-      InsnSetInTry(insn_flags, addr, true);
+  if (DEAD_CODE_SCAN && ((method->GetAccessFlags() & kAccWritable) == 0)) {
+    /*
+     * Scan for dead code.  There's nothing "evil" about dead code
+     * (besides the wasted space), but it indicates a flaw somewhere
+     * down the line, possibly in the verifier.
+     *
+     * If we've substituted "always throw" instructions into the stream,
+     * we are almost certainly going to have some dead code.
+     */
+    int dead_start = -1;
+    for (insn_idx = 0; insn_idx < insns_size;
+         insn_idx += InsnGetWidth(insn_flags, insn_idx)) {
+      /*
+       * Switch-statement data doesn't get "visited" by scanner.  It
+       * may or may not be preceded by a padding NOP (for alignment).
+       */
+      if (insns[insn_idx] == Instruction::kPackedSwitchSignature ||
+          insns[insn_idx] == Instruction::kSparseSwitchSignature ||
+          insns[insn_idx] == Instruction::kArrayDataSignature ||
+          (insns[insn_idx] == Instruction::NOP &&
+           (insns[insn_idx + 1] == Instruction::kPackedSwitchSignature ||
+            insns[insn_idx + 1] == Instruction::kSparseSwitchSignature ||
+            insns[insn_idx + 1] == Instruction::kArrayDataSignature))) {
+        InsnSetVisited(insn_flags, insn_idx, true);
+      }
+
+      if (!InsnIsVisited(insn_flags, insn_idx)) {
+        if (dead_start < 0)
+          dead_start = insn_idx;
+      } else if (dead_start >= 0) {
+        Class* klass = method->GetDeclaringClass();
+        LOG(INFO) << "VFY: dead code 0x" << std::hex << dead_start << "-"
+                  << insn_idx - 1 << std::dec << " in "
+                  << klass->GetDescriptor()->ToModifiedUtf8() << "."
+                  << method->GetName()->ToModifiedUtf8() << " "
+                  << method->GetSignature()->ToModifiedUtf8();
+        dead_start = -1;
+      }
+    }
+    if (dead_start >= 0) {
+      Class* klass = method->GetDeclaringClass();
+      LOG(INFO) << "VFY: dead code 0x" << std::hex << dead_start << "-"
+                << insn_idx - 1 << std::dec << " in "
+                << klass->GetDescriptor()->ToModifiedUtf8() << "."
+                << method->GetName()->ToModifiedUtf8() << " "
+                << method->GetSignature()->ToModifiedUtf8();
     }
   }
 
-  /* Iterate over each of the handlers to verify target addresses. */
+  return true;
+}
+
+bool DexVerifier::CodeFlowVerifyInstruction(VerifierData* vdata,
+    RegisterTable* reg_table, uint32_t insn_idx, size_t* start_guess) {
+  const Method* method = vdata->method_;
+  Class* klass = method->GetDeclaringClass();
+  const DexFile::CodeItem* code_item = vdata->code_item_;
+  InsnFlags* insn_flags = vdata->insn_flags_;
+  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+  UninitInstanceMap* uninit_map = vdata->uninit_map_;
+  const uint16_t* insns = code_item->insns_ + insn_idx;
+  uint32_t insns_size = code_item->insns_size_;
+  uint32_t registers_size = code_item->registers_size_;
+
+#ifdef VERIFIER_STATS
+  if (InsnIsVisited(insn_flags, insn_idx)) {
+    gDvm.verifierStats.instrsReexamined++;
+  } else {
+    gDvm.verifierStats.instrsExamined++;
+  }
+#endif
+
+  /*
+   * Once we finish decoding the instruction, we need to figure out where
+   * we can go from here.  There are three possible ways to transfer
+   * control to another statement:
+   *
+   * (1) Continue to the next instruction.  Applies to all but
+   *     unconditional branches, method returns, and exception throws.
+   * (2) Branch to one or more possible locations.  Applies to branches
+   *     and switch statements.
+   * (3) Exception handlers.  Applies to any instruction that can
+   *     throw an exception that is handled by an encompassing "try"
+   *     block.
+   *
+   * We can also return, in which case there is no successor instruction
+   * from this point.
+   *
+   * The behavior can be determined from the OpcodeFlags.
+   */
+  RegisterLine* work_line = &reg_table->work_line_;
+  const DexFile* dex_file = vdata->dex_file_;
+  const byte* ptr = reinterpret_cast<const byte*>(insns);
+  const Instruction* inst = Instruction::At(ptr);
+  Instruction::DecodedInstruction dec_insn(inst);
+  int opcode_flag = inst->Flag();
+
+  Class* res_class;
+  int32_t branch_target = 0;
+  RegType tmp_type;
+  bool just_set_result = false;
+  VerifyError failure = VERIFY_ERROR_NONE;
+
+  /*
+   * Make a copy of the previous register state.  If the instruction
+   * can throw an exception, we will copy/merge this into the "catch"
+   * address rather than work_line, because we don't want the result
+   * from the "successful" code path (e.g. a check-cast that "improves"
+   * a type) to be visible to the exception handler.
+   */
+  if ((opcode_flag & Instruction::kThrow) != 0 &&
+      InsnIsInTry(insn_flags, insn_idx)) {
+    CopyRegisterLine(&reg_table->saved_line_, work_line,
+        reg_table->insn_reg_count_plus_);
+  } else {
+#ifndef NDEBUG
+    memset(reg_table->saved_line_.reg_types_, 0xdd,
+        reg_table->insn_reg_count_plus_ * sizeof(RegType));
+#endif
+  }
+
+  switch (dec_insn.opcode_) {
+    case Instruction::NOP:
+      /*
+       * A "pure" NOP has no effect on anything.  Data tables start with
+       * a signature that looks like a NOP; if we see one of these in
+       * the course of executing code then we have a problem.
+       */
+      if (dec_insn.vA_ != 0) {
+        LOG(ERROR) << "VFY: encountered data table in instruction stream";
+        failure = VERIFY_ERROR_GENERIC;
+      }
+      break;
+
+    case Instruction::MOVE:
+    case Instruction::MOVE_FROM16:
+    case Instruction::MOVE_16:
+      CopyRegister1(work_line, dec_insn.vA_, dec_insn.vB_, kTypeCategory1nr,
+          &failure);
+      break;
+    case Instruction::MOVE_WIDE:
+    case Instruction::MOVE_WIDE_FROM16:
+    case Instruction::MOVE_WIDE_16:
+      CopyRegister2(work_line, dec_insn.vA_, dec_insn.vB_, &failure);
+      break;
+    case Instruction::MOVE_OBJECT:
+    case Instruction::MOVE_OBJECT_FROM16:
+    case Instruction::MOVE_OBJECT_16:
+      CopyRegister1(work_line, dec_insn.vA_, dec_insn.vB_, kTypeCategoryRef,
+          &failure);
+      break;
+
+    /*
+     * The move-result instructions copy data out of a "pseudo-register"
+     * with the results from the last method invocation.  In practice we
+     * might want to hold the result in an actual CPU register, so the
+     * Dalvik spec requires that these only appear immediately after an
+     * invoke or filled-new-array.
+     *
+     * These calls invalidate the "result" register.  (This is now
+     * redundant with the reset done below, but it can make the debug info
+     * easier to read in some cases.)
+     */
+    case Instruction::MOVE_RESULT:
+      CopyResultRegister1(work_line, registers_size, dec_insn.vA_,
+          kTypeCategory1nr, &failure);
+      break;
+    case Instruction::MOVE_RESULT_WIDE:
+      CopyResultRegister2(work_line, registers_size, dec_insn.vA_, &failure);
+      break;
+    case Instruction::MOVE_RESULT_OBJECT:
+      CopyResultRegister1(work_line, registers_size, dec_insn.vA_,
+          kTypeCategoryRef, &failure);
+      break;
+
+    case Instruction::MOVE_EXCEPTION:
+      /*
+       * This statement can only appear as the first instruction in an
+       * exception handler (though not all exception handlers need to
+       * have one of these).  We verify that as part of extracting the
+       * exception type from the catch block list.
+       *
+       * "res_class" will hold the closest common superclass of all
+       * exceptions that can be handled here.
+       */
+      res_class = GetCaughtExceptionType(vdata, insn_idx, &failure);
+      if (res_class == NULL) {
+        assert(failure != VERIFY_ERROR_NONE);
+      } else {
+        SetRegisterType(work_line, dec_insn.vA_, RegTypeFromClass(res_class));
+      }
+      break;
+
+    case Instruction::RETURN_VOID:
+      if (!CheckConstructorReturn(method, work_line, registers_size)) {
+        failure = VERIFY_ERROR_GENERIC;
+      } else if (GetMethodReturnType(dex_file, method) != kRegTypeUnknown) {
+        LOG(ERROR) << "VFY: return-void not expected";
+        failure = VERIFY_ERROR_GENERIC;
+      }
+      break;
+    case Instruction::RETURN:
+      if (!CheckConstructorReturn(method, work_line, registers_size)) {
+        failure = VERIFY_ERROR_GENERIC;
+      } else {
+        /* check the method signature */
+        RegType return_type = GetMethodReturnType(dex_file, method);
+        CheckTypeCategory(return_type, kTypeCategory1nr, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          LOG(ERROR) << "VFY: return-1nr not expected";
+
+        /*
+         * compiler may generate synthetic functions that write byte
+         * values into boolean fields. Also, it may use integer values
+         * for boolean, byte, short, and character return types.
+         */
+        RegType src_type = GetRegisterType(work_line, dec_insn.vA_);
+        if ((return_type == kRegTypeBoolean && src_type == kRegTypeByte) ||
+           ((return_type == kRegTypeBoolean || return_type == kRegTypeByte ||
+             return_type == kRegTypeShort || return_type == kRegTypeChar) &&
+             src_type == kRegTypeInteger))
+          return_type = src_type;
+
+        /* check the register contents */
+        VerifyRegisterType(work_line, dec_insn.vA_, return_type, &failure);
+        if (failure != VERIFY_ERROR_NONE) {
+          LOG(ERROR) << "VFY: return-1nr on invalid register v" << dec_insn.vA_;
+        }
+      }
+      break;
+    case Instruction::RETURN_WIDE:
+      if (!CheckConstructorReturn(method, work_line, registers_size)) {
+        failure = VERIFY_ERROR_GENERIC;
+      } else {
+        RegType return_type;
+
+        /* check the method signature */
+        return_type = GetMethodReturnType(dex_file, method);
+        CheckTypeCategory(return_type, kTypeCategory2, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          LOG(ERROR) << "VFY: return-wide not expected";
+
+        /* check the register contents */
+        VerifyRegisterType(work_line, dec_insn.vA_, return_type, &failure);
+        if (failure != VERIFY_ERROR_NONE) {
+          LOG(ERROR) << "VFY: return-wide on invalid register pair v"
+                     << dec_insn.vA_;
+        }
+      }
+      break;
+    case Instruction::RETURN_OBJECT:
+      if (!CheckConstructorReturn(method, work_line, registers_size)) {
+        failure = VERIFY_ERROR_GENERIC;
+      } else {
+        RegType return_type = GetMethodReturnType(dex_file, method);
+        CheckTypeCategory(return_type, kTypeCategoryRef, &failure);
+        if (failure != VERIFY_ERROR_NONE) {
+          LOG(ERROR) << "VFY: return-object not expected";
+          break;
+        }
+
+        /* return_type is the *expected* return type, not register value */
+        assert(return_type != kRegTypeZero);
+        assert(!RegTypeIsUninitReference(return_type));
+
+        /*
+         * Verify that the reference in vAA is an instance of the type
+         * in "return_type".  The Zero type is allowed here.  If the
+         * method is declared to return an interface, then any
+         * initialized reference is acceptable.
+         *
+         * Note GetClassFromRegister fails if the register holds an
+         * uninitialized reference, so we do not allow them to be
+         * returned.
+         */
+        Class* decl_class = RegTypeInitializedReferenceToClass(return_type);
+        res_class = GetClassFromRegister(work_line, dec_insn.vA_, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+        if (res_class != NULL) {
+          if (!decl_class->IsInterface() &&
+              //!res_class->InstanceOf(decl_class)) {
+              !decl_class->IsAssignableFrom(res_class)) {
+            LOG(ERROR) << "VFY: returning " << std::hex
+                       << res_class->GetDescriptor()->ToModifiedUtf8()
+                       << " (cl=0x" << (int) res_class->GetClassLoader()
+                       << "), declared "
+                       << decl_class->GetDescriptor()->ToModifiedUtf8()
+                       << " (cl=0x" << (int) decl_class->GetClassLoader()
+                       << ")" << std::dec;
+            failure = VERIFY_ERROR_GENERIC;
+            break;
+          }
+        }
+      }
+      break;
+
+    case Instruction::CONST_4:
+    case Instruction::CONST_16:
+    case Instruction::CONST:
+      /* could be boolean, int, float, or a null reference */
+      SetRegisterType(work_line, dec_insn.vA_,
+          DetermineCat1Const((int32_t) dec_insn.vB_));
+      break;
+    case Instruction::CONST_HIGH16:
+      /* could be boolean, int, float, or a null reference */
+      SetRegisterType(work_line, dec_insn.vA_,
+          DetermineCat1Const((int32_t) dec_insn.vB_ << 16));
+      break;
+    case Instruction::CONST_WIDE_16:
+    case Instruction::CONST_WIDE_32:
+    case Instruction::CONST_WIDE:
+    case Instruction::CONST_WIDE_HIGH16:
+      /* could be long or double; resolved upon use */
+      SetRegisterType(work_line, dec_insn.vA_, kRegTypeConstLo);
+      break;
+    case Instruction::CONST_STRING:
+    case Instruction::CONST_STRING_JUMBO:
+      SetRegisterType(work_line, dec_insn.vA_, RegTypeFromClass(
+          class_linker->FindSystemClass("Ljava/lang/String;")));
+      break;
+    case Instruction::CONST_CLASS:
+      /* make sure we can resolve the class; access check is important */
+      res_class = class_linker->ResolveType(*dex_file, dec_insn.vB_, klass);
+      if (res_class == NULL) {
+        const char* bad_class_desc = dex_file->dexStringByTypeIdx(dec_insn.vB_);
+        LOG(ERROR) << "VFY: unable to resolve const-class " << dec_insn.vB_
+                   << " (" << bad_class_desc << ") in "
+                   << klass->GetDescriptor()->ToModifiedUtf8();
+        assert(failure != VERIFY_ERROR_GENERIC);
+      } else {
+        SetRegisterType(work_line, dec_insn.vA_, RegTypeFromClass(
+            class_linker->FindSystemClass("Ljava/lang/Class;")));
+      }
+      break;
+
+    case Instruction::MONITOR_ENTER:
+      HandleMonitorEnter(work_line, dec_insn.vA_, insn_idx, &failure);
+      break;
+    case Instruction::MONITOR_EXIT:
+      /*
+       * monitor-exit instructions are odd.  They can throw exceptions,
+       * but when they do they act as if they succeeded and the PC is
+       * pointing to the following instruction.  (This behavior goes back
+       * to the need to handle asynchronous exceptions, a now-deprecated
+       * feature that Dalvik doesn't support.)
+       *
+       * In practice we don't need to worry about this.  The only
+       * exceptions that can be thrown from monitor-exit are for a
+       * null reference and -exit without a matching -enter.  If the
+       * structured locking checks are working, the former would have
+       * failed on the -enter instruction, and the latter is impossible.
+       *
+       * This is fortunate, because issue 3221411 prevents us from
+       * chasing the "can throw" path when monitor verification is
+       * enabled.  If we can fully verify the locking we can ignore
+       * some catch blocks (which will show up as "dead" code when
+       * we skip them here); if we can't, then the code path could be
+       * "live" so we still need to check it.
+       */
+      if (work_line->monitor_entries_ != NULL)
+        opcode_flag &= ~Instruction::kThrow;
+      HandleMonitorExit(work_line, dec_insn.vA_, insn_idx, &failure);
+      break;
+
+    case Instruction::CHECK_CAST:
+      /*
+       * If this instruction succeeds, we will promote register vA to
+       * the type in vB.  (This could be a demotion -- not expected, so
+       * we don't try to address it.)
+       *
+       * If it fails, an exception is thrown, which we deal with later
+       * by ignoring the update to dec_insn.vA_ when branching to a handler.
+       */
+      res_class = class_linker->ResolveType(*dex_file, dec_insn.vB_, klass);
+      if (res_class == NULL) {
+        const char* bad_class_desc = dex_file->dexStringByTypeIdx(dec_insn.vB_);
+        LOG(ERROR) << "VFY: unable to resolve check-cast " << dec_insn.vB_
+                   << " (" << bad_class_desc << ") in "
+                   << klass->GetDescriptor()->ToModifiedUtf8();
+        assert(failure != VERIFY_ERROR_GENERIC);
+      } else {
+        RegType orig_type;
+
+        orig_type = GetRegisterType(work_line, dec_insn.vA_);
+        if (!RegTypeIsReference(orig_type)) {
+          LOG(ERROR) << "VFY: check-cast on non-reference in v" << dec_insn.vA_;
+          failure = VERIFY_ERROR_GENERIC;
+          break;
+        }
+        SetRegisterType(work_line, dec_insn.vA_, RegTypeFromClass(res_class));
+      }
+      break;
+    case Instruction::INSTANCE_OF:
+      /* make sure we're checking a reference type */
+      tmp_type = GetRegisterType(work_line, dec_insn.vB_);
+      if (!RegTypeIsReference(tmp_type)) {
+        LOG(ERROR) << "VFY: vB not a reference (" << tmp_type << ")";
+        failure = VERIFY_ERROR_GENERIC;
+        break;
+      }
+
+      /* make sure we can resolve the class; access check is important */
+      res_class = class_linker->ResolveType(*dex_file, dec_insn.vC_, klass);
+      if (res_class == NULL) {
+        const char* bad_class_desc = dex_file->dexStringByTypeIdx(dec_insn.vC_);
+        LOG(ERROR) << "VFY: unable to resolve instanceof " << dec_insn.vC_
+                   << " (" << bad_class_desc << ") in "
+                   << klass->GetDescriptor()->ToModifiedUtf8();
+        assert(failure != VERIFY_ERROR_GENERIC);
+      } else {
+        /* result is boolean */
+        SetRegisterType(work_line, dec_insn.vA_, kRegTypeBoolean);
+      }
+      break;
+
+    case Instruction::ARRAY_LENGTH:
+      res_class = GetClassFromRegister(work_line, dec_insn.vB_, &failure);
+      if (failure != VERIFY_ERROR_NONE)
+        break;
+      if (res_class != NULL && !res_class->IsArrayClass()) {
+        LOG(ERROR) << "VFY: array-length on non-array";
+        failure = VERIFY_ERROR_GENERIC;
+        break;
+      }
+      SetRegisterType(work_line, dec_insn.vA_, kRegTypeInteger);
+      break;
+
+    case Instruction::NEW_INSTANCE:
+      res_class = class_linker->ResolveType(*dex_file, dec_insn.vB_, klass);
+      if (res_class == NULL) {
+        const char* bad_class_desc = dex_file->dexStringByTypeIdx(dec_insn.vB_);
+        LOG(ERROR) << "VFY: unable to resolve new-instance " << dec_insn.vB_
+                   << " (" << bad_class_desc << ") in "
+                   << klass->GetDescriptor()->ToModifiedUtf8();
+        assert(failure != VERIFY_ERROR_GENERIC);
+      } else {
+        RegType uninit_type;
+
+        /* can't create an instance of an interface or abstract class */
+        if (res_class->IsAbstract() || res_class->IsInterface()) {
+          LOG(ERROR) << "VFY: new-instance on interface or abstract class"
+                     << res_class->GetDescriptor()->ToModifiedUtf8();
+          failure = VERIFY_ERROR_INSTANTIATION;
+          break;
+        }
+
+        /* add resolved class to uninit map if not already there */
+        int uidx = SetUninitInstance(uninit_map, insn_idx, res_class);
+        assert(uidx >= 0);
+        uninit_type = RegTypeFromUninitIndex(uidx);
+
+        /*
+         * Any registers holding previous allocations from this address
+         * that have not yet been initialized must be marked invalid.
+         */
+        MarkUninitRefsAsInvalid(work_line, registers_size, uninit_map,
+            uninit_type);
+
+        /* add the new uninitialized reference to the register ste */
+        SetRegisterType(work_line, dec_insn.vA_, uninit_type);
+      }
+      break;
+   case Instruction::NEW_ARRAY:
+      res_class = class_linker->ResolveType(*dex_file, dec_insn.vC_, klass);
+      if (res_class == NULL) {
+        const char* bad_class_desc = dex_file->dexStringByTypeIdx(dec_insn.vC_);
+        LOG(ERROR) << "VFY: unable to resolve new-array " << dec_insn.vC_
+                   << " (" << bad_class_desc << ") in "
+                   << klass->GetDescriptor()->ToModifiedUtf8();
+        assert(failure != VERIFY_ERROR_GENERIC);
+      } else if (!res_class->IsArrayClass()) {
+        LOG(ERROR) << "VFY: new-array on non-array class";
+        failure = VERIFY_ERROR_GENERIC;
+      } else {
+        /* make sure "size" register is valid type */
+        VerifyRegisterType(work_line, dec_insn.vB_, kRegTypeInteger, &failure);
+        /* set register type to array class */
+        SetRegisterType(work_line, dec_insn.vA_, RegTypeFromClass(res_class));
+      }
+      break;
+    case Instruction::FILLED_NEW_ARRAY:
+    case Instruction::FILLED_NEW_ARRAY_RANGE:
+      res_class = class_linker->ResolveType(*dex_file, dec_insn.vB_, klass);
+      if (res_class == NULL) {
+        const char* bad_class_desc = dex_file->dexStringByTypeIdx(dec_insn.vB_);
+        LOG(ERROR) << "VFY: unable to resolve filled-array " << dec_insn.vB_
+                   << " (" << bad_class_desc << ") in "
+                   << klass->GetDescriptor()->ToModifiedUtf8();
+        assert(failure != VERIFY_ERROR_GENERIC);
+      } else if (!res_class->IsArrayClass()) {
+        LOG(ERROR) << "VFY: filled-new-array on non-array class";
+        failure = VERIFY_ERROR_GENERIC;
+      } else {
+        bool is_range = (dec_insn.opcode_ ==
+            Instruction::FILLED_NEW_ARRAY_RANGE);
+
+        /* check the arguments to the instruction */
+        VerifyFilledNewArrayRegs(method, work_line, &dec_insn, res_class,
+            is_range, &failure);
+        /* filled-array result goes into "result" register */
+        SetResultRegisterType(work_line, registers_size,
+            RegTypeFromClass(res_class));
+        just_set_result = true;
+      }
+      break;
+
+    case Instruction::CMPL_FLOAT:
+    case Instruction::CMPG_FLOAT:
+      VerifyRegisterType(work_line, dec_insn.vB_, kRegTypeFloat, &failure);
+      VerifyRegisterType(work_line, dec_insn.vC_, kRegTypeFloat, &failure);
+      SetRegisterType(work_line, dec_insn.vA_, kRegTypeBoolean);
+      break;
+    case Instruction::CMPL_DOUBLE:
+    case Instruction::CMPG_DOUBLE:
+      VerifyRegisterType(work_line, dec_insn.vB_, kRegTypeDoubleLo, &failure);
+      VerifyRegisterType(work_line, dec_insn.vC_, kRegTypeDoubleLo, &failure);
+      SetRegisterType(work_line, dec_insn.vA_, kRegTypeBoolean);
+      break;
+    case Instruction::CMP_LONG:
+      VerifyRegisterType(work_line, dec_insn.vB_, kRegTypeLongLo, &failure);
+      VerifyRegisterType(work_line, dec_insn.vC_, kRegTypeLongLo, &failure);
+      SetRegisterType(work_line, dec_insn.vA_, kRegTypeBoolean);
+      break;
+
+    case Instruction::THROW:
+      res_class = GetClassFromRegister(work_line, dec_insn.vA_, &failure);
+      if (failure == VERIFY_ERROR_NONE && res_class != NULL) {
+        Class* throwable_class =
+            class_linker->FindSystemClass("Ljava/lang/Throwable;");
+        if (!throwable_class->IsAssignableFrom(res_class)) {
+          LOG(ERROR) << "VFY: thrown class "
+                     << res_class->GetDescriptor()->ToModifiedUtf8()
+                     << " not instanceof Throwable",
+          failure = VERIFY_ERROR_GENERIC;
+        }
+      }
+      break;
+
+    case Instruction::GOTO:
+    case Instruction::GOTO_16:
+    case Instruction::GOTO_32:
+      /* no effect on or use of registers */
+      break;
+
+    case Instruction::PACKED_SWITCH:
+    case Instruction::SPARSE_SWITCH:
+      /* verify that vAA is an integer, or can be converted to one */
+      VerifyRegisterType(work_line, dec_insn.vA_, kRegTypeInteger, &failure);
+      break;
+
+    case Instruction::FILL_ARRAY_DATA:
+      {
+        RegType value_type;
+        const uint16_t *array_data;
+        uint16_t elem_width;
+
+        /* Similar to the verification done for APUT */
+        res_class = GetClassFromRegister(work_line, dec_insn.vA_, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+
+        /* res_class can be null if the reg type is Zero */
+        if (res_class == NULL)
+          break;
+
+        Class::PrimitiveType prim_type =
+            res_class->GetComponentType()->GetPrimitiveType();
+        if (!res_class->IsArrayClass() || res_class->GetArrayRank() != 1 ||
+            prim_type == Class::kPrimNot || prim_type == Class::kPrimVoid) {
+          LOG(ERROR) << "VFY: invalid fill-array-data on " <<
+                res_class->GetDescriptor()->ToModifiedUtf8();
+          failure = VERIFY_ERROR_GENERIC;
+          break;
+        }
+
+        value_type = PrimitiveTypeToRegType(prim_type);
+        assert(value_type != kRegTypeUnknown);
+
+        /*
+         * Now verify if the element width in the table matches the element
+         * width declared in the array
+         */
+        array_data = insns + (insns[1] | (((int32_t) insns[2]) << 16));
+        if (array_data[0] != Instruction::kArrayDataSignature) {
+          LOG(ERROR) << "VFY: invalid magic for array-data";
+          failure = VERIFY_ERROR_GENERIC;
+          break;
+        }
+
+        switch (prim_type) {
+          case Class::kPrimBoolean:
+          case Class::kPrimByte:
+            elem_width = 1;
+            break;
+          case Class::kPrimChar:
+          case Class::kPrimShort:
+            elem_width = 2;
+            break;
+          case Class::kPrimFloat:
+          case Class::kPrimInt:
+            elem_width = 4;
+            break;
+          case Class::kPrimDouble:
+          case Class::kPrimLong:
+            elem_width = 8;
+            break;
+          default:
+            elem_width = 0;
+            break;
+        }
+
+        /*
+         * Since we don't compress the data in Dex, expect to see equal
+         * width of data stored in the table and expected from the array
+         * class.
+         */
+        if (array_data[1] != elem_width) {
+          LOG(ERROR) << "VFY: array-data size mismatch (" << array_data[1]
+                     << " vs " << elem_width << ")";
+          failure = VERIFY_ERROR_GENERIC;
+        }
+      }
+      break;
+
+    case Instruction::IF_EQ:
+    case Instruction::IF_NE:
+      {
+        RegType type1, type2;
+
+        type1 = GetRegisterType(work_line, dec_insn.vA_);
+        type2 = GetRegisterType(work_line, dec_insn.vB_);
+
+        /* both references? */
+        if (RegTypeIsReference(type1) && RegTypeIsReference(type2))
+          break;
+
+        /* both category-1nr? */
+        CheckTypeCategory(type1, kTypeCategory1nr, &failure);
+        CheckTypeCategory(type2, kTypeCategory1nr, &failure);
+        if (failure != VERIFY_ERROR_NONE) {
+          LOG(ERROR) << "VFY: args to if-eq/if-ne must both be refs or cat1";
+          break;
+        }
+      }
+      break;
+    case Instruction::IF_LT:
+    case Instruction::IF_GE:
+    case Instruction::IF_GT:
+    case Instruction::IF_LE:
+      tmp_type = GetRegisterType(work_line, dec_insn.vA_);
+      CheckTypeCategory(tmp_type, kTypeCategory1nr, &failure);
+      if (failure != VERIFY_ERROR_NONE) {
+        LOG(ERROR) << "VFY: args to 'if' must be cat-1nr";
+        break;
+      }
+      tmp_type = GetRegisterType(work_line, dec_insn.vB_);
+      CheckTypeCategory(tmp_type, kTypeCategory1nr, &failure);
+      if (failure != VERIFY_ERROR_NONE) {
+        LOG(ERROR) << "VFY: args to 'if' must be cat-1nr";
+        break;
+      }
+      break;
+    case Instruction::IF_EQZ:
+    case Instruction::IF_NEZ:
+      tmp_type = GetRegisterType(work_line, dec_insn.vA_);
+      if (RegTypeIsReference(tmp_type))
+        break;
+      CheckTypeCategory(tmp_type, kTypeCategory1nr, &failure);
+      if (failure != VERIFY_ERROR_NONE)
+        LOG(ERROR) << "VFY: expected cat-1 arg to if";
+      break;
+    case Instruction::IF_LTZ:
+    case Instruction::IF_GEZ:
+    case Instruction::IF_GTZ:
+    case Instruction::IF_LEZ:
+      tmp_type = GetRegisterType(work_line, dec_insn.vA_);
+      CheckTypeCategory(tmp_type, kTypeCategory1nr, &failure);
+      if (failure != VERIFY_ERROR_NONE)
+        LOG(ERROR) << "VFY: expected cat-1 arg to if";
+      break;
+
+    case Instruction::AGET:
+      tmp_type = kRegTypeConstInteger;
+      goto aget_1nr_common;
+    case Instruction::AGET_BOOLEAN:
+      tmp_type = kRegTypeBoolean;
+      goto aget_1nr_common;
+    case Instruction::AGET_BYTE:
+      tmp_type = kRegTypeByte;
+      goto aget_1nr_common;
+    case Instruction::AGET_CHAR:
+      tmp_type = kRegTypeChar;
+      goto aget_1nr_common;
+    case Instruction::AGET_SHORT:
+      tmp_type = kRegTypeShort;
+      goto aget_1nr_common;
+aget_1nr_common:
+      {
+        RegType src_type, index_type;
+
+        index_type = GetRegisterType(work_line, dec_insn.vC_);
+        CheckArrayIndexType(method, index_type, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+
+        res_class = GetClassFromRegister(work_line, dec_insn.vB_, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+        if (res_class != NULL) {
+          /* verify the class */
+          Class::PrimitiveType prim_type =
+              res_class->GetComponentType()->GetPrimitiveType();
+          if (!res_class->IsArrayClass() || res_class->GetArrayRank() != 1 ||
+              prim_type == Class::kPrimNot) {
+            LOG(ERROR) << "VFY: invalid aget-1nr target "
+                       << res_class->GetDescriptor()->ToModifiedUtf8();
+            failure = VERIFY_ERROR_GENERIC;
+            break;
+          }
+
+          /* make sure array type matches instruction */
+          src_type = PrimitiveTypeToRegType(prim_type);
+
+          /* differentiate between float and int */
+          if (src_type == kRegTypeFloat || src_type == kRegTypeInteger)
+            tmp_type = src_type;
+
+          if (tmp_type != src_type) {
+            LOG(ERROR) << "VFY: invalid aget-1nr, array type=" << src_type
+                       << " with inst type=" << tmp_type << " (on "
+                       << res_class->GetDescriptor()->ToModifiedUtf8() << ")";
+            failure = VERIFY_ERROR_GENERIC;
+            break;
+          }
+
+        }
+        SetRegisterType(work_line, dec_insn.vA_, tmp_type);
+      }
+      break;
+
+    case Instruction::AGET_WIDE:
+      {
+        RegType dst_type, index_type;
+
+        index_type = GetRegisterType(work_line, dec_insn.vC_);
+        CheckArrayIndexType(method, index_type, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+
+        res_class = GetClassFromRegister(work_line, dec_insn.vB_, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+        if (res_class != NULL) {
+          /* verify the class */
+          Class::PrimitiveType prim_type =
+              res_class->GetComponentType()->GetPrimitiveType();
+          if (!res_class->IsArrayClass() || res_class->GetArrayRank() != 1 ||
+              prim_type == Class::kPrimNot) {
+            LOG(ERROR) << "VFY: invalid aget-wide target "
+                       << res_class->GetDescriptor()->ToModifiedUtf8();
+            failure = VERIFY_ERROR_GENERIC;
+            break;
+          }
+
+          /* try to refine "dst_type" */
+          switch (prim_type) {
+            case Class::kPrimLong:
+              dst_type = kRegTypeLongLo;
+              break;
+            case Class::kPrimDouble:
+              dst_type = kRegTypeDoubleLo;
+              break;
+            default:
+              LOG(ERROR) << "VFY: invalid aget-wide on "
+                         << res_class->GetDescriptor()->ToModifiedUtf8();
+              dst_type = kRegTypeUnknown;
+              failure = VERIFY_ERROR_GENERIC;
+              break;
+          }
+        } else {
+          /*
+           * Null array ref; this code path will fail at runtime.  We
+           * know this is either long or double, so label it const.
+           */
+          dst_type = kRegTypeConstLo;
+        }
+        SetRegisterType(work_line, dec_insn.vA_, dst_type);
+      }
+      break;
+
+    case Instruction::AGET_OBJECT:
+      {
+        RegType dst_type, index_type;
+
+        index_type = GetRegisterType(work_line, dec_insn.vC_);
+        CheckArrayIndexType(method, index_type, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+
+        /* get the class of the array we're pulling an object from */
+        res_class = GetClassFromRegister(work_line, dec_insn.vB_, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+        if (res_class != NULL) {
+          Class* element_class;
+
+          assert(res_class != NULL);
+          if (!res_class->IsArrayClass()) {
+            LOG(ERROR) << "VFY: aget-object on non-array class";
+            failure = VERIFY_ERROR_GENERIC;
+            break;
+          }
+          assert(res_class->GetComponentType() != NULL);
+
+          /*
+           * Find the element class.  res_class->GetComponentType() indicates
+           * the basic type, which won't be what we want for a
+           * multi-dimensional array.
+           */
+          if (res_class->GetDescriptor()->CharAt(1) == '[') {
+            assert(res_class->GetArrayRank() > 1);
+            std::string descriptor =
+                res_class->GetDescriptor()->ToModifiedUtf8();
+            element_class = class_linker->FindClass(descriptor.c_str() + 1,
+                           res_class->GetClassLoader());
+          } else if (res_class->GetDescriptor()->CharAt(1) == 'L') {
+            assert(res_class->GetArrayRank() == 1);
+            element_class = res_class->GetComponentType();
+          } else {
+            LOG(ERROR) << "VFY: aget-object on non-ref array class ("
+                       << res_class->GetDescriptor()->ToModifiedUtf8() << ")";
+            failure = VERIFY_ERROR_GENERIC;
+            break;
+          }
+
+          dst_type = RegTypeFromClass(element_class);
+        } else {
+          /*
+           * The array reference is NULL, so the current code path will
+           * throw an exception.  For proper merging with later code
+           * paths, and correct handling of "if-eqz" tests on the
+           * result of the array get, we want to treat this as a null
+           * reference.
+           */
+          dst_type = kRegTypeZero;
+        }
+      SetRegisterType(work_line, dec_insn.vA_, dst_type);
+      }
+      break;
+    case Instruction::APUT:
+      tmp_type = kRegTypeInteger;
+      goto aput_1nr_common;
+    case Instruction::APUT_BOOLEAN:
+      tmp_type = kRegTypeBoolean;
+      goto aput_1nr_common;
+    case Instruction::APUT_BYTE:
+      tmp_type = kRegTypeByte;
+      goto aput_1nr_common;
+    case Instruction::APUT_CHAR:
+      tmp_type = kRegTypeChar;
+      goto aput_1nr_common;
+    case Instruction::APUT_SHORT:
+      tmp_type = kRegTypeShort;
+      goto aput_1nr_common;
+aput_1nr_common:
+      {
+        RegType src_type, dst_type, index_type;
+
+        index_type = GetRegisterType(work_line, dec_insn.vC_);
+        CheckArrayIndexType(method, index_type, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+
+        res_class = GetClassFromRegister(work_line, dec_insn.vB_, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+
+        /* res_class can be null if the reg type is Zero */
+        if (res_class == NULL)
+          break;
+
+        Class::PrimitiveType prim_type =
+            res_class->GetComponentType()->GetPrimitiveType();
+        if (!res_class->IsArrayClass() || res_class->GetArrayRank() != 1 ||
+            prim_type == Class::kPrimNot) {
+          LOG(ERROR) << "VFY: invalid aput-1nr on "
+                     << res_class->GetDescriptor()->ToModifiedUtf8();
+          failure = VERIFY_ERROR_GENERIC;
+          break;
+        }
+
+        /* verify that instruction matches array */
+        dst_type = PrimitiveTypeToRegType(prim_type);
+
+        /* correct if float */
+        if (dst_type == kRegTypeFloat)
+          tmp_type = kRegTypeFloat;
+
+        /* make sure the source register has the correct type */
+        src_type = GetRegisterType(work_line, dec_insn.vA_);
+        if (!CanConvertTo1nr(src_type, tmp_type)) {
+          LOG(ERROR) << "VFY: invalid reg type " << src_type
+                     << " on aput instr (need " << tmp_type << ")";
+          failure = VERIFY_ERROR_GENERIC;
+          break;
+        }
+
+        VerifyRegisterType(work_line, dec_insn.vA_, dst_type, &failure);
+
+        if (failure != VERIFY_ERROR_NONE || dst_type == kRegTypeUnknown ||
+          tmp_type != dst_type) {
+          LOG(ERROR) << "VFY: invalid aput-1nr on "
+                     << res_class->GetDescriptor()->ToModifiedUtf8()
+                     << " (inst=" << tmp_type << " dst=" << dst_type << ")";
+          failure = VERIFY_ERROR_GENERIC;
+          break;
+        }
+      }
+      break;
+    case Instruction::APUT_WIDE:
+      tmp_type = GetRegisterType(work_line, dec_insn.vC_);
+      CheckArrayIndexType(method, tmp_type, &failure);
+      if (failure != VERIFY_ERROR_NONE)
+        break;
+
+      res_class = GetClassFromRegister(work_line, dec_insn.vB_, &failure);
+      if (failure != VERIFY_ERROR_NONE)
+        break;
+      if (res_class != NULL) {
+        Class::PrimitiveType prim_type =
+            res_class->GetComponentType()->GetPrimitiveType();
+        /* verify the class and try to refine "dst_type" */
+        if (!res_class->IsArrayClass() || res_class->GetArrayRank() != 1 ||
+            prim_type == Class::kPrimNot)
+        {
+          LOG(ERROR) << "VFY: invalid aput-wide on "
+                     << res_class->GetDescriptor()->ToModifiedUtf8();
+          failure = VERIFY_ERROR_GENERIC;
+          break;
+        }
+
+        switch (prim_type) {
+          case Class::kPrimLong:
+            VerifyRegisterType(work_line, dec_insn.vA_, kRegTypeLongLo,
+                &failure);
+            break;
+          case Class::kPrimDouble:
+            VerifyRegisterType(work_line, dec_insn.vA_, kRegTypeDoubleLo,
+                &failure);
+            break;
+          default:
+            LOG(ERROR) << "VFY: invalid aput-wide on "
+                       << res_class->GetDescriptor()->ToModifiedUtf8();
+            failure = VERIFY_ERROR_GENERIC;
+            break;
+        }
+      }
+      break;
+    case Instruction::APUT_OBJECT:
+      tmp_type = GetRegisterType(work_line, dec_insn.vC_);
+      CheckArrayIndexType(method, tmp_type, &failure);
+      if (failure != VERIFY_ERROR_NONE)
+        break;
+
+      /* get the ref we're storing; Zero is okay, Uninit is not */
+      res_class = GetClassFromRegister(work_line, dec_insn.vA_, &failure);
+      if (failure != VERIFY_ERROR_NONE)
+        break;
+      if (res_class != NULL) {
+        Class* array_class;
+        Class* element_class;
+
+        /*
+         * Get the array class.  If the array ref is null, we won't
+         * have type information (and we'll crash at runtime with a
+         * null pointer exception).
+         */
+        array_class = GetClassFromRegister(work_line, dec_insn.vB_, &failure);
+
+        if (array_class != NULL) {
+          /* see if the array holds a compatible type */
+          if (!array_class->IsArrayClass()) {
+            LOG(ERROR) << "VFY: invalid aput-object on "
+                       << array_class->GetDescriptor()->ToModifiedUtf8();
+            failure = VERIFY_ERROR_GENERIC;
+            break;
+          }
+
+          /*
+           * Find the element class.  res_class->GetComponentType() indicates
+           * the basic type, which won't be what we want for a
+           * multi-dimensional array.
+           *
+           * All we want to check here is that the element type is a
+           * reference class.  We *don't* check instanceof here, because
+           * you can still put a String into a String[] after the latter
+           * has been cast to an Object[].
+           */
+          if (array_class->GetDescriptor()->CharAt(1) == '[') {
+            assert(array_class->GetArrayRank() > 1);
+            std::string descriptor =
+                array_class->GetDescriptor()->ToModifiedUtf8();
+            element_class = class_linker->FindClass(descriptor.c_str() + 1,
+                           array_class->GetClassLoader());
+          } else {
+            assert(array_class->GetArrayRank() == 1);
+            element_class = array_class->GetComponentType();
+          }
+          if (element_class->GetPrimitiveType() != Class::kPrimNot) {
+            LOG(ERROR) << "VFY: invalid aput-object of "
+                       << res_class->GetDescriptor()->ToModifiedUtf8()
+                       << " into "
+                       << array_class->GetDescriptor()->ToModifiedUtf8();
+            failure = VERIFY_ERROR_GENERIC;
+            break;
+          }
+        }
+      }
+      break;
+
+    case Instruction::IGET:
+      tmp_type = kRegTypeInteger;
+      goto iget_1nr_common;
+    case Instruction::IGET_BOOLEAN:
+      tmp_type = kRegTypeBoolean;
+      goto iget_1nr_common;
+    case Instruction::IGET_BYTE:
+      tmp_type = kRegTypeByte;
+      goto iget_1nr_common;
+    case Instruction::IGET_CHAR:
+      tmp_type = kRegTypeChar;
+      goto iget_1nr_common;
+    case Instruction::IGET_SHORT:
+      tmp_type = kRegTypeShort;
+      goto iget_1nr_common;
+iget_1nr_common:
+      {
+        Field* inst_field;
+        RegType obj_type, field_type;
+
+        obj_type = GetRegisterType(work_line, dec_insn.vB_);
+        inst_field = GetInstField(vdata, obj_type, dec_insn.vC_, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+
+        /* make sure the field's type is compatible with expectation */
+        field_type =
+            PrimitiveTypeToRegType(inst_field->GetType()->GetPrimitiveType());
+
+        /* correct if float */
+        if (field_type == kRegTypeFloat)
+          tmp_type = kRegTypeFloat;
+
+        if (field_type == kRegTypeUnknown || tmp_type != field_type) {
+          Class* inst_field_class = inst_field->GetDeclaringClass();
+          LOG(ERROR) << "VFY: invalid iget-1nr of "
+                     << inst_field_class->GetDescriptor()->ToModifiedUtf8()
+                     << "." << inst_field->GetName()->ToModifiedUtf8()
+                     << " (inst=" << tmp_type << " field=" << field_type << ")";
+          failure = VERIFY_ERROR_GENERIC;
+          break;
+        }
+
+        SetRegisterType(work_line, dec_insn.vA_, tmp_type);
+      }
+      break;
+    case Instruction::IGET_WIDE:
+      {
+        RegType dst_type;
+        Field* inst_field;
+        RegType obj_type;
+
+        obj_type = GetRegisterType(work_line, dec_insn.vB_);
+        inst_field = GetInstField(vdata, obj_type, dec_insn.vC_, &failure);
+        Class* inst_field_class = inst_field->GetDeclaringClass();
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+        /* check the type, which should be prim */
+        switch (inst_field->GetType()->GetPrimitiveType()) {
+          case Class::kPrimDouble:
+            dst_type = kRegTypeDoubleLo;
+            break;
+          case Class::kPrimLong:
+            dst_type = kRegTypeLongLo;
+            break;
+          default:
+            LOG(ERROR) << "VFY: invalid iget-wide of "
+                       << inst_field_class->GetDescriptor()->ToModifiedUtf8()
+                       << "." << inst_field->GetName()->ToModifiedUtf8();
+            dst_type = kRegTypeUnknown;
+            failure = VERIFY_ERROR_GENERIC;
+            break;
+        }
+        if (failure == VERIFY_ERROR_NONE) {
+          SetRegisterType(work_line, dec_insn.vA_, dst_type);
+        }
+      }
+      break;
+    case Instruction::IGET_OBJECT:
+      {
+        Class* field_class;
+        Field* inst_field;
+        RegType obj_type;
+
+        obj_type = GetRegisterType(work_line, dec_insn.vB_);
+        inst_field = GetInstField(vdata, obj_type, dec_insn.vC_, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+        field_class = inst_field->GetType();
+        if (field_class == NULL) {
+          /* class not found or primitive type */
+          LOG(ERROR) << "VFY: unable to recover field class from "
+                     << inst_field->GetName()->ToModifiedUtf8();
+          failure = VERIFY_ERROR_GENERIC;
+          break;
+        }
+        if (failure == VERIFY_ERROR_NONE) {
+          assert(!field_class->IsPrimitive());
+          SetRegisterType(work_line, dec_insn.vA_,
+              RegTypeFromClass(field_class));
+        }
+      }
+      break;
+    case Instruction::IPUT:
+      tmp_type = kRegTypeInteger;
+      goto iput_1nr_common;
+    case Instruction::IPUT_BOOLEAN:
+      tmp_type = kRegTypeBoolean;
+      goto iput_1nr_common;
+    case Instruction::IPUT_BYTE:
+      tmp_type = kRegTypeByte;
+      goto iput_1nr_common;
+    case Instruction::IPUT_CHAR:
+      tmp_type = kRegTypeChar;
+      goto iput_1nr_common;
+    case Instruction::IPUT_SHORT:
+      tmp_type = kRegTypeShort;
+      goto iput_1nr_common;
+iput_1nr_common:
+      {
+        RegType src_type, field_type, obj_type;
+        Field* inst_field;
+
+        obj_type = GetRegisterType(work_line, dec_insn.vB_);
+        inst_field = GetInstField(vdata, obj_type, dec_insn.vC_, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+        CheckFinalFieldAccess(method, inst_field, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+
+        /* get type of field we're storing into */
+        field_type =
+            PrimitiveTypeToRegType(inst_field->GetType()->GetPrimitiveType());
+        src_type = GetRegisterType(work_line, dec_insn.vA_);
+
+        /* correct if float */
+        if (field_type == kRegTypeFloat)
+          tmp_type = kRegTypeFloat;
+
+        /*
+         * compiler can generate synthetic functions that write byte values
+         * into boolean fields.
+         */
+        if (tmp_type == kRegTypeBoolean && src_type == kRegTypeByte)
+          tmp_type = kRegTypeByte;
+        if (field_type == kRegTypeBoolean && src_type == kRegTypeByte)
+          field_type = kRegTypeByte;
+
+        /* make sure the source register has the correct type */
+        if (!CanConvertTo1nr(src_type, tmp_type)) {
+          LOG(ERROR) << "VFY: invalid reg type " << src_type
+                     << " on iput instr (need " << tmp_type << ")",
+          failure = VERIFY_ERROR_GENERIC;
+          break;
+        }
+
+        VerifyRegisterType(work_line, dec_insn.vA_, field_type, &failure);
+
+        if (failure != VERIFY_ERROR_NONE || field_type == kRegTypeUnknown ||
+            tmp_type != field_type) {
+          Class* inst_field_class = inst_field->GetDeclaringClass();
+          LOG(ERROR) << "VFY: invalid iput-1nr of "
+                     << inst_field_class->GetDescriptor()->ToModifiedUtf8()
+                     << "." << inst_field->GetName()->ToModifiedUtf8()
+                     << " (inst=" << tmp_type << " field=" << field_type << ")";
+          failure = VERIFY_ERROR_GENERIC;
+          break;
+        }
+      }
+      break;
+    case Instruction::IPUT_WIDE:
+      Field* inst_field;
+      RegType obj_type;
+
+      obj_type = GetRegisterType(work_line, dec_insn.vB_);
+      inst_field = GetInstField(vdata, obj_type, dec_insn.vC_, &failure);
+      if (failure != VERIFY_ERROR_NONE)
+        break;
+      CheckFinalFieldAccess(method, inst_field, &failure);
+      if (failure != VERIFY_ERROR_NONE)
+        break;
+
+      /* check the type, which should be prim */
+      switch (inst_field->GetType()->GetPrimitiveType()) {
+        case Class::kPrimDouble:
+          VerifyRegisterType(work_line, dec_insn.vA_, kRegTypeDoubleLo,
+              &failure);
+          break;
+        case Class::kPrimLong:
+          VerifyRegisterType(work_line, dec_insn.vA_, kRegTypeLongLo, &failure);
+          break;
+        default:
+          LOG(ERROR) << "VFY: invalid iput-wide of "
+                     << inst_field->GetDeclaringClass()->GetDescriptor()->ToModifiedUtf8()
+                     << "." << inst_field->GetName()->ToModifiedUtf8();
+          failure = VERIFY_ERROR_GENERIC;
+          break;
+        }
+      break;
+    case Instruction::IPUT_OBJECT:
+      {
+        Class* field_class;
+        Class* value_class;
+        Field* inst_field;
+        RegType obj_type, value_type;
+
+        obj_type = GetRegisterType(work_line, dec_insn.vB_);
+        inst_field = GetInstField(vdata, obj_type, dec_insn.vC_, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+        CheckFinalFieldAccess(method, inst_field, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+
+        field_class = inst_field->GetType();
+        if (field_class == NULL) {
+          LOG(ERROR) << "VFY: unable to recover field class from '"
+                     << inst_field->GetName()->ToModifiedUtf8() << "'";
+          failure = VERIFY_ERROR_GENERIC;
+          break;
+        }
+
+        value_type = GetRegisterType(work_line, dec_insn.vA_);
+        if (!RegTypeIsReference(value_type)) {
+          LOG(ERROR) << "VFY: storing non-ref v" << dec_insn.vA_
+                     << " into ref field '"
+                     << inst_field->GetName()->ToModifiedUtf8() << "' ("
+                     << field_class->GetDescriptor()->ToModifiedUtf8() << ")";
+          failure = VERIFY_ERROR_GENERIC;
+          break;
+        }
+        if (value_type != kRegTypeZero) {
+          value_class = RegTypeInitializedReferenceToClass(value_type);
+          if (value_class == NULL) {
+            LOG(ERROR) << "VFY: storing uninit ref v" << dec_insn.vA_
+                       << " into ref field";
+            failure = VERIFY_ERROR_GENERIC;
+            break;
+          }
+          /* allow if field is any interface or field is base class */
+          if (!field_class->IsInterface() &&
+              !field_class->IsAssignableFrom(value_class)) {
+            Class* inst_field_class = inst_field->GetDeclaringClass();
+            LOG(ERROR) << "VFY: storing type '"
+                       << value_class->GetDescriptor()->ToModifiedUtf8()
+                       << "' into field type '"
+                       << field_class->GetDescriptor()->ToModifiedUtf8()
+                       << "' ("
+                       << inst_field_class->GetDescriptor()->ToModifiedUtf8()
+                       << "." << inst_field->GetName()->ToModifiedUtf8() << ")";
+            failure = VERIFY_ERROR_GENERIC;
+            break;
+          }
+        }
+      }
+      break;
+
+    case Instruction::SGET:
+      tmp_type = kRegTypeInteger;
+      goto sget_1nr_common;
+    case Instruction::SGET_BOOLEAN:
+      tmp_type = kRegTypeBoolean;
+      goto sget_1nr_common;
+    case Instruction::SGET_BYTE:
+      tmp_type = kRegTypeByte;
+      goto sget_1nr_common;
+    case Instruction::SGET_CHAR:
+      tmp_type = kRegTypeChar;
+      goto sget_1nr_common;
+    case Instruction::SGET_SHORT:
+      tmp_type = kRegTypeShort;
+      goto sget_1nr_common;
+sget_1nr_common:
+      {
+        Field* static_field;
+        RegType field_type;
+
+        static_field = GetStaticField(vdata, dec_insn.vB_, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+
+        /*
+         * Make sure the field's type is compatible with expectation.
+         * We can get ourselves into trouble if we mix & match loads
+         * and stores with different widths, so rather than just checking
+         * "CanConvertTo1nr" we require that the field types have equal
+         * widths.
+         */
+        field_type =
+            PrimitiveTypeToRegType(static_field->GetType()->GetPrimitiveType());
+
+        /* correct if float */
+        if (field_type == kRegTypeFloat)
+          tmp_type = kRegTypeFloat;
+
+        if (tmp_type != field_type) {
+          Class* static_field_class = static_field->GetDeclaringClass();
+          LOG(ERROR) << "VFY: invalid sget-1nr of "
+                     << static_field_class->GetDescriptor()->ToModifiedUtf8()
+                     << "." << static_field->GetName()->ToModifiedUtf8()
+                     << " (inst=" << tmp_type << " actual=" << field_type
+                     << ")";
+          failure = VERIFY_ERROR_GENERIC;
+          break;
+        }
+
+        SetRegisterType(work_line, dec_insn.vA_, tmp_type);
+      }
+      break;
+    case Instruction::SGET_WIDE:
+      {
+        Field* static_field;
+        RegType dst_type;
+
+        static_field = GetStaticField(vdata, dec_insn.vB_, &failure);
+        Class* static_field_class = static_field->GetDeclaringClass();
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+        /* check the type, which should be prim */
+        switch (static_field->GetType()->GetPrimitiveType()) {
+          case Class::kPrimDouble:
+            dst_type = kRegTypeDoubleLo;
+            break;
+          case Class::kPrimLong:
+            dst_type = kRegTypeLongLo;
+            break;
+          default:
+            LOG(ERROR) << "VFY: invalid sget-wide of "
+                       << static_field_class->GetDescriptor()->ToModifiedUtf8()
+                       << "." << static_field->GetName()->ToModifiedUtf8();
+            dst_type = kRegTypeUnknown;
+            failure = VERIFY_ERROR_GENERIC;
+            break;
+        }
+        if (failure == VERIFY_ERROR_NONE) {
+          SetRegisterType(work_line, dec_insn.vA_, dst_type);
+        }
+      }
+      break;
+    case Instruction::SGET_OBJECT:
+      {
+        Field* static_field;
+        Class* field_class;
+
+        static_field = GetStaticField(vdata, dec_insn.vB_, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+        field_class = static_field->GetType();
+        if (field_class == NULL) {
+          LOG(ERROR) << "VFY: unable to recover field class from '"
+                     << static_field->GetName()->ToModifiedUtf8() << "'";
+          failure = VERIFY_ERROR_GENERIC;
+          break;
+        }
+        if (field_class->IsPrimitive()) {
+          LOG(ERROR) << "VFY: attempt to get prim field with sget-object";
+          failure = VERIFY_ERROR_GENERIC;
+          break;
+        }
+      SetRegisterType(work_line, dec_insn.vA_, RegTypeFromClass(field_class));
+      }
+      break;
+    case Instruction::SPUT:
+      tmp_type = kRegTypeInteger;
+      goto sput_1nr_common;
+    case Instruction::SPUT_BOOLEAN:
+      tmp_type = kRegTypeBoolean;
+      goto sput_1nr_common;
+    case Instruction::SPUT_BYTE:
+      tmp_type = kRegTypeByte;
+      goto sput_1nr_common;
+    case Instruction::SPUT_CHAR:
+      tmp_type = kRegTypeChar;
+      goto sput_1nr_common;
+    case Instruction::SPUT_SHORT:
+      tmp_type = kRegTypeShort;
+      goto sput_1nr_common;
+sput_1nr_common:
+      {
+        RegType src_type, field_type;
+        Field* static_field;
+
+        static_field = GetStaticField(vdata, dec_insn.vB_, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+        CheckFinalFieldAccess(method, static_field, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+
+        /*
+         * Get type of field we're storing into.  We know that the
+         * contents of the register match the instruction, but we also
+         * need to ensure that the instruction matches the field type.
+         * Using e.g. sput-short to write into a 32-bit integer field
+         * can lead to trouble if we do 16-bit writes.
+         */
+        field_type =
+            PrimitiveTypeToRegType(static_field->GetType()->GetPrimitiveType());
+        src_type = GetRegisterType(work_line, dec_insn.vA_);
+
+        /* correct if float */
+        if (field_type == kRegTypeFloat)
+          tmp_type = kRegTypeFloat;
+
+        /*
+         * compiler can generate synthetic functions that write byte values
+         * into boolean fields.
+         */
+        if (tmp_type == kRegTypeBoolean && src_type == kRegTypeByte)
+          tmp_type = kRegTypeByte;
+        if (field_type == kRegTypeBoolean && src_type == kRegTypeByte)
+          field_type = kRegTypeByte;
+
+        /* make sure the source register has the correct type */
+        if (!CanConvertTo1nr(src_type, tmp_type)) {
+          LOG(ERROR) << "VFY: invalid reg type " << src_type
+                     << " on sput instr (need " << tmp_type << ")";
+          failure = VERIFY_ERROR_GENERIC;
+          break;
+        }
+
+        VerifyRegisterType(work_line, dec_insn.vA_, field_type, &failure);
+
+        if (failure != VERIFY_ERROR_NONE || field_type == kRegTypeUnknown ||
+            tmp_type != field_type) {
+          Class* static_field_class = static_field->GetDeclaringClass();
+          LOG(ERROR) << "VFY: invalid sput-1nr of "
+                     << static_field_class->GetDescriptor()->ToModifiedUtf8()
+                     << "." << static_field->GetName()->ToModifiedUtf8()
+                     << " (inst=" << tmp_type << " actual=" << field_type
+                     << ")";
+          failure = VERIFY_ERROR_GENERIC;
+          break;
+        }
+      }
+      break;
+    case Instruction::SPUT_WIDE:
+      Field* static_field;
+
+      static_field = GetStaticField(vdata, dec_insn.vB_, &failure);
+      if (failure != VERIFY_ERROR_NONE)
+        break;
+      CheckFinalFieldAccess(method, static_field, &failure);
+      if (failure != VERIFY_ERROR_NONE)
+        break;
+
+      /* check the type, which should be prim */
+      switch (static_field->GetType()->GetPrimitiveType()) {
+        case Class::kPrimDouble:
+          VerifyRegisterType(work_line, dec_insn.vA_, kRegTypeDoubleLo,
+              &failure);
+          break;
+        case Class::kPrimLong:
+          VerifyRegisterType(work_line, dec_insn.vA_, kRegTypeLongLo, &failure);
+          break;
+        default:
+          LOG(ERROR) << "VFY: invalid sput-wide of "
+                     << static_field->GetDeclaringClass()->GetDescriptor()->ToModifiedUtf8()
+                     << "." << static_field->GetName()->ToModifiedUtf8();
+          failure = VERIFY_ERROR_GENERIC;
+          break;
+      }
+      break;
+    case Instruction::SPUT_OBJECT:
+      {
+        Class* field_class;
+        Class* value_class;
+        Field* static_field;
+        RegType value_type;
+
+        static_field = GetStaticField(vdata, dec_insn.vB_, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+        CheckFinalFieldAccess(method, static_field, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+
+        field_class = static_field->GetType();
+        if (field_class == NULL) {
+          LOG(ERROR) << "VFY: unable to recover field class from '"
+                     << static_field->GetName()->ToModifiedUtf8() << "'";
+          failure = VERIFY_ERROR_GENERIC;
+          break;
+        }
+
+        value_type = GetRegisterType(work_line, dec_insn.vA_);
+        if (!RegTypeIsReference(value_type)) {
+          LOG(ERROR) << "VFY: storing non-ref v" << dec_insn.vA_
+                     << " into ref field '"
+                     << static_field->GetName()->ToModifiedUtf8() << "' ("
+                     << field_class->GetDescriptor()->ToModifiedUtf8() << ")",
+          failure = VERIFY_ERROR_GENERIC;
+          break;
+        }
+        if (value_type != kRegTypeZero) {
+          value_class = RegTypeInitializedReferenceToClass(value_type);
+          if (value_class == NULL) {
+            LOG(ERROR) << "VFY: storing uninit ref v" << dec_insn.vA_
+                       << " into ref field";
+            failure = VERIFY_ERROR_GENERIC;
+            break;
+          }
+          /* allow if field is any interface or field is base class */
+          if (!field_class->IsInterface() &&
+              !field_class->IsAssignableFrom(value_class)) {
+            Class* static_field_class = static_field->GetDeclaringClass();
+            LOG(ERROR) << "VFY: storing type '"
+                       << value_class->GetDescriptor()->ToModifiedUtf8()
+                       << "' into field type '"
+                       << field_class->GetDescriptor()->ToModifiedUtf8()
+                       << "' ("
+                       << static_field_class->GetDescriptor()->ToModifiedUtf8()
+                       << "." << static_field->GetName()->ToModifiedUtf8()
+                       << ")",
+            failure = VERIFY_ERROR_GENERIC;
+            break;
+          }
+        }
+      }
+      break;
+
+    case Instruction::INVOKE_VIRTUAL:
+    case Instruction::INVOKE_VIRTUAL_RANGE:
+    case Instruction::INVOKE_SUPER:
+    case Instruction::INVOKE_SUPER_RANGE:
+      {
+        Method* called_method;
+        RegType return_type;
+        bool is_range;
+        bool is_super;
+
+        is_range =  (dec_insn.opcode_ == Instruction::INVOKE_VIRTUAL_RANGE ||
+                     dec_insn.opcode_ == Instruction::INVOKE_SUPER_RANGE);
+        is_super =  (dec_insn.opcode_ == Instruction::INVOKE_SUPER ||
+                     dec_insn.opcode_ == Instruction::INVOKE_SUPER_RANGE);
+
+        called_method = VerifyInvocationArgs(vdata, work_line, registers_size,
+            &dec_insn, METHOD_VIRTUAL, is_range, is_super, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+            break;
+        return_type = GetMethodReturnType(dex_file, called_method);
+        SetResultRegisterType(work_line, registers_size, return_type);
+        just_set_result = true;
+      }
+      break;
+    case Instruction::INVOKE_DIRECT:
+    case Instruction::INVOKE_DIRECT_RANGE:
+      {
+        RegType return_type;
+        Method* called_method;
+        bool is_range;
+
+        is_range = (dec_insn.opcode_ == Instruction::INVOKE_DIRECT_RANGE);
+        called_method = VerifyInvocationArgs(vdata, work_line, registers_size,
+            &dec_insn, METHOD_DIRECT, is_range, false, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+
+        /*
+         * Some additional checks when calling <init>.  We know from
+         * the invocation arg check that the "this" argument is an
+         * instance of called_method->klass.  Now we further restrict
+         * that to require that called_method->klass is the same as
+         * this->klass or this->super, allowing the latter only if
+         * the "this" argument is the same as the "this" argument to
+         * this method (which implies that we're in <init> ourselves).
+         */
+        if (IsInitMethod(called_method)) {
+          RegType this_type;
+          this_type = GetInvocationThis(work_line, &dec_insn, &failure);
+          if (failure != VERIFY_ERROR_NONE)
+            break;
+
+          /* no null refs allowed (?) */
+          if (this_type == kRegTypeZero) {
+            LOG(ERROR) << "VFY: unable to initialize null ref";
+            failure = VERIFY_ERROR_GENERIC;
+            break;
+          }
+
+          Class* this_class;
+
+          this_class = RegTypeReferenceToClass(this_type, uninit_map);
+          assert(this_class != NULL);
+
+          /* must be in same class or in superclass */
+          if (called_method->GetDeclaringClass() == this_class->GetSuperClass())
+          {
+            if (this_class != method->GetDeclaringClass()) {
+              LOG(ERROR) << "VFY: invoke-direct <init> on super only "
+                         << "allowed for 'this' in <init>";
+              failure = VERIFY_ERROR_GENERIC;
+              break;
+            }
+          }  else if (called_method->GetDeclaringClass() != this_class) {
+            LOG(ERROR) << "VFY: invoke-direct <init> must be on current "
+                       << "class or super";
+            failure = VERIFY_ERROR_GENERIC;
+            break;
+          }
+
+          /* arg must be an uninitialized reference */
+          if (!RegTypeIsUninitReference(this_type)) {
+            LOG(ERROR) << "VFY: can only initialize the uninitialized";
+            failure = VERIFY_ERROR_GENERIC;
+            break;
+          }
+
+          /*
+           * Replace the uninitialized reference with an initialized
+           * one, and clear the entry in the uninit map.  We need to
+           * do this for all registers that have the same object
+           * instance in them, not just the "this" register.
+           */
+          MarkRefsAsInitialized(work_line, registers_size, uninit_map,
+              this_type, &failure);
+          if (failure != VERIFY_ERROR_NONE)
+            break;
+          }
+        return_type = GetMethodReturnType(dex_file, called_method);
+        SetResultRegisterType(work_line, registers_size, return_type);
+        just_set_result = true;
+      }
+      break;
+    case Instruction::INVOKE_STATIC:
+    case Instruction::INVOKE_STATIC_RANGE:
+      {
+        RegType return_type;
+        Method* called_method;
+        bool is_range;
+
+        is_range = (dec_insn.opcode_ == Instruction::INVOKE_STATIC_RANGE);
+        called_method = VerifyInvocationArgs(vdata, work_line, registers_size,
+            &dec_insn, METHOD_STATIC, is_range, false, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+
+        return_type = GetMethodReturnType(dex_file, called_method);
+        SetResultRegisterType(work_line, registers_size, return_type);
+        just_set_result = true;
+      }
+      break;
+    case Instruction::INVOKE_INTERFACE:
+    case Instruction::INVOKE_INTERFACE_RANGE:
+      {
+        RegType /*this_type,*/ return_type;
+        Method* abs_method;
+        bool is_range;
+
+        is_range =  (dec_insn.opcode_ == Instruction::INVOKE_INTERFACE_RANGE);
+        abs_method = VerifyInvocationArgs(vdata, work_line, registers_size,
+            &dec_insn, METHOD_INTERFACE, is_range, false, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+
+#if 0   /* can't do this here, fails on dalvik test 052-verifier-fun */
+        /*
+         * Get the type of the "this" arg, which should always be an
+         * interface class.  Because we don't do a full merge on
+         * interface classes, this might have reduced to Object.
+         */
+        this_type = GetInvocationThis(work_line, &dec_insn, &failure);
+        if (failure != VERIFY_ERROR_NONE)
+          break;
+
+        if (this_type == kRegTypeZero) {
+          /* null pointer always passes (and always fails at runtime) */
+        } else {
+          Class* this_class;
+
+          this_class = RegTypeInitializedReferenceToClass(this_type);
+          if (this_class == NULL) {
+            LOG(ERROR) << "VFY: interface call on uninitialized";
+            failure = VERIFY_ERROR_GENERIC;
+            break;
+          }
+
+          /*
+           * Either "this_class" needs to be the interface class that
+           * defined abs_method, or abs_method's class needs to be one
+           * of the interfaces implemented by "this_class".  (Or, if
+           * we couldn't complete the merge, this will be Object.)
+           */
+          if (this_class != abs_method->GetDeclaringClass() &&
+              this_class != class_linker->FindSystemClass("Ljava/lang/Object;") &&
+              !this_class->Implements(abs_method->GetDeclaringClass())) {
+            LOG(ERROR) << "VFY: unable to match abs_method '"
+                       << abs_method->GetName()->ToModifiedUtf8() << "' with "
+                       << this_class->GetDescriptor()->ToModifiedUtf8()
+                       << " interfaces";
+            failure = VERIFY_ERROR_GENERIC;
+            break;
+          }
+        }
+#endif
+
+        /*
+         * We don't have an object instance, so we can't find the
+         * concrete method.  However, all of the type information is
+         * in the abstract method, so we're good.
+         */
+        return_type = GetMethodReturnType(dex_file, abs_method);
+        SetResultRegisterType(work_line, registers_size, return_type);
+        just_set_result = true;
+      }
+      break;
+
+    case Instruction::NEG_INT:
+    case Instruction::NOT_INT:
+      CheckUnop(work_line, &dec_insn, kRegTypeInteger, kRegTypeInteger,
+          &failure);
+      break;
+    case Instruction::NEG_LONG:
+    case Instruction::NOT_LONG:
+      CheckUnop(work_line, &dec_insn, kRegTypeLongLo, kRegTypeLongLo, &failure);
+      break;
+    case Instruction::NEG_FLOAT:
+      CheckUnop(work_line, &dec_insn, kRegTypeFloat, kRegTypeFloat, &failure);
+      break;
+    case Instruction::NEG_DOUBLE:
+      CheckUnop(work_line, &dec_insn, kRegTypeDoubleLo, kRegTypeDoubleLo,
+          &failure);
+      break;
+    case Instruction::INT_TO_LONG:
+      CheckUnop(work_line, &dec_insn, kRegTypeLongLo, kRegTypeInteger,
+          &failure);
+      break;
+    case Instruction::INT_TO_FLOAT:
+      CheckUnop(work_line, &dec_insn, kRegTypeFloat, kRegTypeInteger, &failure);
+      break;
+    case Instruction::INT_TO_DOUBLE:
+      CheckUnop(work_line, &dec_insn, kRegTypeDoubleLo, kRegTypeInteger,
+          &failure);
+      break;
+    case Instruction::LONG_TO_INT:
+      CheckUnop(work_line, &dec_insn, kRegTypeInteger, kRegTypeLongLo,
+          &failure);
+      break;
+    case Instruction::LONG_TO_FLOAT:
+      CheckUnop(work_line, &dec_insn, kRegTypeFloat, kRegTypeLongLo, &failure);
+      break;
+    case Instruction::LONG_TO_DOUBLE:
+      CheckUnop(work_line, &dec_insn, kRegTypeDoubleLo, kRegTypeLongLo,
+          &failure);
+      break;
+    case Instruction::FLOAT_TO_INT:
+      CheckUnop(work_line, &dec_insn, kRegTypeInteger, kRegTypeFloat, &failure);
+      break;
+    case Instruction::FLOAT_TO_LONG:
+      CheckUnop(work_line, &dec_insn, kRegTypeLongLo, kRegTypeFloat, &failure);
+      break;
+    case Instruction::FLOAT_TO_DOUBLE:
+      CheckUnop(work_line, &dec_insn, kRegTypeDoubleLo, kRegTypeFloat,
+          &failure);
+      break;
+    case Instruction::DOUBLE_TO_INT:
+      CheckUnop(work_line, &dec_insn, kRegTypeInteger, kRegTypeDoubleLo,
+          &failure);
+      break;
+    case Instruction::DOUBLE_TO_LONG:
+      CheckUnop(work_line, &dec_insn, kRegTypeLongLo, kRegTypeDoubleLo,
+          &failure);
+      break;
+    case Instruction::DOUBLE_TO_FLOAT:
+      CheckUnop(work_line, &dec_insn, kRegTypeFloat, kRegTypeDoubleLo,
+          &failure);
+      break;
+    case Instruction::INT_TO_BYTE:
+      CheckUnop(work_line, &dec_insn, kRegTypeByte, kRegTypeInteger, &failure);
+      break;
+    case Instruction::INT_TO_CHAR:
+      CheckUnop(work_line, &dec_insn, kRegTypeChar, kRegTypeInteger, &failure);
+      break;
+    case Instruction::INT_TO_SHORT:
+      CheckUnop(work_line, &dec_insn, kRegTypeShort, kRegTypeInteger, &failure);
+      break;
+
+    case Instruction::ADD_INT:
+    case Instruction::SUB_INT:
+    case Instruction::MUL_INT:
+    case Instruction::REM_INT:
+    case Instruction::DIV_INT:
+    case Instruction::SHL_INT:
+    case Instruction::SHR_INT:
+    case Instruction::USHR_INT:
+      CheckBinop(work_line, &dec_insn, kRegTypeInteger, kRegTypeInteger,
+          kRegTypeInteger, false, &failure);
+      break;
+    case Instruction::AND_INT:
+    case Instruction::OR_INT:
+    case Instruction::XOR_INT:
+      CheckBinop(work_line, &dec_insn, kRegTypeInteger, kRegTypeInteger,
+          kRegTypeInteger, true, &failure);
+      break;
+    case Instruction::ADD_LONG:
+    case Instruction::SUB_LONG:
+    case Instruction::MUL_LONG:
+    case Instruction::DIV_LONG:
+    case Instruction::REM_LONG:
+    case Instruction::AND_LONG:
+    case Instruction::OR_LONG:
+    case Instruction::XOR_LONG:
+      CheckBinop(work_line, &dec_insn, kRegTypeLongLo, kRegTypeLongLo,
+          kRegTypeLongLo, false, &failure);
+      break;
+    case Instruction::SHL_LONG:
+    case Instruction::SHR_LONG:
+    case Instruction::USHR_LONG:
+      /* shift distance is Int, making these different from other binops */
+      CheckBinop(work_line, &dec_insn, kRegTypeLongLo, kRegTypeLongLo,
+          kRegTypeInteger, false, &failure);
+      break;
+    case Instruction::ADD_FLOAT:
+    case Instruction::SUB_FLOAT:
+    case Instruction::MUL_FLOAT:
+    case Instruction::DIV_FLOAT:
+    case Instruction::REM_FLOAT:
+      CheckBinop(work_line, &dec_insn, kRegTypeFloat, kRegTypeFloat,
+          kRegTypeFloat, false, &failure);
+      break;
+    case Instruction::ADD_DOUBLE:
+    case Instruction::SUB_DOUBLE:
+    case Instruction::MUL_DOUBLE:
+    case Instruction::DIV_DOUBLE:
+    case Instruction::REM_DOUBLE:
+      CheckBinop(work_line, &dec_insn, kRegTypeDoubleLo, kRegTypeDoubleLo,
+          kRegTypeDoubleLo, false, &failure);
+      break;
+    case Instruction::ADD_INT_2ADDR:
+    case Instruction::SUB_INT_2ADDR:
+    case Instruction::MUL_INT_2ADDR:
+    case Instruction::REM_INT_2ADDR:
+    case Instruction::SHL_INT_2ADDR:
+    case Instruction::SHR_INT_2ADDR:
+    case Instruction::USHR_INT_2ADDR:
+      CheckBinop2addr(work_line, &dec_insn, kRegTypeInteger, kRegTypeInteger,
+          kRegTypeInteger, false, &failure);
+      break;
+    case Instruction::AND_INT_2ADDR:
+    case Instruction::OR_INT_2ADDR:
+    case Instruction::XOR_INT_2ADDR:
+      CheckBinop2addr(work_line, &dec_insn, kRegTypeInteger, kRegTypeInteger,
+          kRegTypeInteger, true, &failure);
+      break;
+    case Instruction::DIV_INT_2ADDR:
+      CheckBinop2addr(work_line, &dec_insn, kRegTypeInteger, kRegTypeInteger,
+          kRegTypeInteger, false, &failure);
+      break;
+    case Instruction::ADD_LONG_2ADDR:
+    case Instruction::SUB_LONG_2ADDR:
+    case Instruction::MUL_LONG_2ADDR:
+    case Instruction::DIV_LONG_2ADDR:
+    case Instruction::REM_LONG_2ADDR:
+    case Instruction::AND_LONG_2ADDR:
+    case Instruction::OR_LONG_2ADDR:
+    case Instruction::XOR_LONG_2ADDR:
+      CheckBinop2addr(work_line, &dec_insn, kRegTypeLongLo, kRegTypeLongLo,
+          kRegTypeLongLo, false, &failure);
+      break;
+    case Instruction::SHL_LONG_2ADDR:
+    case Instruction::SHR_LONG_2ADDR:
+    case Instruction::USHR_LONG_2ADDR:
+      CheckBinop2addr(work_line, &dec_insn, kRegTypeLongLo, kRegTypeLongLo,
+          kRegTypeInteger, false, &failure);
+      break;
+    case Instruction::ADD_FLOAT_2ADDR:
+    case Instruction::SUB_FLOAT_2ADDR:
+    case Instruction::MUL_FLOAT_2ADDR:
+    case Instruction::DIV_FLOAT_2ADDR:
+    case Instruction::REM_FLOAT_2ADDR:
+      CheckBinop2addr(work_line, &dec_insn, kRegTypeFloat, kRegTypeFloat,
+          kRegTypeFloat, false, &failure);
+      break;
+    case Instruction::ADD_DOUBLE_2ADDR:
+    case Instruction::SUB_DOUBLE_2ADDR:
+    case Instruction::MUL_DOUBLE_2ADDR:
+    case Instruction::DIV_DOUBLE_2ADDR:
+    case Instruction::REM_DOUBLE_2ADDR:
+      CheckBinop2addr(work_line, &dec_insn, kRegTypeDoubleLo, kRegTypeDoubleLo,
+          kRegTypeDoubleLo, false, &failure);
+      break;
+    case Instruction::ADD_INT_LIT16:
+    case Instruction::RSUB_INT:
+    case Instruction::MUL_INT_LIT16:
+    case Instruction::DIV_INT_LIT16:
+    case Instruction::REM_INT_LIT16:
+      CheckLitop(work_line, &dec_insn, kRegTypeInteger, kRegTypeInteger, false,
+          &failure);
+      break;
+    case Instruction::AND_INT_LIT16:
+    case Instruction::OR_INT_LIT16:
+    case Instruction::XOR_INT_LIT16:
+      CheckLitop(work_line, &dec_insn, kRegTypeInteger, kRegTypeInteger, true,
+          &failure);
+      break;
+    case Instruction::ADD_INT_LIT8:
+    case Instruction::RSUB_INT_LIT8:
+    case Instruction::MUL_INT_LIT8:
+    case Instruction::DIV_INT_LIT8:
+    case Instruction::REM_INT_LIT8:
+    case Instruction::SHL_INT_LIT8:
+      CheckLitop(work_line, &dec_insn, kRegTypeInteger, kRegTypeInteger, false,
+          &failure);
+      break;
+    case Instruction::SHR_INT_LIT8:
+      tmp_type = AdjustForRightShift(work_line, dec_insn.vB_, dec_insn.vC_,
+          false, &failure);
+      CheckLitop(work_line, &dec_insn, tmp_type, kRegTypeInteger, false,
+          &failure);
+      break;
+    case Instruction::USHR_INT_LIT8:
+      tmp_type = AdjustForRightShift(work_line, dec_insn.vB_, dec_insn.vC_,
+          true, &failure);
+      CheckLitop(work_line, &dec_insn, tmp_type, kRegTypeInteger, false,
+          &failure);
+      break;
+    case Instruction::AND_INT_LIT8:
+    case Instruction::OR_INT_LIT8:
+    case Instruction::XOR_INT_LIT8:
+      CheckLitop(work_line, &dec_insn, kRegTypeInteger, kRegTypeInteger, true,
+          &failure);
+      break;
+
+    /*
+     * This falls into the general category of "optimized" instructions,
+     * which don't generally appear during verification.  Because it's
+     * inserted in the course of verification, we can expect to see it here.
+     */
+    //case Instruction::THROW_VERIFICATION_ERROR:
+    case Instruction::UNUSED_ED:
+      break;
+
+    /*
+     * Verifying "quickened" instructions is tricky, because we have
+     * discarded the original field/method information.  The byte offsets
+     * and vtable indices only have meaning in the context of an object
+     * instance.
+     *
+     * If a piece of code declares a local reference variable, assigns
+     * null to it, and then issues a virtual method call on it, we
+     * cannot evaluate the method call during verification.  This situation
+     * isn't hard to handle, since we know the call will always result in an
+     * NPE, and the arguments and return value don't matter.  Any code that
+     * depends on the result of the method call is inaccessible, so the
+     * fact that we can't fully verify anything that comes after the bad
+     * call is not a problem.
+     *
+     * We must also consider the case of multiple code paths, only some of
+     * which involve a null reference.  We can completely verify the method
+     * if we sidestep the results of executing with a null reference.
+     * For example, if on the first pass through the code we try to do a
+     * virtual method invocation through a null ref, we have to skip the
+     * method checks and have the method return a "wildcard" type (which
+     * merges with anything to become that other thing).  The move-result
+     * will tell us if it's a reference, single-word numeric, or double-word
+     * value.  We continue to perform the verification, and at the end of
+     * the function any invocations that were never fully exercised are
+     * marked as null-only.
+     *
+     * We would do something similar for the field accesses.  The field's
+     * type, once known, can be used to recover the width of short integers.
+     * If the object reference was null, the field-get returns the "wildcard"
+     * type, which is acceptable for any operation.
+     */
+    case Instruction::UNUSED_EE:
+    case Instruction::UNUSED_EF:
+    case Instruction::UNUSED_F2:
+    case Instruction::UNUSED_F3:
+    case Instruction::UNUSED_F4:
+    case Instruction::UNUSED_F5:
+    case Instruction::UNUSED_F6:
+    case Instruction::UNUSED_F7:
+    case Instruction::UNUSED_F8:
+    case Instruction::UNUSED_F9:
+    case Instruction::UNUSED_FA:
+    case Instruction::UNUSED_FB:
+    //case Instruction::EXECUTE_INLINE:
+    //case Instruction::EXECUTE_INLINE_RANGE:
+    //case Instruction::IGET_QUICK:
+    //case Instruction::IGET_WIDE_QUICK:
+    //case Instruction::IGET_OBJECT_QUICK:
+    //case Instruction::IPUT_QUICK:
+    //case Instruction::IPUT_WIDE_QUICK:
+    //case Instruction::IPUT_OBJECT_QUICK:
+    //case Instruction::INVOKE_VIRTUAL_QUICK:
+    //case Instruction::INVOKE_VIRTUAL_QUICK_RANGE:
+    //case Instruction::INVOKE_SUPER_QUICK:
+    //case Instruction::INVOKE_SUPER_QUICK_RANGE:
+      /* fall through to failure */
+
+    /*
+     * These instructions are equivalent (from the verifier's point of view)
+     * to the original form.  The change was made for correctness rather
+     * than improved performance (except for invoke-object-init, which
+     * provides both).  The substitution takes place after verification
+     * completes, though, so we don't expect to see them here.
+     */
+    case Instruction::UNUSED_F0:
+    case Instruction::UNUSED_F1:
+    case Instruction::UNUSED_E3:
+    case Instruction::UNUSED_E8:
+    case Instruction::UNUSED_E7:
+    case Instruction::UNUSED_E4:
+    case Instruction::UNUSED_E9:
+    case Instruction::UNUSED_FC:
+    case Instruction::UNUSED_E5:
+    case Instruction::UNUSED_EA:
+    case Instruction::UNUSED_FD:
+    case Instruction::UNUSED_E6:
+    case Instruction::UNUSED_EB:
+    case Instruction::UNUSED_FE:
+    //case Instruction::INVOKE_OBJECT_INIT_RANGE:
+    //case Instruction::RETURN_VOID_BARRIER:
+    //case Instruction::IGET_VOLATILE:
+    //case Instruction::IGET_WIDE_VOLATILE:
+    //case Instruction::IGET_OBJECT_VOLATILE:
+    //case Instruction::IPUT_VOLATILE:
+    //case Instruction::IPUT_WIDE_VOLATILE:
+    //case Instruction::IPUT_OBJECT_VOLATILE:
+    //case Instruction::SGET_VOLATILE:
+    //case Instruction::SGET_WIDE_VOLATILE:
+    //case Instruction::SGET_OBJECT_VOLATILE:
+    //case Instruction::SPUT_VOLATILE:
+    //case Instruction::SPUT_WIDE_VOLATILE:
+    //case Instruction::SPUT_OBJECT_VOLATILE:
+      /* fall through to failure */
+
+    /* These should never appear during verification. */
+    case Instruction::UNUSED_3E:
+    case Instruction::UNUSED_3F:
+    case Instruction::UNUSED_40:
+    case Instruction::UNUSED_41:
+    case Instruction::UNUSED_42:
+    case Instruction::UNUSED_43:
+    case Instruction::UNUSED_73:
+    case Instruction::UNUSED_79:
+    case Instruction::UNUSED_7A:
+    case Instruction::UNUSED_EC:
+    case Instruction::UNUSED_FF:
+    //case Instruction::BREAKPOINT:
+    //case Instruction::DISPATCH_FF:
+      failure = VERIFY_ERROR_GENERIC;
+      break;
+
+    /*
+     * DO NOT add a "default" clause here.  Without it the compiler will
+     * complain if an instruction is missing (which is desirable).
+     */
+    }
+
+  if (failure != VERIFY_ERROR_NONE) {
+    //if (failure == VERIFY_ERROR_GENERIC || gDvm.optimizing)
+    if (failure == VERIFY_ERROR_GENERIC) {
+      /* immediate failure, reject class */
+      LOG(ERROR) << "VFY:  rejecting opcode 0x" << std::hex
+                 << (int) dec_insn.opcode_ << " at 0x" << insn_idx << std::dec;
+      return false;
+    } else {
+      /* replace opcode and continue on */
+      LOG(ERROR) << "VFY: replacing opcode 0x" << std::hex
+                 << (int) dec_insn.opcode_ << " at 0x" << insn_idx << std::dec;
+      if (!ReplaceFailingInstruction(code_item, insn_flags, insn_idx, failure))
+      {
+        LOG(ERROR) << "VFY:  rejecting opcode 0x" << std::hex
+                   << (int) dec_insn.opcode_ << " at 0x" << insn_idx
+                   << std::dec;
+        return false;
+      }
+      /* IMPORTANT: method->insns may have been changed */
+      insns = code_item->insns_ + insn_idx;
+
+      /* continue on as if we just handled a throw-verification-error */
+      failure = VERIFY_ERROR_NONE;
+      opcode_flag = Instruction::kThrow;
+    }
+  }
+
+  /*
+   * If we didn't just set the result register, clear it out.  This
+   * ensures that you can only use "move-result" immediately after the
+   * result is set.  (We could check this statically, but it's not
+   * expensive and it makes our debugging output cleaner.)
+   */
+  if (!just_set_result) {
+    int reg = RESULT_REGISTER(registers_size);
+    SetRegisterType(work_line, reg, kRegTypeUnknown);
+    SetRegisterType(work_line, reg + 1, kRegTypeUnknown);
+  }
+
+  /*
+   * Handle "continue".  Tag the next consecutive instruction.
+   */
+  if ((opcode_flag & Instruction::kContinue) != 0) {
+    size_t insn_width = InsnGetWidth(insn_flags, insn_idx);
+    if (insn_idx + insn_width >= insns_size) {
+      LOG(ERROR) << "VFY: execution can walk off end of code area (from 0x"
+                 << std::hex << insn_idx << std::dec << ")";
+      return false;
+    }
+
+    /*
+     * The only way to get to a move-exception instruction is to get
+     * thrown there.  Make sure the next instruction isn't one.
+     */
+    if (!CheckMoveException(code_item->insns_, insn_idx + insn_width))
+      return false;
+
+    if (GetRegisterLine(reg_table, insn_idx + insn_width)->reg_types_ != NULL) {
+      /*
+       * Merge registers into what we have for the next instruction,
+       * and set the "changed" flag if needed.
+       */
+      if (!UpdateRegisters(insn_flags, reg_table, insn_idx + insn_width,
+          work_line))
+        return false;
+    } else {
+      /*
+       * We're not recording register data for the next instruction,
+       * so we don't know what the prior state was.  We have to
+       * assume that something has changed and re-evaluate it.
+       */
+      InsnSetChanged(insn_flags, insn_idx + insn_width, true);
+    }
+  }
+
+  /*
+   * Handle "branch".  Tag the branch target.
+   *
+   * NOTE: instructions like Instruction::EQZ provide information about the
+   * state of the register when the branch is taken or not taken.  For example,
+   * somebody could get a reference field, check it for zero, and if the
+   * branch is taken immediately store that register in a boolean field
+   * since the value is known to be zero.  We do not currently account for
+   * that, and will reject the code.
+   *
+   * TODO: avoid re-fetching the branch target
+   */
+  if ((opcode_flag & Instruction::kBranch) != 0) {
+    bool isConditional, selfOkay;
+
+    if (!GetBranchOffset(code_item, insn_flags, insn_idx, &branch_target,
+        &isConditional, &selfOkay)) {
+      /* should never happen after static verification */
+      LOG(ERROR) << "VFY: bad branch at 0x" << std::hex << insn_idx << std::dec;
+      return false;
+    }
+    assert(isConditional || (opcode_flag & Instruction::kContinue) == 0);
+    assert(!isConditional || (opcode_flag & Instruction::kContinue) != 0);
+
+    if (!CheckMoveException(code_item->insns_, insn_idx + branch_target))
+      return false;
+
+    /* update branch target, set "changed" if appropriate */
+    if (!UpdateRegisters(insn_flags, reg_table, insn_idx + branch_target,
+        work_line))
+      return false;
+  }
+
+  /*
+   * Handle "switch".  Tag all possible branch targets.
+   *
+   * We've already verified that the table is structurally sound, so we
+   * just need to walk through and tag the targets.
+   */
+  if ((opcode_flag & Instruction::kSwitch) != 0) {
+    int offset_to_switch = insns[1] | (((int32_t) insns[2]) << 16);
+    const uint16_t* switch_insns = insns + offset_to_switch;
+    int switch_count = switch_insns[1];
+    int offset_to_targets, targ;
+
+    if ((*insns & 0xff) == Instruction::PACKED_SWITCH) {
+      /* 0 = sig, 1 = count, 2/3 = first key */
+      offset_to_targets = 4;
+    } else {
+      /* 0 = sig, 1 = count, 2..count * 2 = keys */
+      assert((*insns & 0xff) == Instruction::SPARSE_SWITCH);
+      offset_to_targets = 2 + 2 * switch_count;
+    }
+
+    /* verify each switch target */
+    for (targ = 0; targ < switch_count; targ++) {
+      int offset;
+      uint32_t abs_offset;
+
+      /* offsets are 32-bit, and only partly endian-swapped */
+      offset = switch_insns[offset_to_targets + targ * 2] |
+         (((int32_t) switch_insns[offset_to_targets + targ * 2 + 1]) << 16);
+      abs_offset = insn_idx + offset;
+
+      assert(abs_offset < insns_size);
+
+      if (!CheckMoveException(code_item->insns_, abs_offset))
+        return false;
+
+      if (!UpdateRegisters(insn_flags, reg_table, abs_offset, work_line))
+        return false;
+    }
+  }
+
+  /*
+   * Handle instructions that can throw and that are sitting in a
+   * "try" block.  (If they're not in a "try" block when they throw,
+   * control transfers out of the method.)
+   */
+  if ((opcode_flag & Instruction::kThrow) != 0 &&
+      InsnIsInTry(insn_flags, insn_idx)) {
+    bool has_catch_all = false;
+    DexFile::CatchHandlerIterator iterator = DexFile::dexFindCatchHandler(
+        *code_item, insn_idx);
+
+    for (; !iterator.HasNext(); iterator.Next()) {
+      if (iterator.Get().type_idx_ == DexFile::kDexNoIndex)
+        has_catch_all = true;
+
+      /*
+       * Merge registers into the "catch" block.  We want to
+       * use the "savedRegs" rather than "work_regs", because
+       * at runtime the exception will be thrown before the
+       * instruction modifies any registers.
+       */
+      if (!UpdateRegisters(insn_flags, reg_table, iterator.Get().address_,
+          &reg_table->saved_line_))
+        return false;
+    }
+
+    /*
+     * If the monitor stack depth is nonzero, there must be a "catch all"
+     * handler for this instruction.  This does apply to monitor-exit
+     * because of async exception handling.
+     */
+    if (work_line->monitor_stack_top_ != 0 && !has_catch_all) {
+      /*
+       * The state in work_line reflects the post-execution state.
+       * If the current instruction is a monitor-enter and the monitor
+       * stack was empty, we don't need a catch-all (if it throws,
+       * it will do so before grabbing the lock).
+       */
+      if (!(dec_insn.opcode_ == Instruction::MONITOR_ENTER &&
+          work_line->monitor_stack_top_ == 1))
+      {
+        LOG(ERROR) << "VFY: no catch-all for instruction at 0x" << std::hex
+                   << insn_idx << std::dec;
+        return false;
+      }
+    }
+  }
+
+  /*
+   * If we're returning from the method, make sure our monitor stack is empty.
+   */
+  if ((opcode_flag & Instruction::kReturn) != 0 &&
+      work_line->monitor_stack_top_ != 0) {
+    LOG(ERROR) << "VFY: return with stack depth="
+               << work_line->monitor_stack_top_ << " at 0x" << std::hex
+               << insn_idx << std::dec;
+    return false;
+  }
+
+  /*
+   * Update start_guess.  Advance to the next instruction of that's
+   * possible, otherwise use the branch target if one was found.  If
+   * neither of those exists we're in a return or throw; leave start_guess
+   * alone and let the caller sort it out.
+   */
+  if ((opcode_flag & Instruction::kContinue) != 0) {
+    *start_guess = insn_idx + InsnGetWidth(insn_flags, insn_idx);
+  } else if ((opcode_flag & Instruction::kBranch) != 0) {
+    /* we're still okay if branch_target is zero */
+    *start_guess = insn_idx + branch_target;
+  }
+
+  assert(*start_guess < insns_size &&
+      InsnGetWidth(insn_flags, *start_guess) != 0);
+
+  return true;
+}
+
+bool DexVerifier::ReplaceFailingInstruction(const DexFile::CodeItem* code_item,
+    InsnFlags* insn_flags, int insn_idx, VerifyError failure) {
+  const uint16_t* insns = code_item->insns_ + insn_idx;
+  const byte* ptr = reinterpret_cast<const byte*>(insns);
+  const Instruction* inst = Instruction::At(ptr);
+  Instruction::Code opcode = inst->Opcode();
+  VerifyErrorRefType ref_type;
+
+  /*
+   * Generate the new instruction out of the old.
+   *
+   * First, make sure this is an instruction we're expecting to stomp on.
+   */
+  switch (opcode) {
+    case Instruction::CONST_CLASS:            // insn[1] == class ref, 2 bytes
+    case Instruction::CHECK_CAST:
+    case Instruction::INSTANCE_OF:
+    case Instruction::NEW_INSTANCE:
+    case Instruction::NEW_ARRAY:
+    case Instruction::FILLED_NEW_ARRAY:       // insn[1] == class ref, 3 bytes
+    case Instruction::FILLED_NEW_ARRAY_RANGE:
+      ref_type = VERIFY_ERROR_REF_CLASS;
+      break;
+
+    case Instruction::IGET:                   // insn[1] == field ref, 2 bytes
+    case Instruction::IGET_BOOLEAN:
+    case Instruction::IGET_BYTE:
+    case Instruction::IGET_CHAR:
+    case Instruction::IGET_SHORT:
+    case Instruction::IGET_WIDE:
+    case Instruction::IGET_OBJECT:
+    case Instruction::IPUT:
+    case Instruction::IPUT_BOOLEAN:
+    case Instruction::IPUT_BYTE:
+    case Instruction::IPUT_CHAR:
+    case Instruction::IPUT_SHORT:
+    case Instruction::IPUT_WIDE:
+    case Instruction::IPUT_OBJECT:
+    case Instruction::SGET:
+    case Instruction::SGET_BOOLEAN:
+    case Instruction::SGET_BYTE:
+    case Instruction::SGET_CHAR:
+    case Instruction::SGET_SHORT:
+    case Instruction::SGET_WIDE:
+    case Instruction::SGET_OBJECT:
+    case Instruction::SPUT:
+    case Instruction::SPUT_BOOLEAN:
+    case Instruction::SPUT_BYTE:
+    case Instruction::SPUT_CHAR:
+    case Instruction::SPUT_SHORT:
+    case Instruction::SPUT_WIDE:
+    case Instruction::SPUT_OBJECT:
+      ref_type = VERIFY_ERROR_REF_FIELD;
+      break;
+
+    case Instruction::INVOKE_VIRTUAL:         // insn[1] == method ref, 3 bytes
+    case Instruction::INVOKE_VIRTUAL_RANGE:
+    case Instruction::INVOKE_SUPER:
+    case Instruction::INVOKE_SUPER_RANGE:
+    case Instruction::INVOKE_DIRECT:
+    case Instruction::INVOKE_DIRECT_RANGE:
+    case Instruction::INVOKE_STATIC:
+    case Instruction::INVOKE_STATIC_RANGE:
+    case Instruction::INVOKE_INTERFACE:
+    case Instruction::INVOKE_INTERFACE_RANGE:
+      ref_type = VERIFY_ERROR_REF_METHOD;
+      break;
+
+    default:
+      /* could handle this in a generic way, but this is probably safer */
+      LOG(ERROR) << "GLITCH: verifier asked to replace opcode 0x" << std::hex
+                 << (int) opcode << std::dec;
+      return false;
+  }
+
+  assert(inst->IsThrow());
+
+  /* write a NOP over the third code unit, if necessary */
+  int width = InsnGetWidth(insn_flags, insn_idx);
+  switch (width) {
+    case 2:
+      /* nothing to do */
+      break;
+    case 3:
+      // TODO: Add this functionality
+      //UpdateCodeUnit(method, insns + 2, Instruction::NOP);
+      break;
+    default:
+      /* whoops */
+      LOG(FATAL) << "ERROR: stomped a " << width
+                 << "-unit instruction with a verifier error";
+  }
+
+  /* encode the opcode, with the failure code in the high byte */
+  // TODO: REPLACE FAILING OPCODES
+  //assert(width == 2 || width == 3);
+  //uint16_t new_val = Instruction::THROW_VERIFICATION_ERROR |
+      //(failure << 8) | (ref_type << (8 + kVerifyErrorRefTypeShift));
+  //UpdateCodeUnit(method, insns, new_val);
+
+  return true;
+}
+
+/* Handle a monitor-enter instruction. */
+void DexVerifier::HandleMonitorEnter(RegisterLine* work_line, uint32_t reg_idx,
+    uint32_t insn_idx, VerifyError* failure) {
+  if (!RegTypeIsReference(GetRegisterType(work_line, reg_idx))) {
+    LOG(ERROR) << "VFY: monitor-enter on non-object";
+    *failure = VERIFY_ERROR_GENERIC;
+    return;
+  }
+
+  if (work_line->monitor_entries_ == NULL) {
+    return;
+  }
+
+  if (work_line->monitor_stack_top_ == kMaxMonitorStackDepth) {
+    LOG(ERROR) << "VFY: monitor-enter stack overflow (" << kMaxMonitorStackDepth
+               << ")";
+    *failure = VERIFY_ERROR_GENERIC;
+    return;
+  }
+
+  /*
+   * Push an entry on the stack, and set a bit in the register flags to
+   * indicate that it's associated with this register.
+   */
+  work_line->monitor_entries_[reg_idx] |= 1 << work_line->monitor_stack_top_;
+  work_line->monitor_stack_[work_line->monitor_stack_top_++] = insn_idx;
+}
+
+/* Handle a monitor-exit instruction. */
+void DexVerifier::HandleMonitorExit(RegisterLine* work_line, uint32_t reg_idx,
+    uint32_t insn_idx, VerifyError* failure) {
+  if (!RegTypeIsReference(GetRegisterType(work_line, reg_idx))) {
+    LOG(ERROR) << "VFY: monitor-exit on non-object";
+    *failure = VERIFY_ERROR_GENERIC;
+    return;
+  }
+
+  if (work_line->monitor_entries_ == NULL) {
+    return;
+  }
+
+  if (work_line->monitor_stack_top_ == 0) {
+    LOG(ERROR) << "VFY: monitor-exit stack underflow";
+    *failure = VERIFY_ERROR_GENERIC;
+    return;
+  }
+
+  /*
+   * Confirm that the entry at the top of the stack is associated with
+   * the register.  Pop the top entry off.
+   */
+  work_line->monitor_stack_top_--;
+#ifdef BUG_3215458_FIXED
+  /*
+   * TODO: This code can safely be enabled if know we are working on
+   * a dex file of format version 036 or later. (That is, we'll need to
+   * add a check for the version number.)
+   */
+  if ((work_line->monitor_entries_[reg_idx] &
+      (1 << work_line->monitor_stack_top_)) == 0) {
+    LOG(ERROR) << "VFY: monitor-exit bit " << work_line->monitor_stack_top_
+               << " not set: addr=0x" << std::hex << insn_idx << std::dec
+               << " (bits[" << reg_idx << "]=" << std::hex
+               << work_line->monitor_entries_[reg_idx] << std::dec << ")";
+    *failure = VERIFY_ERROR_GENERIC;
+    return;
+  }
+#endif
+  work_line->monitor_stack_[work_line->monitor_stack_top_] = 0;
+
+  /* Clear the bit from the register flags. */
+  work_line->monitor_entries_[reg_idx] &= ~(1 << work_line->monitor_stack_top_);
+}
+
+Field* DexVerifier::GetInstField(VerifierData* vdata, RegType obj_type,
+    int field_idx, VerifyError* failure) {
+  Method* method = vdata->method_;
+  const DexFile* dex_file = vdata->dex_file_;
+  UninitInstanceMap* uninit_map = vdata->uninit_map_;
+  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+  DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
+  const ClassLoader* class_loader =
+      method->GetDeclaringClass()->GetClassLoader();
+  Field* field = NULL;
+  Class* obj_class;
+  bool must_be_local = false;
+
+  if (!RegTypeIsReference(obj_type)) {
+    LOG(ERROR) << "VFY: attempt to access field in non-reference type "
+               << obj_type;
+    *failure = VERIFY_ERROR_GENERIC;
+    return field;
+  }
+
+  field = class_linker->ResolveField(*dex_file, field_idx, dex_cache,
+      class_loader, false);
+  if (field == NULL) {
+    LOG(ERROR) << "VFY: unable to resolve instance field " << field_idx;
+    return field;
+  }
+
+  if (obj_type == kRegTypeZero)
+    return field;
+
+  /*
+   * Access to fields in uninitialized objects is allowed if this is
+   * the <init> method for the object and the field in question is
+   * declared by this class.
+   */
+  obj_class = RegTypeReferenceToClass(obj_type, uninit_map);
+  assert(obj_class != NULL);
+  if (RegTypeIsUninitReference(obj_type)) {
+    if (!IsInitMethod(method) || method->GetDeclaringClass() != obj_class) {
+      LOG(ERROR) << "VFY: attempt to access field via uninitialized ref";
+      *failure = VERIFY_ERROR_GENERIC;
+      return field;
+    }
+    must_be_local = true;
+  }
+
+  //if (!obj_class->InstanceOf(field->GetDeclaringClass())) {
+  if (!field->GetDeclaringClass()->IsAssignableFrom(obj_class)) {
+    LOG(ERROR) << "VFY: invalid field access (field "
+               << field->GetDeclaringClass()->GetDescriptor()->ToModifiedUtf8()
+               << "." << field->GetName()->ToModifiedUtf8() << ", through "
+               << obj_class->GetDescriptor()->ToModifiedUtf8() << " ref)";
+    *failure = VERIFY_ERROR_NO_FIELD;
+    return field;
+  }
+
+  if (must_be_local) {
+    bool found = false;
+    /* for uninit ref, make sure it's defined by this class, not super */
+    for (uint32_t i = 0; i < obj_class->NumInstanceFields(); i++) {
+      found |= (field == obj_class->GetInstanceField(i));
+    }
+    if (!found) {
+      LOG(ERROR) << "VFY: invalid constructor field access (field "
+                 << field->GetName()->ToModifiedUtf8() << " in "
+                 << obj_class->GetDescriptor()->ToModifiedUtf8() << ")";
+      *failure = VERIFY_ERROR_GENERIC;
+      return field;
+    }
+  }
+
+  return field;
+}
+
+Field* DexVerifier::GetStaticField(VerifierData* vdata, int field_idx,
+    VerifyError* failure) {
+  Method* method = vdata->method_;
+  const DexFile* dex_file = vdata->dex_file_;
+  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+  DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
+  const ClassLoader* class_loader =
+      method->GetDeclaringClass()->GetClassLoader();
+  Field* field;
+
+  field = class_linker->ResolveField(*dex_file, field_idx, dex_cache,
+      class_loader, true);
+  if (field == NULL) {
+    //const DexFile::FieldId field_id = dex_file->GetFieldId(field_idx);
+
+    //LOG(ERROR) << "VFY: unable to resolve static field " << field_idx << " ("
+               //<< dex_file->GetFieldName(field_id) << ") in "
+               //<< dex_file->GetFieldClassDescriptor(field_id);
+    LOG(ERROR) << "VFY: unable to resolve static field";
+  }
+
+  return field;
+}
+
+Class* DexVerifier::GetCaughtExceptionType(VerifierData* vdata, int insn_idx,
+    VerifyError* failure) {
+  const DexFile* dex_file = vdata->dex_file_;
+  const DexFile::CodeItem* code_item = vdata->code_item_;
+  Method* method = vdata->method_;
+  Class* common_super = NULL;
+  uint32_t handlers_size;
   const byte* handlers_ptr = DexFile::dexGetCatchHandlerData(*code_item, 0);
-  uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr);
-  for (uint32_t idx = 0; idx < handlers_size; idx++) {
+
+  if (code_item->tries_size_ != 0) {
+    handlers_size = DecodeUnsignedLeb128(&handlers_ptr);
+  } else {
+    handlers_size = 0;
+  }
+
+  for (uint32_t i = 0; i < handlers_size; i++) {
     DexFile::CatchHandlerIterator iterator(handlers_ptr);
 
     for (; !iterator.HasNext(); iterator.Next()) {
-      uint32_t addr = iterator.Get().address_;
-      if (InsnGetWidth(insn_flags, addr) == 0) {
-        LOG(ERROR) << "VFY: exception handler starts at bad address ("
-                   << addr << ")";
-        return false;
-      }
+      DexFile::CatchHandlerItem handler = iterator.Get();
+      if (handler.address_ == (uint32_t) insn_idx) {
+        ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+        Class* klass;
 
-      InsnSetBranchTarget(insn_flags, addr, true);
+        if (handler.type_idx_ == DexFile::kDexNoIndex) {
+          klass = class_linker->FindSystemClass("Ljava/lang/Throwable;");
+        } else {
+          klass = class_linker->ResolveType(*dex_file, handler.type_idx_,
+              method->GetDeclaringClass());
+        }
+
+        if (klass == NULL) {
+          LOG(ERROR) << "VFY: unable to resolve exception class "
+                     << handler.type_idx_ << " ("
+                     << dex_file->dexStringByTypeIdx(handler.type_idx_) << ")";
+          /* TODO: do we want to keep going?  If we don't fail
+           * this we run the risk of having a non-Throwable
+           * introduced at runtime.  However, that won't pass
+           * an instanceof test, so is essentially harmless.
+           */
+        } else {
+          if (common_super == NULL)
+            common_super = klass;
+          else
+            common_super = FindCommonSuperclass(klass, common_super);
+        }
+      }
     }
 
     handlers_ptr = iterator.GetData();
   }
 
-  return true;
+  if (common_super == NULL) {
+    /* no catch blocks, or no catches with classes we can find */
+    LOG(ERROR) << "VFY: unable to find exception handler at addr 0x" << std::hex
+               << insn_idx << std::dec;
+    *failure = VERIFY_ERROR_GENERIC;
+  }
+
+  return common_super;
 }
 
-
-
-bool DexVerify::VerifyClass(Class* klass) {
-  if (klass->IsVerified()) {
-    return true;
-  }
-  for (size_t i = 0; i < klass->NumDirectMethods(); ++i) {
-    Method* method = klass->GetDirectMethod(i);
-    if (!VerifyMethod(method)) {
-        LOG(ERROR) << "Verifier rejected class "
-                   << klass->GetDescriptor()->ToModifiedUtf8();
-      return false;
-    }
-  }
-  for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
-    Method* method = klass->GetVirtualMethod(i);
-    if (!VerifyMethod(method)) {
-        LOG(ERROR) << "Verifier rejected class "
-                   << klass->GetDescriptor()->ToModifiedUtf8();
-      return false;
-    }
-  }
-  return true;
+DexVerifier::RegType DexVerifier::GetMethodReturnType(const DexFile* dex_file,
+    const Method* method) {
+  Class* klass = method->GetReturnType();
+  if (klass->IsPrimitive())
+    return PrimitiveTypeToRegType(klass->GetPrimitiveType());
+  else
+    return RegTypeFromClass(klass);
 }
 
-bool DexVerify::VerifyMethod(Method* method) {
-  const DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
-  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
-  const DexFile& dex_file = class_linker->FindDexFile(dex_cache);
-  const DexFile::CodeItem *code_item = dex_file.GetCodeItem(method->GetCodeItemOffset());
+Class* DexVerifier::GetClassFromRegister(const RegisterLine* register_line,
+    uint32_t vsrc, VerifyError* failure) {
+  /* get the element type of the array held in vsrc */
+  RegType type = GetRegisterType(register_line, vsrc);
 
-  /*
-   * If there aren't any instructions, make sure that's expected, then
-   * exit successfully.
-   */
-  if (code_item == NULL) {
-    if (!method->IsNative() && !method->IsAbstract()) {
-      LOG(ERROR) << "VFY: zero-length code in concrete non-native method";
-      return false;
-    }
-    return true;
+  /* if "always zero", we allow it to fail at runtime */
+  if (type == kRegTypeZero)
+    return NULL;
+
+  if (!RegTypeIsReference(type)) {
+    LOG(ERROR) << "VFY: tried to get class from non-ref register v" << vsrc
+               << " (type=" << type << ")",
+    *failure = VERIFY_ERROR_GENERIC;
+    return NULL;
+  }
+  if (RegTypeIsUninitReference(type)) {
+    LOG(ERROR) << "VFY: register " << vsrc << " holds uninitialized reference";
+    *failure = VERIFY_ERROR_GENERIC;
+    return NULL;
   }
 
-  /*
-   * Sanity-check the register counts.  ins + locals = registers, so make
-   * sure that ins <= registers.
-   */
-  if (code_item->ins_size_ > code_item->registers_size_) {
-    LOG(ERROR) << "VFY: bad register counts (ins=" << code_item->ins_size_
-               << " regs=" << code_item->registers_size_;
-    return false;
-  }
-
-  /*
-   * Allocate and initialize an array to hold instruction data.
-   */
-  UniquePtr<uint32_t[]> insn_flags(new uint32_t[code_item->insns_size_]());
-
-  /*
-   * Run through the instructions and see if the width checks out.
-   */
-  if (!CheckInsnWidth(code_item->insns_, code_item->insns_size_, insn_flags.get())) {
-    return false;
-  }
-
-  /*
-   * Flag instructions guarded by a "try" block and check exception handlers.
-   */
-  if (!ScanTryCatchBlocks(code_item, insn_flags.get())) {
-    return false;
-  }
-
-  /*
-   * Perform static instruction verification.
-   */
-  if (!VerifyInstructions(&dex_file, code_item, insn_flags.get())) {
-    return false;
-  }
-
-  /*
-   * TODO: Code flow analysis
-   */
-
-  return true;
+  return RegTypeInitializedReferenceToClass(type);
 }
 
-bool DexVerify::VerifyInstructions(const DexFile* dex_file,
-    const DexFile::CodeItem* code_item, uint32_t insn_flags[]) {
-  const byte* ptr = reinterpret_cast<const byte*>(code_item->insns_);
-  const Instruction* inst = Instruction::At(ptr);
-
-  /* Flag the start of the method as a branch target. */
-  InsnSetBranchTarget(insn_flags, 0, true);
-
-  uint32_t width = 0;
-  uint32_t insns_size = code_item->insns_size_;
-
-  while (width < insns_size) {
-    if (!VerifyInstruction(dex_file, inst, width, code_item, insn_flags)) {
-      LOG(ERROR) << "VFY:  rejecting opcode 0x" << std::hex
-                 << (int) inst->Opcode() << " at 0x" << width << std::dec;
-      return false;
-    }
-
-    /* Flag instructions that are garbage collection points */
-    if (inst->IsBranch() || inst->IsSwitch() || inst->IsThrow() ||
-        inst->IsReturn()) {
-      InsnSetGcPoint(insn_flags, width, true);
-    }
-
-    width += inst->Size();
-    inst = inst->Next();
+DexVerifier::RegType DexVerifier::GetInvocationThis(
+    const RegisterLine* register_line,
+    const Instruction::DecodedInstruction* dec_insn, VerifyError* failure) {
+  if (dec_insn->vA_ < 1) {
+    LOG(ERROR) << "VFY: invoke lacks 'this'";
+    *failure = VERIFY_ERROR_GENERIC;
+    return kRegTypeUnknown;
   }
-  return true;
+
+  /* get the element type of the array held in vsrc */
+  RegType this_type = GetRegisterType(register_line, dec_insn->vC_);
+  if (!RegTypeIsReference(this_type)) {
+    LOG(ERROR) << "VFY: tried to get class from non-ref register v"
+               << dec_insn->vC_ << " (type=" << this_type << ")";
+    *failure = VERIFY_ERROR_GENERIC;
+    return kRegTypeUnknown;
+  }
+
+  return this_type;
 }
 
-bool DexVerify::VerifyInstruction(const DexFile* dex_file,
-    const Instruction* inst, uint32_t code_offset,
-    const DexFile::CodeItem* code_item, uint32_t insn_flags[]) {
-  Instruction::Code opcode = inst->Opcode();
-  bool result = true;
-  uint32_t vA, vB, vC;
-  uint64_t vB_wide;
-  uint32_t arg[5];
+void DexVerifier::SetRegisterType(RegisterLine* register_line, uint32_t vdst,
+    RegType new_type) {
+  RegType* insn_regs = register_line->reg_types_;
 
-  inst->Decode(vA, vB, vB_wide, vC, arg);
-
-  int argumentA = inst->GetVerifyTypeArgumentA();
-  int argumentB = inst->GetVerifyTypeArgumentB();
-  int argumentC = inst->GetVerifyTypeArgumentC();
-  int extra_flags = inst->GetVerifyExtraFlags();
-
-  switch (argumentA) {
-    case Instruction::kVerifyRegA:
-      result &= CheckRegisterIndex(code_item, vA);
+  switch (new_type) {
+    case kRegTypeUnknown:
+    case kRegTypeBoolean:
+    case kRegTypeOne:
+    case kRegTypeConstByte:
+    case kRegTypeConstPosByte:
+    case kRegTypeConstShort:
+    case kRegTypeConstPosShort:
+    case kRegTypeConstChar:
+    case kRegTypeConstInteger:
+    case kRegTypeByte:
+    case kRegTypePosByte:
+    case kRegTypeShort:
+    case kRegTypePosShort:
+    case kRegTypeChar:
+    case kRegTypeInteger:
+    case kRegTypeFloat:
+    case kRegTypeZero:
+    case kRegTypeUninit:
+      insn_regs[vdst] = new_type;
       break;
-    case Instruction::kVerifyRegAWide:
-      result &= CheckWideRegisterIndex(code_item, vA);
+    case kRegTypeConstLo:
+    case kRegTypeLongLo:
+    case kRegTypeDoubleLo:
+      insn_regs[vdst] = new_type;
+      insn_regs[vdst + 1] = new_type + 1;
+      break;
+    case kRegTypeConstHi:
+    case kRegTypeLongHi:
+    case kRegTypeDoubleHi:
+      /* should never set these explicitly */
+      LOG(FATAL) << "BUG: explicit set of high register type";
+      break;
+
+    default:
+      /* can't switch for ref types, so we check explicitly */
+      if (RegTypeIsReference(new_type)) {
+        insn_regs[vdst] = new_type;
+
+        /*
+         * In most circumstances we won't see a reference to a primitive
+         * class here (e.g. "D"), since that would mean the object in the
+         * register is actually a primitive type.  It can happen as the
+         * result of an assumed-successful check-cast instruction in
+         * which the second argument refers to a primitive class.  (In
+         * practice, such an instruction will always throw an exception.)
+         *
+         * This is not an issue for instructions like const-class, where
+         * the object in the register is a java.lang.Class instance.
+         */
+        break;
+      }
+      /* bad type - fall through */
+
+    case kRegTypeConflict:      // should only be set during a merge
+      LOG(FATAL) << "BUG: set register to unknown type " << new_type;
       break;
   }
 
-  switch (argumentB) {
-    case Instruction::kVerifyRegB:
-      result &= CheckRegisterIndex(code_item, vB);
+  /*
+   * Clear the monitor entry bits for this register.
+   */
+  if (register_line->monitor_entries_ != NULL)
+    register_line->monitor_entries_[vdst] = 0;
+}
+
+void DexVerifier::VerifyRegisterType(RegisterLine* register_line, uint32_t vsrc,
+    RegType check_type, VerifyError* failure) {
+  const RegType* insn_regs = register_line->reg_types_;
+  RegType src_type = insn_regs[vsrc];
+
+  switch (check_type) {
+    case kRegTypeFloat:
+    case kRegTypeBoolean:
+    case kRegTypePosByte:
+    case kRegTypeByte:
+    case kRegTypePosShort:
+    case kRegTypeShort:
+    case kRegTypeChar:
+    case kRegTypeInteger:
+      if (!CanConvertTo1nr(src_type, check_type)) {
+        LOG(ERROR) << "VFY: register1 v" << vsrc << " type " << src_type
+                   << ", wanted " << check_type;
+        *failure = VERIFY_ERROR_GENERIC;
+      }
+      /* Update type if result is float */
+      if (check_type == kRegTypeFloat) {
+        SetRegisterType(register_line, vsrc, check_type);
+      } else {
+        /* Update const type to actual type after use */
+        SetRegisterType(register_line, vsrc, ConstTypeToRegType(src_type));
+      }
       break;
-    case Instruction::kVerifyRegBField:
-      result &= CheckFieldIndex(dex_file, vB);
+    case kRegTypeLongLo:
+    case kRegTypeDoubleLo:
+      if (insn_regs[vsrc + 1] != src_type + 1) {
+        LOG(ERROR) << "VFY: register2 v" << vsrc << "-" << vsrc + 1
+                   << " values " << insn_regs[vsrc] << ","
+                   << insn_regs[vsrc + 1];
+        *failure = VERIFY_ERROR_GENERIC;
+      } else if (!CanConvertTo2(src_type, check_type)) {
+        LOG(ERROR) << "VFY: register2 v" << vsrc << " type " << src_type
+                   << ", wanted " << check_type;
+        *failure = VERIFY_ERROR_GENERIC;
+      }
+      /* Update type if source is from const */
+      if (src_type == kRegTypeConstLo) {
+        SetRegisterType(register_line, vsrc, check_type);
+      }
       break;
-    case Instruction::kVerifyRegBMethod:
-      result &= CheckMethodIndex(dex_file, vB);
-      break;
-    case Instruction::kVerifyRegBNewInstance:
-      result &= CheckNewInstance(dex_file, vB);
-      break;
-    case Instruction::kVerifyRegBString:
-      result &= CheckStringIndex(dex_file, vB);
-      break;
-    case Instruction::kVerifyRegBType:
-      result &= CheckTypeIndex(dex_file, vB);
-      break;
-    case Instruction::kVerifyRegBWide:
-      result &= CheckWideRegisterIndex(code_item, vB);
+    case kRegTypeConstLo:
+    case kRegTypeConstHi:
+    case kRegTypeLongHi:
+    case kRegTypeDoubleHi:
+    case kRegTypeZero:
+    case kRegTypeOne:
+    case kRegTypeUnknown:
+    case kRegTypeConflict:
+      /* should never be checking for these explicitly */
+      assert(false);
+      *failure = VERIFY_ERROR_GENERIC;
+      return;
+    case kRegTypeUninit:
+    default:
+      /* make sure check_type is initialized reference */
+      if (!RegTypeIsReference(check_type)) {
+        LOG(ERROR) << "VFY: unexpected check type " << check_type;
+        assert(false);
+        *failure = VERIFY_ERROR_GENERIC;
+        break;
+      }
+      if (RegTypeIsUninitReference(check_type)) {
+        LOG(ERROR) << "VFY: uninitialized ref not expected as reg check";
+        *failure = VERIFY_ERROR_GENERIC;
+        break;
+      }
+      /* make sure src_type is initialized reference or always-NULL */
+      if (!RegTypeIsReference(src_type)) {
+        LOG(ERROR) << "VFY: register1 v" << vsrc << " type " << src_type
+                   << ", wanted ref";
+        *failure = VERIFY_ERROR_GENERIC;
+        break;
+      }
+      if (RegTypeIsUninitReference(src_type)) {
+        LOG(ERROR) << "VFY: register1 v" << vsrc << " holds uninitialized ref";
+        *failure = VERIFY_ERROR_GENERIC;
+        break;
+      }
+      /* if the register isn't Zero, make sure it's an instance of check */
+      if (src_type != kRegTypeZero) {
+        Class* src_class = RegTypeInitializedReferenceToClass(src_type);
+        Class* check_class = RegTypeInitializedReferenceToClass(check_type);
+        assert(src_class != NULL);
+        assert(check_class != NULL);
+
+        if (!check_class->IsAssignableFrom(src_class)) {
+          LOG(ERROR) << "VFY: " << src_class->GetDescriptor()->ToModifiedUtf8()
+                     << " is not instance of "
+                     << check_class->GetDescriptor()->ToModifiedUtf8();
+          *failure = VERIFY_ERROR_GENERIC;
+        }
+      }
       break;
   }
+}
 
-  switch (argumentC) {
-    case Instruction::kVerifyRegC:
-      result &= CheckRegisterIndex(code_item, vC);
-      break;
-    case Instruction::kVerifyRegCField:
-      result &= CheckFieldIndex(dex_file, vC);
-      break;
-    case Instruction::kVerifyRegCNewArray:
-      result &= CheckNewArray(dex_file, vC);
-      break;
-    case Instruction::kVerifyRegCType:
-      result &= CheckTypeIndex(dex_file, vC);
-      break;
-    case Instruction::kVerifyRegCWide:
-      result &= CheckWideRegisterIndex(code_item, vC);
-      break;
+void DexVerifier::SetResultRegisterType(RegisterLine* register_line,
+    const int insn_reg_count, RegType new_type) {
+  SetRegisterType(register_line, RESULT_REGISTER(insn_reg_count), new_type);
+}
+
+void DexVerifier::MarkRefsAsInitialized(RegisterLine* register_line,
+    int insn_reg_count, UninitInstanceMap* uninit_map, RegType uninit_type,
+    VerifyError* failure) {
+  RegType* insn_regs = register_line->reg_types_;
+  Class* klass = GetUninitInstance(uninit_map,
+      RegTypeToUninitIndex(uninit_type));
+
+  if (klass == NULL) {
+    LOG(ERROR) << "VFY: unable to find type=" << std::hex << uninit_type
+               << std::dec << " (idx=" << RegTypeToUninitIndex(uninit_type)
+               << ")";
+    *failure = VERIFY_ERROR_GENERIC;
+    return;
   }
 
-  switch (extra_flags) {
-    case Instruction::kVerifyArrayData:
-      result &= CheckArrayData(code_item, code_offset);
-      break;
-    case Instruction::kVerifyBranchTarget:
-      result &= CheckBranchTarget(code_item, insn_flags, code_offset);
-      break;
-    case Instruction::kVerifySwitchTargets:
-      result &= CheckSwitchTargets(code_item, insn_flags, code_offset);
-      break;
-    case Instruction::kVerifyVarArg:
-      result &= CheckVarArgRegs(code_item, vA, arg);
-      break;
-    case Instruction::kVerifyVarArgRange:
-      result &= CheckVarArgRangeRegs(code_item, vA, vC);
-      break;
-    case Instruction::kVerifyError:
-      LOG(ERROR) << "VFY: unexpected opcode " << (int) opcode;
-      result = false;
-      break;
+  RegType init_type = RegTypeFromClass(klass);
+  int changed = 0;
+  for (int i = 0; i < insn_reg_count; i++) {
+    if (insn_regs[i] == uninit_type) {
+      insn_regs[i] = init_type;
+      changed++;
+    }
+  }
+  assert(changed > 0);
+
+  return;
+}
+
+void DexVerifier::MarkUninitRefsAsInvalid(RegisterLine* register_line,
+    int insn_reg_count, UninitInstanceMap* uninit_map, RegType uninit_type) {
+  RegType* insn_regs = register_line->reg_types_;
+
+  for (int i = 0; i < insn_reg_count; i++) {
+    if (insn_regs[i] == uninit_type) {
+      insn_regs[i] = kRegTypeConflict;
+      if (register_line->monitor_entries_ != NULL)
+        register_line->monitor_entries_[i] = 0;
+    }
+  }
+}
+
+void DexVerifier::CopyRegister1(RegisterLine* register_line, uint32_t vdst,
+    uint32_t vsrc, TypeCategory cat, VerifyError* failure) {
+  assert(cat == kTypeCategory1nr || cat == kTypeCategoryRef);
+  RegType type = GetRegisterType(register_line, vsrc);
+  CheckTypeCategory(type, cat, failure);
+  if (*failure != VERIFY_ERROR_NONE) {
+    LOG(ERROR) << "VFY: copy1 v" << vdst << "<-v" << vsrc << " type=" << type
+               << " cat=" << (int) cat;
+  } else {
+    SetRegisterType(register_line, vdst, type);
+    if (cat == kTypeCategoryRef && register_line->monitor_entries_ != NULL) {
+      register_line->monitor_entries_[vdst] =
+          register_line->monitor_entries_[vsrc];
+    }
+  }
+}
+
+void DexVerifier::CopyRegister2(RegisterLine* register_line, uint32_t vdst,
+    uint32_t vsrc, VerifyError* failure) {
+  RegType type_l = GetRegisterType(register_line, vsrc);
+  RegType type_h = GetRegisterType(register_line, vsrc + 1);
+
+  CheckTypeCategory(type_l, kTypeCategory2, failure);
+  CheckWidePair(type_l, type_h, failure);
+  if (*failure != VERIFY_ERROR_NONE) {
+    LOG(ERROR) << "VFY: copy2 v" << vdst << "<-v" << vsrc << " type=" << type_l
+               << "/" << type_h;
+  } else {
+    SetRegisterType(register_line, vdst, type_l);
+  }
+}
+
+void DexVerifier::CopyResultRegister1(RegisterLine* register_line,
+    const int insn_reg_count, uint32_t vdst, TypeCategory cat,
+    VerifyError* failure) {
+  assert(vdst < (uint32_t) insn_reg_count);
+
+  uint32_t vsrc = RESULT_REGISTER(insn_reg_count);
+  RegType type = GetRegisterType(register_line, vsrc);
+  CheckTypeCategory(type, cat, failure);
+  if (*failure != VERIFY_ERROR_NONE) {
+    LOG(ERROR) << "VFY: copyRes1 v" << vdst << "<-v" << vsrc << " cat="
+               << (int) cat << " type=" << type;
+  } else {
+    SetRegisterType(register_line, vdst, type);
+    SetRegisterType(register_line, vsrc, kRegTypeUnknown);
+  }
+}
+
+/*
+ * Implement "move-result-wide".  Copy the category-2 value from the result
+ * register to another register, and reset the result register.
+ */
+void DexVerifier::CopyResultRegister2(RegisterLine* register_line,
+    const int insn_reg_count, uint32_t vdst, VerifyError* failure) {
+  assert(vdst < (uint32_t) insn_reg_count);
+
+  uint32_t vsrc = RESULT_REGISTER(insn_reg_count);
+  RegType type_l = GetRegisterType(register_line, vsrc);
+  RegType type_h = GetRegisterType(register_line, vsrc + 1);
+  CheckTypeCategory(type_l, kTypeCategory2, failure);
+  CheckWidePair(type_l, type_h, failure);
+  if (*failure != VERIFY_ERROR_NONE) {
+    LOG(ERROR) << "VFY: copyRes2 v" << vdst << "<-v" << vsrc << " type="
+               << type_l << "/" << type_h;
+  } else {
+    SetRegisterType(register_line, vdst, type_l);
+    SetRegisterType(register_line, vsrc, kRegTypeUnknown);
+    SetRegisterType(register_line, vsrc + 1, kRegTypeUnknown);
+  }
+}
+
+int DexVerifier::GetClassDepth(Class* klass) {
+  int depth = 0;
+  while (klass->GetSuperClass() != NULL) {
+    klass = klass->GetSuperClass();
+    depth++;
+  }
+  return depth;
+}
+
+Class* DexVerifier::DigForSuperclass(Class* c1, Class* c2) {
+  int depth1, depth2;
+
+  depth1 = GetClassDepth(c1);
+  depth2 = GetClassDepth(c2);
+
+  /* pull the deepest one up */
+  if (depth1 > depth2) {
+    while (depth1 > depth2) {
+      c1 = c1->GetSuperClass();
+      depth1--;
+    }
+  } else {
+    while (depth2 > depth1) {
+      c2 = c2->GetSuperClass();
+      depth2--;
+    }
   }
 
+  /* walk up in lock-step */
+  while (c1 != c2) {
+    c1 = c1->GetSuperClass();
+    c2 = c2->GetSuperClass();
+
+    assert(c1 != NULL && c2 != NULL);
+  }
+
+  return c1;
+}
+
+Class* DexVerifier::FindCommonArraySuperclass(Class* c1, Class* c2) {
+  Class* array_class = NULL;
+  Class* common_elem;
+  int array_dim1, array_dim2;
+  int i, num_dims;
+  bool has_primitive = false;
+
+  array_dim1 = c1->GetArrayRank();
+  array_dim2 = c2->GetArrayRank();
+  assert(c1->GetArrayRank() > 0);
+  assert(c2->GetArrayRank() > 0);
+
+  if (c1->GetComponentType()->IsPrimitive()) {
+    array_dim1--;
+    has_primitive = true;
+  }
+  if (c2->GetComponentType()->IsPrimitive()) {
+    array_dim2--;
+    has_primitive = true;
+  }
+
+  if (!has_primitive && array_dim1 == array_dim2) {
+    /*
+     * Two arrays of reference types with equal dimensions.  Try to
+     * find a good match.
+     */
+    common_elem = FindCommonSuperclass(c1->GetComponentType(),
+        c2->GetComponentType());
+    num_dims = array_dim1;
+  } else {
+    /*
+     * Mismatched array depths and/or array(s) of primitives.  We want
+     * Object, or an Object array with appropriate dimensions.
+     *
+     * We initialize array_class to Object here, because it's possible
+     * for us to set num_dims=0.
+     */
+    if (array_dim1 < array_dim2)
+      num_dims = array_dim1;
+    else
+      num_dims = array_dim2;
+    array_class = common_elem = c1->GetSuperClass();  // == java.lang.Object
+  }
+
+  /*
+   * Find an appropriately-dimensioned array class.  This is easiest
+   * to do iteratively, using the array class found by the current round
+   * as the element type for the next round.
+   */
+  for (i = 0; i < num_dims; i++) {
+    ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+    const ClassLoader* class_loader = c1->GetClassLoader();
+    std::string descriptor = "[" +
+        common_elem->GetDescriptor()->ToModifiedUtf8();
+    array_class = class_linker->FindClass(descriptor.c_str(), class_loader);
+    common_elem = array_class;
+  }
+  assert(array_class != NULL);
+
+  return array_class;
+}
+
+Class* DexVerifier::FindCommonSuperclass(Class* c1, Class* c2) {
+  assert(!c1->IsPrimitive() && !c2->IsPrimitive());
+
+  if (c1 == c2)
+    return c1;
+
+  if (c1->IsInterface() && c2->Implements(c1)) {
+    return c1;
+  }
+  if (c2->IsInterface() && c1->Implements(c2)) {
+    return c2;
+  }
+  if (c1->IsArrayClass() && c2->IsArrayClass()) {
+    return FindCommonArraySuperclass(c1, c2);
+  }
+
+  return DigForSuperclass(c1, c2);
+}
+
+DexVerifier::RegType DexVerifier::MergeTypes(RegType type1, RegType type2,
+    bool* changed) {
+  RegType result;
+
+  /*
+   * Check for trivial case so we don't have to hit memory.
+   */
+  if (type1 == type2)
+    return type1;
+
+  /*
+   * Use the table if we can, and reject any attempts to merge something
+   * from the table with a reference type.
+   *
+   * Uninitialized references are composed of the enum ORed with an
+   * index value.  The uninitialized table entry at index zero *will*
+   * show up as a simple kRegTypeUninit value.  Since this cannot be
+   * merged with anything but itself, the rules do the right thing.
+   */
+  if (type1 < kRegTypeMAX) {
+    if (type2 < kRegTypeMAX) {
+      result = merge_table_[type1][type2];
+    } else {
+      /* simple + reference == conflict, usually */
+      if (type1 == kRegTypeZero)
+        result = type2;
+      else
+        result = kRegTypeConflict;
+    }
+  } else {
+    if (type2 < kRegTypeMAX) {
+      /* reference + simple == conflict, usually */
+      if (type2 == kRegTypeZero)
+        result = type1;
+      else
+        result = kRegTypeConflict;
+    } else {
+      /* merging two references */
+      if (RegTypeIsUninitReference(type1) ||
+          RegTypeIsUninitReference(type2))
+      {
+        /* can't merge uninit with anything but self */
+        result = kRegTypeConflict;
+      } else {
+        Class* klass1 = RegTypeInitializedReferenceToClass(type1);
+        Class* klass2 = RegTypeInitializedReferenceToClass(type2);
+        Class* merged_class = FindCommonSuperclass(klass1, klass2);
+        assert(merged_class != NULL);
+        result = RegTypeFromClass(merged_class);
+      }
+    }
+  }
+
+  if (result != type1)
+    *changed = true;
   return result;
-};
+}
+
+DexVerifier::MonitorEntries DexVerifier::MergeMonitorEntries(
+    MonitorEntries ents1, MonitorEntries ents2, bool* changed) {
+  MonitorEntries result = ents1 & ents2;
+  if (result != ents1)
+    *changed = true;
+  return result;
+}
+
+bool DexVerifier::UpdateRegisters(InsnFlags* insn_flags,
+    RegisterTable* reg_table, int next_insn, const RegisterLine* work_line) {
+  const size_t insn_reg_count_plus = reg_table->insn_reg_count_plus_;
+  assert(work_line != NULL);
+  const RegType* work_regs = work_line->reg_types_;
+
+  if (!InsnIsVisitedOrChanged(insn_flags, next_insn)) {
+    /*
+     * We haven't processed this instruction before, and we haven't
+     * touched the registers here, so there's nothing to "merge".  Copy
+     * the registers over and mark it as changed.  (This is the only
+     * way a register can transition out of "unknown", so this is not
+     * just an optimization.)
+     */
+    CopyLineToTable(reg_table, next_insn, work_line);
+    InsnSetChanged(insn_flags, next_insn, true);
+  } else {
+    /* Merge registers, set Changed only if different */
+    RegisterLine* target_line = GetRegisterLine(reg_table, next_insn);
+    RegType* target_regs = target_line->reg_types_;
+    MonitorEntries* work_mon_ents = work_line->monitor_entries_;
+    MonitorEntries* target_mon_ents = target_line->monitor_entries_;
+    bool changed = false;
+    unsigned int idx;
+
+    assert(target_regs != NULL);
+    if (target_mon_ents != NULL) {
+      /* Monitor stacks must be identical. */
+      if (target_line->monitor_stack_top_ != work_line->monitor_stack_top_) {
+        LOG(ERROR) << "VFY: mismatched stack depth "
+                   << target_line->monitor_stack_top_ << " vs. "
+                   << work_line->monitor_stack_top_ << " at 0x"
+                   << std::hex << next_insn << std::dec;
+        return false;
+      }
+      if (memcmp(target_line->monitor_stack_, work_line->monitor_stack_,
+                 target_line->monitor_stack_top_ * sizeof(uint32_t)) != 0) {
+         LOG(ERROR) << "VFY: mismatched monitor stacks at 0x" << std::hex
+                    << next_insn << std::dec;
+         return false;
+      }
+    }
+
+    for (idx = 0; idx < insn_reg_count_plus; idx++) {
+      target_regs[idx] = MergeTypes(target_regs[idx], work_regs[idx], &changed);
+
+      if (target_mon_ents != NULL) {
+        target_mon_ents[idx] = MergeMonitorEntries(target_mon_ents[idx],
+             work_mon_ents[idx], &changed);
+      }
+    }
+
+    if (changed) {
+      InsnSetChanged(insn_flags, next_insn, true);
+    }
+  }
+
+  return true;
+}
+
+bool DexVerifier::CanConvertTo1nr(RegType src_type, RegType check_type) {
+  static const char conv_tab[kRegType1nrEND - kRegType1nrSTART + 1]
+                            [kRegType1nrEND - kRegType1nrSTART + 1] =
+  {
+    /* chk: 0  1  Z  y  Y  h  H  c  i  b  B  s  S  C  I  F */
+    { /*0*/ 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+    { /*1*/ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+    { /*Z*/ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
+    { /*y*/ 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+    { /*Y*/ 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1 },
+    { /*h*/ 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1 },
+    { /*H*/ 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1 },
+    { /*c*/ 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1 },
+    { /*i*/ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1 },
+    { /*b*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0 },
+    { /*B*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0 },
+    { /*s*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0 },
+    { /*S*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 },
+    { /*C*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 },
+    { /*I*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 },
+    { /*F*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+  };
+
+  assert(check_type >= kRegType1nrSTART && check_type <= kRegType1nrEND);
+
+  if (src_type >= kRegType1nrSTART && src_type <= kRegType1nrEND)
+    return (bool) conv_tab[src_type - kRegType1nrSTART]
+                          [check_type - kRegType1nrSTART];
+
+  return false;
+}
+
+bool DexVerifier::CanConvertTo2(RegType src_type, RegType check_type) {
+  return ((src_type == kRegTypeConstLo || src_type == check_type) &&
+          (check_type == kRegTypeLongLo || check_type == kRegTypeDoubleLo));
+}
+
+DexVerifier::RegType DexVerifier::PrimitiveTypeToRegType(
+    Class::PrimitiveType prim_type) {
+  switch (prim_type) {
+    case Class::kPrimBoolean: return kRegTypeBoolean;
+    case Class::kPrimByte:    return kRegTypeByte;
+    case Class::kPrimShort:   return kRegTypeShort;
+    case Class::kPrimChar:    return kRegTypeChar;
+    case Class::kPrimInt:     return kRegTypeInteger;
+    case Class::kPrimLong:    return kRegTypeLongLo;
+    case Class::kPrimFloat:   return kRegTypeFloat;
+    case Class::kPrimDouble:  return kRegTypeDoubleLo;
+    case Class::kPrimVoid:
+    default: {
+      return kRegTypeUnknown;
+    }
+  }
+}
+
+DexVerifier::RegType DexVerifier::ConstTypeToRegType(RegType const_type) {
+  switch (const_type) {
+    case kRegTypeConstPosByte: return kRegTypePosByte;
+    case kRegTypeConstByte: return kRegTypeByte;
+    case kRegTypeConstPosShort: return kRegTypePosShort;
+    case kRegTypeConstShort: return kRegTypeShort;
+    case kRegTypeConstChar: return kRegTypeChar;
+    case kRegTypeConstInteger: return kRegTypeInteger;
+    default: {
+      return const_type;
+    }
+  }
+}
+
+char DexVerifier::DetermineCat1Const(int32_t value) {
+  if (value < -32768)
+    return kRegTypeConstInteger;
+  else if (value < -128)
+    return kRegTypeConstShort;
+  else if (value < 0)
+    return kRegTypeConstByte;
+  else if (value == 0)
+    return kRegTypeZero;
+  else if (value == 1)
+    return kRegTypeOne;
+  else if (value < 128)
+    return kRegTypeConstPosByte;
+  else if (value < 32768)
+    return kRegTypeConstPosShort;
+  else if (value < 65536)
+    return kRegTypeConstChar;
+  else
+    return kRegTypeConstInteger;
+}
+
+void DexVerifier::CheckFinalFieldAccess(const Method* method,
+    const Field* field, VerifyError* failure) {
+  if (!field->IsFinal())
+    return;
+
+  /* make sure we're in the same class */
+  if (method->GetDeclaringClass() != field->GetDeclaringClass()) {
+    LOG(ERROR) << "VFY: can't modify final field "
+               << field->GetDeclaringClass()->GetDescriptor()->ToModifiedUtf8()
+               << "." << field->GetName()->ToModifiedUtf8();
+    *failure = VERIFY_ERROR_ACCESS_FIELD;
+    return;
+  }
+}
+
+void DexVerifier::CheckArrayIndexType(const Method* method, RegType reg_type,
+    VerifyError* failure) {
+  if (*failure == VERIFY_ERROR_NONE) {
+    /*
+     * The 1nr types are interchangeable at this level.  We could
+     * do something special if we can definitively identify it as a
+     * float, but there's no real value in doing so.
+     */
+    CheckTypeCategory(reg_type, kTypeCategory1nr, failure);
+    if (*failure != VERIFY_ERROR_NONE) {
+      LOG(ERROR) << "Invalid reg type for array index (" << reg_type << ")";
+    }
+  }
+}
+
+bool DexVerifier::CheckConstructorReturn(const Method* method,
+    const RegisterLine* register_line, const int insn_reg_count) {
+  const RegType* insn_regs = register_line->reg_types_;
+
+  if (!IsInitMethod(method))
+    return true;
+
+  RegType uninit_this = RegTypeFromUninitIndex(kUninitThisArgSlot);
+
+  for (int i = 0; i < insn_reg_count; i++) {
+    if (insn_regs[i] == uninit_this) {
+      LOG(ERROR) << "VFY: <init> returning without calling superclass init";
+      return false;
+    }
+  }
+  return true;
+}
+
+bool DexVerifier::CheckMoveException(const uint16_t* insns, int insn_idx) {
+  if ((insns[insn_idx] & 0xff) == Instruction::MOVE_EXCEPTION) {
+    LOG(ERROR) << "VFY: invalid use of move-exception";
+    return false;
+  }
+  return true;
+}
+
+void DexVerifier::CheckTypeCategory(RegType type, TypeCategory cat,
+    VerifyError* failure) {
+  switch (cat) {
+    case kTypeCategory1nr:
+      switch (type) {
+        case kRegTypeZero:
+        case kRegTypeOne:
+        case kRegTypeBoolean:
+        case kRegTypeConstPosByte:
+        case kRegTypeConstByte:
+        case kRegTypeConstPosShort:
+        case kRegTypeConstShort:
+        case kRegTypeConstChar:
+        case kRegTypeConstInteger:
+        case kRegTypePosByte:
+        case kRegTypeByte:
+        case kRegTypePosShort:
+        case kRegTypeShort:
+        case kRegTypeChar:
+        case kRegTypeInteger:
+        case kRegTypeFloat:
+          break;
+        default:
+          *failure = VERIFY_ERROR_GENERIC;
+          break;
+      }
+      break;
+    case kTypeCategory2:
+      switch (type) {
+        case kRegTypeConstLo:
+        case kRegTypeLongLo:
+        case kRegTypeDoubleLo:
+          break;
+        default:
+          *failure = VERIFY_ERROR_GENERIC;
+         break;
+      }
+      break;
+    case kTypeCategoryRef:
+      if (type != kRegTypeZero && !RegTypeIsReference(type))
+        *failure = VERIFY_ERROR_GENERIC;
+      break;
+    default:
+      assert(false);
+      *failure = VERIFY_ERROR_GENERIC;
+      break;
+  }
+}
+
+void DexVerifier::CheckWidePair(RegType type_l, RegType type_h,
+    VerifyError* failure) {
+  if ((type_h != type_l + 1))
+    *failure = VERIFY_ERROR_GENERIC;
+}
+
+void DexVerifier::CheckUnop(RegisterLine* register_line,
+    Instruction::DecodedInstruction* dec_insn, RegType dst_type,
+    RegType src_type, VerifyError* failure) {
+  VerifyRegisterType(register_line, dec_insn->vB_, src_type, failure);
+  SetRegisterType(register_line, dec_insn->vA_, dst_type);
+}
+
+bool DexVerifier::UpcastBooleanOp(RegisterLine* register_line, uint32_t reg1,
+    uint32_t reg2) {
+  RegType type1, type2;
+
+  type1 = GetRegisterType(register_line, reg1);
+  type2 = GetRegisterType(register_line, reg2);
+
+  if ((type1 == kRegTypeBoolean || type1 == kRegTypeZero || type1 == kRegTypeOne) &&
+      (type2 == kRegTypeBoolean || type2 == kRegTypeZero || type2 == kRegTypeOne)) {
+    return true;
+  }
+  return false;
+}
+
+void DexVerifier::CheckLitop(RegisterLine* register_line,
+    Instruction::DecodedInstruction* dec_insn, RegType dst_type,
+    RegType src_type, bool check_boolean_op, VerifyError* failure) {
+  VerifyRegisterType(register_line, dec_insn->vB_, src_type, failure);
+
+  if ((*failure == VERIFY_ERROR_NONE) && check_boolean_op) {
+    assert(dst_type == kRegTypeInteger);
+
+    /* check vB with the call, then check the constant manually */
+    if (UpcastBooleanOp(register_line, dec_insn->vB_, dec_insn->vB_)
+        && (dec_insn->vC_ == 0 || dec_insn->vC_ == 1)) {
+      dst_type = kRegTypeBoolean;
+    }
+  }
+
+  SetRegisterType(register_line, dec_insn->vA_, dst_type);
+}
+
+void DexVerifier::CheckBinop(RegisterLine* register_line,
+    Instruction::DecodedInstruction* dec_insn, RegType dst_type,
+    RegType src_type1, RegType src_type2, bool check_boolean_op,
+    VerifyError* failure) {
+  VerifyRegisterType(register_line, dec_insn->vB_, src_type1, failure);
+  VerifyRegisterType(register_line, dec_insn->vC_, src_type2, failure);
+
+  if ((*failure == VERIFY_ERROR_NONE) && check_boolean_op) {
+    assert(dst_type == kRegTypeInteger);
+    if (UpcastBooleanOp(register_line, dec_insn->vB_, dec_insn->vC_))
+      dst_type = kRegTypeBoolean;
+  }
+
+  SetRegisterType(register_line, dec_insn->vA_, dst_type);
+}
+
+void DexVerifier::CheckBinop2addr(RegisterLine* register_line,
+    Instruction::DecodedInstruction* dec_insn, RegType dst_type,
+    RegType src_type1, RegType src_type2, bool check_boolean_op,
+    VerifyError* failure) {
+  VerifyRegisterType(register_line, dec_insn->vA_, src_type1, failure);
+  VerifyRegisterType(register_line, dec_insn->vB_, src_type2, failure);
+
+  if ((*failure == VERIFY_ERROR_NONE) && check_boolean_op) {
+    assert(dst_type == kRegTypeInteger);
+    if (UpcastBooleanOp(register_line, dec_insn->vA_, dec_insn->vB_))
+      dst_type = kRegTypeBoolean;
+  }
+
+  SetRegisterType(register_line, dec_insn->vA_, dst_type);
+}
+
+DexVerifier::RegType DexVerifier::AdjustForRightShift(
+    RegisterLine* register_line, int reg, unsigned int shift_count,
+    bool is_unsigned_shift, VerifyError* failure) {
+  RegType src_type = GetRegisterType(register_line, reg);
+  RegType new_type;
+
+  /* convert const derived types to their actual types */
+  src_type = ConstTypeToRegType(src_type);
+
+  /* no-op */
+  if (shift_count == 0)
+    return src_type;
+
+  /* safe defaults */
+  if (is_unsigned_shift)
+    new_type = kRegTypeInteger;
+  else
+    new_type = src_type;
+
+  if (shift_count >= 32) {
+    LOG(ERROR) << "Got unexpectedly large shift count " << shift_count;
+    /* fail? */
+    return new_type;
+  }
+
+  switch (src_type) {
+    case kRegTypeInteger:               /* 32-bit signed value */
+      if (is_unsigned_shift) {
+        if (shift_count > 24)
+          new_type = kRegTypePosByte;
+        else if (shift_count >= 16)
+          new_type = kRegTypeChar;
+      } else {
+        if (shift_count >= 24)
+          new_type = kRegTypeByte;
+        else if (shift_count >= 16)
+          new_type = kRegTypeShort;
+      }
+      break;
+    case kRegTypeShort:                 /* 16-bit signed value */
+      if (is_unsigned_shift) {
+        /* default (kRegTypeInteger) is correct */
+      } else {
+        if (shift_count >= 8)
+          new_type = kRegTypeByte;
+      }
+      break;
+    case kRegTypePosShort:              /* 15-bit unsigned value */
+      if (shift_count >= 8)
+        new_type = kRegTypePosByte;
+      break;
+    case kRegTypeChar:                  /* 16-bit unsigned value */
+      if (shift_count > 8)
+        new_type = kRegTypePosByte;
+      break;
+    case kRegTypeByte:                  /* 8-bit signed value */
+      /* defaults (u=kRegTypeInteger / s=src_type) are correct */
+      break;
+    case kRegTypePosByte:               /* 7-bit unsigned value */
+      /* always use new_type=src_type */
+      new_type = src_type;
+      break;
+    case kRegTypeZero:                  /* 1-bit unsigned value */
+    case kRegTypeOne:
+    case kRegTypeBoolean:
+      /* unnecessary? */
+      new_type = kRegTypeZero;
+      break;
+    default:
+      /* long, double, references; shouldn't be here! */
+      assert(false);
+      break;
+  }
+
+  return new_type;
+}
+
+void DexVerifier::VerifyFilledNewArrayRegs(const Method* method,
+    RegisterLine* register_line,
+    const Instruction::DecodedInstruction* dec_insn, Class* res_class,
+    bool is_range, VerifyError* failure) {
+  uint32_t arg_count = dec_insn->vA_;
+  RegType expected_type;
+  Class::PrimitiveType elem_type;
+  unsigned int ui;
+
+  assert(res_class->IsArrayClass());
+  elem_type = res_class->GetComponentType()->GetPrimitiveType();
+  if (elem_type == Class::kPrimNot) {
+    expected_type = RegTypeFromClass(res_class->GetComponentType());
+  } else {
+    expected_type = PrimitiveTypeToRegType(elem_type);
+  }
+
+  /*
+   * Verify each register.  If "arg_count" is bad, VerifyRegisterType()
+   * will run off the end of the list and fail.  It's legal, if silly,
+   * for arg_count to be zero.
+   */
+  for (ui = 0; ui < arg_count; ui++) {
+    uint32_t get_reg;
+
+    if (is_range)
+      get_reg = dec_insn->vC_ + ui;
+    else
+      get_reg = dec_insn->arg_[ui];
+
+    VerifyRegisterType(register_line, get_reg, expected_type, failure);
+    if (*failure != VERIFY_ERROR_NONE) {
+      LOG(ERROR) << "VFY: filled-new-array arg " << ui << "(" << get_reg
+                 << ") not valid";
+      return;
+    }
+  }
+}
+
+bool DexVerifier::IsCorrectInvokeKind(MethodType method_type,
+    Method* res_method) {
+  switch (method_type) {
+    case METHOD_DIRECT:
+      return res_method->IsDirect();
+    case METHOD_STATIC:
+      return res_method->IsStatic();
+    case METHOD_VIRTUAL:
+    case METHOD_INTERFACE:
+      return !res_method->IsDirect();
+    default:
+      return false;
+  }
+}
+
+Method* DexVerifier::VerifyInvocationArgs(VerifierData* vdata,
+    RegisterLine* register_line, const int insn_reg_count,
+    const Instruction::DecodedInstruction* dec_insn, MethodType method_type,
+    bool is_range, bool is_super, VerifyError* failure) {
+  Method* method = vdata->method_;
+  const DexFile* dex_file = vdata->dex_file_;
+  const DexFile::CodeItem* code_item = vdata->code_item_;
+  UninitInstanceMap* uninit_map = vdata->uninit_map_;
+  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+  DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
+  const ClassLoader* class_loader =
+      method->GetDeclaringClass()->GetClassLoader();
+
+  Method* res_method;
+  std::string sig;
+  size_t sig_offset;
+  int expected_args;
+  int actual_args;
+
+  /*
+   * Resolve the method.  This could be an abstract or concrete method
+   * depending on what sort of call we're making.
+   */
+  res_method = class_linker->ResolveMethod(*dex_file, dec_insn->vB_, dex_cache,
+      class_loader, (method_type == METHOD_DIRECT || method_type == METHOD_STATIC));
+
+  /* Scan all implemented interfaces for the method */
+  if (method_type == METHOD_INTERFACE && res_method == NULL) {
+
+  }
+
+  if (res_method == NULL) {
+    /* failed; print a meaningful failure message */
+    //const DexFile::MethodId method_id = dex_file->GetMethodId(dec_insn->vB_);
+    //const char* method_name = dex_file->dexStringById(method_id.name_idx_);
+    //const char* class_name = dex_file->dexStringByTypeIdx(method_id.class_idx_);
+
+    //LOG(ERROR) << "VFY: unable to resolve " << (int) method_type << " method "
+               //<< dec_insn->vB_ << ": " << class_name << "." << method_name;
+    LOG(ERROR) << "VFY: unable to resolve called method";
+    *failure = VERIFY_ERROR_NO_METHOD;
+    return NULL;
+  }
+  Class* res_class = res_method->GetDeclaringClass();
+
+  /*
+   * Only time you can explicitly call a method starting with '<' is when
+   * making a "direct" invocation on "<init>".  There are additional
+   * restrictions but we don't enforce them here.
+   */
+  if (res_method->GetName()->Equals("<init>")) {
+    if (method_type != METHOD_DIRECT || !IsInitMethod(res_method)) {
+      LOG(ERROR) << "VFY: invalid call to "
+                 << res_class->GetDescriptor()->ToModifiedUtf8()
+                 << "." << res_method->GetName();
+      goto bad_sig;
+    }
+  }
+
+  /*
+   * See if the method type implied by the invoke instruction matches the
+   * access flags for the target method.
+   */
+  if (!IsCorrectInvokeKind(method_type, res_method)) {
+    LOG(ERROR) << "VFY: invoke type does not match method type of "
+               << res_class->GetDescriptor()->ToModifiedUtf8()
+               << "." << res_method->GetName()->ToModifiedUtf8();
+
+    *failure = VERIFY_ERROR_GENERIC;
+    return NULL;
+  }
+
+  /*
+   * If we're using invoke-super(method), make sure that the executing
+   * method's class' superclass has a vtable entry for the target method.
+   */
+  if (is_super) {
+    assert(method_type == METHOD_VIRTUAL);
+    Class* super = method->GetDeclaringClass()->GetSuperClass();
+    if (super == NULL || res_method->GetMethodIndex() > super->GetVTable()->GetLength()) {
+      if (super == NULL) {
+        LOG(ERROR) << "VFY: invalid invoke-super from "
+                   << method->GetDeclaringClass()->GetDescriptor()->ToModifiedUtf8()
+                   << "." << method->GetName()->ToModifiedUtf8() << " to super -."
+                   << res_method->GetName()->ToModifiedUtf8()
+                   << " " << res_method->GetSignature()->ToModifiedUtf8();
+      } else {
+        LOG(ERROR) << "VFY: invalid invoke-super from "
+                   << method->GetDeclaringClass()->GetDescriptor()->ToModifiedUtf8()
+                   << "." << method->GetName()->ToModifiedUtf8() << " to super "
+                   << super->GetDescriptor()->ToModifiedUtf8()
+                   << "." << res_method->GetName()->ToModifiedUtf8()
+                   << " " << res_method->GetSignature()->ToModifiedUtf8();
+      }
+      *failure = VERIFY_ERROR_NO_METHOD;
+      return NULL;
+    }
+  }
+
+  /*
+   * We use vAA as our expected arg count, rather than res_method->insSize,
+   * because we need to match the call to the signature.  Also, we might
+   * might be calling through an abstract method definition (which doesn't
+   * have register count values).
+   */
+  expected_args = dec_insn->vA_;
+  actual_args = 0;
+
+  /* caught by static verifier */
+  assert(is_range || expected_args <= 5);
+
+  if (expected_args > code_item->outs_size_) {
+    LOG(ERROR) << "VFY: invalid arg count (" << expected_args
+               << ") exceeds outsSize (" << code_item->outs_size_ << ")";
+    *failure = VERIFY_ERROR_GENERIC;
+    return NULL;
+  }
+
+  sig = res_method->GetSignature()->ToModifiedUtf8();
+  if (sig[0] != '(') {
+    LOG(ERROR) << "VFY: descriptor doesn't start with '(': " << sig;
+    goto bad_sig;
+  }
+
+  /*
+   * Check the "this" argument, which must be an instance of the class
+   * that declared the method.  For an interface class, we don't do the
+   * full interface merge, so we can't do a rigorous check here (which
+   * is okay since we have to do it at runtime).
+   */
+  if (!res_method->IsStatic()) {
+    Class* actual_this_ref;
+    RegType actual_arg_type;
+
+    actual_arg_type = GetInvocationThis(register_line, dec_insn, failure);
+    if (*failure != VERIFY_ERROR_NONE)
+      return NULL;
+
+    if (RegTypeIsUninitReference(actual_arg_type) &&
+        !res_method->GetName()->Equals("<init>")) {
+      LOG(ERROR) << "VFY: 'this' arg must be initialized";
+      *failure = VERIFY_ERROR_GENERIC;
+      return NULL;
+    }
+    if (method_type != METHOD_INTERFACE && actual_arg_type != kRegTypeZero) {
+      actual_this_ref = RegTypeReferenceToClass(actual_arg_type, uninit_map);
+      if (!res_method->GetDeclaringClass()->IsAssignableFrom(actual_this_ref)) {
+        LOG(ERROR) << "VFY: 'this' arg '"
+                   << actual_this_ref->GetDescriptor()->ToModifiedUtf8()
+                   << "' not instance of '"
+                   << res_method->GetDeclaringClass()->GetDescriptor()->ToModifiedUtf8()
+                   << "'";
+        *failure = VERIFY_ERROR_GENERIC;
+        return NULL;
+      }
+    }
+    actual_args++;
+  }
+
+  /*
+   * Process the target method's signature.  This signature may or may not
+   * have been verified, so we can't assume it's properly formed.
+   */
+  for (sig_offset = 1; sig_offset < sig.size(); sig_offset++) {
+  //while (*sig != '\0' && *sig != ')') {
+    if (sig[sig_offset] == ')')
+      break;
+
+    if (actual_args >= expected_args) {
+      LOG(ERROR) << "VFY: expected " << expected_args << " args, found more ("
+                 << sig.substr(sig_offset) << ")";
+      goto bad_sig;
+    }
+
+    uint32_t get_reg;
+    if (is_range)
+      get_reg = dec_insn->vC_ + actual_args;
+    else
+      get_reg = dec_insn->arg_[actual_args];
+
+    switch (sig[sig_offset]) {
+      case 'L':
+        {
+          Class* klass = LookupSignatureClass(method, sig.substr(sig_offset),
+              failure);
+          if (*failure != VERIFY_ERROR_NONE)
+            goto bad_sig;
+          VerifyRegisterType(register_line, get_reg, RegTypeFromClass(klass),
+              failure);
+          if (*failure != VERIFY_ERROR_NONE) {
+            LOG(ERROR) << "VFY: bad arg " << actual_args << " (into "
+                       << klass->GetDescriptor()->ToModifiedUtf8() << ")";
+            goto bad_sig;
+          }
+          sig_offset += sig.substr(sig_offset).find(';');
+        }
+        actual_args++;
+        break;
+      case '[':
+        {
+          Class* klass = LookupSignatureArrayClass(method,
+              sig.substr(sig_offset), failure);
+          if (*failure != VERIFY_ERROR_NONE)
+            goto bad_sig;
+          VerifyRegisterType(register_line, get_reg, RegTypeFromClass(klass),
+              failure);
+          if (*failure != VERIFY_ERROR_NONE) {
+            LOG(ERROR) << "VFY: bad arg " << actual_args << " (into "
+                       << klass->GetDescriptor()->ToModifiedUtf8() << ")";
+            goto bad_sig;
+          }
+          while (sig[sig_offset] == '[')
+            sig_offset++;
+          if (sig[sig_offset] == 'L')
+            sig_offset += sig.substr(sig_offset).find(';');
+        }
+        actual_args++;
+        break;
+      case 'Z':
+        VerifyRegisterType(register_line, get_reg, kRegTypeBoolean, failure);
+        actual_args++;
+        break;
+      case 'C':
+        VerifyRegisterType(register_line, get_reg, kRegTypeChar, failure);
+        actual_args++;
+        break;
+      case 'B':
+        VerifyRegisterType(register_line, get_reg, kRegTypeByte, failure);
+        actual_args++;
+        break;
+      case 'I':
+        VerifyRegisterType(register_line, get_reg, kRegTypeInteger, failure);
+        actual_args++;
+        break;
+      case 'S':
+        VerifyRegisterType(register_line, get_reg, kRegTypeShort, failure);
+        actual_args++;
+        break;
+      case 'F':
+        VerifyRegisterType(register_line, get_reg, kRegTypeFloat, failure);
+        actual_args++;
+        break;
+      case 'D':
+        VerifyRegisterType(register_line, get_reg, kRegTypeDoubleLo, failure);
+        actual_args += 2;
+        break;
+      case 'J':
+        VerifyRegisterType(register_line, get_reg, kRegTypeLongLo, failure);
+        actual_args += 2;
+        break;
+      default:
+        LOG(ERROR) << "VFY: invocation target: bad signature type char '"
+                   << sig << "'";
+        goto bad_sig;
+    }
+  }
+  if (sig[sig_offset] != ')') {
+    LOG(ERROR) << "VFY: invocation target: bad signature '"
+               << res_method->GetSignature()->ToModifiedUtf8() << "'";
+    goto bad_sig;
+  }
+
+  if (actual_args != expected_args) {
+    LOG(ERROR) << "VFY: expected " << expected_args << " args, found "
+               << actual_args;
+    goto bad_sig;
+  }
+
+  return res_method;
+
+bad_sig:
+  if (res_method != NULL) {
+    LOG(ERROR) << "VFY:  rejecting call to "
+               << res_method->GetDeclaringClass()->GetDescriptor()->ToModifiedUtf8()
+               << "." << res_method->GetName()->ToModifiedUtf8() << " "
+               << res_method->GetSignature()->ToModifiedUtf8();
+  }
+
+  if (*failure == VERIFY_ERROR_NONE)
+    *failure = VERIFY_ERROR_GENERIC;
+  return NULL;
+}
 
 }  // namespace art
diff --git a/src/dex_verifier.h b/src/dex_verifier.h
index e909b35..b6fbd46 100644
--- a/src/dex_verifier.h
+++ b/src/dex_verifier.h
@@ -10,31 +10,1488 @@
 
 namespace art {
 
-class DexVerify {
+#define kMaxMonitorStackDepth   (sizeof(MonitorEntries) * 8)
+
+/*
+ * Set this to enable dead code scanning.  This is not required, but it's
+ * very useful when testing changes to the verifier (to make sure we're not
+ * skipping over stuff). The only reason not to do it is that it slightly
+ * increases the time required to perform verification.
+ */
+#ifndef NDEBUG
+# define DEAD_CODE_SCAN  true
+#else
+# define DEAD_CODE_SCAN  false
+#endif
+
+/*
+ * We need an extra "pseudo register" to hold the return type briefly.  It
+ * can be category 1 or 2, so we need two slots.
+ */
+#define kExtraRegs  2
+#define RESULT_REGISTER(_insnRegCount)  (_insnRegCount)
+
+class DexVerifier {
  public:
-  enum {
-    kInsnFlagWidthMask = 0x0000ffff,
-    kInsnFlagInTry = (1 << 16),
+  /*
+   * RegType holds information about the type of data held in a register.
+   * For most types it's a simple enum.  For reference types it holds a
+   * pointer to the ClassObject, and for uninitialized references it holds
+   * an index into the UninitInstanceMap.
+   */
+  typedef uint32_t RegType;
+
+  /*
+   * A bit vector indicating which entries in the monitor stack are
+   * associated with this register.  The low bit corresponds to the stack's
+   * bottom-most entry.
+   */
+  typedef uint32_t MonitorEntries;
+
+  /*
+   * InsnFlags is a 32-bit integer with the following layout:
+   *   0-15  instruction length (or 0 if this address doesn't hold an opcode)
+   *  16-31  single bit flags:
+   *    InTry: in "try" block; exceptions thrown here may be caught locally
+   *    BranchTarget: other instructions can branch to this instruction
+   *    GcPoint: this instruction is a GC safe point
+   *    Visited: verifier has examined this instruction at least once
+   *    Changed: set/cleared as bytecode verifier runs
+   */
+  typedef uint32_t InsnFlags;
+
+  enum InsnFlag {
+    kInsnFlagWidthMask    = 0x0000ffff,
+    kInsnFlagInTry        = (1 << 16),
     kInsnFlagBranchTarget = (1 << 17),
-    kInsnFlagGcPoint = (1 << 18),
-    kInsnFlagVisited = (1 << 30),
-    kInsnFlagChanged = (1 << 31),
+    kInsnFlagGcPoint      = (1 << 18),
+    kInsnFlagVisited      = (1 << 30),
+    kInsnFlagChanged      = (1 << 31),
   };
 
+  /*
+   * "Direct" and "virtual" methods are stored independently.  The type of call
+   * used to invoke the method determines which list we search, and whether
+   * we travel up into superclasses.
+   *
+   * (<clinit>, <init>, and methods declared "private" or "static" are stored
+   * in the "direct" list.  All others are stored in the "virtual" list.)
+   */
+  enum MethodType {
+    METHOD_UNKNOWN  = 0,
+    METHOD_DIRECT,      // <init>, private
+    METHOD_STATIC,      // static
+    METHOD_VIRTUAL,     // virtual, super
+    METHOD_INTERFACE    // interface
+  };
+
+  /*
+   * We don't need to store the register data for many instructions, because
+   * we either only need it at branch points (for verification) or GC points
+   * and branches (for verification + type-precise register analysis).
+   */
+  enum RegisterTrackingMode {
+    kTrackRegsBranches,
+    kTrackRegsGcPoints,
+    kTrackRegsAll,
+  };
+
+  /*
+   * Enumeration for register type values.  The "hi" piece of a 64-bit value
+   * MUST immediately follow the "lo" piece in the enumeration, so we can check
+   * that hi==lo+1.
+   *
+   * Assignment of constants:
+   *   [-MAXINT,-32768)   : integer
+   *   [-32768,-128)      : short
+   *   [-128,0)           : byte
+   *   0                  : zero
+   *   1                  : one
+   *   [2,128)            : posbyte
+   *   [128,32768)        : posshort
+   *   [32768,65536)      : char
+   *   [65536,MAXINT]     : integer
+   *
+   * Allowed "implicit" widening conversions:
+   *   zero -> boolean, posbyte, byte, posshort, short, char, integer, ref (null)
+   *   one -> boolean, posbyte, byte, posshort, short, char, integer
+   *   boolean -> posbyte, byte, posshort, short, char, integer
+   *   posbyte -> posshort, short, integer, char
+   *   byte -> short, integer
+   *   posshort -> integer, char
+   *   short -> integer
+   *   char -> integer
+   *
+   * In addition, all of the above can convert to "float".
+   *
+   * We're more careful with integer values than the spec requires.  The
+   * motivation is to restrict byte/char/short to the correct range of values.
+   * For example, if a method takes a byte argument, we don't want to allow
+   * the code to load the constant "1024" and pass it in.
+   */
+  enum {
+    kRegTypeUnknown = 0,    /* initial state; use value=0 so calloc works */
+    kRegTypeUninit = 1,     /* MUST be odd to distinguish from pointer */
+    kRegTypeConflict,       /* merge clash makes this reg's type unknowable */
+
+    /*
+     * Category-1nr types.  The order of these is chiseled into a couple
+     * of tables, so don't add, remove, or reorder if you can avoid it.
+     */
+#define kRegType1nrSTART    kRegTypeZero
+    kRegTypeZero,           /* 32-bit 0, could be Boolean, Int, Float, or Ref */
+    kRegTypeOne,            /* 32-bit 1, could be Boolean, Int, Float */
+    kRegTypeBoolean,        /* must be 0 or 1 */
+    kRegTypeConstPosByte,   /* const derived byte, known positive */
+    kRegTypeConstByte,      /* const derived byte */
+    kRegTypeConstPosShort,  /* const derived short, known positive */
+    kRegTypeConstShort,     /* const derived short */
+    kRegTypeConstChar,      /* const derived char */
+    kRegTypeConstInteger,   /* const derived integer */
+    kRegTypePosByte,        /* byte, known positive (can become char) */
+    kRegTypeByte,
+    kRegTypePosShort,       /* short, known positive (can become char) */
+    kRegTypeShort,
+    kRegTypeChar,
+    kRegTypeInteger,
+    kRegTypeFloat,
+#define kRegType1nrEND      kRegTypeFloat
+    kRegTypeConstLo,        /* const derived wide, lower half */
+    kRegTypeConstHi,        /* const derived wide, upper half */
+    kRegTypeLongLo,         /* lower-numbered register; endian-independent */
+    kRegTypeLongHi,
+    kRegTypeDoubleLo,
+    kRegTypeDoubleHi,
+
+    /*
+     * Enumeration max; this is used with "full" (32-bit) RegType values.
+     *
+     * Anything larger than this is a ClassObject or uninit ref.  Mask off
+     * all but the low 8 bits; if you're left with kRegTypeUninit, pull
+     * the uninit index out of the high 24.  Because kRegTypeUninit has an
+     * odd value, there is no risk of a particular ClassObject pointer bit
+     * pattern being confused for it (assuming our class object allocator
+     * uses word alignment).
+     */
+    kRegTypeMAX
+  };
+#define kRegTypeUninitMask  0xff
+#define kRegTypeUninitShift 8
+
+  /*
+   * Register type categories, for type checking.
+   *
+   * The spec says category 1 includes boolean, byte, char, short, int, float,
+   * reference, and returnAddress.  Category 2 includes long and double.
+   *
+   * We treat object references separately, so we have "category1nr".  We
+   * don't support jsr/ret, so there is no "returnAddress" type.
+   */
+  enum TypeCategory {
+    kTypeCategoryUnknown = 0,
+    kTypeCategory1nr = 1,         // boolean, byte, char, short, int, float
+    kTypeCategory2 = 2,           // long, double
+    kTypeCategoryRef = 3,         // object reference
+  };
+
+  /* An enumeration of problems that can turn up during verification. */
+  enum VerifyError {
+    VERIFY_ERROR_NONE = 0,      /* no error; must be zero */
+    VERIFY_ERROR_GENERIC,       /* VerifyError */
+
+    VERIFY_ERROR_NO_CLASS,      /* NoClassDefFoundError */
+    VERIFY_ERROR_NO_FIELD,      /* NoSuchFieldError */
+    VERIFY_ERROR_NO_METHOD,     /* NoSuchMethodError */
+    VERIFY_ERROR_ACCESS_CLASS,  /* IllegalAccessError */
+    VERIFY_ERROR_ACCESS_FIELD,  /* IllegalAccessError */
+    VERIFY_ERROR_ACCESS_METHOD, /* IllegalAccessError */
+    VERIFY_ERROR_CLASS_CHANGE,  /* IncompatibleClassChangeError */
+    VERIFY_ERROR_INSTANTIATION, /* InstantiationError */
+  };
+
+  /*
+   * Identifies the type of reference in the instruction that generated the
+   * verify error (e.g. VERIFY_ERROR_ACCESS_CLASS could come from a method,
+   * field, or class reference).
+   *
+   * This must fit in two bits.
+   */
+  enum VerifyErrorRefType {
+    VERIFY_ERROR_REF_CLASS  = 0,
+    VERIFY_ERROR_REF_FIELD  = 1,
+    VERIFY_ERROR_REF_METHOD = 2,
+  };
+#define kVerifyErrorRefTypeShift 6
+
+  /*
+   * During verification, we associate one of these with every "interesting"
+   * instruction.  We track the status of all registers, and (if the method
+   * has any monitor-enter instructions) maintain a stack of entered monitors
+   * (identified by code unit offset).
+   *
+   * If live-precise register maps are enabled, the "liveRegs" vector will
+   * be populated.  Unlike the other lists of registers here, we do not
+   * track the liveness of the method result register (which is not visible
+   * to the GC).
+   */
+  struct RegisterLine {
+    RegType*        reg_types_;
+    MonitorEntries* monitor_entries_;
+    uint32_t*       monitor_stack_;
+    uint32_t        monitor_stack_top_;
+
+    /* Default constructor. */
+    RegisterLine() {
+      reg_types_ = NULL;
+      monitor_entries_ = NULL;
+      monitor_stack_ = NULL;
+      monitor_stack_top_ = 0;
+    }
+
+    /* Default destructor. */
+    ~RegisterLine() {
+      delete reg_types_;
+      delete monitor_entries_;
+      delete monitor_stack_;
+    }
+
+    /* Allocate space for the fields. */
+    void Alloc(size_t size, bool track_monitors) {
+      reg_types_ = new RegType[size]();
+      if (track_monitors) {
+        monitor_entries_ = new MonitorEntries[size];
+        monitor_stack_ = new uint32_t[kMaxMonitorStackDepth];
+      }
+    }
+  };
+
+  /* Big fat collection of register data. */
+  struct RegisterTable {
+    /*
+     * Array of RegisterLine structs, one per address in the method.  We only
+     * set the pointers for certain addresses, based on instruction widths
+     * and what we're trying to accomplish.
+     */
+    RegisterLine* register_lines_;
+
+    /*
+     * Number of registers we track for each instruction.  This is equal
+     * to the method's declared "registersSize" plus kExtraRegs (2).
+     */
+    size_t      insn_reg_count_plus_;
+
+    /* Storage for a register line we're currently working on. */
+    RegisterLine work_line_;
+
+    /* Storage for a register line we're saving for later. */
+    RegisterLine saved_line_;
+
+    /* Default constructor. */
+    RegisterTable() {
+      register_lines_ = NULL;
+      insn_reg_count_plus_ = 0;
+    }
+
+    /* Default destructor. */
+    ~RegisterTable() {
+      delete [] register_lines_;
+    }
+  };
+
+  /* Entries in the UninitInstanceMap. */
+  struct UninitInstanceMapEntry {
+    /* Code offset, or -1 for method arg ("this"). */
+    int addr_;
+
+    /* Class created at this address. */
+    Class* klass_;
+  };
+
+  /*
+   * Table that maps uninitialized instances to classes, based on the
+   * address of the new-instance instruction.  One per method.
+   */
+  struct UninitInstanceMap {
+    int num_entries_;
+    UninitInstanceMapEntry* map_;
+
+    /* Basic constructor */
+    UninitInstanceMap(int num_entries) {
+      num_entries_ = num_entries;
+      map_ = new UninitInstanceMapEntry[num_entries]();
+    }
+
+    /* Default destructor */
+    ~UninitInstanceMap() {
+      delete map_;
+    }
+  };
+  #define kUninitThisArgAddr  (-1)
+  #define kUninitThisArgSlot  0
+
+  /* Various bits of data used by the verifier and register map generator. */
+  struct VerifierData {
+    /* The method we're working on. */
+    Method* method_;
+
+    /* The dex file containing the method. */
+    const DexFile* dex_file_;
+
+    /* The code item containing the code for the method. */
+    const DexFile::CodeItem* code_item_;
+
+    /* Instruction widths and flags, one entry per code unit. */
+    InsnFlags* insn_flags_;
+
+    /*
+     * Uninitialized instance map, used for tracking the movement of
+     * objects that have been allocated but not initialized.
+     */
+    UninitInstanceMap* uninit_map_;
+
+    /*
+     * Array of RegisterLine structs, one entry per code unit.  We only need
+     * entries for code units that hold the start of an "interesting"
+     * instruction.  For register map generation, we're only interested
+     * in GC points.
+     */
+    RegisterLine* register_lines_;
+
+    /* The number of occurrences of specific opcodes. */
+    size_t new_instance_count_;
+    size_t monitor_enter_count_;
+
+    /* Basic constructor. */
+    VerifierData(Method* method, const DexFile* dex_file,
+        const DexFile::CodeItem* code_item)
+        : method_(method), dex_file_(dex_file), code_item_(code_item),
+          insn_flags_(NULL), uninit_map_(NULL), register_lines_(NULL),
+          new_instance_count_(0), monitor_enter_count_(0) { }
+  };
+
+  /*
+   * Merge result table for primitive values.  The table is symmetric along
+   * the diagonal.
+   *
+   * Note that 32-bit int/float do not merge into 64-bit long/double.  This
+   * is a register merge, not a widening conversion.  Only the "implicit"
+   * widening within a category, e.g. byte to short, is allowed.
+   *
+   * Dalvik does not draw a distinction between int and float, but we enforce
+   * that once a value is used as int, it can't be used as float, and vice
+   * versa. We do not allow free exchange between 32-bit int/float and 64-bit
+   * long/double.
+   *
+   * Note that Uninit+Uninit=Uninit.  This holds true because we only
+   * use this when the RegType value is exactly equal to kRegTypeUninit, which
+   * can only happen for the zeroeth entry in the table.
+   *
+   * "Unknown" never merges with anything known.  The only time a register
+   * transitions from "unknown" to "known" is when we're executing code
+   * for the first time, and we handle that with a simple copy.
+   */
+  static const char merge_table_[kRegTypeMAX][kRegTypeMAX];
+
+  /*
+   * Returns "true" if the flags indicate that this address holds the start
+   * of an instruction.
+   */
+  static inline bool InsnIsOpcode(const InsnFlags insn_flags[], int addr) {
+    return (insn_flags[addr] & kInsnFlagWidthMask) != 0;
+  }
+
+  /* Extract the unsigned 16-bit instruction width from "flags". */
+  static inline int InsnGetWidth(const InsnFlags insn_flags[], int addr) {
+    return insn_flags[addr] & kInsnFlagWidthMask;
+  }
+
+  /* Utilities to check and set kInsnFlagChanged. */
+  static inline bool InsnIsChanged(const InsnFlags insn_flags[], int addr) {
+    return (insn_flags[addr] & kInsnFlagChanged) != 0;
+  }
+  static inline void InsnSetChanged(InsnFlags insn_flags[], int addr,
+      bool changed) {
+    if (changed)
+      insn_flags[addr] |= kInsnFlagChanged;
+    else
+      insn_flags[addr] &= ~kInsnFlagChanged;
+  }
+
+  /* Utilities to check and set kInsnFlagVisited. */
+  static inline bool InsnIsVisited(const InsnFlags insn_flags[], int addr) {
+      return (insn_flags[addr] & kInsnFlagVisited) != 0;
+  }
+  static inline void InsnSetVisited(InsnFlags insn_flags[], int addr,
+      bool visited) {
+    if (visited)
+      insn_flags[addr] |= kInsnFlagVisited;
+    else
+      insn_flags[addr] &= ~kInsnFlagVisited;
+  }
+
+  static inline bool InsnIsVisitedOrChanged(const InsnFlags insn_flags[],
+      int addr) {
+    return (insn_flags[addr] & (kInsnFlagVisited |
+                                kInsnFlagChanged)) != 0;
+  }
+
+  /* Utilities to check and set kInsnFlagInTry. */
+  static inline bool InsnIsInTry(const InsnFlags insn_flags[], int addr) {
+    return (insn_flags[addr] & kInsnFlagInTry) != 0;
+  }
+  static inline void InsnSetInTry(InsnFlags insn_flags[], int addr) {
+    insn_flags[addr] |= kInsnFlagInTry;
+  }
+
+  /* Utilities to check and set kInsnFlagBranchTarget. */
+  static inline bool InsnIsBranchTarget(const InsnFlags insn_flags[], int addr)
+  {
+    return (insn_flags[addr] & kInsnFlagBranchTarget) != 0;
+  }
+  static inline void InsnSetBranchTarget(InsnFlags insn_flags[], int addr) {
+    insn_flags[addr] |= kInsnFlagBranchTarget;
+  }
+
+  /* Utilities to check and set kInsnFlagGcPoint. */
+  static inline bool InsnIsGcPoint(const InsnFlags insn_flags[], int addr) {
+    return (insn_flags[addr] & kInsnFlagGcPoint) != 0;
+  }
+  static inline void InsnSetGcPoint(InsnFlags insn_flags[], int addr) {
+    insn_flags[addr] |= kInsnFlagGcPoint;
+  }
+
+  /* Get the class object at the specified index. */
+  static inline Class* GetUninitInstance(const UninitInstanceMap* uninit_map,
+      int idx) {
+    assert(idx >= 0 && idx < uninit_map->num_entries_);
+    return uninit_map->map_[idx].klass_;
+  }
+
+  /* Determine if "type" is actually an object reference (init/uninit/zero) */
+  static inline bool RegTypeIsReference(RegType type) {
+    return (type > kRegTypeMAX || type == kRegTypeUninit ||
+            type == kRegTypeZero);
+  }
+
+  /* Determine if "type" is an uninitialized object reference */
+  static inline bool RegTypeIsUninitReference(RegType type) {
+    return ((type & kRegTypeUninitMask) == kRegTypeUninit);
+  }
+
+  /*
+   * Convert the initialized reference "type" to a Class pointer
+   * (does not expect uninit ref types or "zero").
+   */
+  static Class* RegTypeInitializedReferenceToClass(RegType type) {
+    assert(RegTypeIsReference(type) && type != kRegTypeZero);
+    if ((type & 0x01) == 0) {
+      return (Class*) type;
+    } else {
+      LOG(ERROR) << "VFY: attempted to use uninitialized reference";
+      return NULL;
+    }
+  }
+
+  /* Extract the index into the uninitialized instance map table. */
+  static inline int RegTypeToUninitIndex(RegType type) {
+    assert(RegTypeIsUninitReference(type));
+    return (type & ~kRegTypeUninitMask) >> kRegTypeUninitShift;
+  }
+
+  /* Convert the reference "type" to a Class pointer. */
+  static Class* RegTypeReferenceToClass(RegType type,
+      const UninitInstanceMap* uninit_map) {
+    assert(RegTypeIsReference(type) && type != kRegTypeZero);
+    if (RegTypeIsUninitReference(type)) {
+      assert(uninit_map != NULL);
+      return GetUninitInstance(uninit_map, RegTypeToUninitIndex(type));
+    } else {
+        return (Class*) type;
+    }
+  }
+
+  /* Convert the ClassObject pointer to an (initialized) register type. */
+  static inline RegType RegTypeFromClass(Class* klass) {
+    return (uint32_t) klass;
+  }
+
+  /* Return the RegType for the uninitialized reference in slot "uidx". */
+  static inline RegType RegTypeFromUninitIndex(int uidx) {
+    return (uint32_t) (kRegTypeUninit | (uidx << kRegTypeUninitShift));
+  }
+
+  /* Verify a class. Returns "true" on success. */
   static bool VerifyClass(Class* klass);
 
  private:
+  /*
+   * Perform verification on a single method.
+   *
+   * We do this in three passes:
+   *  (1) Walk through all code units, determining instruction locations,
+   *      widths, and other characteristics.
+   *  (2) Walk through all code units, performing static checks on
+   *      operands.
+   *  (3) Iterate through the method, checking type safety and looking
+   *      for code flow problems.
+   *
+   * Some checks may be bypassed depending on the verification mode.  We can't
+   * turn this stuff off completely if we want to do "exact" GC.
+   *
+   * Confirmed here:
+   * - code array must not be empty
+   * Confirmed by ComputeWidthsAndCountOps():
+   * - opcode of first instruction begins at index 0
+   * - only documented instructions may appear
+   * - each instruction follows the last
+   * - last byte of last instruction is at (code_length-1)
+   */
   static bool VerifyMethod(Method* method);
-  static bool VerifyInstructions(const DexFile* dex_file,
-                                 const DexFile::CodeItem* code_item,
-                                 uint32_t insn_flags[]);
-  static bool VerifyInstruction(const DexFile* dex_file,
-                                const Instruction* inst,
-                                uint32_t code_offset,
-                                const DexFile::CodeItem* code_item,
-                                uint32_t insn_flags[]);
 
-  DISALLOW_COPY_AND_ASSIGN(DexVerify);
+  /*
+   * Perform static verification on all instructions in a method.
+   *
+   * Walks through instructions in a method calling VerifyInstruction on each.
+   */
+  static bool VerifyInstructions(VerifierData* vdata);
+
+  /*
+   * Perform static verification on an instruction.
+   *
+   * As a side effect, this sets the "branch target" flags in InsnFlags.
+   *
+   * "(CF)" items are handled during code-flow analysis.
+   *
+   * v3 4.10.1
+   * - target of each jump and branch instruction must be valid
+   * - targets of switch statements must be valid
+   * - operands referencing constant pool entries must be valid
+   * - (CF) operands of getfield, putfield, getstatic, putstatic must be valid
+   * - (CF) operands of method invocation instructions must be valid
+   * - (CF) only invoke-direct can call a method starting with '<'
+   * - (CF) <clinit> must never be called explicitly
+   * - operands of instanceof, checkcast, new (and variants) must be valid
+   * - new-array[-type] limited to 255 dimensions
+   * - can't use "new" on an array class
+   * - (?) limit dimensions in multi-array creation
+   * - local variable load/store register values must be in valid range
+   *
+   * v3 4.11.1.2
+   * - branches must be within the bounds of the code array
+   * - targets of all control-flow instructions are the start of an instruction
+   * - register accesses fall within range of allocated registers
+   * - (N/A) access to constant pool must be of appropriate type
+   * - code does not end in the middle of an instruction
+   * - execution cannot fall off the end of the code
+   * - (earlier) for each exception handler, the "try" area must begin and
+   *   end at the start of an instruction (end can be at the end of the code)
+   * - (earlier) for each exception handler, the handler must start at a valid
+   *   instruction
+   */
+  static bool VerifyInstruction(VerifierData* vdata,
+      const Instruction* inst, uint32_t code_offset);
+
+  /* Perform detailed code-flow analysis on a single method. */
+  static bool VerifyCodeFlow(VerifierData* vdata);
+
+  /*
+   * Compute the width of the instruction at each address in the instruction
+   * stream, and store it in vdata->insn_flags.  Addresses that are in the
+   * middle of an instruction, or that are part of switch table data, are not
+   * touched (so the caller should probably initialize "insn_flags" to zero).
+   *
+   * The "new_instance_count_" and "monitor_enter_count_" fields in vdata are
+   * also set.
+   *
+   * Performs some static checks, notably:
+   * - opcode of first instruction begins at index 0
+   * - only documented instructions may appear
+   * - each instruction follows the last
+   * - last byte of last instruction is at (code_length-1)
+   *
+   * Logs an error and returns "false" on failure.
+   */
+  static bool ComputeWidthsAndCountOps(VerifierData* vdata);
+
+  /*
+   * Set the "in try" flags for all instructions protected by "try" statements.
+   * Also sets the "branch target" flags for exception handlers.
+   *
+   * Call this after widths have been set in "insn_flags".
+   *
+   * Returns "false" if something in the exception table looks fishy, but
+   * we're expecting the exception table to be somewhat sane.
+   */
+  static bool ScanTryCatchBlocks(VerifierData* vdata);
+
+  /*
+   * Extract the relative offset from a branch instruction.
+   *
+   * Returns "false" on failure (e.g. this isn't a branch instruction).
+   */
+  static bool GetBranchOffset(const DexFile::CodeItem* code_item,
+      const InsnFlags insn_flags[], uint32_t cur_offset, int32_t* pOffset,
+      bool* pConditional, bool* selfOkay);
+
+  /*
+   * Verify an array data table.  "cur_offset" is the offset of the
+   * fill-array-data instruction.
+   */
+  static bool CheckArrayData(const DexFile::CodeItem* code_item,
+      uint32_t cur_offset);
+
+  /*
+   * Perform static checks on a "new-instance" instruction.  Specifically,
+   * make sure the class reference isn't for an array class.
+   *
+   * We don't need the actual class, just a pointer to the class name.
+   */
+  static bool CheckNewInstance(const DexFile* dex_file, uint32_t idx);
+
+  /*
+   * Perform static checks on a "new-array" instruction.  Specifically, make
+   * sure they aren't creating an array of arrays that causes the number of
+   * dimensions to exceed 255.
+   */
+  static bool CheckNewArray(const DexFile* dex_file, uint32_t idx);
+
+  /*
+   * Perform static checks on an instruction that takes a class constant.
+   * Ensure that the class index is in the valid range.
+   */
+  static bool CheckTypeIndex(const DexFile* dex_file, uint32_t idx);
+
+  /*
+   * Perform static checks on a field get or set instruction.  All we do
+   * here is ensure that the field index is in the valid range.
+   */
+  static bool CheckFieldIndex(const DexFile* dex_file, uint32_t idx);
+
+  /*
+   * Perform static checks on a method invocation instruction.  All we do
+   * here is ensure that the method index is in the valid range.
+   */
+  static bool CheckMethodIndex(const DexFile* dex_file, uint32_t idx);
+
+  /* Ensure that the string index is in the valid range. */
+  static bool CheckStringIndex(const DexFile* dex_file, uint32_t idx);
+
+  /* Ensure that the register index is valid for this code item. */
+  static bool CheckRegisterIndex(const DexFile::CodeItem* code_item,
+      uint32_t idx);
+
+  /* Ensure that the wide register index is valid for this code item. */
+  static bool CheckWideRegisterIndex(const DexFile::CodeItem* code_item,
+      uint32_t idx);
+
+  /*
+   * Check the register indices used in a "vararg" instruction, such as
+   * invoke-virtual or filled-new-array.
+   *
+   * vA holds word count (0-5), args[] have values.
+   *
+   * There are some tests we don't do here, e.g. we don't try to verify
+   * that invoking a method that takes a double is done with consecutive
+   * registers.  This requires parsing the target method signature, which
+   * we will be doing later on during the code flow analysis.
+   */
+  static bool CheckVarArgRegs(const DexFile::CodeItem* code_item, uint32_t vA,
+      uint32_t arg[]);
+
+  /*
+   * Check the register indices used in a "vararg/range" instruction, such as
+   * invoke-virtual/range or filled-new-array/range.
+   *
+   * vA holds word count, vC holds index of first reg.
+   */
+  static bool CheckVarArgRangeRegs(const DexFile::CodeItem* code_item,
+      uint32_t vA, uint32_t vC);
+
+  /*
+   * Verify a switch table. "cur_offset" is the offset of the switch
+   * instruction.
+   *
+   * Updates "insnFlags", setting the "branch target" flag.
+   */
+  static bool CheckSwitchTargets(const DexFile::CodeItem* code_item,
+      InsnFlags insn_flags[], uint32_t cur_offset);
+
+  /*
+   * Verify that the target of a branch instruction is valid.
+   *
+   * We don't expect code to jump directly into an exception handler, but
+   * it's valid to do so as long as the target isn't a "move-exception"
+   * instruction.  We verify that in a later stage.
+   *
+   * The dex format forbids certain instructions from branching to itself.
+   *
+   * Updates "insnFlags", setting the "branch target" flag.
+   */
+  static bool CheckBranchTarget(const DexFile::CodeItem* code_item,
+      InsnFlags insn_flags[], uint32_t cur_offset);
+
+  /*
+   * Initialize the RegisterTable.
+   *
+   * Every instruction address can have a different set of information about
+   * what's in which register, but for verification purposes we only need to
+   * store it at branch target addresses (because we merge into that).
+   *
+   * By zeroing out the regType storage we are effectively initializing the
+   * register information to kRegTypeUnknown.
+   *
+   * We jump through some hoops here to minimize the total number of
+   * allocations we have to perform per method verified.
+   */
+  static bool InitRegisterTable(VerifierData* vdata, RegisterTable* reg_table,
+      RegisterTrackingMode track_regs_for);
+
+  /* Get the register line for the given instruction in the current method. */
+  static inline RegisterLine* GetRegisterLine(const RegisterTable* reg_table,
+      int insn_idx) {
+    return &reg_table->register_lines_[insn_idx];
+  }
+
+  /* Copy a register line. */
+  static inline void CopyRegisterLine(RegisterLine* dst,
+      const RegisterLine* src, size_t num_regs) {
+    memcpy(dst->reg_types_, src->reg_types_, num_regs * sizeof(RegType));
+
+    assert((src->monitor_entries_ == NULL && dst->monitor_entries_ == NULL) ||
+           (src->monitor_entries_ != NULL && dst->monitor_entries_ != NULL));
+    if (dst->monitor_entries_ != NULL) {
+      assert(dst->monitor_stack_ != NULL);
+      memcpy(dst->monitor_entries_, src->monitor_entries_,
+          num_regs * sizeof(MonitorEntries));
+      memcpy(dst->monitor_stack_, src->monitor_stack_,
+          kMaxMonitorStackDepth * sizeof(uint32_t));
+      dst->monitor_stack_top_ = src->monitor_stack_top_;
+    }
+  }
+
+  /* Copy a register line into the table. */
+  static inline void CopyLineToTable(RegisterTable* reg_table, int insn_idx,
+      const RegisterLine* src) {
+    RegisterLine* dst = GetRegisterLine(reg_table, insn_idx);
+    assert(dst->reg_types_ != NULL);
+    CopyRegisterLine(dst, src, reg_table->insn_reg_count_plus_);
+  }
+
+  /* Copy a register line out of the table. */
+  static inline void CopyLineFromTable(RegisterLine* dst,
+      const RegisterTable* reg_table, int insn_idx) {
+    RegisterLine* src = GetRegisterLine(reg_table, insn_idx);
+    assert(src->reg_types_ != NULL);
+    CopyRegisterLine(dst, src, reg_table->insn_reg_count_plus_);
+  }
+
+#ifndef NDEBUG
+  /*
+   * Compare two register lines.  Returns 0 if they match.
+   *
+   * Using this for a sort is unwise, since the value can change based on
+   * machine endianness.
+   */
+  static inline int CompareLineToTable(const RegisterTable* reg_table,
+      int insn_idx, const RegisterLine* line2) {
+    const RegisterLine* line1 = GetRegisterLine(reg_table, insn_idx);
+    if (line1->monitor_entries_ != NULL) {
+      int result;
+
+      if (line2->monitor_entries_ == NULL)
+        return 1;
+      result = memcmp(line1->monitor_entries_, line2->monitor_entries_,
+          reg_table->insn_reg_count_plus_ * sizeof(MonitorEntries));
+      if (result != 0) {
+        LOG(ERROR) << "monitor_entries_ mismatch";
+        return result;
+      }
+      result = line1->monitor_stack_top_ - line2->monitor_stack_top_;
+      if (result != 0) {
+        LOG(ERROR) << "monitor_stack_top_ mismatch";
+        return result;
+      }
+      result = memcmp(line1->monitor_stack_, line2->monitor_stack_,
+            line1->monitor_stack_top_);
+      if (result != 0) {
+        LOG(ERROR) << "monitor_stack_ mismatch";
+        return result;
+      }
+    }
+    return memcmp(line1->reg_types_, line2->reg_types_,
+        reg_table->insn_reg_count_plus_ * sizeof(RegType));
+  }
+#endif
+
+  /*
+   * Create a new uninitialized instance map.
+   *
+   * The map is allocated and populated with address entries.  The addresses
+   * appear in ascending order to allow binary searching.
+   *
+   * Very few methods have 10 or more new-instance instructions; the
+   * majority have 0 or 1.  Occasionally a static initializer will have 200+.
+   *
+   * TODO: merge this into the static pass or initRegisterTable; want to
+   * avoid walking through the instructions yet again just to set up this table
+   */
+  static UninitInstanceMap* CreateUninitInstanceMap(VerifierData* vdata);
+
+  /* Returns true if this method is a constructor. */
+  static bool IsInitMethod(const Method* method);
+
+  /*
+   * Look up a class reference given as a simple string descriptor.
+   *
+   * If we can't find it, return a generic substitute when possible.
+   */
+  static Class* LookupClassByDescriptor(const Method* method,
+      const char* descriptor, VerifyError* failure);
+
+  /*
+   * Look up a class reference in a signature.  Could be an arg or the
+   * return value.
+   *
+   * Advances "*sig" to the last character in the signature (that is, to
+   * the ';').
+   *
+   * NOTE: this is also expected to verify the signature.
+   */
+  static Class* LookupSignatureClass(const Method* method, std::string sig,
+      VerifyError* failure);
+
+  /*
+   * Look up an array class reference in a signature.  Could be an arg or the
+   * return value.
+   *
+   * Advances "*sig" to the last character in the signature.
+   *
+   * NOTE: this is also expected to verify the signature.
+   */
+  static Class* LookupSignatureArrayClass(const Method* method,
+      std::string sig, VerifyError* failure);
+
+  /*
+   * Set the register types for the first instruction in the method based on
+   * the method signature.
+   *
+   * This has the side-effect of validating the signature.
+   *
+   * Returns "true" on success.
+   */
+  static bool SetTypesFromSignature(VerifierData* vdata, RegType* reg_types);
+
+  /*
+   * Set the class object associated with the instruction at "addr".
+   *
+   * Returns the map slot index, or -1 if the address isn't listed in the map
+   * (shouldn't happen) or if a class is already associated with the address
+   * (bad bytecode).
+   *
+   * Entries, once set, do not change -- a given address can only allocate
+   * one type of object.
+   */
+  static int SetUninitInstance(UninitInstanceMap* uninit_map, int addr,
+      Class* klass);
+
+  /*
+   * Perform code flow on a method.
+   *
+   * The basic strategy is as outlined in v3 4.11.1.2: set the "changed" bit
+   * on the first instruction, process it (setting additional "changed" bits),
+   * and repeat until there are no more.
+   *
+   * v3 4.11.1.1
+   * - (N/A) operand stack is always the same size
+   * - operand stack [registers] contain the correct types of values
+   * - local variables [registers] contain the correct types of values
+   * - methods are invoked with the appropriate arguments
+   * - fields are assigned using values of appropriate types
+   * - opcodes have the correct type values in operand registers
+   * - there is never an uninitialized class instance in a local variable in
+   *   code protected by an exception handler (operand stack is okay, because
+   *   the operand stack is discarded when an exception is thrown) [can't
+   *   know what's a local var w/o the debug info -- should fall out of
+   *   register typing]
+   *
+   * v3 4.11.1.2
+   * - execution cannot fall off the end of the code
+   *
+   * (We also do many of the items described in the "static checks" sections,
+   * because it's easier to do them here.)
+   *
+   * We need an array of RegType values, one per register, for every
+   * instruction.  If the method uses monitor-enter, we need extra data
+   * for every register, and a stack for every "interesting" instruction.
+   * In theory this could become quite large -- up to several megabytes for
+   * a monster function.
+   *
+   * NOTE:
+   * The spec forbids backward branches when there's an uninitialized reference
+   * in a register.  The idea is to prevent something like this:
+   *   loop:
+   *     move r1, r0
+   *     new-instance r0, MyClass
+   *     ...
+   *     if-eq rN, loop  // once
+   *   initialize r0
+   *
+   * This leaves us with two different instances, both allocated by the
+   * same instruction, but only one is initialized.  The scheme outlined in
+   * v3 4.11.1.4 wouldn't catch this, so they work around it by preventing
+   * backward branches.  We achieve identical results without restricting
+   * code reordering by specifying that you can't execute the new-instance
+   * instruction if a register contains an uninitialized instance created
+   * by that same instrutcion.
+   */
+  static bool CodeFlowVerifyMethod(VerifierData* vdata,
+      RegisterTable* reg_table);
+
+  /*
+   * Perform verification for a single instruction.
+   *
+   * This requires fully decoding the instruction to determine the effect
+   * it has on registers.
+   *
+   * Finds zero or more following instructions and sets the "changed" flag
+   * if execution at that point needs to be (re-)evaluated.  Register changes
+   * are merged into "reg_types_" at the target addresses.  Does not set or
+   * clear any other flags in "insn_flags".
+   */
+  static bool CodeFlowVerifyInstruction(VerifierData* vdata,
+      RegisterTable* reg_table, uint32_t insn_idx, size_t* start_guess);
+
+  /*
+   * Replace an instruction with "throw-verification-error".  This allows us to
+   * defer error reporting until the code path is first used.
+   *
+   * This is expected to be called during "just in time" verification, not
+   * from within dexopt.  (Verification failures in dexopt will result in
+   * postponement of verification to first use of the class.)
+   *
+   * The throw-verification-error instruction requires two code units.  Some
+   * of the replaced instructions require three; the third code unit will
+   * receive a "nop".  The instruction's length will be left unchanged
+   * in "insn_flags".
+   *
+   * The VM postpones setting of debugger breakpoints in unverified classes,
+   * so there should be no clashes with the debugger.
+   *
+   * Returns "true" on success.
+   */
+  static bool ReplaceFailingInstruction(const DexFile::CodeItem* code_item,
+      InsnFlags* insn_flags, int insn_idx, VerifyError failure);
+
+  /* Handle a monitor-enter instruction. */
+  static void HandleMonitorEnter(RegisterLine* work_line, uint32_t reg_idx,
+      uint32_t insn_idx, VerifyError* failure);
+
+  /* Handle a monitor-exit instruction. */
+  static void HandleMonitorExit(RegisterLine* work_line, uint32_t reg_idx,
+      uint32_t insn_idx, VerifyError* failure);
+
+  /*
+   * Look up an instance field, specified by "field_idx", that is going to be
+   * accessed in object "obj_type".  This resolves the field and then verifies
+   * that the class containing the field is an instance of the reference in
+   * "obj_type".
+   *
+   * It is possible for "obj_type" to be kRegTypeZero, meaning that we might
+   * have a null reference.  This is a runtime problem, so we allow it,
+   * skipping some of the type checks.
+   *
+   * In general, "obj_type" must be an initialized reference.  However, we
+   * allow it to be uninitialized if this is an "<init>" method and the field
+   * is declared within the "obj_type" class.
+   *
+   * Returns a Field on success, returns NULL and sets "*failure" on failure.
+   */
+  static Field* GetInstField(VerifierData* vdata, RegType obj_type,
+      int field_idx, VerifyError* failure);
+
+  /*
+   * Look up a static field.
+   *
+   * Returns a StaticField on success, returns NULL and sets "*failure"
+   * on failure.
+   */
+  static Field* GetStaticField(VerifierData* vdata, int field_idx,
+      VerifyError* failure);
+  /*
+   * For the "move-exception" instruction at "insn_idx", which must be at an
+   * exception handler address, determine the first common superclass of
+   * all exceptions that can land here.  (For javac output, we're probably
+   * looking at multiple spans of bytecode covered by one "try" that lands
+   * at an exception-specific "catch", but in general the handler could be
+   * shared for multiple exceptions.)
+   *
+   * Returns NULL if no matching exception handler can be found, or if the
+   * exception is not a subclass of Throwable.
+   */
+  static Class* GetCaughtExceptionType(VerifierData* vdata, int insn_idx,
+      VerifyError* failure);
+
+  /*
+   * Get the type of register N.
+   *
+   * The register index was validated during the static pass, so we don't
+   * need to check it here.
+   */
+  static inline RegType GetRegisterType(const RegisterLine* register_line,
+      uint32_t vsrc) {
+    return register_line->reg_types_[vsrc];
+  }
+
+  /*
+   * Return the register type for the method.  We can't just use the
+   * already-computed DalvikJniReturnType, because if it's a reference type
+   * we need to do the class lookup.
+   *
+   * Returned references are assumed to be initialized.
+   *
+   * Returns kRegTypeUnknown for "void".
+   */
+  static RegType GetMethodReturnType(const DexFile* dex_file,
+      const Method* method);
+
+  /*
+   * Get the value from a register, and cast it to a Class.  Sets
+   * "*failure" if something fails.
+   *
+   * This fails if the register holds an uninitialized class.
+   *
+   * If the register holds kRegTypeZero, this returns a NULL pointer.
+   */
+  static Class* GetClassFromRegister(const RegisterLine* register_line,
+      uint32_t vsrc, VerifyError* failure);
+
+  /*
+   * Get the "this" pointer from a non-static method invocation.  This
+   * returns the RegType so the caller can decide whether it needs the
+   * reference to be initialized or not.  (Can also return kRegTypeZero
+   * if the reference can only be zero at this point.)
+   *
+   * The argument count is in vA, and the first argument is in vC, for both
+   * "simple" and "range" versions.  We just need to make sure vA is >= 1
+   * and then return vC.
+   */
+  static RegType GetInvocationThis(const RegisterLine* register_line,
+      const Instruction::DecodedInstruction* dec_insn, VerifyError* failure);
+
+  /*
+   * Set the type of register N, verifying that the register is valid.  If
+   * "new_type" is the "Lo" part of a 64-bit value, register N+1 will be
+   * set to "new_type+1".
+   *
+   * The register index was validated during the static pass, so we don't
+   * need to check it here.
+   *
+   * TODO: clear mon stack bits
+   */
+  static void SetRegisterType(RegisterLine* register_line, uint32_t vdst,
+      RegType new_type);
+
+  /*
+   * Verify that the contents of the specified register have the specified
+   * type (or can be converted to it through an implicit widening conversion).
+   *
+   * This will modify the type of the source register if it was originally
+   * derived from a constant to prevent mixing of int/float and long/double.
+   *
+   * If "vsrc" is a reference, both it and the "vsrc" register must be
+   * initialized ("vsrc" may be Zero).  This will verify that the value in
+   * the register is an instance of check_type, or if check_type is an
+   * interface, verify that the register implements check_type.
+   */
+  static void VerifyRegisterType(RegisterLine* register_line, uint32_t vsrc,
+      RegType check_type, VerifyError* failure);
+
+  /* Set the type of the "result" register. */
+  static void SetResultRegisterType(RegisterLine* register_line,
+      const int insn_reg_count, RegType new_type);
+
+  /*
+   * Update all registers holding "uninit_type" to instead hold the
+   * corresponding initialized reference type.  This is called when an
+   * appropriate <init> method is invoked -- all copies of the reference
+   * must be marked as initialized.
+   */
+  static void MarkRefsAsInitialized(RegisterLine* register_line,
+      int insn_reg_count, UninitInstanceMap* uninit_map, RegType uninit_type,
+      VerifyError* failure);
+
+  /*
+   * Implement category-1 "move" instructions.  Copy a 32-bit value from
+   * "vsrc" to "vdst".
+   */
+  static void CopyRegister1(RegisterLine* register_line, uint32_t vdst,
+      uint32_t vsrc, TypeCategory cat, VerifyError* failure);
+
+  /*
+   * Implement category-2 "move" instructions.  Copy a 64-bit value from
+   * "vsrc" to "vdst".  This copies both halves of the register.
+   */
+  static void CopyRegister2(RegisterLine* register_line, uint32_t vdst,
+      uint32_t vsrc, VerifyError* failure);
+
+  /*
+   * Implement "move-result".  Copy the category-1 value from the result
+   * register to another register, and reset the result register.
+   */
+  static void CopyResultRegister1(RegisterLine* register_line,
+      const int insn_reg_count, uint32_t vdst, TypeCategory cat,
+      VerifyError* failure);
+
+  /*
+   * Implement "move-result-wide".  Copy the category-2 value from the result
+   * register to another register, and reset the result register.
+   */
+  static void CopyResultRegister2(RegisterLine* register_line,
+      const int insn_reg_count, uint32_t vdst, VerifyError* failure);
+
+  /*
+   * Compute the "class depth" of a class.  This is the distance from the
+   * class to the top of the tree, chasing superclass links.  java.lang.Object
+   * has a class depth of 0.
+   */
+  static int GetClassDepth(Class* klass);
+
+  /*
+   * Given two classes, walk up the superclass tree to find a common
+   * ancestor.  (Called from findCommonSuperclass().)
+   *
+   * TODO: consider caching the class depth in the class object so we don't
+   * have to search for it here.
+   */
+  static Class* DigForSuperclass(Class* c1, Class* c2);
+
+  /*
+   * Merge two array classes.  We can't use the general "walk up to the
+   * superclass" merge because the superclass of an array is always Object.
+   * We want String[] + Integer[] = Object[].  This works for higher dimensions
+   * as well, e.g. String[][] + Integer[][] = Object[][].
+   *
+   * If Foo1 and Foo2 are subclasses of Foo, Foo1[] + Foo2[] = Foo[].
+   *
+   * If Class implements Type, Class[] + Type[] = Type[].
+   *
+   * If the dimensions don't match, we want to convert to an array of Object
+   * with the least dimension, e.g. String[][] + String[][][][] = Object[][].
+   *
+   * Arrays of primitive types effectively have one less dimension when
+   * merging.  int[] + float[] = Object, int[] + String[] = Object,
+   * int[][] + float[][] = Object[], int[][] + String[] = Object[].  (The
+   * only time this function doesn't return an array class is when one of
+   * the arguments is a 1-dimensional primitive array.)
+   *
+   * This gets a little awkward because we may have to ask the VM to create
+   * a new array type with the appropriate element and dimensions.  However, we
+   * shouldn't be doing this often.
+   */
+  static Class* FindCommonArraySuperclass(Class* c1, Class* c2);
+
+  /*
+   * Find the first common superclass of the two classes.  We're not
+   * interested in common interfaces.
+   *
+   * The easiest way to do this for concrete classes is to compute the "class
+   * depth" of each, move up toward the root of the deepest one until they're
+   * at the same depth, then walk both up to the root until they match.
+   *
+   * If both classes are arrays, we need to merge based on array depth and
+   * element type.
+   *
+   * If one class is an interface, we check to see if the other class/interface
+   * (or one of its predecessors) implements the interface.  If so, we return
+   * the interface; otherwise, we return Object.
+   *
+   * NOTE: we continue the tradition of "lazy interface handling".  To wit,
+   * suppose we have three classes:
+   *   One implements Fancy, Free
+   *   Two implements Fancy, Free
+   *   Three implements Free
+   * where Fancy and Free are unrelated interfaces.  The code requires us
+   * to merge One into Two.  Ideally we'd use a common interface, which
+   * gives us a choice between Fancy and Free, and no guidance on which to
+   * use.  If we use Free, we'll be okay when Three gets merged in, but if
+   * we choose Fancy, we're hosed.  The "ideal" solution is to create a
+   * set of common interfaces and carry that around, merging further references
+   * into it.  This is a pain.  The easy solution is to simply boil them
+   * down to Objects and let the runtime invokeinterface call fail, which
+   * is what we do.
+   */
+  static Class* FindCommonSuperclass(Class* c1, Class* c2);
+
+  /*
+   * Merge two RegType values.
+   *
+   * Sets "*changed" to "true" if the result doesn't match "type1".
+   */
+  static RegType MergeTypes(RegType type1, RegType type2, bool* changed);
+
+  /*
+   * Merge the bits that indicate which monitor entry addresses on the stack
+   * are associated with this register.
+   *
+   * The merge is a simple bitwise AND.
+   *
+   * Sets "*pChanged" to "true" if the result doesn't match "ents1".
+   */
+  static MonitorEntries MergeMonitorEntries(MonitorEntries ents1,
+      MonitorEntries ents2, bool* changed);
+
+  /*
+   * We're creating a new instance of class C at address A.  Any registers
+   * holding instances previously created at address A must be initialized
+   * by now.  If not, we mark them as "conflict" to prevent them from being
+   * used (otherwise, MarkRefsAsInitialized would mark the old ones and the
+   * new ones at the same time).
+   */
+  static void MarkUninitRefsAsInvalid(RegisterLine* register_line,
+      int insn_reg_count, UninitInstanceMap* uninit_map, RegType uninit_type);
+
+  /*
+   * Control can transfer to "next_insn".
+   *
+   * Merge the registers from "work_line" into "reg_table" at "next_insn", and
+   * set the "changed" flag on the target address if any of the registers
+   * has changed.
+   *
+   * Returns "false" if we detect mismatched monitor stacks.
+   */
+  static bool UpdateRegisters(InsnFlags* insn_flags, RegisterTable* reg_table,
+      int next_insn, const RegisterLine* work_line);
+
+  /*
+   * Determine whether we can convert "src_type" to "check_type", where
+   * "check_type" is one of the category-1 non-reference types.
+   *
+   * Constant derived types may become floats, but other values may not.
+   */
+  static bool CanConvertTo1nr(RegType src_type, RegType check_type);
+
+  /* Determine whether the category-2 types are compatible. */
+  static bool CanConvertTo2(RegType src_type, RegType check_type);
+
+  /* Convert a VM PrimitiveType enum value to the equivalent RegType value. */
+  static RegType PrimitiveTypeToRegType(Class::PrimitiveType prim_type);
+
+  /*
+   * Convert a const derived RegType to the equivalent non-const RegType value.
+   * Does nothing if the argument type isn't const derived.
+   */
+  static RegType ConstTypeToRegType(RegType const_type);
+
+  /*
+   * Given a 32-bit constant, return the most-restricted RegType enum entry
+   * that can hold the value. The types used here indicate the value came
+   * from a const instruction, and may not correctly represent the real type
+   * of the value. Upon use, a constant derived type is updated with the
+   * type from the use, which will be unambiguous.
+   */
+  static char DetermineCat1Const(int32_t value);
+
+  /*
+   * If "field" is marked "final", make sure this is the either <clinit>
+   * or <init> as appropriate.
+   *
+   * Sets "*failure" on failure.
+   */
+  static void CheckFinalFieldAccess(const Method* method, const Field* field,
+      VerifyError* failure);
+
+  /*
+   * Make sure that the register type is suitable for use as an array index.
+   *
+   * Sets "*failure" if not.
+   */
+  static void CheckArrayIndexType(const Method* method, RegType reg_type,
+      VerifyError* failure);
+
+  /*
+   * Check constraints on constructor return.  Specifically, make sure that
+   * the "this" argument got initialized.
+   *
+   * The "this" argument to <init> uses code offset kUninitThisArgAddr, which
+   * puts it at the start of the list in slot 0.  If we see a register with
+   * an uninitialized slot 0 reference, we know it somehow didn't get
+   * initialized.
+   *
+   * Returns "true" if all is well.
+   */
+  static bool CheckConstructorReturn(const Method* method,
+      const RegisterLine* register_line, const int insn_reg_count);
+
+  /*
+   * Verify that the target instruction is not "move-exception".  It's important
+   * that the only way to execute a move-exception is as the first instruction
+   * of an exception handler.
+   *
+   * Returns "true" if all is well, "false" if the target instruction is
+   * move-exception.
+   */
+  static bool CheckMoveException(const uint16_t* insns, int insn_idx);
+
+  /*
+   * See if "type" matches "cat".  All we're really looking for here is that
+   * we're not mixing and matching 32-bit and 64-bit quantities, and we're
+   * not mixing references with numerics.  (For example, the arguments to
+   * "a < b" could be integers of different sizes, but they must both be
+   * integers.  Dalvik is less specific about int vs. float, so we treat them
+   * as equivalent here.)
+   *
+   * For category 2 values, "type" must be the "low" half of the value.
+   *
+   * Sets "*failure" if something looks wrong.
+   */
+  static void CheckTypeCategory(RegType type, TypeCategory cat,
+      VerifyError* failure);
+
+  /*
+   * For a category 2 register pair, verify that "type_h" is the appropriate
+   * high part for "type_l".
+   *
+   * Does not verify that "type_l" is in fact the low part of a 64-bit
+   * register pair.
+   */
+  static void CheckWidePair(RegType type_l, RegType type_h,
+      VerifyError* failure);
+
+  /*
+   * Verify types for a simple two-register instruction (e.g. "neg-int").
+   * "dst_type" is stored into vA, and "src_type" is verified against vB.
+   */
+  static void CheckUnop(RegisterLine* register_line,
+      Instruction::DecodedInstruction* dec_insn, RegType dst_type,
+      RegType src_type, VerifyError* failure);
+
+  /*
+   * Verify types for a simple three-register instruction (e.g. "add-int").
+   * "dst_type" is stored into vA, and "src_type1"/"src_type2" are verified
+   * against vB/vC.
+   */
+  static void CheckBinop(RegisterLine* register_line,
+      Instruction::DecodedInstruction* dec_insn, RegType dst_type,
+      RegType src_type1, RegType src_type2, bool check_boolean_op,
+      VerifyError* failure);
+
+  /*
+   * Verify types for a binary "2addr" operation.  "src_type1"/"src_type2"
+   * are verified against vA/vB, then "dst_type" is stored into vA.
+   */
+  static void CheckBinop2addr(RegisterLine* register_line,
+      Instruction::DecodedInstruction* dec_insn, RegType dst_type,
+      RegType src_type1, RegType src_type2, bool check_boolean_op,
+      VerifyError* failure);
+
+  /*
+   * Treat right-shifting as a narrowing conversion when possible.
+   *
+   * For example, right-shifting an int 24 times results in a value that can
+   * be treated as a byte.
+   *
+   * Things get interesting when contemplating sign extension.  Right-
+   * shifting an integer by 16 yields a value that can be represented in a
+   * "short" but not a "char", but an unsigned right shift by 16 yields a
+   * value that belongs in a char rather than a short.  (Consider what would
+   * happen if the result of the shift were cast to a char or short and then
+   * cast back to an int.  If sign extension, or the lack thereof, causes
+   * a change in the 32-bit representation, then the conversion was lossy.)
+   *
+   * A signed right shift by 17 on an integer results in a short.  An unsigned
+   * right shfit by 17 on an integer results in a posshort, which can be
+   * assigned to a short or a char.
+   *
+   * An unsigned right shift on a short can actually expand the result into
+   * a 32-bit integer.  For example, 0xfffff123 >>> 8 becomes 0x00fffff1,
+   * which can't be represented in anything smaller than an int.
+   *
+   * javac does not generate code that takes advantage of this, but some
+   * of the code optimizers do.  It's generally a peephole optimization
+   * that replaces a particular sequence, e.g. (bipush 24, ishr, i2b) is
+   * replaced by (bipush 24, ishr).  Knowing that shifting a short 8 times
+   * to the right yields a byte is really more than we need to handle the
+   * code that's out there, but support is not much more complex than just
+   * handling integer.
+   *
+   * Right-shifting never yields a boolean value.
+   *
+   * Returns the new register type.
+   */
+  static RegType AdjustForRightShift(RegisterLine* register_line, int reg,
+      unsigned int shift_count, bool is_unsigned_shift, VerifyError* failure);
+
+  /*
+   * We're performing an operation like "and-int/2addr" that can be
+   * performed on booleans as well as integers.  We get no indication of
+   * boolean-ness, but we can infer it from the types of the arguments.
+   *
+   * Assumes we've already validated reg1/reg2.
+   *
+   * TODO: consider generalizing this.  The key principle is that the
+   * result of a bitwise operation can only be as wide as the widest of
+   * the operands.  You can safely AND/OR/XOR two chars together and know
+   * you still have a char, so it's reasonable for the compiler or "dx"
+   * to skip the int-to-char instruction.  (We need to do this for boolean
+   * because there is no int-to-boolean operation.)
+   *
+   * Returns true if both args are Boolean, Zero, or One.
+   */
+  static bool UpcastBooleanOp(RegisterLine* register_line, uint32_t reg1,
+      uint32_t reg2);
+
+  /*
+   * Verify types for A two-register instruction with a literal constant
+   * (e.g. "add-int/lit8").  "dst_type" is stored into vA, and "src_type" is
+   * verified against vB.
+   *
+   * If "check_boolean_op" is set, we use the constant value in vC.
+   */
+  static void CheckLitop(RegisterLine* register_line,
+      Instruction::DecodedInstruction* dec_insn, RegType dst_type,
+      RegType src_type, bool check_boolean_op, VerifyError* failure);
+
+  /*
+   * Verify that the arguments in a filled-new-array instruction are valid.
+   *
+   * "res_class" is the class refered to by dec_insn->vB_.
+   */
+  static void VerifyFilledNewArrayRegs(const Method* method,
+      RegisterLine* register_line,
+      const Instruction::DecodedInstruction* dec_insn, Class* res_class,
+      bool is_range, VerifyError* failure);
+
+  /* See if the method matches the MethodType. */
+  static bool IsCorrectInvokeKind(MethodType method_type, Method* res_method);
+
+  /*
+   * Verify the arguments to a method.  We're executing in "method", making
+   * a call to the method reference in vB.
+   *
+   * If this is a "direct" invoke, we allow calls to <init>.  For calls to
+   * <init>, the first argument may be an uninitialized reference.  Otherwise,
+   * calls to anything starting with '<' will be rejected, as will any
+   * uninitialized reference arguments.
+   *
+   * For non-static method calls, this will verify that the method call is
+   * appropriate for the "this" argument.
+   *
+   * The method reference is in vBBBB.  The "is_range" parameter determines
+   * whether we use 0-4 "args" values or a range of registers defined by
+   * vAA and vCCCC.
+   *
+   * Widening conversions on integers and references are allowed, but
+   * narrowing conversions are not.
+   *
+   * Returns the resolved method on success, NULL on failure (with *failure
+   * set appropriately).
+   */
+  static Method* VerifyInvocationArgs(VerifierData* vdata,
+      RegisterLine* register_line, const int insn_reg_count,
+      const Instruction::DecodedInstruction* dec_insn, MethodType method_type,
+      bool is_range, bool is_super, VerifyError* failure);
+
+  DISALLOW_COPY_AND_ASSIGN(DexVerifier);
 };
 
 }  // namespace art
diff --git a/src/dex_verifier_test.cc b/src/dex_verifier_test.cc
index e6d8096..39e14c4 100644
--- a/src/dex_verifier_test.cc
+++ b/src/dex_verifier_test.cc
@@ -18,7 +18,7 @@
     Class* klass = class_linker_->FindSystemClass(descriptor);
 
     // Verify the class
-    ASSERT_TRUE(DexVerify::VerifyClass(klass));
+    ASSERT_TRUE(DexVerifier::VerifyClass(klass));
   }
 
   void VerifyDexFile(const DexFile* dex, ClassLoader* class_loader) {
@@ -41,7 +41,7 @@
 TEST_F(DexVerifierTest, IntMath) {
   const ClassLoader* class_loader = LoadDex("IntMath");
   Class* klass = class_linker_->FindClass("LIntMath;", class_loader);
-  ASSERT_TRUE(DexVerify::VerifyClass(klass));
+  ASSERT_TRUE(DexVerifier::VerifyClass(klass));
 }
 
 }  // namespace art
diff --git a/src/object.cc b/src/object.cc
index 4384a24..edc5bdd 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -774,6 +774,24 @@
   return NULL;
 }
 
+Method* Class::FindInterfaceMethod(const StringPiece& name,
+                                   const StringPiece& signature) {
+  // Check the current class before checking the interfaces.
+  Method* method = FindVirtualMethod(name, signature);
+  if (method != NULL) {
+    return method;
+  }
+
+  InterfaceEntry* iftable = GetIFTable();
+  for (size_t i = 0; i < GetIFTableCount(); i++) {
+    method = iftable[i].GetInterface()->FindVirtualMethod(name, signature);
+    if (method != NULL) {
+      return method;
+    }
+  }
+  return NULL;
+}
+
 Method* Class::FindDeclaredDirectMethod(const StringPiece& name,
                                         const StringPiece& signature) {
   for (size_t i = 0; i < NumDirectMethods(); ++i) {
diff --git a/src/object.h b/src/object.h
index 050f571..9106472 100644
--- a/src/object.h
+++ b/src/object.h
@@ -82,6 +82,7 @@
 
 static const uint32_t kAccConstructor = 0x00010000;  // method (Dalvik only)
 static const uint32_t kAccDeclaredSynchronized = 0x00020000;  // method (Dalvik only)
+static const uint32_t kAccWritable = 0x80000000; // method (Dalvik only)
 
 static const uint32_t kAccClassFlagsMask = (kAccPublic
                                             | kAccFinal
@@ -501,6 +502,10 @@
     return (GetAccessFlags() & kAccStatic) != 0;
   }
 
+  bool IsFinal() const {
+    return (access_flags_ & kAccFinal) != 0;
+  }
+
   uint32_t GetTypeIdx() const;
 
   void SetTypeIdx(uint32_t type_idx);
@@ -1666,6 +1671,9 @@
   // method for this class.
   Method* FindVirtualMethodForInterface(Method* method);
 
+  Method* FindInterfaceMethod(const StringPiece& name,
+                              const StringPiece& descriptor);
+
   Method* FindVirtualMethodForVirtualOrInterface(Method* method) {
     if (method->GetDeclaringClass()->IsInterface()) {
       return FindVirtualMethodForInterface(method);
@@ -1931,8 +1939,9 @@
                              new_source_file, false);
   }
 
- private:
   bool Implements(const Class* klass) const;
+
+ private:
   bool IsArrayAssignableFromArray(const Class* klass) const;
   bool IsAssignableFromArray(const Class* klass) const;
   bool IsSubClass(const Class* klass) const;
@@ -1977,7 +1986,7 @@
   // is 2.  Otherwise 0.
   int32_t array_rank_;
 
-  // primitive type index, or PRIM_NOT (-1); set for generated prim classes
+  // primitive type index, or kPrimNot (0); set for generated prim classes
   PrimitiveType primitive_type_;
 
   // The superclass, or NULL if this is java.lang.Object or a
