merged volatile memory barriers
[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  * Returns the primitive type of the given primitive-class.
374  *
375  * @param c Class structure.
376  *
377  * @return Integer type of the class.
378  */
379 int Primitive::get_type_by_primitiveclass(classinfo *c)
380 {
381         /* Search primitive table. */
382
383         for (int i = 0; i < PRIMITIVETYPE_COUNT; i++)
384                 if (primitivetype_table[i].class_primitive == c)
385                         return i;
386         
387         /* Invalid primitive class. */
388
389         return -1;
390 }
391
392
393 /**
394  * Box a primitive of the given type.  If the type is an object,
395  * simply return it.
396  *
397  * @param type  Type of the passed value.
398  * @param value Value to box.
399  *
400  * @return Handle of the boxing Java object.
401  */
402 java_handle_t* Primitive::box(int type, imm_union value)
403 {
404         java_handle_t* o;
405
406         switch (type) {
407         case PRIMITIVETYPE_BOOLEAN:
408                 o = box((uint8_t) value.i);
409                 break;
410         case PRIMITIVETYPE_BYTE:
411                 o = box((int8_t) value.i);
412                 break;
413         case PRIMITIVETYPE_CHAR:
414                 o = box((uint16_t) value.i);
415                 break;
416         case PRIMITIVETYPE_SHORT:
417                 o = box((int16_t) value.i);
418                 break;
419         case PRIMITIVETYPE_INT:
420                 o = box(value.i);
421                 break;
422         case PRIMITIVETYPE_LONG:
423                 o = box(value.l);
424                 break;
425         case PRIMITIVETYPE_FLOAT:
426                 o = box(value.f);
427                 break;
428         case PRIMITIVETYPE_DOUBLE:
429                 o = box(value.d);
430                 break;
431         case PRIMITIVETYPE_VOID:
432                 o = (java_handle_t*) value.a;
433                 break;
434         default:
435                 o = NULL;
436                 os::abort("Primitive::box: Invalid primitive type %d", type);
437         }
438
439         return o;
440 }
441
442
443 /**
444  * Unbox a primitive of the given type.  If the type is an object,
445  * simply return it.
446  *
447  * @param h Handle of the Java object.
448  *
449  * @return Unboxed value as union.
450  */
451 imm_union Primitive::unbox(java_handle_t *h)
452 {
453         classinfo *c;
454         int        type;
455         imm_union  value;
456
457         if (h == NULL) {
458                 value.a = NULL;
459                 return value;
460         }
461
462         LLNI_class_get(h, c);
463
464         type = get_type_by_wrapperclass(c);
465
466         switch (type) {
467         case PRIMITIVETYPE_BOOLEAN:
468                 value.i = unbox_boolean(h);
469                 break;
470         case PRIMITIVETYPE_BYTE:
471                 value.i = unbox_byte(h);
472                 break;
473         case PRIMITIVETYPE_CHAR:
474                 value.i = unbox_char(h);
475                 break;
476         case PRIMITIVETYPE_SHORT:
477                 value.i = unbox_short(h);
478                 break;
479         case PRIMITIVETYPE_INT:
480                 value.i = unbox_int(h);
481                 break;
482         case PRIMITIVETYPE_LONG:
483                 value.l = unbox_long(h);
484                 break;
485         case PRIMITIVETYPE_FLOAT:
486                 value.f = unbox_float(h);
487                 break;
488         case PRIMITIVETYPE_DOUBLE:
489                 value.d = unbox_double(h);
490                 break;
491         case -1:
492                 /* If type is -1 the object is not a primitive box but a
493                    normal object. */
494                 value.a = h;
495                 break;
496         default:
497                 os::abort("Primitive::unbox: Invalid primitive type %d", type);
498         }
499
500         return value;
501 }
502
503
504 /**
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".
510  *
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.
515  *
516  * @return True of the conversion is allowed, false otherwise.
517  */
518 bool Primitive::unbox_typed(java_handle_t *h, int type, imm_union* value)
519 {
520         classinfo *c;
521         int        src_type;
522
523         if (h == NULL)
524                 return false;
525
526         LLNI_class_get(h, c);
527
528         src_type = get_type_by_wrapperclass(c);
529
530         switch (src_type) {
531         case PRIMITIVETYPE_BOOLEAN:
532                 switch (type) {
533                         case PRIMITIVETYPE_BOOLEAN:
534                                 value->i = unbox_boolean(h);
535                                 return true;
536                         default:
537                                 return false;
538                 }
539
540         case PRIMITIVETYPE_BYTE:
541                 switch (type) {
542                         case PRIMITIVETYPE_BYTE:
543                         case PRIMITIVETYPE_SHORT:
544                         case PRIMITIVETYPE_INT:
545                                 value->i = unbox_byte(h);
546                                 return true;
547                         case PRIMITIVETYPE_LONG:
548                                 value->l = unbox_byte(h);
549                                 return true;
550                         case PRIMITIVETYPE_FLOAT:
551                                 value->f = unbox_byte(h);
552                                 return true;
553                         case PRIMITIVETYPE_DOUBLE:
554                                 value->d = unbox_byte(h);
555                                 return true;
556                         default:
557                                 return false;
558                 }
559
560         case PRIMITIVETYPE_CHAR:
561                 switch (type) {
562                         case PRIMITIVETYPE_CHAR:
563                         case PRIMITIVETYPE_INT:
564                                 value->i = unbox_char(h);
565                                 return true;
566                         case PRIMITIVETYPE_LONG:
567                                 value->l = unbox_char(h);
568                                 return true;
569                         case PRIMITIVETYPE_FLOAT:
570                                 value->f = unbox_char(h);
571                                 return true;
572                         case PRIMITIVETYPE_DOUBLE:
573                                 value->d = unbox_char(h);
574                                 return true;
575                         default:
576                                 return false;
577                 }
578
579         case PRIMITIVETYPE_SHORT:
580                 switch (type) {
581                         case PRIMITIVETYPE_SHORT:
582                         case PRIMITIVETYPE_INT:
583                                 value->i = unbox_short(h);
584                                 return true;
585                         case PRIMITIVETYPE_LONG:
586                                 value->l = unbox_short(h);
587                                 return true;
588                         case PRIMITIVETYPE_FLOAT:
589                                 value->f = unbox_short(h);
590                                 return true;
591                         case PRIMITIVETYPE_DOUBLE:
592                                 value->d = unbox_short(h);
593                                 return true;
594                         default:
595                                 return false;
596                 }
597
598         case PRIMITIVETYPE_INT:
599                 switch (type) {
600                         case PRIMITIVETYPE_INT:
601                                 value->i = unbox_int(h);
602                                 return true;
603                         case PRIMITIVETYPE_LONG:
604                                 value->l = unbox_int(h);
605                                 return true;
606                         case PRIMITIVETYPE_FLOAT:
607                                 value->f = unbox_int(h);
608                                 return true;
609                         case PRIMITIVETYPE_DOUBLE:
610                                 value->d = unbox_int(h);
611                                 return true;
612                         default:
613                                 return false;
614                 }
615
616         case PRIMITIVETYPE_LONG:
617                 switch (type) {
618                         case PRIMITIVETYPE_LONG:
619                                 value->l = unbox_long(h);
620                                 return true;
621                         case PRIMITIVETYPE_FLOAT:
622                                 value->f = unbox_long(h);
623                                 return true;
624                         case PRIMITIVETYPE_DOUBLE:
625                                 value->d = unbox_long(h);
626                                 return true;
627                         default:
628                                 return false;
629                 }
630
631         case PRIMITIVETYPE_FLOAT:
632                 switch (type) {
633                         case PRIMITIVETYPE_FLOAT:
634                                 value->f = unbox_float(h);
635                                 return true;
636                         case PRIMITIVETYPE_DOUBLE:
637                                 value->d = unbox_float(h);
638                                 return true;
639                         default:
640                                 return false;
641                 }
642
643         case PRIMITIVETYPE_DOUBLE:
644                 switch (type) {
645                         case PRIMITIVETYPE_DOUBLE:
646                                 value->d = unbox_double(h);
647                                 return true;
648                         default:
649                                 return false;
650                 }
651
652         default:
653                 os::abort("Primitive::unbox_typed: Invalid primitive type %d", type);
654                 return false;
655         }
656 }
657
658
659 /**
660  * Box a primitive type.
661  */
662 java_handle_t* Primitive::box(uint8_t value)
663 {
664         java_handle_t *h = builtin_new(class_java_lang_Boolean);
665
666         if (h == NULL)
667                 return NULL;
668
669         java_lang_Boolean b(h);
670         b.set_value(value);
671
672         return h;
673 }
674
675 java_handle_t* Primitive::box(int8_t value)
676 {
677         java_handle_t *h = builtin_new(class_java_lang_Byte);
678
679         if (h == NULL)
680                 return NULL;
681
682         java_lang_Byte b(h);
683         b.set_value(value);
684
685         return h;
686 }
687
688 java_handle_t* Primitive::box(uint16_t value)
689 {
690         java_handle_t *h = builtin_new(class_java_lang_Character);
691
692         if (h == NULL)
693                 return NULL;
694
695         java_lang_Character c(h);
696         c.set_value(value);
697
698         return h;
699 }
700
701 java_handle_t* Primitive::box(int16_t value)
702 {
703         java_handle_t *h = builtin_new(class_java_lang_Short);
704
705         if (h == NULL)
706                 return NULL;
707
708         java_lang_Short s(h);
709         s.set_value(value);
710
711         return h;
712 }
713
714 java_handle_t* Primitive::box(int32_t value)
715 {
716         java_handle_t *h = builtin_new(class_java_lang_Integer);
717
718         if (h == NULL)
719                 return NULL;
720
721         java_lang_Integer i(h);
722         i.set_value(value);
723
724         return h;
725 }
726
727 java_handle_t* Primitive::box(int64_t value)
728 {
729         java_handle_t *h = builtin_new(class_java_lang_Long);
730
731         if (h == NULL)
732                 return NULL;
733
734         java_lang_Long l(h);
735         l.set_value(value);
736
737         return h;
738 }
739
740 java_handle_t* Primitive::box(float value)
741 {
742         java_handle_t *h = builtin_new(class_java_lang_Float);
743
744         if (h == NULL)
745                 return NULL;
746
747         java_lang_Float f(h);
748         f.set_value(value);
749
750         return h;
751 }
752
753 java_handle_t* Primitive::box(double value)
754 {
755         java_handle_t *h = builtin_new(class_java_lang_Double);
756
757         if (h == NULL)
758                 return NULL;
759
760         java_lang_Double d(h);
761         d.set_value(value);
762
763         return h;
764 }
765
766
767
768 /**
769  * Unbox a primitive type.
770  */
771
772 // template<class T> T Primitive::unbox(java_handle_t *h)
773 // {
774 //      return java_lang_Boolean::get_value(h);
775 // }
776
777 inline uint8_t Primitive::unbox_boolean(java_handle_t *h)
778 {
779         java_lang_Boolean b(h);
780         return b.get_value();
781 }
782
783 inline int8_t Primitive::unbox_byte(java_handle_t *h)
784 {
785         java_lang_Byte b(h);
786         return b.get_value();
787 }
788
789 inline uint16_t Primitive::unbox_char(java_handle_t *h)
790 {
791         java_lang_Character c(h);
792         return c.get_value();
793 }
794
795 inline int16_t Primitive::unbox_short(java_handle_t *h)
796 {
797         java_lang_Short s(h);
798         return s.get_value();
799 }
800
801 inline int32_t Primitive::unbox_int(java_handle_t *h)
802 {
803         java_lang_Integer i(h);
804         return i.get_value();
805 }
806
807 inline int64_t Primitive::unbox_long(java_handle_t *h)
808 {
809         java_lang_Long l(h);
810         return l.get_value();
811 }
812
813 inline float Primitive::unbox_float(java_handle_t *h)
814 {
815         java_lang_Float f(h);
816         return f.get_value();
817 }
818
819 inline double Primitive::unbox_double(java_handle_t *h)
820 {
821         java_lang_Double d(h);
822         return d.get_value();
823 }
824
825
826 /*
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  * ---------------------------------------------------------------------
831  * Local variables:
832  * mode: c++
833  * indent-tabs-mode: t
834  * c-basic-offset: 4
835  * tab-width: 4
836  * End:
837  * vim:noexpandtab:sw=4:ts=4:
838  */