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 * Returns the primitive type of the given primitive-class.
375 * @param c Class structure.
377 * @return Integer type of the class.
379 int Primitive::get_type_by_primitiveclass(classinfo *c)
381 /* Search primitive table. */
383 for (int i = 0; i < PRIMITIVETYPE_COUNT; i++)
384 if (primitivetype_table[i].class_primitive == c)
387 /* Invalid primitive class. */
394 * Box a primitive of the given type. If the type is an object,
397 * @param type Type of the passed value.
398 * @param value Value to box.
400 * @return Handle of the boxing Java object.
402 java_handle_t* Primitive::box(int type, imm_union value)
407 case PRIMITIVETYPE_BOOLEAN:
408 o = box((uint8_t) value.i);
410 case PRIMITIVETYPE_BYTE:
411 o = box((int8_t) value.i);
413 case PRIMITIVETYPE_CHAR:
414 o = box((uint16_t) value.i);
416 case PRIMITIVETYPE_SHORT:
417 o = box((int16_t) value.i);
419 case PRIMITIVETYPE_INT:
422 case PRIMITIVETYPE_LONG:
425 case PRIMITIVETYPE_FLOAT:
428 case PRIMITIVETYPE_DOUBLE:
431 case PRIMITIVETYPE_VOID:
432 o = (java_handle_t*) value.a;
436 os::abort("Primitive::box: Invalid primitive type %d", type);
444 * Unbox a primitive of the given type. If the type is an object,
447 * @param h Handle of the Java object.
449 * @return Unboxed value as union.
451 imm_union Primitive::unbox(java_handle_t *h)
462 LLNI_class_get(h, c);
464 type = get_type_by_wrapperclass(c);
467 case PRIMITIVETYPE_BOOLEAN:
468 value.i = unbox_boolean(h);
470 case PRIMITIVETYPE_BYTE:
471 value.i = unbox_byte(h);
473 case PRIMITIVETYPE_CHAR:
474 value.i = unbox_char(h);
476 case PRIMITIVETYPE_SHORT:
477 value.i = unbox_short(h);
479 case PRIMITIVETYPE_INT:
480 value.i = unbox_int(h);
482 case PRIMITIVETYPE_LONG:
483 value.l = unbox_long(h);
485 case PRIMITIVETYPE_FLOAT:
486 value.f = unbox_float(h);
488 case PRIMITIVETYPE_DOUBLE:
489 value.d = unbox_double(h);
492 /* If type is -1 the object is not a primitive box but a
497 os::abort("Primitive::unbox: Invalid primitive type %d", type);
505 * Unbox a primitive of the given type. Also checks if the
506 * boxed primitive type can be widened into the destination
507 * type. This conversion is done according to
508 * "The Java Language Specification, Third Edition,
509 * $5.1.2 Widening Primitive Conversion".
511 * @param h Handle of the boxing Java object.
512 * @param type Destination type of the conversion.
513 * @param value Pointer to union where the resulting primitive
514 * value will be stored will.
516 * @return True of the conversion is allowed, false otherwise.
518 bool Primitive::unbox_typed(java_handle_t *h, int type, imm_union* value)
526 LLNI_class_get(h, c);
528 src_type = get_type_by_wrapperclass(c);
531 case PRIMITIVETYPE_BOOLEAN:
533 case PRIMITIVETYPE_BOOLEAN:
534 value->i = unbox_boolean(h);
540 case PRIMITIVETYPE_BYTE:
542 case PRIMITIVETYPE_BYTE:
543 case PRIMITIVETYPE_SHORT:
544 case PRIMITIVETYPE_INT:
545 value->i = unbox_byte(h);
547 case PRIMITIVETYPE_LONG:
548 value->l = unbox_byte(h);
550 case PRIMITIVETYPE_FLOAT:
551 value->f = unbox_byte(h);
553 case PRIMITIVETYPE_DOUBLE:
554 value->d = unbox_byte(h);
560 case PRIMITIVETYPE_CHAR:
562 case PRIMITIVETYPE_CHAR:
563 case PRIMITIVETYPE_INT:
564 value->i = unbox_char(h);
566 case PRIMITIVETYPE_LONG:
567 value->l = unbox_char(h);
569 case PRIMITIVETYPE_FLOAT:
570 value->f = unbox_char(h);
572 case PRIMITIVETYPE_DOUBLE:
573 value->d = unbox_char(h);
579 case PRIMITIVETYPE_SHORT:
581 case PRIMITIVETYPE_SHORT:
582 case PRIMITIVETYPE_INT:
583 value->i = unbox_short(h);
585 case PRIMITIVETYPE_LONG:
586 value->l = unbox_short(h);
588 case PRIMITIVETYPE_FLOAT:
589 value->f = unbox_short(h);
591 case PRIMITIVETYPE_DOUBLE:
592 value->d = unbox_short(h);
598 case PRIMITIVETYPE_INT:
600 case PRIMITIVETYPE_INT:
601 value->i = unbox_int(h);
603 case PRIMITIVETYPE_LONG:
604 value->l = unbox_int(h);
606 case PRIMITIVETYPE_FLOAT:
607 value->f = unbox_int(h);
609 case PRIMITIVETYPE_DOUBLE:
610 value->d = unbox_int(h);
616 case PRIMITIVETYPE_LONG:
618 case PRIMITIVETYPE_LONG:
619 value->l = unbox_long(h);
621 case PRIMITIVETYPE_FLOAT:
622 value->f = unbox_long(h);
624 case PRIMITIVETYPE_DOUBLE:
625 value->d = unbox_long(h);
631 case PRIMITIVETYPE_FLOAT:
633 case PRIMITIVETYPE_FLOAT:
634 value->f = unbox_float(h);
636 case PRIMITIVETYPE_DOUBLE:
637 value->d = unbox_float(h);
643 case PRIMITIVETYPE_DOUBLE:
645 case PRIMITIVETYPE_DOUBLE:
646 value->d = unbox_double(h);
653 os::abort("Primitive::unbox_typed: Invalid primitive type %d", type);
660 * Box a primitive type.
662 java_handle_t* Primitive::box(uint8_t value)
664 java_handle_t *h = builtin_new(class_java_lang_Boolean);
669 java_lang_Boolean b(h);
675 java_handle_t* Primitive::box(int8_t value)
677 java_handle_t *h = builtin_new(class_java_lang_Byte);
688 java_handle_t* Primitive::box(uint16_t value)
690 java_handle_t *h = builtin_new(class_java_lang_Character);
695 java_lang_Character c(h);
701 java_handle_t* Primitive::box(int16_t value)
703 java_handle_t *h = builtin_new(class_java_lang_Short);
708 java_lang_Short s(h);
714 java_handle_t* Primitive::box(int32_t value)
716 java_handle_t *h = builtin_new(class_java_lang_Integer);
721 java_lang_Integer i(h);
727 java_handle_t* Primitive::box(int64_t value)
729 java_handle_t *h = builtin_new(class_java_lang_Long);
740 java_handle_t* Primitive::box(float value)
742 java_handle_t *h = builtin_new(class_java_lang_Float);
747 java_lang_Float f(h);
753 java_handle_t* Primitive::box(double value)
755 java_handle_t *h = builtin_new(class_java_lang_Double);
760 java_lang_Double d(h);
769 * Unbox a primitive type.
772 // template<class T> T Primitive::unbox(java_handle_t *h)
774 // return java_lang_Boolean::get_value(h);
777 inline uint8_t Primitive::unbox_boolean(java_handle_t *h)
779 java_lang_Boolean b(h);
780 return b.get_value();
783 inline int8_t Primitive::unbox_byte(java_handle_t *h)
786 return b.get_value();
789 inline uint16_t Primitive::unbox_char(java_handle_t *h)
791 java_lang_Character c(h);
792 return c.get_value();
795 inline int16_t Primitive::unbox_short(java_handle_t *h)
797 java_lang_Short s(h);
798 return s.get_value();
801 inline int32_t Primitive::unbox_int(java_handle_t *h)
803 java_lang_Integer i(h);
804 return i.get_value();
807 inline int64_t Primitive::unbox_long(java_handle_t *h)
810 return l.get_value();
813 inline float Primitive::unbox_float(java_handle_t *h)
815 java_lang_Float f(h);
816 return f.get_value();
819 inline double Primitive::unbox_double(java_handle_t *h)
821 java_lang_Double d(h);
822 return d.get_value();
827 * These are local overrides for various environment variables in Emacs.
828 * Please do not remove this and leave it at the end of the file, where
829 * Emacs will automagically detect them.
830 * ---------------------------------------------------------------------
833 * indent-tabs-mode: t
837 * vim:noexpandtab:sw=4:ts=4: