Add semi-functional exception throwing.

We still need a way to call <init> on the new exception instance, in particular.

Change-Id: I839365d20288208cb8847253380cf654a35aeddd
diff --git a/src/thread.cc b/src/thread.cc
index 1dee238..51b72ce 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -8,6 +8,8 @@
 #include <cerrno>
 #include <list>
 
+#include "class_linker.h"
+#include "object.h"
 #include "runtime.h"
 #include "utils.h"
 
@@ -128,6 +130,46 @@
   return true;
 }
 
+void ThrowNewException(Thread* thread, const char* exception_class_name, const char* msg) {
+  CHECK(thread != NULL);
+
+  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+  Class* exception_class = class_linker->FindSystemClass(exception_class_name);
+  CHECK(exception_class != NULL);
+
+  Object* exception = exception_class->NewInstance();
+  CHECK(exception != NULL);
+
+  size_t char_count = String::ModifiedUtf8Len(msg);
+  String* java_msg = String::AllocFromModifiedUtf8(char_count, 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");
+
+  // TODO: need to *call* the constructor!
+  UNIMPLEMENTED(WARNING) << "can't call "
+                         << exception_class->GetDescriptor() << "."
+                         << ctor->GetDescriptor() << " "
+                         << "\"" << msg << "\"";
+
+  thread->SetException(exception);
+}
+
+void ThrowNewExceptionV(Thread* thread, const char* exception_class_name, const char* fmt, va_list args) {
+  char msg[512];
+  vsnprintf(msg, sizeof(msg), fmt, args);
+  ThrowNewException(thread, exception_class_name, msg);
+}
+
+void Thread::ThrowNewException(const char* exception_class_name, const char* fmt, ...) {
+  va_list args;
+  va_start(args, fmt);
+  ThrowNewExceptionV(this, exception_class_name, fmt, args);
+  va_end(args);
+}
+
 static const char* kStateNames[] = {
   "New",
   "Runnable",