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"
34 #include "vm/class.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 * Unbox a primitive of the given type. Also checks if the
485 * boxed primitive type can be widened into the destination
486 * type. This conversion is done according to
487 * "The Java Language Specification, Third Edition,
488 * $5.1.2 Widening Primitive Conversion".
490 * @param h Handle of the boxing Java object.
491 * @param type Destination type of the conversion.
492 * @param value Pointer to union where the resulting primitive
493 * value will be stored will.
495 * @return True of the conversion is allowed, false otherwise.
497 bool Primitive::unbox_typed(java_handle_t *h, int type, imm_union* value)
505 LLNI_class_get(h, c);
507 src_type = get_type_by_wrapperclass(c);
510 case PRIMITIVETYPE_BOOLEAN:
512 case PRIMITIVETYPE_BOOLEAN:
513 value->i = unbox_boolean(h);
519 case PRIMITIVETYPE_BYTE:
521 case PRIMITIVETYPE_BYTE:
522 case PRIMITIVETYPE_SHORT:
523 case PRIMITIVETYPE_INT:
524 value->i = unbox_byte(h);
526 case PRIMITIVETYPE_LONG:
527 value->l = unbox_byte(h);
529 case PRIMITIVETYPE_FLOAT:
530 value->f = unbox_byte(h);
532 case PRIMITIVETYPE_DOUBLE:
533 value->d = unbox_byte(h);
539 case PRIMITIVETYPE_CHAR:
541 case PRIMITIVETYPE_CHAR:
542 case PRIMITIVETYPE_INT:
543 value->i = unbox_char(h);
545 case PRIMITIVETYPE_LONG:
546 value->l = unbox_char(h);
548 case PRIMITIVETYPE_FLOAT:
549 value->f = unbox_char(h);
551 case PRIMITIVETYPE_DOUBLE:
552 value->d = unbox_char(h);
558 case PRIMITIVETYPE_SHORT:
560 case PRIMITIVETYPE_SHORT:
561 case PRIMITIVETYPE_INT:
562 value->i = unbox_short(h);
564 case PRIMITIVETYPE_LONG:
565 value->l = unbox_short(h);
567 case PRIMITIVETYPE_FLOAT:
568 value->f = unbox_short(h);
570 case PRIMITIVETYPE_DOUBLE:
571 value->d = unbox_short(h);
577 case PRIMITIVETYPE_INT:
579 case PRIMITIVETYPE_INT:
580 value->i = unbox_int(h);
582 case PRIMITIVETYPE_LONG:
583 value->l = unbox_int(h);
585 case PRIMITIVETYPE_FLOAT:
586 value->f = unbox_int(h);
588 case PRIMITIVETYPE_DOUBLE:
589 value->d = unbox_int(h);
595 case PRIMITIVETYPE_LONG:
597 case PRIMITIVETYPE_LONG:
598 value->l = unbox_long(h);
600 case PRIMITIVETYPE_FLOAT:
601 value->f = unbox_long(h);
603 case PRIMITIVETYPE_DOUBLE:
604 value->d = unbox_long(h);
610 case PRIMITIVETYPE_FLOAT:
612 case PRIMITIVETYPE_FLOAT:
613 value->f = unbox_float(h);
615 case PRIMITIVETYPE_DOUBLE:
616 value->d = unbox_float(h);
622 case PRIMITIVETYPE_DOUBLE:
624 case PRIMITIVETYPE_DOUBLE:
625 value->d = unbox_double(h);
632 os::abort("Primitive::unbox_typed: Invalid primitive type %d", type);
639 * Box a primitive type.
641 java_handle_t* Primitive::box(uint8_t value)
643 java_handle_t *h = builtin_new(class_java_lang_Boolean);
648 java_lang_Boolean b(h);
654 java_handle_t* Primitive::box(int8_t value)
656 java_handle_t *h = builtin_new(class_java_lang_Byte);
667 java_handle_t* Primitive::box(uint16_t value)
669 java_handle_t *h = builtin_new(class_java_lang_Character);
674 java_lang_Character c(h);
680 java_handle_t* Primitive::box(int16_t value)
682 java_handle_t *h = builtin_new(class_java_lang_Short);
687 java_lang_Short s(h);
693 java_handle_t* Primitive::box(int32_t value)
695 java_handle_t *h = builtin_new(class_java_lang_Integer);
700 java_lang_Integer i(h);
706 java_handle_t* Primitive::box(int64_t value)
708 java_handle_t *h = builtin_new(class_java_lang_Long);
719 java_handle_t* Primitive::box(float value)
721 java_handle_t *h = builtin_new(class_java_lang_Float);
726 java_lang_Float f(h);
732 java_handle_t* Primitive::box(double value)
734 java_handle_t *h = builtin_new(class_java_lang_Double);
739 java_lang_Double d(h);
748 * Unbox a primitive type.
751 // template<class T> T Primitive::unbox(java_handle_t *h)
753 // return java_lang_Boolean::get_value(h);
756 inline uint8_t Primitive::unbox_boolean(java_handle_t *h)
758 java_lang_Boolean b(h);
759 return b.get_value();
762 inline int8_t Primitive::unbox_byte(java_handle_t *h)
765 return b.get_value();
768 inline uint16_t Primitive::unbox_char(java_handle_t *h)
770 java_lang_Character c(h);
771 return c.get_value();
774 inline int16_t Primitive::unbox_short(java_handle_t *h)
776 java_lang_Short s(h);
777 return s.get_value();
780 inline int32_t Primitive::unbox_int(java_handle_t *h)
782 java_lang_Integer i(h);
783 return i.get_value();
786 inline int64_t Primitive::unbox_long(java_handle_t *h)
789 return l.get_value();
792 inline float Primitive::unbox_float(java_handle_t *h)
794 java_lang_Float f(h);
795 return f.get_value();
798 inline double Primitive::unbox_double(java_handle_t *h)
800 java_lang_Double d(h);
801 return d.get_value();
806 // Legacy C interface.
810 classinfo* Primitive_get_class_by_name(utf *name) { return Primitive::get_class_by_name(name); }
811 classinfo* Primitive_get_class_by_type(int type) { return Primitive::get_class_by_type(type); }
812 classinfo* Primitive_get_arrayclass_by_type(int type) { return Primitive::get_arrayclass_by_type(type); }
817 * These are local overrides for various environment variables in Emacs.
818 * Please do not remove this and leave it at the end of the file, where
819 * Emacs will automagically detect them.
820 * ---------------------------------------------------------------------
823 * indent-tabs-mode: t
827 * vim:noexpandtab:sw=4:ts=4: