Finish cleanup of class/field/method caching.
Change-Id: I289ae724cbd98487429275837d23b7b2d7096156
diff --git a/src/jni_internal.cc b/src/jni_internal.cc
index 03d668c..87d5449 100644
--- a/src/jni_internal.cc
+++ b/src/jni_internal.cc
@@ -522,6 +522,47 @@
}
}
+int ThrowNewException(JNIEnv* env, jclass exception_class, const char* msg, jobject cause) {
+ ScopedJniThreadState ts(env);
+
+ // Turn the const char* into a java.lang.String.
+ ScopedLocalRef<jstring> s(env, env->NewStringUTF(msg));
+ if (msg != NULL && s.get() == NULL) {
+ return JNI_ERR;
+ }
+
+ // Choose an appropriate constructor and set up the arguments.
+ jvalue args[2];
+ const char* signature;
+ if (msg == NULL && cause == NULL) {
+ signature = "()V";
+ } else if (msg != NULL && cause == NULL) {
+ signature = "(Ljava/lang/String;)V";
+ args[0].l = s.get();
+ } else if (msg == NULL && cause != NULL) {
+ signature = "(Ljava/lang/Throwable;)V";
+ args[0].l = cause;
+ } else {
+ signature = "(Ljava/lang/String;Ljava/lang/Throwable;)V";
+ args[0].l = s.get();
+ args[1].l = cause;
+ }
+ jmethodID mid = env->GetMethodID(exception_class, "<init>", signature);
+ if (mid == NULL) {
+ LOG(ERROR) << "No <init>" << signature << " in " << PrettyClass(Decode<Class*>(env, exception_class));
+ return JNI_ERR;
+ }
+
+ ScopedLocalRef<jthrowable> exception(env, reinterpret_cast<jthrowable>(env->NewObjectA(exception_class, mid, args)));
+ if (exception.get() == NULL) {
+ return JNI_ERR;
+ }
+
+ ts.Self()->SetException(Decode<Throwable*>(ts, exception.get()));
+
+ return JNI_OK;
+}
+
static jint JII_AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* raw_args, bool as_daemon) {
if (vm == NULL || p_env == NULL) {
return JNI_ERR;
@@ -821,29 +862,7 @@
}
static jint ThrowNew(JNIEnv* env, jclass c, const char* msg) {
- ScopedJniThreadState ts(env);
- // TODO: check for a pending exception to decide what constructor to call.
- jmethodID mid = ((msg != NULL)
- ? env->GetMethodID(c, "<init>", "(Ljava/lang/String;)V")
- : env->GetMethodID(c, "<init>", "()V"));
- if (mid == NULL) {
- return JNI_ERR;
- }
- ScopedLocalRef<jstring> s(env, env->NewStringUTF(msg));
- if (msg != NULL && s.get() == NULL) {
- return JNI_ERR;
- }
-
- jvalue args[1];
- args[0].l = s.get();
- ScopedLocalRef<jthrowable> exception(env, reinterpret_cast<jthrowable>(env->NewObjectA(c, mid, args)));
- if (exception.get() == NULL) {
- return JNI_ERR;
- }
-
- ts.Self()->SetException(Decode<Throwable*>(ts, exception.get()));
-
- return JNI_OK;
+ return ThrowNewException(env, c, msg, NULL);
}
static jboolean ExceptionCheck(JNIEnv* env) {