* src/vm/global.h (TYPE_RET): New constant.
[cacao.git] / src / vm / exceptions.c
index 8b8cecba0b6b5bb59c47a17857ba86e27c7682a4..1b7e77b1296008830e4148724784bbf552b6fdf5 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes: Edwin Steiner
 
-   $Id: exceptions.c 5251 2006-08-18 13:01:00Z twisti $
+   $Id: exceptions.c 5461 2006-09-11 00:33:32Z edwin $
 
 */
 
@@ -1124,6 +1124,7 @@ void exceptions_throw_verifyerror_for_stack(methodinfo *m,int type)
                case TYPE_FLT: typename = "float"; break;
                case TYPE_DBL: typename = "double"; break;
                case TYPE_ADR: typename = "object/array"; break;
+               case TYPE_RET: typename = "returnAddress"; break;
                default:       typename = "<INVALID>"; assert(0); break;
        }
        strcat(msg, typename);
@@ -1313,26 +1314,39 @@ void exceptions_throw_illegalargumentexception(void)
 }
 
 
-/* new_illegalmonitorstateexception ********************************************
+/* exceptions_new_illegalmonitorstateexception *********************************
 
    Generates a java.lang.IllegalMonitorStateException for the VM
    thread system.
 
 *******************************************************************************/
 
-java_objectheader *new_illegalmonitorstateexception(void)
+java_objectheader *exceptions_new_illegalmonitorstateexception(void)
 {
        java_objectheader *e;
 
        e = native_new_and_init(class_java_lang_IllegalMonitorStateException);
 
-       if (!e)
+       if (e == NULL)
                return *exceptionptr;
 
        return e;
 }
 
 
+/* exceptions_throw_illegalmonitorstateexception *******************************
+
+   Generates a java.lang.IllegalMonitorStateException for the VM
+   system and throw it in the VM system.
+
+*******************************************************************************/
+
+void exceptions_throw_illegalmonitorstateexception(void)
+{
+       *exceptionptr = exceptions_new_illegalmonitorstateexception();
+}
+
+
 /* exceptions_new_negativearraysizeexception ***********************************
 
    Generates a java.lang.NegativeArraySizeException for the VM system.
@@ -1548,17 +1562,40 @@ u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp
                        /* resolve or load/link the exception class */
 
                        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.                              */
+
                                c = resolve_classref_eager(cr.ref);
 
+                               if (c == NULL) {
+                                       /* Exception resolving the exception class, argh! */
+                                       return NULL;
+                               }
+
+                               /* 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;
 
+                               /* XXX I don't think this case can ever happen. -Edwin */
                                if (!(c->state & CLASS_LOADED))
                                        /* use the methods' classloader */
                                        if (!load_class_from_classloader(c->name,
                                                                                                         m->class->classloader))
                                                return NULL;
 
+                               /* XXX I think, if it is not linked, we can be sure that     */
+                               /* the exception object is no (indirect) instance of it, no? */
+                               /* -Edwin                                                    */
                                if (!(c->state & CLASS_LINKED))
                                        if (!link_class(c))
                                                return NULL;