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

  /* Header for RegisterMap */
  struct RegisterMapHeader {
    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 */

    RegisterMapHeader(uint8_t format, uint8_t reg_width, uint16_t num_entries)
        : format_(format), reg_width_(reg_width), num_entries_(num_entries) {
    }
  };

  /*
   * 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 {
    RegisterMapHeader* header_;
    uint8_t* data_;
    bool needs_free_;

    RegisterMap(ByteArray* header, ByteArray* data) {
      header_ = (RegisterMapHeader*) header->GetData();
      data_ = (uint8_t*) data->GetData();
      needs_free_ = false;
    }

    RegisterMap(uint8_t format, uint8_t reg_width, uint16_t num_entries,
        uint32_t data_size) {
      header_ = new RegisterMapHeader(format, reg_width, num_entries);
      data_ = new uint8_t[data_size]();
      needs_free_ = true;
    }

    ~RegisterMap() {
      if (needs_free_) {
        delete header_;
        delete [] data_;
      }
    }
  };

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

  /*
   * 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);

  /*
   * Get the expanded form of the register map associated with the specified
   * method. May update the RegisterMap, possibly freeing the previous map.
   *
   * Returns NULL on failure (e.g. unable to expand map).
   *
   * NOTE: this function is not synchronized; external locking is mandatory.
   * (This is expected to be called at GC time.)
   */
  static inline RegisterMap* GetExpandedRegisterMap(Method* method) {
    if (method->GetRegisterMapHeader() == NULL ||
        method->GetRegisterMapData() == NULL) {
      return NULL;
    }
    RegisterMap* cur_map = new RegisterMap(method->GetRegisterMapHeader(),
        method->GetRegisterMapData());
    uint8_t format = cur_map->header_->format_;
    if (format == kRegMapFormatCompact8 || format == kRegMapFormatCompact16) {
      return cur_map;
    } else {
      return GetExpandedRegisterMapHelper(method, cur_map);
    }
  }

  /*
   * Get the expanded form of the register map associated with the method.
   *
   * If the map is already in one of the uncompressed formats, we return
   * immediately.  Otherwise, we expand the map and replace method's register
   * map pointer, freeing it if it was allocated on the heap.
   *
   * NOTE: this function is not synchronized; external locking is mandatory
   * (unless we're in the zygote, where single-threaded access is guaranteed).
   */
  static RegisterMap* GetExpandedRegisterMapHelper(Method* method,
      RegisterMap* map);

  /* Return the data for the specified address, or NULL if not found. */
  static const uint8_t* RegisterMapGetLine(const RegisterMap* map, int addr);

  /*
   * 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);


  /* 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);

  /*
   * Resolves a class based on an index and performs access checks to ensure
   * the referrer can access the resolved class.
   *
   * Exceptions caused by failures are cleared before returning.
   *
   * Sets "*failure" on failure.
   */
  static Class* ResolveClassAndCheckAccess(const DexFile* dex_file,
      uint32_t class_idx, const Class* referrer, VerifyError* failure);

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

#endif  // ART_SRC_DEX_VERIFY_H_
