OSDN Git Service

Invert sense of a test.
[android-x86/dalvik.git] / vm / Exception.h
index 6d05b09..055ed2b 100644 (file)
 /*
  * Exception handling.
  */
-#ifndef _DALVIK_EXCEPTION
-#define _DALVIK_EXCEPTION
-
-/* initialization */
-bool dvmExceptionStartup(void);
-void dvmExceptionShutdown(void);
+#ifndef DALVIK_EXCEPTION_H_
+#define DALVIK_EXCEPTION_H_
 
 /*
- * Throw an exception in the current thread, by class descriptor.
+ * Create a Throwable and throw an exception in the current thread (where
+ * "throwing" just means "set the thread's exception pointer").
+ *
+ * "msg" and/or "cause" may be NULL.
+ *
+ * If we have a bad exception hierarchy -- something in Throwable.<init>
+ * is missing -- then every attempt to throw an exception will result
+ * in another exception.  Exceptions are generally allowed to "chain"
+ * to other exceptions, so it's hard to auto-detect this problem.  It can
+ * only happen if the system classes are broken, so it's probably not
+ * worth spending cycles to detect it.
+ *
+ * We do have one case to worry about: if the classpath is completely
+ * wrong, we'll go into a death spin during startup because we can't find
+ * the initial class and then we can't find NoClassDefFoundError.  We have
+ * to handle this case.
  */
