/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Dalvik bytecode structural verifier.  The only public entry point
 * (except for a few shared utility functions) is dvmVerifyCodeFlow().
 *
 * TODO: might benefit from a signature-->class lookup cache.  Could avoid
 * some string-peeling and wouldn't need to compute hashes.
 */
#include "Dalvik.h"
#include "analysis/BackwardFlow.h"
#include "analysis/CodeVerify.h"
#include "analysis/Optimize.h"
#include "analysis/RegisterMap.h"
#include "libdex/DexCatch.h"
#include "libdex/InstrUtils.h"

#include <stddef.h>


/*
 * 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).
 */
typedef enum RegisterTrackingMode {
    kTrackRegsBranches,
    kTrackRegsGcPoints,
    kTrackRegsAll
} RegisterTrackingMode;

/*
 * 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) and for checking the optimized output from "dx".
 * 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

static bool gDebugVerbose = false;

#define SHOW_REG_DETAILS \
    (0 | DRT_SHOW_LIVENESS /*| DRT_SHOW_REF_TYPES | DRT_SHOW_LOCALS*/)

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

/*
 * Big fat collection of register data.
 */
typedef struct RegisterTable {
    /*
     * Array of RegisterLine structs, one per address in the method.  We only
     * set the pointers for certain addresses, based on instruction widths
     * and what we're trying to accomplish.
     */
    RegisterLine* registerLines;

    /*
     * Number of registers we track for each instruction.  This is equal
     * to the method's declared "registersSize" plus kExtraRegs.
     */
    size_t      insnRegCountPlus;

    /*
     * Storage for a register line we're currently working on.
     */
    RegisterLine workLine;

    /*
     * Storage for a register line we're saving for later.
     */
    RegisterLine savedLine;

    /*
     * A single large alloc, with all of the storage needed for RegisterLine
     * data (RegType array, MonitorEntries array, monitor stack).
     */
    void*       lineAlloc;
} RegisterTable;


/* fwd */
#ifndef NDEBUG
static void checkMergeTab(void);
#endif
static bool isInitMethod(const Method* meth);
static RegType getInvocationThis(const RegisterLine* registerLine,\
    const DecodedInstruction* pDecInsn, VerifyError* pFailure);
static void verifyRegisterType(const RegisterLine* registerLine, \
    u4 vsrc, RegType checkType, VerifyError* pFailure);
static bool doCodeVerification(VerifierData* vdata, RegisterTable* regTable);
static bool verifyInstruction(const Method* meth, InsnFlags* insnFlags,\
    RegisterTable* regTable, int insnIdx, UninitInstanceMap* uninitMap,
    int* pStartGuess);
static ClassObject* findCommonSuperclass(ClassObject* c1, ClassObject* c2);
static void dumpRegTypes(const VerifierData* vdata, \
    const RegisterLine* registerLine, int addr, const char* addrName,
    const UninitInstanceMap* uninitMap, int displayFlags);

/* bit values for dumpRegTypes() "displayFlags" */
enum {
    DRT_SIMPLE          = 0,
    DRT_SHOW_REF_TYPES  = 0x01,
    DRT_SHOW_LOCALS     = 0x02,
    DRT_SHOW_LIVENESS   = 0x04,
};


/*
 * ===========================================================================
 *      RegType and UninitInstanceMap utility functions
 * ===========================================================================
 */

#define __  kRegTypeUnknown
#define _U  kRegTypeUninit
#define _X  kRegTypeConflict
#define _F  kRegTypeFloat
#define _0  kRegTypeZero
#define _1  kRegTypeOne
#define _Z  kRegTypeBoolean
#define _b  kRegTypePosByte
#define _B  kRegTypeByte
#define _s  kRegTypePosShort
#define _S  kRegTypeShort
#define _C  kRegTypeChar
#define _I  kRegTypeInteger
#define _J  kRegTypeLongLo
#define _j  kRegTypeLongHi
#define _D  kRegTypeDoubleLo
#define _d  kRegTypeDoubleHi

/*
 * 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.
 *
 * Because Dalvik does not draw a distinction between int and float, we
 * have to 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.
 */
const char gDvmMergeTab[kRegTypeMAX][kRegTypeMAX] =
{
    /* chk:  _  U  X  F  0  1  Z  b  B  s  S  C  I  J  j  D  d */
    { /*_*/ __,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X },
    { /*U*/ _X,_U,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X },
    { /*X*/ _X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X },
    { /*F*/ _X,_X,_X,_F,_F,_F,_F,_F,_F,_F,_F,_F,_F,_X,_X,_X,_X },
    { /*0*/ _X,_X,_X,_F,_0,_Z,_Z,_b,_B,_s,_S,_C,_I,_X,_X,_X,_X },
    { /*1*/ _X,_X,_X,_F,_Z,_1,_Z,_b,_B,_s,_S,_C,_I,_X,_X,_X,_X },
    { /*Z*/ _X,_X,_X,_F,_Z,_Z,_Z,_b,_B,_s,_S,_C,_I,_X,_X,_X,_X },
    { /*b*/ _X,_X,_X,_F,_b,_b,_b,_b,_B,_s,_S,_C,_I,_X,_X,_X,_X },
    { /*B*/ _X,_X,_X,_F,_B,_B,_B,_B,_B,_S,_S,_I,_I,_X,_X,_X,_X },
    { /*s*/ _X,_X,_X,_F,_s,_s,_s,_s,_S,_s,_S,_C,_I,_X,_X,_X,_X },
    { /*S*/ _X,_X,_X,_F,_S,_S,_S,_S,_S,_S,_S,_I,_I,_X,_X,_X,_X },
    { /*C*/ _X,_X,_X,_F,_C,_C,_C,_C,_I,_C,_I,_C,_I,_X,_X,_X,_X },
    { /*I*/ _X,_X,_X,_F,_I,_I,_I,_I,_I,_I,_I,_I,_I,_X,_X,_X,_X },
    { /*J*/ _X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_J,_X,_J,_X },
    { /*j*/ _X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_j,_X,_j },
    { /*D*/ _X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_J,_X,_D,_X },
    { /*d*/ _X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_X,_j,_X,_d },
};

#undef __
#undef _U
#undef _X
#undef _F
#undef _0
#undef _1
#undef _Z
#undef _b
#undef _B
#undef _s
#undef _S
#undef _C
#undef _I
#undef _J
#undef _j
#undef _D
#undef _d

#ifndef NDEBUG
/*
 * Verify symmetry in the conversion table.
 */
static void checkMergeTab(void)
{
    int i, j;

    for (i = 0; i < kRegTypeMAX; i++) {
        for (j = i; j < kRegTypeMAX; j++) {
            if (gDvmMergeTab[i][j] != gDvmMergeTab[j][i]) {
                LOGE("Symmetry violation: %d,%d vs %d,%d\n", i, j, j, i);
                dvmAbort();
            }
        }
    }
}
#endif

/*
 * Determine whether we can convert "srcType" to "checkType", where
 * "checkType" is one of the category-1 non-reference types.
 *
 * 32-bit int and float are interchangeable.
 */
static bool canConvertTo1nr(RegType srcType, RegType checkType)
{
    static const char convTab
        [kRegType1nrEND-kRegType1nrSTART+1][kRegType1nrEND-kRegType1nrSTART+1] =
    {
        /* chk: F  0  1  Z  b  B  s  S  C  I */
        { /*F*/ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { /*0*/ 1, 1, 0, 1, 1, 1, 1, 1, 1, 1 },
        { /*1*/ 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
        { /*Z*/ 1, 0, 0, 1, 1, 1, 1, 1, 1, 1 },
        { /*b*/ 1, 0, 0, 0, 1, 1, 1, 1, 1, 1 },
        { /*B*/ 1, 0, 0, 0, 0, 1, 0, 1, 0, 1 },
        { /*s*/ 1, 0, 0, 0, 0, 0, 1, 1, 1, 1 },
        { /*S*/ 1, 0, 0, 0, 0, 0, 0, 1, 0, 1 },
        { /*C*/ 1, 0, 0, 0, 0, 0, 0, 0, 1, 1 },
        { /*I*/ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
    };

    assert(checkType >= kRegType1nrSTART && checkType <= kRegType1nrEND);
#if 0
    if (checkType < kRegType1nrSTART || checkType > kRegType1nrEND) {
        LOG_VFY("Unexpected checkType %d (srcType=%d)\n", checkType, srcType);
        assert(false);
        return false;
    }
#endif

    //printf("convTab[%d][%d] = %d\n", srcType, checkType,
    //    convTab[srcType-kRegType1nrSTART][checkType-kRegType1nrSTART]);
    if (srcType >= kRegType1nrSTART && srcType <= kRegType1nrEND)
        return (bool) convTab[srcType-kRegType1nrSTART][checkType-kRegType1nrSTART];

    return false;
}

/*
 * Determine whether the types are compatible.  In Dalvik, 64-bit doubles
 * and longs are interchangeable.
 */
static bool canConvertTo2(RegType srcType, RegType checkType)
{
    return ((srcType == kRegTypeLongLo || srcType == kRegTypeDoubleLo) &&
            (checkType == kRegTypeLongLo || checkType == kRegTypeDoubleLo));
}

/*
 * Determine whether or not "instrType" and "targetType" are compatible,
 * for purposes of getting or setting a value in a field or array.  The
 * idea is that an instruction with a category 1nr type (say, aget-short
 * or iput-boolean) is accessing a static field, instance field, or array
 * entry, and we want to make sure sure that the operation is legal.
 *
 * At a minimum, source and destination must have the same width.  We
 * further refine this to assert that "short" and "char" are not
 * compatible, because the sign-extension is different on the "get"
 * operations.  As usual, "float" and "int" are interoperable.
 *
 * We're not considering the actual contents of the register, so we'll
 * never get "pseudo-types" like kRegTypeZero or kRegTypePosShort.  We
 * could get kRegTypeUnknown in "targetType" if a field or array class
 * lookup failed.  Category 2 types and references are checked elsewhere.
 */
static bool checkFieldArrayStore1nr(RegType instrType, RegType targetType)
{
    if (instrType == targetType)
        return true;            /* quick positive; most common case */

    if ((instrType == kRegTypeInteger && targetType == kRegTypeFloat) ||
        (instrType == kRegTypeFloat && targetType == kRegTypeInteger))
    {
        return true;
    }

    return false;
}

/*
 * Convert a VM PrimitiveType enum value to the equivalent RegType value.
 */
static RegType primitiveTypeToRegType(PrimitiveType primType)
{
    static const struct {
        RegType         regType;        /* type equivalent */
        PrimitiveType   primType;       /* verification */
    } convTab[] = {
        /* must match order of enum in Object.h */
        { kRegTypeBoolean,      PRIM_BOOLEAN },
        { kRegTypeChar,         PRIM_CHAR },
        { kRegTypeFloat,        PRIM_FLOAT },
        { kRegTypeDoubleLo,     PRIM_DOUBLE },
        { kRegTypeByte,         PRIM_BYTE },
        { kRegTypeShort,        PRIM_SHORT },
        { kRegTypeInteger,      PRIM_INT },
        { kRegTypeLongLo,       PRIM_LONG },
        // PRIM_VOID
    };

    if (primType < 0 || primType > (int) (sizeof(convTab) / sizeof(convTab[0])))
    {
        assert(false);
        return kRegTypeUnknown;
    }

    assert(convTab[primType].primType == primType);
    return convTab[primType].regType;
}

/*
 * Given a 32-bit constant, return the most-restricted RegType enum entry
 * that can hold the value.
 */
static char determineCat1Const(s4 value)
{
    if (value < -32768)
        return kRegTypeInteger;
    else if (value < -128)
        return kRegTypeShort;
    else if (value < 0)
        return kRegTypeByte;
    else if (value == 0)
        return kRegTypeZero;
    else if (value == 1)
        return kRegTypeOne;
    else if (value < 128)
        return kRegTypePosByte;
    else if (value < 32768)
        return kRegTypePosShort;
    else if (value < 65536)
        return kRegTypeChar;
    else
        return kRegTypeInteger;
}

/*
 * 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
 */
UninitInstanceMap* dvmCreateUninitInstanceMap(const Method* meth,
    const InsnFlags* insnFlags, int newInstanceCount)
{
    const int insnsSize = dvmGetMethodInsnsSize(meth);
    const u2* insns = meth->insns;
    UninitInstanceMap* uninitMap;
    bool isInit = false;
    int idx, addr;

    if (isInitMethod(meth)) {
        newInstanceCount++;
        isInit = true;
    }

    /*
     * Allocate the header and map as a single unit.
     *
     * TODO: consider having a static instance so we can avoid allocations.
     * I don't think the verifier is guaranteed to be single-threaded when
     * running in the VM (rather than dexopt), so that must be taken into
     * account.
     */
    int size = offsetof(UninitInstanceMap, map) +
                newInstanceCount * sizeof(uninitMap->map[0]);
    uninitMap = (UninitInstanceMap*)calloc(1, size);
    if (uninitMap == NULL)
        return NULL;
    uninitMap->numEntries = newInstanceCount;

    idx = 0;
    if (isInit) {
        uninitMap->map[idx++].addr = kUninitThisArgAddr;
    }

    /*
     * Run through and find the new-instance instructions.
     */
    for (addr = 0; addr < insnsSize; /**/) {
        int width = dvmInsnGetWidth(insnFlags, addr);

        if ((*insns & 0xff) == OP_NEW_INSTANCE)
            uninitMap->map[idx++].addr = addr;

        addr += width;
        insns += width;
    }

    assert(idx == newInstanceCount);
    return uninitMap;
}

/*
 * Free the map.
 */
void dvmFreeUninitInstanceMap(UninitInstanceMap* uninitMap)
{
    free(uninitMap);
}

/*
 * 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* uninitMap, int addr,
    ClassObject* clazz)
{
    int idx;

    assert(clazz != NULL);

#ifdef VERIFIER_STATS
    gDvm.verifierStats.uninitSearches++;
#endif

    /* TODO: binary search when numEntries > 8 */
    for (idx = uninitMap->numEntries - 1; idx >= 0; idx--) {
        if (uninitMap->map[idx].addr == addr) {
            if (uninitMap->map[idx].clazz != NULL &&
                uninitMap->map[idx].clazz != clazz)
            {
                LOG_VFY("VFY: addr %d already set to %p, not setting to %p\n",
                    addr, uninitMap->map[idx].clazz, clazz);
                return -1;          // already set to something else??
            }
            uninitMap->map[idx].clazz = clazz;
            return idx;
        }
    }

    LOG_VFY("VFY: addr %d not found in uninit map\n", addr);
    assert(false);      // shouldn't happen
    return -1;
}

/*
 * Get the class object at the specified index.
 */
static ClassObject* getUninitInstance(const UninitInstanceMap* uninitMap,
    int idx)
{
    assert(idx >= 0 && idx < uninitMap->numEntries);
    return uninitMap->map[idx].clazz;
}

/* 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 ClassObject pointer */
/* (does not expect uninit ref types or "zero") */
static ClassObject* regTypeInitializedReferenceToClass(RegType type)
{
    assert(regTypeIsReference(type) && type != kRegTypeZero);
    if ((type & 0x01) == 0) {
        return (ClassObject*) type;
    } else {
        //LOG_VFY("VFY: attempted to use uninitialized reference\n");
        return NULL;
    }
}

/* extract the index into the uninitialized instance map table */
static inline int regTypeToUninitIndex(RegType type) {
    assert(regTypeIsUninitReference(type));
    return (type & ~kRegTypeUninitMask) >> kRegTypeUninitShift;
}

/* convert the reference "type" to a ClassObject pointer */
static ClassObject* regTypeReferenceToClass(RegType type,
    const UninitInstanceMap* uninitMap)
{
    assert(regTypeIsReference(type) && type != kRegTypeZero);
    if (regTypeIsUninitReference(type)) {
        assert(uninitMap != NULL);
        return getUninitInstance(uninitMap, regTypeToUninitIndex(type));
    } else {
        return (ClassObject*) type;
    }
}

/* convert the ClassObject pointer to an (initialized) register type */
static inline RegType regTypeFromClass(ClassObject* clazz) {
    return (u4) clazz;
}

/* return the RegType for the uninitialized reference in slot "uidx" */
static RegType regTypeFromUninitIndex(int uidx) {
    return (u4) (kRegTypeUninit | (uidx << kRegTypeUninitShift));
}


/*
 * ===========================================================================
 *      Signature operations
 * ===========================================================================
 */

/*
 * Is this method a constructor?
 */
static bool isInitMethod(const Method* meth)
{
    return (*meth->name == '<' && strcmp(meth->name+1, "init>") == 0);
}

/*
 * Is this method a class initializer?
 */
#if 0
static bool isClassInitMethod(const Method* meth)
{
    return (*meth->name == '<' && strcmp(meth->name+1, "clinit>") == 0);
}
#endif

/*
 * Look up a class reference given as a simple string descriptor.
 *
 * If we can't find it, return a generic substitute when possible.
 */
static ClassObject* lookupClassByDescriptor(const Method* meth,
    const char* pDescriptor, VerifyError* pFailure)
{
    /*
     * The javac compiler occasionally puts references to nonexistent
     * classes in signatures.  For example, if you have a non-static
     * inner class with no constructor, the compiler provides
     * a private <init> for you.  Constructing the class
     * requires <init>(parent), but the outer class can't call
     * that because the method is private.  So the compiler
     * generates a package-scope <init>(parent,bogus) method that
     * just calls the regular <init> (the "bogus" part being necessary
     * to distinguish the signature of the synthetic method).
     * Treating the bogus class as an instance of java.lang.Object
     * allows the verifier to process the class successfully.
     */

    //LOGI("Looking up '%s'\n", typeStr);
    ClassObject* clazz;
    clazz = dvmFindClassNoInit(pDescriptor, meth->clazz->classLoader);
    if (clazz == NULL) {
        dvmClearOptException(dvmThreadSelf());
        if (strchr(pDescriptor, '$') != NULL) {
            LOGV("VFY: unable to find class referenced in signature (%s)\n",
                pDescriptor);
        } else {
            LOG_VFY("VFY: unable to find class referenced in signature (%s)\n",
                pDescriptor);
        }

        if (pDescriptor[0] == '[') {
            /* We are looking at an array descriptor. */

            /*
             * There should never be a problem loading primitive arrays.
             */
            if (pDescriptor[1] != 'L' && pDescriptor[1] != '[') {
                LOG_VFY("VFY: invalid char in signature in '%s'\n",
                    pDescriptor);
                *pFailure = VERIFY_ERROR_GENERIC;
            }

            /*
             * Try to continue with base array type.  This will let
             * us pass basic stuff (e.g. get array len) that wouldn't
             * fly with an Object.  This is NOT correct if the
             * missing type is a primitive array, but we should never
             * have a problem loading those.  (I'm not convinced this
             * is correct or even useful.  Just use Object here?)
             */
            clazz = dvmFindClassNoInit("[Ljava/lang/Object;",
                meth->clazz->classLoader);
        } else if (pDescriptor[0] == 'L') {
            /*
             * We are looking at a non-array reference descriptor;
             * try to continue with base reference type.
             */
            clazz = gDvm.classJavaLangObject;
        } else {
            /* We are looking at a primitive type. */
            LOG_VFY("VFY: invalid char in signature in '%s'\n", pDescriptor);
            *pFailure = VERIFY_ERROR_GENERIC;
        }

        if (clazz == NULL) {
            *pFailure = VERIFY_ERROR_GENERIC;
        }
    }

    if (dvmIsPrimitiveClass(clazz)) {
        LOG_VFY("VFY: invalid use of primitive type '%s'\n", pDescriptor);
        *pFailure = VERIFY_ERROR_GENERIC;
        clazz = NULL;
    }

    return clazz;
}

/*
 * Look up a class reference in a signature.  Could be an arg or the
 * return value.
 *
 * Advances "*pSig" to the last character in the signature (that is, to
 * the ';').
 *
 * NOTE: this is also expected to verify the signature.
 */
static ClassObject* lookupSignatureClass(const Method* meth, const char** pSig,
    VerifyError* pFailure)
{
    const char* sig = *pSig;
    const char* endp = sig;

    assert(sig != NULL && *sig == 'L');

    while (*++endp != ';' && *endp != '\0')
        ;
    if (*endp != ';') {
        LOG_VFY("VFY: bad signature component '%s' (missing ';')\n", sig);
        *pFailure = VERIFY_ERROR_GENERIC;
        return NULL;
    }

    endp++;    /* Advance past the ';'. */
    int typeLen = endp - sig;
    char typeStr[typeLen+1]; /* +1 for the '\0' */
    memcpy(typeStr, sig, typeLen);
    typeStr[typeLen] = '\0';

    *pSig = endp - 1; /* - 1 so that *pSig points at, not past, the ';' */

    return lookupClassByDescriptor(meth, typeStr, pFailure);
}

/*
 * Look up an array class reference in a signature.  Could be an arg or the
 * return value.
 *
 * Advances "*pSig" to the last character in the signature.
 *
 * NOTE: this is also expected to verify the signature.
 */
static ClassObject* lookupSignatureArrayClass(const Method* meth,
    const char** pSig, VerifyError* pFailure)
{
    const char* sig = *pSig;
    const char* endp = sig;

    assert(sig != NULL && *sig == '[');

    /* find the end */
    while (*++endp == '[' && *endp != '\0')
        ;

    if (*endp == 'L') {
        while (*++endp != ';' && *endp != '\0')
            ;
        if (*endp != ';') {
            LOG_VFY("VFY: bad signature component '%s' (missing ';')\n", sig);
            *pFailure = VERIFY_ERROR_GENERIC;
            return NULL;
        }
    }

    int typeLen = endp - sig +1;
    char typeStr[typeLen+1];
    memcpy(typeStr, sig, typeLen);
    typeStr[typeLen] = '\0';

    *pSig = endp;

    return lookupClassByDescriptor(meth, typeStr, pFailure);
}

/*
 * 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(const Method* meth, RegType* regTypes,
    UninitInstanceMap* uninitMap)
{
    DexParameterIterator iterator;
    int actualArgs, expectedArgs, argStart;
    VerifyError failure = VERIFY_ERROR_NONE;

    dexParameterIteratorInit(&iterator, &meth->prototype);
    argStart = meth->registersSize - meth->insSize;
    expectedArgs = meth->insSize;     /* long/double count as two */
    actualArgs = 0;

    assert(argStart >= 0);      /* should have been verified earlier */

    /*
     * Include the "this" pointer.
     */
    if (!dvmIsStaticMethod(meth)) {
        /*
         * If this is a constructor for a class other than java.lang.Object,
         * mark the first ("this") argument as uninitialized.  This restricts
         * field access until the superclass constructor is called.
         */
        if (isInitMethod(meth) && meth->clazz != gDvm.classJavaLangObject) {
            int uidx = setUninitInstance(uninitMap, kUninitThisArgAddr,
                            meth->clazz);
            assert(uidx == 0);
            regTypes[argStart + actualArgs] = regTypeFromUninitIndex(uidx);
        } else {
            regTypes[argStart + actualArgs] = regTypeFromClass(meth->clazz);
        }
        actualArgs++;
    }

    for (;;) {
        const char* descriptor = dexParameterIteratorNextDescriptor(&iterator);

        if (descriptor == NULL) {
            break;
        }

        if (actualArgs >= expectedArgs) {
            LOG_VFY("VFY: expected %d args, found more (%s)\n",
                expectedArgs, descriptor);
            goto bad_sig;
        }

        switch (*descriptor) {
        case 'L':
        case '[':
            /*
             * We assume that reference arguments are initialized.  The
             * only way it could be otherwise (assuming the caller was
             * verified) is if the current method is <init>, but in that
             * case it's effectively considered initialized the instant
             * we reach here (in the sense that we can return without
             * doing anything or call virtual methods).
             */
            {
                ClassObject* clazz =
                    lookupClassByDescriptor(meth, descriptor, &failure);
                if (!VERIFY_OK(failure))
                    goto bad_sig;
                regTypes[argStart + actualArgs] = regTypeFromClass(clazz);
            }
            actualArgs++;
            break;
        case 'Z':
            regTypes[argStart + actualArgs] = kRegTypeBoolean;
            actualArgs++;
            break;
        case 'C':
            regTypes[argStart + actualArgs] = kRegTypeChar;
            actualArgs++;
            break;
        case 'B':
            regTypes[argStart + actualArgs] = kRegTypeByte;
            actualArgs++;
            break;
        case 'I':
            regTypes[argStart + actualArgs] = kRegTypeInteger;
            actualArgs++;
            break;
        case 'S':
            regTypes[argStart + actualArgs] = kRegTypeShort;
            actualArgs++;
            break;
        case 'F':
            regTypes[argStart + actualArgs] = kRegTypeFloat;
            actualArgs++;
            break;
        case 'D':
            regTypes[argStart + actualArgs] = kRegTypeDoubleLo;
            regTypes[argStart + actualArgs +1] = kRegTypeDoubleHi;
            actualArgs += 2;
            break;
        case 'J':
            regTypes[argStart + actualArgs] = kRegTypeLongLo;
            regTypes[argStart + actualArgs +1] = kRegTypeLongHi;
            actualArgs += 2;
            break;
        default:
            LOG_VFY("VFY: unexpected signature type char '%c'\n", *descriptor);
            goto bad_sig;
        }
    }

    if (actualArgs != expectedArgs) {
        LOG_VFY("VFY: expected %d args, found %d\n", expectedArgs, actualArgs);
        goto bad_sig;
    }

    const char* descriptor = dexProtoGetReturnType(&meth->prototype);

    /*
     * Validate return type.  We don't do the type lookup; just want to make
     * sure that it has the right format.  Only major difference from the
     * method argument format is that 'V' is supported.
     */
    switch (*descriptor) {
    case 'I':
    case 'C':
    case 'S':
    case 'B':
    case 'Z':
    case 'V':
    case 'F':
    case 'D':
    case 'J':
        if (*(descriptor+1) != '\0')
            goto bad_sig;
        break;
    case '[':
        /* single/multi, object/primitive */
        while (*++descriptor == '[')
            ;
        if (*descriptor == 'L') {
            while (*++descriptor != ';' && *descriptor != '\0')
                ;
            if (*descriptor != ';')
                goto bad_sig;
        } else {
            if (*(descriptor+1) != '\0')
                goto bad_sig;
        }
        break;
    case 'L':
        /* could be more thorough here, but shouldn't be required */
        while (*++descriptor != ';' && *descriptor != '\0')
            ;
        if (*descriptor != ';')
            goto bad_sig;
        break;
    default:
        goto bad_sig;
    }

    return true;

//fail:
//    LOG_VFY_METH(meth, "VFY:  bad sig\n");
//    return false;

bad_sig:
    {
        char* desc = dexProtoCopyMethodDescriptor(&meth->prototype);
        LOG_VFY("VFY: bad signature '%s' for %s.%s\n",
            desc, meth->clazz->descriptor, meth->name);
        free(desc);
    }
    return false;
}

/*
 * 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 Method* meth)
{
    RegType type;
    const char* descriptor = dexProtoGetReturnType(&meth->prototype);

    switch (*descriptor) {
    case 'I':
        type = kRegTypeInteger;
        break;
    case 'C':
        type = kRegTypeChar;
        break;
    case 'S':
        type = kRegTypeShort;
        break;
    case 'B':
        type = kRegTypeByte;
        break;
    case 'Z':
        type = kRegTypeBoolean;
        break;
    case 'V':
        type = kRegTypeUnknown;
        break;
    case 'F':
        type = kRegTypeFloat;
        break;
    case 'D':
        type = kRegTypeDoubleLo;
        break;
    case 'J':
        type = kRegTypeLongLo;
        break;
    case 'L':
    case '[':
        {
            VerifyError failure = VERIFY_ERROR_NONE;
            ClassObject* clazz =
                lookupClassByDescriptor(meth, descriptor, &failure);
            assert(VERIFY_OK(failure));
            type = regTypeFromClass(clazz);
        }
        break;
    default:
        /* we verified signature return type earlier, so this is impossible */
        assert(false);
        type = kRegTypeConflict;
        break;
    }

    return type;
}

