Changes:
- $Id: asmpart.c 5055 2006-06-28 20:33:38Z edwin $
+ $Id: asmpart.c 5694 2006-10-05 16:12:16Z edwin $
*/
Inst *intrp_asm_handle_exception(Inst *ip, java_objectheader *o, Cell *fp, Cell **new_spp, Cell **new_fpp)
{
- classinfo *c;
- s4 framesize;
- exceptionentry *ex;
- s4 exceptiontablelength;
- s4 i;
+ classinfo *c;
+ classref_or_classinfo cr;
+ s4 framesize;
+ s4 issync;
+ exceptionentry *ex;
+ s4 exceptiontablelength;
+ s4 i;
/* for a description of the stack see IRETURN in java.vmg */
for (; fp != NULL; ) {
- u1 *f = codegen_findmethod((u1 *) (ip - 1));
+ u1 *f = codegen_get_pv_from_pc((u1 *) (ip - 1));
/* get methodinfo pointer from method header */
codeinfo *code = *((codeinfo **) ((u1 *)f + CodeinfoPointer));
methodinfo *m = code->m;
- framesize = (*((s4 *) (((u1 *) f) + FrameSize)));
- ex = (exceptionentry *) (((u1 *) f) + ExTableStart);
- exceptiontablelength = *((s4 *) (((u1 *) f) + ExTableSize));
+ framesize = *((s4 *) (((u1 *) f) + FrameSize));
+ issync = *((s4 *) (((u1 *) f) + IsSync));
+ ex = (exceptionentry *) (((u1 *) f) + ExTableStart);
+ exceptiontablelength = *((s4 *) (((u1 *) f) + ExTableSize));
#if !defined(NDEBUG)
if (opt_verbose || opt_verbosecall || opt_verboseexception)
for (i = 0; i < exceptiontablelength; i++) {
ex--;
- c = ex->catchtype.cls;
- if (c != NULL) {
- if (!(c->state & CLASS_LOADED))
- /* XXX fix me! */
- if (!load_class_bootstrap(c->name))
- assert(0);
+ cr = ex->catchtype;
+
+ if (cr.any == NULL) {
+ /* catch all */
+ c = NULL;
+ }
+ else {
+ if (IS_CLASSREF(cr)) {
+ /* The exception class reference is unresolved. */
+ /* We have to do _eager_ resolving here. While the class of */
+ /* the exception object is guaranteed to be loaded, it may */
+ /* well have been loaded by a different loader than the */
+ /* defining loader of m's class, which is the one we must */
+ /* use to resolve the catch class. Thus lazy resolving */
+ /* might fail, even if the result of the resolution would */
+ /* be an already loaded class. */
+
+ /* The resolving may involve Java code, so we need a usable */
+ /* global_sp. XXX is this a correct value for global_sp? */
+
+ global_sp = (Cell *)(((u1 *)fp) - framesize - SIZEOF_VOID_P);
- if (!(c->state & CLASS_LINKED))
- if (!link_class(c))
+ c = resolve_classref_eager(cr.ref);
+
+ CLEAR_global_sp;
+
+ if (c == NULL) {
+ /* Exception resolving the exception class, argh! */
+ /* XXX how to report that error? */
assert(0);
+ }
+
+ /* Ok, we resolved it. Enter it in the table, so we don't */
+ /* have to do this again. */
+ /* XXX this write should be atomic. Is it? */
+
+ ex->catchtype.cls = c;
+ }
+ else {
+ c = cr.cls;
+
+ /* If the class is not linked, the exception object cannot */
+ /* be an instance of it. */
+ if (!(c->state & CLASS_LINKED))
+ continue;
+ }
}
if (ip-1 >= (Inst *) ex->startpc && ip-1 < (Inst *) ex->endpc &&
}
}
+#if defined(ENABLE_THREADS)
+ /* is this method synchronized? */
+
+ if (issync) {
+ java_objectheader *syncobj;
+
+ /* get synchronization object */
+
+ if (m->flags & ACC_STATIC) {
+ syncobj = (java_objectheader *) m->class;
+ }
+ else {
+ syncobj = (java_objectheader *) access_local_cell(-framesize + SIZEOF_VOID_P);
+ }
+
+ assert(syncobj != NULL);
+
+ lock_monitor_exit(syncobj);
+ }
+#endif /* defined(ENABLE_THREADS) */
+
+ /* unwind stack frame */
+
ip = (Inst *)access_local_cell(-framesize - SIZEOF_VOID_P);
fp = (Cell *)access_local_cell(-framesize);
}