static void* lookupVirtualMethod(Env* env, Object* thiz, char* name, char* desc) { Method* method = rvmGetMethod(env, thiz->clazz, name, desc); if (!method) return NULL; if (METHOD_IS_ABSTRACT(method)) { rvmThrowAbstractMethodError(env, ""); // TODO: Message return NULL; } return method->synchronizedImpl ? method->synchronizedImpl : method->impl; }
Method* rvmGetInstanceMethod(Env* env, Class* clazz, const char* name, const char* desc) { Method* method = rvmGetMethod(env, clazz, name, desc); if (!method) return NULL; if (METHOD_IS_STATIC(method)) { // TODO: JNI spec doesn't say anything about throwing this rvmThrowIncompatibleClassChangeErrorMethod(env, clazz, name, desc); return NULL; } return method; }
void* _bcResolveNative(Env* env, Class* clazz, char* name, char* desc, char* shortMangledName, char* longMangledName, void** ptr) { if (*ptr != NULL) return *ptr; TRACEF("_bcResolveNative: owner=%s, name=%s, desc=%s, shortMangledName=%s, longMangledName=%s", clazz->name, name, desc, shortMangledName, longMangledName); NativeMethod* method = (NativeMethod*) rvmGetMethod(env, clazz, name, desc); void* impl = NULL; if (method) { impl = rvmResolveNativeMethodImpl(env, method, shortMangledName, longMangledName, clazz->classLoader, ptr); } return impl; }
static jboolean getEnclosingMethodIterator(Env* env, char* className, char* methodName, char* methodDesc, void* data) { Method** result = (Method**) ((void**) data)[0]; Class* clazz = (Class*) ((void**) data)[1]; if (methodName && methodDesc) { Class* c = rvmFindClassUsingLoader(env, className, clazz->classLoader); if (c) { *result = rvmGetMethod(env, c, methodName, methodDesc); } return FALSE; // Stop iterating } return TRUE; // Continue with next attribute }
void throwInvocationTargetException(Env* env, Object* throwable) { rvmExceptionClear(env); if (!java_lang_reflect_InvocationTargetException) { java_lang_reflect_InvocationTargetException = rvmFindClassUsingLoader(env, "java/lang/reflect/InvocationTargetException", NULL); if (!java_lang_reflect_InvocationTargetException) return; } if (!java_lang_reflect_InvocationTargetException_init) { java_lang_reflect_InvocationTargetException_init = rvmGetMethod(env, java_lang_reflect_InvocationTargetException, "<init>", "(Ljava/lang/Throwable;)V"); if (!java_lang_reflect_InvocationTargetException_init) return; } jvalue initArgs[1]; initArgs[0].l = (jobject) throwable; Object* exception = rvmNewObjectA(env, java_lang_reflect_InvocationTargetException, java_lang_reflect_InvocationTargetException_init, initArgs); if (!exception) return; rvmThrow(env, exception); }
static jint RegisterNatives(JNIEnv* env, jclass clazz, const JNINativeMethod* methods, jint nMethods) { NativeMethod* nativeMethods[nMethods]; jint i; for (i = 0; i < nMethods; i++) { nativeMethods[i] = (NativeMethod*) rvmGetMethod((Env*) env, (Class*) clazz, methods[i].name, methods[i].signature); if (nativeMethods[i] == NULL || !METHOD_IS_NATIVE(&nativeMethods[i]->method)) { rvmThrowNoSuchMethodError((Env*) env, methods[i].name); return JNI_ERR; } } for (i = 0; i < nMethods; i++) { if (!rvmRegisterNative((Env*) env, nativeMethods[i], methods[i].fnPtr)) { return JNI_ERR; } } return 0; }