* src/vm/vm.c, src/vm/vm.h: Moved to .cpp.
[cacao.git] / src / vmcore / primitivecore.c
index 34318a01e484d6774bcaab14dba10d52d0f1fb12..5f4cac830832c9759e76da40c42bca35e9884639 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vmcore/primitivecore.c - core functions for primitive types
 
-   Copyright (C) 2007 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
+   Copyright (C) 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
 #include <stdint.h>
 
 #include "vm/global.h"
-#include "vm/primitive.h"
+#include "vm/primitive.hpp"
+#include "vm/vm.hpp"
 
 #include "vmcore/class.h"
+#include "vmcore/options.h"
 #include "vmcore/utf8.h"
 
 
@@ -70,19 +70,37 @@ primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = {
 
 /* primitive_init **************************************************************
 
-   Create classes representing primitive types.
+   Fill the primitive type table with the primitive-type classes,
+   array-classes and wrapper classes.  This is important in the VM
+   startup.
+
+   We split this primitive-type table initialization because of
+   annotations in the bootstrap classes.
+
+   But we may get a problem if we have annotations in:
+
+   java/lang/Object
+   java/lang/Cloneable
+   java/io/Serializable
+
+   Also see: loader_preinit and linker_preinit.
 
 *******************************************************************************/
 
-bool primitive_init(void)
+void primitive_init(void)
 {  
        utf       *name;
        classinfo *c;
        utf       *u;
+       classinfo *ac;
        int        i;
 
+       TRACESUBSYSTEMINITIALIZATION("primitive_init");
+
+       /* Load and link primitive-type classes and array-classes. */
+
        for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
-               /* skip dummies */
+               /* Skip dummy entries. */
 
                if (primitivetype_table[i].cname == NULL)
                        continue;
@@ -97,9 +115,9 @@ bool primitive_init(void)
 
                c = class_create_classinfo(name);
 
-               /* primitive classes don't have a super class */
+               /* Primitive type classes don't have a super class. */
 
-               c->super.any = NULL;
+               c->super = NULL;
 
                /* set flags and mark it as primitive class */
 
@@ -112,41 +130,102 @@ bool primitive_init(void)
                /* INFO: don't put primitive classes into the classcache */
 
                if (!link_class(c))
-                       return false;
+                       vm_abort("linker_init: linking failed");
+
+               /* Just to be sure. */
+
+               assert(c->state & CLASS_LOADED);
+               assert(c->state & CLASS_LINKED);
 
                primitivetype_table[i].class_primitive = c;
 
-               /* create class for wrapping the primitive type */
+               /* Create primitive array class. */
+
+               if (primitivetype_table[i].arrayname != NULL) {
+                       u  = utf_new_char(primitivetype_table[i].arrayname);
+                       ac = class_create_classinfo(u);
+                       ac = load_newly_created_array(ac, NULL);
+
+                       if (ac == NULL)
+                               vm_abort("primitive_init: loading failed");
+
+                       assert(ac->state & CLASS_LOADED);
+
+                       if (!link_class(ac))
+                               vm_abort("primitive_init: linking failed");
+
+                       /* Just to be sure. */
+
+                       assert(ac->state & CLASS_LOADED);
+                       assert(ac->state & CLASS_LINKED);
+
+                       primitivetype_table[i].arrayclass = ac;
+               }
+       }
+
+       /* We use two for-loops to have the array-classes already in the
+          primitive-type table (hint: annotations in wrapper-classes). */
+
+       for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
+               /* Skip dummy entries. */
+
+               if (primitivetype_table[i].cname == NULL)
+                       continue;
+
+               /* Create class for wrapping the primitive type. */
 
                u = utf_new_char(primitivetype_table[i].wrapname);
                c = load_class_bootstrap(u);
 
                if (c == NULL)
-                       return false;
+                       vm_abort("primitive_init: loading failed");
+
+               if (!link_class(c))
+                       vm_abort("primitive_init: linking failed");
+
+               /* Just to be sure. */
+
+               assert(c->state & CLASS_LOADED);
+               assert(c->state & CLASS_LINKED);
 
                primitivetype_table[i].class_wrap = c;
+       }
+}
 
-               /* create the primitive array class */
 
-               if (primitivetype_table[i].arrayname) {
-                       u = utf_new_char(primitivetype_table[i].arrayname);
-                       c = class_create_classinfo(u);
-                       c = load_newly_created_array(c, NULL);
+/* primitive_postinit **********************************************************
 
-                       if (c == NULL)
-                               return false;
+   Finish the primitive-type table initialization.  In this step we
+   set the vftbl of the primitive-type classes.
 
-                       primitivetype_table[i].arrayclass = c;
+   This is necessary because java/lang/Class is loaded and linked
+   after the primitive types have been linked.
 
-                       assert(c->state & CLASS_LOADED);
+   We have to do that in an extra function, as the primitive types are
+   not stored in the classcache.
 
-                       if (!(c->state & CLASS_LINKED))
-                               if (!link_class(c))
-                                       return false;
-               }
-       }
+*******************************************************************************/
+
+void primitive_postinit(void)
+{
+       classinfo *c;
+       int        i;
+
+       TRACESUBSYSTEMINITIALIZATION("primitive_postinit");
+
+       assert(class_java_lang_Class);
+       assert(class_java_lang_Class->vftbl);
+
+       for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
+               /* Skip dummy entries. */
 
-       return true;
+               if (primitivetype_table[i].cname == NULL)
+                       continue;
+
+               c = primitivetype_table[i].class_primitive;
+
+               c->object.header.vftbl = class_java_lang_Class->vftbl;
+       }
 }