/*
 * Convert a single-character signature value (i.e. a primitive type) to
 * the corresponding RegType.  This is intended for access to object fields
 * holding primitive types.
 *
 * Returns kRegTypeUnknown for objects, arrays, and void.
 */
static RegType primSigCharToRegType(char sigChar)
{
    RegType type;

    switch (sigChar) {
    case 'I':
        type = kRegTypeInteger;
        break;
    case 'C':
        type = kRegTypeChar;
        break;
    case 'S':
        type = kRegTypeShort;
        break;
    case 'B':
        type = kRegTypeByte;
        break;
    case 'Z':
        type = kRegTypeBoolean;
        break;
    case 'F':
        type = kRegTypeFloat;
        break;
    case 'D':
        type = kRegTypeDoubleLo;
        break;
    case 'J':
        type = kRegTypeLongLo;
        break;
    case 'V':
    case 'L':
    case '[':
        type = kRegTypeUnknown;
        break;
    default:
        assert(false);
        type = kRegTypeUnknown;
        break;
    }

    return type;
}

/*
 * See if the method matches the MethodType.
 */
static bool isCorrectInvokeKind(MethodType methodType, Method* resMethod)
{
    switch (methodType) {
    case METHOD_DIRECT:
        return dvmIsDirectMethod(resMethod);
    case METHOD_STATIC:
        return dvmIsStaticMethod(resMethod);
    case METHOD_VIRTUAL:
    case METHOD_INTERFACE:
        return !dvmIsDirectMethod(resMethod);
    default:
        return false;
    }
}

/*
 * 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 "isRange" 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 *pFailure
 * set appropriately).
 */
static Method* verifyInvocationArgs(const Method* meth,
    const RegisterLine* registerLine, const int insnRegCount,
    const DecodedInstruction* pDecInsn, UninitInstanceMap* uninitMap,
    MethodType methodType, bool isRange, bool isSuper, VerifyError* pFailure)
{
    Method* resMethod;
    char* sigOriginal = NULL;

    /*
     * Resolve the method.  This could be an abstract or concrete method
     * depending on what sort of call we're making.
     */
    if (methodType == METHOD_INTERFACE) {
        resMethod = dvmOptResolveInterfaceMethod(meth->clazz, pDecInsn->vB);
    } else {
        resMethod = dvmOptResolveMethod(meth->clazz, pDecInsn->vB, methodType,
            pFailure);
    }
    if (resMethod == NULL) {
        /* failed; print a meaningful failure message */
        DexFile* pDexFile = meth->clazz->pDvmDex->pDexFile;
        const DexMethodId* pMethodId;
        const char* methodName;
        char* methodDesc;
        const char* classDescriptor;

        pMethodId = dexGetMethodId(pDexFile, pDecInsn->vB);
        methodName = dexStringById(pDexFile, pMethodId->nameIdx);
        methodDesc = dexCopyDescriptorFromMethodId(pDexFile, pMethodId);
        classDescriptor = dexStringByTypeIdx(pDexFile, pMethodId->classIdx);

        if (!gDvm.optimizing) {
            char* dotMissingClass =
                dvmHumanReadableDescriptor(classDescriptor);
            char* dotMethClass =
                dvmHumanReadableDescriptor(meth->clazz->descriptor);
            //char* curMethodDesc =
            //    dexProtoCopyMethodDescriptor(&meth->prototype);

            LOGI("Could not find method %s.%s, referenced from method %s.%s\n",
                dotMissingClass, methodName/*, methodDesc*/,
                dotMethClass, meth->name/*, curMethodDesc*/);

            free(dotMissingClass);
            free(dotMethClass);
            //free(curMethodDesc);
        }

        LOG_VFY("VFY: unable to resolve %s method %u: %s.%s %s\n",
            dvmMethodTypeStr(methodType), pDecInsn->vB,
            classDescriptor, methodName, methodDesc);
        free(methodDesc);
        if (VERIFY_OK(*pFailure))       /* not set for interface resolve */
            *pFailure = VERIFY_ERROR_NO_METHOD;
        goto fail;
    }

    /*
     * Only time you can explicitly call a method starting with '<' is when
     * making a "direct" invocation on "<init>".  There are additional
     * restrictions but we don't enforce them here.
     */
    if (resMethod->name[0] == '<') {
        if (methodType != METHOD_DIRECT || !isInitMethod(resMethod)) {
            LOG_VFY("VFY: invalid call to %s.%s\n",
                    resMethod->clazz->descriptor, resMethod->name);
            goto bad_sig;
        }
    }

    /*
     * See if the method type implied by the invoke instruction matches the
     * access flags for the target method.
     */
    if (!isCorrectInvokeKind(methodType, resMethod)) {
        LOG_VFY("VFY: invoke type does not match method type of %s.%s\n",
            resMethod->clazz->descriptor, resMethod->name);
        goto fail;
    }

    /*
     * If we're using invoke-super(method), make sure that the executing
     * method's class' superclass has a vtable entry for the target method.
     */
    if (isSuper) {
        assert(methodType == METHOD_VIRTUAL);
        ClassObject* super = meth->clazz->super;
        if (super == NULL || resMethod->methodIndex > super->vtableCount) {
            char* desc = dexProtoCopyMethodDescriptor(&resMethod->prototype);
            LOG_VFY("VFY: invalid invoke-super from %s.%s to super %s.%s %s\n",
                    meth->clazz->descriptor, meth->name,
                    (super == NULL) ? "-" : super->descriptor,
                    resMethod->name, desc);
            free(desc);
            *pFailure = VERIFY_ERROR_NO_METHOD;
            goto fail;
        }
    }

    /*
     * We use vAA as our expected arg count, rather than resMethod->insSize,
     * because we need to match the call to the signature.  Also, we might
     * might be calling through an abstract method definition (which doesn't
     * have register count values).
     */
    sigOriginal = dexProtoCopyMethodDescriptor(&resMethod->prototype);
    const char* sig = sigOriginal;
    int expectedArgs = pDecInsn->vA;
    int actualArgs = 0;

    /* caught by static verifier */
    assert(isRange || expectedArgs <= 5);

    if (expectedArgs > meth->outsSize) {
        LOG_VFY("VFY: invalid arg count (%d) exceeds outsSize (%d)\n",
            expectedArgs, meth->outsSize);
        goto fail;
    }

    if (*sig++ != '(')
        goto bad_sig;

    /*
     * Check the "this" argument, which must be an instance of the class
     * that declared the method.  For an interface class, we don't do the
     * full interface merge, so we can't do a rigorous check here (which
     * is okay since we have to do it at runtime).
     */
    if (!dvmIsStaticMethod(resMethod)) {
        ClassObject* actualThisRef;
        RegType actualArgType;

        actualArgType = getInvocationThis(registerLine, pDecInsn, pFailure);
        if (!VERIFY_OK(*pFailure))
            goto fail;

        if (regTypeIsUninitReference(actualArgType) && resMethod->name[0] != '<')
        {
            LOG_VFY("VFY: 'this' arg must be initialized\n");
            goto fail;
        }
        if (methodType != METHOD_INTERFACE && actualArgType != kRegTypeZero) {
            actualThisRef = regTypeReferenceToClass(actualArgType, uninitMap);
            if (!dvmInstanceof(actualThisRef, resMethod->clazz)) {
                LOG_VFY("VFY: 'this' arg '%s' not instance of '%s'\n",
                        actualThisRef->descriptor,
                        resMethod->clazz->descriptor);
                goto fail;
            }
        }
        actualArgs++;
    }

    /*
     * Process the target method's signature.  This signature may or may not
     * have been verified, so we can't assume it's properly formed.
     */
    while (*sig != '\0' && *sig != ')') {
        if (actualArgs >= expectedArgs) {
            LOG_VFY("VFY: expected %d args, found more (%c)\n",
                expectedArgs, *sig);
            goto bad_sig;
        }

        u4 getReg;
        if (isRange)
            getReg = pDecInsn->vC + actualArgs;
        else
            getReg = pDecInsn->arg[actualArgs];

        switch (*sig) {
        case 'L':
            {
                ClassObject* clazz = lookupSignatureClass(meth, &sig, pFailure);
                if (!VERIFY_OK(*pFailure))
                    goto bad_sig;
                verifyRegisterType(registerLine, getReg,
                    regTypeFromClass(clazz), pFailure);
                if (!VERIFY_OK(*pFailure)) {
                    LOG_VFY("VFY: bad arg %d (into %s)\n",
                            actualArgs, clazz->descriptor);
                    goto bad_sig;
                }
            }
            actualArgs++;
            break;
        case '[':
            {
                ClassObject* clazz =
                    lookupSignatureArrayClass(meth, &sig, pFailure);
                if (!VERIFY_OK(*pFailure))
                    goto bad_sig;
                verifyRegisterType(registerLine, getReg,
                    regTypeFromClass(clazz), pFailure);
                if (!VERIFY_OK(*pFailure)) {
                    LOG_VFY("VFY: bad arg %d (into %s)\n",
                            actualArgs, clazz->descriptor);
                    goto bad_sig;
                }
            }
            actualArgs++;
            break;
        case 'Z':
            verifyRegisterType(registerLine, getReg, kRegTypeBoolean, pFailure);
            actualArgs++;
            break;
        case 'C':
            verifyRegisterType(registerLine, getReg, kRegTypeChar, pFailure);
            actualArgs++;
            break;
        case 'B':
            verifyRegisterType(registerLine, getReg, kRegTypeByte, pFailure);
            actualArgs++;
            break;
        case 'I':
            verifyRegisterType(registerLine, getReg, kRegTypeInteger, pFailure);
            actualArgs++;
            break;
        case 'S':
            verifyRegisterType(registerLine, getReg, kRegTypeShort, pFailure);
            actualArgs++;
            break;
        case 'F':
            verifyRegisterType(registerLine, getReg, kRegTypeFloat, pFailure);
            actualArgs++;
            break;
        case 'D':
            verifyRegisterType(registerLine, getReg, kRegTypeDoubleLo, pFailure);
            actualArgs += 2;
            break;
        case 'J':
            verifyRegisterType(registerLine, getReg, kRegTypeLongLo, pFailure);
            actualArgs += 2;
            break;
        default:
            LOG_VFY("VFY: invocation target: bad signature type char '%c'\n",
                *sig);
            goto bad_sig;
        }

        sig++;
    }
    if (*sig != ')') {
        char* desc = dexProtoCopyMethodDescriptor(&resMethod->prototype);
        LOG_VFY("VFY: invocation target: bad signature '%s'\n", desc);
        free(desc);
        goto bad_sig;
    }

    if (actualArgs != expectedArgs) {
        LOG_VFY("VFY: expected %d args, found %d\n", expectedArgs, actualArgs);
        goto bad_sig;
    }

    free(sigOriginal);
    return resMethod;

bad_sig:
    if (resMethod != NULL) {
        char* desc = dexProtoCopyMethodDescriptor(&resMethod->prototype);
        LOG_VFY("VFY:  rejecting call to %s.%s %s\n",
            resMethod->clazz->descriptor, resMethod->name, desc);
        free(desc);
    }

fail:
    free(sigOriginal);
    if (*pFailure == VERIFY_ERROR_NONE)
        *pFailure = VERIFY_ERROR_GENERIC;
    return NULL;
}

/*
 * Get the class object for the type of data stored in a field.  This isn't
 * stored in the Field struct, so we have to recover it from the signature.
 *
 * This only works for reference types.  Don't call this for primitive types.
 *
 * If we can't find the class, we return java.lang.Object, so that
 * verification can continue if a field is only accessed in trivial ways.
 */
static ClassObject* getFieldClass(const Method* meth, const Field* field)
{
    ClassObject* fieldClass;
    const char* signature = field->signature;

    if ((*signature == 'L') || (*signature == '[')) {
        fieldClass = dvmFindClassNoInit(signature,
                meth->clazz->classLoader);
    } else {
        return NULL;
    }

    if (fieldClass == NULL) {
        dvmClearOptException(dvmThreadSelf());
        LOGV("VFY: unable to find class '%s' for field %s.%s, trying Object\n",
            field->signature, meth->clazz->descriptor, field->name);
        fieldClass = gDvm.classJavaLangObject;
    } else {
        assert(!dvmIsPrimitiveClass(fieldClass));
    }
    return fieldClass;
}


/*
 * ===========================================================================
 *      Register operations
 * ===========================================================================
 */

/*
 * 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* registerLine, u4 vsrc)
{
    return registerLine->regTypes[vsrc];
}

/*
 * Get the value from a register, and cast it to a ClassObject.  Sets
 * "*pFailure" if something fails.
 *
 * This fails if the register holds an uninitialized class.
 *
 * If the register holds kRegTypeZero, this returns a NULL pointer.
 */
static ClassObject* getClassFromRegister(const RegisterLine* registerLine,
    u4 vsrc, VerifyError* pFailure)
{
    ClassObject* clazz = NULL;
    RegType type;

    /* get the element type of the array held in vsrc */
    type = getRegisterType(registerLine, vsrc);

    /* if "always zero", we allow it to fail at runtime */
    if (type == kRegTypeZero)
        goto bail;

    if (!regTypeIsReference(type)) {
        LOG_VFY("VFY: tried to get class from non-ref register v%d (type=%d)\n",
            vsrc, type);
        *pFailure = VERIFY_ERROR_GENERIC;
        goto bail;
    }
    if (regTypeIsUninitReference(type)) {
        LOG_VFY("VFY: register %u holds uninitialized reference\n", vsrc);
        *pFailure = VERIFY_ERROR_GENERIC;
        goto bail;
    }

    clazz = regTypeInitializedReferenceToClass(type);

bail:
    return clazz;
}

/*
 * 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* registerLine,
    const DecodedInstruction* pDecInsn, VerifyError* pFailure)
{
    RegType thisType = kRegTypeUnknown;

    if (pDecInsn->vA < 1) {
        LOG_VFY("VFY: invoke lacks 'this'\n");
        *pFailure = VERIFY_ERROR_GENERIC;
        goto bail;
    }

    /* get the element type of the array held in vsrc */
    thisType = getRegisterType(registerLine, pDecInsn->vC);
    if (!regTypeIsReference(thisType)) {
        LOG_VFY("VFY: tried to get class from non-ref register v%d (type=%d)\n",
            pDecInsn->vC, thisType);
        *pFailure = VERIFY_ERROR_GENERIC;
        goto bail;
    }

bail:
    return thisType;
}

/*
 * Set the type of register N, verifying that the register is valid.  If
 * "newType" is the "Lo" part of a 64-bit value, register N+1 will be
 * set to "newType+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* registerLine, u4 vdst,
    RegType newType)
{
    RegType* insnRegs = registerLine->regTypes;

    switch (newType) {
    case kRegTypeUnknown:
    case kRegTypeBoolean:
    case kRegTypeOne:
    case kRegTypeByte:
    case kRegTypePosByte:
    case kRegTypeShort:
    case kRegTypePosShort:
    case kRegTypeChar:
    case kRegTypeInteger:
    case kRegTypeFloat:
    case kRegTypeZero:
    case kRegTypeUninit:
        insnRegs[vdst] = newType;
        break;
    case kRegTypeLongLo:
    case kRegTypeDoubleLo:
        insnRegs[vdst] = newType;
        insnRegs[vdst+1] = newType+1;
        break;
    case kRegTypeLongHi:
    case kRegTypeDoubleHi:
        /* should never set these explicitly */
        LOGE("BUG: explicit set of high register type\n");
        dvmAbort();
        break;

    default:
        /* can't switch for ref types, so we check explicitly */
        if (regTypeIsReference(newType)) {
            insnRegs[vdst] = newType;

            /*
             * In most circumstances we won't see a reference to a primitive
             * class here (e.g. "D"), since that would mean the object in the
             * register is actually a primitive type.  It can happen as the
             * result of an assumed-successful check-cast instruction in
             * which the second argument refers to a primitive class.  (In
             * practice, such an instruction will always throw an exception.)
             *
             * This is not an issue for instructions like const-class, where
             * the object in the register is a java.lang.Class instance.
             */
            break;
        }
        /* bad type - fall through */

    case kRegTypeConflict:      // should only be set during a merge
        LOGE("BUG: set register to unknown type %d\n", newType);
        dvmAbort();
        break;
    }

    /*
     * Clear the monitor entry bits for this register.
     */
    if (registerLine->monitorEntries != NULL)
        registerLine->monitorEntries[vdst] = 0;
}

/*
 * Verify that the contents of the specified register have the specified
 * type (or can be converted to it through an implicit widening conversion).
 *
 * In theory we could use this to modify the type of the source register,
 * e.g. a generic 32-bit constant, once used as a float, would thereafter
 * remain a float.  There is no compelling reason to require this though.
 *
 * 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 checkType, or if checkType is an
 * interface, verify that the register implements checkType.
 */
static void verifyRegisterType(const RegisterLine* registerLine, u4 vsrc,
    RegType checkType, VerifyError* pFailure)
{
    const RegType* insnRegs = registerLine->regTypes;
    RegType srcType = insnRegs[vsrc];

    //LOGD("check-reg v%u = %d\n", vsrc, checkType);
    switch (checkType) {
    case kRegTypeFloat:
    case kRegTypeBoolean:
    case kRegTypePosByte:
    case kRegTypeByte:
    case kRegTypePosShort:
    case kRegTypeShort:
    case kRegTypeChar:
    case kRegTypeInteger:
        if (!canConvertTo1nr(srcType, checkType)) {
            LOG_VFY("VFY: register1 v%u type %d, wanted %d\n",
                vsrc, srcType, checkType);
            *pFailure = VERIFY_ERROR_GENERIC;
        }
        break;
    case kRegTypeLongLo:
    case kRegTypeDoubleLo:
        if (insnRegs[vsrc+1] != srcType+1) {
            LOG_VFY("VFY: register2 v%u-%u values %d,%d\n",
                vsrc, vsrc+1, insnRegs[vsrc], insnRegs[vsrc+1]);
            *pFailure = VERIFY_ERROR_GENERIC;
        } else if (!canConvertTo2(srcType, checkType)) {
            LOG_VFY("VFY: register2 v%u type %d, wanted %d\n",
                vsrc, srcType, checkType);
            *pFailure = VERIFY_ERROR_GENERIC;
        }
        break;

    case kRegTypeLongHi:
    case kRegTypeDoubleHi:
    case kRegTypeZero:
    case kRegTypeOne:
    case kRegTypeUnknown:
    case kRegTypeConflict:
        /* should never be checking for these explicitly */
        assert(false);
        *pFailure = VERIFY_ERROR_GENERIC;
        return;
    case kRegTypeUninit:
    default:
        /* make sure checkType is initialized reference */
        if (!regTypeIsReference(checkType)) {
            LOG_VFY("VFY: unexpected check type %d\n", checkType);
            assert(false);
            *pFailure = VERIFY_ERROR_GENERIC;
            break;
        }
        if (regTypeIsUninitReference(checkType)) {
            LOG_VFY("VFY: uninitialized ref not expected as reg check\n");
            *pFailure = VERIFY_ERROR_GENERIC;
            break;
        }
        /* make sure srcType is initialized reference or always-NULL */
        if (!regTypeIsReference(srcType)) {
            LOG_VFY("VFY: register1 v%u type %d, wanted ref\n", vsrc, srcType);
            *pFailure = VERIFY_ERROR_GENERIC;
            break;
        }
        if (regTypeIsUninitReference(srcType)) {
            LOG_VFY("VFY: register1 v%u holds uninitialized ref\n", vsrc);
            *pFailure = VERIFY_ERROR_GENERIC;
            break;
        }
        /* if the register isn't Zero, make sure it's an instance of check */
        if (srcType != kRegTypeZero) {
            ClassObject* srcClass = regTypeInitializedReferenceToClass(srcType);
            ClassObject* checkClass = regTypeInitializedReferenceToClass(checkType);
            assert(srcClass != NULL);
            assert(checkClass != NULL);

            if (dvmIsInterfaceClass(checkClass)) {
                /*
                 * All objects implement all interfaces as far as the
                 * verifier is concerned.  The runtime has to sort it out.
                 * See comments above findCommonSuperclass.
                 */
                /*
                if (srcClass != checkClass &&
                    !dvmImplements(srcClass, checkClass))
                {
                    LOG_VFY("VFY: %s does not implement %s\n",
                            srcClass->descriptor, checkClass->descriptor);
                    *pFailure = VERIFY_ERROR_GENERIC;
                }
                */
            } else {
                if (!dvmInstanceof(srcClass, checkClass)) {
                    LOG_VFY("VFY: %s is not instance of %s\n",
                            srcClass->descriptor, checkClass->descriptor);
                    *pFailure = VERIFY_ERROR_GENERIC;
                }
            }
        }
        break;
    }
}

