Merge "Abstract Method Error unit test and fixes." into dalvik-dev
diff --git a/src/compiler_test.cc b/src/compiler_test.cc
index 7886e60..e951ade 100644
--- a/src/compiler_test.cc
+++ b/src/compiler_test.cc
@@ -54,6 +54,7 @@
   void EnsureCompiled(const ClassLoader* class_loader,
       const char* class_name, const char* method, const char* signature, bool is_virtual) {
     CompileAll(class_loader);
+    runtime_->Start();
     env_ = Thread::Current()->GetJniEnv();
     class_ = env_->FindClass(class_name);
     CHECK(class_ != NULL) << "Class not found: " << class_name;
@@ -163,19 +164,24 @@
   }
 }
 
-TEST_F(CompilerTest, DISABLED_AbstractMethodErrorStub) {
+TEST_F(CompilerTest, AbstractMethodErrorStub) {
   const ClassLoader* class_loader = LoadDex("AbstractMethod");
-  EnsureCompiled(class_loader, "AbstractMethod", "callme", "()V", true);
+  ASSERT_TRUE(class_loader != NULL);
+  EnsureCompiled(class_loader, "AbstractClass", "foo", "()V", true);
 
-  // Create a jobj_ of class "B", NOT class "AbstractMethod".
-  jclass b_class = env_->FindClass("B");
-  jmethodID constructor = env_->GetMethodID(b_class, "<init>", "()V");
-  jobject jobj_ = env_->NewObject(b_class, constructor);
+  // Create a jobj_ of ConcreteClass, NOT AbstractClass.
+  jclass c_class = env_->FindClass("ConcreteClass");
+  jmethodID constructor = env_->GetMethodID(c_class, "<init>", "()V");
+  jobject jobj_ = env_->NewObject(c_class, constructor);
   ASSERT_TRUE(jobj_ != NULL);
 
 #if defined(__arm__)
-  // Will throw AbstractMethodError exception.
+  Class* jlame = class_linker_->FindClass("Ljava/lang/AbstractMethodError;", class_loader);
+  // Force non-virtal call to AbstractClass foo, will throw AbstractMethodError exception.
   env_->CallNonvirtualVoidMethod(jobj_, class_, mid_);
+  EXPECT_TRUE(Thread::Current()->IsExceptionPending());
+  EXPECT_TRUE(Thread::Current()->GetException()->InstanceOf(jlame));
+  Thread::Current()->ClearException();
 #endif  // __arm__
 }
 
diff --git a/src/thread.cc b/src/thread.cc
index 74d62d7..989f56d 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -122,7 +122,7 @@
 void ThrowAbstractMethodErrorFromCode(Method* method, Thread* thread, Method** sp) {
   *sp = Runtime::Current()->GetCalleeSaveMethod();
   thread->SetTopOfStack(sp, 0);
-  thread->ThrowNewException("Ljava/lang/AbstractMethodError",
+  thread->ThrowNewException("Ljava/lang/AbstractMethodError;",
                             "abstract method \"%s\"",
                             PrettyMethod(method).c_str());
   thread->DeliverException();
diff --git a/test/AbstractMethod/AbstractClass.java b/test/AbstractMethod/AbstractClass.java
new file mode 100644
index 0000000..0f6a33e
--- /dev/null
+++ b/test/AbstractMethod/AbstractClass.java
@@ -0,0 +1,17 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+// Test case for AbstractMethodError, we will try to do a non-virtual call to
+// foo.
+abstract class AbstractClass {
+  public AbstractClass() {}
+
+  abstract void foo();
+}
+
+class ConcreteClass extends AbstractClass {
+  public ConcreteClass() {}
+
+  void foo() {
+    throw new Error("This method shouldn't be called");
+  }
+}
diff --git a/test/AbstractMethod/AbstractMethod.java b/test/AbstractMethod/AbstractMethod.java
deleted file mode 100644
index f40e9a9..0000000
--- a/test/AbstractMethod/AbstractMethod.java
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-
-abstract class AbstractMethod {
-  abstract void callme();
-
-  public AbstractMethod() {
-  }
-}
-
-class B extends AbstractMethod {
-  void callme() {
-    System.out.println("B's implementation of callme");
-  }
-}