* literalstring_u2: Bugfix when reorganizing the string hashtable, the
[cacao.git] / src / vm / class.c
index be3c569ac31a3ad2cdc6443b5c3efe2819d55d6e..394da80f6b44157e0046e3590feb2fd8d8ba7029 100644 (file)
@@ -30,7 +30,7 @@
             Andreas Krall
             Christian Thalinger
 
-   $Id: class.c 2257 2005-04-11 09:42:19Z twisti $
+   $Id: class.c 3292 2005-09-28 10:36:34Z twisti $
 
 */
 
@@ -93,6 +93,9 @@ classinfo *class_java_lang_Cloneable = NULL;
 classinfo *class_java_lang_SecurityManager = NULL;
 classinfo *class_java_lang_String = NULL;
 classinfo *class_java_lang_System = NULL;
+classinfo *class_java_lang_Thread = NULL;
+classinfo *class_java_lang_ThreadGroup = NULL;
+classinfo *class_java_lang_VMThread = NULL;
 classinfo *class_java_io_Serializable = NULL;
 
 
@@ -100,10 +103,12 @@ classinfo *class_java_io_Serializable = NULL;
 
 classinfo *class_java_lang_Throwable = NULL;
 classinfo *class_java_lang_VMThrowable = NULL;
-classinfo *class_java_lang_Exception = NULL;
 classinfo *class_java_lang_Error = NULL;
-classinfo *class_java_lang_OutOfMemoryError = NULL;
 classinfo *class_java_lang_NoClassDefFoundError = NULL;
+classinfo *class_java_lang_OutOfMemoryError = NULL;
+
+classinfo *class_java_lang_Exception = NULL;
+classinfo *class_java_lang_ClassNotFoundException = NULL;
 
 classinfo *class_java_lang_Void = NULL;
 classinfo *class_java_lang_Boolean = NULL;
@@ -115,10 +120,18 @@ classinfo *class_java_lang_Long = NULL;
 classinfo *class_java_lang_Float = NULL;
 classinfo *class_java_lang_Double = NULL;
 
+
 /* some classes which may be used more often */
 
+classinfo *class_java_lang_StackTraceElement = NULL;
+classinfo *class_java_lang_reflect_Constructor = NULL;
+classinfo *class_java_lang_reflect_Field = NULL;
+classinfo *class_java_lang_reflect_Method = NULL;
+classinfo *class_java_security_PrivilegedAction = NULL;
 classinfo *class_java_util_Vector = NULL;
 
+classinfo *arrayclass_java_lang_Object = NULL;
+
 
 /* pseudo classes for the typechecker */
 
@@ -127,27 +140,67 @@ classinfo *pseudo_class_Null = NULL;
 classinfo *pseudo_class_New = NULL;
 
 
