Ejemplo n.º 1
0
/*
 * We have a method pointer for a method in "clazz", but it might be
 * pointing to a method in a derived class.  We want to find the actual entry
 * from the class' vtable.  If "clazz" is an interface, we have to do a
 * little more digging.
 *
 * (This is used for reflection and JNI "call method" calls.)
 */
const Method* dvmGetVirtualizedMethod(const ClassObject* clazz,
    const Method* meth)
{
    Method* actualMeth;
    int methodIndex;

    assert(!dvmIsStaticMethod(meth));

    if (dvmIsPrivateMethod(meth))   // no vtable entry for these
        return meth;

    /*
     * If the method was declared in an interface, we need to scan through
     * the class' list of interfaces for it, and find the vtable index
     * from that.
     *
     * TODO: use the interface cache.
     */
    if (dvmIsInterfaceClass(meth->clazz)) {
        int i;

        for (i = 0; i < clazz->iftableCount; i++) {
            if (clazz->iftable[i].clazz == meth->clazz)
                break;
        }
        if (i == clazz->iftableCount) {
            dvmThrowException("Ljava/lang/IncompatibleClassChangeError;",
                "invoking method from interface not implemented by class");
            return NULL;
        }

        methodIndex = clazz->iftable[i].methodIndexArray[meth->methodIndex];
    } else {
        methodIndex = meth->methodIndex;
    }

    assert(methodIndex >= 0 && methodIndex < clazz->vtableCount);
    actualMeth = clazz->vtable[methodIndex];

    /*
     * Make sure there's code to execute.
     */
    if (dvmIsAbstractMethod(actualMeth)) {
        dvmThrowException("Ljava/lang/AbstractMethodError;", NULL);
        return NULL;
    }
    assert(!dvmIsMirandaMethod(actualMeth));

    return actualMeth;
}
Ejemplo n.º 2
0
/* Dalvik puts private, static, and constructors into non-virtual table */
INLINE bool dvmIsDirectMethod(const Method* method) {
    return dvmIsPrivateMethod(method) ||
           dvmIsStaticMethod(method) ||
           dvmIsConstructorMethod(method);
}