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

/*
 * Implementation of java.lang.reflect.Proxy.
 *
 * Traditionally this is implemented entirely in interpreted code,
 * generating bytecode that defines the proxy class.  Dalvik doesn't
 * currently support this approach, so we generate the class directly.  If
 * we add support for DefineClass with standard classfiles we can
 * eliminate this.
 */
#include "Dalvik.h"

#include <stdlib.h>

// fwd
static bool returnTypesAreCompatible(Method* baseMethod, Method* subMethod);
static bool gatherMethods(ArrayObject* interfaces, Method*** pMethods,\
    ArrayObject** pThrows, int* pMethodCount);
static int copyWithoutDuplicates(Method** allMethods, int allCount,
    Method** outMethods, ArrayObject* throws);
static bool createExceptionClassList(const Method* method,
    PointerSet** pThrows);
static void updateExceptionClassList(const Method* method, PointerSet* throws);
static void createConstructor(ClassObject* clazz, Method* meth);
static void createHandlerMethod(ClassObject* clazz, Method* dstMeth,
    const Method* srcMeth);
static void proxyConstructor(const u4* args, JValue* pResult,
    const Method* method, Thread* self);
static void proxyInvoker(const u4* args, JValue* pResult,
    const Method* method, Thread* self);
static bool mustWrapException(const Method* method, const Object* throwable);

/* private static fields in the Proxy class */
#define kThrowsField    0
#define kProxySFieldCount 1


/*
 * Perform Proxy setup.
 */
bool dvmReflectProxyStartup()
{
    /*
     * Standard methods we must provide in our proxy.
     */
    Method* methE;
    Method* methH;
    Method* methT;
    Method* methF;
    methE = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangObject,
                "equals", "(Ljava/lang/Object;)Z");
    methH = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangObject,
                "hashCode", "()I");
    methT = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangObject,
                "toString", "()Ljava/lang/String;");
    methF = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangObject,
                "finalize", "()V");
    if (methE == NULL || methH == NULL || methT == NULL || methF == NULL) {
        LOGE("Could not find equals/hashCode/toString/finalize in Object\n");
        return false;
    }
    gDvm.voffJavaLangObject_equals = methE->methodIndex;
    gDvm.voffJavaLangObject_hashCode = methH->methodIndex;
    gDvm.voffJavaLangObject_toString = methT->methodIndex;
    gDvm.voffJavaLangObject_finalize = methF->methodIndex;

    /*
     * The prototype signature needs to be cloned from a method in a
     * "real" DEX file.  We declared this otherwise unused method just
     * for this purpose.
     */
    ClassObject* proxyClass;
    Method* meth;
    proxyClass = dvmFindSystemClassNoInit("Ljava/lang/reflect/Proxy;");
    if (proxyClass == NULL) {
        LOGE("No java.lang.reflect.Proxy\n");
        return false;
    }
    meth = dvmFindDirectMethodByDescriptor(proxyClass, "constructorPrototype",
                "(Ljava/lang/reflect/InvocationHandler;)V");
    if (meth == NULL) {
        LOGE("Could not find java.lang.Proxy.constructorPrototype()\n");
        return false;
    }
    gDvm.methJavaLangReflectProxy_constructorPrototype = meth;

    /*
     * Get the offset of the "h" field in Proxy.
     */
    gDvm.offJavaLangReflectProxy_h = dvmFindFieldOffset(proxyClass, "h",
        "Ljava/lang/reflect/InvocationHandler;");
    if (gDvm.offJavaLangReflectProxy_h < 0) {
        LOGE("Unable to find 'h' field in java.lang.Proxy\n");
        return false;
    }

    return true;
}


/*
 * Generate a proxy class with the specified name, interfaces, and loader.
 * "interfaces" is an array of class objects.
 *
 * The Proxy.getProxyClass() code has done the following:
 *  - Verified that "interfaces" contains only interfaces
 *  - Verified that no interface appears twice
 *  - Prepended the package name to the class name if one or more
 *    interfaces are non-public
 *  - Searched for an existing instance of an appropriate Proxy class
 *
 * On failure we leave a partially-created class object sitting around,
 * but the garbage collector will take care of it.
 */