/*
 * Set the type of the "result" register.
 */
static void setResultRegisterType(RegisterLine* registerLine,
    const int insnRegCount, RegType newType)
{
    setRegisterType(registerLine, RESULT_REGISTER(insnRegCount), newType);
}


/*
 * Update all registers holding "uninitType" 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* registerLine, int insnRegCount,
    UninitInstanceMap* uninitMap, RegType uninitType, VerifyError* pFailure)
{
    RegType* insnRegs = registerLine->regTypes;
    ClassObject* clazz;
    RegType initType;
    int i, changed;

    clazz = getUninitInstance(uninitMap, regTypeToUninitIndex(uninitType));
    if (clazz == NULL) {
        LOGE("VFY: unable to find type=0x%x (idx=%d)\n",
            uninitType, regTypeToUninitIndex(uninitType));
        *pFailure = VERIFY_ERROR_GENERIC;
        return;
    }
    initType = regTypeFromClass(clazz);

    changed = 0;
    for (i = 0; i < insnRegCount; i++) {
        if (insnRegs[i] == uninitType) {
            insnRegs[i] = initType;
            changed++;
        }
    }
    //LOGD("VFY: marked %d registers as initialized\n", changed);
    assert(changed > 0);

    return;
}

/*
 * 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* registerLine,
    int insnRegCount, UninitInstanceMap* uninitMap, RegType uninitType)
{
    RegType* insnRegs = registerLine->regTypes;
    int i, changed;

    changed = 0;
    for (i = 0; i < insnRegCount; i++) {
        if (insnRegs[i] == uninitType) {
            insnRegs[i] = kRegTypeConflict;
            if (registerLine->monitorEntries != NULL)
                registerLine->monitorEntries[i] = 0;
            changed++;
        }
    }

    //if (changed)
    //    LOGD("VFY: marked %d uninitialized registers as invalid\n", changed);
}

/*
 * Find the register line for the specified instruction in the current method.
 */
static inline RegisterLine* getRegisterLine(const RegisterTable* regTable,
    int insnIdx)
{
    return &regTable->registerLines[insnIdx];
}

/*
 * Copy a register line.
 */
static inline void copyRegisterLine(RegisterLine* dst, const RegisterLine* src,
    size_t numRegs)
{
    memcpy(dst->regTypes, src->regTypes, numRegs * sizeof(RegType));

    assert((src->monitorEntries == NULL && dst->monitorEntries == NULL) ||
           (src->monitorEntries != NULL && dst->monitorEntries != NULL));
    if (dst->monitorEntries != NULL) {
        assert(dst->monitorStack != NULL);
        memcpy(dst->monitorEntries, src->monitorEntries,
            numRegs * sizeof(MonitorEntries));
        memcpy(dst->monitorStack, src->monitorStack,
            kMaxMonitorStackDepth * sizeof(u4));
        dst->monitorStackTop = src->monitorStackTop;
    }
}

/*
 * Copy a register line into the table.
 */
static inline void copyLineToTable(RegisterTable* regTable, int insnIdx,
    const RegisterLine* src)
{
    RegisterLine* dst = getRegisterLine(regTable, insnIdx);
    assert(dst->regTypes != NULL);
    copyRegisterLine(dst, src, regTable->insnRegCountPlus);
}

/*
 * Copy a register line out of the table.
 */
static inline void copyLineFromTable(RegisterLine* dst,
    const RegisterTable* regTable, int insnIdx)
{
    RegisterLine* src = getRegisterLine(regTable, insnIdx);
    assert(src->regTypes != NULL);
    copyRegisterLine(dst, src, regTable->insnRegCountPlus);
}


#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* regTable,
    int insnIdx, const RegisterLine* line2)
{
    const RegisterLine* line1 = getRegisterLine(regTable, insnIdx);
    if (line1->monitorEntries != NULL) {
        int result;

        if (line2->monitorEntries == NULL)
            return 1;
        result = memcmp(line1->monitorEntries, line2->monitorEntries,
            regTable->insnRegCountPlus * sizeof(MonitorEntries));
        if (result != 0) {
            LOG_VFY("monitorEntries mismatch\n");
            return result;
        }
        result = line1->monitorStackTop - line2->monitorStackTop;
        if (result != 0) {
            LOG_VFY("monitorStackTop mismatch\n");
            return result;
        }
        result = memcmp(line1->monitorStack, line2->monitorStack,
            line1->monitorStackTop);
        if (result != 0) {
            LOG_VFY("monitorStack mismatch\n");
            return result;
        }
    }
    return memcmp(line1->regTypes, line2->regTypes,
            regTable->insnRegCountPlus * sizeof(RegType));
}
#endif

/*
 * 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.
 */
typedef enum TypeCategory {
    kTypeCategoryUnknown = 0,
    kTypeCategory1nr,           // boolean, byte, char, short, int, float
    kTypeCategory2,             // long, double
    kTypeCategoryRef,           // object reference
} TypeCategory;

/*
 * 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 "*pFailure" if something looks wrong.
 */
static void checkTypeCategory(RegType type, TypeCategory cat,
    VerifyError* pFailure)
{
    switch (cat) {
    case kTypeCategory1nr:
        switch (type) {
        case kRegTypeFloat:
        case kRegTypeZero:
        case kRegTypeOne:
        case kRegTypeBoolean:
        case kRegTypePosByte:
        case kRegTypeByte:
        case kRegTypePosShort:
        case kRegTypeShort:
        case kRegTypeChar:
        case kRegTypeInteger:
            break;
        default:
            *pFailure = VERIFY_ERROR_GENERIC;
            break;
        }
        break;

    case kTypeCategory2:
        switch (type) {
        case kRegTypeLongLo:
        case kRegTypeDoubleLo:
            break;
        default:
            *pFailure = VERIFY_ERROR_GENERIC;
            break;
        }
        break;

    case kTypeCategoryRef:
        if (type != kRegTypeZero && !regTypeIsReference(type))
            *pFailure = VERIFY_ERROR_GENERIC;
        break;

    default:
        assert(false);
        *pFailure = VERIFY_ERROR_GENERIC;
        break;
    }
}

/*
 * For a category 2 register pair, verify that "typeh" is the appropriate
 * high part for "typel".
 *
 * Does not verify that "typel" is in fact the low part of a 64-bit
 * register pair.
 */
static void checkWidePair(RegType typel, RegType typeh, VerifyError* pFailure)
{
    if ((typeh != typel+1))
        *pFailure = VERIFY_ERROR_GENERIC;
}

/*
 * Implement category-1 "move" instructions.  Copy a 32-bit value from
 * "vsrc" to "vdst".
 */
static void copyRegister1(RegisterLine* registerLine, u4 vdst, u4 vsrc,
    TypeCategory cat, VerifyError* pFailure)
{
    assert(cat == kTypeCategory1nr || cat == kTypeCategoryRef);
    RegType type = getRegisterType(registerLine, vsrc);
    checkTypeCategory(type, cat, pFailure);
    if (!VERIFY_OK(*pFailure)) {
        LOG_VFY("VFY: copy1 v%u<-v%u type=%d cat=%d\n", vdst, vsrc, type, cat);
    } else {
        setRegisterType(registerLine, vdst, type);
        if (cat == kTypeCategoryRef && registerLine->monitorEntries != NULL) {
            registerLine->monitorEntries[vdst] =
                registerLine->monitorEntries[vsrc];
        }
    }
}

/*
 * 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* registerLine, u4 vdst, u4 vsrc,
    VerifyError* pFailure)
{
    RegType typel = getRegisterType(registerLine, vsrc);
    RegType typeh = getRegisterType(registerLine, vsrc+1);

    checkTypeCategory(typel, kTypeCategory2, pFailure);
    checkWidePair(typel, typeh, pFailure);
    if (!VERIFY_OK(*pFailure)) {
        LOG_VFY("VFY: copy2 v%u<-v%u type=%d/%d\n", vdst, vsrc, typel, typeh);
    } else {
        setRegisterType(registerLine, vdst, typel);
        /* target monitor stack bits will be cleared */
    }
}

/*
 * Implement "move-result".  Copy the category-1 value from the result
 * register to another register, and reset the result register.
 */
static void copyResultRegister1(RegisterLine* registerLine,
    const int insnRegCount, u4 vdst, TypeCategory cat, VerifyError* pFailure)
{
    RegType type;
    u4 vsrc;

    assert(vdst < (u4) insnRegCount);

    vsrc = RESULT_REGISTER(insnRegCount);
    type = getRegisterType(registerLine, vsrc);
    checkTypeCategory(type, cat, pFailure);
    if (!VERIFY_OK(*pFailure)) {
        LOG_VFY("VFY: copyRes1 v%u<-v%u cat=%d type=%d\n",
            vdst, vsrc, cat, type);
    } else {
        setRegisterType(registerLine, vdst, type);
        setRegisterType(registerLine, vsrc, kRegTypeUnknown);
        /* target monitor stack bits will be cleared */
    }
}

/*
 * 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* registerLine,
    const int insnRegCount, u4 vdst, VerifyError* pFailure)
{
    RegType typel, typeh;
    u4 vsrc;

    assert(vdst < (u4) insnRegCount);

    vsrc = RESULT_REGISTER(insnRegCount);
    typel = getRegisterType(registerLine, vsrc);
    typeh = getRegisterType(registerLine, vsrc+1);
    checkTypeCategory(typel, kTypeCategory2, pFailure);
    checkWidePair(typel, typeh, pFailure);
    if (!VERIFY_OK(*pFailure)) {
        LOG_VFY("VFY: copyRes2 v%u<-v%u type=%d/%d\n",
            vdst, vsrc, typel, typeh);
    } else {
        setRegisterType(registerLine, vdst, typel);
        setRegisterType(registerLine, vsrc, kRegTypeUnknown);
        setRegisterType(registerLine, vsrc+1, kRegTypeUnknown);
        /* target monitor stack bits will be cleared */
    }
}

/*
 * Verify types for a simple two-register instruction (e.g. "neg-int").
 * "dstType" is stored into vA, and "srcType" is verified against vB.
 */
static void checkUnop(RegisterLine* registerLine, DecodedInstruction* pDecInsn,
    RegType dstType, RegType srcType, VerifyError* pFailure)
{
    verifyRegisterType(registerLine, pDecInsn->vB, srcType, pFailure);
    setRegisterType(registerLine, pDecInsn->vA, dstType);
}

/*
 * 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* registerLine, u4 reg1, u4 reg2)
{
    RegType type1, type2;

    type1 = getRegisterType(registerLine, reg1);
    type2 = getRegisterType(registerLine, reg2);

    if ((type1 == kRegTypeBoolean || type1 == kRegTypeZero ||
            type1 == kRegTypeOne) &&
        (type2 == kRegTypeBoolean || type2 == kRegTypeZero ||
            type2 == kRegTypeOne))
    {
        return true;
    }
    return false;
}

/*
 * Verify types for A two-register instruction with a literal constant
 * (e.g. "add-int/lit8").  "dstType" is stored into vA, and "srcType" is
 * verified against vB.
 *
 * If "checkBooleanOp" is set, we use the constant value in vC.
 */
static void checkLitop(RegisterLine* registerLine, DecodedInstruction* pDecInsn,
    RegType dstType, RegType srcType, bool checkBooleanOp,
    VerifyError* pFailure)
{
    verifyRegisterType(registerLine, pDecInsn->vB, srcType, pFailure);
    if (VERIFY_OK(*pFailure) && checkBooleanOp) {
        assert(dstType == kRegTypeInteger);
        /* check vB with the call, then check the constant manually */
        if (upcastBooleanOp(registerLine, pDecInsn->vB, pDecInsn->vB)
            && (pDecInsn->vC == 0 || pDecInsn->vC == 1))
        {
            dstType = kRegTypeBoolean;
        }
    }
    setRegisterType(registerLine, pDecInsn->vA, dstType);
}

/*
 * Verify types for a simple three-register instruction (e.g. "add-int").
 * "dstType" is stored into vA, and "srcType1"/"srcType2" are verified
 * against vB/vC.
 */
static void checkBinop(RegisterLine* registerLine, DecodedInstruction* pDecInsn,
    RegType dstType, RegType srcType1, RegType srcType2, bool checkBooleanOp,
    VerifyError* pFailure)
{
    verifyRegisterType(registerLine, pDecInsn->vB, srcType1, pFailure);
    verifyRegisterType(registerLine, pDecInsn->vC, srcType2, pFailure);
    if (VERIFY_OK(*pFailure) && checkBooleanOp) {
        assert(dstType == kRegTypeInteger);
        if (upcastBooleanOp(registerLine, pDecInsn->vB, pDecInsn->vC))
            dstType = kRegTypeBoolean;
    }
    setRegisterType(registerLine, pDecInsn->vA, dstType);
}

/*
 * Verify types for a binary "2addr" operation.  "srcType1"/"srcType2"
 * are verified against vA/vB, then "dstType" is stored into vA.
 */
static void checkBinop2addr(RegisterLine* registerLine,
    DecodedInstruction* pDecInsn, RegType dstType, RegType srcType1,
    RegType srcType2, bool checkBooleanOp, VerifyError* pFailure)
{
    verifyRegisterType(registerLine, pDecInsn->vA, srcType1, pFailure);
    verifyRegisterType(registerLine, pDecInsn->vB, srcType2, pFailure);
    if (VERIFY_OK(*pFailure) && checkBooleanOp) {
        assert(dstType == kRegTypeInteger);
        if (upcastBooleanOp(registerLine, pDecInsn->vA, pDecInsn->vB))
            dstType = kRegTypeBoolean;
    }
    setRegisterType(registerLine, pDecInsn->vA, dstType);
}

/*
 * 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* registerLine, int reg,
    unsigned int shiftCount, bool isUnsignedShift, VerifyError* pFailure)
{
    RegType srcType = getRegisterType(registerLine, reg);
    RegType newType;

    /* no-op */
    if (shiftCount == 0)
        return srcType;

    /* safe defaults */
    if (isUnsignedShift)
        newType = kRegTypeInteger;
    else
        newType = srcType;

    if (shiftCount >= 32) {
        LOG_VFY("Got unexpectedly large shift count %u\n", shiftCount);
        /* fail? */
        return newType;
    }

    switch (srcType) {
    case kRegTypeInteger:               /* 32-bit signed value */
    case kRegTypeFloat:                 /* (allowed; treat same as int) */
        if (isUnsignedShift) {
            if (shiftCount > 24)
                newType = kRegTypePosByte;
            else if (shiftCount >= 16)
                newType = kRegTypeChar;
        } else {
            if (shiftCount >= 24)
                newType = kRegTypeByte;
            else if (shiftCount >= 16)
                newType = kRegTypeShort;
        }
        break;
    case kRegTypeShort:                 /* 16-bit signed value */
        if (isUnsignedShift) {
            /* default (kRegTypeInteger) is correct */
        } else {
            if (shiftCount >= 8)
                newType = kRegTypeByte;
        }
        break;
    case kRegTypePosShort:              /* 15-bit unsigned value */
        if (shiftCount >= 8)
            newType = kRegTypePosByte;
        break;
    case kRegTypeChar:                  /* 16-bit unsigned value */
        if (shiftCount > 8)
            newType = kRegTypePosByte;
        break;
    case kRegTypeByte:                  /* 8-bit signed value */
        /* defaults (u=kRegTypeInteger / s=srcType) are correct */
        break;
    case kRegTypePosByte:               /* 7-bit unsigned value */
        /* always use newType=srcType */
        newType = srcType;
        break;
    case kRegTypeZero:                  /* 1-bit unsigned value */
    case kRegTypeOne:
    case kRegTypeBoolean:
        /* unnecessary? */
        newType = kRegTypeZero;
        break;
    default:
        /* long, double, references; shouldn't be here! */
        assert(false);
        break;
    }

    if (newType != srcType) {
        LOGVV("narrowing: %d(%d) --> %d to %d\n",
            shiftCount, isUnsignedShift, srcType, newType);
    } else {
        LOGVV("not narrowed: %d(%d) --> %d\n",
            shiftCount, isUnsignedShift, srcType);
    }
    return newType;
}


/*
 * ===========================================================================
 *      Register merge
 * ===========================================================================
 */

/*
 * 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(ClassObject* clazz)
{
    int depth = 0;

    while (clazz->super != NULL) {
        clazz = clazz->super;
        depth++;
    }
    return depth;
}

/*
 * 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 ClassObject* digForSuperclass(ClassObject* c1, ClassObject* c2)
{
    int depth1, depth2;

    depth1 = getClassDepth(c1);
    depth2 = getClassDepth(c2);

    if (gDebugVerbose) {
        LOGVV("COMMON: %s(%d) + %s(%d)\n",
            c1->descriptor, depth1, c2->descriptor, depth2);
    }

    /* pull the deepest one up */
    if (depth1 > depth2) {
        while (depth1 > depth2) {
            c1 = c1->super;
            depth1--;
        }
    } else {
        while (depth2 > depth1) {
            c2 = c2->super;
            depth2--;
        }
    }

    /* walk up in lock-step */
    while (c1 != c2) {
        c1 = c1->super;
        c2 = c2->super;

        assert(c1 != NULL && c2 != NULL);
    }

    if (gDebugVerbose) {
        LOGVV("      : --> %s\n", c1->descriptor);
    }
    return c1;
}

/*
 * 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 ClassObject* findCommonArraySuperclass(ClassObject* c1, ClassObject* c2)
{
    ClassObject* arrayClass = NULL;
    ClassObject* commonElem;
    int arrayDim1, arrayDim2;
    int i, numDims;
    bool hasPrimitive = false;

    arrayDim1 = c1->arrayDim;
    arrayDim2 = c2->arrayDim;
    assert(c1->arrayDim > 0);
    assert(c2->arrayDim > 0);

    if (dvmIsPrimitiveClass(c1->elementClass)) {
        arrayDim1--;
        hasPrimitive = true;
    }
    if (dvmIsPrimitiveClass(c2->elementClass)) {
        arrayDim2--;
        hasPrimitive = true;
    }

    if (!hasPrimitive && arrayDim1 == arrayDim2) {
        /*
         * Two arrays of reference types with equal dimensions.  Try to
         * find a good match.
         */
        commonElem = findCommonSuperclass(c1->elementClass, c2->elementClass);
        numDims = arrayDim1;
    } else {
        /*
         * Mismatched array depths and/or array(s) of primitives.  We want
         * Object, or an Object array with appropriate dimensions.
         *
         * We initialize arrayClass to Object here, because it's possible
         * for us to set numDims=0.
         */
        if (arrayDim1 < arrayDim2)
            numDims = arrayDim1;
        else
            numDims = arrayDim2;
        arrayClass = commonElem = c1->super;     // == java.lang.Object
    }

    /*
     * Find an appropriately-dimensioned array class.  This is easiest
     * to do iteratively, using the array class found by the current round
     * as the element type for the next round.
     */
    for (i = 0; i < numDims; i++) {
        arrayClass = dvmFindArrayClassForElement(commonElem);
        commonElem = arrayClass;
    }
    assert(arrayClass != NULL);

    LOGVV("ArrayMerge '%s' + '%s' --> '%s'\n",
        c1->descriptor, c2->descriptor, arrayClass->descriptor);
    return arrayClass;
}

/*
 * 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 ClassObject* findCommonSuperclass(ClassObject* c1, ClassObject* c2)
{
    assert(!dvmIsPrimitiveClass(c1) && !dvmIsPrimitiveClass(c2));

    if (c1 == c2)
        return c1;

    if (dvmIsInterfaceClass(c1) && dvmImplements(c2, c1)) {
        if (gDebugVerbose)
            LOGVV("COMMON/I1: %s + %s --> %s\n",
                c1->descriptor, c2->descriptor, c1->descriptor);
        return c1;
    }
    if (dvmIsInterfaceClass(c2) && dvmImplements(c1, c2)) {
        if (gDebugVerbose)
            LOGVV("COMMON/I2: %s + %s --> %s\n",
                c1->descriptor, c2->descriptor, c2->descriptor);
        return c2;
    }

    if (dvmIsArrayClass(c1) && dvmIsArrayClass(c2)) {
        return findCommonArraySuperclass(c1, c2);
    }

    return digForSuperclass(c1, c2);
}

/*
 * Merge two RegType values.
 *
 * Sets "*pChanged" to "true" if the result doesn't match "type1".
 */
static RegType mergeTypes(RegType type1, RegType type2, bool* pChanged)
{
    RegType result;

    /*
     * Check for trivial case so we don't have to hit memory.
     */
    if (type1 == type2)
        return type1;

    /*
     * Use the table if we can, and reject any attempts to merge something
     * from the table with a reference type.
     *
     * Uninitialized references are composed of the enum ORed with an
     * index value.  The uninitialized table entry at index zero *will*
     * show up as a simple kRegTypeUninit value.  Since this cannot be
     * merged with anything but itself, the rules do the right thing.
     */
    if (type1 < kRegTypeMAX) {
        if (type2 < kRegTypeMAX) {
            result = gDvmMergeTab[type1][type2];
        } else {
            /* simple + reference == conflict, usually */
            if (type1 == kRegTypeZero)
                result = type2;
            else
                result = kRegTypeConflict;
        }
    } else {
        if (type2 < kRegTypeMAX) {
            /* reference + simple == conflict, usually */
            if (type2 == kRegTypeZero)
                result = type1;
            else
                result = kRegTypeConflict;
        } else {
            /* merging two references */
            if (regTypeIsUninitReference(type1) ||
                regTypeIsUninitReference(type2))
            {
                /* can't merge uninit with anything but self */
                result = kRegTypeConflict;
            } else {
                ClassObject* clazz1 = regTypeInitializedReferenceToClass(type1);
                ClassObject* clazz2 = regTypeInitializedReferenceToClass(type2);
                ClassObject* mergedClass;

                mergedClass = findCommonSuperclass(clazz1, clazz2);
                assert(mergedClass != NULL);
                result = regTypeFromClass(mergedClass);
            }
        }
    }

    if (result != type1)
        *pChanged = true;
    return result;
}

/*
 * 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* pChanged)
{
    MonitorEntries result = ents1 & ents2;
    if (result != ents1)
        *pChanged = true;
    return result;
}

/*
 * Control can transfer to "nextInsn".
 *
 * Merge the registers from "workLine" into "regTable" at "nextInsn", and
 * set the "changed" flag on the target address if any of the registers
 * has changed.
 *
 * Returns "false" if we detect mis-matched monitor stacks.
 */
