Exception.h revision 74501e600dcb5634aa26aee0a3f57f2b45b213f2
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17/* 18 * Exception handling. 19 */ 20#ifndef _DALVIK_EXCEPTION 21#define _DALVIK_EXCEPTION 22 23/* initialization */ 24bool dvmExceptionStartup(void); 25void dvmExceptionShutdown(void); 26 27/* 28 * Throw an exception in the current thread, by class descriptor. 29 */ 30void dvmThrowChainedException(const char* exceptionDescriptor, const char* msg, 31 Object* cause); 32INLINE void dvmThrowException(const char* exceptionDescriptor, 33 const char* msg) 34{ 35 dvmThrowChainedException(exceptionDescriptor, msg, NULL); 36} 37 38/* 39 * Like dvmThrowChainedException, but takes printf-style args for the message. 40 */ 41void dvmThrowExceptionFmtV(const char* exceptionDescriptor, const char* fmt, 42 va_list args); 43void dvmThrowExceptionFmt(const char* exceptionDescriptor, const char* fmt, ...) 44#if defined(__GNUC__) 45 __attribute__ ((format(printf, 2, 3))) 46#endif 47 ; 48INLINE void dvmThrowExceptionFmt(const char* exceptionDescriptor, 49 const char* fmt, ...) 50{ 51 va_list args; 52 va_start(args, fmt); 53 dvmThrowExceptionFmtV(exceptionDescriptor, fmt, args); 54 va_end(args); 55} 56 57/* 58 * Throw an exception in the current thread, by class object. 59 */ 60void dvmThrowChainedExceptionByClass(ClassObject* exceptionClass, 61 const char* msg, Object* cause); 62INLINE void dvmThrowExceptionByClass(ClassObject* exceptionClass, 63 const char* msg) 64{ 65 dvmThrowChainedExceptionByClass(exceptionClass, msg, NULL); 66} 67 68/* 69 * Throw the named exception using the human-readable form of the class 70 * descriptor as the exception message, and with the specified cause. 71 */ 72void dvmThrowChainedExceptionWithClassMessage(const char* exceptionDescriptor, 73 const char* messageDescriptor, Object* cause); 74INLINE void dvmThrowExceptionWithClassMessage(const char* exceptionDescriptor, 75 const char* messageDescriptor) 76{ 77 dvmThrowChainedExceptionWithClassMessage(exceptionDescriptor, 78 messageDescriptor, NULL); 79} 80 81/* 82 * Like dvmThrowException, but take a class object instead of a name 83 * and turn the given message into the human-readable form for a descriptor. 84 */ 85void dvmThrowExceptionByClassWithClassMessage(ClassObject* exceptionClass, 86 const char* messageDescriptor); 87 88/* 89 * Return the exception being thrown in the current thread, or NULL if 90 * no exception is pending. 91 */ 92INLINE Object* dvmGetException(Thread* self) { 93 return self->exception; 94} 95 96/* 97 * Set the exception being thrown in the current thread. 98 */ 99INLINE void dvmSetException(Thread* self, Object* exception) 100{ 101 assert(exception != NULL); 102 self->exception = exception; 103} 104 105/* 106 * Clear the pending exception. 107 * 108 * (We use this rather than "set(null)" because we may need to have special 109 * fixups here for StackOverflowError stuff. Calling "clear" in the code 110 * makes it obvious.) 111 */ 112INLINE void dvmClearException(Thread* self) { 113 self->exception = NULL; 114} 115 116/* 117 * Clear the pending exception. Used by the optimization and verification 118 * code, which has to run with "initializing" set to avoid going into a 119 * death-spin if the "class not found" exception can't be found. 120 */ 121void dvmClearOptException(Thread* self); 122 123/* 124 * Returns "true" if an exception is pending. Use this if you have a 125 * "self" pointer. 126 */ 127INLINE bool dvmCheckException(Thread* self) { 128 return (self->exception != NULL); 129} 130 131/* 132 * Returns "true" if this is a "checked" exception, i.e. it's a subclass 133 * of Throwable (assumed) but not a subclass of RuntimeException or Error. 134 */ 135bool dvmIsCheckedException(const Object* exception); 136 137/* 138 * Wrap the now-pending exception in a different exception. 139 * 140 * If something fails, an (unchecked) exception related to that failure 141 * will be pending instead. 142 */ 143void dvmWrapException(const char* newExcepStr); 144 145/* 146 * Get the "cause" field from an exception. 147 * 148 * Returns NULL if the field is null or uninitialized. 149 */ 150Object* dvmGetExceptionCause(const Object* exception); 151 152/* 153 * Print the exception stack trace on stderr. Calls the exception's 154 * print function. 155 */ 156void dvmPrintExceptionStackTrace(void); 157 158/* 159 * Print the exception stack trace to the log file. The exception stack 160 * trace is computed within the VM. 161 */ 162void dvmLogExceptionStackTrace(void); 163 164/* 165 * Search for a catch block that matches "exception". 166 * 167 * "*newFrame" gets a copy of the new frame pointer. 168 * 169 * If "doUnroll" is set, we unroll "thread"s stack as we go (and update 170 * self->curFrame with the same value as in *newFrame). 171 * 172 * Returns the offset to the catch code on success, or -1 if we couldn't 173 * find a catcher. 174 */ 175int dvmFindCatchBlock(Thread* self, int relPc, Object* exception, 176 bool doUnroll, void** newFrame); 177 178/* 179 * Support for saving exception stack traces and converting them to 180 * usable form. Use the "FillIn" function to generate a compact array 181 * that represents the stack frames, then "GetStackTrace" to convert it 182 * to an array of StackTraceElement objects. 183 * 184 * Don't call the "Internal" form of the function directly. 185 */ 186void* dvmFillInStackTraceInternal(Thread* thread, bool wantObject, int* pCount); 187/* return an [I for use by interpreted code */ 188INLINE Object* dvmFillInStackTrace(Thread* thread) { 189 return (Object*) dvmFillInStackTraceInternal(thread, true, NULL); 190} 191ArrayObject* dvmGetStackTrace(const Object* stackState); 192/* return an int* and array count; caller must free() the return value */ 193INLINE int* dvmFillInStackTraceRaw(Thread* thread, int* pCount) { 194 return (int*) dvmFillInStackTraceInternal(thread, false, pCount); 195} 196ArrayObject* dvmGetStackTraceRaw(const int* intVals, int stackDepth); 197 198/* 199 * Print a formatted version of a raw stack trace to the log file. 200 */ 201void dvmLogRawStackTrace(const int* intVals, int stackDepth); 202 203/** 204 * Throw an AbstractMethodError in the current thread, with the given detail 205 * message. 206 */ 207void dvmThrowAbstractMethodError(const char* msg); 208 209/** 210 * Throw an ArithmeticException in the current thread, with the given detail 211 * message. 212 */ 213void dvmThrowArithmeticException(const char* msg); 214 215/* 216 * Throw an ArrayIndexOutOfBoundsException in the current thread, 217 * using the given index and array length in the detail message. 218 */ 219void dvmThrowArrayIndexOutOfBoundsException(int index, int length); 220 221/* 222 * Throw an ArrayStoreException in the current thread, using the given classes' 223 * names in the detail message. 224 */ 225void dvmThrowArrayStoreException(ClassObject* actual, ClassObject* desired); 226 227/** 228 * Throw a ClassCastException in the current thread, using the given classes' 229 * names in the detail message. 230 */ 231void dvmThrowClassCastException(ClassObject* actual, ClassObject* desired); 232 233/** 234 * Throw a ClassCircularityError in the current thread, with the 235 * human-readable form of the given descriptor as the detail message. 236 */ 237void dvmThrowClassCircularityError(const char* descriptor); 238 239/** 240 * Throw a ClassFormatError in the current thread, with the given 241 * detail message. 242 */ 243void dvmThrowClassFormatError(const char* msg); 244 245/** 246 * Throw a ClassNotFoundException in the current thread, with the given 247 * detail message. 248 */ 249void dvmThrowClassNotFoundException(const char* msg); 250 251/** 252 * Throw a FileNotFoundException in the current thread, with the given 253 * detail message. 254 */ 255void dvmThrowFileNotFoundException(const char* msg); 256 257/** 258 * Throw an IOException in the current thread, with the given 259 * detail message. 260 */ 261void dvmThrowIOException(const char* msg); 262 263/** 264 * Throw an IllegalAccessError in the current thread, with the 265 * given detail message. 266 */ 267void dvmThrowIllegalAccessError(const char* msg); 268 269/** 270 * Throw an IllegalAccessException in the current thread, with the 271 * given detail message. 272 */ 273void dvmThrowIllegalAccessException(const char* msg); 274 275/** 276 * Throw an IllegalArgumentException in the current thread, with the 277 * given detail message. 278 */ 279void dvmThrowIllegalArgumentException(const char* msg); 280 281/** 282 * Throw an IllegalMonitorStateException in the current thread, with 283 * the given detail message. 284 */ 285void dvmThrowIllegalMonitorStateException(const char* msg); 286 287/** 288 * Throw an IllegalStateException in the current thread, with 289 * the given detail message. 290 */ 291void dvmThrowIllegalStateException(const char* msg); 292 293/** 294 * Throw an IllegalThreadStateException in the current thread, with 295 * the given detail message. 296 */ 297void dvmThrowIllegalThreadStateException(const char* msg); 298 299/** 300 * Throw an IncompatibleClassChangeError in the current thread, 301 * the given detail message. 302 */ 303void dvmThrowIncompatibleClassChangeError(const char* msg); 304 305/** 306 * Throw an IncompatibleClassChangeError in the current thread, with the 307 * human-readable form of the given descriptor as the detail message. 308 */ 309void dvmThrowIncompatibleClassChangeErrorWithClassMessage( 310 const char* descriptor); 311 312/** 313 * Throw an InternalError in the current thread, with the given 314 * detail message. 315 */ 316void dvmThrowInternalError(const char* msg); 317 318/** 319 * Throw an InterruptedException in the current thread, with the given 320 * detail message. 321 */ 322void dvmThrowInterruptedException(const char* msg); 323 324/** 325 * Throw a LinkageError in the current thread, with the 326 * given detail message. 327 */ 328void dvmThrowLinkageError(const char* msg); 329 330/** 331 * Throw a NegativeArraySizeException in the current thread, with the 332 * given detail message. 333 */ 334void dvmThrowNegativeArraySizeException(const char* msg); 335 336/** 337 * Throw a NoClassDefFoundError in the current thread, with the 338 * human-readable form of the given descriptor as the detail message. 339 */ 340void dvmThrowNoClassDefFoundError(const char* descriptor); 341 342/** 343 * Throw a NoSuchFieldError in the current thread, with the given 344 * detail message. 345 */ 346void dvmThrowNoSuchFieldError(const char* msg); 347 348/** 349 * Throw a NoSuchFieldException in the current thread, with the given 350 * detail message. 351 */ 352void dvmThrowNoSuchFieldException(const char* msg); 353 354/** 355 * Throw a NoSuchMethodError in the current thread, with the given 356 * detail message. 357 */ 358void dvmThrowNoSuchMethodError(const char* msg); 359 360/** 361 * Throw a NullPointerException in the current thread, with the given 362 * detail message. 363 */ 364void dvmThrowNullPointerException(const char* msg); 365 366/** 367 * Throw an OutOfMemoryError in the current thread, with the given 368 * detail message. 369 */ 370void dvmThrowOutOfMemoryError(const char* msg); 371 372/** 373 * Throw a RuntimeException in the current thread, with the given detail 374 * message. 375 */ 376void dvmThrowRuntimeException(const char* msg); 377 378/** 379 * Throw a StaleDexCacheError in the current thread, with 380 * the given detail message. 381 */ 382void dvmThrowStaleDexCacheError(const char* msg); 383 384/** 385 * Throw a StringIndexOutOfBoundsException in the current thread, with 386 * the given detail message. 387 */ 388void dvmThrowStringIndexOutOfBoundsException(const char* msg); 389 390/** 391 * Throw an UnsatisfiedLinkError in the current thread, with 392 * the given detail message. 393 */ 394void dvmThrowUnsatisfiedLinkError(const char* msg); 395 396/** 397 * Throw an UnsupportedOperationException in the current thread, with 398 * the given detail message. 399 */ 400void dvmThrowUnsupportedOperationException(const char* msg); 401 402/** 403 * Throw a VirtualMachineError in the current thread, with 404 * the given detail message. 405 */ 406void dvmThrowVirtualMachineError(const char* msg); 407 408#endif /*_DALVIK_EXCEPTION*/ 409