Add "class Throwable" and rewrite exception throwing to use JNI.
Change-Id: I79836075337eedfc5923ebff028176615ffd3598
diff --git a/src/thread.cc b/src/thread.cc
index db4c59f..30012b9 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -174,38 +174,24 @@
return false;
}
-void Thread::ThrowNewException(Class* exception_class, const char* msg) {
- Object* exception = exception_class->NewInstance();
- CHECK(exception != NULL);
-
- String* java_msg = String::AllocFromModifiedUtf8(msg);
- CHECK(java_msg != NULL);
-
- // TODO: what if there's already a pending exception?
- // TODO: support the other constructors.
- Method* ctor = exception_class->FindDirectMethod("<init>", "(Ljava/lang/String;)V");
- CHECK(ctor != NULL);
-
- // TODO: need to *call* the constructor!
- UNIMPLEMENTED(WARNING) << "can't call "
- << exception_class->GetDescriptor()->ToModifiedUtf8() << ".<init> "
- << "\"" << msg << "\"";
-
- SetException(exception);
-}
-
-void Thread::ThrowNewException(const char* exception_class_name, const char* fmt, ...) {
- ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- Class* exception_class = class_linker->FindSystemClass(exception_class_name);
- CHECK(exception_class != NULL);
-
+void Thread::ThrowNewException(const char* exception_class_descriptor, const char* fmt, ...) {
std::string msg;
va_list args;
va_start(args, fmt);
StringAppendV(&msg, fmt, args);
va_end(args);
- ThrowNewException(exception_class, msg.c_str());
+ // Convert "Ljava/lang/Exception;" into JNI-style "java/lang/Exception".
+ CHECK(exception_class_descriptor[0] == 'L');
+ std::string descriptor(exception_class_descriptor + 1);
+ CHECK(descriptor[descriptor.length() - 1] == ';');
+ descriptor.erase(descriptor.length() - 1);
+
+ JNIEnv* env = GetJniEnv();
+ jclass exception_class = env->FindClass(descriptor.c_str());
+ CHECK(exception_class != NULL) << "descriptor=\"" << descriptor << "\"";
+ int rc = env->ThrowNew(exception_class, msg.c_str());
+ CHECK_EQ(rc, JNI_OK);
}
Frame Thread::FindExceptionHandler(void* throw_pc, void** handler_pc) {
@@ -243,7 +229,7 @@
void* throw_pc,
const DexFile& dex_file,
ClassLinker* class_linker) {
- Object* exception_obj = exception_;
+ Throwable* exception_obj = exception_;
exception_ = NULL;
intptr_t dex_pc = -1;