ClassObject* dvmGenerateProxyClass(StringObject* str, ArrayObject* interfaces,
    Object* loader)
{
    int result = -1;
    char* nameStr = NULL;
    Method** methods = NULL;
    ArrayObject* throws = NULL;
    ClassObject* newClass = NULL;
    int i;
    
    nameStr = dvmCreateCstrFromString(str);
    if (nameStr == NULL) {
        dvmThrowException("Ljava/lang/IllegalArgumentException;",
            "missing name");
        goto bail;
    }

    LOGV("+++ Generate proxy class '%s' %p from %d interface classes\n",
        nameStr, loader, interfaces->length);


    /*
     * Characteristics of a Proxy class:
     * - concrete class, public and final
     * - superclass is java.lang.reflect.Proxy
     * - implements all listed interfaces (req'd for instanceof)
     * - has one method for each method in the interfaces (for duplicates,
     *   the method in the earliest interface wins)
     * - has one constructor (takes an InvocationHandler arg)
     * - has overrides for hashCode, equals, and toString (these come first)
     * - has one field, a reference to the InvocationHandler object, inherited
     *   from Proxy
     *
     * TODO: set protection domain so it matches bootstrap classes.
     *
     * The idea here is to create a class object and fill in the details
     * as we would in loadClassFromDex(), and then call dvmLinkClass() to do
     * all the heavy lifting (notably populating the virtual and interface
     * method tables).
     */

    /*
     * Generate a temporary list of virtual methods.
     */
    int methodCount = -1;
    if (!gatherMethods(interfaces, &methods, &throws, &methodCount))
        goto bail;

    /*
     * Allocate storage for the class object and set some basic fields.
     */
    newClass = (ClassObject*) dvmMalloc(sizeof(*newClass) +
                                        kProxySFieldCount * sizeof(StaticField),
                                        ALLOC_DEFAULT);
    if (newClass == NULL)
        goto bail;
    DVM_OBJECT_INIT(&newClass->obj, gDvm.unlinkedJavaLangClass);
    dvmSetClassSerialNumber(newClass);
    newClass->descriptorAlloc = dvmNameToDescriptor(nameStr);
    newClass->descriptor = newClass->descriptorAlloc;
    newClass->accessFlags = ACC_PUBLIC | ACC_FINAL;
    newClass->super = gDvm.classJavaLangReflectProxy;
    newClass->primitiveType = PRIM_NOT;
    newClass->classLoader = loader;
#if WITH_HPROF && WITH_HPROF_STACK
    hprofFillInStackTrace(newClass);
#endif

    /*
     * Add direct method definitions.  We have one (the constructor).
     */
    newClass->directMethodCount = 1;
    newClass->directMethods = (Method*) dvmLinearAlloc(newClass->classLoader,
            1 * sizeof(Method));
    createConstructor(newClass, &newClass->directMethods[0]);
    dvmLinearReadOnly(newClass->classLoader, newClass->directMethods);

    /*
     * Add virtual method definitions.
     */
    newClass->virtualMethodCount = methodCount;
    newClass->virtualMethods = (Method*) dvmLinearAlloc(newClass->classLoader,
            newClass->virtualMethodCount * sizeof(Method));
    for (i = 0; i < newClass->virtualMethodCount; i++) {
        createHandlerMethod(newClass, &newClass->virtualMethods[i],methods[i]);
    }
    dvmLinearReadOnly(newClass->classLoader, newClass->virtualMethods);

    /*
     * Add interface list.
     */
    int interfaceCount = interfaces->length;
    ClassObject** ifArray = (ClassObject**) interfaces->contents;
    newClass->interfaceCount = interfaceCount;
    newClass->interfaces = (ClassObject**)dvmLinearAlloc(newClass->classLoader,
                                sizeof(ClassObject*) * interfaceCount);
    for (i = 0; i < interfaceCount; i++)
        newClass->interfaces[i] = ifArray[i];
    dvmLinearReadOnly(newClass->classLoader, newClass->interfaces);

    /*
     * Static field list.  We have one private field, for our list of
     * exceptions declared for each method.
     */
    assert(kProxySFieldCount == 1);
    newClass->sfieldCount = kProxySFieldCount;
    StaticField* sfield = &newClass->sfields[kThrowsField];
    sfield->field.clazz = newClass;
    sfield->field.name = "throws";
    sfield->field.signature = "[[Ljava/lang/Throwable;";
    sfield->field.accessFlags = ACC_STATIC | ACC_PRIVATE;
    dvmSetStaticFieldObject(sfield, (Object*)throws);

    /*
     * Everything is ready.  See if the linker will lap it up.
     */
    newClass->status = CLASS_LOADED;
    if (!dvmLinkClass(newClass, true)) {
        LOGD("Proxy class link failed\n");
        goto bail;
    }

    /*
     * All good.  Add it to the hash table.  We should NOT see a collision
     * here; if we do, it means the caller has screwed up and provided us
     * with a duplicate name.
     */
    if (!dvmAddClassToHash(newClass)) {
        LOGE("ERROR: attempted to generate %s more than once\n",
            newClass->descriptor);
        goto bail;
    }

    result = 0;

bail:
    free(nameStr);
    free(methods);
    if (result != 0) {
        /* must free innards explicitly if we didn't finish linking */
        dvmFreeClassInnards(newClass);
        newClass = NULL;
        if (!dvmCheckException(dvmThreadSelf())) {
            /* throw something */
            dvmThrowException("Ljava/lang/RuntimeException;", NULL);
        }
    }

    /* allow the GC to free these when nothing else has a reference */
    dvmReleaseTrackedAlloc((Object*) throws, NULL);
    dvmReleaseTrackedAlloc((Object*) newClass, NULL);

    return newClass;
}


