/*
 * 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.
 *
 * TODO: we do too much stuff in here that could be done in the static
 * verification pass.  It's convenient, because we have all of the
 * necessary information, but it's more efficient to do it over in
 * DexVerify.c because in here we may have to process instructions
 * multiple times.
 */
#include "Dalvik.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.
 */
#define DEAD_CODE_SCAN  true

static bool gDebugVerbose = false;      // TODO: remove this

#if 0
int gDvm__totalInstr = 0;
int gDvm__gcInstr = 0;
int gDvm__gcData = 0;
int gDvm__gcSimpleData = 0;
#endif

/*
 * Selectively enable verbose debug logging -- use this to activate
 * dumpRegTypes() calls for all instructions in the specified method.
 */
static inline bool doVerboseLogging(const Method* meth) {
    return false;       /* COMMENT OUT to enable verbose debugging */

    const char* cd = "Landroid/net/http/Request;";
    const char* mn = "readResponse";
    const char* sg = "(Landroid/net/http/AndroidHttpClientConnection;)V";
    return (strcmp(meth->clazz->descriptor, cd) == 0 &&
            dvmCompareNameDescriptorAndMethod(mn, sg, meth) == 0);
}

#define SHOW_REG_DETAILS    (0 /*| 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(const Method* meth, InsnFlags* insnFlags,\
    RegisterTable* regTable, UninitInstanceMap* uninitMap);
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 Method* meth, const InsnFlags* insnFlags,\
    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,
};


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

    assert(clazz != NULL);

    /* 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.
 */
ClassObject* dvmGetUninitInstance(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 dvmGetUninitInstance(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 = dvmSetUninitInstance(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 = dvmDescriptorToDot(classDescriptor);
            char* dotMethClass = dvmDescriptorToDot(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;
    }
}

/*
 * 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 = dvmGetUninitInstance(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).
 *
 * TODO: clear mon stack bits
 */
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;
            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));
    }
}

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


/*
 * 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);
    /* TODO: compare mon stack and stack bits */
    return memcmp(line1->regTypes, line2->regTypes,
            regTable->insnRegCountPlus * sizeof(RegType));
}

/*
 * 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);
        /* TODO copy mon stack bits for Ref; will be cleared for 1nr */
    }
}

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

/*
 * 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.
 */
static void 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(meth, insnFlags, targetRegs, 0, "targ", NULL, 0);
            //dumpRegTypes(meth, insnFlags, workRegs, 0, "work", NULL, 0);
        }
        /* merge registers, set Changed only if different */
        RegisterLine* targetLine = getRegisterLine(regTable, nextInsn);
        RegType* targetRegs = targetLine->regTypes;
        bool changed = false;
        unsigned int idx;

        assert(targetRegs != NULL);

        /* TODO: check mon stacks are the same; if different, fail somehow */
        for (idx = 0; idx < insnRegCountPlus; idx++) {
            targetRegs[idx] =
                    mergeTypes(targetRegs[idx], workRegs[idx], &changed);
            /* TODO merge monitorEntries */
        }

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

        if (changed)
            dvmInsnSetChanged(insnFlags, nextInsn, 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;
}

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

    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: also allocate and assign storage for monitor tracking
     */
    regTable->lineAlloc =
        calloc(regTable->insnRegCountPlus * interestingCount, sizeof(RegType));
    if (regTable->lineAlloc == NULL)
        return false;

    /*
     * Populate the sparse register line table.
     */
    RegType* regPtr = 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) {
            regTable->registerLines[i].regTypes = regPtr;
            regPtr += regTable->insnRegCountPlus;
        }
    }

    /*
     * Grab storage for our "temporary" register lines.
     */
    regTable->workLine.regTypes = regPtr;
    regPtr += regTable->insnRegCountPlus;
    regTable->savedLine.regTypes = regPtr;
    regPtr += regTable->insnRegCountPlus;

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

    assert(regPtr - (RegType*)regTable->lineAlloc ==
        (int) (regTable->insnRegCountPlus * interestingCount));
    assert(regTable->registerLines[0].regTypes != NULL);
    return true;
}