-void dvmThrowChainedException(const char* exceptionDescriptor, const char* msg,
-    Object* cause);
-INLINE void dvmThrowException(const char* exceptionDescriptor,
+void dvmThrowChainedException(ClassObject* exceptionClass,
+    const char* msg, Object* cause);
+INLINE void dvmThrowException(ClassObject* exceptionClass,
     const char* msg)
 {
-    dvmThrowChainedException(exceptionDescriptor, msg, NULL);
+    dvmThrowChainedException(exceptionClass, msg, NULL);
 }
 
 /*
- * Throw an ArrayIndexOutOfBoundsException in the current thread, using the given
- * index and array length in the detail message.
+ * Like dvmThrowException, but takes printf-style args for the message.
  */
-void dvmThrowAIOOBE(int index, int length);
-/*
- * Throw an ArrayStoreException in the current thread, using the given classes'
- * names in the detail message.
- */
-void dvmThrowArrayStoreException(ClassObject* actual, ClassObject* desired);
-
-/**
- * Throw a ClassCastException in the current thread, using the given classes'
- * names in the detail message.
- */
-void dvmThrowClassCastException(ClassObject* actual, ClassObject* desired);
-
-/*
- * Like dvmThrowChainedException, but takes printf-style args for the message.
- */
-void dvmThrowExceptionFmtV(const char* exceptionDescriptor, const char* fmt,
-    va_list args);
-void dvmThrowExceptionFmt(const char* exceptionDescriptor, const char* fmt, ...)
+void dvmThrowExceptionFmtV(ClassObject* exceptionClass,
+    const char* fmt, va_list args);
+void dvmThrowExceptionFmt(ClassObject* exceptionClass,
+    const char* fmt, ...)
 #if defined(__GNUC__)
     __attribute__ ((format(printf, 2, 3)))
 #endif
     ;
-INLINE void dvmThrowExceptionFmt(const char* exceptionDescriptor,
+INLINE void dvmThrowExceptionFmt(ClassObject* exceptionClass,
     const char* fmt, ...)
 {
     va_list args;
     va_start(args, fmt);
-    dvmThrowExceptionFmtV(exceptionDescriptor, fmt, args);
+    dvmThrowExceptionFmtV(exceptionClass, fmt, args);
     va_end(args);
 }
 
 /*
- * Throw an exception in the current thread, by class object.
+ * 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 dvmThrowChainedExceptionByClass(ClassObject* exceptionClass,
-    const char* msg, Object* cause);
-INLINE void dvmThrowExceptionByClass(ClassObject* exceptionClass,
-    const char* msg)
-{
-    dvmThrowChainedExceptionByClass(exceptionClass, msg, NULL);
-}
+void dvmThrowChainedExceptionWithClassMessage(
+    ClassObject* exceptionClass, const char* messageDescriptor,
+    Object* cause);
 
 /*
- * Throw the named exception using the name of a class as the exception
- * 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 dvmThrowChainedExceptionWithClassMessage(const char* exceptionDescriptor,
-    const char* messageDescriptor, Object* cause);
-INLINE void dvmThrowExceptionWithClassMessage(const char* exceptionDescriptor,
-    const char* messageDescriptor)
+INLINE void dvmThrowExceptionWithClassMessage(
+    ClassObject* exceptionClass, const char* messageDescriptor)
 {
-    dvmThrowChainedExceptionWithClassMessage(exceptionDescriptor,
-        messageDescriptor, NULL);
+    dvmThrowChainedExceptionWithClassMessage(exceptionClass,
+            messageDescriptor, NULL);
 }
 
 /*
- * Like dvmThrowExceptionWithMessageFromDescriptor, but take a
- * class object instead of a name.
- */
-void dvmThrowExceptionByClassWithClassMessage(ClassObject* exceptionClass,
-    const char* messageDescriptor);
-
-/*
  * Return the exception being thrown in the current thread, or NULL if
  * no exception is pending.
  */
@@ -184,12 +168,12 @@ void dvmLogExceptionStackTrace(void);
  * "*newFrame" gets a copy of the new frame pointer.
  *
  * If "doUnroll" is set, we unroll "thread"s stack as we go (and update
- * self->curFrame with the same value as in *newFrame).
+ * self->interpSave.curFrame with the same value as in *newFrame).
  *
  * Returns the offset to the catch code on success, or -1 if we couldn't
  * find a catcher.
  */
-int dvmFindCatchBlock(Thread* self, int relPc, Object* exception,
+extern "C" int dvmFindCatchBlock(Thread* self, int relPc, Object* exception,
     bool doUnroll, void** newFrame);
 
 /*
@@ -200,21 +184,303 @@ int dvmFindCatchBlock(Thread* self, int relPc, Object* exception,
  *
  * Don't call the "Internal" form of the function directly.
  */
-void* dvmFillInStackTraceInternal(Thread* thread, bool wantObject, int* pCount);
+void* dvmFillInStackTraceInternal(Thread* thread, bool wantObject, size_t* pCount);
 /* return an [I for use by interpreted code */
 INLINE Object* dvmFillInStackTrace(Thread* thread) {
     return (Object*) dvmFillInStackTraceInternal(thread, true, NULL);
 }
 ArrayObject* dvmGetStackTrace(const Object* stackState);
 /* return an int* and array count; caller must free() the return value */
-INLINE int* dvmFillInStackTraceRaw(Thread* thread, int* pCount) {
+INLINE int* dvmFillInStackTraceRaw(Thread* thread, size_t* pCount) {
     return (int*) dvmFillInStackTraceInternal(thread, false, pCount);
 }
-ArrayObject* dvmGetStackTraceRaw(const int* intVals, int stackDepth);
+ArrayObject* dvmGetStackTraceRaw(const int* intVals, size_t stackDepth);
+void dvmFillStackTraceElements(const int* intVals, size_t stackDepth, ArrayObject* steArray);
 
 /*
  * Print a formatted version of a raw stack trace to the log file.
  */
 void dvmLogRawStackTrace(const int* intVals, int stackDepth);
 
-#endif /*_DALVIK_EXCEPTION*/
+/**
+ * Throw an AbstractMethodError in the current thread, with the given detail
+ * message.
+ */
+void dvmThrowAbstractMethodError(const char* msg);
+
+/**
+ * Throw an ArithmeticException in the current thread, with the given detail
+ * message.
+ */
+extern "C" void dvmThrowArithmeticException(const char* msg);
+
+/*
+ * Throw an ArrayIndexOutOfBoundsException in the current thread,
+ * using the given array length and index in the detail message.
+ */
+extern "C" void dvmThrowArrayIndexOutOfBoundsException(int length, int index);
+
+/*
+ * Throw an ArrayStoreException in the current thread, using the given classes'
+ * names in the detail message, indicating that an object of the given type
+ * can't be stored into an array of the given type.
+ */
+extern "C" void dvmThrowArrayStoreExceptionIncompatibleElement(ClassObject* objectType, ClassObject* arrayType);
+
+/*
+ * Throw an ArrayStoreException in the current thread, using the given
+ * class name and argument label in the detail message, indicating
+ * that it is not an array.
+ */
+void dvmThrowArrayStoreExceptionNotArray(ClassObject* actual, const char* label);
+
+/*
+ * Throw an ArrayStoreException in the current thread, using the given
+ * classes' names in the detail message, indicating that the arrays
+ * aren't compatible (for copying contents).
+ */
+void dvmThrowArrayStoreExceptionIncompatibleArrays(ClassObject* source, ClassObject* destination);
+
+/*
+ * Throw an ArrayStoreException in the current thread, using the given
+ * index and classes' names in the detail message, indicating that the
+ * object at the given index and of the given type cannot be stored
+ * into an array of the given type.
+ */
+void dvmThrowArrayStoreExceptionIncompatibleArrayElement(s4 index, ClassObject* objectType,
+        ClassObject* arrayType);
+
+/**
+ * Throw a ClassCastException in the current thread, using the given classes'
+ * names in the detail message.
+ */
+extern "C" void dvmThrowClassCastException(ClassObject* actual, ClassObject* desired);
+
+/**
+ * Throw a ClassCircularityError in the current thread, with the
+ * human-readable form of the given descriptor as the detail message.
+ */
+void dvmThrowClassCircularityError(const char* descriptor);
+
+/**
+ * Throw a ClassFormatError in the current thread, with the given
+ * detail message.
+ */
+void dvmThrowClassFormatError(const char* msg);
+
+/**
+ * Throw a ClassNotFoundException in the current thread, with the given
+ * class name as the detail message.
+ */
+void dvmThrowClassNotFoundException(const char* name);
+
+/**
+ * Throw a ClassNotFoundException in the current thread, with the given
+ * cause, and the given class name as the detail message.
+ */
+void dvmThrowChainedClassNotFoundException(const char* name, Object* cause);
+
+/*
+ * Throw the VM-spec-mandated error when an exception is thrown during
+ * class initialization. Unlike other helper functions, this automatically
+ * wraps the current thread's pending exception.
+ */
+void dvmThrowExceptionInInitializerError(void);
+
+/**
+ * Throw a FileNotFoundException in the current thread, with the given
+ * detail message.
+ */
+void dvmThrowFileNotFoundException(const char* msg);
+
+/**
+ * Throw an IOException in the current thread, with the given
+ * detail message.
+ */
+void dvmThrowIOException(const char* msg);
+
+/**
+ * Throw an IllegalAccessError in the current thread, with the
+ * given detail message.
+ */
+void dvmThrowIllegalAccessError(const char* msg);
+
+/**
+ * Throw an IllegalAccessException in the current thread, with the
+ * given detail message.
+ */
+void dvmThrowIllegalAccessException(const char* msg);
+
+/**
+ * Throw an IllegalArgumentException in the current thread, with the
+ * given detail message.
+ */
+void dvmThrowIllegalArgumentException(const char* msg);
+
+/**
+ * Throw an IllegalMonitorStateException in the current thread, with
+ * the given detail message.
+ */
+void dvmThrowIllegalMonitorStateException(const char* msg);
+
+/**
+ * Throw an IllegalStateException in the current thread, with
+ * the given detail message.
+ */
+void dvmThrowIllegalStateException(const char* msg);
+
+/**
+ * Throw an IllegalThreadStateException in the current thread, with
+ * the given detail message.
+ */
+void dvmThrowIllegalThreadStateException(const char* msg);
+
+/**
+ * Throw an IncompatibleClassChangeError in the current thread,
+ * the given detail message.
+ */
+void dvmThrowIncompatibleClassChangeError(const char* msg);
+
+/**
+ * Throw an IncompatibleClassChangeError in the current thread, with the
+ * human-readable form of the given descriptor as the detail message.
+ */
+void dvmThrowIncompatibleClassChangeErrorWithClassMessage(
+        const char* descriptor);
+
+/**
+ * Throw an InstantiationException in the current thread, with
+ * the human-readable form of the given class as the detail message,
+ * with optional extra detail appended to the message.
+ */
+void dvmThrowInstantiationException(ClassObject* clazz,
+        const char* extraDetail);
+
+/**
+ * Throw an InternalError in the current thread, with the given
+ * detail message.
+ */
+extern "C" void dvmThrowInternalError(const char* msg);
+
+/**
+ * Throw an InterruptedException in the current thread, with the given
+ * detail message.
+ */
+void dvmThrowInterruptedException(const char* msg);
+
+/**
+ * Throw a LinkageError in the current thread, with the
+ * given detail message.
+ */
+void dvmThrowLinkageError(const char* msg);
+
+/**
+ * Throw a NegativeArraySizeException in the current thread, with the
+ * given number as the detail message.
+ */
+extern "C" void dvmThrowNegativeArraySizeException(s4 size);
+
+/**
+ * Throw a NoClassDefFoundError in the current thread, with the
+ * human-readable form of the given descriptor as the detail message.
+ */
+extern "C" 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.
+ */
+extern "C" void dvmThrowNoSuchFieldError(const char* msg);
+
+/**
+ * Throw a NoSuchFieldException in the current thread, with the given
+ * detail message.
+ */
+void dvmThrowNoSuchFieldException(const char* msg);
+
+/**
+ * Throw a NoSuchMethodError in the current thread, with the given
+ * detail message.
+ */
+extern "C" void dvmThrowNoSuchMethodError(const char* msg);
+
+/**
+ * Throw a NullPointerException in the current thread, with the given
+ * detail message.
+ */
+extern "C" void dvmThrowNullPointerException(const char* msg);
+
+/**
+ * Throw an OutOfMemoryError in the current thread, with the given
+ * detail message.
+ */
+void dvmThrowOutOfMemoryError(const char* msg);
+
+/**
+ * Throw a RuntimeException in the current thread, with the given detail
+ * message.
+ */
+void dvmThrowRuntimeException(const char* msg);
+
+/**
+ * Throw a StaleDexCacheError in the current thread, with
+ * the given detail message.
+ */
+void dvmThrowStaleDexCacheError(const char* msg);
+
+/**
+ * Throw a StringIndexOutOfBoundsException in the current thread, with
+ * a detail message specifying an actual length as well as a requested
+ * index.
+ */
+void dvmThrowStringIndexOutOfBoundsExceptionWithIndex(jsize stringLength,
+        jsize requestIndex);
+
+/**
+ * Throw a StringIndexOutOfBoundsException in the current thread, with
+ * a detail message specifying an actual length as well as a requested
+ * region.
+ */
+void dvmThrowStringIndexOutOfBoundsExceptionWithRegion(jsize stringLength,
+        jsize requestStart, jsize requestLength);
+
+/**
+ * Throw a TypeNotPresentException in the current thread, with the
+ * human-readable form of the given descriptor as the detail message.
+ */
+void dvmThrowTypeNotPresentException(const char* descriptor);
+
+/**
+ * Throw an UnsatisfiedLinkError in the current thread, with
+ * the given detail message.
+ */
+void dvmThrowUnsatisfiedLinkError(const char* msg);
+void dvmThrowUnsatisfiedLinkError(const char* msg, const Method* method);
+
+/**
+ * Throw an UnsupportedOperationException in the current thread, with
+ * the given detail message.
+ */
+void dvmThrowUnsupportedOperationException(const char* msg);
+
+/**
+ * Throw a VerifyError in the current thread, with the
+ * human-readable form of the given descriptor as the detail message.
+ */
+void dvmThrowVerifyError(const char* descriptor);
+
+/**
+ * Throw a VirtualMachineError in the current thread, with
+ * the given detail message.
+ */
+void dvmThrowVirtualMachineError(const char* msg);
+
+#endif  // DALVIK_EXCEPTION_H_