static bool updateRegisters(const Method* meth, InsnFlags* insnFlags,
    RegisterTable* regTable, int nextInsn, const RegisterLine* workLine)
{
    const size_t insnRegCountPlus = regTable->insnRegCountPlus;
    assert(workLine != NULL);
    const RegType* workRegs = workLine->regTypes;

    if (!dvmInsnIsVisitedOrChanged(insnFlags, nextInsn)) {
        /*
         * We haven't processed this instruction before, and we haven't
         * touched the registers here, so there's nothing to "merge".  Copy
         * the registers over and mark it as changed.  (This is the only
         * way a register can transition out of "unknown", so this is not
         * just an optimization.)
         */
        LOGVV("COPY into 0x%04x\n", nextInsn);
        copyLineToTable(regTable, nextInsn, workLine);
        dvmInsnSetChanged(insnFlags, nextInsn, true);
#ifdef VERIFIER_STATS
        gDvm.verifierStats.copyRegCount++;
#endif
    } else {
        if (gDebugVerbose) {
            LOGVV("MERGE into 0x%04x\n", nextInsn);
            //dumpRegTypes(vdata, targetRegs, 0, "targ", NULL, 0);
            //dumpRegTypes(vdata, workRegs, 0, "work", NULL, 0);
        }
        /* merge registers, set Changed only if different */
        RegisterLine* targetLine = getRegisterLine(regTable, nextInsn);
        RegType* targetRegs = targetLine->regTypes;
        MonitorEntries* workMonEnts = workLine->monitorEntries;
        MonitorEntries* targetMonEnts = targetLine->monitorEntries;
        bool changed = false;
        unsigned int idx;

        assert(targetRegs != NULL);

        if (targetMonEnts != NULL) {
            /*
             * Monitor stacks must be identical.
             */
            if (targetLine->monitorStackTop != workLine->monitorStackTop) {
                LOG_VFY_METH(meth,
                    "VFY: mismatched stack depth %d vs. %d at 0x%04x\n",
                    targetLine->monitorStackTop, workLine->monitorStackTop,
                    nextInsn);
                return false;
            }
            if (memcmp(targetLine->monitorStack, workLine->monitorStack,
                    targetLine->monitorStackTop * sizeof(u4)) != 0)
            {
                LOG_VFY_METH(meth, "VFY: mismatched monitor stacks at 0x%04x\n",
                    nextInsn);
                return false;
            }
        }

        for (idx = 0; idx < insnRegCountPlus; idx++) {
            targetRegs[idx] =
                    mergeTypes(targetRegs[idx], workRegs[idx], &changed);

            if (targetMonEnts != NULL) {
                targetMonEnts[idx] = mergeMonitorEntries(targetMonEnts[idx],
                    workMonEnts[idx], &changed);
            }
        }

        if (gDebugVerbose) {
            //LOGI(" RESULT (changed=%d)\n", changed);
            //dumpRegTypes(vdata, targetRegs, 0, "rslt", NULL, 0);
        }
#ifdef VERIFIER_STATS
        gDvm.verifierStats.mergeRegCount++;
        if (changed)
            gDvm.verifierStats.mergeRegChanged++;
#endif

        if (changed)
            dvmInsnSetChanged(insnFlags, nextInsn, true);
    }

    return true;
}


/*
 * ===========================================================================
 *      Utility functions
 * ===========================================================================
 */

/*
 * Look up an instance field, specified by "fieldIdx", that is going to be
 * accessed in object "objType".  This resolves the field and then verifies
 * that the class containing the field is an instance of the reference in
 * "objType".
 *
 * It is possible for "objType" 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, "objType" 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 "objType" class.
 *
 * Returns an InstField on success, returns NULL and sets "*pFailure"
 * on failure.
 */
static InstField* getInstField(const Method* meth,
    const UninitInstanceMap* uninitMap, RegType objType, int fieldIdx,
    VerifyError* pFailure)
{
    InstField* instField = NULL;
    ClassObject* objClass;
    bool mustBeLocal = false;

    if (!regTypeIsReference(objType)) {
        LOG_VFY("VFY: attempt to access field in non-reference type %d\n",
            objType);
        *pFailure = VERIFY_ERROR_GENERIC;
        goto bail;
    }

    instField = dvmOptResolveInstField(meth->clazz, fieldIdx, pFailure);
    if (instField == NULL) {
        LOG_VFY("VFY: unable to resolve instance field %u\n", fieldIdx);
        assert(!VERIFY_OK(*pFailure));
        goto bail;
    }

    if (objType == kRegTypeZero)
        goto bail;

    /*
     * Access to fields in uninitialized objects is allowed if this is
     * the <init> method for the object and the field in question is
     * declared by this class.
     */
    objClass = regTypeReferenceToClass(objType, uninitMap);
    assert(objClass != NULL);
    if (regTypeIsUninitReference(objType)) {
        if (!isInitMethod(meth) || meth->clazz != objClass) {
            LOG_VFY("VFY: attempt to access field via uninitialized ref\n");
            *pFailure = VERIFY_ERROR_GENERIC;
            goto bail;
        }
        mustBeLocal = true;
    }

    if (!dvmInstanceof(objClass, instField->field.clazz)) {
        LOG_VFY("VFY: invalid field access (field %s.%s, through %s ref)\n",
                instField->field.clazz->descriptor, instField->field.name,
                objClass->descriptor);
        *pFailure = VERIFY_ERROR_NO_FIELD;
        goto bail;
    }

    if (mustBeLocal) {
        /* for uninit ref, make sure it's defined by this class, not super */
        if (instField < objClass->ifields ||
            instField >= objClass->ifields + objClass->ifieldCount)
        {
            LOG_VFY("VFY: invalid constructor field access (field %s in %s)\n",
                    instField->field.name, objClass->descriptor);
            *pFailure = VERIFY_ERROR_GENERIC;
            goto bail;
        }
    }

bail:
    return instField;
}

/*
 * Look up a static field.
 *
 * Returns a StaticField on success, returns NULL and sets "*pFailure"
 * on failure.
 */
static StaticField* getStaticField(const Method* meth, int fieldIdx,
    VerifyError* pFailure)
{
    StaticField* staticField;

    staticField = dvmOptResolveStaticField(meth->clazz, fieldIdx, pFailure);
    if (staticField == NULL) {
        DexFile* pDexFile = meth->clazz->pDvmDex->pDexFile;
        const DexFieldId* pFieldId;

        pFieldId = dexGetFieldId(pDexFile, fieldIdx);

        LOG_VFY("VFY: unable to resolve static field %u (%s) in %s\n", fieldIdx,
            dexStringById(pDexFile, pFieldId->nameIdx),
            dexStringByTypeIdx(pDexFile, pFieldId->classIdx));
        assert(!VERIFY_OK(*pFailure));
        goto bail;
    }

bail:
    return staticField;
}

/*
 * If "field" is marked "final", make sure this is the either <clinit>
 * or <init> as appropriate.
 *
 * Sets "*pFailure" on failure.
 */
static void checkFinalFieldAccess(const Method* meth, const Field* field,
    VerifyError* pFailure)
{
    if (!dvmIsFinalField(field))
        return;

    /* make sure we're in the same class */
    if (meth->clazz != field->clazz) {
        LOG_VFY_METH(meth, "VFY: can't modify final field %s.%s\n",
            field->clazz->descriptor, field->name);
        *pFailure = VERIFY_ERROR_ACCESS_FIELD;
        return;
    }

    /*
     * The VM spec descriptions of putfield and putstatic say that
     * IllegalAccessError is only thrown when the instructions appear
     * outside the declaring class.  Our earlier attempts to restrict
     * final field modification to constructors are, therefore, wrong.
     */
#if 0
    /* make sure we're in the right kind of constructor */
    if (dvmIsStaticField(field)) {
        if (!isClassInitMethod(meth)) {
            LOG_VFY_METH(meth,
                "VFY: can't modify final static field outside <clinit>\n");
            *pFailure = VERIFY_ERROR_GENERIC;
        }
    } else {
        if (!isInitMethod(meth)) {
            LOG_VFY_METH(meth,
                "VFY: can't modify final field outside <init>\n");
            *pFailure = VERIFY_ERROR_GENERIC;
        }
    }
#endif
}

/*
 * Make sure that the register type is suitable for use as an array index.
 *
 * Sets "*pFailure" if not.
 */
static void checkArrayIndexType(const Method* meth, RegType regType,
    VerifyError* pFailure)
{
    if (VERIFY_OK(*pFailure)) {
        /*
         * The 1nr types are interchangeable at this level.  We could
         * do something special if we can definitively identify it as a
         * float, but there's no real value in doing so.
         */
        checkTypeCategory(regType, kTypeCategory1nr, pFailure);
        if (!VERIFY_OK(*pFailure)) {
            LOG_VFY_METH(meth, "Invalid reg type for array index (%d)\n",
                regType);
        }
    }
}

/*
 * 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* meth,
    const RegisterLine* registerLine, const int insnRegCount)
{
    const RegType* insnRegs = registerLine->regTypes;
    int i;

    if (!isInitMethod(meth))
        return true;

    RegType uninitThis = regTypeFromUninitIndex(kUninitThisArgSlot);

    for (i = 0; i < insnRegCount; i++) {
        if (insnRegs[i] == uninitThis) {
            LOG_VFY("VFY: <init> returning without calling superclass init\n");
            return false;
        }
    }
    return true;
}

/*
 * 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 Method* meth, int insnIdx,
    const char* logNote)
{
    assert(insnIdx >= 0 && insnIdx < (int)dvmGetMethodInsnsSize(meth));

    if ((meth->insns[insnIdx] & 0xff) == OP_MOVE_EXCEPTION) {
        LOG_VFY("VFY: invalid use of move-exception\n");
        return false;
    }
    return true;
}

/*
 * For the "move-exception" instruction at "insnIdx", 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 ClassObject* getCaughtExceptionType(const Method* meth, int insnIdx,
    VerifyError* pFailure)
{
    VerifyError localFailure;
    const DexCode* pCode;
    DexFile* pDexFile;
    ClassObject* commonSuper = NULL;
    bool foundPossibleHandler = false;
    u4 handlersSize;
    u4 offset;
    u4 i;

    pDexFile = meth->clazz->pDvmDex->pDexFile;
    pCode = dvmGetMethodCode(meth);

    if (pCode->triesSize != 0) {
        handlersSize = dexGetHandlersSize(pCode);
        offset = dexGetFirstHandlerOffset(pCode);
    } else {
        handlersSize = 0;
        offset = 0;
    }

    for (i = 0; i < handlersSize; i++) {
        DexCatchIterator iterator;
        dexCatchIteratorInit(&iterator, pCode, offset);

        for (;;) {
            const DexCatchHandler* handler = dexCatchIteratorNext(&iterator);

            if (handler == NULL) {
                break;
            }

            if (handler->address == (u4) insnIdx) {
                ClassObject* clazz;
                foundPossibleHandler = true;

                if (handler->typeIdx == kDexNoIndex)
                    clazz = gDvm.classJavaLangThrowable;
                else
                    clazz = dvmOptResolveClass(meth->clazz, handler->typeIdx,
                                &localFailure);

                if (clazz == NULL) {
                    LOG_VFY("VFY: unable to resolve exception class %u (%s)\n",
                        handler->typeIdx,
                        dexStringByTypeIdx(pDexFile, handler->typeIdx));
                    /* TODO: do we want to keep going?  If we don't fail
                     * this we run the risk of having a non-Throwable
                     * introduced at runtime.  However, that won't pass
                     * an instanceof test, so is essentially harmless. */
                } else {
                    if (commonSuper == NULL)
                        commonSuper = clazz;
                    else
                        commonSuper = findCommonSuperclass(clazz, commonSuper);
                }
            }
        }

        offset = dexCatchIteratorGetEndOffset(&iterator, pCode);
    }

    if (commonSuper == NULL) {
        /* no catch blocks, or no catches with classes we can find */
        LOG_VFY_METH(meth,
            "VFY: unable to find exception handler at addr 0x%x\n", insnIdx);
        *pFailure = VERIFY_ERROR_GENERIC;
    } else {
        // TODO: verify the class is an instance of Throwable?
    }

    return commonSuper;
}

/*
 * Helper for initRegisterTable.
 *
 * Returns an updated copy of "storage".
 */
static u1* assignLineStorage(u1* storage, RegisterLine* line,
    bool trackMonitors, size_t regTypeSize, size_t monEntSize, size_t stackSize)
{
    line->regTypes = (RegType*) storage;
    storage += regTypeSize;

    if (trackMonitors) {
        line->monitorEntries = (MonitorEntries*) storage;
        storage += monEntSize;
        line->monitorStack = (u4*) storage;
        storage += stackSize;

        assert(line->monitorStackTop == 0);
    }

    return storage;
}

/*
 * 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(const VerifierData* vdata,
    RegisterTable* regTable, RegisterTrackingMode trackRegsFor)
{
    const Method* meth = vdata->method;
    const int insnsSize = vdata->insnsSize;
    const InsnFlags* insnFlags = vdata->insnFlags;
    const int kExtraLines = 2;  /* workLine, savedLine */
    int i;

    /*
     * Every address gets a RegisterLine struct.  This is wasteful, but
     * not so much that it's worth chasing through an extra level of
     * indirection.
     */
    regTable->insnRegCountPlus = meth->registersSize + kExtraRegs;
    regTable->registerLines =
        (RegisterLine*) calloc(insnsSize, sizeof(RegisterLine));
    if (regTable->registerLines == NULL)
        return false;

    assert(insnsSize > 0);

    /*
     * Count up the number of "interesting" instructions.
     *
     * "All" means "every address that holds the start of an instruction".
     * "Branches" and "GcPoints" mean just those addresses.
     *
     * "GcPoints" fills about half the addresses, "Branches" about 15%.
     */
    int interestingCount = kExtraLines;

    for (i = 0; i < insnsSize; i++) {
        bool interesting;

        switch (trackRegsFor) {
        case kTrackRegsAll:
            interesting = dvmInsnIsOpcode(insnFlags, i);
            break;
        case kTrackRegsGcPoints:
            interesting = dvmInsnIsGcPoint(insnFlags, i) ||
                          dvmInsnIsBranchTarget(insnFlags, i);
            break;
        case kTrackRegsBranches:
            interesting = dvmInsnIsBranchTarget(insnFlags, i);
            break;
        default:
            dvmAbort();
            return false;
        }

        if (interesting)
            interestingCount++;

        /* count instructions, for display only */
        //if (dvmInsnIsOpcode(insnFlags, i))
        //    insnCount++;
    }

    /*
     * Allocate storage for the register type arrays.
     * TODO: set trackMonitors based on global config option
     */
    size_t regTypeSize = regTable->insnRegCountPlus * sizeof(RegType);
    size_t monEntSize = regTable->insnRegCountPlus * sizeof(MonitorEntries);
    size_t stackSize = kMaxMonitorStackDepth * sizeof(u4);
    bool trackMonitors;

    if (gDvm.monitorVerification) {
        trackMonitors = (vdata->monitorEnterCount != 0);
    } else {
        trackMonitors = false;
    }

    size_t spacePerEntry = regTypeSize +
        (trackMonitors ? monEntSize + stackSize : 0);
    regTable->lineAlloc = calloc(interestingCount, spacePerEntry);
    if (regTable->lineAlloc == NULL)
        return false;

#ifdef VERIFIER_STATS
    size_t totalSpace = interestingCount * spacePerEntry +
        insnsSize * sizeof(RegisterLine);
    if (gDvm.verifierStats.biggestAlloc < totalSpace)
        gDvm.verifierStats.biggestAlloc = totalSpace;
#endif

    /*
     * Populate the sparse register line table.
     *
     * There is a RegisterLine associated with every address, but not
     * every RegisterLine has non-NULL pointers to storage for its fields.
     */
    u1* storage = (u1*)regTable->lineAlloc;
    for (i = 0; i < insnsSize; i++) {
        bool interesting;

        switch (trackRegsFor) {
        case kTrackRegsAll:
            interesting = dvmInsnIsOpcode(insnFlags, i);
            break;
        case kTrackRegsGcPoints:
            interesting = dvmInsnIsGcPoint(insnFlags, i) ||
                          dvmInsnIsBranchTarget(insnFlags, i);
            break;
        case kTrackRegsBranches:
            interesting = dvmInsnIsBranchTarget(insnFlags, i);
            break;
        default:
            dvmAbort();
            return false;
        }

        if (interesting) {
            storage = assignLineStorage(storage, &regTable->registerLines[i],
                trackMonitors, regTypeSize, monEntSize, stackSize);
        }
    }

    /*
     * Grab storage for our "temporary" register lines.
     */
    storage = assignLineStorage(storage, &regTable->workLine,
        trackMonitors, regTypeSize, monEntSize, stackSize);
    storage = assignLineStorage(storage, &regTable->savedLine,
        trackMonitors, regTypeSize, monEntSize, stackSize);

    //LOGD("Tracking registers for [%d], total %d in %d units\n",
    //    trackRegsFor, interestingCount-kExtraLines, insnsSize);

    assert(storage - (u1*)regTable->lineAlloc ==
        (int) (interestingCount * spacePerEntry));
    assert(regTable->registerLines[0].regTypes != NULL);
    return true;
}

/*
 * Free up any "hairy" structures associated with register lines.
 */
static void freeRegisterLineInnards(VerifierData* vdata)
{
    unsigned int idx;

    if (vdata->registerLines == NULL)
        return;

    for (idx = 0; idx < vdata->insnsSize; idx++) {
        BitVector* liveRegs = vdata->registerLines[idx].liveRegs;
        if (liveRegs != NULL)
            dvmFreeBitVector(liveRegs);
    }
}


/*
 * Verify that the arguments in a filled-new-array instruction are valid.
 *
 * "resClass" is the class refered to by pDecInsn->vB.
 */
static void verifyFilledNewArrayRegs(const Method* meth,
    const RegisterLine* registerLine, const DecodedInstruction* pDecInsn,
    ClassObject* resClass, bool isRange, VerifyError* pFailure)
{
    u4 argCount = pDecInsn->vA;
    RegType expectedType;
    PrimitiveType elemType;
    unsigned int ui;

    assert(dvmIsArrayClass(resClass));
    elemType = resClass->elementClass->primitiveType;
    if (elemType == PRIM_NOT) {
        expectedType = regTypeFromClass(resClass->elementClass);
    } else {
        expectedType = primitiveTypeToRegType(elemType);
    }
    //LOGI("filled-new-array: %s -> %d\n", resClass->descriptor, expectedType);

    /*
     * Verify each register.  If "argCount" is bad, verifyRegisterType()
     * will run off the end of the list and fail.  It's legal, if silly,
     * for argCount to be zero.
     */
    for (ui = 0; ui < argCount; ui++) {
        u4 getReg;

        if (isRange)
            getReg = pDecInsn->vC + ui;
        else
            getReg = pDecInsn->arg[ui];

        verifyRegisterType(registerLine, getReg, expectedType, pFailure);
        if (!VERIFY_OK(*pFailure)) {
            LOG_VFY("VFY: filled-new-array arg %u(%u) not valid\n", ui, getReg);
            return;
        }
    }
}


/*
 * 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 "insnFlags".
 *
 * 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 Method* meth, InsnFlags* insnFlags,
    int insnIdx, VerifyError failure)
{
    VerifyErrorRefType refType;
    u2* oldInsns = (u2*) meth->insns + insnIdx;
    bool result = false;

    if (gDvm.optimizing)
        LOGD("Weird: RFI during dexopt?");

    /*
     * Generate the new instruction out of the old.
     *
     * First, make sure this is an instruction we're expecting to stomp on.
     */
    Opcode opcode = dexOpcodeFromCodeUnit(*oldInsns);
    switch (opcode) {
    case OP_CONST_CLASS:                // insn[1] == class ref, 2 bytes
    case OP_CHECK_CAST:
    case OP_INSTANCE_OF:
    case OP_NEW_INSTANCE:
    case OP_NEW_ARRAY:
    case OP_FILLED_NEW_ARRAY:           // insn[1] == class ref, 3 bytes
    case OP_FILLED_NEW_ARRAY_RANGE:
        refType = VERIFY_ERROR_REF_CLASS;
        break;

    case OP_IGET:                       // insn[1] == field ref, 2 bytes
    case OP_IGET_BOOLEAN:
    case OP_IGET_BYTE:
    case OP_IGET_CHAR:
    case OP_IGET_SHORT:
    case OP_IGET_WIDE:
    case OP_IGET_OBJECT:
    case OP_IPUT:
    case OP_IPUT_BOOLEAN:
    case OP_IPUT_BYTE:
    case OP_IPUT_CHAR:
    case OP_IPUT_SHORT:
    case OP_IPUT_WIDE:
    case OP_IPUT_OBJECT:
    case OP_SGET:
    case OP_SGET_BOOLEAN:
    case OP_SGET_BYTE:
    case OP_SGET_CHAR:
    case OP_SGET_SHORT:
    case OP_SGET_WIDE:
    case OP_SGET_OBJECT:
    case OP_SPUT:
    case OP_SPUT_BOOLEAN:
    case OP_SPUT_BYTE:
    case OP_SPUT_CHAR:
    case OP_SPUT_SHORT:
    case OP_SPUT_WIDE:
    case OP_SPUT_OBJECT:
        refType = VERIFY_ERROR_REF_FIELD;
        break;

    case OP_INVOKE_VIRTUAL:             // insn[1] == method ref, 3 bytes
    case OP_INVOKE_VIRTUAL_RANGE:
    case OP_INVOKE_SUPER:
    case OP_INVOKE_SUPER_RANGE:
    case OP_INVOKE_DIRECT:
    case OP_INVOKE_DIRECT_RANGE:
    case OP_INVOKE_STATIC:
    case OP_INVOKE_STATIC_RANGE:
    case OP_INVOKE_INTERFACE:
    case OP_INVOKE_INTERFACE_RANGE:
        refType = VERIFY_ERROR_REF_METHOD;
        break;

    default:
        /* could handle this in a generic way, but this is probably safer */
        LOG_VFY("GLITCH: verifier asked to replace opcode 0x%02x\n", opcode);
        goto bail;
    }

    assert((dexGetFlagsFromOpcode(opcode) & kInstrCanThrow) != 0);

    /* write a NOP over the third code unit, if necessary */
    int width = dvmInsnGetWidth(insnFlags, insnIdx);
    switch (width) {
    case 2:
        /* nothing to do */
        break;
    case 3:
        dvmDexChangeDex2(meth->clazz->pDvmDex, oldInsns+2, OP_NOP);
        break;
    default:
        /* whoops */
        LOGE("ERROR: stomped a %d-unit instruction with a verifier error\n",
            width);
        dvmAbort();
    }

    /* encode the opcode, with the failure code in the high byte */
    u2 newVal = OP_THROW_VERIFICATION_ERROR |
        (failure << 8) | (refType << (8 + kVerifyErrorRefTypeShift));
    dvmDexChangeDex2(meth->clazz->pDvmDex, oldInsns, newVal);

    result = true;

bail:
    return result;
}

/*
 * Handle a monitor-enter instruction.
 */
void handleMonitorEnter(RegisterLine* workLine, u4 regIdx, u4 insnIdx,
    VerifyError* pFailure)
{
    if (!regTypeIsReference(getRegisterType(workLine, regIdx))) {
        LOG_VFY("VFY: monitor-enter on non-object\n");
        *pFailure = VERIFY_ERROR_GENERIC;
        return;
    }

    if (workLine->monitorEntries == NULL) {
        /* should only be true if monitor verification is disabled */
        assert(!gDvm.monitorVerification);
        return;
    }

    if (workLine->monitorStackTop == kMaxMonitorStackDepth) {
        LOG_VFY("VFY: monitor-enter stack overflow (%d)\n",
            kMaxMonitorStackDepth);
        *pFailure = VERIFY_ERROR_GENERIC;
        return;
    }

    /*
     * Push an entry on the stack, and set a bit in the register flags to
     * indicate that it's associated with this register.
     */
    workLine->monitorEntries[regIdx] |= 1 << workLine->monitorStackTop;
    workLine->monitorStack[workLine->monitorStackTop++] = insnIdx;
}

/*
 * Handle a monitor-exit instruction.
 */
void handleMonitorExit(RegisterLine* workLine, u4 regIdx, u4 insnIdx,
    VerifyError* pFailure)
{
    if (!regTypeIsReference(getRegisterType(workLine, regIdx))) {
        LOG_VFY("VFY: monitor-exit on non-object\n");
        *pFailure = VERIFY_ERROR_GENERIC;
        return;
    }

    if (workLine->monitorEntries == NULL) {
        /* should only be true if monitor verification is disabled */
        assert(!gDvm.monitorVerification);
        return;
    }

    if (workLine->monitorStackTop == 0) {
        LOG_VFY("VFY: monitor-exit stack underflow\n");
        *pFailure = VERIFY_ERROR_GENERIC;
        return;
    }

    /*
     * Confirm that the entry at the top of the stack is associated with
     * the register.  Pop the top entry off.
     */
    workLine->monitorStackTop--;
#ifdef BUG_3215458_FIXED
    if ((workLine->monitorEntries[regIdx] & (1 << workLine->monitorStackTop))
            == 0)
    {
        LOG_VFY("VFY: monitor-exit bit %d not set: addr=0x%04x (bits[%d]=0x%x)\n",
            workLine->monitorStackTop, insnIdx, regIdx,
            workLine->monitorEntries[regIdx]);
        *pFailure = VERIFY_ERROR_GENERIC;
        return;
    }
#endif
    workLine->monitorStack[workLine->monitorStackTop] = 0;

    /*
     * Clear the bit from the register flags.
     */
    workLine->monitorEntries[regIdx] &= ~(1 << workLine->monitorStackTop);
}