/*
 * Generate a list of methods.  The Method pointers returned point to the
 * abstract method definition from the appropriate interface, or to the
 * virtual method definition in java.lang.Object.
 *
 * We also allocate an array of arrays of throwable classes, one for each
 * method,so we can do some special handling of checked exceptions.  The
 * caller must call ReleaseTrackedAlloc() on *pThrows.
 */
static bool gatherMethods(ArrayObject* interfaces, Method*** pMethods,
    ArrayObject** pThrows, int* pMethodCount)
{
    ClassObject** classes;
    ArrayObject* throws = NULL;
    Method** methods = NULL;
    Method** allMethods = NULL;
    int numInterfaces, maxCount, actualCount, allCount;
    bool result = false;
    int i;

    /*
     * Get a maximum count so we can allocate storage.  We need the
     * methods declared by each interface and all of its superinterfaces.
     */
    maxCount = 3;       // 3 methods in java.lang.Object
    numInterfaces = interfaces->length;
    classes = (ClassObject**) interfaces->contents;

    for (i = 0; i < numInterfaces; i++, classes++) {
        ClassObject* clazz = *classes;

        LOGVV("---  %s virtualMethodCount=%d\n",
            clazz->descriptor, clazz->virtualMethodCount);
        maxCount += clazz->virtualMethodCount;

        int j;
        for (j = 0; j < clazz->iftableCount; j++) {
            ClassObject* iclass = clazz->iftable[j].clazz;

            LOGVV("---  +%s %d\n",
                iclass->descriptor, iclass->virtualMethodCount);
            maxCount += iclass->virtualMethodCount;
        }
    }

    methods = (Method**) malloc(maxCount * sizeof(*methods));
    allMethods = (Method**) malloc(maxCount * sizeof(*methods));
    if (methods == NULL || allMethods == NULL)
        goto bail;

    /*
     * First three entries are the java.lang.Object methods.
     */
    ClassObject* obj = gDvm.classJavaLangObject;
    allMethods[0] = obj->vtable[gDvm.voffJavaLangObject_equals];
    allMethods[1] = obj->vtable[gDvm.voffJavaLangObject_hashCode];
    allMethods[2] = obj->vtable[gDvm.voffJavaLangObject_toString];
    allCount = 3;

    /*
     * Add the methods from each interface, in order.
     */
    classes = (ClassObject**) interfaces->contents;
    for (i = 0; i < numInterfaces; i++, classes++) {
        ClassObject* clazz = *classes;
        int j;

        for (j = 0; j < clazz->virtualMethodCount; j++) {
            allMethods[allCount++] = &clazz->virtualMethods[j];
        }

        for (j = 0; j < clazz->iftableCount; j++) {
            ClassObject* iclass = clazz->iftable[j].clazz;
            int k;

            for (k = 0; k < iclass->virtualMethodCount; k++) {
                allMethods[allCount++] = &iclass->virtualMethods[k];
            }
        }
    }
    assert(allCount == maxCount);

    /*
     * Allocate some storage to hold the lists of throwables.  We need
     * one entry per unique method, but it's convenient to allocate it
     * ahead of the duplicate processing.
     */
    ClassObject* arrArrClass;
    arrArrClass = dvmFindArrayClass("[[Ljava/lang/Throwable;", NULL);
    if (arrArrClass == NULL)
        goto bail;
    throws = dvmAllocArrayByClass(arrArrClass, allCount, ALLOC_DEFAULT);

    /*
     * Identify and remove duplicates.
     */
    actualCount = copyWithoutDuplicates(allMethods, allCount, methods, throws);
    if (actualCount < 0)
        goto bail;

    //LOGI("gathered methods:\n");
    //for (i = 0; i < actualCount; i++) {
    //    LOGI(" %d: %s.%s\n",
    //        i, methods[i]->clazz->descriptor, methods[i]->name);
    //}

    *pMethods = methods;
    *pMethodCount = actualCount;
    *pThrows = throws;
    result = true;

bail:
    free(allMethods);
    if (!result) {
        free(methods);
        dvmReleaseTrackedAlloc((Object*)throws, NULL);
    }
    return result;
}

