1 /* src/vm/primitive.cpp - primitive types
3 Copyright (C) 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
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.
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.
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
31 #include "native/llni.h"
33 #include "vm/jit/builtin.hpp"
35 #include "vm/global.h"
36 #include "vm/globals.hpp"
37 #include "vm/javaobjects.hpp"
38 #include "vm/options.h"
40 #include "vm/primitive.hpp"
44 /* primitivetype_table *********************************************************
46 Structure for primitive classes: contains the class for wrapping
47 the primitive type, the primitive class, the name of the class for
48 wrapping, the one character type signature and the name of the
51 CAUTION: Don't change the order of the types. This table is indexed
52 by the ARRAYTYPE_ constants (except ARRAYTYPE_OBJECT).
54 *******************************************************************************/
56 primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = {
57 { "int" , NULL, NULL, NULL, "java/lang/Integer", 'I', "[I", NULL },
58 { "long" , NULL, NULL, NULL, "java/lang/Long", 'J', "[J", NULL },
59 { "float" , NULL, NULL, NULL, "java/lang/Float", 'F', "[F", NULL },
60 { "double" , NULL, NULL, NULL, "java/lang/Double", 'D', "[D", NULL },
61 { NULL , NULL, NULL, NULL, NULL, 0 , NULL, NULL },
62 { "byte" , NULL, NULL, NULL, "java/lang/Byte", 'B', "[B", NULL },
63 { "char" , NULL, NULL, NULL, "java/lang/Character", 'C', "[C", NULL },
64 { "short" , NULL, NULL, NULL, "java/lang/Short", 'S', "[S", NULL },
65 { "boolean" , NULL, NULL, NULL, "java/lang/Boolean", 'Z', "[Z", NULL },
66 { NULL , NULL, NULL, NULL, NULL, 0 , NULL, NULL },
67 #if defined(ENABLE_JAVASE)
68 { "void" , NULL, NULL, NULL, "java/lang/Void", 'V', NULL, NULL }
70 { NULL , NULL, NULL, NULL, NULL, 0 , NULL, NULL },
76 * Fill the primitive type table with the primitive-type classes,
77 * array-classes and wrapper classes. This is important in the VM
80 * We split this primitive-type table initialization because of
81 * annotations in the bootstrap classes.
83 * But we may get a problem if we have annotations in:
87 * java/io/Serializable
89 * Also see: loader_preinit and linker_preinit.
91 void Primitive::initialize_table()
98 TRACESUBSYSTEMINITIALIZATION("primitive_init");
100 /* Load and link primitive-type classes and array-classes. */
102 for (int i = 0; i < PRIMITIVETYPE_COUNT; i++) {
103 /* Skip dummy entries. */
105 if (primitivetype_table[i].cname == NULL)
108 /* create UTF-8 name */
110 name = utf_new_char(primitivetype_table[i].cname);
112 primitivetype_table[i].name = name;
114 /* create primitive class */
116 c = class_create_classinfo(name);
118 /* Primitive type classes don't have a super class. */
122 /* set flags and mark it as primitive class */
124 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT | ACC_CLASS_PRIMITIVE;
126 /* prevent loader from loading primitive class */
128 c->state |= CLASS_LOADED;
130 /* INFO: don't put primitive classes into the classcache */
133 vm_abort("linker_init: linking failed");
135 /* Just to be sure. */
137 assert(c->state & CLASS_LOADED);
138 assert(c->state & CLASS_LINKED);
140 primitivetype_table[i].class_primitive = c;
142 /* Create primitive array class. */
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);
150 vm_abort("primitive_init: loading failed");
152 assert(ac->state & CLASS_LOADED);
155 vm_abort("primitive_init: linking failed");
157 /* Just to be sure. */
159 assert(ac->state & CLASS_LOADED);
160 assert(ac->state & CLASS_LINKED);
162 primitivetype_table[i].arrayclass = ac;
166 /* We use two for-loops to have the array-classes already in the
167 primitive-type table (hint: annotations in wrapper-classes). */
169 for (int i = 0; i < PRIMITIVETYPE_COUNT; i++) {
170 /* Skip dummy entries. */
172 if (primitivetype_table[i].cname == NULL)
175 /* Create class for wrapping the primitive type. */
177 u = utf_new_char(primitivetype_table[i].wrapname);
178 c = load_class_bootstrap(u);
181 vm_abort("primitive_init: loading failed");
184 vm_abort("primitive_init: linking failed");
186 /* Just to be sure. */
188 assert(c->state & CLASS_LOADED);
189 assert(c->state & CLASS_LINKED);
191 primitivetype_table[i].class_wrap = c;
197 * Finish the primitive-type table initialization. In this step we
198 * set the vftbl of the primitive-type classes.
200 * This is necessary because java/lang/Class is loaded and linked
201 * after the primitive types have been linked.
203 * We have to do that in an extra function, as the primitive types are
204 * not stored in the classcache.
206 void Primitive::post_initialize_table()
211 TRACESUBSYSTEMINITIALIZATION("primitive_postinit");
213 assert(class_java_lang_Class);
214 assert(class_java_lang_Class->vftbl);
216 for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
217 /* Skip dummy entries. */
219 if (primitivetype_table[i].cname == NULL)
222 c = primitivetype_table[i].class_primitive;
224 c->object.header.vftbl = class_java_lang_Class->vftbl;
230 * Returns the primitive class of the given class name.
232 * @param name Name of the class.
234 * @return Class structure.
236 classinfo* Primitive::get_class_by_name(utf *name)
240 /* search table of primitive classes */
242 for (i = 0; i < PRIMITIVETYPE_COUNT; i++)
243 if (primitivetype_table[i].name == name)
244 return primitivetype_table[i].class_primitive;
246 /* keep compiler happy */
253 * Returns the primitive class of the given type.
255 * @param type Integer type of the class.
257 * @return Class structure.
259 classinfo* Primitive::get_class_by_type(int type)
261 return primitivetype_table[type].class_primitive;
266 * Returns the primitive class of the given type.
270 * @return Class structure.
272 classinfo* Primitive::get_class_by_char(char ch)
278 index = PRIMITIVETYPE_INT;
281 index = PRIMITIVETYPE_LONG;
284 index = PRIMITIVETYPE_FLOAT;
287 index = PRIMITIVETYPE_DOUBLE;
290 index = PRIMITIVETYPE_BYTE;
293 index = PRIMITIVETYPE_CHAR;
296 index = PRIMITIVETYPE_SHORT;
299 index = PRIMITIVETYPE_BOOLEAN;
302 index = PRIMITIVETYPE_VOID;
308 return primitivetype_table[index].class_primitive;
313 * Returns the primitive array-class of the given primitive class
316 * @param name Name of the class.
318 * @return Class structure.
320 classinfo* Primitive::get_arrayclass_by_name(utf *name)
324 /* search table of primitive classes */
326 for (i = 0; i < PRIMITIVETYPE_COUNT; i++)
327 if (primitivetype_table[i].name == name)
328 return primitivetype_table[i].arrayclass;
330 /* keep compiler happy */
337 * Returns the primitive array-class of the given type.
339 * @param type Integer type of the class.
341 * @return Class structure.
343 classinfo* Primitive::get_arrayclass_by_type(int type)
345 return primitivetype_table[type].arrayclass;
350 * Returns the primitive type of the given wrapper-class.
352 * @param c Class structure.
354 * @return Integer type of the class.
356 int Primitive::get_type_by_wrapperclass(classinfo *c)
360 /* Search primitive table. */
362 for (i = 0; i < PRIMITIVETYPE_COUNT; i++)
363 if (primitivetype_table[i].class_wrap == c)
366 /* Invalid primitive wrapper-class. */
373 * Box a primitive of the given type. If the type is an object,
376 * @param type Type of the passed value.
377 * @param value Value to box.
379 * @return Handle of the boxing Java object.
381 java_handle_t* Primitive::box(int type, imm_union value)
386 case PRIMITIVETYPE_BOOLEAN:
387 o = box((uint8_t) value.i);
389 case PRIMITIVETYPE_BYTE:
390 o = box((int8_t) value.i);
392 case PRIMITIVETYPE_CHAR:
393 o = box((uint16_t) value.i);
395 case PRIMITIVETYPE_SHORT:
396 o = box((int16_t) value.i);
398 case PRIMITIVETYPE_INT:
401 case PRIMITIVETYPE_LONG:
404 case PRIMITIVETYPE_FLOAT:
407 case PRIMITIVETYPE_DOUBLE:
410 case PRIMITIVETYPE_VOID:
411 o = (java_handle_t*) value.a;
415 os::abort("Primitive::box: Invalid primitive type %d", type);
423 * Unbox a primitive of the given type. If the type is an object,
426 * @param h Handle of the Java object.
428 * @return Unboxed value as union.
430 imm_union Primitive::unbox(java_handle_t *h)
441 LLNI_class_get(h, c);
443 type = get_type_by_wrapperclass(c);
446 case PRIMITIVETYPE_BOOLEAN:
447 value.i = unbox_boolean(h);
449 case PRIMITIVETYPE_BYTE:
450 value.i = unbox_byte(h);
452 case PRIMITIVETYPE_CHAR:
453 value.i = unbox_char(h);
455 case PRIMITIVETYPE_SHORT:
456 value.i = unbox_short(h);
458 case PRIMITIVETYPE_INT:
459 value.i = unbox_int(h);
461 case PRIMITIVETYPE_LONG:
462 value.l = unbox_long(h);
464 case PRIMITIVETYPE_FLOAT:
465 value.f = unbox_float(h);
467 case PRIMITIVETYPE_DOUBLE:
468 value.d = unbox_double(h);
471 /* If type is -1 the object is not a primitive box but a
476 os::abort("Primitive::unbox: Invalid primitive type %d", type);
484 * Box a primitive type.
486 java_handle_t* Primitive::box(uint8_t value)
488 java_handle_t *h = builtin_new(class_java_lang_Boolean);
493 java_lang_Boolean b(h);
499 java_handle_t* Primitive::box(int8_t value)
501 java_handle_t *h = builtin_new(class_java_lang_Byte);
512 java_handle_t* Primitive::box(uint16_t value)
514 java_handle_t *h = builtin_new(class_java_lang_Character);
519 java_lang_Character c(h);
525 java_handle_t* Primitive::box(int16_t value)
527 java_handle_t *h = builtin_new(class_java_lang_Short);
532 java_lang_Short s(h);
538 java_handle_t* Primitive::box(int32_t value)
540 java_handle_t *h = builtin_new(class_java_lang_Integer);
545 java_lang_Integer i(h);
551 java_handle_t* Primitive::box(int64_t value)
553 java_handle_t *h = builtin_new(class_java_lang_Long);
564 java_handle_t* Primitive::box(float value)
566 java_handle_t *h = builtin_new(class_java_lang_Float);
571 java_lang_Float f(h);
577 java_handle_t* Primitive::box(double value)
579 java_handle_t *h = builtin_new(class_java_lang_Double);
584 java_lang_Double d(h);
593 * Unbox a primitive type.
596 // template<class T> T Primitive::unbox(java_handle_t *h)
598 // return java_lang_Boolean::get_value(h);
601 inline uint8_t Primitive::unbox_boolean(java_handle_t *h)
603 java_lang_Boolean b(h);
604 return b.get_value();
607 inline int8_t Primitive::unbox_byte(java_handle_t *h)
610 return b.get_value();
613 inline uint16_t Primitive::unbox_char(java_handle_t *h)
615 java_lang_Character c(h);
616 return c.get_value();
619 inline int16_t Primitive::unbox_short(java_handle_t *h)
621 java_lang_Short s(h);
622 return s.get_value();
625 inline int32_t Primitive::unbox_int(java_handle_t *h)
627 java_lang_Integer i(h);
628 return i.get_value();
631 inline int64_t Primitive::unbox_long(java_handle_t *h)
634 return l.get_value();
637 inline float Primitive::unbox_float(java_handle_t *h)
639 java_lang_Float f(h);
640 return f.get_value();
643 inline double Primitive::unbox_double(java_handle_t *h)
645 java_lang_Double d(h);
646 return d.get_value();
651 // Legacy C interface.
655 classinfo* Primitive_get_class_by_name(utf *name) { return Primitive::get_class_by_name(name); }
656 classinfo* Primitive_get_class_by_type(int type) { return Primitive::get_class_by_type(type); }
657 classinfo* Primitive_get_arrayclass_by_type(int type) { return Primitive::get_arrayclass_by_type(type); }
662 * These are local overrides for various environment variables in Emacs.
663 * Please do not remove this and leave it at the end of the file, where
664 * Emacs will automagically detect them.
665 * ---------------------------------------------------------------------
668 * indent-tabs-mode: t
672 * vim:noexpandtab:sw=4:ts=4: