// Copyright 2011 Google Inc. All Rights Reserved.

#ifndef ART_SRC_DEX_VERIFY_H_
#define ART_SRC_DEX_VERIFY_H_

#include "dex_file.h"
#include "dex_instruction.h"
#include "macros.h"
#include "object.h"
#include "UniquePtr.h"

namespace art {

#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:
  /*
   * 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),
  };

  /*
   * "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

  /*
   * Format enumeration for RegisterMap data area.
   */
  enum RegisterMapFormat {
    kRegMapFormatUnknown = 0,
    kRegMapFormatNone,          /* indicates no map data follows */
    kRegMapFormatCompact8,      /* compact layout, 8-bit addresses */
    kRegMapFormatCompact16,     /* compact layout, 16-bit addresses */
    kRegMapFormatDifferential,  /* compressed, differential encoding */
  };

  /*
   * 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 {
    UniquePtr<RegType[]> reg_types_;
    UniquePtr<MonitorEntries[]> monitor_entries_;
    UniquePtr<uint32_t[]> monitor_stack_;
    uint32_t monitor_stack_top_;

    RegisterLine()
        : reg_types_(NULL), monitor_entries_(NULL), monitor_stack_(NULL),
          monitor_stack_top_(0) {
    }

    /* Allocate space for the fields. */
    void Alloc(size_t size, bool track_monitors) {
      reg_types_.reset(new RegType[size]());
      if (track_monitors) {
        monitor_entries_.reset(new MonitorEntries[size]);
        monitor_stack_.reset(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.
     */
    UniquePtr<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_;

    RegisterTable() : register_lines_(NULL), insn_reg_count_plus_(0) {
    }
  };

  /* 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_;
    UniquePtr<UninitInstanceMapEntry[]> map_;

    UninitInstanceMap(int num_entries)
        : num_entries_(num_entries),
          map_(new UninitInstanceMapEntry[num_entries]()) {
    }
  };
  #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. */
    UniquePtr<InsnFlags[]> insn_flags_;

    /*
     * Uninitialized instance map, used for tracking the movement of
     * objects that have been allocated but not initialized.
     */
    UniquePtr<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_;

    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) {
    }
  };

  /*
   * This is a single variable-size structure. It may be allocated on the
   * heap or mapped out of a (post-dexopt) DEX file.
   *
   * 32-bit alignment of the structure is NOT guaranteed. This makes it a
   * little awkward to deal with as a structure; to avoid accidents we use
   * only byte types. Multi-byte values are little-endian.
   *
   * Size of (format==FormatNone): 1 byte
   * Size of (format==FormatCompact8): 4 + (1 + reg_width) * num_entries
   * Size of (format==FormatCompact16): 4 + (2 + reg_width) * num_entries
   */
  struct RegisterMap {
    /* header */
    uint8_t format_;          /* enum RegisterMapFormat; MUST be first entry */
    uint8_t reg_width_;       /* bytes per register line, 1+ */
    uint16_t num_entries_;    /* number of entries */
    bool    format_on_heap_;  /* indicates allocation on heap */

    /* raw data starts here; need not be aligned */
    UniquePtr<uint8_t[]> data_;

    RegisterMap(uint8_t format, uint8_t reg_width, uint16_t num_entries,
        bool format_on_heap, uint32_t data_size)
        : format_(format), reg_width_(reg_width), num_entries_(num_entries),
          format_on_heap_(format_on_heap), data_(new uint8_t[data_size]()) {
    }
  };

  /*
   * 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) {
    DCHECK_GE(idx, 0);
    DCHECK_LT(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) {
    DCHECK(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) {
    DCHECK(RegTypeIsUninitReference(type));
    return (type & ~kRegTypeUninitMask) >> kRegTypeUninitShift;
  }

  /* Convert the reference "type" to a Class pointer. */
  static Class* RegTypeReferenceToClass(RegType type,
      const UninitInstanceMap* uninit_map) {
    DCHECK(RegTypeIsReference(type) && type != kRegTypeZero);
    if (RegTypeIsUninitReference(type)) {
      DCHECK(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);

  /*
   * 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_.get(), src->reg_types_.get(), num_regs * sizeof(RegType));

    DCHECK((src->monitor_entries_.get() == NULL && dst->monitor_entries_.get() == NULL) ||
        (src->monitor_entries_.get() != NULL && dst->monitor_entries_.get() != NULL));
    if (dst->monitor_entries_.get() != NULL) {
      DCHECK(dst->monitor_stack_.get() != NULL);
      memcpy(dst->monitor_entries_.get(), src->monitor_entries_.get(),
          num_regs * sizeof(MonitorEntries));
      memcpy(dst->monitor_stack_.get(), src->monitor_stack_.get(),
          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);
    DCHECK(dst->reg_types_.get() != 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);
    DCHECK(src->reg_types_.get() != 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_.get() != NULL) {
      int result;

      if (line2->monitor_entries_.get() == NULL)
        return 1;
      result = memcmp(line1->monitor_entries_.get(), line2->monitor_entries_.get(),
          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_.get(), line2->monitor_stack_.get(),
            line1->monitor_stack_top_);
      if (result != 0) {
        LOG(ERROR) << "monitor_stack_ mismatch";
        return result;
      }
    }
    return memcmp(line1->reg_types_.get(), line2->reg_types_.get(),
        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);

  /*
   * Generate the register map for a method that has just been verified
   * (i.e. we're doing this as part of verification).
   *
   * For type-precise determination we have all the data we need, so we
   * just need to encode it in some clever fashion.
   *
   * Returns a pointer to a newly-allocated RegisterMap, or NULL on failure.
   */
  static RegisterMap* GenerateRegisterMapV(VerifierData* vdata);

  /*
   * Determine if the RegType value is a reference type.
   *
   * Ordinarily we include kRegTypeZero in the "is it a reference"
   * check. There's no value in doing so here, because we know
   * the register can't hold anything but zero.
   */
  static inline bool IsReferenceType(RegType type) {
    return (type > kRegTypeMAX || type == kRegTypeUninit);
  }

  /* Toggle the value of the "idx"th bit in "ptr". */
  static inline void ToggleBit(uint8_t* ptr, int idx) {
    ptr[idx >> 3] ^= 1 << (idx & 0x07);
  }

  /*
   * Given a line of registers, output a bit vector that indicates whether
   * or not the register holds a reference type (which could be null).
   *
   * We use '1' to indicate it's a reference, '0' for anything else (numeric
   * value, uninitialized data, merge conflict). Register 0 will be found
   * in the low bit of the first byte.
   */
  static void OutputTypeVector(const RegType* regs, int insn_reg_count,
      uint8_t* data);

  /*
   * Double-check the map.
   *
   * We run through all of the data in the map, and compare it to the original.
   * Only works on uncompressed data.
   */
  static bool VerifyMap(VerifierData* vdata, const RegisterMap* map);

  /* Compare two register maps. Returns true if they're equal, false if not. */
  static bool CompareMaps(const RegisterMap* map1, const RegisterMap* map2);

  /* Compute the size, in bytes, of a register map. */
  static size_t ComputeRegisterMapSize(const RegisterMap* map);

  /*
   * Compute the difference between two bit vectors.
   *
   * If "leb_out_buf" is non-NULL, we output the bit indices in ULEB128 format
   * as we go. Otherwise, we just generate the various counts.
   *
   * The bit vectors are compared byte-by-byte, so any unused bits at the
   * end must be zero.
   *
   * Returns the number of bytes required to hold the ULEB128 output.
   *
   * If "first_bit_changed_ptr" or "num_bits_changed_ptr" are non-NULL, they
   * will receive the index of the first changed bit and the number of changed
   * bits, respectively.
   */
  static int ComputeBitDiff(const uint8_t* bits1, const uint8_t* bits2,
      int byte_width, int* first_bit_changed_ptr, int* num_bits_changed_ptr,
      uint8_t* leb_out_buf);

  /*
   * Compress the register map with differential encoding.
   *
   * On success, returns a newly-allocated RegisterMap. If the map is not
   * compatible for some reason, or fails to get smaller, this will return NULL.
   */
  static RegisterMap* CompressMapDifferential(const RegisterMap* map);

  /*
   * Expand a compressed map to an uncompressed form.
   *
   * Returns a newly-allocated RegisterMap on success, or NULL on failure.
   *
   * TODO: consider using the linear allocator or a custom allocator with
   * LRU replacement for these instead of the native heap.
   */
  static RegisterMap* UncompressMapDifferential(const RegisterMap* map);

  DISALLOW_COPY_AND_ASSIGN(DexVerifier);
};

}  // namespace art

#endif  // ART_SRC_DEX_VERIFY_H_