/*
 * Identify and remove duplicates, where "duplicate" means it has the
 * same name and arguments, but not necessarily the same return type.
 *
 * If duplicate methods have different return types, we want to use the
 * first method whose return type is assignable from all other duplicate
 * methods.  That is, if we have:
 *   class base {...}
 *   class sub extends base {...}
 *   class subsub extends sub {...}
 * Then we want to return the method that returns subsub, since callers
 * to any form of the method will get a usable object back.
 *
 * All other duplicate methods are stripped out.
 *
 * This also populates the "throwLists" array with arrays of Class objects,
 * one entry per method in "outMethods".  Methods that don't declare any
 * throwables (or have no common throwables with duplicate methods) will
 * have NULL entries.
 *
 * Returns the number of methods copied into "methods", or -1 on failure.
 */
static int copyWithoutDuplicates(Method** allMethods, int allCount,
    Method** outMethods, ArrayObject* throwLists)
{
    Method* best;
    int outCount = 0;
    int i, j;

    /*
     * The plan is to run through all methods, checking all other methods
     * for a duplicate.  If we find a match, we see if the other methods'
     * return type is compatible/assignable with ours.  If the current
     * method is assignable from all others, we copy it to the new list,
     * and NULL out all other entries.  If not, we keep looking for a
     * better version.
     *
     * If there are no duplicates, we copy the method and NULL the entry.
     *
     * At the end of processing, if we have any non-NULL entries, then we
     * have bad duplicates and must exit with an exception.
     */
    for (i = 0; i < allCount; i++) {
        bool best, dupe;

        if (allMethods[i] == NULL)
            continue;

        /*
         * Find all duplicates.  If any of the return types is not
         * assignable to our return type, then we're not the best.
         *
         * We start from 0, not i, because we need to compare assignability
         * the other direction even if we've compared these before.
         */
        dupe = false;
        best = true;
        for (j = 0; j < allCount; j++) {
            if (i == j)
                continue;
            if (allMethods[j] == NULL)
                continue;

            if (dvmCompareMethodNamesAndParameterProtos(allMethods[i],
                    allMethods[j]) == 0)
            {
                /*
                 * Duplicate method, check return type.  If it's a primitive
                 * type or void, the types must match exactly, or we throw
                 * an exception now.
                 */
                LOGV("MATCH on %s.%s and %s.%s\n",
                    allMethods[i]->clazz->descriptor, allMethods[i]->name,
                    allMethods[j]->clazz->descriptor, allMethods[j]->name);
                dupe = true;
                if (!returnTypesAreCompatible(allMethods[i], allMethods[j]))
                    best = false;
            }
        }

        /*
         * If this is the best of a set of duplicates, copy it over and
         * nuke all duplicates.
         *
         * While we do this, we create the set of exceptions declared to
         * be thrown by all occurrences of the method.
         */
        if (dupe) {
            if (best) {
                LOGV("BEST %d %s.%s -> %d\n", i,
                    allMethods[i]->clazz->descriptor, allMethods[i]->name,
                    outCount);

                /* if we have exceptions, make a local copy */
                PointerSet* commonThrows = NULL;
                if (!createExceptionClassList(allMethods[i], &commonThrows))
                    return -1;

                /*
                 * Run through one more time, erasing the duplicates.  (This
                 * would go faster if we had marked them somehow.)
                 */
                for (j = 0; j < allCount; j++) {
                    if (i == j)
                        continue;
                    if (allMethods[j] == NULL)
                        continue;
                    if (dvmCompareMethodNamesAndParameterProtos(allMethods[i],
                            allMethods[j]) == 0)
                    {
                        LOGV("DEL %d %s.%s\n", j,
                            allMethods[j]->clazz->descriptor,
                            allMethods[j]->name);

                        /*
                         * Update set to hold the intersection of method[i]'s
                         * and method[j]'s throws.
                         */
                        if (commonThrows != NULL) {
                            updateExceptionClassList(allMethods[j],
                                commonThrows);
                        }

                        allMethods[j] = NULL;
                    }
                }

                /*
                 * If the set of Throwable classes isn't empty, create an
                 * array of Class, copy them into it, and put the result
                 * into the "throwLists" array.
                 */
                if (commonThrows != NULL &&
                    dvmPointerSetGetCount(commonThrows) > 0)
                {
                    int commonCount = dvmPointerSetGetCount(commonThrows);
                    ArrayObject* throwArray;
                    Object** contents;
                    int ent;

                    throwArray = dvmAllocArrayByClass(
                            gDvm.classJavaLangClassArray, commonCount,
                            ALLOC_DEFAULT);
                    if (throwArray == NULL) {
                        LOGE("common-throw array alloc failed\n");
                        return -1;
                    }

                    contents = (Object**) throwArray->contents;
                    for (ent = 0; ent < commonCount; ent++) {
                        contents[ent] = (Object*)
                            dvmPointerSetGetEntry(commonThrows, ent);
                    }

                    /* add it to the array of arrays */
                    contents = (Object**) throwLists->contents;
                    contents[outCount] = (Object*) throwArray;
                    dvmReleaseTrackedAlloc((Object*) throwArray, NULL);
                }

                /* copy the winner and NULL it out */
                outMethods[outCount++] = allMethods[i];
                allMethods[i] = NULL;

                dvmPointerSetFree(commonThrows);
            } else {
                LOGV("BEST not %d\n", i);
            }
        } else {
            /*
             * Singleton.  Copy the entry and NULL it out.
             */
            LOGV("COPY singleton %d %s.%s -> %d\n", i,
                allMethods[i]->clazz->descriptor, allMethods[i]->name,
                outCount);

            /* keep track of our throwables */
            ArrayObject* exceptionArray = dvmGetMethodThrows(allMethods[i]);
            if (exceptionArray != NULL) {
                Object** contents;

                contents = (Object**) throwLists->contents;
                contents[outCount] = (Object*) exceptionArray;
                dvmReleaseTrackedAlloc((Object*) exceptionArray, NULL);
            }

            outMethods[outCount++] = allMethods[i];
            allMethods[i] = NULL;
        }
    }

    /*
     * Check for stragglers.  If we find any, throw an exception.
     */
    for (i = 0; i < allCount; i++) {
        if (allMethods[i] != NULL) {
            LOGV("BAD DUPE: %d %s.%s\n", i,
                allMethods[i]->clazz->descriptor, allMethods[i]->name);
            dvmThrowException("Ljava/lang/IllegalArgumentException;",
                "incompatible return types in proxied interfaces");
            return -1;
        }
    }

    return outCount;
}