+/* class_set_packagename *******************************************************
+
+   Derive the package name from the class name and store it in the struct.
+
+*******************************************************************************/
+
+void class_set_packagename(classinfo *c)
+{
+       char *p = UTF_END(c->name) - 1;
+       char *start = c->name->text;
+
+       /* set the package name */
+       /* classes in the unnamed package keep packagename == NULL */
+
+       if (c->name->text[0] == '[') {
+               /* set packagename of arrays to the element's package */
+
+               for (; *start == '['; start++);
+
+               /* skip the 'L' in arrays of references */
+               if (*start == 'L')
+                       start++;
+
+               for (; (p > start) && (*p != '/'); --p);
+
+               c->packagename = utf_new(start, p - start);
+
+       } else {
+               for (; (p > start) && (*p != '/'); --p);
+
+               c->packagename = utf_new(start, p - start);
+       }
+}
+
+
 /* class_create_classinfo ******************************************************
 
-   XXX
+   Create a new classinfo struct. The class name is set to the given utf *,
+   most other fields are initialized to zero.
+
+   Note: classname may be NULL. In this case a not-yet-named classinfo is
+         created. The name must be filled in later and class_set_packagename
+                must be called after that.
 
 *******************************************************************************/
 
 classinfo *class_create_classinfo(utf *classname)
 {
-       classinfo *c;     /* hashtable element */
+       classinfo *c;
 
 #if defined(STATISTICS)
        if (opt_stat)
                count_class_infos += sizeof(classinfo);
 #endif
 
-       if (initverbose) {
-               char logtext[MAXLOGTEXT];
-               sprintf(logtext, "Creating class: ");
-               utf_sprint_classname(logtext + strlen(logtext), classname);
-               log_text(logtext);
-       }
+       /* we use a safe name for temporarily unnamed classes */
+       if (!classname)
+               classname = utf_not_named_yet;
+
+       if (initverbose)
+               log_message_utf("Creating class: ", classname);
 
        c = GCNEW(classinfo, 1); /*JOWENN: NEW*/
        /*c=NEW(classinfo);*/
@@ -188,21 +241,8 @@ classinfo *class_create_classinfo(utf *classname)
        c->classloader = NULL;
        c->sourcefile = NULL;
        
-       if (c->name->text[0] == '[') {
-               /* Array classes are not loaded from classfiles. */
-               c->packagename = array_packagename;
-
-       } else {
-               /* Find the package name */
-               /* Classes in the unnamed package keep packagename == NULL. */
-               char *p = utf_end(c->name) - 1;
-               char *start = c->name->text;
-               for (;p > start; --p) {
-                       if (*p == '/') {
-                               c->packagename = utf_new(start, p - start);
-                               break;
-                       }
-               }
+       if (classname != utf_not_named_yet) {
+               class_set_packagename(c);
        }
 
 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
@@ -372,7 +412,9 @@ void class_free(classinfo *c)
 /* get_array_class *************************************************************
 
    Returns the array class with the given name for the given
-   classloader.
+   classloader, or NULL if an exception occurred.
+
+   Note: This function does eager loading. 
 
 *******************************************************************************/
 
@@ -383,16 +425,16 @@ static classinfo *get_array_class(utf *name,java_objectheader *initloader,
        
        /* lookup this class in the classcache */
        c = classcache_lookup(initloader,name);
-       if (c)
-               return c;
-       c = classcache_lookup_defined(defloader,name);
-       if (c)
-               return c;
-
-       /* we have to create it */
-       c = class_create_classinfo(name);
-       if (!load_newly_created_array(c,initloader))
-               return NULL;
+       if (!c)
+               c = classcache_lookup_defined(defloader,name);
+
+       if (!c) {
+               /* we have to create it */
+               c = class_create_classinfo(name);
+               c = load_newly_created_array(c,initloader);
+               if (c == NULL)
+                       return NULL;
+       }
 
        CLASS_ASSERT(c);
        CLASS_ASSERT(c->loaded);
@@ -459,8 +501,10 @@ classinfo *class_multiarray_of(s4 dim, classinfo *element, bool link)
     s4 namelen;
     char *namebuf;
 
-       if (dim < 1)
-               panic("Invalid array dimension requested");
+       if (dim < 1) {
+               log_text("Invalid array dimension requested");
+               assert(0);
+       }
 
     /* Assemble the array class name */
     namelen = element->name->blength;
@@ -569,6 +613,25 @@ constant_classref *class_get_classref(classinfo *cls, utf *name)
 }
 
 
+/* class_get_self_classref *****************************************************
+
+   Returns the constant_classref to the class itself.
+
+   IN:
+       cls..............the class containing the reference
+
+   RETURN VALUE:
+       a pointer to a constant_classref (never NULL)
+
+*******************************************************************************/
+
+constant_classref *class_get_self_classref(classinfo *cls)
+{
+       /* XXX this should be done in a faster way. Maybe always make */
+       /* the classref of index 0 a self reference.                  */
+       return class_get_classref(cls,cls->name);
+}
+
 /* class_get_classref_multiarray_of ********************************************
 
    Returns an array type reference with the given dimension and element class