[kaffe] Inlining BEGIN/END_EXCEPTION_HANDLING macros in jni.c (Was: Re: [kaffe] Moving away from macros to inlined functions)

Dalibor Topic robilad@kaffe.org
Sun Sep 21 09:50:04 2003


This is a multi-part message in MIME format.
--------------050400090801060402040404
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Guilhem Lavaux wrote:
> Dalibor Topic wrote:
> 
>> Hi,
>>
>> this is a simple code hygene issue: I'd like to move away from using 
>> preprocessor macros all over kaffe's C sources, to use inline 
>> functions. Since the gdb debugger has a much better time with inlines, 
>> the gcc compiler produces more useful error and warning messages, 
>> inlines can be prototyped to check for type violations, and so on.
>>
>> I'd like to start with BEGIN/END_EXCEPTION_HANDLING in jni.c and the 
>> sysdepCallMethod on arm, as that's what I'm trying to debug at the 
>> moment. Is everyone O.K. with the idea to move away from macros?
>>
>> cheers,
>> dalibor topic
> 
> 
> As far as it doesn't complicate kaffe's structure I don't see why we 
> should keep them. By the way, introducing true function calls helps the 
> programmers to keep a clean way to program. Usually macros are bad 
> used... So this should be done at a time or another. I am for it.

Seems that it not always easy to do without crashing kaffe badly. I 
tried my luck with the BEGIN/END_EXCEPTION_HANDLING macros in jni.c but 
I got only crashes during regression tests while compiling the tests:


