changed exception types and innerclass references to classref_or_classinfo
[cacao.git] / src / native / vm / VMClass.c
index 6a95bb9c5f1790ba450d38f1fafd7d29ccc804fa..4e3d7b495ef014a0cc9e0e42faecfaa5b315e4c4 100644 (file)
@@ -1,9 +1,9 @@
-/* nat/VMClass.c - java/lang/Class
+/* src/native/vm/VMClass.c - java/lang/VMClass
 
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
-   R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
-   M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
-   P. Tomsich, J. Wenninger
+   Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
+   R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
+   C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
+   Institut f. Computersprachen - TU Wien
 
    This file is part of CACAO.
 
    Authors: Roman Obermaiser
 
    Changes: Joseph Wenninger
+            Christian Thalinger
 
-   $Id: VMClass.c 1201 2004-06-20 21:24:17Z twisti $
+   $Id: VMClass.c 2190 2005-04-02 10:07:44Z edwin $
 
 */
 
 
 #include <string.h>
-#include "jni.h"
+
 #include "types.h"
-#include "global.h"
-#include "builtin.h"
-#include "loader.h"
-#include "native.h"
-#include "tables.h"
+#include "mm/memory.h"
+#include "native/jni.h"
+#include "native/native.h"
+#include "native/include/java_lang_Class.h"
+#include "native/include/java_lang_ClassLoader.h"
+#include "native/include/java_lang_Object.h"
+#include "native/include/java_lang_VMClass.h"
+#include "native/include/java_lang_reflect_Constructor.h"
+#include "native/include/java_lang_reflect_Field.h"
+#include "native/include/java_lang_reflect_Method.h"
+#include "native/include/java_security_ProtectionDomain.h"
 #include "toolbox/logging.h"
