More exception cleanup.

Added a few more classes to the list and tweaked
dvmThrowNegativeArraySizeException() to actually take the size as an
argument. Still pending: Changing the assembly interp files to make
better calls.

Change-Id: I3a470f5fd4c9a1f7f55fc875900096c00c4ac010
diff --git a/vm/Exception.c b/vm/Exception.c
index 9d4cd24..9e32d47 100644
--- a/vm/Exception.c
+++ b/vm/Exception.c
@@ -142,9 +142,17 @@
             "Ljava/lang/ArrayStoreException;");
     ok &= initRef(&gDvm.exClassCastException,
             "Ljava/lang/ClassCastException;");
+    ok &= initRef(&gDvm.exClassFormatError, "Ljava/lang/ClassFormatError;");
     ok &= initRef(&gDvm.exError, "Ljava/lang/Error;");
     ok &= initRef(&gDvm.exExceptionInInitializerError,
             "Ljava/lang/ExceptionInInitializerError;");
+    ok &= initRef(&gDvm.exFileNotFoundException,
+            "Ljava/io/FileNotFoundException;");
+    ok &= initRef(&gDvm.exIOException, "Ljava/io/IOException;");
+    ok &= initRef(&gDvm.exNegativeArraySizeException,
+            "Ljava/lang/NegativeArraySizeException;");
+    ok &= initRef(&gDvm.exNullPointerException,
+            "Ljava/lang/NullPointerException;");
     ok &= initRef(&gDvm.exRuntimeException, "Ljava/lang/RuntimeException;");
     ok &= initRef(&gDvm.exStackOverflowError,
             "Ljava/lang/StackOverflowError;");
@@ -308,6 +316,16 @@
     Thread* self = dvmThreadSelf();
     Object* exception;
 
