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 + -
显示快捷键?