/*
 * Classes can declare to throw multiple exceptions in a hierarchy, e.g.
 * IOException and FileNotFoundException.  Since we're only interested in
 * knowing the set that can be thrown without requiring an extra wrapper,
 * we can remove anything that is a subclass of something else in the list.
 *
 * The "mix" step we do next reduces things toward the most-derived class,
 * so it's important that we start with the least-derived classes.
 */
static void reduceExceptionClassList(ArrayObject* exceptionArray)
{
    const ClassObject** classes = (const ClassObject**)exceptionArray->contents;
    int len = exceptionArray->length;
    int i, j;

    /*
     * Consider all pairs of classes.  If one is the subclass of the other,
     * null out the subclass.
     */
    for (i = 0; i < len-1; i++) {
        if (classes[i] == NULL)
            continue;
        for (j = i + 1; j < len; j++) {
            if (classes[j] == NULL)
                continue;

            if (dvmInstanceof(classes[i], classes[j])) {
                classes[i] = NULL;
                break;      /* no more comparisons against classes[i] */
            } else if (dvmInstanceof(classes[j], classes[i])) {
                classes[j] = NULL;
            }
        }
    }
}

/*
 * Create a local array with a copy of the throwable classes declared by
 * "method".  If no throws are declared, "*pSet" will be NULL.
 *
 * Returns "false" on allocation failure.
 */
static bool createExceptionClassList(const Method* method, PointerSet** pThrows)
{
    ArrayObject* exceptionArray = NULL;
    bool result = false;

    exceptionArray = dvmGetMethodThrows(method);
    if (exceptionArray != NULL && exceptionArray->length > 0) {
        /* reduce list, nulling out redundant entries */
        reduceExceptionClassList(exceptionArray);

        *pThrows = dvmPointerSetAlloc(exceptionArray->length);
        if (*pThrows == NULL)
            goto bail;

        const ClassObject** contents;
        int i;

        contents = (const ClassObject**) exceptionArray->contents;
        for (i = 0; i < (int) exceptionArray->length; i++) {
            if (contents[i] != NULL)
                dvmPointerSetAddEntry(*pThrows, contents[i]);
        }
    } else {
        *pThrows = NULL;
    }

    result = true;

bail:
    dvmReleaseTrackedAlloc((Object*) exceptionArray, NULL);
    return result;
}