/*
 * 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;
    const u2* oldInsns = meth->insns + insnIdx;
    u2 oldInsn = *oldInsns;
    bool result = false;

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

    //LOGD("  was 0x%04x\n", oldInsn);
    u2* newInsns = (u2*) meth->insns + insnIdx;

    /*
     * Generate the new instruction out of the old.
     *
     * First, make sure this is an instruction we're expecting to stomp on.
     */
    switch (oldInsn & 0xff) {
    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",
            oldInsn & 0xff);
        goto bail;
    }

    /* 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, newInsns+2, OP_NOP);
        //newInsns[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));
    //newInsns[0] = newVal;
    dvmDexChangeDex2(meth->clazz->pDvmDex, newInsns, newVal);

    result = true;

bail:
    return result;
}


/*
 * ===========================================================================
 *      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++;
#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(meth, vdata->insnFlags, &regTable,
            generateRegisterMap ? kTrackRegsGcPoints : kTrackRegsBranches))
        goto bail;

    vdata->registerLines = NULL;     /* don't set this until we need it */

    /*
     * 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(meth, vdata->insnFlags, &regTable,
            vdata->uninitMap))
        goto bail;

    /*
     * Generate a register map.
     */
    if (generateRegisterMap) {
        vdata->registerLines = regTable.registerLines;

        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:
    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(const Method* meth, InsnFlags* insnFlags,
    RegisterTable* regTable, UninitInstanceMap* 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 (doVerboseLogging(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(meth, insnFlags, registerLine, 0, "work",
                    uninitMap, DRT_SHOW_REF_TYPES | DRT_SHOW_LOCALS);
                dumpRegTypes(meth, insnFlags, registerLine, 0, "insn",
                    uninitMap, DRT_SHOW_REF_TYPES | DRT_SHOW_LOCALS);
            }
#endif
        }
        if (debugVerbose) {
            dumpRegTypes(meth, insnFlags, &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 InstructionFlags.
     */

    RegisterLine* workLine = &regTable->workLine;
    const DexFile* pDexFile = meth->clazz->pDvmDex->pDexFile;
    ClassObject* resClass;
    int 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 = dexGetInstrFlags(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-32 not expected\n");

            /* check the register contents */
            returnType = getRegisterType(workLine, decInsn.vA);
            checkTypeCategory(returnType, kTypeCategory1nr, &failure);
            if (!VERIFY_OK(failure))
                LOG_VFY("VFY: return-32 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:
    case OP_MONITOR_EXIT:
        tmpType = getRegisterType(workLine, decInsn.vA);
        if (!regTypeIsReference(tmpType)) {
            LOG_VFY("VFY: monitor op on non-object\n");
            failure = VERIFY_ERROR_GENERIC;
        }
        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 = dvmSetUninitInstance(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_UNUSED_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.
             */
            updateRegisters(meth, insnFlags, regTable, insnIdx+insnWidth,
                workLine);
        } 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 (!dvmGetBranchTarget(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 */
        updateRegisters(meth, insnFlags, regTable, insnIdx+branchTarget,
            workLine);
    }

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

            updateRegisters(meth, insnFlags, regTable, absOffset, workLine);
        }
    }

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

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

                if (handler == NULL) {
                    break;
                }

                /* note we use savedLine, not workLine */
                updateRegisters(meth, insnFlags, regTable, handler->address,
                    &regTable->savedLine);
            }
        }
    }

    /*
     * 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 Method* meth, const InsnFlags* insnFlags,
    const RegisterLine* registerLine, int addr, const char* addrName,
    const UninitInstanceMap* uninitMap, int displayFlags)
{
    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\n", branchTarget ? '>' : ' ', addrName, regChars);
    else
        LOGI("%c0x%04x %s\n", branchTarget ? '>' : ' ', addr, regChars);

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