void dvmThrowExceptionInInitializerError()
{
/*
- * TODO: Do we want to wrap it if the original is an Error rather than
- * an Exception?
- *
* TODO: Should this just use dvmWrapException()?
*/
- if (gDvm.exExceptionInInitializerError == NULL) {
+ if (gDvm.exExceptionInInitializerError == NULL || gDvm.exError == NULL) {
/*
* ExceptionInInitializerError isn't itself initialized. This
* can happen very early during VM startup if there is a
Thread* self = dvmThreadSelf();
Object* exception = dvmGetException(self);
+ // We only wrap non-Error exceptions; an Error can just be used as-is.
+ if (dvmInstanceof(exception->clazz, gDvm.exError)) {
+ return;
+ }
+
dvmAddTrackedAlloc(exception, self);
dvmClearException(self);
dvmThrowException(gDvm.exUnsatisfiedLinkError, msg);
}
+void dvmThrowUnsatisfiedLinkError(const char* msg, const Method* method) {
+ char* desc = dexProtoCopyMethodDescriptor(&method->prototype);
+ char* className = dvmDescriptorToDot(method->clazz->descriptor);
+ dvmThrowExceptionFmt(gDvm.exUnsatisfiedLinkError, "%s: %s.%s:%s",
+ msg, className, method->name, desc);
+ free(className);
+ free(desc);
+}
+
void dvmThrowUnsupportedOperationException(const char* msg) {
dvmThrowException(gDvm.exUnsupportedOperationException, msg);
}