/*
 * We need to compute the intersection of the arguments, i.e. remove
 * anything from "throws" that isn't in the method's list of throws.
 *
 * If one class is a subclass of another, we want to keep just the subclass,
 * moving toward the most-restrictive set.
 *
 * We assume these are all classes, and don't try to filter out interfaces.
 */
static void updateExceptionClassList(const Method* method, PointerSet* throws)
{
    int setSize = dvmPointerSetGetCount(throws);
    if (setSize == 0)
        return;

    ArrayObject* exceptionArray = dvmGetMethodThrows(method);
    if (exceptionArray == NULL) {
        /* nothing declared, so intersection is empty */
        dvmPointerSetClear(throws);
        return;
    }

    /* reduce list, nulling out redundant entries */
    reduceExceptionClassList(exceptionArray);

    int mixLen = dvmPointerSetGetCount(throws);
    const ClassObject* mixSet[mixLen];

    int declLen = exceptionArray->length;
    const ClassObject** declSet = (const ClassObject**)exceptionArray->contents;

    int i, j;

    /* grab a local copy to work on */
    for (i = 0; i < mixLen; i++) {
        mixSet[i] = dvmPointerSetGetEntry(throws, i);
    }

    for (i = 0; i < mixLen; i++) {
        for (j = 0; j < declLen; j++) {
            if (declSet[j] == NULL)
                continue;

            if (mixSet[i] == declSet[j]) {
                /* match, keep this one */
                break;
            } else if (dvmInstanceof(mixSet[i], declSet[j])) {
                /* mix is a subclass of a declared throwable, keep it */
                break;
            } else if (dvmInstanceof(declSet[j], mixSet[i])) {
                /* mix is a superclass, replace it */
                mixSet[i] = declSet[j];
                break;
            }
        }

        if (j == declLen) {
            /* no match, remove entry by nulling it out */
            mixSet[i] = NULL;
        }
    }

    /* copy results back out; this eliminates duplicates as we go */
    dvmPointerSetClear(throws);
    for (i = 0; i < mixLen; i++) {
        if (mixSet[i] != NULL)
            dvmPointerSetAddEntry(throws, mixSet[i]);
    }

    dvmReleaseTrackedAlloc((Object*) exceptionArray, NULL);
}


/*
 * Check to see if the return types are compatible.
 *
 * If the return type is primitive or void, it must match exactly.
 *
 * If not, the type in "subMethod" must be assignable to the type in
 * "baseMethod".
 */
static bool returnTypesAreCompatible(Method* subMethod, Method* baseMethod)
{
    const char* baseSig = dexProtoGetReturnType(&baseMethod->prototype);
    const char* subSig = dexProtoGetReturnType(&subMethod->prototype);
    ClassObject* baseClass;
    ClassObject* subClass;

    if (baseSig[1] == '\0' || subSig[1] == '\0') {
        /* at least one is primitive type */
        return (baseSig[0] == subSig[0] && baseSig[1] == subSig[1]);
    }

    baseClass = dvmFindClass(baseSig, baseMethod->clazz->classLoader);
    subClass = dvmFindClass(subSig, subMethod->clazz->classLoader);
    bool result = dvmInstanceof(subClass, baseClass);
    return result;
}

/*
 * Create a constructor for our Proxy class.  The constructor takes one
 * argument, a java.lang.reflect.InvocationHandler.
 */
static void createConstructor(ClassObject* clazz, Method* meth)
{
    meth->clazz = clazz;
    meth->accessFlags = ACC_PUBLIC | ACC_NATIVE;
    meth->name = "<init>";
    meth->prototype =
        gDvm.methJavaLangReflectProxy_constructorPrototype->prototype;
    meth->shorty = 
        gDvm.methJavaLangReflectProxy_constructorPrototype->shorty;
    // no pDexCode or pDexMethod

    int argsSize = dvmComputeMethodArgsSize(meth) + 1;
    meth->registersSize = meth->insSize = argsSize;

    meth->nativeFunc = proxyConstructor;
}

/*
 * Create a method in our Proxy class with the name and signature of
 * the interface method it implements.
 */
