* src/vm/vm.c, src/vm/vm.h: Moved to .cpp.
[cacao.git] / src / vmcore / primitivecore.c
1 /* src/vmcore/primitivecore.c - core functions for primitive types
2
3    Copyright (C) 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #include "config.h"
27
28 #include <assert.h>
29 #include <stdint.h>
30
31 #include "vm/global.h"
32 #include "vm/primitive.hpp"
33 #include "vm/vm.hpp"
34
35 #include "vmcore/class.h"
36 #include "vmcore/options.h"
37 #include "vmcore/utf8.h"
38
39
40 /* primitivetype_table *********************************************************
41
42    Structure for primitive classes: contains the class for wrapping
43    the primitive type, the primitive class, the name of the class for
44    wrapping, the one character type signature and the name of the
45    primitive class.
46  
47    CAUTION: Don't change the order of the types. This table is indexed
48    by the ARRAYTYPE_ constants (except ARRAYTYPE_OBJECT).
49
50 *******************************************************************************/
51
52 primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = {
53         { "int"     , NULL, NULL, NULL, "java/lang/Integer",   'I', "[I", NULL },
54         { "long"    , NULL, NULL, NULL, "java/lang/Long",      'J', "[J", NULL },
55         { "float"   , NULL, NULL, NULL, "java/lang/Float",     'F', "[F", NULL },
56         { "double"  , NULL, NULL, NULL, "java/lang/Double",    'D', "[D", NULL },
57         { NULL      , NULL, NULL, NULL, NULL,                   0 , NULL, NULL },
58         { "byte"    , NULL, NULL, NULL, "java/lang/Byte",      'B', "[B", NULL },
59         { "char"    , NULL, NULL, NULL, "java/lang/Character", 'C', "[C", NULL },
60         { "short"   , NULL, NULL, NULL, "java/lang/Short",     'S', "[S", NULL },
61         { "boolean" , NULL, NULL, NULL, "java/lang/Boolean",   'Z', "[Z", NULL },
62         { NULL      , NULL, NULL, NULL, NULL,                   0 , NULL, NULL },
63 #if defined(ENABLE_JAVASE)
64         { "void"    , NULL, NULL, NULL, "java/lang/Void",      'V', NULL, NULL }
65 #else
66         { NULL      , NULL, NULL, NULL, NULL,                   0 , NULL, NULL },
67 #endif
68 };
69
70
71 /* primitive_init **************************************************************
72
73    Fill the primitive type table with the primitive-type classes,
74    array-classes and wrapper classes.  This is important in the VM
75    startup.
76
77    We split this primitive-type table initialization because of
78    annotations in the bootstrap classes.
79
80    But we may get a problem if we have annotations in:
81
82    java/lang/Object
83    java/lang/Cloneable
84    java/io/Serializable
85
86    Also see: loader_preinit and linker_preinit.
87
88 *******************************************************************************/
89
90 void primitive_init(void)
91 {  
92         utf       *name;
93         classinfo *c;
94         utf       *u;
95         classinfo *ac;
96         int        i;
97
98         TRACESUBSYSTEMINITIALIZATION("primitive_init");
99
100         /* Load and link primitive-type classes and array-classes. */
101
102         for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
103                 /* Skip dummy entries. */
104
105                 if (primitivetype_table[i].cname == NULL)
106                         continue;
107
108                 /* create UTF-8 name */
109
110                 name = utf_new_char(primitivetype_table[i].cname);
111
112                 primitivetype_table[i].name = name;
113
114                 /* create primitive class */
115
116                 c = class_create_classinfo(name);
117
118                 /* Primitive type classes don't have a super class. */
119
120                 c->super = NULL;
121
122                 /* set flags and mark it as primitive class */
123
124                 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT | ACC_CLASS_PRIMITIVE;
125                 
126                 /* prevent loader from loading primitive class */
127
128                 c->state |= CLASS_LOADED;
129
130                 /* INFO: don't put primitive classes into the classcache */
131
132                 if (!link_class(c))
133                         vm_abort("linker_init: linking failed");
134
135                 /* Just to be sure. */
136
137                 assert(c->state & CLASS_LOADED);
138                 assert(c->state & CLASS_LINKED);
139
140                 primitivetype_table[i].class_primitive = c;
141
142                 /* Create primitive array class. */
143
144                 if (primitivetype_table[i].arrayname != NULL) {
145                         u  = utf_new_char(primitivetype_table[i].arrayname);
146                         ac = class_create_classinfo(u);
147                         ac = load_newly_created_array(ac, NULL);
148
149                         if (ac == NULL)
150                                 vm_abort("primitive_init: loading failed");
151
152                         assert(ac->state & CLASS_LOADED);
153
154                         if (!link_class(ac))
155                                 vm_abort("primitive_init: linking failed");
156
157                         /* Just to be sure. */
158
159                         assert(ac->state & CLASS_LOADED);
160                         assert(ac->state & CLASS_LINKED);
161
162                         primitivetype_table[i].arrayclass = ac;
163                 }
164         }
165
166         /* We use two for-loops to have the array-classes already in the
167            primitive-type table (hint: annotations in wrapper-classes). */
168
169         for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
170                 /* Skip dummy entries. */
171
172                 if (primitivetype_table[i].cname == NULL)
173                         continue;
174
175                 /* Create class for wrapping the primitive type. */
176
177                 u = utf_new_char(primitivetype_table[i].wrapname);
178                 c = load_class_bootstrap(u);
179
180                 if (c == NULL)
181                         vm_abort("primitive_init: loading failed");
182
183                 if (!link_class(c))
184                         vm_abort("primitive_init: linking failed");
185
186                 /* Just to be sure. */
187
188                 assert(c->state & CLASS_LOADED);
189                 assert(c->state & CLASS_LINKED);
190
191                 primitivetype_table[i].class_wrap = c;
192         }
193 }
194
195
196 /* primitive_postinit **********************************************************
197
198    Finish the primitive-type table initialization.  In this step we
199    set the vftbl of the primitive-type classes.
200
201    This is necessary because java/lang/Class is loaded and linked
202    after the primitive types have been linked.
203
204    We have to do that in an extra function, as the primitive types are
205    not stored in the classcache.
206
207 *******************************************************************************/
208
209 void primitive_postinit(void)
210 {
211         classinfo *c;
212         int        i;
213
214         TRACESUBSYSTEMINITIALIZATION("primitive_postinit");
215
216         assert(class_java_lang_Class);
217         assert(class_java_lang_Class->vftbl);
218
219         for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
220                 /* Skip dummy entries. */
221
222                 if (primitivetype_table[i].cname == NULL)
223                         continue;
224
225                 c = primitivetype_table[i].class_primitive;
226
227                 c->object.header.vftbl = class_java_lang_Class->vftbl;
228         }
229 }
230
231
232 /*
233  * These are local overrides for various environment variables in Emacs.
234  * Please do not remove this and leave it at the end of the file, where
235  * Emacs will automagically detect them.
236  * ---------------------------------------------------------------------
237  * Local variables:
238  * mode: c
239  * indent-tabs-mode: t
240  * c-basic-offset: 4
241  * tab-width: 4
242  * End:
243  * vim:noexpandtab:sw=4:ts=4:
244  */