Numerous fixes to compiler and verifier for cts vm-tests.
ClassNotFoundExceptions in ResolveType are converted to
NoClassDefFoundErrors.
Compiler checks for puts into final fields.
Method resolution searches direct methods if an appropriate virtual
method can't be found.
Invocations of <clinit> are rejected by the verifier.
Invoke-super and invoke-virtual can't be used on private methods.
Using invoke-interface on non-interface methods and not using
invoke-interface on interface methods leads do an error.
Change-Id: Ia589f1ffccf91b62812ee34c8c5fae1aaf3798c6
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 449bb53..f48a25c 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -188,6 +188,7 @@
"Ldalvik/system/BaseDexClassLoader;",
"Ldalvik/system/PathClassLoader;",
"Ljava/lang/Throwable;",
+ "Ljava/lang/ClassNotFoundException;",
"Ljava/lang/StackTraceElement;",
"Z",
"B",
@@ -458,9 +459,11 @@
SetClassRoot(kDalvikSystemPathClassLoader, dalvik_system_PathClassLoader);
PathClassLoader::SetClass(dalvik_system_PathClassLoader);
- // Set up java.lang.Throwable and java.lang.StackTraceElement as a convenience
+ // Set up java.lang.Throwable, java.lang.ClassNotFoundException, and
+ // java.lang.StackTraceElement as a convenience
SetClassRoot(kJavaLangThrowable, FindSystemClass("Ljava/lang/Throwable;"));
Throwable::SetClass(GetClassRoot(kJavaLangThrowable));
+ SetClassRoot(kJavaLangClassNotFoundException, FindSystemClass("Ljava/lang/ClassNotFoundException;"));
SetClassRoot(kJavaLangStackTraceElement, FindSystemClass("Ljava/lang/StackTraceElement;"));
SetClassRoot(kJavaLangStackTraceElementArrayClass, FindSystemClass("[Ljava/lang/StackTraceElement;"));
StackTraceElement::SetClass(GetClassRoot(kJavaLangStackTraceElement));
@@ -3180,6 +3183,11 @@
} else {
CHECK(Thread::Current()->IsExceptionPending())
<< "Expected pending exception for failed resolution of: " << descriptor;
+ // Convert a ClassNotFoundException to a NoClassDefFoundError
+ if (Thread::Current()->GetException()->InstanceOf(GetClassRoot(kJavaLangClassNotFoundException))) {
+ Thread::Current()->ClearException();
+ ThrowNoClassDefFoundError("Failed resolution of: %s", descriptor);
+ }
}
}
return resolved;
@@ -3218,6 +3226,12 @@
resolved = klass->FindInterfaceMethod(name, signature);
} else {
resolved = klass->FindVirtualMethod(name, signature);
+ // If a virtual method isn't found, search the direct methods. This can
+ // happen when trying to access private methods directly, and allows the
+ // proper exception to be thrown in the caller.
+ if (resolved == NULL) {
+ resolved = klass->FindDirectMethod(name, signature);
+ }
}
if (resolved == NULL) {
ThrowNoSuchMethodError(is_direct, klass, name, signature);