static void createHandlerMethod(ClassObject* clazz, Method* dstMeth,
    const Method* srcMeth)
{
    dstMeth->clazz = clazz;
    dstMeth->insns = (u2*) srcMeth;
    dstMeth->accessFlags = ACC_PUBLIC | ACC_NATIVE;
    dstMeth->name = srcMeth->name;
    dstMeth->prototype = srcMeth->prototype;
    dstMeth->shorty = srcMeth->shorty;
    // no pDexCode or pDexMethod

    int argsSize = dvmComputeMethodArgsSize(dstMeth) + 1;
    dstMeth->registersSize = dstMeth->insSize = argsSize;

    dstMeth->nativeFunc = proxyInvoker;
}

/*
 * Return a new Object[] array with the contents of "args".  We determine
 * the number and types of values in "args" based on the method signature.
 * Primitive types are boxed.
 *
 * Returns NULL if the method takes no arguments.
 *
 * The caller must call dvmReleaseTrackedAlloc() on the return value.
 *
 * On failure, returns with an appropriate exception raised.
 */
static ArrayObject* boxMethodArgs(const Method* method, const u4* args)
{
    const char* desc = &method->shorty[1]; // [0] is the return type.
    ArrayObject* argArray = NULL;
    int argCount;
    Object** argObjects;
    bool failed = true;

    /* count args */
    argCount = dexProtoGetParameterCount(&method->prototype);

    /* allocate storage */
    argArray = dvmAllocArray(gDvm.classJavaLangObjectArray, argCount,
        kObjectArrayRefWidth, ALLOC_DEFAULT);
    if (argArray == NULL)
        goto bail;
    argObjects = (Object**) argArray->contents;

    /*
     * Fill in the array.
     */

    int srcIndex = 0;
    
    argCount = 0;
    while (*desc != '\0') {
        char descChar = *(desc++);
        JValue value;

        switch (descChar) {
        case 'Z':
        case 'C':
        case 'F':
        case 'B':
        case 'S':
        case 'I':
            value.i = args[srcIndex++];
            argObjects[argCount] = (Object*) dvmWrapPrimitive(value,
                dvmFindPrimitiveClass(descChar));
            /* argObjects is tracked, don't need to hold this too */
            dvmReleaseTrackedAlloc(argObjects[argCount], NULL);
            argCount++;
            break;
        case 'D':
        case 'J':
            value.j = dvmGetArgLong(args, srcIndex);
            srcIndex += 2;
            argObjects[argCount] = (Object*) dvmWrapPrimitive(value,
                dvmFindPrimitiveClass(descChar));
            dvmReleaseTrackedAlloc(argObjects[argCount], NULL);
            argCount++;
            break;
        case '[':
        case 'L':
            argObjects[argCount++] = (Object*) args[srcIndex++];
            break;
        }
    }

    failed = false;

bail:
    if (failed) {
        dvmReleaseTrackedAlloc((Object*)argArray, NULL);
        argArray = NULL;
    }
    return argArray;
}

/*
 * This is the constructor for a generated proxy object.  All we need to
 * do is stuff "handler" into "h".
 */
static void proxyConstructor(const u4* args, JValue* pResult,
    const Method* method, Thread* self)
{
    Object* obj = (Object*) args[0];
    Object* handler = (Object*) args[1];

    dvmSetFieldObject(obj, gDvm.offJavaLangReflectProxy_h, handler);
}

/*
 * This is the common message body for proxy methods.
 *
 * The method we're calling looks like:
 *   public Object invoke(Object proxy, Method method, Object[] args)
 *
 * This means we have to create a Method object, box our arguments into
 * a new Object[] array, make the call, and unbox the return value if
 * necessary.
 */
