/* * 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; }
/* Dalvik puts private, static, and constructors into non-virtual table */ INLINE bool dvmIsDirectMethod(const Method* method) { return dvmIsPrivateMethod(method) || dvmIsStaticMethod(method) || dvmIsConstructorMethod(method); }