/*
 * ===========================================================================
 *      Entry point and driver loop
 * ===========================================================================
 */

/*
 * One-time preparation.
 */
static void verifyPrep(void)
{
#ifndef NDEBUG
    /* only need to do this if the table was updated */
    checkMergeTab();
#endif

    /*
     * We rely on these for verification of const-class, const-string,
     * and throw instructions.  Make sure we have them loaded.
     */
    if (gDvm.classJavaLangClass == NULL)
        gDvm.classJavaLangClass =
            dvmFindSystemClassNoInit("Ljava/lang/Class;");
    if (gDvm.classJavaLangString == NULL)
        gDvm.classJavaLangString =
            dvmFindSystemClassNoInit("Ljava/lang/String;");
    if (gDvm.classJavaLangThrowable == NULL) {
        gDvm.classJavaLangThrowable =
            dvmFindSystemClassNoInit("Ljava/lang/Throwable;");
        gDvm.offJavaLangThrowable_cause =
            dvmFindFieldOffset(gDvm.classJavaLangThrowable,
                "cause", "Ljava/lang/Throwable;");
    }
    if (gDvm.classJavaLangObject == NULL)
        gDvm.classJavaLangObject =
            dvmFindSystemClassNoInit("Ljava/lang/Object;");
}

/*
 * Entry point for the detailed code-flow analysis of a single method.
 */
bool dvmVerifyCodeFlow(VerifierData* vdata)
{
    bool result = false;
    const Method* meth = vdata->method;
    const int insnsSize = vdata->insnsSize;
    const bool generateRegisterMap = gDvm.generateRegisterMaps;
    RegisterTable regTable;

    memset(&regTable, 0, sizeof(regTable));

#ifdef VERIFIER_STATS
    gDvm.verifierStats.methodsExamined++;
    if (vdata->monitorEnterCount)
        gDvm.verifierStats.monEnterMethods++;
#endif

    /* TODO: move this elsewhere -- we don't need to do this for every method */
    verifyPrep();

    if (meth->registersSize * insnsSize > 4*1024*1024) {
        LOG_VFY_METH(meth,
            "VFY: warning: method is huge (regs=%d insnsSize=%d)\n",
            meth->registersSize, insnsSize);
        /* might be bogus data, might be some huge generated method */
    }

    /*
     * Create register lists, and initialize them to "Unknown".  If we're
     * also going to create the register map, we need to retain the
     * register lists for a larger set of addresses.
     */
    if (!initRegisterTable(vdata, &regTable,
            generateRegisterMap ? kTrackRegsGcPoints : kTrackRegsBranches))
        goto bail;

    vdata->registerLines = regTable.registerLines;

    /*
     * Perform liveness analysis.
     *
     * We can do this before or after the main verifier pass.  The choice
     * affects whether or not we see the effects of verifier instruction
     * changes, i.e. substitution of throw-verification-error.
     *
     * In practice the ordering doesn't really matter, because T-V-E
     * just prunes "can continue", creating regions of dead code (with
     * corresponding register map data that will never be used).
     */
    if (generateRegisterMap &&
        gDvm.registerMapMode == kRegisterMapModeLivePrecise)
    {
        /*
         * Compute basic blocks and predecessor lists.
         */
        if (!dvmComputeVfyBasicBlocks(vdata))
            goto bail;

        /*
         * Compute liveness.
         */
        if (!dvmComputeLiveness(vdata))
            goto bail;
    }

    /*
     * Initialize the types of the registers that correspond to the
     * method arguments.  We can determine this from the method signature.
     */
    if (!setTypesFromSignature(meth, regTable.registerLines[0].regTypes,
            vdata->uninitMap))
        goto bail;

    /*
     * Run the verifier.
     */
    if (!doCodeVerification(vdata, &regTable))
        goto bail;

    /*
     * Generate a register map.
     */
    if (generateRegisterMap) {
        RegisterMap* pMap = dvmGenerateRegisterMapV(vdata);
        if (pMap != NULL) {
            /*
             * Tuck it into the Method struct.  It will either get used
             * directly or, if we're in dexopt, will be packed up and
             * appended to the DEX file.
             */
            dvmSetRegisterMap((Method*)meth, pMap);
        }
    }

    /*
     * Success.
     */
    result = true;

bail:
    freeRegisterLineInnards(vdata);
    free(regTable.registerLines);
    free(regTable.lineAlloc);
    return result;
}

/*
 * Grind through the instructions.
 *
 * 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 doCodeVerification(VerifierData* vdata, RegisterTable* regTable)
{
    const Method* meth = vdata->method;
    InsnFlags* insnFlags = vdata->insnFlags;
    UninitInstanceMap* uninitMap = vdata->uninitMap;
    const int insnsSize = dvmGetMethodInsnsSize(meth);
    bool result = false;
    bool debugVerbose = false;
    int insnIdx, startGuess;

    /*
     * Begin by marking the first instruction as "changed".
     */
    dvmInsnSetChanged(insnFlags, 0, true);

    if (dvmWantVerboseVerification(meth)) {
        IF_LOGI() {
            char* desc = dexProtoCopyMethodDescriptor(&meth->prototype);
            LOGI("Now verifying: %s.%s %s (ins=%d regs=%d)\n",
                meth->clazz->descriptor, meth->name, desc,
                meth->insSize, meth->registersSize);
            LOGI(" ------ [0    4    8    12   16   20   24   28   32   36\n");
            free(desc);
        }
        debugVerbose = true;
        gDebugVerbose = true;
    } else {
        gDebugVerbose = false;
    }

    startGuess = 0;

    /*
     * Continue until no instructions are marked "changed".
     */
    while (true) {
        /*
         * Find the first marked one.  Use "startGuess" as a way to find
         * one quickly.
         */
        for (insnIdx = startGuess; insnIdx < insnsSize; insnIdx++) {
            if (dvmInsnIsChanged(insnFlags, insnIdx))
                break;
        }

        if (insnIdx == insnsSize) {
            if (startGuess != 0) {
                /* try again, starting from the top */
                startGuess = 0;
                continue;
            } else {
                /* all flags are clear */
                break;
            }
        }

        /*
         * We carry the working set of registers from instruction to
         * instruction.  If this address can be the target of a branch
         * (or throw) instruction, or if we're skipping around chasing
         * "changed" flags, we need to load the set of registers from
         * the table.
         *
         * Because we always prefer to continue on to the next instruction,
         * we should never have a situation where we have a stray
         * "changed" flag set on an instruction that isn't a branch target.
         */
        if (dvmInsnIsBranchTarget(insnFlags, insnIdx)) {
            RegisterLine* workLine = &regTable->workLine;

            copyLineFromTable(workLine, regTable, insnIdx);
        } else {
#ifndef NDEBUG
            /*
             * Sanity check: retrieve the stored register line (assuming
             * a full table) and make sure it actually matches.
             */
            RegisterLine* registerLine = getRegisterLine(regTable, insnIdx);
            if (registerLine->regTypes != NULL &&
                compareLineToTable(regTable, insnIdx, &regTable->workLine) != 0)
            {
                char* desc = dexProtoCopyMethodDescriptor(&meth->prototype);
                LOG_VFY("HUH? workLine diverged in %s.%s %s\n",
                        meth->clazz->descriptor, meth->name, desc);
                free(desc);
                dumpRegTypes(vdata, registerLine, 0, "work",
                    uninitMap, DRT_SHOW_REF_TYPES | DRT_SHOW_LOCALS);
                dumpRegTypes(vdata, registerLine, 0, "insn",
                    uninitMap, DRT_SHOW_REF_TYPES | DRT_SHOW_LOCALS);
            }
#endif
        }
        if (debugVerbose) {
            dumpRegTypes(vdata, &regTable->workLine, insnIdx,
                NULL, uninitMap, SHOW_REG_DETAILS);
        }

        //LOGI("process %s.%s %s %d\n",
        //    meth->clazz->descriptor, meth->name, meth->descriptor, insnIdx);
        if (!verifyInstruction(meth, insnFlags, regTable, insnIdx,
                uninitMap, &startGuess))
        {
            //LOGD("+++ %s bailing at %d\n", meth->name, insnIdx);
            goto bail;
        }

        /*
         * Clear "changed" and mark as visited.
         */
        dvmInsnSetVisited(insnFlags, insnIdx, true);
        dvmInsnSetChanged(insnFlags, insnIdx, false);
    }

    if (DEAD_CODE_SCAN && !IS_METHOD_FLAG_SET(meth, METHOD_ISWRITABLE)) {
        /*
         * Scan for dead code.  There's nothing "evil" about dead code
         * (besides the wasted space), but it indicates a flaw somewhere
         * down the line, possibly in the verifier.
         *
         * If we've substituted "always throw" instructions into the stream,
         * we are almost certainly going to have some dead code.
         */
        int deadStart = -1;
        for (insnIdx = 0; insnIdx < insnsSize;
            insnIdx += dvmInsnGetWidth(insnFlags, insnIdx))
        {
            /*
             * Switch-statement data doesn't get "visited" by scanner.  It
             * may or may not be preceded by a padding NOP (for alignment).
             */
            int instr = meth->insns[insnIdx];
            if (instr == kPackedSwitchSignature ||
                instr == kSparseSwitchSignature ||
                instr == kArrayDataSignature ||
                (instr == OP_NOP &&
                 (meth->insns[insnIdx+1] == kPackedSwitchSignature ||
                  meth->insns[insnIdx+1] == kSparseSwitchSignature ||
                  meth->insns[insnIdx+1] == kArrayDataSignature)))
            {
                dvmInsnSetVisited(insnFlags, insnIdx, true);
            }

            if (!dvmInsnIsVisited(insnFlags, insnIdx)) {
                if (deadStart < 0)
                    deadStart = insnIdx;
            } else if (deadStart >= 0) {
                IF_LOGD() {
                    char* desc =
                        dexProtoCopyMethodDescriptor(&meth->prototype);
                    LOGD("VFY: dead code 0x%04x-%04x in %s.%s %s\n",
                        deadStart, insnIdx-1,
                        meth->clazz->descriptor, meth->name, desc);
                    free(desc);
                }

                deadStart = -1;
            }
        }
        if (deadStart >= 0) {
            IF_LOGD() {
                char* desc = dexProtoCopyMethodDescriptor(&meth->prototype);
                LOGD("VFY: dead code 0x%04x-%04x in %s.%s %s\n",
                    deadStart, insnIdx-1,
                    meth->clazz->descriptor, meth->name, desc);
                free(desc);
            }
        }
    }

    result = true;

bail:
    return result;
}


/*
 * 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 "regTypes" at the target addresses.  Does not set or
 * clear any other flags in "insnFlags".
 *
 * This may alter meth->insns if we need to replace an instruction with
 * throw-verification-error.
 */
