Index: kaffe/kaffevm/classMethod.c =================================================================== RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/classMethod.c,v retrieving revision 1.119 diff -u -r1.119 classMethod.c --- kaffe/kaffevm/classMethod.c 18 Apr 2004 13:57:26 -0000 1.119 +++ kaffe/kaffevm/classMethod.c 5 Jul 2004 07:22:46 -0000 @@ -193,10 +193,33 @@ else #endif { + uintp idx = (uintp)class->superclass; + int tag = CLASS_CONSTANTS(class)->tags[idx]; + + if (tag != CONSTANT_Class) { + postExceptionMessage(einfo, + JAVA_LANG(ClassFormatError), + "%s (Invalid constant reference, %d, " + "expecting class, likely an internal " + "error)", + class->name->data, + tag); + success = false; + goto done; + } + class->superclass = - getClass((uintp)class->superclass, - class, - einfo); + loadClass (WORD2UTF(CLASS_CONSTANTS(class)->data[idx]), + class->loader, + einfo); + + /* updating the const pool w/o holding a lock is ok, since no other + * thread can use this class at this early stage + */ + if (class->superclass != NULL) { + CLASS_CONSTANTS(class)->tags[idx] = CONSTANT_ResolvedClass; + CLASS_CONSTANTS(class)->data[idx] = (ConstSlot)class->superclass; + } } lockClass(class); @@ -216,21 +239,26 @@ success = false; goto done; } - /* that's pretty much obsolete. */ - assert(class->superclass->state >= CSTATE_DOING_LINK); - classMappingLoaded(ce, class); /* Copy initial field size and gc layout. * Later, as this class's fields are resolved, they * are added to the superclass's layout. */ CLASS_FSIZE(class) = CLASS_FSIZE(class->superclass); class->gc_layout = class->superclass->gc_layout; + + /* Mark the class as loaded and set the state to CSTATE_LOADED_SUPER before + * processing the superclass to LINKED. That way, we will process this class + * to LINKED when it has to be loaded while verifying one of its superclasses. + * Since the superclass is already PREPARED, possible ClassCircularityErrors + * would've been detected earlier. + */ + classMappingLoaded(ce, class); + SET_CLASS_STATE(CSTATE_LOADED_SUPER); + if (processClass (class->superclass, CSTATE_LINKED, einfo) == false) { + success = false; + goto done; + } } - if( class->superclass ) - { - assert(class->superclass->state >= CSTATE_DOING_LINK); - } - } DO_CLASS_STATE(CSTATE_VERIFIED) { @@ -364,7 +392,8 @@ } SET_CLASS_STATE(CSTATE_DOING_LINK); - + class->processingThread = THREAD_NATIVE (); + /* Third stage verification - check the bytecode is okay */ success = verify3(class, einfo); if (success == false) { @@ -1477,8 +1506,7 @@ /* No joy, update state. */ setClassMappingState(ce, NMS_EMPTY); } - else if( processClass(retval, CSTATE_LINKED, einfo) - == false ) + else if ( processClass(retval, CSTATE_PREPARED, einfo) == false ) { retval = NULL; } Index: kaffe/kaffevm/itypes.c =================================================================== RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/itypes.c,v retrieving revision 1.30 diff -u -r1.30 itypes.c --- kaffe/kaffevm/itypes.c 7 Apr 2004 21:30:15 -0000 1.30 +++ kaffe/kaffevm/itypes.c 5 Jul 2004 07:22:46 -0000 @@ -186,6 +186,9 @@ return (0); } cl = loadClass(utf8, loader, einfo); + if (cl != NULL && !processClass (cl, CSTATE_LINKED, einfo)) { + cl = NULL; + } utf8ConstRelease(utf8); return(cl); @@ -212,12 +215,13 @@ if (cls != 0 && *sig == 0) { return (cls); } + /* * or rather VerifyError? It could be a malformed sig in a malformed * .class file, or it could be a malformed user input from * Class.forName() */ - postExceptionMessage(einfo, JAVA_LANG(NoClassDefFoundError), "%s", sig0); + /* postExceptionMessage(einfo, JAVA_LANG(NoClassDefFoundError), "%s", sig0); */ return (0); } Index: kaffe/kaffevm/lookup.c =================================================================== RCS file: /cvs/kaffe/kaffe/kaffe/kaffevm/lookup.c,v retrieving revision 1.35 diff -u -r1.35 lookup.c --- kaffe/kaffevm/lookup.c 29 Mar 2004 21:13:33 -0000 1.35 +++ kaffe/kaffevm/lookup.c 5 Jul 2004 07:22:46 -0000 @@ -221,6 +221,12 @@ return NULL; } + /* process the class to LINKED if necessary */ + if (processClass (class, CSTATE_LINKED, einfo) == false) + { + return NULL; + } + /* Lock the class while we update the constant pool. Someone * may have done this already but we don't care. */ Index: libraries/clib/native/Class.c =================================================================== RCS file: /cvs/kaffe/kaffe/libraries/clib/native/Class.c,v retrieving revision 1.73 diff -u -r1.73 Class.c --- libraries/clib/native/Class.c 21 May 2004 15:19:24 -0000 1.73 +++ libraries/clib/native/Class.c 5 Jul 2004 07:22:46 -0000 @@ -118,6 +118,9 @@ if (doinit && processClass(clazz, CSTATE_COMPLETE, &einfo) == false) { throwError(&einfo); } + else if (!doinit && processClass(clazz, CSTATE_LINKED, &einfo) == false) { + throwError(&einfo); + } return (clazz); } Index: libraries/clib/native/PrimordialClassLoader.c =================================================================== RCS file: /cvs/kaffe/kaffe/libraries/clib/native/PrimordialClassLoader.c,v retrieving revision 1.3 diff -u -r1.3 PrimordialClassLoader.c --- libraries/clib/native/PrimordialClassLoader.c 21 May 2004 15:19:24 -0000 1.3 +++ libraries/clib/native/PrimordialClassLoader.c 5 Jul 2004 07:22:46 -0000 @@ -53,19 +53,7 @@ { clazz = loadClass(c, 0, &info); } - if( clazz ) - { - /* - * do not process to COMPLETE, it will run static - * initializers prematurely! - */ - if( processClass(clazz, CSTATE_LINKED, &info) == - false ) - { - error = 1; - } - } - else + if( clazz == NULL ) { error = 1; }