exception.c
来自「基于LWVCL开发的库」· C语言 代码 · 共 673 行 · 第 1/2 页
C
673 行
/* * exception.c * Handle exceptions for the interpreter or translator. * * Copyright (c) 1996, 1997 * Transvirtual Technologies, Inc. All rights reserved. * * Copyright (c) 2003 * Mark J. Wielaard <mark@klomp.org> * * Copyright (c) 2004 * Kaffe.org contributors. See ChangeLogs for details. All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file. */#if defined(HAVE_STDARG_H)#include <stdarg.h>#endif /* defined(HAVE_STDARG_H) */#include <stdio.h>#include "config.h"#include "debug.h"#include "config-std.h"#include "config-signal.h"#include "config-mem.h"#include "config-setjmp.h"#include "config-hacks.h"#include "jni_md.h"#include "gtypes.h"#include "access.h"#include "object.h"#include "constants.h"#include "md.h"#include "methodcalls.h"#include "classMethod.h"#include "code.h"#include "exception.h"#include "baseClasses.h"#include "lookup.h"#include "thread.h"#include "thread-impl.h"#include "errors.h"#include "itypes.h"#include "external.h"#include "soft.h"#include "locks.h"#include "stackTrace.h"#include "machine.h"#include "slots.h"#include "gcj/gcj.h"#include "java_lang_Throwable.h"#include "java_lang_VMThrowable.h"#if defined(INTERPRETER)static struct Hjava_lang_Object*vmExcept_getSyncObj(VmExceptHandler* eh){ assert(eh != NULL); assert(eh->meth != NULL); assert(eh->meth != VMEXCEPTHANDLER_KAFFEJNI_HANDLER); return eh->frame.intrp.syncobj;}#define FRAMEOBJECT(O, F, E) (O) = vmExcept_getSyncObj((VmExceptHandler*)(F))#endif /* INTERPRETER */static void nullException(struct _exceptionFrame *);static void floatingException(struct _exceptionFrame *);static void stackOverflowException(struct _exceptionFrame *);static void dispatchException(Hjava_lang_Throwable*, stackTraceInfo*);static bool findExceptionBlockInMethod(uintp, Hjava_lang_Class*, Method*, uintp*);boolvmExcept_isJNIFrame(VmExceptHandler* eh){ assert(eh != NULL); return (eh->meth == VMEXCEPTHANDLER_KAFFEJNI_HANDLER);}static boolvmExcept_JNIContains(VmExceptHandler* eh, JNIFrameAddress fp){ assert(eh != NULL); assert(eh->meth == VMEXCEPTHANDLER_KAFFEJNI_HANDLER); assert(fp != (JNIFrameAddress)0); return (eh->frame.jni.fp == fp);}void vmExcept_setJNIFrame(VmExceptHandler* eh, JNIFrameAddress fp){ assert(eh != NULL); eh->meth = VMEXCEPTHANDLER_KAFFEJNI_HANDLER; eh->frame.jni.fp = fp;}voidvmExcept_jumpToHandler(VmExceptHandler* frame){ JTHREAD_LONGJMP(frame->jbuf, 1);}void vmExcept_setSyncObj(VmExceptHandler* eh, struct Hjava_lang_Object* syncobj){ assert(eh != NULL); assert(eh->meth != NULL); assert(eh->meth != VMEXCEPTHANDLER_KAFFEJNI_HANDLER); eh->frame.intrp.syncobj = syncobj;}void vmExcept_setPC(volatile VmExceptHandler* eh, u4 pc){ assert(eh != NULL); assert(eh->meth != NULL); assert(eh->meth != VMEXCEPTHANDLER_KAFFEJNI_HANDLER); eh->frame.intrp.pc = pc;}u4 vmExcept_getPC(const VmExceptHandler* eh){ assert(eh != NULL); assert(eh->meth != NULL); assert(eh->meth != VMEXCEPTHANDLER_KAFFEJNI_HANDLER); return eh->frame.intrp.pc;}/* * Create an exception from error information. */Hjava_lang_Throwable*error2Throwable(errorInfo* einfo){ Hjava_lang_Throwable *err = NULL; switch (einfo->type & KERR_CODE_MASK) { case KERR_EXCEPTION: if (einfo->mess == 0 || *einfo->mess == '\0') { err = (Hjava_lang_Throwable*)execute_java_constructor( einfo->classname, NULL, NULL, "()V"); } else { err = (Hjava_lang_Throwable*)execute_java_constructor( einfo->classname, NULL, NULL, "(Ljava/lang/String;)V", checkPtr(stringC2Java(einfo->mess))); } break; case KERR_INITIALIZER_ERROR: if (strcmp(CLASS_CNAME(OBJECT_CLASS(&einfo->throwable->base)), "java/lang/ExceptionInInitializerError") != 0) { err = (Hjava_lang_Throwable*)execute_java_constructor( JAVA_LANG(ExceptionInInitializerError), NULL, NULL, "(Ljava/lang/Throwable;)V", einfo->throwable); break; } /* FALLTHRU */ case KERR_RETHROW: err = einfo->throwable; break; case KERR_OUT_OF_MEMORY: err = gc_throwOOM(); break; default: assert(!!!"Unexpected error info mask"); } discardErrorInfo(einfo); return (err);}/* * post out-of-memory condition */voidpostOutOfMemory(errorInfo *einfo){ memset(einfo, 0, sizeof(*einfo)); einfo->type = KERR_OUT_OF_MEMORY;}/* * post a simple exception using its full name without a message */voidpostException(errorInfo *einfo, const char *name){ einfo->type = KERR_EXCEPTION; einfo->classname = name; einfo->mess = ""; einfo->throwable = NULL;}voidvpostExceptionMessage(errorInfo *einfo, const char * fullname, const char * fmt, va_list args){ char *msgBuf; int msgLen; msgBuf = KMALLOC(MAX_ERROR_MESSAGE_SIZE); if (msgBuf == 0) { einfo->type = KERR_OUT_OF_MEMORY; return; }#ifdef HAVE_VSNPRINTF msgLen = vsnprintf(msgBuf, MAX_ERROR_MESSAGE_SIZE, fmt, args);#else /* XXX potential buffer overruns problem: */ msgLen = vsprintf(msgBuf, fmt, args);#endif einfo->type = KERR_EXCEPTION | KERR_FREE_MESSAGE; einfo->classname = fullname; einfo->mess = msgBuf; einfo->throwable = NULL;}/* * post a longer exception with a message using full name */voidpostExceptionMessage(errorInfo *einfo, const char * fullname, const char * fmt, ...){ va_list args; va_start(args, fmt); vpostExceptionMessage(einfo, fullname, fmt, args); va_end(args);}/* * post a NoClassDefFoundError - we handle this specially since it might * not be a fatal error (depending no where it's generated). */voidpostNoClassDefFoundError(errorInfo* einfo, const char* cname){ postExceptionMessage(einfo, JAVA_LANG(NoClassDefFoundError), "%s", cname); einfo->type |= KERR_NO_CLASS_FOUND;}/* * Check whether we threw a NoClassFoundError and if we did clear it. * We need this in code-analyse.c to avoid throwing errors when we can't find * classes but to terminate when we get real errors. */intcheckNoClassDefFoundError(errorInfo* einfo){ if (einfo->type & KERR_NO_CLASS_FOUND) { discardErrorInfo(einfo); return (1); } else { return (0); }}/* * dump error info to stderr */voiddumpErrorInfo(errorInfo *einfo UNUSED){ /* XXX */}/** * Discard the errorinfo, freeing a message if necessary * * @param einfo error info */voiddiscardErrorInfo(errorInfo *einfo){ if (einfo->type & KERR_FREE_MESSAGE) { void * message = (void *) einfo->mess; KFREE(message); einfo->type &= ~KERR_FREE_MESSAGE; }}/* * Create and throw an exception resulting from an error during VM processing. */voidthrowError(errorInfo* einfo){ Hjava_lang_Throwable* eobj = error2Throwable (einfo); throwException(eobj);}/* * Throw an exception with backtrace recomputed. * * Semantic: take stacktrace right now (overwrite whatever stacktrace * is in the exception object) and dispatch. */voidthrowException(struct Hjava_lang_Throwable* eobj){ Hjava_lang_VMThrowable* vmstate; Hjava_lang_Object* backtrace; if (eobj == 0) { dprintf("Exception thrown on null object ... aborting\n"); KAFFEVM_ABORT(); KAFFEVM_EXIT(1); } vmstate = unhand(eobj)->vmState; if (vmstate == 0) { vmstate = (Hjava_lang_VMThrowable*)newObject(javaLangVMThrowable); unhand(eobj)->vmState = vmstate; } backtrace = buildStackTrace(NULL); unhand(vmstate)->vmdata = backtrace; dispatchException(eobj, (stackTraceInfo*)backtrace);}/* * Throw an exception without altering backtrace. *
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?