static bool verifyInstruction(const Method* meth, InsnFlags* insnFlags,
    RegisterTable* regTable, int insnIdx, UninitInstanceMap* uninitMap,
    int* pStartGuess)
{
    const int insnsSize = dvmGetMethodInsnsSize(meth);
    const u2* insns = meth->insns + insnIdx;
    bool result = false;

#ifdef VERIFIER_STATS
    if (dvmInsnIsVisited(insnFlags, insnIdx)) {
        gDvm.verifierStats.instrsReexamined++;
    } else {
        gDvm.verifierStats.instrsExamined++;
    }
#endif

    /*
     * Once we finish decoding the instruction, we need to figure out where
     * we can go from here.  There are three possible ways to transfer
     * control to another statement:
     *
     * (1) Continue to the next instruction.  Applies to all but
     *     unconditional branches, method returns, and exception throws.
     * (2) Branch to one or more possible locations.  Applies to branches
     *     and switch statements.
     * (3) Exception handlers.  Applies to any instruction that can
     *     throw an exception that is handled by an encompassing "try"
     *     block.
     *
     * We can also return, in which case there is no successor instruction
     * from this point.
     *
     * The behavior can be determined from the OpcodeFlags.
     */

    RegisterLine* workLine = &regTable->workLine;
    const DexFile* pDexFile = meth->clazz->pDvmDex->pDexFile;
    ClassObject* resClass;
    s4 branchTarget = 0;
    const int insnRegCount = meth->registersSize;
    RegType tmpType;
    DecodedInstruction decInsn;
    bool justSetResult = false;
    VerifyError failure = VERIFY_ERROR_NONE;

#ifndef NDEBUG
    memset(&decInsn, 0x81, sizeof(decInsn));
#endif
    dexDecodeInstruction(insns, &decInsn);

    int nextFlags = dexGetFlagsFromOpcode(decInsn.opcode);

    /*
     * Make a copy of the previous register state.  If the instruction
     * can throw an exception, we will copy/merge this into the "catch"
     * address rather than workLine, because we don't want the result
     * from the "successful" code path (e.g. a check-cast that "improves"
     * a type) to be visible to the exception handler.
     */
    if ((nextFlags & kInstrCanThrow) != 0 && dvmInsnIsInTry(insnFlags, insnIdx))
    {
        copyRegisterLine(&regTable->savedLine, workLine,
            regTable->insnRegCountPlus);
    } else {
#ifndef NDEBUG
        memset(regTable->savedLine.regTypes, 0xdd,
            regTable->insnRegCountPlus * sizeof(RegType));
#endif
    }

    switch (decInsn.opcode) {
    case OP_NOP:
        /*
         * A "pure" NOP has no effect on anything.  Data tables start with
         * a signature that looks like a NOP; if we see one of these in
         * the course of executing code then we have a problem.
         */
        if (decInsn.vA != 0) {
            LOG_VFY("VFY: encountered data table in instruction stream\n");
            failure = VERIFY_ERROR_GENERIC;
        }
        break;

    case OP_MOVE:
    case OP_MOVE_FROM16:
    case OP_MOVE_16:
        copyRegister1(workLine, decInsn.vA, decInsn.vB, kTypeCategory1nr,
            &failure);
        break;
    case OP_MOVE_WIDE:
    case OP_MOVE_WIDE_FROM16:
    case OP_MOVE_WIDE_16:
        copyRegister2(workLine, decInsn.vA, decInsn.vB, &failure);
        break;
    case OP_MOVE_OBJECT:
    case OP_MOVE_OBJECT_FROM16:
    case OP_MOVE_OBJECT_16:
        copyRegister1(workLine, decInsn.vA, decInsn.vB, kTypeCategoryRef,
            &failure);
        break;

    /*
     * The move-result instructions copy data out of a "pseudo-register"
     * with the results from the last method invocation.  In practice we
     * might want to hold the result in an actual CPU register, so the
     * Dalvik spec requires that these only appear immediately after an
     * invoke or filled-new-array.
     *
     * These calls invalidate the "result" register.  (This is now
     * redundant with the reset done below, but it can make the debug info
     * easier to read in some cases.)
     */
    case OP_MOVE_RESULT:
        copyResultRegister1(workLine, insnRegCount, decInsn.vA,
            kTypeCategory1nr, &failure);
        break;
    case OP_MOVE_RESULT_WIDE:
        copyResultRegister2(workLine, insnRegCount, decInsn.vA, &failure);
        break;
    case OP_MOVE_RESULT_OBJECT:
        copyResultRegister1(workLine, insnRegCount, decInsn.vA,
            kTypeCategoryRef, &failure);
        break;

    case OP_MOVE_EXCEPTION:
        /*
         * This statement can only appear as the first instruction in an
         * exception handler (though not all exception handlers need to
         * have one of these).  We verify that as part of extracting the
         * exception type from the catch block list.
         *
         * "resClass" will hold the closest common superclass of all
         * exceptions that can be handled here.
         */
        resClass = getCaughtExceptionType(meth, insnIdx, &failure);
        if (resClass == NULL) {
            assert(!VERIFY_OK(failure));
        } else {
            setRegisterType(workLine, decInsn.vA, regTypeFromClass(resClass));
        }
        break;

    case OP_RETURN_VOID:
        if (!checkConstructorReturn(meth, workLine, insnRegCount)) {
            failure = VERIFY_ERROR_GENERIC;
        } else if (getMethodReturnType(meth) != kRegTypeUnknown) {
            LOG_VFY("VFY: return-void not expected\n");
            failure = VERIFY_ERROR_GENERIC;
        }
        break;
    case OP_RETURN:
        if (!checkConstructorReturn(meth, workLine, insnRegCount)) {
            failure = VERIFY_ERROR_GENERIC;
        } else {
            /* check the method signature */
            RegType returnType = getMethodReturnType(meth);
            checkTypeCategory(returnType, kTypeCategory1nr, &failure);
            if (!VERIFY_OK(failure))
                LOG_VFY("VFY: return-1nr not expected\n");

            /* check the register contents */
            returnType = getRegisterType(workLine, decInsn.vA);
            checkTypeCategory(returnType, kTypeCategory1nr, &failure);
            if (!VERIFY_OK(failure)) {
                LOG_VFY("VFY: return-1nr on invalid register v%d\n",
                    decInsn.vA);
            }
        }
        break;
    case OP_RETURN_WIDE:
        if (!checkConstructorReturn(meth, workLine, insnRegCount)) {
            failure = VERIFY_ERROR_GENERIC;
        } else {
            RegType returnType, returnTypeHi;

            /* check the method signature */
            returnType = getMethodReturnType(meth);
            checkTypeCategory(returnType, kTypeCategory2, &failure);
            if (!VERIFY_OK(failure))
                LOG_VFY("VFY: return-wide not expected\n");

            /* check the register contents */
            returnType = getRegisterType(workLine, decInsn.vA);
            returnTypeHi = getRegisterType(workLine, decInsn.vA +1);
            checkTypeCategory(returnType, kTypeCategory2, &failure);
            checkWidePair(returnType, returnTypeHi, &failure);
            if (!VERIFY_OK(failure)) {
                LOG_VFY("VFY: return-wide on invalid register pair v%d\n",
                    decInsn.vA);
            }
        }
        break;
    case OP_RETURN_OBJECT:
        if (!checkConstructorReturn(meth, workLine, insnRegCount)) {
            failure = VERIFY_ERROR_GENERIC;
        } else {
            RegType returnType = getMethodReturnType(meth);
            checkTypeCategory(returnType, kTypeCategoryRef, &failure);
            if (!VERIFY_OK(failure)) {
                LOG_VFY("VFY: return-object not expected\n");
                break;
            }

            /* returnType is the *expected* return type, not register value */
            assert(returnType != kRegTypeZero);
            assert(!regTypeIsUninitReference(returnType));

            /*
             * Verify that the reference in vAA is an instance of the type
             * in "returnType".  The Zero type is allowed here.  If the
             * method is declared to return an interface, then any
             * initialized reference is acceptable.
             *
             * Note getClassFromRegister fails if the register holds an
             * uninitialized reference, so we do not allow them to be
             * returned.
             */
            ClassObject* declClass;

            declClass = regTypeInitializedReferenceToClass(returnType);
            resClass = getClassFromRegister(workLine, decInsn.vA, &failure);
            if (!VERIFY_OK(failure))
                break;
            if (resClass != NULL) {
                if (!dvmIsInterfaceClass(declClass) &&
                    !dvmInstanceof(resClass, declClass))
                {
                    LOG_VFY("VFY: returning %s (cl=%p), declared %s (cl=%p)\n",
                            resClass->descriptor, resClass->classLoader,
                            declClass->descriptor, declClass->classLoader);
                    failure = VERIFY_ERROR_GENERIC;
                    break;
                }
            }
        }
        break;

    case OP_CONST_4:
    case OP_CONST_16:
    case OP_CONST:
        /* could be boolean, int, float, or a null reference */
        setRegisterType(workLine, decInsn.vA,
            determineCat1Const((s4)decInsn.vB));
        break;
    case OP_CONST_HIGH16:
        /* could be boolean, int, float, or a null reference */
        setRegisterType(workLine, decInsn.vA,
            determineCat1Const((s4) decInsn.vB << 16));
        break;
    case OP_CONST_WIDE_16:
    case OP_CONST_WIDE_32:
    case OP_CONST_WIDE:
    case OP_CONST_WIDE_HIGH16:
        /* could be long or double; default to long and allow conversion */
        setRegisterType(workLine, decInsn.vA, kRegTypeLongLo);
        break;
    case OP_CONST_STRING:
    case OP_CONST_STRING_JUMBO:
        assert(gDvm.classJavaLangString != NULL);
        setRegisterType(workLine, decInsn.vA,
            regTypeFromClass(gDvm.classJavaLangString));
        break;
    case OP_CONST_CLASS:
        assert(gDvm.classJavaLangClass != NULL);
        /* make sure we can resolve the class; access check is important */
        resClass = dvmOptResolveClass(meth->clazz, decInsn.vB, &failure);
        if (resClass == NULL) {
            const char* badClassDesc = dexStringByTypeIdx(pDexFile, decInsn.vB);
            dvmLogUnableToResolveClass(badClassDesc, meth);
            LOG_VFY("VFY: unable to resolve const-class %d (%s) in %s\n",
                decInsn.vB, badClassDesc, meth->clazz->descriptor);
            assert(failure != VERIFY_ERROR_GENERIC);
        } else {
            setRegisterType(workLine, decInsn.vA,
                regTypeFromClass(gDvm.classJavaLangClass));
        }
        break;

    case OP_MONITOR_ENTER:
        handleMonitorEnter(workLine, decInsn.vA, insnIdx, &failure);
        break;
    case OP_MONITOR_EXIT:
        /*
         * monitor-exit instructions are odd.  They can throw exceptions,
         * but when they do they act as if they succeeded and the PC is
         * pointing to the following instruction.  (This behavior goes back
         * to the need to handle asynchronous exceptions, a now-deprecated
         * feature that Dalvik doesn't support.)
         *
         * In practice we don't need to worry about this.  The only
         * exceptions that can be thrown from monitor-exit are for a
         * null reference and -exit without a matching -enter.  If the
         * structured locking checks are working, the former would have
         * failed on the -enter instruction, and the latter is impossible.
         *
         * This is fortunate, because issue 3221411 prevents us from
         * chasing the "can throw" path when monitor verification is
         * enabled.  If we can fully verify the locking we can ignore
         * some catch blocks (which will show up as "dead" code when
         * we skip them here); if we can't, then the code path could be
         * "live" so we still need to check it.
         */
        if (workLine->monitorEntries != NULL)
            nextFlags &= ~kInstrCanThrow;
        handleMonitorExit(workLine, decInsn.vA, insnIdx, &failure);
        break;

    case OP_CHECK_CAST:
        /*
         * If this instruction succeeds, we will promote register vA to
         * the type in vB.  (This could be a demotion -- not expected, so
         * we don't try to address it.)
         *
         * If it fails, an exception is thrown, which we deal with later
         * by ignoring the update to decInsn.vA when branching to a handler.
         */
        resClass = dvmOptResolveClass(meth->clazz, decInsn.vB, &failure);
        if (resClass == NULL) {
            const char* badClassDesc = dexStringByTypeIdx(pDexFile, decInsn.vB);
            dvmLogUnableToResolveClass(badClassDesc, meth);
            LOG_VFY("VFY: unable to resolve check-cast %d (%s) in %s\n",
                decInsn.vB, badClassDesc, meth->clazz->descriptor);
            assert(failure != VERIFY_ERROR_GENERIC);
        } else {
            RegType origType;

            origType = getRegisterType(workLine, decInsn.vA);
            if (!regTypeIsReference(origType)) {
                LOG_VFY("VFY: check-cast on non-reference in v%u\n",decInsn.vA);
                failure = VERIFY_ERROR_GENERIC;
                break;
            }
            setRegisterType(workLine, decInsn.vA, regTypeFromClass(resClass));
        }
        break;
    case OP_INSTANCE_OF:
        /* make sure we're checking a reference type */
        tmpType = getRegisterType(workLine, decInsn.vB);
        if (!regTypeIsReference(tmpType)) {
            LOG_VFY("VFY: vB not a reference (%d)\n", tmpType);
            failure = VERIFY_ERROR_GENERIC;
            break;
        }

        /* make sure we can resolve the class; access check is important */
        resClass = dvmOptResolveClass(meth->clazz, decInsn.vC, &failure);
        if (resClass == NULL) {
            const char* badClassDesc = dexStringByTypeIdx(pDexFile, decInsn.vC);
            dvmLogUnableToResolveClass(badClassDesc, meth);
            LOG_VFY("VFY: unable to resolve instanceof %d (%s) in %s\n",
                decInsn.vC, badClassDesc, meth->clazz->descriptor);
            assert(failure != VERIFY_ERROR_GENERIC);
        } else {
            /* result is boolean */
            setRegisterType(workLine, decInsn.vA, kRegTypeBoolean);
        }
        break;

    case OP_ARRAY_LENGTH:
        resClass = getClassFromRegister(workLine, decInsn.vB, &failure);
        if (!VERIFY_OK(failure))
            break;
        if (resClass != NULL && !dvmIsArrayClass(resClass)) {
            LOG_VFY("VFY: array-length on non-array\n");
            failure = VERIFY_ERROR_GENERIC;
            break;
        }
        setRegisterType(workLine, decInsn.vA, kRegTypeInteger);
        break;

    case OP_NEW_INSTANCE:
        resClass = dvmOptResolveClass(meth->clazz, decInsn.vB, &failure);
        if (resClass == NULL) {
            const char* badClassDesc = dexStringByTypeIdx(pDexFile, decInsn.vB);
            dvmLogUnableToResolveClass(badClassDesc, meth);
            LOG_VFY("VFY: unable to resolve new-instance %d (%s) in %s\n",
                decInsn.vB, badClassDesc, meth->clazz->descriptor);
            assert(failure != VERIFY_ERROR_GENERIC);
        } else {
            RegType uninitType;

            /* can't create an instance of an interface or abstract class */
            if (dvmIsAbstractClass(resClass) || dvmIsInterfaceClass(resClass)) {
                LOG_VFY("VFY: new-instance on interface or abstract class %s\n",
                    resClass->descriptor);
                failure = VERIFY_ERROR_INSTANTIATION;
                break;
            }

            /* add resolved class to uninit map if not already there */
            int uidx = setUninitInstance(uninitMap, insnIdx, resClass);
            assert(uidx >= 0);
            uninitType = regTypeFromUninitIndex(uidx);

            /*
             * Any registers holding previous allocations from this address
             * that have not yet been initialized must be marked invalid.
             */
            markUninitRefsAsInvalid(workLine, insnRegCount, uninitMap,
                uninitType);

            /* add the new uninitialized reference to the register ste */
            setRegisterType(workLine, decInsn.vA, uninitType);
        }
        break;
    case OP_NEW_ARRAY:
        resClass = dvmOptResolveClass(meth->clazz, decInsn.vC, &failure);
        if (resClass == NULL) {
            const char* badClassDesc = dexStringByTypeIdx(pDexFile, decInsn.vC);
            dvmLogUnableToResolveClass(badClassDesc, meth);
            LOG_VFY("VFY: unable to resolve new-array %d (%s) in %s\n",
                decInsn.vC, badClassDesc, meth->clazz->descriptor);
            assert(failure != VERIFY_ERROR_GENERIC);
        } else if (!dvmIsArrayClass(resClass)) {
            LOG_VFY("VFY: new-array on non-array class\n");
            failure = VERIFY_ERROR_GENERIC;
        } else {
            /* make sure "size" register is valid type */
            verifyRegisterType(workLine, decInsn.vB, kRegTypeInteger, &failure);
            /* set register type to array class */
            setRegisterType(workLine, decInsn.vA, regTypeFromClass(resClass));
        }
        break;
    case OP_FILLED_NEW_ARRAY:
    case OP_FILLED_NEW_ARRAY_RANGE:
        resClass = dvmOptResolveClass(meth->clazz, decInsn.vB, &failure);
        if (resClass == NULL) {
            const char* badClassDesc = dexStringByTypeIdx(pDexFile, decInsn.vB);
            dvmLogUnableToResolveClass(badClassDesc, meth);
            LOG_VFY("VFY: unable to resolve filled-array %d (%s) in %s\n",
                decInsn.vB, badClassDesc, meth->clazz->descriptor);
            assert(failure != VERIFY_ERROR_GENERIC);
        } else if (!dvmIsArrayClass(resClass)) {
            LOG_VFY("VFY: filled-new-array on non-array class\n");
            failure = VERIFY_ERROR_GENERIC;
        } else {
            bool isRange = (decInsn.opcode == OP_FILLED_NEW_ARRAY_RANGE);

            /* check the arguments to the instruction */
            verifyFilledNewArrayRegs(meth, workLine, &decInsn,
                resClass, isRange, &failure);
            /* filled-array result goes into "result" register */
            setResultRegisterType(workLine, insnRegCount,
                regTypeFromClass(resClass));
            justSetResult = true;
        }
        break;

    case OP_CMPL_FLOAT:
    case OP_CMPG_FLOAT:
        verifyRegisterType(workLine, decInsn.vB, kRegTypeFloat, &failure);
        verifyRegisterType(workLine, decInsn.vC, kRegTypeFloat, &failure);
        setRegisterType(workLine, decInsn.vA, kRegTypeBoolean);
        break;
    case OP_CMPL_DOUBLE:
    case OP_CMPG_DOUBLE:
        verifyRegisterType(workLine, decInsn.vB, kRegTypeDoubleLo, &failure);
        verifyRegisterType(workLine, decInsn.vC, kRegTypeDoubleLo, &failure);
        setRegisterType(workLine, decInsn.vA, kRegTypeBoolean);
        break;
    case OP_CMP_LONG:
        verifyRegisterType(workLine, decInsn.vB, kRegTypeLongLo, &failure);
        verifyRegisterType(workLine, decInsn.vC, kRegTypeLongLo, &failure);
        setRegisterType(workLine, decInsn.vA, kRegTypeBoolean);
        break;

    case OP_THROW:
        resClass = getClassFromRegister(workLine, decInsn.vA, &failure);
        if (VERIFY_OK(failure) && resClass != NULL) {
            if (!dvmInstanceof(resClass, gDvm.classJavaLangThrowable)) {
                LOG_VFY("VFY: thrown class %s not instanceof Throwable\n",
                        resClass->descriptor);
                failure = VERIFY_ERROR_GENERIC;
            }
        }
        break;

    case OP_GOTO:
    case OP_GOTO_16:
    case OP_GOTO_32:
        /* no effect on or use of registers */
        break;

    case OP_PACKED_SWITCH:
    case OP_SPARSE_SWITCH:
        /* verify that vAA is an integer, or can be converted to one */
        verifyRegisterType(workLine, decInsn.vA, kRegTypeInteger, &failure);
        break;

    case OP_FILL_ARRAY_DATA:
        {
            RegType valueType;
            const u2 *arrayData;
            u2 elemWidth;

            /* Similar to the verification done for APUT */
            resClass = getClassFromRegister(workLine, decInsn.vA, &failure);
            if (!VERIFY_OK(failure))
                break;

            /* resClass can be null if the reg type is Zero */
            if (resClass == NULL)
                break;

            if (!dvmIsArrayClass(resClass) || resClass->arrayDim != 1 ||
                resClass->elementClass->primitiveType == PRIM_NOT ||
                resClass->elementClass->primitiveType == PRIM_VOID)
            {
                LOG_VFY("VFY: invalid fill-array-data on %s\n",
                        resClass->descriptor);
                failure = VERIFY_ERROR_GENERIC;
                break;
            }

            valueType = primitiveTypeToRegType(
                                    resClass->elementClass->primitiveType);
            assert(valueType != kRegTypeUnknown);

            /*
             * Now verify if the element width in the table matches the element
             * width declared in the array
             */
            arrayData = insns + (insns[1] | (((s4)insns[2]) << 16));
            if (arrayData[0] != kArrayDataSignature) {
                LOG_VFY("VFY: invalid magic for array-data\n");
                failure = VERIFY_ERROR_GENERIC;
                break;
            }

            switch (resClass->elementClass->primitiveType) {
                case PRIM_BOOLEAN:
                case PRIM_BYTE:
                     elemWidth = 1;
                     break;
                case PRIM_CHAR:
                case PRIM_SHORT:
                     elemWidth = 2;
                     break;
                case PRIM_FLOAT:
                case PRIM_INT:
                     elemWidth = 4;
                     break;
                case PRIM_DOUBLE:
                case PRIM_LONG:
                     elemWidth = 8;
                     break;
                default:
                     elemWidth = 0;
                     break;
            }

            /*
             * Since we don't compress the data in Dex, expect to see equal
             * width of data stored in the table and expected from the array
             * class.
             */
            if (arrayData[1] != elemWidth) {
                LOG_VFY("VFY: array-data size mismatch (%d vs %d)\n",
                        arrayData[1], elemWidth);
                failure = VERIFY_ERROR_GENERIC;
            }
        }
        break;

    case OP_IF_EQ:
    case OP_IF_NE:
        {
            RegType type1, type2;

            type1 = getRegisterType(workLine, decInsn.vA);
            type2 = getRegisterType(workLine, decInsn.vB);

            /* both references? */
            if (regTypeIsReference(type1) && regTypeIsReference(type2))
                break;

            /* both category-1nr? */
            checkTypeCategory(type1, kTypeCategory1nr, &failure);
            checkTypeCategory(type2, kTypeCategory1nr, &failure);
            if (!VERIFY_OK(failure)) {
                LOG_VFY("VFY: args to if-eq/if-ne must both be refs or cat1\n");
                break;
            }
        }
        break;
    case OP_IF_LT:
    case OP_IF_GE:
    case OP_IF_GT:
    case OP_IF_LE:
        tmpType = getRegisterType(workLine, decInsn.vA);
        checkTypeCategory(tmpType, kTypeCategory1nr, &failure);
        if (!VERIFY_OK(failure)) {
            LOG_VFY("VFY: args to 'if' must be cat-1nr\n");
            break;
        }
        tmpType = getRegisterType(workLine, decInsn.vB);
        checkTypeCategory(tmpType, kTypeCategory1nr, &failure);
        if (!VERIFY_OK(failure)) {
            LOG_VFY("VFY: args to 'if' must be cat-1nr\n");
            break;
        }
        break;
    case OP_IF_EQZ:
    case OP_IF_NEZ:
        tmpType = getRegisterType(workLine, decInsn.vA);
        if (regTypeIsReference(tmpType))
            break;
        checkTypeCategory(tmpType, kTypeCategory1nr, &failure);
        if (!VERIFY_OK(failure))
            LOG_VFY("VFY: expected cat-1 arg to if\n");
        break;
    case OP_IF_LTZ:
    case OP_IF_GEZ:
    case OP_IF_GTZ:
    case OP_IF_LEZ:
        tmpType = getRegisterType(workLine, decInsn.vA);
        checkTypeCategory(tmpType, kTypeCategory1nr, &failure);
        if (!VERIFY_OK(failure))
            LOG_VFY("VFY: expected cat-1 arg to if\n");
        break;

    case OP_AGET:
        tmpType = kRegTypeInteger;
        goto aget_1nr_common;
    case OP_AGET_BOOLEAN:
        tmpType = kRegTypeBoolean;
        goto aget_1nr_common;
    case OP_AGET_BYTE:
        tmpType = kRegTypeByte;
        goto aget_1nr_common;
    case OP_AGET_CHAR:
        tmpType = kRegTypeChar;
        goto aget_1nr_common;
    case OP_AGET_SHORT:
        tmpType = kRegTypeShort;
        goto aget_1nr_common;
aget_1nr_common:
        {
            RegType srcType, indexType;

            indexType = getRegisterType(workLine, decInsn.vC);
            checkArrayIndexType(meth, indexType, &failure);
            if (!VERIFY_OK(failure))
                break;

            resClass = getClassFromRegister(workLine, decInsn.vB, &failure);
            if (!VERIFY_OK(failure))
                break;
            if (resClass != NULL) {
                /* verify the class */
                if (!dvmIsArrayClass(resClass) || resClass->arrayDim != 1 ||
                    resClass->elementClass->primitiveType == PRIM_NOT)
                {
                    LOG_VFY("VFY: invalid aget-1nr target %s\n",
                        resClass->descriptor);
                    failure = VERIFY_ERROR_GENERIC;
                    break;
                }

                /* make sure array type matches instruction */
                srcType = primitiveTypeToRegType(
                                        resClass->elementClass->primitiveType);

                if (!checkFieldArrayStore1nr(tmpType, srcType)) {
                    LOG_VFY("VFY: invalid aget-1nr, array type=%d with"
                            " inst type=%d (on %s)\n",
                        srcType, tmpType, resClass->descriptor);
                    failure = VERIFY_ERROR_GENERIC;
                    break;
                }

            }
            setRegisterType(workLine, decInsn.vA, tmpType);
        }
        break;

    case OP_AGET_WIDE:
        {
            RegType dstType, indexType;

            indexType = getRegisterType(workLine, decInsn.vC);
            checkArrayIndexType(meth, indexType, &failure);
            if (!VERIFY_OK(failure))
                break;

            resClass = getClassFromRegister(workLine, decInsn.vB, &failure);
            if (!VERIFY_OK(failure))
                break;
            if (resClass != NULL) {
                /* verify the class */
                if (!dvmIsArrayClass(resClass) || resClass->arrayDim != 1 ||
                    resClass->elementClass->primitiveType == PRIM_NOT)
                {
                    LOG_VFY("VFY: invalid aget-wide target %s\n",
                        resClass->descriptor);
                    failure = VERIFY_ERROR_GENERIC;
                    break;
                }

                /* try to refine "dstType" */
                switch (resClass->elementClass->primitiveType) {
                case PRIM_LONG:
                    dstType = kRegTypeLongLo;
                    break;
                case PRIM_DOUBLE:
                    dstType = kRegTypeDoubleLo;
                    break;
                default:
                    LOG_VFY("VFY: invalid aget-wide on %s\n",
                        resClass->descriptor);
                    dstType = kRegTypeUnknown;
                    failure = VERIFY_ERROR_GENERIC;
                    break;
                }
            } else {
                /*
                 * Null array ref; this code path will fail at runtime.  We
                 * know this is either long or double, and we don't really
                 * discriminate between those during verification, so we
                 * call it a long.
                 */
                dstType = kRegTypeLongLo;
            }
            setRegisterType(workLine, decInsn.vA, dstType);
        }
        break;

    case OP_AGET_OBJECT:
        {
            RegType dstType, indexType;

            indexType = getRegisterType(workLine, decInsn.vC);
            checkArrayIndexType(meth, indexType, &failure);
            if (!VERIFY_OK(failure))
                break;

            /* get the class of the array we're pulling an object from */
            resClass = getClassFromRegister(workLine, decInsn.vB, &failure);
            if (!VERIFY_OK(failure))
                break;
            if (resClass != NULL) {
                ClassObject* elementClass;

                assert(resClass != NULL);
                if (!dvmIsArrayClass(resClass)) {
                    LOG_VFY("VFY: aget-object on non-array class\n");
                    failure = VERIFY_ERROR_GENERIC;
                    break;
                }
                assert(resClass->elementClass != NULL);

                /*
                 * Find the element class.  resClass->elementClass indicates
                 * the basic type, which won't be what we want for a
                 * multi-dimensional array.
                 */
                if (resClass->descriptor[1] == '[') {
                    assert(resClass->arrayDim > 1);
                    elementClass = dvmFindArrayClass(&resClass->descriptor[1],
                                        resClass->classLoader);
                } else if (resClass->descriptor[1] == 'L') {
                    assert(resClass->arrayDim == 1);
                    elementClass = resClass->elementClass;
                } else {
                    LOG_VFY("VFY: aget-object on non-ref array class (%s)\n",
                        resClass->descriptor);
                    failure = VERIFY_ERROR_GENERIC;
                    break;
                }

                dstType = regTypeFromClass(elementClass);
            } else {
                /*
                 * The array reference is NULL, so the current code path will
                 * throw an exception.  For proper merging with later code
                 * paths, and correct handling of "if-eqz" tests on the
                 * result of the array get, we want to treat this as a null
                 * reference.
                 */
                dstType = kRegTypeZero;
            }
            setRegisterType(workLine, decInsn.vA, dstType);
        }
        break;
    case OP_APUT:
        tmpType = kRegTypeInteger;
        goto aput_1nr_common;
    case OP_APUT_BOOLEAN:
        tmpType = kRegTypeBoolean;
        goto aput_1nr_common;
    case OP_APUT_BYTE:
        tmpType = kRegTypeByte;
        goto aput_1nr_common;
    case OP_APUT_CHAR:
        tmpType = kRegTypeChar;
        goto aput_1nr_common;
    case OP_APUT_SHORT:
        tmpType = kRegTypeShort;
        goto aput_1nr_common;
aput_1nr_common:
        {
            RegType srcType, dstType, indexType;

            indexType = getRegisterType(workLine, decInsn.vC);
            checkArrayIndexType(meth, indexType, &failure);
            if (!VERIFY_OK(failure))
                break;

            /* make sure the source register has the correct type */
            srcType = getRegisterType(workLine, decInsn.vA);
            if (!canConvertTo1nr(srcType, tmpType)) {
                LOG_VFY("VFY: invalid reg type %d on aput instr (need %d)\n",
                    srcType, tmpType);
                failure = VERIFY_ERROR_GENERIC;
                break;
            }

            resClass = getClassFromRegister(workLine, decInsn.vB, &failure);
            if (!VERIFY_OK(failure))
                break;

            /* resClass can be null if the reg type is Zero */
            if (resClass == NULL)
                break;

            if (!dvmIsArrayClass(resClass) || resClass->arrayDim != 1 ||
                resClass->elementClass->primitiveType == PRIM_NOT)
            {
                LOG_VFY("VFY: invalid aput-1nr on %s\n", resClass->descriptor);
                failure = VERIFY_ERROR_GENERIC;
                break;
            }

            /* verify that instruction matches array */
            dstType = primitiveTypeToRegType(
                                    resClass->elementClass->primitiveType);
            assert(dstType != kRegTypeUnknown);

            if (!checkFieldArrayStore1nr(tmpType, dstType)) {
                LOG_VFY("VFY: invalid aput-1nr on %s (inst=%d dst=%d)\n",
                        resClass->descriptor, tmpType, dstType);
                failure = VERIFY_ERROR_GENERIC;
                break;
            }
        }
        break;
    case OP_APUT_WIDE:
        tmpType = getRegisterType(workLine, decInsn.vC);
        checkArrayIndexType(meth, tmpType, &failure);
        if (!VERIFY_OK(failure))
            break;

        tmpType = getRegisterType(workLine, decInsn.vA);
        {
            RegType typeHi = getRegisterType(workLine, decInsn.vA+1);
            checkTypeCategory(tmpType, kTypeCategory2, &failure);
            checkWidePair(tmpType, typeHi, &failure);
        }
        if (!VERIFY_OK(failure))
            break;

        resClass = getClassFromRegister(workLine, decInsn.vB, &failure);
        if (!VERIFY_OK(failure))
            break;
        if (resClass != NULL) {
            /* verify the class and try to refine "dstType" */
            if (!dvmIsArrayClass(resClass) || resClass->arrayDim != 1 ||
                resClass->elementClass->primitiveType == PRIM_NOT)
            {
                LOG_VFY("VFY: invalid aput-wide on %s\n",
                        resClass->descriptor);
                failure = VERIFY_ERROR_GENERIC;
                break;
            }

            switch (resClass->elementClass->primitiveType) {
            case PRIM_LONG:
            case PRIM_DOUBLE:
                /* these are okay */
                break;
            default:
                LOG_VFY("VFY: invalid aput-wide on %s\n",
                        resClass->descriptor);
                failure = VERIFY_ERROR_GENERIC;
                break;
            }
        }
        break;
    case OP_APUT_OBJECT:
        tmpType = getRegisterType(workLine, decInsn.vC);
        checkArrayIndexType(meth, tmpType, &failure);
        if (!VERIFY_OK(failure))
            break;

        /* get the ref we're storing; Zero is okay, Uninit is not */
        resClass = getClassFromRegister(workLine, decInsn.vA, &failure);
        if (!VERIFY_OK(failure))
            break;
        if (resClass != NULL) {
            ClassObject* arrayClass;
            ClassObject* elementClass;

            /*
             * Get the array class.  If the array ref is null, we won't
             * have type information (and we'll crash at runtime with a
             * null pointer exception).
             */
            arrayClass = getClassFromRegister(workLine, decInsn.vB, &failure);

            if (arrayClass != NULL) {
                /* see if the array holds a compatible type */
                if (!dvmIsArrayClass(arrayClass)) {
                    LOG_VFY("VFY: invalid aput-object on %s\n",
                            arrayClass->descriptor);
                    failure = VERIFY_ERROR_GENERIC;
                    break;
                }

                /*
                 * Find the element class.  resClass->elementClass indicates
                 * the basic type, which won't be what we want for a
                 * multi-dimensional array.
                 *
                 * All we want to check here is that the element type is a
                 * reference class.  We *don't* check instanceof here, because
                 * you can still put a String into a String[] after the latter
                 * has been cast to an Object[].
                 */
                if (arrayClass->descriptor[1] == '[') {
                    assert(arrayClass->arrayDim > 1);
                    elementClass = dvmFindArrayClass(&arrayClass->descriptor[1],
                                        arrayClass->classLoader);
                } else {
                    assert(arrayClass->arrayDim == 1);
                    elementClass = arrayClass->elementClass;
                }
                if (elementClass->primitiveType != PRIM_NOT) {
                    LOG_VFY("VFY: invalid aput-object of %s into %s\n",
                            resClass->descriptor, arrayClass->descriptor);
                    failure = VERIFY_ERROR_GENERIC;
                    break;
                }
            }
        }
        break;

    case OP_IGET:
    case OP_IGET_VOLATILE:
        tmpType = kRegTypeInteger;
        goto iget_1nr_common;
    case OP_IGET_BOOLEAN:
        tmpType = kRegTypeBoolean;
        goto iget_1nr_common;
    case OP_IGET_BYTE:
        tmpType = kRegTypeByte;
        goto iget_1nr_common;
    case OP_IGET_CHAR:
        tmpType = kRegTypeChar;
        goto iget_1nr_common;
    case OP_IGET_SHORT:
        tmpType = kRegTypeShort;
        goto iget_1nr_common;
iget_1nr_common:
        {
            InstField* instField;
            RegType objType, fieldType;

            objType = getRegisterType(workLine, decInsn.vB);
            instField = getInstField(meth, uninitMap, objType, decInsn.vC,
                            &failure);
            if (!VERIFY_OK(failure))
                break;

            /* make sure the field's type is compatible with expectation */
            fieldType = primSigCharToRegType(instField->field.signature[0]);
            if (fieldType == kRegTypeUnknown ||
                !checkFieldArrayStore1nr(tmpType, fieldType))
            {
                LOG_VFY("VFY: invalid iget-1nr of %s.%s (inst=%d field=%d)\n",
                        instField->field.clazz->descriptor,
                        instField->field.name, tmpType, fieldType);
                failure = VERIFY_ERROR_GENERIC;
                break;
            }

            setRegisterType(workLine, decInsn.vA, tmpType);
        }
        break;
    case OP_IGET_WIDE:
    case OP_IGET_WIDE_VOLATILE:
        {
            RegType dstType;
            InstField* instField;
            RegType objType;

            objType = getRegisterType(workLine, decInsn.vB);
            instField = getInstField(meth, uninitMap, objType, decInsn.vC,
                            &failure);
            if (!VERIFY_OK(failure))
                break;
            /* check the type, which should be prim */
            switch (instField->field.signature[0]) {
            case 'D':
                dstType = kRegTypeDoubleLo;
                break;
            case 'J':
                dstType = kRegTypeLongLo;
                break;
            default:
                LOG_VFY("VFY: invalid iget-wide of %s.%s\n",
                        instField->field.clazz->descriptor,
                        instField->field.name);
                dstType = kRegTypeUnknown;
                failure = VERIFY_ERROR_GENERIC;
                break;
            }
            if (VERIFY_OK(failure)) {
                setRegisterType(workLine, decInsn.vA, dstType);
            }
        }
        break;
    case OP_IGET_OBJECT:
    case OP_IGET_OBJECT_VOLATILE:
        {
            ClassObject* fieldClass;
            InstField* instField;
            RegType objType;

            objType = getRegisterType(workLine, decInsn.vB);
            instField = getInstField(meth, uninitMap, objType, decInsn.vC,
                            &failure);
            if (!VERIFY_OK(failure))
                break;
            fieldClass = getFieldClass(meth, &instField->field);
            if (fieldClass == NULL) {
                /* class not found or primitive type */
                LOG_VFY("VFY: unable to recover field class from '%s'\n",
                    instField->field.signature);
                failure = VERIFY_ERROR_GENERIC;
                break;
            }
            if (VERIFY_OK(failure)) {
                assert(!dvmIsPrimitiveClass(fieldClass));
                setRegisterType(workLine, decInsn.vA,
                    regTypeFromClass(fieldClass));
            }
        }
        break;
    case OP_IPUT:
    case OP_IPUT_VOLATILE:
        tmpType = kRegTypeInteger;
        goto iput_1nr_common;
    case OP_IPUT_BOOLEAN:
        tmpType = kRegTypeBoolean;
        goto iput_1nr_common;
    case OP_IPUT_BYTE:
        tmpType = kRegTypeByte;
        goto iput_1nr_common;
    case OP_IPUT_CHAR:
        tmpType = kRegTypeChar;
        goto iput_1nr_common;
    case OP_IPUT_SHORT:
        tmpType = kRegTypeShort;
        goto iput_1nr_common;
iput_1nr_common:
        {
            RegType srcType, fieldType, objType;
            InstField* instField;

            srcType = getRegisterType(workLine, decInsn.vA);

            /*
             * javac generates synthetic functions that write byte values
             * into boolean fields.
             */
            if (tmpType == kRegTypeBoolean && srcType == kRegTypeByte)
                srcType = kRegTypeBoolean;

            /* make sure the source register has the correct type */
            if (!canConvertTo1nr(srcType, tmpType)) {
                LOG_VFY("VFY: invalid reg type %d on iput instr (need %d)\n",
                    srcType, tmpType);
                failure = VERIFY_ERROR_GENERIC;
                break;
            }

            objType = getRegisterType(workLine, decInsn.vB);
            instField = getInstField(meth, uninitMap, objType, decInsn.vC,
                            &failure);
            if (!VERIFY_OK(failure))
                break;
            checkFinalFieldAccess(meth, &instField->field, &failure);
            if (!VERIFY_OK(failure))
                break;

            /* get type of field we're storing into */
            fieldType = primSigCharToRegType(instField->field.signature[0]);
            if (fieldType == kRegTypeUnknown ||
                !checkFieldArrayStore1nr(tmpType, fieldType))
            {
                LOG_VFY("VFY: invalid iput-1nr of %s.%s (inst=%d field=%d)\n",
                        instField->field.clazz->descriptor,
                        instField->field.name, tmpType, fieldType);
                failure = VERIFY_ERROR_GENERIC;
                break;
            }
        }
        break;
    case OP_IPUT_WIDE:
    case OP_IPUT_WIDE_VOLATILE:
        tmpType = getRegisterType(workLine, decInsn.vA);
        {
            RegType typeHi = getRegisterType(workLine, decInsn.vA+1);
            checkTypeCategory(tmpType, kTypeCategory2, &failure);
            checkWidePair(tmpType, typeHi, &failure);
        }
        if (VERIFY_OK(failure)) {
            InstField* instField;
            RegType objType;

            objType = getRegisterType(workLine, decInsn.vB);
            instField = getInstField(meth, uninitMap, objType, decInsn.vC,
                            &failure);
            if (!VERIFY_OK(failure))
                break;
            checkFinalFieldAccess(meth, &instField->field, &failure);
            if (!VERIFY_OK(failure))
                break;

            /* check the type, which should be prim */
            switch (instField->field.signature[0]) {
            case 'D':
            case 'J':
                /* these are okay (and interchangeable) */
                break;
            default:
                LOG_VFY("VFY: invalid iput-wide of %s.%s\n",
                        instField->field.clazz->descriptor,
                        instField->field.name);
                failure = VERIFY_ERROR_GENERIC;
                break;
            }
        }
        break;
    case OP_IPUT_OBJECT:
    case OP_IPUT_OBJECT_VOLATILE:
        {
            ClassObject* fieldClass;
            ClassObject* valueClass;
            InstField* instField;
            RegType objType, valueType;

            objType = getRegisterType(workLine, decInsn.vB);
            instField = getInstField(meth, uninitMap, objType, decInsn.vC,
                            &failure);
            if (!VERIFY_OK(failure))
                break;
            checkFinalFieldAccess(meth, &instField->field, &failure);
            if (!VERIFY_OK(failure))
                break;

            fieldClass = getFieldClass(meth, &instField->field);
            if (fieldClass == NULL) {
                LOG_VFY("VFY: unable to recover field class from '%s'\n",
                    instField->field.signature);
                failure = VERIFY_ERROR_GENERIC;
                break;
            }

            valueType = getRegisterType(workLine, decInsn.vA);
            if (!regTypeIsReference(valueType)) {
                LOG_VFY("VFY: storing non-ref v%d into ref field '%s' (%s)\n",
                        decInsn.vA, instField->field.name,
                        fieldClass->descriptor);
                failure = VERIFY_ERROR_GENERIC;
                break;
            }
            if (valueType != kRegTypeZero) {
                valueClass = regTypeInitializedReferenceToClass(valueType);
                if (valueClass == NULL) {
                    LOG_VFY("VFY: storing uninit ref v%d into ref field\n",
                        decInsn.vA);
                    failure = VERIFY_ERROR_GENERIC;
                    break;
                }
                /* allow if field is any interface or field is base class */
                if (!dvmIsInterfaceClass(fieldClass) &&
                    !dvmInstanceof(valueClass, fieldClass))
                {
                    LOG_VFY("VFY: storing type '%s' into field type '%s' (%s.%s)\n",
                            valueClass->descriptor, fieldClass->descriptor,
                            instField->field.clazz->descriptor,
                            instField->field.name);
                    failure = VERIFY_ERROR_GENERIC;
                    break;
                }
            }
        }
        break;

    case OP_SGET:
    case OP_SGET_VOLATILE:
        tmpType = kRegTypeInteger;
        goto sget_1nr_common;
    case OP_SGET_BOOLEAN:
        tmpType = kRegTypeBoolean;
        goto sget_1nr_common;
    case OP_SGET_BYTE:
        tmpType = kRegTypeByte;
        goto sget_1nr_common;
    case OP_SGET_CHAR:
        tmpType = kRegTypeChar;
        goto sget_1nr_common;
    case OP_SGET_SHORT:
        tmpType = kRegTypeShort;
        goto sget_1nr_common;
sget_1nr_common:
        {
            StaticField* staticField;
            RegType fieldType;

            staticField = getStaticField(meth, decInsn.vB, &failure);
            if (!VERIFY_OK(failure))
                break;

            /*
             * Make sure the field's type is compatible with expectation.
             * We can get ourselves into trouble if we mix & match loads
             * and stores with different widths, so rather than just checking
             * "canConvertTo1nr" we require that the field types have equal
             * widths.  (We can't generally require an exact type match,
             * because e.g. "int" and "float" are interchangeable.)
             */
            fieldType = primSigCharToRegType(staticField->field.signature[0]);
            if (!checkFieldArrayStore1nr(tmpType, fieldType)) {
                LOG_VFY("VFY: invalid sget-1nr of %s.%s (inst=%d actual=%d)\n",
                    staticField->field.clazz->descriptor,
                    staticField->field.name, tmpType, fieldType);
                failure = VERIFY_ERROR_GENERIC;
                break;
            }

            setRegisterType(workLine, decInsn.vA, tmpType);
        }
        break;
    case OP_SGET_WIDE:
    case OP_SGET_WIDE_VOLATILE:
        {
            StaticField* staticField;
            RegType dstType;

            staticField = getStaticField(meth, decInsn.vB, &failure);
            if (!VERIFY_OK(failure))
                break;
            /* check the type, which should be prim */
            switch (staticField->field.signature[0]) {
            case 'D':
                dstType = kRegTypeDoubleLo;
                break;
            case 'J':
                dstType = kRegTypeLongLo;
                break;
            default:
                LOG_VFY("VFY: invalid sget-wide of %s.%s\n",
                        staticField->field.clazz->descriptor,
                        staticField->field.name);
                dstType = kRegTypeUnknown;
                failure = VERIFY_ERROR_GENERIC;
                break;
            }
            if (VERIFY_OK(failure)) {
                setRegisterType(workLine, decInsn.vA, dstType);
            }
        }
        break;
    case OP_SGET_OBJECT:
    case OP_SGET_OBJECT_VOLATILE:
        {
            StaticField* staticField;
            ClassObject* fieldClass;

            staticField = getStaticField(meth, decInsn.vB, &failure);
            if (!VERIFY_OK(failure))
                break;
            fieldClass = getFieldClass(meth, &staticField->field);
            if (fieldClass == NULL) {
                LOG_VFY("VFY: unable to recover field class from '%s'\n",
                    staticField->field.signature);
                failure = VERIFY_ERROR_GENERIC;
                break;
            }
            if (dvmIsPrimitiveClass(fieldClass)) {
                LOG_VFY("VFY: attempt to get prim field with sget-object\n");
                failure = VERIFY_ERROR_GENERIC;
                break;
            }
            setRegisterType(workLine, decInsn.vA, regTypeFromClass(fieldClass));
        }
        break;
    case OP_SPUT:
    case OP_SPUT_VOLATILE:
        tmpType = kRegTypeInteger;
        goto sput_1nr_common;
    case OP_SPUT_BOOLEAN:
        tmpType = kRegTypeBoolean;
        goto sput_1nr_common;
    case OP_SPUT_BYTE:
        tmpType = kRegTypeByte;
        goto sput_1nr_common;
    case OP_SPUT_CHAR:
        tmpType = kRegTypeChar;
        goto sput_1nr_common;
    case OP_SPUT_SHORT:
        tmpType = kRegTypeShort;
        goto sput_1nr_common;
sput_1nr_common:
        {
            RegType srcType, fieldType;
            StaticField* staticField;

            srcType = getRegisterType(workLine, decInsn.vA);

            /*
             * javac generates synthetic functions that write byte values
             * into boolean fields.
             */
            if (tmpType == kRegTypeBoolean && srcType == kRegTypeByte)
                srcType = kRegTypeBoolean;

            /* make sure the source register has the correct type */
            if (!canConvertTo1nr(srcType, tmpType)) {
                LOG_VFY("VFY: invalid reg type %d on sput instr (need %d)\n",
                    srcType, tmpType);
                failure = VERIFY_ERROR_GENERIC;
                break;
            }

            staticField = getStaticField(meth, decInsn.vB, &failure);
            if (!VERIFY_OK(failure))
                break;
            checkFinalFieldAccess(meth, &staticField->field, &failure);
            if (!VERIFY_OK(failure))
                break;

            /*
             * Get type of field we're storing into.  We know that the
             * contents of the register match the instruction, but we also
             * need to ensure that the instruction matches the field type.
             * Using e.g. sput-short to write into a 32-bit integer field
             * can lead to trouble if we do 16-bit writes.
             */
            fieldType = primSigCharToRegType(staticField->field.signature[0]);
            if (!checkFieldArrayStore1nr(tmpType, fieldType)) {
                LOG_VFY("VFY: invalid sput-1nr of %s.%s (inst=%d actual=%d)\n",
                    staticField->field.clazz->descriptor,
                    staticField->field.name, tmpType, fieldType);
                failure = VERIFY_ERROR_GENERIC;
                break;
            }
        }
        break;
    case OP_SPUT_WIDE:
    case OP_SPUT_WIDE_VOLATILE:
        tmpType = getRegisterType(workLine, decInsn.vA);
        {
            RegType typeHi = getRegisterType(workLine, decInsn.vA+1);
            checkTypeCategory(tmpType, kTypeCategory2, &failure);
            checkWidePair(tmpType, typeHi, &failure);
        }
        if (VERIFY_OK(failure)) {
            StaticField* staticField;

            staticField = getStaticField(meth, decInsn.vB, &failure);
            if (!VERIFY_OK(failure))
                break;
            checkFinalFieldAccess(meth, &staticField->field, &failure);
            if (!VERIFY_OK(failure))
                break;

            /* check the type, which should be prim */
            switch (staticField->field.signature[0]) {
            case 'D':
            case 'J':
                /* these are okay */
                break;
            default:
                LOG_VFY("VFY: invalid sput-wide of %s.%s\n",
                        staticField->field.clazz->descriptor,
                        staticField->field.name);
                failure = VERIFY_ERROR_GENERIC;
                break;
            }
        }
        break;
    case OP_SPUT_OBJECT:
    case OP_SPUT_OBJECT_VOLATILE:
        {
            ClassObject* fieldClass;
            ClassObject* valueClass;
            StaticField* staticField;
            RegType valueType;

            staticField = getStaticField(meth, decInsn.vB, &failure);
            if (!VERIFY_OK(failure))
                break;
            checkFinalFieldAccess(meth, &staticField->field, &failure);
            if (!VERIFY_OK(failure))
                break;

            fieldClass = getFieldClass(meth, &staticField->field);
            if (fieldClass == NULL) {
                LOG_VFY("VFY: unable to recover field class from '%s'\n",
                    staticField->field.signature);
                failure = VERIFY_ERROR_GENERIC;
                break;
            }

            valueType = getRegisterType(workLine, decInsn.vA);
            if (!regTypeIsReference(valueType)) {
                LOG_VFY("VFY: storing non-ref v%d into ref field '%s' (%s)\n",
                        decInsn.vA, staticField->field.name,
                        fieldClass->descriptor);
                failure = VERIFY_ERROR_GENERIC;
                break;
            }
            if (valueType != kRegTypeZero) {
                valueClass = regTypeInitializedReferenceToClass(valueType);
                if (valueClass == NULL) {
                    LOG_VFY("VFY: storing uninit ref v%d into ref field\n",
                        decInsn.vA);
                    failure = VERIFY_ERROR_GENERIC;
                    break;
                }
                /* allow if field is any interface or field is base class */
                if (!dvmIsInterfaceClass(fieldClass) &&
                    !dvmInstanceof(valueClass, fieldClass))
                {
                    LOG_VFY("VFY: storing type '%s' into field type '%s' (%s.%s)\n",
                            valueClass->descriptor, fieldClass->descriptor,
                            staticField->field.clazz->descriptor,
                            staticField->field.name);
                    failure = VERIFY_ERROR_GENERIC;
                    break;
                }
            }
        }
        break;

    case OP_INVOKE_VIRTUAL:
    case OP_INVOKE_VIRTUAL_RANGE:
    case OP_INVOKE_SUPER:
    case OP_INVOKE_SUPER_RANGE:
        {
            Method* calledMethod;
            RegType returnType;
            bool isRange;
            bool isSuper;

            isRange =  (decInsn.opcode == OP_INVOKE_VIRTUAL_RANGE ||
                        decInsn.opcode == OP_INVOKE_SUPER_RANGE);
            isSuper =  (decInsn.opcode == OP_INVOKE_SUPER ||
                        decInsn.opcode == OP_INVOKE_SUPER_RANGE);

            calledMethod = verifyInvocationArgs(meth, workLine, insnRegCount,
                            &decInsn, uninitMap, METHOD_VIRTUAL, isRange,
                            isSuper, &failure);
            if (!VERIFY_OK(failure))
                break;
            returnType = getMethodReturnType(calledMethod);
            setResultRegisterType(workLine, insnRegCount, returnType);
            justSetResult = true;
        }
        break;
    case OP_INVOKE_DIRECT:
    case OP_INVOKE_DIRECT_RANGE:
        {
            RegType returnType;
            Method* calledMethod;
            bool isRange;

            isRange =  (decInsn.opcode == OP_INVOKE_DIRECT_RANGE);
            calledMethod = verifyInvocationArgs(meth, workLine, insnRegCount,
                            &decInsn, uninitMap, METHOD_DIRECT, isRange,
                            false, &failure);
            if (!VERIFY_OK(failure))
                break;

            /*
             * Some additional checks when calling <init>.  We know from
             * the invocation arg check that the "this" argument is an
             * instance of calledMethod->clazz.  Now we further restrict
             * that to require that calledMethod->clazz is the same as
             * this->clazz or this->super, allowing the latter only if
             * the "this" argument is the same as the "this" argument to
             * this method (which implies that we're in <init> ourselves).
             */
            if (isInitMethod(calledMethod)) {
                RegType thisType;
                thisType = getInvocationThis(workLine, &decInsn, &failure);
                if (!VERIFY_OK(failure))
                    break;

                /* no null refs allowed (?) */
                if (thisType == kRegTypeZero) {
                    LOG_VFY("VFY: unable to initialize null ref\n");
                    failure = VERIFY_ERROR_GENERIC;
                    break;
                }

                ClassObject* thisClass;

                thisClass = regTypeReferenceToClass(thisType, uninitMap);
                assert(thisClass != NULL);

                /* must be in same class or in superclass */
                if (calledMethod->clazz == thisClass->super) {
                    if (thisClass != meth->clazz) {
                        LOG_VFY("VFY: invoke-direct <init> on super only "
                            "allowed for 'this' in <init>");
                        failure = VERIFY_ERROR_GENERIC;
                        break;
                    }
                }  else if (calledMethod->clazz != thisClass) {
                    LOG_VFY("VFY: invoke-direct <init> must be on current "
                            "class or super\n");
                    failure = VERIFY_ERROR_GENERIC;
                    break;
                }

                /* arg must be an uninitialized reference */
                if (!regTypeIsUninitReference(thisType)) {
                    LOG_VFY("VFY: can only initialize the uninitialized\n");
                    failure = VERIFY_ERROR_GENERIC;
                    break;
                }

                /*
                 * Replace the uninitialized reference with an initialized
                 * one, and clear the entry in the uninit map.  We need to
                 * do this for all registers that have the same object
                 * instance in them, not just the "this" register.
                 */
                markRefsAsInitialized(workLine, insnRegCount, uninitMap,
                    thisType, &failure);
                if (!VERIFY_OK(failure))
                    break;
            }
            returnType = getMethodReturnType(calledMethod);
            setResultRegisterType(workLine, insnRegCount, returnType);
            justSetResult = true;
        }
        break;
    case OP_INVOKE_STATIC:
    case OP_INVOKE_STATIC_RANGE:
        {
            RegType returnType;
            Method* calledMethod;
            bool isRange;

            isRange =  (decInsn.opcode == OP_INVOKE_STATIC_RANGE);
            calledMethod = verifyInvocationArgs(meth, workLine, insnRegCount,
                            &decInsn, uninitMap, METHOD_STATIC, isRange,
                            false, &failure);
            if (!VERIFY_OK(failure))
                break;

            returnType = getMethodReturnType(calledMethod);
            setResultRegisterType(workLine, insnRegCount, returnType);
            justSetResult = true;
        }
        break;
    case OP_INVOKE_INTERFACE:
    case OP_INVOKE_INTERFACE_RANGE:
        {
            RegType /*thisType,*/ returnType;
            Method* absMethod;
            bool isRange;

            isRange =  (decInsn.opcode == OP_INVOKE_INTERFACE_RANGE);
            absMethod = verifyInvocationArgs(meth, workLine, insnRegCount,
                            &decInsn, uninitMap, METHOD_INTERFACE, isRange,
                            false, &failure);
            if (!VERIFY_OK(failure))
                break;

#if 0       /* can't do this here, fails on dalvik test 052-verifier-fun */
            /*
             * Get the type of the "this" arg, which should always be an
             * interface class.  Because we don't do a full merge on
             * interface classes, this might have reduced to Object.
             */
            thisType = getInvocationThis(workLine, &decInsn, &failure);
            if (!VERIFY_OK(failure))
                break;

            if (thisType == kRegTypeZero) {
                /* null pointer always passes (and always fails at runtime) */
            } else {
                ClassObject* thisClass;

                thisClass = regTypeInitializedReferenceToClass(thisType);
                if (thisClass == NULL) {
                    LOG_VFY("VFY: interface call on uninitialized\n");
                    failure = VERIFY_ERROR_GENERIC;
                    break;
                }

                /*
                 * Either "thisClass" needs to be the interface class that
                 * defined absMethod, or absMethod's class needs to be one
                 * of the interfaces implemented by "thisClass".  (Or, if
                 * we couldn't complete the merge, this will be Object.)
                 */
                if (thisClass != absMethod->clazz &&
                    thisClass != gDvm.classJavaLangObject &&
                    !dvmImplements(thisClass, absMethod->clazz))
                {
                    LOG_VFY("VFY: unable to match absMethod '%s' with %s interfaces\n",
                            absMethod->name, thisClass->descriptor);
                    failure = VERIFY_ERROR_GENERIC;
                    break;
                }
            }
#endif

            /*
             * We don't have an object instance, so we can't find the
             * concrete method.  However, all of the type information is
             * in the abstract method, so we're good.
             */
            returnType = getMethodReturnType(absMethod);
            setResultRegisterType(workLine, insnRegCount, returnType);
            justSetResult = true;
        }
        break;

    case OP_NEG_INT:
    case OP_NOT_INT:
        checkUnop(workLine, &decInsn,
            kRegTypeInteger, kRegTypeInteger, &failure);
        break;
    case OP_NEG_LONG:
    case OP_NOT_LONG:
        checkUnop(workLine, &decInsn,
            kRegTypeLongLo, kRegTypeLongLo, &failure);
        break;
    case OP_NEG_FLOAT:
        checkUnop(workLine, &decInsn,
            kRegTypeFloat, kRegTypeFloat, &failure);
        break;
    case OP_NEG_DOUBLE:
        checkUnop(workLine, &decInsn,
            kRegTypeDoubleLo, kRegTypeDoubleLo, &failure);
        break;
    case OP_INT_TO_LONG:
        checkUnop(workLine, &decInsn,
            kRegTypeLongLo, kRegTypeInteger, &failure);
        break;
    case OP_INT_TO_FLOAT:
        checkUnop(workLine, &decInsn,
            kRegTypeFloat, kRegTypeInteger, &failure);
        break;
    case OP_INT_TO_DOUBLE:
        checkUnop(workLine, &decInsn,
            kRegTypeDoubleLo, kRegTypeInteger, &failure);
        break;
    case OP_LONG_TO_INT:
        checkUnop(workLine, &decInsn,
            kRegTypeInteger, kRegTypeLongLo, &failure);
        break;
    case OP_LONG_TO_FLOAT:
        checkUnop(workLine, &decInsn,
            kRegTypeFloat, kRegTypeLongLo, &failure);
        break;
    case OP_LONG_TO_DOUBLE:
        checkUnop(workLine, &decInsn,
            kRegTypeDoubleLo, kRegTypeLongLo, &failure);
        break;
    case OP_FLOAT_TO_INT:
        checkUnop(workLine, &decInsn,
            kRegTypeInteger, kRegTypeFloat, &failure);
        break;
    case OP_FLOAT_TO_LONG:
        checkUnop(workLine, &decInsn,
            kRegTypeLongLo, kRegTypeFloat, &failure);
        break;
    case OP_FLOAT_TO_DOUBLE:
        checkUnop(workLine, &decInsn,
            kRegTypeDoubleLo, kRegTypeFloat, &failure);
        break;
    case OP_DOUBLE_TO_INT:
        checkUnop(workLine, &decInsn,
            kRegTypeInteger, kRegTypeDoubleLo, &failure);
        break;
    case OP_DOUBLE_TO_LONG:
        checkUnop(workLine, &decInsn,
            kRegTypeLongLo, kRegTypeDoubleLo, &failure);
        break;
    case OP_DOUBLE_TO_FLOAT:
        checkUnop(workLine, &decInsn,
            kRegTypeFloat, kRegTypeDoubleLo, &failure);
        break;
    case OP_INT_TO_BYTE:
        checkUnop(workLine, &decInsn,
            kRegTypeByte, kRegTypeInteger, &failure);
        break;
    case OP_INT_TO_CHAR:
        checkUnop(workLine, &decInsn,
            kRegTypeChar, kRegTypeInteger, &failure);
        break;
    case OP_INT_TO_SHORT:
        checkUnop(workLine, &decInsn,
            kRegTypeShort, kRegTypeInteger, &failure);
        break;

    case OP_ADD_INT:
    case OP_SUB_INT:
    case OP_MUL_INT:
    case OP_REM_INT:
    case OP_DIV_INT:
    case OP_SHL_INT:
    case OP_SHR_INT:
    case OP_USHR_INT:
        checkBinop(workLine, &decInsn,
            kRegTypeInteger, kRegTypeInteger, kRegTypeInteger, false, &failure);
        break;
    case OP_AND_INT:
    case OP_OR_INT:
    case OP_XOR_INT:
        checkBinop(workLine, &decInsn,
            kRegTypeInteger, kRegTypeInteger, kRegTypeInteger, true, &failure);
        break;
    case OP_ADD_LONG:
    case OP_SUB_LONG:
    case OP_MUL_LONG:
    case OP_DIV_LONG:
    case OP_REM_LONG:
    case OP_AND_LONG:
    case OP_OR_LONG:
    case OP_XOR_LONG:
        checkBinop(workLine, &decInsn,
            kRegTypeLongLo, kRegTypeLongLo, kRegTypeLongLo, false, &failure);
        break;
    case OP_SHL_LONG:
    case OP_SHR_LONG:
    case OP_USHR_LONG:
        /* shift distance is Int, making these different from other binops */
        checkBinop(workLine, &decInsn,
            kRegTypeLongLo, kRegTypeLongLo, kRegTypeInteger, false, &failure);
        break;
    case OP_ADD_FLOAT:
    case OP_SUB_FLOAT:
    case OP_MUL_FLOAT:
    case OP_DIV_FLOAT:
    case OP_REM_FLOAT:
        checkBinop(workLine, &decInsn,
            kRegTypeFloat, kRegTypeFloat, kRegTypeFloat, false, &failure);
        break;
    case OP_ADD_DOUBLE:
    case OP_SUB_DOUBLE:
    case OP_MUL_DOUBLE:
    case OP_DIV_DOUBLE:
    case OP_REM_DOUBLE:
        checkBinop(workLine, &decInsn,
            kRegTypeDoubleLo, kRegTypeDoubleLo, kRegTypeDoubleLo, false,
            &failure);
        break;
    case OP_ADD_INT_2ADDR:
    case OP_SUB_INT_2ADDR:
    case OP_MUL_INT_2ADDR:
    case OP_REM_INT_2ADDR:
    case OP_SHL_INT_2ADDR:
    case OP_SHR_INT_2ADDR:
    case OP_USHR_INT_2ADDR:
        checkBinop2addr(workLine, &decInsn,
            kRegTypeInteger, kRegTypeInteger, kRegTypeInteger, false, &failure);
        break;
    case OP_AND_INT_2ADDR:
    case OP_OR_INT_2ADDR:
    case OP_XOR_INT_2ADDR:
        checkBinop2addr(workLine, &decInsn,
            kRegTypeInteger, kRegTypeInteger, kRegTypeInteger, true, &failure);
        break;
    case OP_DIV_INT_2ADDR:
        checkBinop2addr(workLine, &decInsn,
            kRegTypeInteger, kRegTypeInteger, kRegTypeInteger, false, &failure);
        break;
    case OP_ADD_LONG_2ADDR:
    case OP_SUB_LONG_2ADDR:
    case OP_MUL_LONG_2ADDR:
    case OP_DIV_LONG_2ADDR:
    case OP_REM_LONG_2ADDR:
    case OP_AND_LONG_2ADDR:
    case OP_OR_LONG_2ADDR:
    case OP_XOR_LONG_2ADDR:
        checkBinop2addr(workLine, &decInsn,
            kRegTypeLongLo, kRegTypeLongLo, kRegTypeLongLo, false, &failure);
        break;
    case OP_SHL_LONG_2ADDR:
    case OP_SHR_LONG_2ADDR:
    case OP_USHR_LONG_2ADDR:
        checkBinop2addr(workLine, &decInsn,
            kRegTypeLongLo, kRegTypeLongLo, kRegTypeInteger, false, &failure);
        break;
    case OP_ADD_FLOAT_2ADDR:
    case OP_SUB_FLOAT_2ADDR:
    case OP_MUL_FLOAT_2ADDR:
    case OP_DIV_FLOAT_2ADDR:
    case OP_REM_FLOAT_2ADDR:
        checkBinop2addr(workLine, &decInsn,
            kRegTypeFloat, kRegTypeFloat, kRegTypeFloat, false, &failure);
        break;
    case OP_ADD_DOUBLE_2ADDR:
    case OP_SUB_DOUBLE_2ADDR:
    case OP_MUL_DOUBLE_2ADDR:
    case OP_DIV_DOUBLE_2ADDR:
    case OP_REM_DOUBLE_2ADDR:
        checkBinop2addr(workLine, &decInsn,
            kRegTypeDoubleLo, kRegTypeDoubleLo, kRegTypeDoubleLo, false,
            &failure);
        break;
    case OP_ADD_INT_LIT16:
    case OP_RSUB_INT:
    case OP_MUL_INT_LIT16:
    case OP_DIV_INT_LIT16:
    case OP_REM_INT_LIT16:
        checkLitop(workLine, &decInsn,
            kRegTypeInteger, kRegTypeInteger, false, &failure);
        break;
    case OP_AND_INT_LIT16:
    case OP_OR_INT_LIT16:
    case OP_XOR_INT_LIT16:
        checkLitop(workLine, &decInsn,
            kRegTypeInteger, kRegTypeInteger, true, &failure);
        break;
    case OP_ADD_INT_LIT8:
    case OP_RSUB_INT_LIT8:
    case OP_MUL_INT_LIT8:
    case OP_DIV_INT_LIT8:
    case OP_REM_INT_LIT8:
    case OP_SHL_INT_LIT8:
        checkLitop(workLine, &decInsn,
            kRegTypeInteger, kRegTypeInteger, false, &failure);
        break;
    case OP_SHR_INT_LIT8:
        tmpType = adjustForRightShift(workLine,
            decInsn.vB, decInsn.vC, false, &failure);
        checkLitop(workLine, &decInsn,
            tmpType, kRegTypeInteger, false, &failure);
        break;
    case OP_USHR_INT_LIT8:
        tmpType = adjustForRightShift(workLine,
            decInsn.vB, decInsn.vC, true, &failure);
        checkLitop(workLine, &decInsn,
            tmpType, kRegTypeInteger, false, &failure);
        break;
    case OP_AND_INT_LIT8:
    case OP_OR_INT_LIT8:
    case OP_XOR_INT_LIT8:
        checkLitop(workLine, &decInsn,
            kRegTypeInteger, kRegTypeInteger, true, &failure);
        break;

    /*
     * This falls into the general category of "optimized" instructions,
     * which don't generally appear during verification.  Because it's
     * inserted in the course of verification, we can expect to see it here.
     */
    case OP_THROW_VERIFICATION_ERROR:
        break;

    /*
     * Verifying "quickened" instructions is tricky, because we have
     * discarded the original field/method information.  The byte offsets
     * and vtable indices only have meaning in the context of an object
     * instance.
     *
     * If a piece of code declares a local reference variable, assigns
     * null to it, and then issues a virtual method call on it, we
     * cannot evaluate the method call during verification.  This situation
     * isn't hard to handle, since we know the call will always result in an
     * NPE, and the arguments and return value don't matter.  Any code that
     * depends on the result of the method call is inaccessible, so the
     * fact that we can't fully verify anything that comes after the bad
     * call is not a problem.
     *
     * We must also consider the case of multiple code paths, only some of
     * which involve a null reference.  We can completely verify the method
     * if we sidestep the results of executing with a null reference.
     * For example, if on the first pass through the code we try to do a
     * virtual method invocation through a null ref, we have to skip the
     * method checks and have the method return a "wildcard" type (which
     * merges with anything to become that other thing).  The move-result
     * will tell us if it's a reference, single-word numeric, or double-word
     * value.  We continue to perform the verification, and at the end of
     * the function any invocations that were never fully exercised are
     * marked as null-only.
     *
     * We would do something similar for the field accesses.  The field's
     * type, once known, can be used to recover the width of short integers.
     * If the object reference was null, the field-get returns the "wildcard"
     * type, which is acceptable for any operation.
     */
    case OP_EXECUTE_INLINE:
    case OP_EXECUTE_INLINE_RANGE:
    case OP_INVOKE_DIRECT_EMPTY:
    case OP_IGET_QUICK:
    case OP_IGET_WIDE_QUICK:
    case OP_IGET_OBJECT_QUICK:
    case OP_IPUT_QUICK:
    case OP_IPUT_WIDE_QUICK:
    case OP_IPUT_OBJECT_QUICK:
    case OP_INVOKE_VIRTUAL_QUICK:
    case OP_INVOKE_VIRTUAL_QUICK_RANGE:
    case OP_INVOKE_SUPER_QUICK:
    case OP_INVOKE_SUPER_QUICK_RANGE:
    case OP_RETURN_VOID_BARRIER:
        failure = VERIFY_ERROR_GENERIC;
        break;

    /* these should never appear during verification */
    case OP_UNUSED_3E:
    case OP_UNUSED_3F:
    case OP_UNUSED_40:
    case OP_UNUSED_41:
    case OP_UNUSED_42:
    case OP_UNUSED_43:
    case OP_UNUSED_73:
    case OP_UNUSED_79:
    case OP_UNUSED_7A:
    case OP_BREAKPOINT:
    case OP_DISPATCH_FF:
        failure = VERIFY_ERROR_GENERIC;
        break;

    /*
     * DO NOT add a "default" clause here.  Without it the compiler will
     * complain if an instruction is missing (which is desirable).
     */
    }

    if (!VERIFY_OK(failure)) {
        if (failure == VERIFY_ERROR_GENERIC || gDvm.optimizing) {
            /* immediate failure, reject class */
            LOG_VFY_METH(meth, "VFY:  rejecting opcode 0x%02x at 0x%04x\n",
                decInsn.opcode, insnIdx);
            goto bail;
        } else {
            /* replace opcode and continue on */
            LOGD("VFY: replacing opcode 0x%02x at 0x%04x\n",
                decInsn.opcode, insnIdx);
            if (!replaceFailingInstruction(meth, insnFlags, insnIdx, failure)) {
                LOG_VFY_METH(meth, "VFY:  rejecting opcode 0x%02x at 0x%04x\n",
                    decInsn.opcode, insnIdx);
                goto bail;
            }
            /* IMPORTANT: meth->insns may have been changed */
            insns = meth->insns + insnIdx;

            /* continue on as if we just handled a throw-verification-error */
            failure = VERIFY_ERROR_NONE;
            nextFlags = kInstrCanThrow;
        }
    }

    /*
     * If we didn't just set the result register, clear it out.  This
     * ensures that you can only use "move-result" immediately after the
     * result is set.  (We could check this statically, but it's not
     * expensive and it makes our debugging output cleaner.)
     */
    if (!justSetResult) {
        int reg = RESULT_REGISTER(insnRegCount);
        setRegisterType(workLine, reg, kRegTypeUnknown);
        setRegisterType(workLine, reg+1, kRegTypeUnknown);
    }

    /*
     * Handle "continue".  Tag the next consecutive instruction.
     */
    if ((nextFlags & kInstrCanContinue) != 0) {
        int insnWidth = dvmInsnGetWidth(insnFlags, insnIdx);
        if (insnIdx+insnWidth >= insnsSize) {
            LOG_VFY_METH(meth,
                "VFY: execution can walk off end of code area (from 0x%x)\n",
                insnIdx);
            goto bail;
        }

        /*
         * The only way to get to a move-exception instruction is to get
         * thrown there.  Make sure the next instruction isn't one.
         */
        if (!checkMoveException(meth, insnIdx+insnWidth, "next"))
            goto bail;

        if (getRegisterLine(regTable, insnIdx+insnWidth)->regTypes != NULL) {
            /*
             * Merge registers into what we have for the next instruction,
             * and set the "changed" flag if needed.
             */
            if (!updateRegisters(meth, insnFlags, regTable, insnIdx+insnWidth,
                    workLine))
                goto bail;
        } else {
            /*
             * We're not recording register data for the next instruction,
             * so we don't know what the prior state was.  We have to
             * assume that something has changed and re-evaluate it.
             */
            dvmInsnSetChanged(insnFlags, insnIdx+insnWidth, true);
        }
    }

    /*
     * Handle "branch".  Tag the branch target.
     *
     * NOTE: instructions like OP_EQZ provide information about the state
     * of the register when the branch is taken or not taken.  For example,
     * somebody could get a reference field, check it for zero, and if the
     * branch is taken immediately store that register in a boolean field
     * since the value is known to be zero.  We do not currently account for
     * that, and will reject the code.
     *
     * TODO: avoid re-fetching the branch target
     */
    if ((nextFlags & kInstrCanBranch) != 0) {
        bool isConditional;

        if (!dvmGetBranchOffset(meth, insnFlags, insnIdx, &branchTarget,
                &isConditional))
        {
            /* should never happen after static verification */
            LOG_VFY_METH(meth, "VFY: bad branch at %d\n", insnIdx);
            goto bail;
        }
        assert(isConditional || (nextFlags & kInstrCanContinue) == 0);
        assert(!isConditional || (nextFlags & kInstrCanContinue) != 0);

        if (!checkMoveException(meth, insnIdx+branchTarget, "branch"))
            goto bail;

        /* update branch target, set "changed" if appropriate */
        if (!updateRegisters(meth, insnFlags, regTable, insnIdx+branchTarget,
                workLine))
            goto bail;
    }

    /*
     * Handle "switch".  Tag all possible branch targets.
     *
     * We've already verified that the table is structurally sound, so we
     * just need to walk through and tag the targets.
     */
    if ((nextFlags & kInstrCanSwitch) != 0) {
        int offsetToSwitch = insns[1] | (((s4)insns[2]) << 16);
        const u2* switchInsns = insns + offsetToSwitch;
        int switchCount = switchInsns[1];
        int offsetToTargets, targ;

        if ((*insns & 0xff) == OP_PACKED_SWITCH) {
            /* 0=sig, 1=count, 2/3=firstKey */
            offsetToTargets = 4;
        } else {
            /* 0=sig, 1=count, 2..count*2 = keys */
            assert((*insns & 0xff) == OP_SPARSE_SWITCH);
            offsetToTargets = 2 + 2*switchCount;
        }

        /* verify each switch target */
        for (targ = 0; targ < switchCount; targ++) {
            int offset, absOffset;

            /* offsets are 32-bit, and only partly endian-swapped */
            offset = switchInsns[offsetToTargets + targ*2] |
                     (((s4) switchInsns[offsetToTargets + targ*2 +1]) << 16);
            absOffset = insnIdx + offset;

            assert(absOffset >= 0 && absOffset < insnsSize);

            if (!checkMoveException(meth, absOffset, "switch"))
                goto bail;

            if (!updateRegisters(meth, insnFlags, regTable, absOffset,
                    workLine))
                goto bail;
        }
    }

    /*
     * Handle instructions that can throw and that are sitting in a
     * "try" block.  (If they're not in a "try" block when they throw,
     * control transfers out of the method.)
     */
    if ((nextFlags & kInstrCanThrow) != 0 && dvmInsnIsInTry(insnFlags, insnIdx))
    {
        const DexCode* pCode = dvmGetMethodCode(meth);
        DexCatchIterator iterator;
        bool hasCatchAll = false;

        if (dexFindCatchHandler(&iterator, pCode, insnIdx)) {
            for (;;) {
                DexCatchHandler* handler = dexCatchIteratorNext(&iterator);

                if (handler == NULL) {
                    break;
                }

                if (handler->typeIdx == kDexNoIndex)
                    hasCatchAll = true;

                /*
                 * Merge registers into the "catch" block.  We want to
                 * use the "savedRegs" rather than "workRegs", because
                 * at runtime the exception will be thrown before the
                 * instruction modifies any registers.
                 */
                if (!updateRegisters(meth, insnFlags, regTable,
                        handler->address, &regTable->savedLine))
                    goto bail;
            }
        }

        /*
         * If the monitor stack depth is nonzero, there must be a "catch all"
         * handler for this instruction.  This does apply to monitor-exit
         * because of async exception handling.
         */
        if (workLine->monitorStackTop != 0 && !hasCatchAll) {
            /*
             * The state in workLine reflects the post-execution state.
             * If the current instruction is a monitor-enter and the monitor
             * stack was empty, we don't need a catch-all (if it throws,
             * it will do so before grabbing the lock).
             */
            if (!(decInsn.opcode == OP_MONITOR_ENTER &&
                  workLine->monitorStackTop == 1))
            {
                LOG_VFY_METH(meth,
                    "VFY: no catch-all for instruction at 0x%04x\n", insnIdx);
                goto bail;
            }
        }
    }

    /*
     * If we're returning from the method, make sure our monitor stack
     * is empty.
     */
    if ((nextFlags & kInstrCanReturn) != 0 && workLine->monitorStackTop != 0) {
        LOG_VFY_METH(meth, "VFY: return with stack depth=%d at 0x%04x\n",
            workLine->monitorStackTop, insnIdx);
        goto bail;
    }

    /*
     * Update startGuess.  Advance to the next instruction of that's
     * possible, otherwise use the branch target if one was found.  If
     * neither of those exists we're in a return or throw; leave startGuess
     * alone and let the caller sort it out.
     */
    if ((nextFlags & kInstrCanContinue) != 0) {
        *pStartGuess = insnIdx + dvmInsnGetWidth(insnFlags, insnIdx);
    } else if ((nextFlags & kInstrCanBranch) != 0) {
        /* we're still okay if branchTarget is zero */
        *pStartGuess = insnIdx + branchTarget;
    }

    assert(*pStartGuess >= 0 && *pStartGuess < insnsSize &&
        dvmInsnGetWidth(insnFlags, *pStartGuess) != 0);

    result = true;

bail:
    return result;
}