gmake[4]: Entering directory `/tmp/topic/build/test/regression'
TestScript ../../../kaffe/test/regression/HelloWorldApp.java
testing ../../../kaffe/test/regression/HelloWorldApp.java
JAVA_SRCS=../../../kaffe/test/regression/HelloWorldApp.java
/tmp/topic/build/kaffe/kaffe/kaffe-bin -noverify at.dms.kjc.Main 
-classpath 
".:../../../kaffe/test/regression:compile_time:/HG/hiwis/topic/jars/antlrall.jar:/HG/hiwis/topic/jars/bsf.jar:/HG/hiwis/topic/jars/junit.jar::.:.:/tmp/topic/kaffe/libraries/javalib/kjc.jar::.:/tmp/topic/kaffe/libraries/javalib/kjc.jar:" 
-d . ../../../kaffe/test/regression/HelloWorldApp.java
error compiling:
Internal error: caught an unexpected exception.
Please check your CLASSPATH and your installation.
java/lang/UnsatisfiedLinkError: libio: not found
at java.lang.NativeLibrary.linkLibrary(NativeLibrary.java:native)
at java.lang.NativeLibrary.<init>(NativeLibrary.java:40)
at java.lang.Class.getClassLoader0(Class.java:native)
at java.lang.System.loadLibrary(System.java:122)
at java.io.File.<clinit>(File.java:102)
at java.lang.NativeLibrary.getLibraryNames(NativeLibrary.java:51)
at java.lang.Class.getClassLoader0(Class.java:native)
at java.lang.System.loadLibrary(System.java:122)
at java.io.FileDescriptor.<clinit>(FileDescriptor.java:77)
at java.lang.System.<clinit>(System.java:48)
at java.lang.Throwable.<clinit>(Throwable.java:403)
TestScript: line -45: 27180 Aborted 
/tmp/topic/build/kaffe/kaffe/kaffe-bin -noverify at.dms.kjc.Main 
-classpath 
".:../../../kaffe/test/regression:compile_time:/HG/hiwis/topic/jars/antlrall.jar:/HG/hiwis/topic/jars/bsf.jar:/HG/hiwis/topic/jars/junit.jar::.:.:/tmp/topic/kaffe/libraries/javalib/kjc.jar::.:/tmp/topic/kaffe/libraries/javalib/kjc.jar:" 
-d . ../../../kaffe/test/regression/HelloWorldApp.java
FAIL: HelloWorldApp.java
================================
1 of 1 tests failed
Please report to kaffe@kaffe.org
================================

the weird bit is that the compilation worked without a hitch when I ran 
the installed, compiled kaffe with the patched jni.c. I tried to figure 
out what was going on, but I kept running against a wall. So if anyone 
here has an idea, I've attached the diff to this mail for your debugging 
pleasures.

cheers,
dalibor topic

--------------050400090801060402040404
Content-Type: text/plain;
 name="jni.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="jni.diff"

Index: kaffe/kaffevm/jni.c
===================================================================
RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/jni.c,v
retrieving revision 1.94
diff -u -r1.94 jni.c
--- kaffe/kaffevm/jni.c	16 Sep 2003 19:23:37 -0000	1.94
+++ kaffe/kaffevm/jni.c	21 Sep 2003 16:32:07 -0000
@@ -104,11 +104,11 @@
  * Define how to set the frame pointer in a VmExceptHandler.
  */
 #if defined(TRANSLATOR)
-#define KAFFE_JNI_SETEXCEPTFP(ebufp) {				\
-	exceptionFrame currentFrameInfo;			\
-	FIRSTFRAME(currentFrameInfo, 0);			\
-	vmExcept_setJNIFrame(ebufp, (uintp) FPFRAME(&currentFrameInfo));\
-	}
+static inline void kaffeJNISetExceptFP(VmExceptHandler* ebufp) {
+	exceptionFrame currentFrameInfo;
+	FIRSTFRAME(currentFrameInfo, 0);
+	vmExcept_setJNIFrame(ebufp, (uintp) FPFRAME(&currentFrameInfo));
+}
 #else
 /*
  * Stack frame info isn't needed (and isn't available) in the
@@ -116,43 +116,44 @@
  * However, we have to at least tag the VmExceptHandler as
  * a JNIFrame so the stack trace code can ignore it.
  */
-#define KAFFE_JNI_SETEXCEPTFP(ebufp) {   \
-	vmExcept_setJNIFrame(ebufp, (uintp)ebufp); \
-        }
+static inline void kaffeJNISetExceptFP(VmExceptHandler* ebufp) {
+	vmExcept_setJNIFrame(ebufp, (uintp)ebufp);
+}
 #endif 
 
 
 /*
  * Define how we handle exceptions in JNI.
  *
- * Each BEGIN_EXCEPTION_HANDLING macro must be matched by an
- * END_EXCEPTION_HANDLING macro call in the same scope.  Each should
- * be used only once in a given JNI entrypoint.
+ * Each enterJNI function call must be matched by a
+ * leaveJNI function call in the same scope.  Each should
+ * be used only once in a given JNI entrypoint. Each scope
+ * has to define a VmExceptHandler for enterJNI/leaveJNI
+ * functions.
  */
-#define	BEGIN_EXCEPTION_HANDLING(X)			\
-	VmExceptHandler ebuf;				\
-	KAFFE_JNI_SETEXCEPTFP(&ebuf); 			\
-	ebuf.prev = (VmExceptHandler*)(unhand(getCurrentThread())->exceptPtr);\
-	if (JTHREAD_SETJMP(ebuf.jbuf) != 0) {		\
-		unhand(getCurrentThread())->exceptPtr = \
-		  (struct Hkaffe_util_Ptr*)ebuf.prev;	\
-		return X;				\
-	}						\
-	unhand(getCurrentThread())->exceptPtr = (void *) &ebuf
-
-#define	BEGIN_EXCEPTION_HANDLING_VOID()			\
-	VmExceptHandler ebuf; 				\
-	KAFFE_JNI_SETEXCEPTFP(&ebuf); 			\
-	ebuf.prev = (VmExceptHandler*)(unhand(getCurrentThread())->exceptPtr);\
-	if (JTHREAD_SETJMP(ebuf.jbuf) != 0) {		\
-		unhand(getCurrentThread())->exceptPtr = \
-		  (struct Hkaffe_util_Ptr*)ebuf.prev;	\
-		return;					\
-	}						\
-	unhand(getCurrentThread())->exceptPtr = (void *) &ebuf
 
-#define	END_EXCEPTION_HANDLING()			\
-	unhand(getCurrentThread())->exceptPtr = (void *) ebuf.prev
+/* Prepare JNI for exception handling.
+ *
+ * @return true if an exception occurred, false otherwise.
+ */
+static inline bool enterJNI(VmExceptHandler* ebuf) {
+	kaffeJNISetExceptFP(ebuf);		
+	ebuf->prev = (VmExceptHandler*)(unhand(getCurrentThread())->exceptPtr);
+	if (JTHREAD_SETJMP(ebuf->jbuf) != 0) {		
+		unhand(getCurrentThread())->exceptPtr = 
+		  (struct Hkaffe_util_Ptr*)ebuf->prev;	
+		return true;		
+	}						
+	unhand(getCurrentThread())->exceptPtr = (void *) ebuf;
+
+	return false;
+}
+
+/* Cleanup JNI exception handling.
+ */
+static inline void leaveJNI(VmExceptHandler* ebuf) {
+	unhand(getCurrentThread())->exceptPtr = (void *) ebuf->prev;
+}
 
 /*
  * Get and set fields.
@@ -309,7 +310,7 @@
 static jref
 Kaffe_NewGlobalRef(JNIEnv* env, jref obj)
 {
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 	if (!gc_add_ref(obj)) {
 		errorInfo info;
 		postOutOfMemory(&info);
@@ -326,7 +327,7 @@
 		jvmpiPostEvent(&ev);
 	}
 #endif
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return obj;
 }
 
@@ -337,7 +338,7 @@
 	classFile hand;
 	errorInfo info;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	classFileInit(&hand, buf, len, CP_BYTEARRAY);
 
@@ -351,7 +352,7 @@
 		postError(env, &info);
 	}
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (cls);
 }
 
@@ -368,7 +369,7 @@
 	Utf8Const* utf8;
 	jvalue retval;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	/* We accepts slashes, but Class.forName() does not */
 	utf8 = checkPtr(utf8ConstNew(name, -1));
@@ -381,7 +382,7 @@
 	    "forName", "(Ljava/lang/String;)Ljava/lang/Class;", nameString);
 
 	ADD_REF(retval.l);
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.l);
 }
 
@@ -390,11 +391,11 @@
 {
 	jclass ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	ret = ((Hjava_lang_Class*)cls)->superclass;
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -403,7 +404,7 @@
 {
 	jbool ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (instanceof(cls2, cls1) != 0) {
 		ret = JNI_TRUE;
@@ -411,14 +412,14 @@
 	else {
 		ret = JNI_FALSE;
 	}
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
 static jint
 Kaffe_Throw(JNIEnv* env, jobject obj)
 {
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if( obj )
 	{
@@ -433,7 +434,7 @@
 			unhand(getCurrentThread())->outOfMemoryError;
 	}
 	
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (0);
 }
 
@@ -442,7 +443,7 @@
 {
 	Hjava_lang_Object* eobj;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	eobj = execute_java_constructor(NULL, NULL, cls,
 					"(Ljava/lang/String;)V",
@@ -450,7 +451,7 @@
 
 	unhand(getCurrentThread())->exceptObj = (struct Hjava_lang_Throwable*)eobj;
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (0);
 }
 
@@ -459,12 +460,12 @@
 {
 	jobject obj;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	obj = unhand(getCurrentThread())->exceptObj;
 
 	ADD_REF(obj);
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (obj);
 }
 
@@ -474,34 +475,34 @@
 	jboolean result;
 	jobject obj;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	obj = unhand(getCurrentThread())->exceptObj;
 	result = (obj == NULL) ? JNI_FALSE : JNI_TRUE;
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (result);
 }
 
 static void
 Kaffe_ExceptionDescribe(JNIEnv* env)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (unhand(getCurrentThread())->exceptObj != 0) {
 		do_execute_java_method(unhand(getCurrentThread())->exceptObj, "printStackTrace", "()V", 0, 0, unhand(getCurrentThread())->exceptObj); 
 	}
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_ExceptionClear(JNIEnv* env)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	unhand(getCurrentThread())->exceptObj = 0;
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static jobject
@@ -510,7 +511,7 @@
 	jobject obj;
 	Hjava_lang_Class* clazz;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	clazz = (Hjava_lang_Class*)cls;
 
@@ -520,7 +521,7 @@
 	obj = newObject(clazz);
 
 	ADD_REF(obj);
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (obj);
 }
 
@@ -532,7 +533,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	clazz = (Hjava_lang_Class*)cls;
 
@@ -544,7 +545,7 @@
 	callMethodV(m, METHOD_INDIRECTMETHOD(m), obj, args, &retval);
 
 	ADD_REF(obj);
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (obj);
 }
 
@@ -554,13 +555,13 @@
 	jobject obj;
 	va_list args;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	obj = Kaffe_NewObjectV(env, cls, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (obj);
 }
 
@@ -572,7 +573,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	clazz = (Hjava_lang_Class*)cls;
 
@@ -584,7 +585,7 @@
 	callMethodA(m, METHOD_INDIRECTMETHOD(m), obj, args, &retval, 0);
 
 	ADD_REF(obj);
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (obj);
 }
 
@@ -593,11 +594,11 @@
 {
 	jclass cls;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	cls = ((Hjava_lang_Object*)obj)->dtable->class;
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (cls);
 }
 
@@ -606,7 +607,7 @@
 {
 	jbool ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (soft_instanceof((Hjava_lang_Class*)cls, (Hjava_lang_Object*)obj) != 0) {
 		ret = JNI_TRUE;
@@ -615,7 +616,7 @@
 		ret = JNI_FALSE;
 	}
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -625,7 +626,7 @@
 	Method* meth;
 	errorInfo info;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 	meth = lookupClassMethod((Hjava_lang_Class*)cls, (char*)name, (char*)sig, &info);
 	if (meth == 0) {
 		postError(env, &info);
@@ -635,7 +636,7 @@
 		postError(env, &info);
 		meth = 0;
 	}
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	
 	return (meth);
 }
@@ -647,7 +648,7 @@
 	Hjava_lang_Object* o = (Hjava_lang_Object*)obj;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -656,7 +657,7 @@
 	callMethodV(m, getMethodFunc (m, o), obj, args, &retval);
 
 	ADD_REF(retval.l);
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.l);
 }
 
@@ -666,13 +667,13 @@
 	va_list args;
 	jobject ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	ret = Kaffe_CallObjectMethodV(env, obj, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -683,7 +684,7 @@
 	Hjava_lang_Object* o = (Hjava_lang_Object*)obj;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -691,7 +692,7 @@
 
 	callMethodA(m, getMethodFunc (m, o), obj, args, &retval, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.l);
 }
 
@@ -702,7 +703,7 @@
 	Hjava_lang_Object* o = (Hjava_lang_Object*)obj;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -710,7 +711,7 @@
 
 	callMethodV(m, getMethodFunc (m, o), obj, args, &retval);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return ((jboolean) retval.i);
 }
 
@@ -720,13 +721,13 @@
 	va_list args;
 	jboolean ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	ret = Kaffe_CallBooleanMethodV(env, obj, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -737,7 +738,7 @@
 	Hjava_lang_Object* o = (Hjava_lang_Object*)obj;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -745,7 +746,7 @@
 
 	callMethodA(m, getMethodFunc (m, o), obj, args, &retval, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return ((jboolean) retval.i);
 }
 
@@ -756,7 +757,7 @@
 	Hjava_lang_Object* o = (Hjava_lang_Object*)obj;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -764,7 +765,7 @@
 
 	callMethodV(m, getMethodFunc (m, o), obj, args, &retval);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return ((jbyte) retval.i);
 }
 
@@ -774,13 +775,13 @@
 	va_list args;
 	jbyte ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	ret = Kaffe_CallByteMethodV(env, obj, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -791,7 +792,7 @@
 	Hjava_lang_Object* o = (Hjava_lang_Object*)obj;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -799,7 +800,7 @@
 
 	callMethodA(m, getMethodFunc (m, o), obj, args, &retval, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return ((jbyte) retval.i);
 }
 
@@ -810,7 +811,7 @@
 	Hjava_lang_Object* o = (Hjava_lang_Object*)obj;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -818,7 +819,7 @@
 
 	callMethodV(m, getMethodFunc (m, o), obj, args, &retval);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return ((jchar) retval.i);
 }
 
@@ -828,13 +829,13 @@
 	va_list args;
 	jchar ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	ret = Kaffe_CallCharMethodV(env, obj, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -845,7 +846,7 @@
 	Hjava_lang_Object* o = (Hjava_lang_Object*)obj;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -853,7 +854,7 @@
 
 	callMethodA(m, getMethodFunc (m, o), obj, args, &retval, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return ((jchar) retval.i);
 }
 
@@ -864,7 +865,7 @@
 	Hjava_lang_Object* o = (Hjava_lang_Object*)obj;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -872,7 +873,7 @@
 
 	callMethodV(m, getMethodFunc (m, o), obj, args, &retval);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return ((jshort) retval.i);
 }
 
@@ -882,13 +883,13 @@
 	va_list args;
 	jshort ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	ret = Kaffe_CallShortMethodV(env, obj, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -899,7 +900,7 @@
 	Hjava_lang_Object* o = (Hjava_lang_Object*)obj;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -907,7 +908,7 @@
 
 	callMethodA(m, getMethodFunc (m, o), obj, args, &retval, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return ((jshort) retval.i);
 }
 
@@ -918,7 +919,7 @@
 	Hjava_lang_Object* o = (Hjava_lang_Object*)obj;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -926,7 +927,7 @@
 
 	callMethodV(m, getMethodFunc (m, o), obj, args, &retval);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.i);
 }
 
@@ -936,13 +937,13 @@
 	va_list args;
 	jint ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	ret = Kaffe_CallIntMethodV(env, obj, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -953,7 +954,7 @@
 	Hjava_lang_Object* o = (Hjava_lang_Object*)obj;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -961,7 +962,7 @@
 
 	callMethodA(m, getMethodFunc (m, o), obj, args, &retval, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.i);
 }
 
@@ -972,7 +973,7 @@
 	Hjava_lang_Object* o = (Hjava_lang_Object*)obj;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -980,7 +981,7 @@
 
 	callMethodV(m, getMethodFunc (m, o), obj, args, &retval);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.j);
 }
 
@@ -990,13 +991,13 @@
 	va_list args;
 	jlong ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	ret = Kaffe_CallLongMethodV(env, obj, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -1007,7 +1008,7 @@
 	Hjava_lang_Object* o = (Hjava_lang_Object*)obj;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1015,7 +1016,7 @@
 
 	callMethodA(m, getMethodFunc (m, o), obj, args, &retval, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.j);
 }
 
@@ -1026,7 +1027,7 @@
 	Hjava_lang_Object* o = (Hjava_lang_Object*)obj;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1034,7 +1035,7 @@
 
 	callMethodV(m, getMethodFunc (m, o), obj, args, &retval);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.f);
 }
 
@@ -1044,13 +1045,13 @@
 	va_list args;
 	jfloat ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	ret = Kaffe_CallFloatMethodV(env, obj, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -1061,7 +1062,7 @@
 	Hjava_lang_Object* o = (Hjava_lang_Object*)obj;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1069,7 +1070,7 @@
 
 	callMethodA(m, getMethodFunc (m, o), obj, args, &retval, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.f);
 }
 
@@ -1080,7 +1081,7 @@
 	Hjava_lang_Object* o = (Hjava_lang_Object*)obj;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1088,7 +1089,7 @@
 
 	callMethodV(m, getMethodFunc (m, o), obj, args, &retval);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.d);
 }
 
@@ -1098,13 +1099,13 @@
 	va_list args;
 	jdouble ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	ret = Kaffe_CallDoubleMethodV(env, obj, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -1115,7 +1116,7 @@
 	Hjava_lang_Object* o = (Hjava_lang_Object*)obj;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1123,7 +1124,7 @@
 
 	callMethodA(m, getMethodFunc (m, o), obj, args, &retval, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.d);
 }
 
@@ -1133,7 +1134,7 @@
 	Hjava_lang_Object* o = (Hjava_lang_Object*)obj;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1141,7 +1142,7 @@
 
 	callMethodV(m, getMethodFunc (m, o), obj, args, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
@@ -1149,13 +1150,13 @@
 {
 	va_list args;
 
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	va_start(args, meth);
 	Kaffe_CallVoidMethodV(env, obj, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
@@ -1164,7 +1165,7 @@
 	Hjava_lang_Object* o = (Hjava_lang_Object*)obj;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1172,7 +1173,7 @@
 
 	callMethodA(m, getMethodFunc (m, o), obj, args, 0, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static jobject
@@ -1181,7 +1182,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1190,7 +1191,7 @@
 	callMethodV(m, METHOD_INDIRECTMETHOD(m), obj, args, &retval);
 
 	ADD_REF(retval.l);
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.l);
 }
 
@@ -1200,13 +1201,13 @@
 	va_list args;
 	jobject ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	ret = Kaffe_CallNonvirtualObjectMethodV(env, obj, cls, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -1216,7 +1217,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1225,7 +1226,7 @@
 	callMethodA(m, METHOD_INDIRECTMETHOD(m), obj, args, &retval, 0);
 
 	ADD_REF(retval.l);
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.l);
 }
 
@@ -1235,7 +1236,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1243,7 +1244,7 @@
 
 	callMethodV(m, METHOD_INDIRECTMETHOD(m), obj, args, &retval);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return ((jboolean) retval.i);
 }
 
@@ -1253,13 +1254,13 @@
 	va_list args;
 	jboolean ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	ret = Kaffe_CallNonvirtualBooleanMethodV(env, obj, cls, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -1269,7 +1270,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1277,7 +1278,7 @@
 
 	callMethodA(m, METHOD_INDIRECTMETHOD(m), obj, args, &retval, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return ((jboolean) retval.i);
 }
 
@@ -1287,7 +1288,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1295,7 +1296,7 @@
 
 	callMethodV(m, METHOD_INDIRECTMETHOD(m), obj, args, &retval);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return ((jbyte) retval.i);
 }
 
@@ -1305,13 +1306,13 @@
 	va_list args;
 	jbyte ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	ret = Kaffe_CallNonvirtualByteMethodV(env, obj, cls, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -1321,7 +1322,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1329,7 +1330,7 @@
 
 	callMethodA(m, METHOD_INDIRECTMETHOD(m), obj, args, &retval, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return ((jbyte) retval.i);
 }
 
@@ -1339,7 +1340,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1347,7 +1348,7 @@
 
 	callMethodV(m, METHOD_INDIRECTMETHOD(m), obj, args, &retval);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return ((jchar) retval.i);
 }
 
@@ -1357,13 +1358,13 @@
 	va_list args;
 	jchar ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	ret = Kaffe_CallNonvirtualCharMethodV(env, obj, cls, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -1373,7 +1374,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1381,7 +1382,7 @@
 
 	callMethodA(m, METHOD_INDIRECTMETHOD(m), obj, args, &retval, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return ((jchar) retval.i);
 }
 
@@ -1391,7 +1392,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1399,7 +1400,7 @@
 
 	callMethodV(m, METHOD_INDIRECTMETHOD(m), obj, args, &retval);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return ((jshort) retval.i);
 }
 
@@ -1409,13 +1410,13 @@
 	va_list args;
 	jshort ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	ret = Kaffe_CallNonvirtualShortMethodV(env, obj, cls, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -1425,7 +1426,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1433,7 +1434,7 @@
 
 	callMethodA(m, METHOD_INDIRECTMETHOD(m), obj, args, &retval, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return ((jshort) retval.i);
 }
 
@@ -1443,7 +1444,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1451,7 +1452,7 @@
 
 	callMethodV(m, METHOD_INDIRECTMETHOD(m), obj, args, &retval);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.i);
 }
 
@@ -1461,13 +1462,13 @@
 	va_list args;
 	jint ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	ret = Kaffe_CallNonvirtualIntMethodV(env, obj, cls, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -1477,7 +1478,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1485,7 +1486,7 @@
 
 	callMethodA(m, METHOD_INDIRECTMETHOD(m), obj, args, &retval, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.i);
 }
 
@@ -1495,7 +1496,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1503,7 +1504,7 @@
 
 	callMethodV(m, METHOD_INDIRECTMETHOD(m), obj, args, &retval);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.j);
 }
 
@@ -1513,13 +1514,13 @@
 	va_list args;
 	jlong ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	ret = Kaffe_CallNonvirtualLongMethodV(env, obj, cls, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -1529,7 +1530,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1537,7 +1538,7 @@
 
 	callMethodA(m, METHOD_INDIRECTMETHOD(m), obj, args, &retval, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.j);
 }
 
@@ -1547,7 +1548,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1555,7 +1556,7 @@
 
 	callMethodV(m, METHOD_INDIRECTMETHOD(m), obj, args, &retval);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.f);
 }
 
@@ -1565,13 +1566,13 @@
 	va_list args;
 	jfloat ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	ret = Kaffe_CallNonvirtualFloatMethodV(env, obj, cls, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -1581,7 +1582,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1589,7 +1590,7 @@
 
 	callMethodA(m, METHOD_INDIRECTMETHOD(m), obj, args, &retval, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.f);
 }
 
@@ -1599,7 +1600,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1607,7 +1608,7 @@
 
 	callMethodV(m, METHOD_INDIRECTMETHOD(m), obj, args, &retval);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.d);
 }
 
@@ -1617,13 +1618,13 @@
 	va_list args;
 	jdouble ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	ret = Kaffe_CallNonvirtualDoubleMethodV(env, obj, cls, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -1633,7 +1634,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1641,7 +1642,7 @@
 
 	callMethodA(m, METHOD_INDIRECTMETHOD(m), obj, args, &retval, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.d);
 }
 
@@ -1650,7 +1651,7 @@
 {
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1658,7 +1659,7 @@
 
 	callMethodV(m, METHOD_INDIRECTMETHOD(m), obj, args, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
@@ -1666,13 +1667,13 @@
 {
 	va_list args;
 
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	va_start(args, meth);
 	Kaffe_CallNonvirtualVoidMethodV(env, obj, cls, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
@@ -1680,7 +1681,7 @@
 {
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1688,7 +1689,7 @@
 
 	callMethodA(m, METHOD_INDIRECTMETHOD(m), obj, args, 0, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static jfieldID
@@ -1698,14 +1699,14 @@
 	errorInfo info;
 	Utf8Const* utf8;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 	utf8 = checkPtr(utf8ConstNew(name, -1));
 	fld = lookupClassField((Hjava_lang_Class*)cls, utf8, false, &info);
 	utf8ConstRelease(utf8);
 	if (fld == NULL) {
 		postError(env, &info);
 	}
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (fld);
 }
 
@@ -1714,12 +1715,12 @@
 {
 	jobject nobj;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	nobj = GET_FIELD(jobject, obj, fld);
 
 	ADD_REF(nobj);
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (nobj);
 }
 
@@ -1728,11 +1729,11 @@
 {
 	jboolean ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	ret = GET_FIELD(jboolean, obj, fld);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -1740,11 +1741,11 @@
 Kaffe_GetByteField(JNIEnv* env, jobject obj, jfieldID fld)
 {
 	jbyte ret;
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	ret = GET_FIELD(jbyte, obj, fld);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -1752,11 +1753,11 @@
 Kaffe_GetCharField(JNIEnv* env, jobject obj, jfieldID fld)
 {
 	jchar ret;
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	ret = GET_FIELD(jchar, obj, fld);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -1764,11 +1765,11 @@
 Kaffe_GetShortField(JNIEnv* env, jobject obj, jfieldID fld)
 {
 	jshort ret;
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	ret = GET_FIELD(jshort, obj, fld);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -1776,11 +1777,11 @@
 Kaffe_GetIntField(JNIEnv* env, jobject obj, jfieldID fld)
 {
 	jint ret;
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	ret = GET_FIELD(jint, obj, fld);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -1788,11 +1789,11 @@
 Kaffe_GetLongField(JNIEnv* env, jobject obj, jfieldID fld)
 {
 	jlong ret;
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	ret = GET_FIELD(jlong, obj, fld);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -1800,11 +1801,11 @@
 Kaffe_GetFloatField(JNIEnv* env, jobject obj, jfieldID fld)
 {
 	jfloat ret;
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	ret = GET_FIELD(jfloat, obj, fld);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -1812,102 +1813,102 @@
 Kaffe_GetDoubleField(JNIEnv* env, jobject obj, jfieldID fld)
 {
 	jdouble ret;
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	ret = GET_FIELD(jdouble, obj, fld);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
 static void
 Kaffe_SetObjectField(JNIEnv* env, jobject obj, jfieldID fld, jobject val)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	SET_FIELD(jobject, obj, fld, val);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_SetBooleanField(JNIEnv* env, jobject obj, jfieldID fld, jbool val)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	SET_FIELD(jboolean, obj, fld, val);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_SetByteField(JNIEnv* env, jobject obj, jfieldID fld, jbyte val)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	SET_FIELD(jbyte, obj, fld, val);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_SetCharField(JNIEnv* env, jobject obj, jfieldID fld, jchar val)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	SET_FIELD(jchar, obj, fld, val);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_SetShortField(JNIEnv* env, jobject obj, jfieldID fld, jshort val)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	SET_FIELD(jshort, obj, fld, val);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_SetIntField(JNIEnv* env, jobject obj, jfieldID fld, jint val)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	SET_FIELD(jint, obj, fld, val);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_SetLongField(JNIEnv* env, jobject obj, jfieldID fld, jlong val)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	SET_FIELD(jlong, obj, fld, val);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_SetFloatField(JNIEnv* env, jobject obj, jfieldID fld, jfloat val)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	SET_FIELD(jfloat, obj, fld, val);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_SetDoubleField(JNIEnv* env, jobject obj, jfieldID fld, jdouble val)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	SET_FIELD(jdouble, obj, fld, val);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static jmethodID
@@ -1916,7 +1917,7 @@
 	Method* meth;
 	errorInfo info;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 	meth = lookupClassMethod((Hjava_lang_Class*)cls, (char*)name, (char*)sig, &info);
 	if (meth == 0) {
 		postError(env, &info);
@@ -1925,7 +1926,7 @@
 		postError(env, &info);
 		meth = 0;
 	}
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 
 	return (meth);
 }
@@ -1936,7 +1937,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (!METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1945,7 +1946,7 @@
 	callMethodV(m, METHOD_INDIRECTMETHOD(m), 0, args, &retval);
 
 	ADD_REF(retval.l);
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.l);
 }
 
@@ -1955,13 +1956,13 @@
 	va_list args;
 	jobject ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	ret = Kaffe_CallStaticObjectMethodV(env, cls, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -1971,7 +1972,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (!METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1980,7 +1981,7 @@
 	callMethodA(m, METHOD_INDIRECTMETHOD(m), 0, args, &retval, 0);
 
 	ADD_REF(retval.l);
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.l);
 }
 
@@ -1990,7 +1991,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (!METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -1998,7 +1999,7 @@
 
 	callMethodV(m, METHOD_INDIRECTMETHOD(m), 0, args, &retval);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return ((jboolean) retval.i);
 }
 
@@ -2008,13 +2009,13 @@
 	va_list args;
 	jboolean ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	ret = Kaffe_CallStaticBooleanMethodV(env, cls, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -2024,7 +2025,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (!METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -2032,7 +2033,7 @@
 
 	callMethodA(m, METHOD_INDIRECTMETHOD(m), 0, args, &retval, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return ((jboolean) retval.i);
 }
 
@@ -2042,7 +2043,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (!METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -2050,7 +2051,7 @@
 
 	callMethodV(m, METHOD_INDIRECTMETHOD(m), 0, args, &retval);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return ((jbyte) retval.i);
 }
 
@@ -2060,13 +2061,13 @@
 	va_list args;
 	jbyte ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	ret = Kaffe_CallStaticByteMethodV(env, cls, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -2076,7 +2077,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (!METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -2084,7 +2085,7 @@
 
 	callMethodA(m, METHOD_INDIRECTMETHOD(m), 0, args, &retval, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return ((jbyte) retval.i);
 }
 
@@ -2094,7 +2095,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (!METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -2102,7 +2103,7 @@
 
 	callMethodV(m, METHOD_INDIRECTMETHOD(m), 0, args, &retval);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return ((jchar) retval.i);
 }
 
@@ -2112,13 +2113,13 @@
 	va_list args;
 	jchar ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	ret = Kaffe_CallStaticCharMethodV(env, cls, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -2128,7 +2129,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (!METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -2136,7 +2137,7 @@
 
 	callMethodA(m, METHOD_INDIRECTMETHOD(m), 0, args, &retval, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return ((jchar) retval.i);
 }
 
@@ -2146,7 +2147,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (!METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -2154,7 +2155,7 @@
 
 	callMethodV(m, METHOD_INDIRECTMETHOD(m), 0, args, &retval);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return ((jshort) retval.i);
 }
 
@@ -2164,13 +2165,13 @@
 	va_list args;
 	jshort ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	ret = Kaffe_CallStaticShortMethodV(env, cls, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -2180,7 +2181,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (!METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -2188,7 +2189,7 @@
 
 	callMethodA(m, METHOD_INDIRECTMETHOD(m), 0, args, &retval, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return ((jshort) retval.i);
 }
 
@@ -2198,7 +2199,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (!METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -2206,7 +2207,7 @@
 
 	callMethodV(m, METHOD_INDIRECTMETHOD(m), 0, args, &retval);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.i);
 }
 
@@ -2216,13 +2217,13 @@
 	va_list args;
 	jint ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	ret = Kaffe_CallStaticIntMethodV(env, cls, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -2232,7 +2233,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (!METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -2240,7 +2241,7 @@
 
 	callMethodA(m, METHOD_INDIRECTMETHOD(m), 0, args, &retval, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.i);
 }
 
@@ -2250,7 +2251,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (!METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -2258,7 +2259,7 @@
 
 	callMethodV(m, METHOD_INDIRECTMETHOD(m), 0, args, &retval);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.j);
 }
 
@@ -2268,13 +2269,13 @@
 	va_list args;
 	jlong ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	ret = Kaffe_CallStaticLongMethodV(env, cls, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -2284,7 +2285,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (!METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -2292,7 +2293,7 @@
 
 	callMethodA(m, METHOD_INDIRECTMETHOD(m), 0, args, &retval, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.j);
 }
 
@@ -2302,7 +2303,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (!METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -2310,7 +2311,7 @@
 
 	callMethodV(m, METHOD_INDIRECTMETHOD(m), 0, args, &retval);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.f);
 }
 
@@ -2320,13 +2321,13 @@
 	va_list args;
 	jfloat ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	ret = Kaffe_CallStaticFloatMethodV(env, cls, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -2336,7 +2337,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (!METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -2344,7 +2345,7 @@
 
 	callMethodA(m, METHOD_INDIRECTMETHOD(m), 0, args, &retval, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.f);
 }
 
@@ -2354,7 +2355,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (!METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -2362,7 +2363,7 @@
 
 	callMethodV(m, METHOD_INDIRECTMETHOD(m), 0, args, &retval);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.d);
 }
 
@@ -2372,13 +2373,13 @@
 	va_list args;
 	jdouble ret;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	va_start(args, meth);
 	ret = Kaffe_CallStaticDoubleMethodV(env, cls, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -2388,7 +2389,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (!METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -2396,7 +2397,7 @@
 
 	callMethodA(m, METHOD_INDIRECTMETHOD(m), 0, args, &retval, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (retval.d);
 }
 
@@ -2406,7 +2407,7 @@
 	jvalue retval;
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (!METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -2414,7 +2415,7 @@
 
 	callMethodV(m, METHOD_INDIRECTMETHOD(m), 0, args, &retval);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
@@ -2422,13 +2423,13 @@
 {
 	va_list args;
 
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	va_start(args, meth);
 	Kaffe_CallStaticVoidMethodV(env, cls, meth, args);
 	va_end(args);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
@@ -2436,7 +2437,7 @@
 {
 	Method* m = (Method*)meth;
 
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (!METHOD_IS_STATIC(m)) {
 		throwException(NoSuchMethodError(m->name->data));
@@ -2444,7 +2445,7 @@
 
 	callMethodA(m, METHOD_INDIRECTMETHOD(m), 0, args, 0, 0);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static jfieldID
@@ -2454,14 +2455,14 @@
 	errorInfo info;
 	Utf8Const* utf8;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 	utf8 = checkPtr(utf8ConstNew(name, -1));
 	fld = lookupClassField((Hjava_lang_Class*)cls, utf8, true, &info);
 	utf8ConstRelease(utf8);
 	if (fld == NULL) {
 		postError(env, &info);
 	}
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 
 	return (fld);
 }
@@ -2471,12 +2472,12 @@
 {
 	jobject obj;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	obj = GET_STATIC_FIELD(jobject, fld);
 
 	ADD_REF(obj);
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (obj);
 }
 
@@ -2484,11 +2485,11 @@
 Kaffe_GetStaticBooleanField(JNIEnv* env, jclass cls, jfieldID fld)
 {
 	jboolean ret;
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	ret = GET_STATIC_FIELD(jboolean, fld);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -2496,11 +2497,11 @@
 Kaffe_GetStaticByteField(JNIEnv* env, jclass cls, jfieldID fld)
 {
 	jbyte ret;
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	ret = GET_STATIC_FIELD(jbyte, fld);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -2508,11 +2509,11 @@
 Kaffe_GetStaticCharField(JNIEnv* env, jclass cls, jfieldID fld)
 {
 	jchar ret;
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	ret = GET_STATIC_FIELD(jchar, fld);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -2520,11 +2521,11 @@
 Kaffe_GetStaticShortField(JNIEnv* env, jclass cls, jfieldID fld)
 {
 	jint ret;
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	ret = GET_STATIC_FIELD(jshort, fld);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -2532,11 +2533,11 @@
 Kaffe_GetStaticIntField(JNIEnv* env, jclass cls, jfieldID fld)
 {
 	jint ret;
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	ret = GET_STATIC_FIELD(jint, fld);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -2544,11 +2545,11 @@
 Kaffe_GetStaticLongField(JNIEnv* env, jclass cls, jfieldID fld)
 {
 	jlong ret;
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	ret = GET_STATIC_FIELD(jlong, fld);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -2556,11 +2557,11 @@
 Kaffe_GetStaticFloatField(JNIEnv* env, jclass cls, jfieldID fld)
 {
 	jfloat ret;
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	ret = GET_STATIC_FIELD(jfloat, fld);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -2568,102 +2569,102 @@
 Kaffe_GetStaticDoubleField(JNIEnv* env, jclass cls, jfieldID fld)
 {
 	jdouble ret;
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	ret = GET_STATIC_FIELD(jdouble, fld);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
 static void
 Kaffe_SetStaticObjectField(JNIEnv* env, jclass cls, jfieldID fld, jobject val)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	SET_STATIC_FIELD(jobject, fld, val);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_SetStaticBooleanField(JNIEnv* env, jclass cls, jfieldID fld, jbool val)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	SET_STATIC_FIELD(jboolean, fld, val);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_SetStaticByteField(JNIEnv* env, jclass cls, jfieldID fld, jbyte val)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	SET_STATIC_FIELD(jbyte, fld, val);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_SetStaticCharField(JNIEnv* env, jclass cls, jfieldID fld, jchar val)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	SET_STATIC_FIELD(jchar, fld, val);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_SetStaticShortField(JNIEnv* env, jclass cls, jfieldID fld, jshort val)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	SET_STATIC_FIELD(jshort, fld, val);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_SetStaticIntField(JNIEnv* env, jclass cls, jfieldID fld, jint val)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	SET_STATIC_FIELD(jint, fld, val);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_SetStaticLongField(JNIEnv* env, jclass cls, jfieldID fld, jlong val)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	SET_STATIC_FIELD(jlong, fld, val);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_SetStaticFloatField(JNIEnv* env, jclass cls, jfieldID fld, jfloat val)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	SET_STATIC_FIELD(jfloat, fld, val);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_SetStaticDoubleField(JNIEnv* env, jclass cls, jfieldID fld, jdouble val)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	SET_STATIC_FIELD(jdouble, fld, val);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static jstring
@@ -2671,7 +2672,7 @@
 {
 	Hjava_lang_String* str;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	str = (Hjava_lang_String*)newObject(StringClass);
 	unhand(str)->offset = 0;
@@ -2680,7 +2681,7 @@
 	unhand(str)->interned = 0;
 	memcpy(STRING_DATA(str), data, len * sizeof(jchar));
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (str);
 }
 
@@ -2688,10 +2689,10 @@
 Kaffe_GetStringLength(JNIEnv* env, jstring data)
 {
 	jsize ret;
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	ret = STRING_SIZE((Hjava_lang_String*)data);
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -2699,14 +2700,14 @@
 Kaffe_GetStringChars(JNIEnv* env, jstring data, jboolean* copy)
 {
 	jchar* ret;
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (copy != NULL) {
 		*copy = JNI_FALSE;
 	}
 	ret = STRING_DATA(((Hjava_lang_String*)data));
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -2717,7 +2718,7 @@
 	Utf8Const* utf8;
 	int len;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	len = strlen(data);
 	if (!utf8ConstIsValidUtf8(data, len)) {
@@ -2733,7 +2734,7 @@
 		}
 	}
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (str);
 }
 
@@ -2746,7 +2747,7 @@
 	jsize count;
 	jsize i;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	ptr = STRING_DATA(str);
 	len = STRING_SIZE(str);
@@ -2764,7 +2765,7 @@
 		}
 	}
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (count);
 }
 
@@ -2778,7 +2779,7 @@
 	jsize i;
 	jsize j;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	/* We always copy data */
 	if (copy != NULL) {
@@ -2805,29 +2806,29 @@
 		}
 	}
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (buf);
 }
 
 static void
 Kaffe_ReleaseStringUTFChars(JNIEnv* env, jstring data, const jbyte* chars)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	KFREE(chars);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static jsize
 Kaffe_GetArrayLength(JNIEnv* env, jarray arr)
 {
 	jsize ret;
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	ret = obj_length((HArrayOfObject*)arr);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -2837,7 +2838,7 @@
 	HArrayOfObject* obj;
 	int i;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	obj = (HArrayOfObject*)newArray((Hjava_lang_Class*)cls, len);
 
@@ -2847,7 +2848,7 @@
 	}
 
 	ADD_REF(obj);
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (obj);
 }
 
@@ -2856,7 +2857,7 @@
 {
 	jobject obj;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (elem >= obj_length((HArrayOfObject*)arr)) {
 		throwException(ArrayIndexOutOfBoundsException);
@@ -2864,21 +2865,21 @@
 	obj = unhand_array((HArrayOfObject*)arr)->body[elem];
 
 	ADD_REF(obj);
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (obj);
 }
 
 static void
 Kaffe_SetObjectArrayElement(JNIEnv* env, jobjectArray arr, jsize elem, jobject val)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (elem >= obj_length((HArrayOfObject*)arr)) {
 		throwException(ArrayIndexOutOfBoundsException);
 	}
 	unhand_array((HArrayOfObject*)arr)->body[elem] = (Hjava_lang_Object*)val;
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static jbooleanArray
@@ -2886,12 +2887,12 @@
 {
 	jbooleanArray arr;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	arr = newArray(booleanClass, len);
 
 	ADD_REF(arr);
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (arr);
 }
 
@@ -2900,12 +2901,12 @@
 {
 	jbyteArray arr;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	arr = newArray(byteClass, len);
 
 	ADD_REF(arr);
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (arr);
 }
 
@@ -2914,12 +2915,12 @@
 {
 	jcharArray arr;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	arr = newArray(charClass, len);
 
 	ADD_REF(arr);
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (arr);
 }
 
@@ -2928,12 +2929,12 @@
 {
 	jshortArray arr;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	arr = newArray(shortClass, len);
 
 	ADD_REF(arr);
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (arr);
 }
 
@@ -2942,12 +2943,12 @@
 {
 	jintArray arr;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	arr = newArray(intClass, len);
 
 	ADD_REF(arr);
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (arr);
 }
 
@@ -2956,12 +2957,12 @@
 {
 	jlongArray arr;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	arr = newArray(longClass, len);
 
 	ADD_REF(arr);
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (arr);
 }
 
@@ -2970,12 +2971,12 @@
 {
 	jfloatArray arr;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	arr = newArray(floatClass, len);
 
 	ADD_REF(arr);
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (arr);
 }
 
@@ -2984,12 +2985,12 @@
 {
 	jdoubleArray arr;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	arr = newArray(doubleClass, len);
 
 	ADD_REF(arr);
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (arr);
 }
 
@@ -2997,14 +2998,14 @@
 Kaffe_GetBooleanArrayElements(JNIEnv* env, jbooleanArray arr, jbool* iscopy)
 {
 	jboolean* ret;
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (iscopy != NULL) {
 		*iscopy = JNI_FALSE;
 	}
 	ret = unhand_array((HArrayOfBoolean*)arr)->body;
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -3012,14 +3013,14 @@
 Kaffe_GetByteArrayElements(JNIEnv* env, jbyteArray arr, jbool* iscopy)
 {
 	jbyte* ret;
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (iscopy != NULL) {
 		*iscopy = JNI_FALSE;
 	}
 	ret = unhand_array((HArrayOfByte*)arr)->body;
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -3027,14 +3028,14 @@
 Kaffe_GetCharArrayElements(JNIEnv* env, jcharArray arr, jbool* iscopy)
 {
 	jchar* ret;
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (iscopy != NULL) {
 		*iscopy = JNI_FALSE;
 	}
 	ret = unhand_array((HArrayOfChar*)arr)->body;
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -3042,14 +3043,14 @@
 Kaffe_GetShortArrayElements(JNIEnv* env, jshortArray arr, jbool* iscopy)
 {
 	jshort* ret;
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (iscopy != NULL) {
 		*iscopy = JNI_FALSE;
 	}
 	ret = unhand_array((HArrayOfShort*)arr)->body;
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -3057,14 +3058,14 @@
 Kaffe_GetIntArrayElements(JNIEnv* env, jintArray arr, jbool* iscopy)
 {
 	jint* ret;
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (iscopy != NULL) {
 		*iscopy = JNI_FALSE;
 	}
 	ret = unhand_array((HArrayOfInt*)arr)->body;
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -3072,14 +3073,14 @@
 Kaffe_GetLongArrayElements(JNIEnv* env, jlongArray arr, jbool* iscopy)
 {
 	jlong* ret;
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (iscopy != NULL) {
 		*iscopy = JNI_FALSE;
 	}
 	ret = unhand_array((HArrayOfLong*)arr)->body;
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -3087,14 +3088,14 @@
 Kaffe_GetFloatArrayElements(JNIEnv* env, jfloatArray arr, jbool* iscopy)
 {
 	jfloat* ret;
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (iscopy != NULL) {
 		*iscopy = JNI_FALSE;
 	}
 	ret = unhand_array((HArrayOfFloat*)arr)->body;
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
@@ -3102,21 +3103,21 @@
 Kaffe_GetDoubleArrayElements(JNIEnv* env, jdoubleArray arr, jbool* iscopy)
 {
 	jdouble* ret;
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	if (iscopy != NULL) {
 		*iscopy = JNI_FALSE;
 	}
 	ret = unhand_array((HArrayOfDouble*)arr)->body;
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (ret);
 }
 
 static void
 Kaffe_ReleaseBooleanArrayElements(JNIEnv* env, jbooleanArray arr, jbool* elems, jint mode)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (elems != unhand_array((HArrayOfBoolean*)arr)->body) {
 		switch (mode) {
@@ -3132,13 +3133,13 @@
 			break;
 		}
 	}
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_ReleaseByteArrayElements(JNIEnv* env, jbyteArray arr, jbyte* elems, jint mode)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (elems != unhand_array((HArrayOfByte*)arr)->body) {
 		switch (mode) {
@@ -3154,13 +3155,13 @@
 			break;
 		}
 	}
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_ReleaseCharArrayElements(JNIEnv* env, jcharArray arr, jchar* elems, jint mode)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (elems != unhand_array((HArrayOfChar*)arr)->body) {
 		switch (mode) {
@@ -3176,13 +3177,13 @@
 			break;
 		}
 	}
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_ReleaseShortArrayElements(JNIEnv* env, jshortArray arr, jshort* elems, jint mode)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (elems != unhand_array((HArrayOfShort*)arr)->body) {
 		switch (mode) {
@@ -3198,13 +3199,13 @@
 			break;
 		}
 	}
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_ReleaseIntArrayElements(JNIEnv* env, jintArray arr, jint* elems, jint mode)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (elems != unhand_array((HArrayOfInt*)arr)->body) {
 		switch (mode) {
@@ -3220,13 +3221,13 @@
 			break;
 		}
 	}
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_ReleaseLongArrayElements(JNIEnv* env, jlongArray arr, jlong* elems, jint mode)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (elems != unhand_array((HArrayOfLong*)arr)->body) {
 		switch (mode) {
@@ -3242,13 +3243,13 @@
 			break;
 		}
 	}
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_ReleaseFloatArrayElements(JNIEnv* env, jfloatArray arr, jfloat* elems, jint mode)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (elems != unhand_array((HArrayOfFloat*)arr)->body) {
 		switch (mode) {
@@ -3264,13 +3265,13 @@
 			break;
 		}
 	}
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_ReleaseDoubleArrayElements(JNIEnv* env, jdoubleArray arr, jdouble* elems, jint mode)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (elems != unhand_array((HArrayOfDouble*)arr)->body) {
 		switch (mode) {
@@ -3286,215 +3287,215 @@
 			break;
 		}
 	}
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_GetBooleanArrayRegion(JNIEnv* env, jbooleanArray arr, jsize start, jsize len, jbool* data)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (start >= obj_length((HArrayOfBoolean*)arr) || start + len > obj_length((HArrayOfBoolean*)arr)) {
 		throwException(ArrayIndexOutOfBoundsException);
 	}
 	memcpy(data, &unhand_array((HArrayOfBoolean*)arr)->body[start], len * sizeof(jboolean));
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_GetByteArrayRegion(JNIEnv* env, jbyteArray arr, jsize start, jsize len, jbyte* data)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (start >= obj_length((HArrayOfByte*)arr) || start + len > obj_length((HArrayOfByte*)arr)) {
 		throwException(ArrayIndexOutOfBoundsException);
 	}
 	memcpy(data, &unhand_array((HArrayOfByte*)arr)->body[start], len * sizeof(jbyte));
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_GetCharArrayRegion(JNIEnv* env, jcharArray arr, jsize start, jsize len, jchar* data)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (start >= obj_length((HArrayOfChar*)arr) || start + len > obj_length((HArrayOfChar*)arr)) {
 		throwException(ArrayIndexOutOfBoundsException);
 	}
 	memcpy(data, &unhand_array((HArrayOfChar*)arr)->body[start], len * sizeof(jchar));
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_GetShortArrayRegion(JNIEnv* env, jshortArray arr, jsize start, jsize len, jshort* data)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (start >= obj_length((HArrayOfShort*)arr) || start + len > obj_length((HArrayOfShort*)arr)) {
 		throwException(ArrayIndexOutOfBoundsException);
 	}
 	memcpy(data, &unhand_array((HArrayOfShort*)arr)->body[start], len * sizeof(jshort));
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_GetIntArrayRegion(JNIEnv* env, jintArray arr, jsize start, jsize len, jint* data)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (start >= obj_length((HArrayOfInt*)arr) || start + len > obj_length((HArrayOfInt*)arr)) {
 		throwException(ArrayIndexOutOfBoundsException);
 	}
 	memcpy(data, &unhand_array((HArrayOfInt*)arr)->body[start], len * sizeof(jint));
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_GetLongArrayRegion(JNIEnv* env, jlongArray arr, jsize start, jsize len, jlong* data)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (start >= obj_length((HArrayOfLong*)arr) || start + len > obj_length((HArrayOfLong*)arr)) {
 		throwException(ArrayIndexOutOfBoundsException);
 	}
 	memcpy(data, &unhand_array((HArrayOfLong*)arr)->body[start], len * sizeof(jlong));
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_GetFloatArrayRegion(JNIEnv* env, jfloatArray arr, jsize start, jsize len, jfloat* data)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (start >= obj_length((HArrayOfFloat*)arr) || start + len > obj_length((HArrayOfFloat*)arr)) {
 		throwException(ArrayIndexOutOfBoundsException);
 	}
 	memcpy(data, &unhand_array((HArrayOfFloat*)arr)->body[start], len * sizeof(jfloat));
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_GetDoubleArrayRegion(JNIEnv* env, jdoubleArray arr, jsize start, jsize len, jdouble* data)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (start >= obj_length((HArrayOfDouble*)arr) || start + len > obj_length((HArrayOfDouble*)arr)) {
 		throwException(ArrayIndexOutOfBoundsException);
 	}
 	memcpy(data, &unhand_array((HArrayOfDouble*)arr)->body[start], len * sizeof(jdouble));
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_SetBooleanArrayRegion(JNIEnv* env, jbooleanArray arr, jsize start, jsize len, jbool* data)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (start >= obj_length((HArrayOfBoolean*)arr) || start+len > obj_length((HArrayOfBoolean*)arr)) {
 		throwException(ArrayIndexOutOfBoundsException);
 	}
 	memcpy(&unhand_array((HArrayOfBoolean*)arr)->body[start], data, len * sizeof(jboolean));
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_SetByteArrayRegion(JNIEnv* env, jbyteArray arr, jsize start, jsize len, jbyte* data)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (start >= obj_length((HArrayOfByte*)arr) || start+len > obj_length((HArrayOfByte*)arr)) {
 		throwException(ArrayIndexOutOfBoundsException);
 	}
 	memcpy(&unhand_array((HArrayOfByte*)arr)->body[start], data, len * sizeof(jbyte));
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_SetCharArrayRegion(JNIEnv* env, jcharArray arr, jsize start, jsize len, jchar* data)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (start >= obj_length((HArrayOfChar*)arr) || start+len > obj_length((HArrayOfChar*)arr)) {
 		throwException(ArrayIndexOutOfBoundsException);
 	}
 	memcpy(&unhand_array((HArrayOfChar*)arr)->body[start], data, len * sizeof(jchar));
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_SetShortArrayRegion(JNIEnv* env, jshortArray arr, jsize start, jsize len, jshort* data)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (start >= obj_length((HArrayOfShort*)arr) || start+len > obj_length((HArrayOfShort*)arr)) {
 		throwException(ArrayIndexOutOfBoundsException);
 	}
 	memcpy(&unhand_array((HArrayOfShort*)arr)->body[start], data, len * sizeof(jshort));
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_SetIntArrayRegion(JNIEnv* env, jintArray arr, jsize start, jsize len, jint* data)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (start >= obj_length((HArrayOfInt*)arr) || start+len > obj_length((HArrayOfInt*)arr)) {
 		throwException(ArrayIndexOutOfBoundsException);
 	}
 	memcpy(&unhand_array((HArrayOfInt*)arr)->body[start], data, len * sizeof(jint));
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_SetLongArrayRegion(JNIEnv* env, jlongArray arr, jsize start, jsize len, jlong* data)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (start >= obj_length((HArrayOfLong*)arr) || start+len > obj_length((HArrayOfLong*)arr)) {
 		throwException(ArrayIndexOutOfBoundsException);
 	}
 	memcpy(&unhand_array((HArrayOfLong*)arr)->body[start], data, len * sizeof(jlong));
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_SetFloatArrayRegion(JNIEnv* env, jfloatArray arr, jsize start, jsize len, jfloat* data)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (start >= obj_length((HArrayOfFloat*)arr) || start+len > obj_length((HArrayOfFloat*)arr)) {
 		throwException(ArrayIndexOutOfBoundsException);
 	}
 	memcpy(&unhand_array((HArrayOfFloat*)arr)->body[start], data, len * sizeof(jfloat));
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static void
 Kaffe_SetDoubleArrayRegion(JNIEnv* env, jdoubleArray arr, jsize start, jsize len, jdouble* data)
 {
-	BEGIN_EXCEPTION_HANDLING_VOID();
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return;
 
 	if (start >= obj_length((HArrayOfDouble*)arr) || start+len > obj_length((HArrayOfDouble*)arr)) {
 		throwException(ArrayIndexOutOfBoundsException);
 	}
 	memcpy(&unhand_array((HArrayOfDouble*)arr)->body[start], data, len * sizeof(jdouble));
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 }
 
 static jint
@@ -3505,7 +3506,7 @@
 	int i;
 	int j;
 
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	meth = CLASS_METHODS((Hjava_lang_Class*)cls);
 	nmeth = CLASS_NMETHODS((Hjava_lang_Class*)cls);
@@ -3525,7 +3526,7 @@
 		found:;
 	}
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 
 	return (0);
 }
@@ -3540,23 +3541,23 @@
 static jint
 Kaffe_MonitorEnter(JNIEnv* env, jobject obj)
 {
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	/* We should never throw out of a JNI call */
 	lockObject(obj);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (0);
 }
 
 static jint
 Kaffe_MonitorExit(JNIEnv* env, jobject obj)
 {
-	BEGIN_EXCEPTION_HANDLING(0);
+	VmExceptHandler ebuf; if (enterJNI(&ebuf)) return 0;
 
 	unlockObject(obj);
 
-	END_EXCEPTION_HANDLING();
+	leaveJNI(&ebuf);
 	return (0);
 }
 
@@ -4018,7 +4019,9 @@
 		xmeth->accflags |= ACC_JNI;
 
 done:
+/*
 	resetConstants();
+*/
 	resetLabels();
 
 #if defined(KAFFE_PROFILER)

--------------050400090801060402040404--