static void proxyInvoker(const u4* args, JValue* pResult,
    const Method* method, Thread* self)
{
    Object* thisObj = (Object*) args[0];
    Object* methodObj = NULL;
    ArrayObject* argArray = NULL;
    Object* handler;
    Method* invoke;
    ClassObject* returnType;
    int hOffset;
    JValue invokeResult;

    /*
     * Retrieve handler object for this proxy instance.  The field is
     * defined in the superclass (Proxy).
     */
    handler = dvmGetFieldObject(thisObj, gDvm.offJavaLangReflectProxy_h);

    /*
     * Find the invoke() method, looking in "this"s class.  (Because we
     * start here we don't have to convert it to a vtable index and then
     * index into this' vtable.)
     */
    invoke = dvmFindVirtualMethodHierByDescriptor(handler->clazz, "invoke",
            "(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;");
    if (invoke == NULL) {
        LOGE("Unable to find invoke()\n");
        dvmAbort();
    }

    LOGV("invoke: %s.%s, this=%p, handler=%s\n",
        method->clazz->descriptor, method->name,
        thisObj, handler->clazz->descriptor);

    /*
     * Create a java.lang.reflect.Method object for this method.
     *
     * We don't want to use "method", because that's the concrete
     * implementation in the proxy class.  We want the abstract Method
     * from the declaring interface.  We have a pointer to it tucked
     * away in the "insns" field.
     *
     * TODO: this could be cached for performance.
     */
    methodObj = dvmCreateReflectMethodObject((Method*) method->insns);
    if (methodObj == NULL) {
        assert(dvmCheckException(self));
        goto bail;
    }

    /*
     * Determine the return type from the signature.
     *
     * TODO: this could be cached for performance.
     */
    returnType = dvmGetBoxedReturnType(method);
    if (returnType == NULL) {
        char* desc = dexProtoCopyMethodDescriptor(&method->prototype);
        LOGE("Could not determine return type for '%s'\n", desc);
        free(desc);
        assert(dvmCheckException(self));
        goto bail;
    }
    LOGV("  return type will be %s\n", returnType->descriptor);

    /*
     * Convert "args" array into Object[] array, using the method
     * signature to determine types.  If the method takes no arguments,
     * we must pass null.
     */
    argArray = boxMethodArgs(method, args+1);
    if (dvmCheckException(self))
        goto bail;

    /*
     * Call h.invoke(proxy, method, args).
     *
     * We don't need to repackage exceptions, so if one has been thrown
     * just jump to the end.
     */
    dvmCallMethod(self, invoke, handler, &invokeResult,
        thisObj, methodObj, argArray);
    if (dvmCheckException(self)) {
        Object* excep = dvmGetException(self);
        if (mustWrapException(method, excep)) {
            /* wrap with UndeclaredThrowableException */
            dvmWrapException("Ljava/lang/reflect/UndeclaredThrowableException;");
        }
        goto bail;
    }

    /*
     * Unbox the return value.  If it's the wrong type, throw a
     * ClassCastException.  If it's a null pointer and we need a
     * primitive type, throw a NullPointerException.
     */
    if (returnType->primitiveType == PRIM_VOID) {
        LOGVV("+++ ignoring return to void\n");
    } else if (invokeResult.l == NULL) {
        if (dvmIsPrimitiveClass(returnType)) {
            dvmThrowException("Ljava/lang/NullPointerException;",
                "null result when primitive expected");
            goto bail;
        }
        pResult->l = NULL;
    } else {
        if (!dvmUnwrapPrimitive(invokeResult.l, returnType, pResult)) {
            dvmThrowExceptionWithClassMessage("Ljava/lang/ClassCastException;",
                ((Object*)invokeResult.l)->clazz->descriptor);
            goto bail;
        }
    }

bail:
    dvmReleaseTrackedAlloc(methodObj, self);
    dvmReleaseTrackedAlloc((Object*)argArray, self);
}

/*
 * Determine if it's okay for this method to throw this exception.  If
 * an unchecked exception was thrown we immediately return false.  If
 * checked, we have to ensure that this method and all of its duplicates
 * have declared that they throw it.
 */
static bool mustWrapException(const Method* method, const Object* throwable)
{
    const ArrayObject* throws;
    const ArrayObject* methodThrows;
    const Object** contents;
    const ClassObject** classes;

    if (!dvmIsCheckedException(throwable))
        return false;

    const StaticField* sfield = &method->clazz->sfields[kThrowsField];
    throws = (ArrayObject*) dvmGetStaticFieldObject(sfield);

    int methodIndex = method - method->clazz->virtualMethods;
    assert(methodIndex >= 0 && methodIndex < method->clazz->virtualMethodCount);

    contents = (const Object**) throws->contents;
    methodThrows = (ArrayObject*) contents[methodIndex];

    if (methodThrows == NULL) {
        /* no throws declared, must wrap all checked exceptions */
        //printf("+++ methodThrows[%d] is null, wrapping all\n", methodIndex);
        return true;
    }

    int throwCount = methodThrows->length;
    classes = (const ClassObject**) methodThrows->contents;
    int i;

    //printf("%s.%s list:\n", method->clazz->descriptor, method->name);
    //for (i = 0; i < throwCount; i++)
    //    printf(" %d: %s\n", i, classes[i]->descriptor);

    for (i = 0; i < throwCount; i++) {
        if (dvmInstanceof(throwable->clazz, classes[i])) {
            /* this was declared, okay to throw */
            return false;
        }
    }

    /* no match in declared throws */
    return true;
}
