More exception rework.
This includes banishing dvmThrowExceptionWithClassMessage(), in favor
of the "ByClass" version, as well as making the verification error
throwing code use class objects.
Bug: 3500987
Change-Id: I1d63cec0ffaf3a0ad17e9304ba6a21fe51072fc7
diff --git a/vm/Exception.c b/vm/Exception.c
index 02e0e2a..99db870 100644
--- a/vm/Exception.c
+++ b/vm/Exception.c
@@ -261,29 +261,13 @@
dvmReleaseTrackedAlloc(exception, self);
}
-/*
- * Throw the named exception using the human-readable form of the class
- * descriptor as the exception message, and with the specified cause.
- */
-void dvmThrowChainedExceptionWithClassMessage(const char* exceptionDescriptor,
- const char* messageDescriptor, Object* cause)
-{
- char* message = dvmHumanReadableDescriptor(messageDescriptor);
-
- dvmThrowChainedException(exceptionDescriptor, message, cause);
- free(message);
-}
-
-/*
- * Like dvmThrowException, but take a class object instead of a name
- * and turn the given message into the human-readable form for a descriptor.
- */
-void dvmThrowExceptionByClassWithClassMessage(ClassObject* exceptionClass,
- const char* messageDescriptor)
+void dvmThrowChainedExceptionByClassWithClassMessage(
+ ClassObject* exceptionClass, const char* messageDescriptor,
+ Object* cause)
{
char* message = dvmDescriptorToName(messageDescriptor);
- dvmThrowExceptionByClass(exceptionClass, message);
+ dvmThrowChainedExceptionByClass(exceptionClass, message, cause);
free(message);
}
@@ -1470,6 +1454,12 @@
descriptor);
}
+void dvmThrowChainedNoClassDefFoundError(const char* descriptor,
+ Object* cause) {
+ dvmThrowChainedExceptionByClassWithClassMessage(
+ gDvm.exNoClassDefFoundError, descriptor, cause);
+}
+
void dvmThrowNoSuchFieldError(const char* msg) {
dvmThrowExceptionByClass(gDvm.exNoSuchFieldError, msg);
}
diff --git a/vm/Exception.h b/vm/Exception.h
index 6d27437..ccab18c 100644
--- a/vm/Exception.h
+++ b/vm/Exception.h
@@ -83,24 +83,23 @@
}
/*
- * Throw the named exception using the human-readable form of the class
- * descriptor as the exception message, and with the specified cause.
+ * Like dvmThrowChainedException, but take a class object instead of a name
+ * and turn the given message into the human-readable form for a descriptor.
*/
-void dvmThrowChainedExceptionWithClassMessage(const char* exceptionDescriptor,
- const char* messageDescriptor, Object* cause);
-INLINE void dvmThrowExceptionWithClassMessage(const char* exceptionDescriptor,
- const char* messageDescriptor)
-{
- dvmThrowChainedExceptionWithClassMessage(exceptionDescriptor,
- messageDescriptor, NULL);
-}
+void dvmThrowChainedExceptionByClassWithClassMessage(
+ ClassObject* exceptionClass, const char* messageDescriptor,
+ Object* cause);
/*
* Like dvmThrowException, but take a class object instead of a name
* and turn the given message into the human-readable form for a descriptor.
*/
-void dvmThrowExceptionByClassWithClassMessage(ClassObject* exceptionClass,
- const char* messageDescriptor);
+INLINE void dvmThrowExceptionByClassWithClassMessage(
+ ClassObject* exceptionClass, const char* messageDescriptor)
+{
+ dvmThrowChainedExceptionByClassWithClassMessage(exceptionClass,
+ messageDescriptor, NULL);
+}
/*
* Return the exception being thrown in the current thread, or NULL if
@@ -378,6 +377,14 @@
void dvmThrowNoClassDefFoundError(const char* descriptor);
/**
+ * Throw a NoClassDefFoundError in the current thread, with the given
+ * cause, and the human-readable form of the given descriptor as the
+ * detail message.
+ */
+void dvmThrowChainedNoClassDefFoundError(const char* descriptor,
+ Object* cause);
+
+/**
* Throw a NoSuchFieldError in the current thread, with the given
* detail message.
*/
diff --git a/vm/Globals.h b/vm/Globals.h
index a4b47a6..48e3f87 100644
--- a/vm/Globals.h
+++ b/vm/Globals.h
@@ -286,6 +286,7 @@
ClassObject* exIllegalStateException;
ClassObject* exIllegalThreadStateException;
ClassObject* exIncompatibleClassChangeError;
+ ClassObject* exInstantiationError;
ClassObject* exInstantiationException;
ClassObject* exInternalError;
ClassObject* exInterruptedException;
diff --git a/vm/Init.c b/vm/Init.c
index e4d05ee..b9039d8 100644
--- a/vm/Init.c
+++ b/vm/Init.c
@@ -1191,11 +1191,11 @@
ok &= initRef(&gDvm.classJavaLangClass, "Ljava/lang/Class;");
ok &= initRef(&gDvm.classJavaLangObject, "Ljava/lang/Object;");
+ ok &= initRef(&gDvm.exThrowable, "Ljava/lang/Throwable;");
ok &= initRef(&gDvm.classJavaLangString, "Ljava/lang/String;");
ok &= initRef(&gDvm.classJavaLangThread, "Ljava/lang/Thread;");
ok &= initRef(&gDvm.classJavaLangThreadGroup, "Ljava/lang/ThreadGroup;");
- ok &= initRef(&gDvm.exThrowable, "Ljava/lang/Throwable;");
ok &= initRef(&gDvm.classJavaLangVMThread, "Ljava/lang/VMThread;");
/* Exception classes and related support classes */
@@ -1235,6 +1235,8 @@
"Ljava/lang/IllegalThreadStateException;");
ok &= initRef(&gDvm.exIncompatibleClassChangeError,
"Ljava/lang/IncompatibleClassChangeError;");
+ ok &= initRef(&gDvm.exInstantiationError,
+ "Ljava/lang/InstantiationError;");
ok &= initRef(&gDvm.exInstantiationException,
"Ljava/lang/InstantiationException;");
ok &= initRef(&gDvm.exInternalError,
@@ -1264,7 +1266,6 @@
"Ldalvik/system/StaleDexCacheError;");
ok &= initRef(&gDvm.exStringIndexOutOfBoundsException,
"Ljava/lang/StringIndexOutOfBoundsException;");
- ok &= initRef(&gDvm.exThrowable, "Ljava/lang/Throwable;");
ok &= initRef(&gDvm.exTypeNotPresentException,
"Ljava/lang/TypeNotPresentException;");
ok &= initRef(&gDvm.exUnsatisfiedLinkError,
diff --git a/vm/interp/Interp.c b/vm/interp/Interp.c
index 9e94449..a145034 100644
--- a/vm/interp/Interp.c
+++ b/vm/interp/Interp.c
@@ -1154,43 +1154,43 @@
const int typeMask = 0xff << kVerifyErrorRefTypeShift;
VerifyError errorKind = kind & ~typeMask;
VerifyErrorRefType refType = kind >> kVerifyErrorRefTypeShift;
- const char* exceptionName = "Ljava/lang/VerifyError;";
+ ClassObject* exceptionClass = gDvm.exVerifyError;
char* msg = NULL;
switch ((VerifyError) errorKind) {
case VERIFY_ERROR_NO_CLASS:
- exceptionName = "Ljava/lang/NoClassDefFoundError;";
+ exceptionClass = gDvm.exNoClassDefFoundError;
msg = classNameFromIndex(method, ref, refType, 0);
break;
case VERIFY_ERROR_NO_FIELD:
- exceptionName = "Ljava/lang/NoSuchFieldError;";
+ exceptionClass = gDvm.exNoSuchFieldError;
msg = fieldNameFromIndex(method, ref, refType, 0);
break;
case VERIFY_ERROR_NO_METHOD:
- exceptionName = "Ljava/lang/NoSuchMethodError;";
+ exceptionClass = gDvm.exNoSuchMethodError;
msg = methodNameFromIndex(method, ref, refType, 0);
break;
case VERIFY_ERROR_ACCESS_CLASS:
- exceptionName = "Ljava/lang/IllegalAccessError;";
+ exceptionClass = gDvm.exIllegalAccessError;
msg = classNameFromIndex(method, ref, refType,
kThrowShow_accessFromClass);
break;
case VERIFY_ERROR_ACCESS_FIELD:
- exceptionName = "Ljava/lang/IllegalAccessError;";
+ exceptionClass = gDvm.exIllegalAccessError;
msg = fieldNameFromIndex(method, ref, refType,
kThrowShow_accessFromClass);
break;
case VERIFY_ERROR_ACCESS_METHOD:
- exceptionName = "Ljava/lang/IllegalAccessError;";
+ exceptionClass = gDvm.exIllegalAccessError;
msg = methodNameFromIndex(method, ref, refType,
kThrowShow_accessFromClass);
break;
case VERIFY_ERROR_CLASS_CHANGE:
- exceptionName = "Ljava/lang/IncompatibleClassChangeError;";
+ exceptionClass = gDvm.exIncompatibleClassChangeError;
msg = classNameFromIndex(method, ref, refType, 0);
break;
case VERIFY_ERROR_INSTANTIATION:
- exceptionName = "Ljava/lang/InstantiationError;";
+ exceptionClass = gDvm.exInstantiationError;
msg = classNameFromIndex(method, ref, refType, 0);
break;
@@ -1206,7 +1206,7 @@
/* no default clause -- want warning if enum updated */
}
- dvmThrowException(exceptionName, msg);
+ dvmThrowExceptionByClass(exceptionClass, msg);
free(msg);
}
diff --git a/vm/mterp/c/OP_NEW_INSTANCE.c b/vm/mterp/c/OP_NEW_INSTANCE.c
index e7e2952..65a8cf7 100644
--- a/vm/mterp/c/OP_NEW_INSTANCE.c
+++ b/vm/mterp/c/OP_NEW_INSTANCE.c
@@ -32,7 +32,7 @@
* Verifier now tests for interface/abstract class.
*/
//if (dvmIsInterfaceClass(clazz) || dvmIsAbstractClass(clazz)) {
- // dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationError;",
+ // dvmThrowExceptionByClassWithClassMessage(gDvm.exInstantiationError,
// clazz->descriptor);
// GOTO_exceptionThrown();
//}
diff --git a/vm/mterp/c/OP_NEW_INSTANCE_JUMBO.c b/vm/mterp/c/OP_NEW_INSTANCE_JUMBO.c
index b49adbf..6cb27b8 100644
--- a/vm/mterp/c/OP_NEW_INSTANCE_JUMBO.c
+++ b/vm/mterp/c/OP_NEW_INSTANCE_JUMBO.c
@@ -32,7 +32,7 @@
* Verifier now tests for interface/abstract class.
*/
//if (dvmIsInterfaceClass(clazz) || dvmIsAbstractClass(clazz)) {
- // dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationError;",
+ // dvmThrowExceptionByClassWithClassMessage(gDvm.exInstantiationError,
// clazz->descriptor);
// GOTO_exceptionThrown();
//}
diff --git a/vm/mterp/out/InterpC-allstubs.c b/vm/mterp/out/InterpC-allstubs.c
index 632d62d..5d94cef 100644
--- a/vm/mterp/out/InterpC-allstubs.c
+++ b/vm/mterp/out/InterpC-allstubs.c
@@ -1802,7 +1802,7 @@
* Verifier now tests for interface/abstract class.
*/
//if (dvmIsInterfaceClass(clazz) || dvmIsAbstractClass(clazz)) {
- // dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationError;",
+ // dvmThrowExceptionByClassWithClassMessage(gDvm.exInstantiationError,
// clazz->descriptor);
// GOTO_exceptionThrown();
//}
@@ -3276,7 +3276,7 @@
* Verifier now tests for interface/abstract class.
*/
//if (dvmIsInterfaceClass(clazz) || dvmIsAbstractClass(clazz)) {
- // dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationError;",
+ // dvmThrowExceptionByClassWithClassMessage(gDvm.exInstantiationError,
// clazz->descriptor);
// GOTO_exceptionThrown();
//}
diff --git a/vm/mterp/out/InterpC-portdbg.c b/vm/mterp/out/InterpC-portdbg.c
index 090146f..e2b8e67 100644
--- a/vm/mterp/out/InterpC-portdbg.c
+++ b/vm/mterp/out/InterpC-portdbg.c
@@ -2165,7 +2165,7 @@
* Verifier now tests for interface/abstract class.
*/
//if (dvmIsInterfaceClass(clazz) || dvmIsAbstractClass(clazz)) {
- // dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationError;",
+ // dvmThrowExceptionByClassWithClassMessage(gDvm.exInstantiationError,
// clazz->descriptor);
// GOTO_exceptionThrown();
//}
@@ -3639,7 +3639,7 @@
* Verifier now tests for interface/abstract class.
*/
//if (dvmIsInterfaceClass(clazz) || dvmIsAbstractClass(clazz)) {
- // dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationError;",
+ // dvmThrowExceptionByClassWithClassMessage(gDvm.exInstantiationError,
// clazz->descriptor);
// GOTO_exceptionThrown();
//}
diff --git a/vm/mterp/out/InterpC-portstd.c b/vm/mterp/out/InterpC-portstd.c
index e71511e..8204e48 100644
--- a/vm/mterp/out/InterpC-portstd.c
+++ b/vm/mterp/out/InterpC-portstd.c
@@ -1915,7 +1915,7 @@
* Verifier now tests for interface/abstract class.
*/
//if (dvmIsInterfaceClass(clazz) || dvmIsAbstractClass(clazz)) {
- // dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationError;",
+ // dvmThrowExceptionByClassWithClassMessage(gDvm.exInstantiationError,
// clazz->descriptor);
// GOTO_exceptionThrown();
//}
@@ -3389,7 +3389,7 @@
* Verifier now tests for interface/abstract class.
*/
//if (dvmIsInterfaceClass(clazz) || dvmIsAbstractClass(clazz)) {
- // dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationError;",
+ // dvmThrowExceptionByClassWithClassMessage(gDvm.exInstantiationError,
// clazz->descriptor);
// GOTO_exceptionThrown();
//}
diff --git a/vm/oo/Class.c b/vm/oo/Class.c
index 3bd0298..358067e 100644
--- a/vm/oo/Class.c
+++ b/vm/oo/Class.c
@@ -1300,8 +1300,7 @@
#endif
dvmAddTrackedAlloc(excep, self);
dvmClearException(self);
- dvmThrowChainedExceptionWithClassMessage(
- "Ljava/lang/NoClassDefFoundError;", descriptor, excep);
+ dvmThrowChainedNoClassDefFoundError(descriptor, excep);
dvmReleaseTrackedAlloc(excep, self);
clazz = NULL;
goto bail;