+    if (excepClass == NULL) {
+        /*
+         * The exception class was passed in as NULL. This might happen
+         * early on in VM initialization. There's nothing better to do
+         * than just log the message as an error and abort.
+         */
+        LOGE("Fatal error: %s\n", msg);
+        dvmAbort();
+    }
+
     /* make sure the exception is initialized */
     if (!dvmIsClassInitialized(excepClass) && !dvmInitClass(excepClass)) {
         LOGE("ERROR: unable to initialize exception class '%s'\n",
@@ -1455,7 +1473,7 @@
 }
 
 void dvmThrowClassFormatError(const char* msg) {
-    dvmThrowException("Ljava/lang/ClassFormatError;", msg);
+    dvmThrowExceptionByClass(gDvm.exClassFormatError, msg);
 }
 
 void dvmThrowClassNotFoundException(const char* msg) {
@@ -1463,11 +1481,11 @@
 }
 
 void dvmThrowFileNotFoundException(const char* msg) {
-    dvmThrowException("Ljava/io/FileNotFoundException;", msg);
+    dvmThrowExceptionByClass(gDvm.exFileNotFoundException, msg);
 }
 
 void dvmThrowIOException(const char* msg) {
-    dvmThrowException("Ljava/io/IOException;", msg);
+    dvmThrowExceptionByClass(gDvm.exIOException, msg);
 }
 
 void dvmThrowIllegalAccessException(const char* msg) {
@@ -1517,8 +1535,8 @@
     dvmThrowException("Ljava/lang/LinkageError;", msg);
 }
 
-void dvmThrowNegativeArraySizeException(const char* msg) {
-    dvmThrowException("Ljava/lang/NegativeArraySizeException;", msg);
+void dvmThrowNegativeArraySizeException(s4 size) {
+    dvmThrowExceptionFmtByClass(gDvm.exNegativeArraySizeException, "%d", size);
 }
 
 void dvmThrowNoClassDefFoundError(const char* descriptor) {
@@ -1539,7 +1557,7 @@
 }
 
 void dvmThrowNullPointerException(const char* msg) {
-    dvmThrowException("Ljava/lang/NullPointerException;", msg);
+    dvmThrowExceptionByClass(gDvm.exNullPointerException, msg);
 }
 
 void dvmThrowOutOfMemoryError(const char* msg) {
diff --git a/vm/Exception.h b/vm/Exception.h
index 099b883..9fbad99 100644
--- a/vm/Exception.h
+++ b/vm/Exception.h
@@ -350,9 +350,9 @@
 
 /**
  * Throw a NegativeArraySizeException in the current thread, with the
- * given detail message.
+ * given number as the detail message.
  */
-void dvmThrowNegativeArraySizeException(const char* msg);
+void dvmThrowNegativeArraySizeException(s4 size);
 
 /**
  * Throw a NoClassDefFoundError in the current thread, with the
diff --git a/vm/Globals.h b/vm/Globals.h
index 17a0154..25f6c15 100644
--- a/vm/Globals.h
+++ b/vm/Globals.h
@@ -271,8 +271,13 @@
     ClassObject* exArrayIndexOutOfBoundsException;
     ClassObject* exArrayStoreException;
     ClassObject* exClassCastException;
+    ClassObject* exClassFormatError;
     ClassObject* exError;
     ClassObject* exExceptionInInitializerError;
+    ClassObject* exFileNotFoundException; /* in java.io */
+    ClassObject* exIOException;           /* in java.io */
+    ClassObject* exNegativeArraySizeException;
+    ClassObject* exNullPointerException;
     ClassObject* exRuntimeException;
     ClassObject* exStackOverflowError;
     ClassObject* exThrowable;
diff --git a/vm/mterp/c/OP_NEW_ARRAY.c b/vm/mterp/c/OP_NEW_ARRAY.c
index d77c4d5..6d6771a 100644
--- a/vm/mterp/c/OP_NEW_ARRAY.c
+++ b/vm/mterp/c/OP_NEW_ARRAY.c
@@ -13,7 +13,7 @@
             vdst, vsrc1, ref, (s4) GET_REGISTER(vsrc1));
         length = (s4) GET_REGISTER(vsrc1);
         if (length < 0) {
-            dvmThrowNegativeArraySizeException(NULL);
+            dvmThrowNegativeArraySizeException(length);
             GOTO_exceptionThrown();
         }
         arrayClass = dvmDexGetResolvedClass(methodClassDex, ref);
diff --git a/vm/mterp/c/OP_NEW_ARRAY_JUMBO.c b/vm/mterp/c/OP_NEW_ARRAY_JUMBO.c
index 46905cf..7c0d551 100644
--- a/vm/mterp/c/OP_NEW_ARRAY_JUMBO.c
+++ b/vm/mterp/c/OP_NEW_ARRAY_JUMBO.c
@@ -13,7 +13,7 @@
             vdst, vsrc1, ref, (s4) GET_REGISTER(vsrc1));
         length = (s4) GET_REGISTER(vsrc1);
         if (length < 0) {
-            dvmThrowNegativeArraySizeException(NULL);
+            dvmThrowNegativeArraySizeException(length);
             GOTO_exceptionThrown();
         }
         arrayClass = dvmDexGetResolvedClass(methodClassDex, ref);
diff --git a/vm/mterp/out/InterpC-allstubs.c b/vm/mterp/out/InterpC-allstubs.c
index 87293e0..248f37e 100644
--- a/vm/mterp/out/InterpC-allstubs.c
+++ b/vm/mterp/out/InterpC-allstubs.c
@@ -1830,7 +1830,7 @@
             vdst, vsrc1, ref, (s4) GET_REGISTER(vsrc1));
         length = (s4) GET_REGISTER(vsrc1);
         if (length < 0) {
-            dvmThrowNegativeArraySizeException(NULL);
+            dvmThrowNegativeArraySizeException(length);
             GOTO_exceptionThrown();
         }
         arrayClass = dvmDexGetResolvedClass(methodClassDex, ref);
@@ -3304,7 +3304,7 @@
             vdst, vsrc1, ref, (s4) GET_REGISTER(vsrc1));
         length = (s4) GET_REGISTER(vsrc1);
         if (length < 0) {
-            dvmThrowNegativeArraySizeException(NULL);
+            dvmThrowNegativeArraySizeException(length);
             GOTO_exceptionThrown();
         }
         arrayClass = dvmDexGetResolvedClass(methodClassDex, ref);