/*
 * callback function used in dumpRegTypes to print local vars
 * valid at a given address.
 */
static void logLocalsCb(void *cnxt, u2 reg, u4 startAddress, u4 endAddress,
        const char *name, const char *descriptor,
        const char *signature)
{
    int addr = *((int *)cnxt);

    if (addr >= (int) startAddress && addr < (int) endAddress)
    {
        LOGI("        %2d: '%s' %s\n", reg, name, descriptor);
    }
}

/*
 * Dump the register types for the specifed address to the log file.
 */
static void dumpRegTypes(const VerifierData* vdata,
    const RegisterLine* registerLine, int addr, const char* addrName,
    const UninitInstanceMap* uninitMap, int displayFlags)
{
    const Method* meth = vdata->method;
    const InsnFlags* insnFlags = vdata->insnFlags;
    const RegType* addrRegs = registerLine->regTypes;
    int regCount = meth->registersSize;
    int fullRegCount = regCount + kExtraRegs;
    bool branchTarget = dvmInsnIsBranchTarget(insnFlags, addr);
    int i;

    assert(addr >= 0 && addr < (int) dvmGetMethodInsnsSize(meth));

    int regCharSize = fullRegCount + (fullRegCount-1)/4 + 2 +1;
    char regChars[regCharSize +1];
    memset(regChars, ' ', regCharSize);
    regChars[0] = '[';
    if (regCount == 0)
        regChars[1] = ']';
    else
        regChars[1 + (regCount-1) + (regCount-1)/4 +1] = ']';
    regChars[regCharSize] = '\0';

    for (i = 0; i < regCount + kExtraRegs; i++) {
        char tch;

        switch (addrRegs[i]) {
        case kRegTypeUnknown:       tch = '.';  break;
        case kRegTypeConflict:      tch = 'X';  break;
        case kRegTypeFloat:         tch = 'F';  break;
        case kRegTypeZero:          tch = '0';  break;
        case kRegTypeOne:           tch = '1';  break;
        case kRegTypeBoolean:       tch = 'Z';  break;
        case kRegTypePosByte:       tch = 'b';  break;
        case kRegTypeByte:          tch = 'B';  break;
        case kRegTypePosShort:      tch = 's';  break;
        case kRegTypeShort:         tch = 'S';  break;
        case kRegTypeChar:          tch = 'C';  break;
        case kRegTypeInteger:       tch = 'I';  break;
        case kRegTypeLongLo:        tch = 'J';  break;
        case kRegTypeLongHi:        tch = 'j';  break;
        case kRegTypeDoubleLo:      tch = 'D';  break;
        case kRegTypeDoubleHi:      tch = 'd';  break;
        default:
            if (regTypeIsReference(addrRegs[i])) {
                if (regTypeIsUninitReference(addrRegs[i]))
                    tch = 'U';
                else
                    tch = 'L';
            } else {
                tch = '*';
                assert(false);
            }
            break;
        }

        if (i < regCount)
            regChars[1 + i + (i/4)] = tch;
        else
            regChars[1 + i + (i/4) + 2] = tch;
    }

    if (addr == 0 && addrName != NULL) {
        LOGI("%c%s %s mst=%d\n", branchTarget ? '>' : ' ',
            addrName, regChars, registerLine->monitorStackTop);
    } else {
        LOGI("%c0x%04x %s mst=%d\n", branchTarget ? '>' : ' ',
            addr, regChars, registerLine->monitorStackTop);
    }
    if (displayFlags & DRT_SHOW_LIVENESS) {
        /*
         * We can't use registerLine->liveRegs because it might be the
         * "work line" rather than the copy from RegisterTable.
         */
        BitVector* liveRegs = vdata->registerLines[addr].liveRegs;
        if (liveRegs != NULL)  {
            char liveChars[regCharSize + 1];
            memset(liveChars, ' ', regCharSize);
            liveChars[regCharSize] = '\0';

            for (i = 0; i < regCount; i++) {
                bool isLive = dvmIsBitSet(liveRegs, i);
                liveChars[i + 1 + (i / 4)] = isLive ? '+' : '-';
            }
            LOGI("        %s\n", liveChars);
        } else {
            LOGI("        %c\n", '#');
        }
    }

    if (displayFlags & DRT_SHOW_REF_TYPES) {
        for (i = 0; i < regCount + kExtraRegs; i++) {
            if (regTypeIsReference(addrRegs[i]) && addrRegs[i] != kRegTypeZero)
            {
                ClassObject* clazz;

                clazz = regTypeReferenceToClass(addrRegs[i], uninitMap);
                assert(dvmValidateObject((Object*)clazz));
                if (i < regCount) {
                    LOGI("        %2d: 0x%08x %s%s\n",
                        i, addrRegs[i],
                        regTypeIsUninitReference(addrRegs[i]) ? "[U]" : "",
                        clazz->descriptor);
                } else {
                    LOGI("        RS: 0x%08x %s%s\n",
                        addrRegs[i],
                        regTypeIsUninitReference(addrRegs[i]) ? "[U]" : "",
                        clazz->descriptor);
                }
            }
        }
    }
    if (displayFlags & DRT_SHOW_LOCALS) {
        dexDecodeDebugInfo(meth->clazz->pDvmDex->pDexFile,
                dvmGetMethodCode(meth),
                meth->clazz->descriptor,
                meth->prototype.protoIdx,
                meth->accessFlags,
                NULL, logLocalsCb, &addr);
    }
}
