* src/vm/jit/codegen-common.cpp, src/vm/jit/x86_64/codegen.c: Generate
[cacao.git] / src / vm / primitive.cpp
1 /* src/vm/primitive.cpp - 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 "native/llni.h"
32
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"
39 #include "vm/os.hpp"
40 #include "vm/primitive.hpp"
41 #include "vm/utf8.h"
42
43
44 /* primitivetype_table *********************************************************
45
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
49    primitive class.
50  
51    CAUTION: Don't change the order of the types. This table is indexed
52    by the ARRAYTYPE_ constants (except ARRAYTYPE_OBJECT).
53
54 *******************************************************************************/
55
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 }
69 #else
70         { NULL      , NULL, NULL, NULL, NULL,                   0 , NULL, NULL },
71 #endif
72 };
73
74
75 /**
76  * Fill the primitive type table with the primitive-type classes,
77  * array-classes and wrapper classes.  This is important in the VM
78  * startup.
79  *
80  * We split this primitive-type table initialization because of
81  * annotations in the bootstrap classes.
82  *
83  * But we may get a problem if we have annotations in:
84  *
85  * java/lang/Object
86  * java/lang/Cloneable
87  * java/io/Serializable
88  *
89  * Also see: loader_preinit and linker_preinit.
90  */
91 void Primitive::initialize_table()
92 {  
93         utf       *name;
94         classinfo *c;
95         utf       *u;
96         classinfo *ac;
97
98         TRACESUBSYSTEMINITIALIZATION("primitive_init");
99
100         /* Load and link primitive-type classes and array-classes. */
101
102         for (int 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 (int 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 /**
197  * Finish the primitive-type table initialization.  In this step we
198  * set the vftbl of the primitive-type classes.
199  *
200  * This is necessary because java/lang/Class is loaded and linked
201  * after the primitive types have been linked.
202  *
203  * We have to do that in an extra function, as the primitive types are
204  * not stored in the classcache.
205  */
206 void Primitive::post_initialize_table()
207 {
208         classinfo *c;
209         int        i;
210
211         TRACESUBSYSTEMINITIALIZATION("primitive_postinit");
212
213         assert(class_java_lang_Class);
214         assert(class_java_lang_Class->vftbl);
215
216         for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
217                 /* Skip dummy entries. */
218
219                 if (primitivetype_table[i].cname == NULL)
220                         continue;
221
222                 c = primitivetype_table[i].class_primitive;
223
224                 c->object.header.vftbl = class_java_lang_Class->vftbl;
225         }
226 }
227
228
229 /**
230  * Returns the primitive class of the given class name.
231  *
232  * @param name Name of the class.
233  *
234  * @return Class structure.
235  */
236 classinfo* Primitive::get_class_by_name(utf *name)
237 {
238         int i;
239
240         /* search table of primitive classes */
241
242         for (i = 0; i < PRIMITIVETYPE_COUNT; i++)
243                 if (primitivetype_table[i].name == name)
244                         return primitivetype_table[i].class_primitive;
245
246         /* keep compiler happy */
247
248         return NULL;
249 }
250
251
252 /**
253  * Returns the primitive class of the given type.
254  *
255  * @param type Integer type of the class.
256  *
257  * @return Class structure.
258  */
259 classinfo* Primitive::get_class_by_type(int type)
260 {
261         return primitivetype_table[type].class_primitive;
262 }
263
264
265 /**
266  * Returns the primitive class of the given type.
267  *
268  * @param ch 
269  *
270  * @return Class structure.
271  */
272 classinfo* Primitive::get_class_by_char(char ch)
273 {
274         int index;
275
276         switch (ch) {
277         case 'I':
278                 index = PRIMITIVETYPE_INT;
279                 break;
280         case 'J':
281                 index = PRIMITIVETYPE_LONG;
282                 break;
283         case 'F':
284                 index = PRIMITIVETYPE_FLOAT;
285                 break;
286         case 'D':
287                 index = PRIMITIVETYPE_DOUBLE;
288                 break;
289         case 'B':
290                 index = PRIMITIVETYPE_BYTE;
291                 break;
292         case 'C':
293                 index = PRIMITIVETYPE_CHAR;
294                 break;
295         case 'S':
296                 index = PRIMITIVETYPE_SHORT;
297                 break;
298         case 'Z':
299                 index = PRIMITIVETYPE_BOOLEAN;
300                 break;
301         case 'V':
302                 index = PRIMITIVETYPE_VOID;
303                 break;
304         default:
305                 return NULL;
306         }
307
308         return primitivetype_table[index].class_primitive;
309 }
310
311
312 /**
313  * Returns the primitive array-class of the given primitive class
314  * name.
315  *
316  * @param name Name of the class.
317  *
318  * @return Class structure.
319  */
320 classinfo* Primitive::get_arrayclass_by_name(utf *name)
321 {
322         int i;
323
324         /* search table of primitive classes */
325
326         for (i = 0; i < PRIMITIVETYPE_COUNT; i++)
327                 if (primitivetype_table[i].name == name)
328                         return primitivetype_table[i].arrayclass;
329
330         /* keep compiler happy */
331
332         return NULL;
333 }
334
335
336 /**
337  * Returns the primitive array-class of the given type.
338  *
339  * @param type Integer type of the class.
340  *
341  * @return Class structure.
342  */
343 classinfo* Primitive::get_arrayclass_by_type(int type)
344 {
345         return primitivetype_table[type].arrayclass;
346 }
347
348
349 /**
350  * Returns the primitive type of the given wrapper-class.
351  *
352  * @param c Class structure.
353  *
354  * @return Integer type of the class.
355  */
356 int Primitive::get_type_by_wrapperclass(classinfo *c)
357 {
358         int i;
359
360         /* Search primitive table. */
361
362         for (i = 0; i < PRIMITIVETYPE_COUNT; i++)
363                 if (primitivetype_table[i].class_wrap == c)
364                         return i;
365
366         /* Invalid primitive wrapper-class. */
367
368         return -1;
369 }
370
371
372 /**
373  * Box a primitive of the given type.  If the type is an object,
374  * simply return it.
375  *
376  * @param type  Type of the passed value.
377  * @param value Value to box.
378  *
379  * @return Handle of the boxing Java object.
380  */
381 java_handle_t* Primitive::box(int type, imm_union value)
382 {
383         java_handle_t* o;
384
385         switch (type) {
386         case PRIMITIVETYPE_BOOLEAN:
387                 o = box((uint8_t) value.i);
388                 break;
389         case PRIMITIVETYPE_BYTE:
390                 o = box((int8_t) value.i);
391                 break;
392         case PRIMITIVETYPE_CHAR:
393                 o = box((uint16_t) value.i);
394                 break;
395         case PRIMITIVETYPE_SHORT:
396                 o = box((int16_t) value.i);
397                 break;
398         case PRIMITIVETYPE_INT:
399                 o = box(value.i);
400                 break;
401         case PRIMITIVETYPE_LONG:
402                 o = box(value.l);
403                 break;
404         case PRIMITIVETYPE_FLOAT:
405                 o = box(value.f);
406                 break;
407         case PRIMITIVETYPE_DOUBLE:
408                 o = box(value.d);
409                 break;
410         case PRIMITIVETYPE_VOID:
411                 o = (java_handle_t*) value.a;
412                 break;
413         default:
414                 o = NULL;
415                 os::abort("Primitive::box: Invalid primitive type %d", type);
416         }
417
418         return o;
419 }
420
421
422 /**
423  * Unbox a primitive of the given type.  If the type is an object,
424  * simply return it.
425  *
426  * @param h Handle of the Java object.
427  *
428  * @return Unboxed value as union.
429  */
430 imm_union Primitive::unbox(java_handle_t *h)
431 {
432         classinfo *c;
433         int        type;
434         imm_union  value;
435
436         if (h == NULL) {
437                 value.a = NULL;
438                 return value;
439         }
440
441         LLNI_class_get(h, c);
442
443         type = get_type_by_wrapperclass(c);
444
445         switch (type) {
446         case PRIMITIVETYPE_BOOLEAN:
447                 value.i = unbox_boolean(h);
448                 break;
449         case PRIMITIVETYPE_BYTE:
450                 value.i = unbox_byte(h);
451                 break;
452         case PRIMITIVETYPE_CHAR:
453                 value.i = unbox_char(h);
454                 break;
455         case PRIMITIVETYPE_SHORT:
456                 value.i = unbox_short(h);
457                 break;
458         case PRIMITIVETYPE_INT:
459                 value.i = unbox_int(h);
460                 break;
461         case PRIMITIVETYPE_LONG:
462                 value.l = unbox_long(h);
463                 break;
464         case PRIMITIVETYPE_FLOAT:
465                 value.f = unbox_float(h);
466                 break;
467         case PRIMITIVETYPE_DOUBLE:
468                 value.d = unbox_double(h);
469                 break;
470         case -1:
471                 /* If type is -1 the object is not a primitive box but a
472                    normal object. */
473                 value.a = h;
474                 break;
475         default:
476                 os::abort("Primitive::unbox: Invalid primitive type %d", type);
477         }
478
479         return value;
480 }
481
482
483 /**
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".
489  *
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.
494  *
495  * @return True of the conversion is allowed, false otherwise.
496  */
497 bool Primitive::unbox_typed(java_handle_t *h, int type, imm_union* value)
498 {
499         classinfo *c;
500         int        src_type;
501
502         if (h == NULL)
503                 return false;
504
505         LLNI_class_get(h, c);
506
507         src_type = get_type_by_wrapperclass(c);
508
509         switch (src_type) {
510         case PRIMITIVETYPE_BOOLEAN:
511                 switch (type) {
512                         case PRIMITIVETYPE_BOOLEAN:
513                                 value->i = unbox_boolean(h);
514                                 return true;
515                         default:
516                                 return false;
517                 }
518
519         case PRIMITIVETYPE_BYTE:
520                 switch (type) {
521                         case PRIMITIVETYPE_BYTE:
522                         case PRIMITIVETYPE_SHORT:
523                         case PRIMITIVETYPE_INT:
524                                 value->i = unbox_byte(h);
525                                 return true;
526                         case PRIMITIVETYPE_LONG:
527                                 value->l = unbox_byte(h);
528                                 return true;
529                         case PRIMITIVETYPE_FLOAT:
530                                 value->f = unbox_byte(h);
531                                 return true;
532                         case PRIMITIVETYPE_DOUBLE:
533                                 value->d = unbox_byte(h);
534                                 return true;
535                         default:
536                                 return false;
537                 }
538
539         case PRIMITIVETYPE_CHAR:
540                 switch (type) {
541                         case PRIMITIVETYPE_CHAR:
542                         case PRIMITIVETYPE_INT:
543                                 value->i = unbox_char(h);
544                                 return true;
545                         case PRIMITIVETYPE_LONG:
546                                 value->l = unbox_char(h);
547                                 return true;
548                         case PRIMITIVETYPE_FLOAT:
549                                 value->f = unbox_char(h);
550                                 return true;
551                         case PRIMITIVETYPE_DOUBLE:
552                                 value->d = unbox_char(h);
553                                 return true;
554                         default:
555                                 return false;
556                 }
557
558         case PRIMITIVETYPE_SHORT:
559                 switch (type) {
560                         case PRIMITIVETYPE_SHORT:
561                         case PRIMITIVETYPE_INT:
562                                 value->i = unbox_short(h);
563                                 return true;
564                         case PRIMITIVETYPE_LONG:
565                                 value->l = unbox_short(h);
566                                 return true;
567                         case PRIMITIVETYPE_FLOAT:
568                                 value->f = unbox_short(h);
569                                 return true;
570                         case PRIMITIVETYPE_DOUBLE:
571                                 value->d = unbox_short(h);
572                                 return true;
573                         default:
574                                 return false;
575                 }
576
577         case PRIMITIVETYPE_INT:
578                 switch (type) {
579                         case PRIMITIVETYPE_INT:
580                                 value->i = unbox_int(h);
581                                 return true;
582                         case PRIMITIVETYPE_LONG:
583                                 value->l = unbox_int(h);
584                                 return true;
585                         case PRIMITIVETYPE_FLOAT:
586                                 value->f = unbox_int(h);
587                                 return true;
588                         case PRIMITIVETYPE_DOUBLE:
589                                 value->d = unbox_int(h);
590                                 return true;
591                         default:
592                                 return false;
593                 }
594
595         case PRIMITIVETYPE_LONG:
596                 switch (type) {
597                         case PRIMITIVETYPE_LONG:
598                                 value->l = unbox_long(h);
599                                 return true;
600                         case PRIMITIVETYPE_FLOAT:
601                                 value->f = unbox_long(h);
602                                 return true;
603                         case PRIMITIVETYPE_DOUBLE:
604                                 value->d = unbox_long(h);
605                                 return true;
606                         default:
607                                 return false;
608                 }
609
610         case PRIMITIVETYPE_FLOAT:
611                 switch (type) {
612                         case PRIMITIVETYPE_FLOAT:
613                                 value->f = unbox_float(h);
614                                 return true;
615                         case PRIMITIVETYPE_DOUBLE:
616                                 value->d = unbox_float(h);
617                                 return true;
618                         default:
619                                 return false;
620                 }
621
622         case PRIMITIVETYPE_DOUBLE:
623                 switch (type) {
624                         case PRIMITIVETYPE_DOUBLE:
625                                 value->d = unbox_double(h);
626                                 return true;
627                         default:
628                                 return false;
629                 }
630
631         default:
632                 os::abort("Primitive::unbox_typed: Invalid primitive type %d", type);
633                 return false;
634         }
635 }
636
637
638 /**
639  * Box a primitive type.
640  */
641 java_handle_t* Primitive::box(uint8_t value)
642 {
643         java_handle_t *h = builtin_new(class_java_lang_Boolean);
644
645         if (h == NULL)
646                 return NULL;
647
648         java_lang_Boolean b(h);
649         b.set_value(value);
650
651         return h;
652 }
653
654 java_handle_t* Primitive::box(int8_t value)
655 {
656         java_handle_t *h = builtin_new(class_java_lang_Byte);
657
658         if (h == NULL)
659                 return NULL;
660
661         java_lang_Byte b(h);
662         b.set_value(value);
663
664         return h;
665 }
666
667 java_handle_t* Primitive::box(uint16_t value)
668 {
669         java_handle_t *h = builtin_new(class_java_lang_Character);
670
671         if (h == NULL)
672                 return NULL;
673
674         java_lang_Character c(h);
675         c.set_value(value);
676
677         return h;
678 }
679
680 java_handle_t* Primitive::box(int16_t value)
681 {
682         java_handle_t *h = builtin_new(class_java_lang_Short);
683
684         if (h == NULL)
685                 return NULL;
686
687         java_lang_Short s(h);
688         s.set_value(value);
689
690         return h;
691 }
692
693 java_handle_t* Primitive::box(int32_t value)
694 {
695         java_handle_t *h = builtin_new(class_java_lang_Integer);
696
697         if (h == NULL)
698                 return NULL;
699
700         java_lang_Integer i(h);
701         i.set_value(value);
702
703         return h;
704 }
705
706 java_handle_t* Primitive::box(int64_t value)
707 {
708         java_handle_t *h = builtin_new(class_java_lang_Long);
709
710         if (h == NULL)
711                 return NULL;
712
713         java_lang_Long l(h);
714         l.set_value(value);
715
716         return h;
717 }
718
719 java_handle_t* Primitive::box(float value)
720 {
721         java_handle_t *h = builtin_new(class_java_lang_Float);
722
723         if (h == NULL)
724                 return NULL;
725
726         java_lang_Float f(h);
727         f.set_value(value);
728
729         return h;
730 }
731
732 java_handle_t* Primitive::box(double value)
733 {
734         java_handle_t *h = builtin_new(class_java_lang_Double);
735
736         if (h == NULL)
737                 return NULL;
738
739         java_lang_Double d(h);
740         d.set_value(value);
741
742         return h;
743 }
744
745
746
747 /**
748  * Unbox a primitive type.
749  */
750
751 // template<class T> T Primitive::unbox(java_handle_t *h)
752 // {
753 //      return java_lang_Boolean::get_value(h);
754 // }
755
756 inline uint8_t Primitive::unbox_boolean(java_handle_t *h)
757 {
758         java_lang_Boolean b(h);
759         return b.get_value();
760 }
761
762 inline int8_t Primitive::unbox_byte(java_handle_t *h)
763 {
764         java_lang_Byte b(h);
765         return b.get_value();
766 }
767
768 inline uint16_t Primitive::unbox_char(java_handle_t *h)
769 {
770         java_lang_Character c(h);
771         return c.get_value();
772 }
773
774 inline int16_t Primitive::unbox_short(java_handle_t *h)
775 {
776         java_lang_Short s(h);
777         return s.get_value();
778 }
779
780 inline int32_t Primitive::unbox_int(java_handle_t *h)
781 {
782         java_lang_Integer i(h);
783         return i.get_value();
784 }
785
786 inline int64_t Primitive::unbox_long(java_handle_t *h)
787 {
788         java_lang_Long l(h);
789         return l.get_value();
790 }
791
792 inline float Primitive::unbox_float(java_handle_t *h)
793 {
794         java_lang_Float f(h);
795         return f.get_value();
796 }
797
798 inline double Primitive::unbox_double(java_handle_t *h)
799 {
800         java_lang_Double d(h);
801         return d.get_value();
802 }
803
804
805 /*
806  * These are local overrides for various environment variables in Emacs.
807  * Please do not remove this and leave it at the end of the file, where
808  * Emacs will automagically detect them.
809  * ---------------------------------------------------------------------
810  * Local variables:
811  * mode: c++
812  * indent-tabs-mode: t
813  * c-basic-offset: 4
814  * tab-width: 4
815  * End:
816  * vim:noexpandtab:sw=4:ts=4:
817  */