diff --git a/vm/mterp/out/InterpC-portdbg.c b/vm/mterp/out/InterpC-portdbg.c
index 198de61..e002973 100644
--- a/vm/mterp/out/InterpC-portdbg.c
+++ b/vm/mterp/out/InterpC-portdbg.c
@@ -2193,7 +2193,7 @@
             vdst, vsrc1, ref, (s4) GET_REGISTER(vsrc1));
         length = (s4) GET_REGISTER(vsrc1);
         if (length < 0) {
-            dvmThrowNegativeArraySizeException(NULL);
+            dvmThrowNegativeArraySizeException(length);
             GOTO_exceptionThrown();
         }
         arrayClass = dvmDexGetResolvedClass(methodClassDex, ref);
@@ -3667,7 +3667,7 @@
             vdst, vsrc1, ref, (s4) GET_REGISTER(vsrc1));
         length = (s4) GET_REGISTER(vsrc1);
         if (length < 0) {
-            dvmThrowNegativeArraySizeException(NULL);
+            dvmThrowNegativeArraySizeException(length);
             GOTO_exceptionThrown();
         }
         arrayClass = dvmDexGetResolvedClass(methodClassDex, ref);
diff --git a/vm/mterp/out/InterpC-portstd.c b/vm/mterp/out/InterpC-portstd.c
index 6b61644..94f182e 100644
--- a/vm/mterp/out/InterpC-portstd.c
+++ b/vm/mterp/out/InterpC-portstd.c
@@ -1943,7 +1943,7 @@
             vdst, vsrc1, ref, (s4) GET_REGISTER(vsrc1));
         length = (s4) GET_REGISTER(vsrc1);
         if (length < 0) {
-            dvmThrowNegativeArraySizeException(NULL);
+            dvmThrowNegativeArraySizeException(length);
             GOTO_exceptionThrown();
         }
         arrayClass = dvmDexGetResolvedClass(methodClassDex, ref);
@@ -3417,7 +3417,7 @@
             vdst, vsrc1, ref, (s4) GET_REGISTER(vsrc1));
         length = (s4) GET_REGISTER(vsrc1);
         if (length < 0) {
-            dvmThrowNegativeArraySizeException(NULL);
+            dvmThrowNegativeArraySizeException(length);
             GOTO_exceptionThrown();
         }
         arrayClass = dvmDexGetResolvedClass(methodClassDex, ref);
diff --git a/vm/native/dalvik_system_VMRuntime.c b/vm/native/dalvik_system_VMRuntime.c
index 402d607..af0df7a 100644
--- a/vm/native/dalvik_system_VMRuntime.c
+++ b/vm/native/dalvik_system_VMRuntime.c
@@ -122,7 +122,7 @@
         RETURN_VOID();
     }
     if (length < 0) {
-        dvmThrowNegativeArraySizeException(NULL);
+        dvmThrowNegativeArraySizeException(length);
         RETURN_VOID();
     }
 
diff --git a/vm/native/java_lang_reflect_Array.c b/vm/native/java_lang_reflect_Array.c
index 275e826..bc7e5ec 100644
--- a/vm/native/java_lang_reflect_Array.c
+++ b/vm/native/java_lang_reflect_Array.c
@@ -36,7 +36,7 @@
 
     assert(elementClass != NULL);       // tested by caller
     if (length < 0) {
-        dvmThrowNegativeArraySizeException(NULL);
+        dvmThrowNegativeArraySizeException(length);
         RETURN_VOID();
     }
 
@@ -91,7 +91,7 @@
     dimensions = (int*) dimArray->contents;
     for (i = 0; i < numDim; i++) {
         if (dimensions[i] < 0) {
-            dvmThrowNegativeArraySizeException(NULL);
+            dvmThrowNegativeArraySizeException(dimensions[i]);
             RETURN_VOID();
         }
         LOGVV("DIM %d: %d\n", i, dimensions[i]);