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");
- }
-}