-#include "toolbox/memory.h"
-#include "java_lang_Object.h"
-#include "java_lang_Class.h"
-#include "java_lang_ClassLoader.h"
-#include "java_security_ProtectionDomain.h"
-#include "java_lang_reflect_Constructor.h"
-#include "java_lang_reflect_Field.h"
-#include "java_lang_reflect_Method.h"
-#include "java_lang_Throwable.h"    /* needed for java_lang_VMClass.h */
-#include "java_lang_VMClass.h"
+#include "vm/builtin.h"
+#include "vm/exceptions.h"
+#include "vm/global.h"
+#include "vm/loader.h"
+#include "vm/stringlocal.h"
+#include "vm/tables.h"
 
 
 /* for selecting public members */
 
 
 /*
- * Class:     java_lang_VMClass
+ * Class:     java/lang/VMClass
  * Method:    forName
  * Signature: (Ljava/lang/String;)Ljava/lang/Class;
  */
 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_forName(JNIEnv *env, jclass clazz, java_lang_String *s)
 {
+       return NULL;
+
+       /* XXX TWISTI: we currently use the classpath default implementation, maybe 
+          we change this someday to a faster native version */
+#if 0
        classinfo *c;
-       utf *u;
+       utf       *u;
 
        /* illegal argument */
+
        if (!s)
                return NULL;
        
        /* create utf string in which '.' is replaced by '/' */
+
        u = javastring_toutf(s, true);
 
        /* create a new class, ... */
+
        c = class_new(u);
 
-       /* load, ... */
-       if (!class_load(c)) {
+       /* try to load, ... */
+
+       if (!load_class_bootstrap(c)) {
                classinfo *xclass;
 
                xclass = (*exceptionptr)->vftbl->class;
@@ -87,7 +99,7 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_forName(JNIEnv *env, j
                /* if the exception is a NoClassDefFoundError, we replace it with a
                   ClassNotFoundException, otherwise return the exception */
 
-               if (xclass == class_get(utf_new_char(string_java_lang_NoClassDefFoundError))) {
+               if (xclass == class_java_lang_NoClassDefFoundError) {
                        /* clear exceptionptr, because builtin_new checks for 
                           ExceptionInInitializerError */
                        *exceptionptr = NULL;
@@ -100,30 +112,30 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_forName(JNIEnv *env, j
        }
 
        /* link, ... */
-       if (!class_link(c))
+
+       if (!link_class(c))
                return NULL;
        
        /* ...and initialize it */
+
        if (!class_init(c))
                return NULL;
 
        use_class_as_object(c);
 
        return (java_lang_Class *) c;
+#endif
 }
 
 
 /*
- * Class:     java_lang_VMClass
+ * Class:     java/lang/VMClass
  * Method:    getClassLoader
  * Signature: ()Ljava/lang/ClassLoader;
  */
 JNIEXPORT java_lang_ClassLoader* JNICALL Java_java_lang_VMClass_getClassLoader(JNIEnv *env, jclass clazz, java_lang_Class *that)
 {  
-       return ((classinfo*)that)->classloader;
-/*     init_systemclassloader();
-
-       return SystemClassLoader;*/
+       return (java_lang_ClassLoader *) ((classinfo *) that)->classloader;
 }
 
 
@@ -132,7 +144,7 @@ JNIEXPORT java_lang_ClassLoader* JNICALL Java_java_lang_VMClass_getClassLoader(J
  * Method:    getComponentType
  * Signature: ()Ljava/lang/Class;
  */
-JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getComponentType(JNIEnv *env, jclass clazz,java_lang_Class *that)
+JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getComponentType(JNIEnv *env, jclass clazz, java_lang_Class *that)
 {
     classinfo *thisclass = (classinfo *) that;
     classinfo *c = NULL;
@@ -153,12 +165,11 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getComponentType(JNIEn
 
 
 /*
- * Class:     java_lang_VMClass
+ * Class:     java/lang/VMClass
  * Method:    getDeclaredConstructors
  * Signature: (Z)[Ljava/lang/reflect/Constructor;
  */
-JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredConstructors(JNIEnv *env, jclass clazz,
-       struct java_lang_Class *that, s4 public_only)
+JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredConstructors(JNIEnv *env, jclass clazz, java_lang_Class *that, s4 public_only)
 {
   
     classinfo *c = (classinfo *) that;
@@ -170,21 +181,20 @@ JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredConstructo
     int public_methods = 0;            /* number of public methods of the class */
     int pos = 0;
     int i;
-    utf *utf_constr = utf_new_char("<init>");
 
     /* determine number of constructors */
     for (i = 0; i < c->methodscount; i++) 
                if (((c->methods[i].flags & ACC_PUBLIC) || !public_only) && 
-                       (c->methods[i].name == utf_constr))
+                       (c->methods[i].name == utf_init))
                        public_methods++;
 
     class_constructor = class_new(utf_new_char("java/lang/reflect/Constructor"));
 
        if (!class_constructor->loaded)
-               class_load(class_constructor);
+               load_class_bootstrap(class_constructor);
 
        if (!class_constructor->linked)
-               class_link(class_constructor);
+               link_class(class_constructor);
 
     array_constructor = builtin_anewarray(public_methods, class_constructor);
 
@@ -194,7 +204,7 @@ JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredConstructo
     for (i = 0; i < c->methodscount; i++) 
                if ((c->methods[i].flags & ACC_PUBLIC) || !public_only){
                        m = &c->methods[i];         
-                       if (m->name!=utf_constr)
+                       if (m->name != utf_init)
                                continue;
 
                        o = native_new_and_init(class_constructor);     
@@ -242,7 +252,7 @@ JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredClasses(JN
        if (!Java_java_lang_VMClass_isPrimitive(env, clazz, (java_lang_Class *) c) && (c->name->text[0] != '[')) {
                /* determine number of declared classes */
                for (i = 0; i < c->innerclasscount; i++) {
-                       if ( (c->innerclass[i].outer_class == c) && (notPublicOnly || (c->innerclass[i].flags & ACC_PUBLIC)))
+                       if ( (c->innerclass[i].outer_class.cls == c) && (notPublicOnly || (c->innerclass[i].flags & ACC_PUBLIC)))
                                /* outer class is this class */
                                declaredclasscount++;
                }
@@ -253,8 +263,8 @@ JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredClasses(JN
        result = builtin_anewarray(declaredclasscount, class_java_lang_Class);          
 
        for (i = 0; i < c->innerclasscount; i++) {
-               classinfo *inner = c->innerclass[i].inner_class;
-               classinfo *outer = c->innerclass[i].outer_class;
+               classinfo *inner = c->innerclass[i].inner_class.cls;
+               classinfo *outer = c->innerclass[i].outer_class.cls;
                
                if ((outer == c) && (notPublicOnly || (inner->flags & ACC_PUBLIC))) {
                        /* outer class is this class, store innerclass in array */
@@ -286,8 +296,8 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getDeclaringClass(JNIE
                        return NULL;
     
                for (i = 0; i < c->innerclasscount; i++) {
-                       classinfo *inner =  c->innerclass[i].inner_class;
-                       classinfo *outer =  c->innerclass[i].outer_class;
+                       classinfo *inner =  c->innerclass[i].inner_class.cls;
+                       classinfo *outer =  c->innerclass[i].outer_class.cls;
       
                        if (inner == c) {
                                /* innerclass is this class */
@@ -305,10 +315,8 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getDeclaringClass(JNIE
 java_lang_reflect_Field* cacao_getField0(JNIEnv *env, java_lang_Class *that, java_lang_String *name, s4 public_only)
 {
     classinfo *c;
-       classinfo *fieldtype;
     fieldinfo *f;               /* the field to be represented */
     java_lang_reflect_Field *o; /* result: field-object */
-    utf *desc;                         /* the fielddescriptor */
     int idx;
 
     /* create Field object */
@@ -332,16 +340,12 @@ java_lang_reflect_Field* cacao_getField0(JNIEnv *env, java_lang_Class *that, jav
                        return NULL;
                }
 
-               desc = f->descriptor;
-               fieldtype = class_from_descriptor(desc->text, utf_end(desc), NULL, CLASSLOAD_LOAD);
-               if (!fieldtype)
-                       return NULL;
-        
                /* initialize instance fields */
                setfield_critical(c,o,"declaringClass",          "Ljava/lang/Class;",  jobject, (jobject) that /*this*/);
                /*      ((java_lang_reflect_Field*)(o))->flag=f->flags;*/
                /* save type in slot-field for faster processing */
-               /*      setfield_critical(c,o,"flag",           "I",                jint,    (jint) f->flags);  */
+               /* setfield_critical(c,o,"flag",           "I",             jint,    (jint) f->flags); */
+               /*o->flag = f->flags;*/
                setfield_critical(c,o,"slot",           "I",                jint,    (jint) idx);  
                setfield_critical(c,o,"name",           "Ljava/lang/String;", jstring, (jstring) name);
                /*setfield_critical(c,o,"type",           "Ljava/lang/Class;",  jclass,  fieldtype);*/
@@ -412,9 +416,9 @@ JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getInterfaces(JNIEnv
                return NULL;
 
        for (i = 0; i < c->interfacescount; i++) {
-               use_class_as_object(c->interfaces[i]);
+               use_class_as_object(c->interfaces[i].cls);
 
-               a->data[i] = (java_objectheader *) c->interfaces[i];
+               a->data[i] = (java_objectheader *) c->interfaces[i].cls;
        }
 
        return a;
@@ -445,17 +449,31 @@ java_lang_reflect_Method* cacao_getMethod0(JNIEnv *env, java_lang_Class *that, j
                return NULL;
        }
    
-    /* array of exceptions declared to be thrown, information not available !! */
+    /* array of exceptions declared to be thrown, information not available */
     exceptiontypes = builtin_anewarray(0, class_java_lang_Class);
 
     /* initialize instance fields */
-    setfield_critical(c,o,"clazz",          "Ljava/lang/Class;",  jobject, (jobject) clazz /*this*/);
-    setfield_critical(c,o,"parameterTypes", "[Ljava/lang/Class;", jobject, (jobject) types);
-    setfield_critical(c,o,"exceptionTypes", "[Ljava/lang/Class;", jobject, (jobject) exceptiontypes);
-    setfield_critical(c,o,"name",           "Ljava/lang/String;", jstring, javastring_new(m->name));
-    setfield_critical(c,o,"modifiers",      "I",                 jint,    m->flags);
-    setfield_critical(c,o,"slot",           "I",                 jint,    0); 
-    setfield_critical(c,o,"returnType",     "Ljava/lang/Class;",  jclass,  get_returntype(m));
+
+    setfield_critical(c, o, "clazz",          "Ljava/lang/Class;",  jobject,
+                                         (jobject) clazz /*this*/);
+
+    setfield_critical(c, o, "parameterTypes", "[Ljava/lang/Class;", jobject,
+                                         (jobject) types);
+
+    setfield_critical(c, o, "exceptionTypes", "[Ljava/lang/Class;", jobject,
+                                         (jobject) exceptiontypes);
+
+    setfield_critical(c, o, "name",           "Ljava/lang/String;", jstring,
+                                         (jobject) javastring_new(m->name));
+
+    setfield_critical(c, o, "modifiers",      "I",                  jint,
+                                         m->flags);
+
+    setfield_critical(c, o, "slot",           "I",                  jint,
+                                         0); 
+
+    setfield_critical(c, o, "returnType",     "Ljava/lang/Class;",  jclass,
+                                         get_returntype(m));
 
     return o;
 }
@@ -477,8 +495,6 @@ JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredMethods(JN
     int public_methods = 0;            /* number of public methods of the class */
     int pos = 0;
     int i;
-    utf *utf_constr=utf_new_char("<init>");
-    utf *utf_clinit=utf_new_char("<clinit>");
 
 /*      class_method = (classinfo*) loader_load(utf_new_char ("java/lang/reflect/Method")); */
     class_method = class_new(utf_new_char("java/lang/reflect/Method"));
@@ -497,8 +513,8 @@ JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredMethods(JN
     for (i = 0; i < c->methodscount; i++) 
                if ((((c->methods[i].flags & ACC_PUBLIC)) || (!public_only)) && 
                        (!
-                        ((c->methods[i].name==utf_constr) ||
-                         (c->methods[i].name==utf_clinit) )
+                        ((c->methods[i].name == utf_init) ||
+                         (c->methods[i].name == utf_clinit) )
                         )) public_methods++;
 
        /*      
@@ -515,8 +531,8 @@ JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredMethods(JN
     for (i = 0; i < c->methodscount; i++) 
                if (((c->methods[i].flags & ACC_PUBLIC) || (!public_only)) && 
                        (!
-                        ((c->methods[i].name==utf_constr) ||
-                         (c->methods[i].name==utf_clinit) )
+                        ((c->methods[i].name == utf_init) ||
+                         (c->methods[i].name == utf_clinit) )
                         )) {
 
                        m = &c->methods[i];         
@@ -533,7 +549,7 @@ JNIEXPORT java_objectarray* JNICALL Java_java_lang_VMClass_getDeclaredMethods(JN
                                        ACC_SYNCHRONIZED | ACC_NATIVE | ACC_STRICT)
                                        );*/
                        setfield_critical(class_method,o,"declaringClass",          "Ljava/lang/Class;",  jobject, (jobject) c /*this*/);
-                       setfield_critical(class_method,o,"name",           "Ljava/lang/String;", jstring, javastring_new(m->name));
+                       setfield_critical(class_method,o,"name",           "Ljava/lang/String;", jstring, (jobject) javastring_new(m->name));
                        /*          setfield_critical(class_method,o,"flag",      "I",               jint,   (m->flags &
                                        (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_ABSTRACT | ACC_STATIC | ACC_FINAL |
                                        ACC_SYNCHRONIZED | ACC_NATIVE | ACC_STRICT)));*/
@@ -676,12 +692,12 @@ JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMClass_getBeautifiedName(JNI
 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_getSuperclass(JNIEnv *env, jclass clazz, java_lang_Class *that)
 {
        classinfo *cl = (classinfo *) that;
-       classinfo *c = cl->super;
+       classinfo *c = cl->super.cls;
 
        if (!c)
                return NULL;
 
-       use_class_as_object (c);
+       use_class_as_object(c);
 
        return (java_lang_Class *) c;
 }
@@ -707,14 +723,14 @@ JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isArray(JNIEnv *env, jclass clazz, j
  */
 JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isAssignableFrom(JNIEnv *env, jclass clazz, java_lang_Class *that, java_lang_Class *sup)
 {
-       /*      log_text("Java_java_lang_VMClass_isAssignableFrom");*/
-       
-       if (!sup) return 0;
-       if (!that) {
-               panic("sup->vmClass is NULL in VMClass.isAssignableFrom");
+       if (!sup) {
+               *exceptionptr = new_nullpointerexception();
                return 0;
        }
-       return (*env)->IsAssignableForm(env, (jclass) sup, (jclass) that);
+
+       /* XXX this may be wrong for array classes */
+       return builtin_isanysubclass((classinfo*)sup, (classinfo*)that);
+
 }
 
 
@@ -725,9 +741,7 @@ JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isAssignableFrom(JNIEnv *env, jclass
  */
 JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isInstance(JNIEnv *env, jclass clazz, java_lang_Class *that, java_lang_Object *obj)
 {
-/*     classinfo *clazz = (classinfo *) that; */
-
-       return (*env)->IsInstanceOf(env, (jobject) obj, that);
+       return builtin_instanceof((java_objectheader*)obj, (classinfo*)that);
 }
 
 
@@ -766,46 +780,64 @@ JNIEXPORT s4 JNICALL Java_java_lang_VMClass_isPrimitive(JNIEnv *env, jclass claz
 }
 
 
-
-
 /*
- * Class:     java_lang_VMClass
+ * Class:     java/lang/VMClass
  * Method:    initialize
  * Signature: ()V
  */
-JNIEXPORT void JNICALL Java_java_lang_VMClass_initialize(JNIEnv *env, jclass clazz, java_lang_Class *that)
+JNIEXPORT void JNICALL Java_java_lang_VMClass_initialize(JNIEnv *env, jclass clazz, java_lang_Class *c)
 {
-       log_text("Java_java_lang_VMClass_initialize");
+       classinfo *ci;
+
+       ci = (classinfo *) c;
+
+       /* initialize class */
+       if (!ci->initialized)
+               /* No need to check return value, because class_init already sets the */
+               /* exception pointer. */
+               (void) class_init(ci);
 }
 
 
 /*
- * Class:     java_lang_VMClass
+ * Class:     java/lang/VMClass
  * Method:    loadArrayClass
  * Signature: (Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/lang/Class;
  */
-JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_loadArrayClass(JNIEnv *env, jclass clazz, java_lang_String *par1, java_lang_ClassLoader* par2)
+JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClass_loadArrayClass(JNIEnv *env, jclass clazz, java_lang_String *name, java_lang_ClassLoader *classloader)
 {
-       log_text("Java_java_lang_VMClass_loadArrayClass");
+       classinfo *c;
+       utf       *u;
+
+       /* create utf string with `.' replaced by `/' */
+
+       u = javastring_toutf(name, true);
 
-       return 0;
+       /* class_new "loads" the array class */
+
+       c = class_new(u);
+
+       /* set the classloader */
+
+       c->classloader = (java_objectheader*) classloader; /* XXX is this correct? */
+
+       use_class_as_object(c);
+
+       return (java_lang_Class *) c;
 }
 
 
 /*
- * Class:     java_lang_VMClass
+ * Class:     java/lang/VMClass
  * Method:    throwException
  * Signature: (Ljava/lang/Throwable;)V
  */
-JNIEXPORT void JNICALL Java_java_lang_VMClass_throwException(JNIEnv *env, jclass clazz, java_lang_Throwable *par1)
+JNIEXPORT void JNICALL Java_java_lang_VMClass_throwException(JNIEnv *env, jclass clazz, java_lang_Throwable *t)
 {
-       log_text("Won't implement VmClass.throwException. (Not needed according to spec) Is only needed to be bug compatible with the SUN VM. (according to gnuclasspath team)");
+       *exceptionptr = (java_objectheader *) t;
 }
 
 
-
-
-
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where