1 /* src/vmcore/loader.c - class loader functions
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 $Id: loader.c 7483 2007-03-08 13:17:40Z michi $
38 #include "mm/memory.h"
40 #if defined(ENABLE_THREADS)
41 # include "threads/native/lock.h"
43 # include "threads/none/lock.h"
46 #include "toolbox/hashtable.h"
47 #include "toolbox/logging.h"
49 #include "vm/builtin.h"
50 #include "vm/exceptions.h"
51 #include "vm/global.h"
52 #include "vm/stringlocal.h"
55 #include "vm/jit_interface.h"
57 #if defined(ENABLE_JAVASE)
58 # include "vmcore/annotation.h"
59 # include "vmcore/stackmap.h"
62 #include "vmcore/classcache.h"
63 #include "vmcore/linker.h"
64 #include "vmcore/loader.h"
65 #include "vmcore/options.h"
66 #include "vmcore/rt-timing.h"
68 #if defined(ENABLE_STATISTICS)
69 # include "vmcore/statistics.h"
72 #include "vmcore/suck.h"
74 #if defined(ENABLE_ZLIB)
75 # include "vmcore/zip.h"
78 #if defined(ENABLE_JVMTI)
79 # include "native/jvmti/cacaodbg.h"
83 /* global variables ***********************************************************/
85 hashtable *hashtable_classloader;
88 /* loader_init *****************************************************************
90 Initializes all lists and loads all classes required for the system
93 *******************************************************************************/
95 bool loader_init(void)
97 #if defined(ENABLE_THREADS)
98 list_classpath_entry *lce;
100 /* Initialize the monitor pointer for zip/jar file locking. */
102 for (lce = list_first(list_classpath_entries); lce != NULL;
103 lce = list_next(list_classpath_entries, lce))
104 if (lce->type == CLASSPATH_ARCHIVE)
105 lock_init_object_lock((java_objectheader *) lce);
108 /* initialize classloader hashtable, 10 entries should be enough */
110 hashtable_classloader = NEW(hashtable);
111 hashtable_create(hashtable_classloader, 10);
113 /* load some important classes */
115 if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
118 if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
121 #if defined(ENABLE_JAVASE)
122 if (!(class_java_lang_Cloneable =
123 load_class_bootstrap(utf_java_lang_Cloneable)))
126 if (!(class_java_io_Serializable =
127 load_class_bootstrap(utf_java_io_Serializable)))
131 /* load classes for wrapping primitive types */
133 #if defined(ENABLE_JAVASE)
134 if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
138 if (!(class_java_lang_Boolean =
139 load_class_bootstrap(utf_java_lang_Boolean)))
142 if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
145 if (!(class_java_lang_Character =
146 load_class_bootstrap(utf_java_lang_Character)))
149 if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
152 if (!(class_java_lang_Integer =
153 load_class_bootstrap(utf_java_lang_Integer)))
156 if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
159 if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
162 if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
166 /* load some other important classes */
168 if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
171 #if defined(ENABLE_JAVASE)
172 if (!(class_java_lang_ClassLoader =
173 load_class_bootstrap(utf_java_lang_ClassLoader)))
176 if (!(class_java_lang_SecurityManager =
177 load_class_bootstrap(utf_java_lang_SecurityManager)))
181 if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
184 if (!(class_java_lang_Thread =
185 load_class_bootstrap(utf_new_char("java/lang/Thread"))))
188 #if defined(ENABLE_JAVASE)
189 if (!(class_java_lang_ThreadGroup =
190 load_class_bootstrap(utf_java_lang_ThreadGroup)))
194 #if defined(WITH_CLASSPATH_GNU)
195 if (!(class_java_lang_VMSystem =
196 load_class_bootstrap(utf_new_char("java/lang/VMSystem"))))
200 if (!(class_java_lang_VMThread =
201 load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
206 /* some classes which may be used more often */
208 #if defined(ENABLE_JAVASE)
209 if (!(class_java_lang_StackTraceElement =
210 load_class_bootstrap(utf_java_lang_StackTraceElement)))
213 if (!(class_java_lang_reflect_Constructor =
214 load_class_bootstrap(utf_java_lang_reflect_Constructor)))
217 if (!(class_java_lang_reflect_Field =
218 load_class_bootstrap(utf_java_lang_reflect_Field)))
221 if (!(class_java_lang_reflect_Method =
222 load_class_bootstrap(utf_java_lang_reflect_Method)))
225 if (!(class_java_security_PrivilegedAction =
226 load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
229 if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
232 if (!(arrayclass_java_lang_Object =
233 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
241 /* loader_hashtable_classloader_add ********************************************
243 Adds an entry to the classloader hashtable.
245 REMEMBER: Also use this to register native loaders!
247 *******************************************************************************/
249 classloader *loader_hashtable_classloader_add(java_objectheader *cl)
251 hashtable_classloader_entry *cle;
258 LOCK_MONITOR_ENTER(hashtable_classloader->header);
260 /* key for entry is the hashcode of the classloader;
261 aligned to 16-byte boundaries */
263 #if defined(ENABLE_GC_CACAO)
264 key = heap_get_hashcode(cl) >> 4;
266 key = ((u4) (ptrint) cl) >> 4;
269 slot = key & (hashtable_classloader->size - 1);
270 cle = hashtable_classloader->ptr[slot];
272 /* search hashchain for existing entry */
273 /* XXX no GC collection is allowed here, make this a critical section */
276 if (cle->object == cl)
282 /* if no classloader was found, we create a new entry here */
285 cle = NEW(hashtable_classloader_entry);
289 /* insert entry into hashtable */
291 cle->hashlink = hashtable_classloader->ptr[slot];
292 hashtable_classloader->ptr[slot] = cle;
294 /* update number of entries */
296 hashtable_classloader->entries++;
300 LOCK_MONITOR_EXIT(hashtable_classloader->header);
306 /* loader_hashtable_classloader_find *******************************************
308 Find an entry in the classloader hashtable.
310 *******************************************************************************/
312 classloader *loader_hashtable_classloader_find(java_objectheader *cl)
314 hashtable_classloader_entry *cle;
321 /* key for entry is the hashcode of the classloader;
322 aligned to 16-byte boundaries */
324 #if defined(ENABLE_GC_CACAO)
325 key = heap_get_hashcode(cl) >> 4;
327 key = ((u4) (ptrint) cl) >> 4;
330 slot = key & (hashtable_classloader->size - 1);
331 cle = hashtable_classloader->ptr[slot];
333 /* search hashchain for existing entry */
334 /* XXX no GC collection is allowed here, make this a critical section */
337 if (cle->object == cl)
347 /* loader_load_all_classes *****************************************************
349 Loads all classes specified in the BOOTCLASSPATH.
351 *******************************************************************************/
353 void loader_load_all_classes(void)
355 list_classpath_entry *lce;
356 #if defined(ENABLE_ZLIB)
359 hashtable_zipfile_entry *htzfe;
363 for (lce = list_first(list_classpath_entries); lce != NULL;
364 lce = list_next(list_classpath_entries, lce)) {
365 #if defined(ENABLE_ZLIB)
366 if (lce->type == CLASSPATH_ARCHIVE) {
367 /* get the classes hashtable */
371 for (slot = 0; slot < ht->size; slot++) {
372 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
374 for (; htzfe; htzfe = htzfe->hashlink) {
377 /* skip all entries in META-INF and .properties,
380 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
381 strstr(u->text, ".properties") ||
382 strstr(u->text, ".png"))
385 /* load class from bootstrap classloader */
387 if (!load_class_bootstrap(u)) {
388 fprintf(stderr, "Error loading: ");
389 utf_fprint_printable_ascii_classname(stderr, u);
390 fprintf(stderr, "\n");
393 /* print out exception and cause */
395 exceptions_print_current_exception();
403 #if defined(ENABLE_ZLIB)
410 /* loader_skip_attribute_body **************************************************
412 Skips an attribute the attribute_name_index has already been read.
415 u2 attribute_name_index;
417 u1 info[attribute_length];
420 *******************************************************************************/
422 bool loader_skip_attribute_body(classbuffer *cb)
426 if (!suck_check_classbuffer_size(cb, 4))
429 attribute_length = suck_u4(cb);
431 if (!suck_check_classbuffer_size(cb, attribute_length))
434 suck_skip_nbytes(cb, attribute_length);
440 /* load_constantpool ***********************************************************
442 Loads the constantpool of a class, the entries are transformed into
443 a simpler format by resolving references (a detailed overview of
444 the compact structures can be found in global.h).
446 *******************************************************************************/
448 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
451 /* The following structures are used to save information which cannot be
452 processed during the first pass. After the complete constantpool has
453 been traversed the references can be resolved.
454 (only in specific order) */
456 /* CONSTANT_Class entries */
457 typedef struct forward_class {
458 struct forward_class *next;
463 /* CONSTANT_String */
464 typedef struct forward_string {
465 struct forward_string *next;
470 /* CONSTANT_NameAndType */
471 typedef struct forward_nameandtype {
472 struct forward_nameandtype *next;
476 } forward_nameandtype;
478 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
479 typedef struct forward_fieldmethint {
480 struct forward_fieldmethint *next;
484 u2 nameandtype_index;
485 } forward_fieldmethint;
491 forward_class *forward_classes = NULL;
492 forward_string *forward_strings = NULL;
493 forward_nameandtype *forward_nameandtypes = NULL;
494 forward_fieldmethint *forward_fieldmethints = NULL;
498 forward_nameandtype *nfn;
499 forward_fieldmethint *nff;
507 /* number of entries in the constant_pool table plus one */
508 if (!suck_check_classbuffer_size(cb, 2))
511 cpcount = c->cpcount = suck_u2(cb);
513 /* allocate memory */
514 cptags = c->cptags = MNEW(u1, cpcount);
515 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
518 exceptions_throw_classformaterror(c, "Illegal constant pool size");
522 #if defined(ENABLE_STATISTICS)
524 count_const_pool_len += (sizeof(u1) + sizeof(voidptr)) * cpcount;
527 /* initialize constantpool */
528 for (idx = 0; idx < cpcount; idx++) {
529 cptags[idx] = CONSTANT_UNUSED;
534 /******* first pass *******/
535 /* entries which cannot be resolved now are written into
536 temporary structures and traversed again later */
539 while (idx < cpcount) {
542 /* get constant type */
543 if (!suck_check_classbuffer_size(cb, 1))
550 nfc = DNEW(forward_class);
552 nfc->next = forward_classes;
553 forward_classes = nfc;
555 nfc->thisindex = idx;
556 /* reference to CONSTANT_NameAndType */
557 if (!suck_check_classbuffer_size(cb, 2))
560 nfc->name_index = suck_u2(cb);
565 case CONSTANT_String:
566 nfs = DNEW(forward_string);
568 nfs->next = forward_strings;
569 forward_strings = nfs;
571 nfs->thisindex = idx;
573 /* reference to CONSTANT_Utf8_info with string characters */
574 if (!suck_check_classbuffer_size(cb, 2))
577 nfs->string_index = suck_u2(cb);
582 case CONSTANT_NameAndType:
583 nfn = DNEW(forward_nameandtype);
585 nfn->next = forward_nameandtypes;
586 forward_nameandtypes = nfn;
588 nfn->thisindex = idx;
590 if (!suck_check_classbuffer_size(cb, 2 + 2))
593 /* reference to CONSTANT_Utf8_info containing simple name */
594 nfn->name_index = suck_u2(cb);
596 /* reference to CONSTANT_Utf8_info containing field or method
598 nfn->sig_index = suck_u2(cb);
603 case CONSTANT_Fieldref:
604 case CONSTANT_Methodref:
605 case CONSTANT_InterfaceMethodref:
606 nff = DNEW(forward_fieldmethint);
608 nff->next = forward_fieldmethints;
609 forward_fieldmethints = nff;
611 nff->thisindex = idx;
615 if (!suck_check_classbuffer_size(cb, 2 + 2))
618 /* class or interface type that contains the declaration of the
620 nff->class_index = suck_u2(cb);
622 /* name and descriptor of the field or method */
623 nff->nameandtype_index = suck_u2(cb);
628 case CONSTANT_Integer: {
629 constant_integer *ci = NEW(constant_integer);
631 #if defined(ENABLE_STATISTICS)
633 count_const_pool_len += sizeof(constant_integer);
636 if (!suck_check_classbuffer_size(cb, 4))
639 ci->value = suck_s4(cb);
640 cptags[idx] = CONSTANT_Integer;
647 case CONSTANT_Float: {
648 constant_float *cf = NEW(constant_float);
650 #if defined(ENABLE_STATISTICS)
652 count_const_pool_len += sizeof(constant_float);
655 if (!suck_check_classbuffer_size(cb, 4))
658 cf->value = suck_float(cb);
659 cptags[idx] = CONSTANT_Float;
666 case CONSTANT_Long: {
667 constant_long *cl = NEW(constant_long);
669 #if defined(ENABLE_STATISTICS)
671 count_const_pool_len += sizeof(constant_long);
674 if (!suck_check_classbuffer_size(cb, 8))
677 cl->value = suck_s8(cb);
678 cptags[idx] = CONSTANT_Long;
682 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
688 case CONSTANT_Double: {
689 constant_double *cd = NEW(constant_double);
691 #if defined(ENABLE_STATISTICS)
693 count_const_pool_len += sizeof(constant_double);
696 if (!suck_check_classbuffer_size(cb, 8))
699 cd->value = suck_double(cb);
700 cptags[idx] = CONSTANT_Double;
704 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
710 case CONSTANT_Utf8: {
713 /* number of bytes in the bytes array (not string-length) */
714 if (!suck_check_classbuffer_size(cb, 2))
717 length = suck_u2(cb);
718 cptags[idx] = CONSTANT_Utf8;
720 /* validate the string */
721 if (!suck_check_classbuffer_size(cb, length))
724 #ifdef ENABLE_VERIFIER
726 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
728 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
731 #endif /* ENABLE_VERIFIER */
732 /* insert utf-string into the utf-symboltable */
733 cpinfos[idx] = utf_new((char *) cb->pos, length);
735 /* skip bytes of the string (buffer size check above) */
736 suck_skip_nbytes(cb, length);
742 exceptions_throw_classformaterror(c, "Illegal constant pool type");
748 /* resolve entries in temporary structures */
750 while (forward_classes) {
752 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
756 #ifdef ENABLE_VERIFIER
757 if (opt_verify && !is_valid_name_utf(name)) {
758 exceptions_throw_classformaterror(c, "Class reference with invalid name");
761 #endif /* ENABLE_VERIFIER */
763 /* add all class references to the descriptor_pool */
765 if (!descriptor_pool_add_class(descpool, name))
768 cptags[forward_classes->thisindex] = CONSTANT_Class;
773 if (!(tc = load_class_bootstrap(name)))
776 /* link the class later, because we cannot link the class currently
778 list_add_first(&unlinkedclasses, tc);
781 /* the classref is created later */
782 cpinfos[forward_classes->thisindex] = name;
784 nfc = forward_classes;
785 forward_classes = forward_classes->next;
788 while (forward_strings) {
790 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
794 /* resolve utf-string */
795 cptags[forward_strings->thisindex] = CONSTANT_String;
796 cpinfos[forward_strings->thisindex] = text;
798 nfs = forward_strings;
799 forward_strings = forward_strings->next;
802 while (forward_nameandtypes) {
803 constant_nameandtype *cn = NEW(constant_nameandtype);
805 #if defined(ENABLE_STATISTICS)
807 count_const_pool_len += sizeof(constant_nameandtype);
810 /* resolve simple name and descriptor */
811 cn->name = class_getconstant(c,
812 forward_nameandtypes->name_index,
817 cn->descriptor = class_getconstant(c,
818 forward_nameandtypes->sig_index,
823 #ifdef ENABLE_VERIFIER
826 if (!is_valid_name_utf(cn->name)) {
827 exceptions_throw_classformaterror(c,
828 "Illegal Field name \"%s\"",
834 /* disallow referencing <clinit> among others */
835 if (cn->name->text[0] == '<' && cn->name != utf_init) {
836 exceptions_throw_classformaterror(c, "Illegal reference to special method");
840 #endif /* ENABLE_VERIFIER */
842 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
843 cpinfos[forward_nameandtypes->thisindex] = cn;
845 nfn = forward_nameandtypes;
846 forward_nameandtypes = forward_nameandtypes->next;
849 while (forward_fieldmethints) {
850 constant_nameandtype *nat;
851 constant_FMIref *fmi = NEW(constant_FMIref);
853 #if defined(ENABLE_STATISTICS)
855 count_const_pool_len += sizeof(constant_FMIref);
857 /* resolve simple name and descriptor */
859 nat = class_getconstant(c,
860 forward_fieldmethints->nameandtype_index,
861 CONSTANT_NameAndType);
865 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
867 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
870 /* the classref is created later */
872 fmi->p.index = forward_fieldmethints->class_index;
873 fmi->name = nat->name;
874 fmi->descriptor = nat->descriptor;
876 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
877 cpinfos[forward_fieldmethints->thisindex] = fmi;
879 nff = forward_fieldmethints;
880 forward_fieldmethints = forward_fieldmethints->next;
883 /* everything was ok */
889 /* loader_load_attribute_signature *********************************************
891 Signature_attribute {
892 u2 attribute_name_index;
897 *******************************************************************************/
899 #if defined(ENABLE_JAVASE)
900 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
910 /* check remaining bytecode */
912 if (!suck_check_classbuffer_size(cb, 4 + 2))
915 /* check attribute length */
917 attribute_length = suck_u4(cb);
919 if (attribute_length != 2) {
920 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
924 if (*signature != NULL) {
925 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
931 signature_index = suck_u2(cb);
933 if (!(*signature = class_getconstant(c, signature_index, CONSTANT_Utf8)))
938 #endif /* defined(ENABLE_JAVASE) */
941 /* load_field ******************************************************************
943 Load everything about a class field from the class file and fill a
944 'fieldinfo' structure. For static fields, space in the data segment
947 *******************************************************************************/
949 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
951 static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
956 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
961 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
964 f->flags = suck_u2(cb);
966 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
971 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
975 f->parseddesc = NULL;
977 if (!descriptor_pool_add(descpool, u, NULL))
980 /* descriptor_pool_add accepts method descriptors, so we have to check */
981 /* against them here before the call of descriptor_to_basic_type below. */
982 if (u->text[0] == '(') {
983 exceptions_throw_classformaterror(c, "Method descriptor used for field");
987 #ifdef ENABLE_VERIFIER
990 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<') {
991 exceptions_throw_classformaterror(c,
992 "Illegal Field name \"%s\"",
997 /* check flag consistency */
998 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
1000 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
1001 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
1002 exceptions_throw_classformaterror(c,
1003 "Illegal field modifiers: 0x%X",
1008 if (c->flags & ACC_INTERFACE) {
1009 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
1010 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
1011 f->flags & ACC_TRANSIENT) {
1012 exceptions_throw_classformaterror(c,
1013 "Illegal field modifiers: 0x%X",
1019 #endif /* ENABLE_VERIFIER */
1021 f->type = jtype = descriptor_to_basic_type(f->descriptor); /* data type */
1022 f->offset = 0; /* offset from start of object */
1040 if (!(f->flags & ACC_STATIC))
1041 c->flags |= ACC_CLASS_HAS_POINTERS;
1049 f->value.l.high = 0;
1054 /* read attributes */
1055 if (!suck_check_classbuffer_size(cb, 2))
1058 attrnum = suck_u2(cb);
1059 for (i = 0; i < attrnum; i++) {
1060 if (!suck_check_classbuffer_size(cb, 2))
1063 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1066 if (u == utf_ConstantValue) {
1067 if (!suck_check_classbuffer_size(cb, 4 + 2))
1070 /* check attribute length */
1072 if (suck_u4(cb) != 2) {
1073 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
1077 /* constant value attribute */
1079 if (pindex != field_load_NOVALUE) {
1080 exceptions_throw_classformaterror(c, "Multiple ConstantValue attributes");
1084 /* index of value in constantpool */
1086 pindex = suck_u2(cb);
1088 /* initialize field with value from constantpool */
1091 constant_integer *ci;
1093 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
1096 f->value.i = ci->value;
1103 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
1106 f->value.l = cl->value;
1113 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
1116 f->value.f = cf->value;
1121 constant_double *cd;
1123 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
1126 f->value.d = cd->value;
1131 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
1134 /* create javastring from compressed utf8-string */
1135 f->value.a = literalstring_new(u);
1139 log_text("Invalid Constant - Type");
1142 #if defined(ENABLE_JAVASE)
1143 else if (u == utf_Signature) {
1146 if (!loader_load_attribute_signature(cb, &(f->signature)))
1151 /* unknown attribute */
1153 if (!loader_skip_attribute_body(cb))
1158 /* everything was ok */
1164 /* loader_load_method **********************************************************
1166 Loads a method from the class file and fills an existing
1167 'methodinfo' structure. For native methods, the function pointer
1168 field is set to the real function pointer, for JavaVM methods a
1169 pointer to the compiler is used preliminarily.
1174 u2 descriptor_index;
1175 u2 attributes_count;
1176 attribute_info attributes[attribute_count];
1180 u2 attribute_name_index;
1181 u4 attribute_length;
1182 u1 info[attribute_length];
1185 LineNumberTable_attribute {
1186 u2 attribute_name_index;
1187 u4 attribute_length;
1188 u2 line_number_table_length;
1192 } line_number_table[line_number_table_length];
1195 *******************************************************************************/
1197 static bool loader_load_method(classbuffer *cb, methodinfo *m,
1198 descriptor_pool *descpool)
1205 u2 descriptor_index;
1206 u2 attributes_count;
1207 u2 attribute_name_index;
1208 utf *attribute_name;
1209 u2 code_attributes_count;
1210 u2 code_attribute_name_index;
1211 utf *code_attribute_name;
1217 #if defined(ENABLE_STATISTICS)
1219 count_all_methods++;
1222 /* all fields of m have been zeroed in load_class_from_classbuffer */
1226 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
1231 m->flags = suck_u2(cb);
1235 name_index = suck_u2(cb);
1237 if (!(u = class_getconstant(c, name_index, CONSTANT_Utf8)))
1244 descriptor_index = suck_u2(cb);
1246 if (!(u = class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
1251 if (!descriptor_pool_add(descpool, u, &argcount))
1254 #ifdef ENABLE_VERIFIER
1256 if (!is_valid_name_utf(m->name)) {
1257 exceptions_throw_classformaterror(c, "Method with invalid name");
1261 if (m->name->text[0] == '<' &&
1262 m->name != utf_init && m->name != utf_clinit) {
1263 exceptions_throw_classformaterror(c, "Method with invalid special name");
1267 #endif /* ENABLE_VERIFIER */
1269 if (!(m->flags & ACC_STATIC))
1270 argcount++; /* count the 'this' argument */
1272 #ifdef ENABLE_VERIFIER
1274 if (argcount > 255) {
1275 exceptions_throw_classformaterror(c, "Too many arguments in signature");
1279 /* check flag consistency */
1280 if (m->name != utf_clinit) {
1281 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1283 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1284 exceptions_throw_classformaterror(c,
1285 "Illegal method modifiers: 0x%X",
1290 if (m->flags & ACC_ABSTRACT) {
1291 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1292 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1293 exceptions_throw_classformaterror(c,
1294 "Illegal method modifiers: 0x%X",
1300 if (c->flags & ACC_INTERFACE) {
1301 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1302 exceptions_throw_classformaterror(c,
1303 "Illegal method modifiers: 0x%X",
1309 if (m->name == utf_init) {
1310 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1311 ACC_NATIVE | ACC_ABSTRACT)) {
1312 exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
1318 #endif /* ENABLE_VERIFIER */
1320 /* mark the method as monomorphic until further notice */
1322 m->flags |= ACC_METHOD_MONOMORPHIC;
1324 /* non-abstract methods have an implementation in this class */
1326 if (!(m->flags & ACC_ABSTRACT))
1327 m->flags |= ACC_METHOD_IMPLEMENTED;
1329 if (!suck_check_classbuffer_size(cb, 2))
1332 /* attributes count */
1334 attributes_count = suck_u2(cb);
1336 for (i = 0; i < attributes_count; i++) {
1337 if (!suck_check_classbuffer_size(cb, 2))
1340 /* attribute name index */
1342 attribute_name_index = suck_u2(cb);
1344 if (!(attribute_name = class_getconstant(c, attribute_name_index, CONSTANT_Utf8)))
1347 if (attribute_name == utf_Code) {
1349 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1350 exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
1355 exceptions_throw_classformaterror(c, "Multiple Code attributes");
1359 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1363 m->maxstack = suck_u2(cb);
1364 m->maxlocals = suck_u2(cb);
1366 if (m->maxlocals < argcount) {
1367 exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
1371 if (!suck_check_classbuffer_size(cb, 4))
1374 m->jcodelength = suck_u4(cb);
1376 if (m->jcodelength == 0) {
1377 exceptions_throw_classformaterror(c, "Code of a method has length 0");
1381 if (m->jcodelength > 65535) {
1382 exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
1386 if (!suck_check_classbuffer_size(cb, m->jcodelength))
1389 m->jcode = MNEW(u1, m->jcodelength);
1390 suck_nbytes(m->jcode, cb, m->jcodelength);
1392 if (!suck_check_classbuffer_size(cb, 2))
1395 m->rawexceptiontablelength = suck_u2(cb);
1396 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->rawexceptiontablelength))
1399 m->rawexceptiontable = MNEW(raw_exception_entry, m->rawexceptiontablelength);
1401 #if defined(ENABLE_STATISTICS)
1403 count_vmcode_len += m->jcodelength + 18;
1404 count_extable_len +=
1405 m->rawexceptiontablelength * sizeof(raw_exception_entry);
1409 for (j = 0; j < m->rawexceptiontablelength; j++) {
1411 m->rawexceptiontable[j].startpc = suck_u2(cb);
1412 m->rawexceptiontable[j].endpc = suck_u2(cb);
1413 m->rawexceptiontable[j].handlerpc = suck_u2(cb);
1417 m->rawexceptiontable[j].catchtype.any = NULL;
1420 /* the classref is created later */
1421 if (!(m->rawexceptiontable[j].catchtype.any =
1422 (utf*)class_getconstant(c, idx, CONSTANT_Class)))
1427 if (!suck_check_classbuffer_size(cb, 2))
1430 /* code attributes count */
1432 code_attributes_count = suck_u2(cb);
1434 for (k = 0; k < code_attributes_count; k++) {
1435 if (!suck_check_classbuffer_size(cb, 2))
1438 /* code attribute name index */
1440 code_attribute_name_index = suck_u2(cb);
1442 if (!(code_attribute_name = class_getconstant(c, code_attribute_name_index, CONSTANT_Utf8)))
1445 /* check which code attribute */
1447 if (code_attribute_name == utf_LineNumberTable) {
1448 /* LineNumberTable */
1449 if (!suck_check_classbuffer_size(cb, 4 + 2))
1452 /* attribute length */
1456 /* line number table length */
1458 m->linenumbercount = suck_u2(cb);
1460 if (!suck_check_classbuffer_size(cb,
1461 (2 + 2) * m->linenumbercount))
1464 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1466 #if defined(ENABLE_STATISTICS)
1468 size_lineinfo += sizeof(lineinfo) * m->linenumbercount;
1471 for (l = 0; l < m->linenumbercount; l++) {
1472 m->linenumbers[l].start_pc = suck_u2(cb);
1473 m->linenumbers[l].line_number = suck_u2(cb);
1476 #if defined(ENABLE_JAVASE)
1477 else if (code_attribute_name == utf_StackMapTable) {
1480 if (!stackmap_load_attribute_stackmaptable(cb, m))
1485 /* unknown code attribute */
1487 if (!loader_skip_attribute_body(cb))
1492 else if (attribute_name == utf_Exceptions) {
1495 if (m->thrownexceptions != NULL) {
1496 exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
1500 if (!suck_check_classbuffer_size(cb, 4 + 2))
1503 /* attribute length */
1507 m->thrownexceptionscount = suck_u2(cb);
1509 if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1512 m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
1514 for (j = 0; j < m->thrownexceptionscount; j++) {
1515 /* the classref is created later */
1516 if (!((m->thrownexceptions)[j].any =
1517 (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1521 #if defined(ENABLE_JAVASE)
1522 else if (attribute_name == utf_Signature) {
1525 if (!loader_load_attribute_signature(cb, &(m->signature)))
1530 /* unknown attribute */
1532 if (!loader_skip_attribute_body(cb))
1537 if ((m->jcode == NULL) && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1538 exceptions_throw_classformaterror(c, "Missing Code attribute");
1542 /* initialize the hit countdown field */
1544 #if defined(ENABLE_REPLACEMENT)
1545 m->hitcountdown = METHOD_INITIAL_HIT_COUNTDOWN;
1548 /* everything was ok */
1554 /* load_class_from_sysloader ***************************************************
1556 Load the class with the given name using the system class loader
1559 name.............the classname
1562 the loaded class, or
1563 NULL if an exception has been thrown
1565 *******************************************************************************/
1567 classinfo *load_class_from_sysloader(utf *name)
1570 java_objectheader *clo;
1574 assert(class_java_lang_Object);
1575 assert(class_java_lang_ClassLoader);
1576 assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
1578 m = class_resolveclassmethod(class_java_lang_ClassLoader,
1579 utf_getSystemClassLoader,
1580 utf_void__java_lang_ClassLoader,
1581 class_java_lang_Object,
1587 clo = vm_call_method(m, NULL);
1592 cl = loader_hashtable_classloader_add(clo);
1594 c = load_class_from_classloader(name, cl);
1600 /* load_class_from_classloader *************************************************
1602 Load the class with the given name using the given user-defined class loader.
1605 name.............the classname
1606 cl...............user-defined class loader
1609 the loaded class, or
1610 NULL if an exception has been thrown
1612 *******************************************************************************/
1614 classinfo *load_class_from_classloader(utf *name, classloader *cl)
1616 java_objectheader *o;
1619 java_objectheader *string;
1620 #if defined(ENABLE_RT_TIMING)
1621 struct timespec time_start, time_lookup, time_prepare, time_java,
1625 RT_TIMING_GET_TIME(time_start);
1629 /* lookup if this class has already been loaded */
1631 c = classcache_lookup(cl, name);
1633 RT_TIMING_GET_TIME(time_lookup);
1634 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1639 /* if other class loader than bootstrap, call it */
1647 namelen = name->blength;
1649 /* handle array classes */
1650 if (text[0] == '[') {
1656 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1657 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1658 exceptions_throw_noclassdeffounderror(name);
1662 u = utf_new(text + 2, namelen - 3);
1664 if (!(comp = load_class_from_classloader(u, cl)))
1667 /* create the array class */
1669 c = class_array_of(comp, false);
1671 tmpc = classcache_store(cl, c, true);
1674 /* exception, free the loaded class */
1675 c->state &= ~CLASS_LOADING;
1682 /* load the component class */
1684 u = utf_new(text + 1, namelen - 1);
1686 if (!(comp = load_class_from_classloader(u, cl)))
1689 /* create the array class */
1691 c = class_array_of(comp, false);
1693 tmpc = classcache_store(cl, c, true);
1696 /* exception, free the loaded class */
1697 c->state &= ~CLASS_LOADING;
1704 /* primitive array classes are loaded by the bootstrap loader */
1706 c = load_class_bootstrap(name);
1712 assert(class_java_lang_Object);
1714 lc = class_resolveclassmethod(cl->object->vftbl->class,
1716 utf_java_lang_String__java_lang_Class,
1717 class_java_lang_Object,
1721 return false; /* exception */
1723 /* move return value into `o' and cast it afterwards to a classinfo* */
1725 string = javastring_new_slash_to_dot(name);
1727 RT_TIMING_GET_TIME(time_prepare);
1729 o = vm_call_method(lc, cl->object, string);
1731 RT_TIMING_GET_TIME(time_java);
1733 c = (classinfo *) o;
1736 /* Store this class in the loaded class cache. If another
1737 class with the same (initloader,name) pair has been
1738 stored earlier it will be returned by classcache_store
1739 In this case classcache_store may not free the class
1740 because it has already been exposed to Java code which
1741 may have kept references to that class. */
1743 tmpc = classcache_store(cl, c, false);
1746 /* exception, free the loaded class */
1747 c->state &= ~CLASS_LOADING;
1754 /* loadClass has thrown an exception. We must convert
1755 ClassNotFoundException into
1756 NoClassDefFoundException. */
1758 /* XXX Maybe we should have a flag that avoids this
1759 conversion for calling load_class_from_classloader from
1760 Class.forName. Currently we do a double conversion in
1763 classnotfoundexception_to_noclassdeffounderror();
1766 RT_TIMING_GET_TIME(time_cache);
1768 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1769 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1770 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1772 /* SUN compatible -verbose:class output */
1774 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1776 utf_display_printable_ascii_classname(name);
1780 #if defined(ENABLE_JVMTI)
1781 /* fire Class Load JVMTI event */
1782 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1789 c = load_class_bootstrap(name);
1795 /* load_class_bootstrap ********************************************************
1797 Load the class with the given name using the bootstrap class loader.
1800 name.............the classname
1803 loaded classinfo, or
1804 NULL if an exception has been thrown
1807 load_class_bootstrap is synchronized. It can be treated as an
1810 *******************************************************************************/
1812 classinfo *load_class_bootstrap(utf *name)
1817 #if defined(ENABLE_RT_TIMING)
1818 struct timespec time_start, time_lookup, time_array, time_suck,
1819 time_load, time_cache;
1822 RT_TIMING_GET_TIME(time_start);
1828 /* lookup if this class has already been loaded */
1830 if ((r = classcache_lookup(NULL, name))) {
1832 RT_TIMING_GET_TIME(time_lookup);
1833 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1838 RT_TIMING_GET_TIME(time_lookup);
1839 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1841 /* create the classinfo */
1843 c = class_create_classinfo(name);
1845 /* handle array classes */
1847 if (name->text[0] == '[') {
1848 c = load_newly_created_array(c, NULL);
1851 assert(c->state & CLASS_LOADED);
1853 RT_TIMING_GET_TIME(time_array);
1854 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1859 #if defined(ENABLE_STATISTICS)
1862 if (opt_getcompilingtime)
1863 compilingtime_stop();
1865 if (opt_getloadingtime)
1866 loadingtime_start();
1869 /* load classdata, throw exception on error */
1874 /* this normally means, the classpath was not set properly */
1876 if (name == utf_java_lang_Object)
1877 vm_abort("java/lang/NoClassDefFoundError: java/lang/Object");
1879 exceptions_throw_noclassdeffounderror(name);
1884 RT_TIMING_GET_TIME(time_suck);
1886 /* load the class from the buffer */
1888 r = load_class_from_classbuffer(cb);
1890 RT_TIMING_GET_TIME(time_load);
1893 /* the class could not be loaded, free the classinfo struct */
1898 /* Store this class in the loaded class cache this step also
1899 checks the loading constraints. If the class has been loaded
1900 before, the earlier loaded class is returned. */
1902 classinfo *res = classcache_store(NULL, c, true);
1912 RT_TIMING_GET_TIME(time_cache);
1914 /* SUN compatible -verbose:class output */
1916 if (opt_verboseclass && r) {
1918 utf_display_printable_ascii_classname(name);
1919 printf(" from %s]\n", cb->path);
1926 #if defined(ENABLE_STATISTICS)
1929 if (opt_getloadingtime)
1932 if (opt_getcompilingtime)
1933 compilingtime_start();
1936 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1937 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1938 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1939 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1945 /* load_class_from_classbuffer *************************************************
1947 Loads everything interesting about a class from the class file. The
1948 'classinfo' structure must have been allocated previously.
1950 The super class and the interfaces implemented by this class need
1951 not be loaded. The link is set later by the function 'class_link'.
1953 The loaded class is removed from the list 'unloadedclasses' and
1954 added to the list 'unlinkedclasses'.
1957 This function is NOT synchronized!
1959 *******************************************************************************/
1961 classinfo *load_class_from_classbuffer(classbuffer *cb)
1969 descriptor_pool *descpool;
1970 #if defined(ENABLE_STATISTICS)
1974 #if defined(ENABLE_RT_TIMING)
1975 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1976 time_setup, time_fields, time_methods, time_classrefs,
1977 time_descs, time_setrefs, time_parsefds, time_parsemds,
1978 time_parsecpool, time_verify, time_attrs;
1981 RT_TIMING_GET_TIME(time_start);
1983 /* get the classbuffer's class */
1987 /* the class is already loaded */
1989 if (c->state & CLASS_LOADED)
1992 #if defined(ENABLE_STATISTICS)
1994 count_class_loads++;
1997 #if !defined(NDEBUG)
1998 /* output for debugging purposes */
2001 log_message_class("Loading class: ", c);
2004 /* mark start of dump memory area */
2006 dumpsize = dump_size();
2008 /* class is currently loading */
2010 c->state |= CLASS_LOADING;
2012 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
2013 goto return_exception;
2015 /* check signature */
2017 if (suck_u4(cb) != MAGIC) {
2018 exceptions_throw_classformaterror(c, "Bad magic number");
2020 goto return_exception;
2028 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
2029 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
2030 goto return_exception;
2033 RT_TIMING_GET_TIME(time_checks);
2035 /* create a new descriptor pool */
2037 descpool = descriptor_pool_new(c);
2039 RT_TIMING_GET_TIME(time_ndpool);
2041 /* load the constant pool */
2043 if (!load_constantpool(cb, descpool))
2044 goto return_exception;
2046 RT_TIMING_GET_TIME(time_cpool);
2050 if (!suck_check_classbuffer_size(cb, 2))
2051 goto return_exception;
2053 /* We OR the flags here, as we set already some flags in
2054 class_create_classinfo. */
2056 c->flags |= suck_u2(cb);
2058 /* check ACC flags consistency */
2060 if (c->flags & ACC_INTERFACE) {
2061 if (!(c->flags & ACC_ABSTRACT)) {
2062 /* We work around this because interfaces in JDK 1.1 are
2063 * not declared abstract. */
2065 c->flags |= ACC_ABSTRACT;
2068 if (c->flags & ACC_FINAL) {
2069 exceptions_throw_classformaterror(c,
2070 "Illegal class modifiers: 0x%X",
2072 goto return_exception;
2075 if (c->flags & ACC_SUPER) {
2076 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
2080 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
2081 exceptions_throw_classformaterror(c,
2082 "Illegal class modifiers: 0x%X",
2084 goto return_exception;
2087 if (!suck_check_classbuffer_size(cb, 2 + 2))
2088 goto return_exception;
2093 if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
2094 goto return_exception;
2096 if (c->name == utf_not_named_yet) {
2097 /* we finally have a name for this class */
2099 class_set_packagename(c);
2101 } else if (name != c->name) {
2102 /* TODO: i want to be an exceptions-function! */
2106 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
2107 utf_bytes(name) + strlen(")") + strlen("0");
2109 msg = MNEW(char, msglen);
2111 utf_copy_classname(msg, c->name);
2112 strcat(msg, " (wrong name: ");
2113 utf_cat_classname(msg, name);
2117 /* *exceptionptr = */
2118 /* new_exception_message("java/lang/NoClassDefFoundError", msg); */
2119 exceptions_throw_noclassdeffounderror(c->name);
2121 MFREE(msg, char, msglen);
2123 goto return_exception;
2126 /* retrieve superclass */
2128 c->super.any = NULL;
2129 if ((i = suck_u2(cb))) {
2130 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
2131 goto return_exception;
2133 /* java.lang.Object may not have a super class. */
2135 if (c->name == utf_java_lang_Object) {
2136 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
2137 goto return_exception;
2140 /* Interfaces must have java.lang.Object as super class. */
2142 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
2143 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
2144 goto return_exception;
2150 /* This is only allowed for java.lang.Object. */
2152 if (c->name != utf_java_lang_Object) {
2153 exceptions_throw_classformaterror(c, "Bad superclass index");
2154 goto return_exception;
2158 /* retrieve interfaces */
2160 if (!suck_check_classbuffer_size(cb, 2))
2161 goto return_exception;
2163 c->interfacescount = suck_u2(cb);
2165 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
2166 goto return_exception;
2168 c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
2169 for (i = 0; i < c->interfacescount; i++) {
2170 /* the classrefs are created later */
2171 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2172 goto return_exception;
2175 RT_TIMING_GET_TIME(time_setup);
2178 if (!suck_check_classbuffer_size(cb, 2))
2179 goto return_exception;
2181 c->fieldscount = suck_u2(cb);
2182 #if defined(ENABLE_GC_CACAO)
2183 c->fields = MNEW(fieldinfo, c->fieldscount);
2184 MZERO(c->fields, fieldinfo, c->fieldscount);
2186 c->fields = GCNEW_UNCOLLECTABLE(fieldinfo, c->fieldscount);
2189 for (i = 0; i < c->fieldscount; i++) {
2190 if (!load_field(cb, &(c->fields[i]),descpool))
2191 goto return_exception;
2194 RT_TIMING_GET_TIME(time_fields);
2197 if (!suck_check_classbuffer_size(cb, 2))
2198 goto return_exception;
2200 c->methodscount = suck_u2(cb);
2201 c->methods = MNEW(methodinfo, c->methodscount);
2203 MZERO(c->methods, methodinfo, c->methodscount);
2205 for (i = 0; i < c->methodscount; i++) {
2206 if (!loader_load_method(cb, &(c->methods[i]), descpool))
2207 goto return_exception;
2210 RT_TIMING_GET_TIME(time_methods);
2212 /* create the class reference table */
2215 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
2217 RT_TIMING_GET_TIME(time_classrefs);
2219 /* allocate space for the parsed descriptors */
2221 descriptor_pool_alloc_parsed_descriptors(descpool);
2223 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
2225 #if defined(ENABLE_STATISTICS)
2227 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
2228 count_classref_len += classrefsize;
2229 count_parsed_desc_len += descsize;
2233 RT_TIMING_GET_TIME(time_descs);
2235 /* put the classrefs in the constant pool */
2236 for (i = 0; i < c->cpcount; i++) {
2237 if (c->cptags[i] == CONSTANT_Class) {
2238 utf *name = (utf *) c->cpinfos[i];
2239 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
2243 /* set the super class reference */
2246 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
2248 goto return_exception;
2251 /* set the super interfaces references */
2253 for (i = 0; i < c->interfacescount; i++) {
2254 c->interfaces[i].ref =
2255 descriptor_pool_lookup_classref(descpool,
2256 (utf *) c->interfaces[i].any);
2257 if (!c->interfaces[i].ref)
2258 goto return_exception;
2261 RT_TIMING_GET_TIME(time_setrefs);
2263 /* parse field descriptors */
2265 for (i = 0; i < c->fieldscount; i++) {
2266 c->fields[i].parseddesc =
2267 descriptor_pool_parse_field_descriptor(descpool,
2268 c->fields[i].descriptor);
2269 if (!c->fields[i].parseddesc)
2270 goto return_exception;
2273 RT_TIMING_GET_TIME(time_parsefds);
2275 /* parse method descriptors */
2277 for (i = 0; i < c->methodscount; i++) {
2278 methodinfo *m = &c->methods[i];
2280 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
2281 m->flags, class_get_self_classref(m->class));
2283 goto return_exception;
2285 for (j = 0; j < m->rawexceptiontablelength; j++) {
2286 if (!m->rawexceptiontable[j].catchtype.any)
2288 if ((m->rawexceptiontable[j].catchtype.ref =
2289 descriptor_pool_lookup_classref(descpool,
2290 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
2291 goto return_exception;
2294 for (j = 0; j < m->thrownexceptionscount; j++) {
2295 if (!m->thrownexceptions[j].any)
2297 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
2298 (utf *) m->thrownexceptions[j].any)) == NULL)
2299 goto return_exception;
2303 RT_TIMING_GET_TIME(time_parsemds);
2305 /* parse the loaded descriptors */
2307 for (i = 0; i < c->cpcount; i++) {
2308 constant_FMIref *fmi;
2311 switch (c->cptags[i]) {
2312 case CONSTANT_Fieldref:
2313 fmi = (constant_FMIref *) c->cpinfos[i];
2314 fmi->parseddesc.fd =
2315 descriptor_pool_parse_field_descriptor(descpool,
2317 if (!fmi->parseddesc.fd)
2318 goto return_exception;
2319 index = fmi->p.index;
2321 (constant_classref *) class_getconstant(c, index,
2323 if (!fmi->p.classref)
2324 goto return_exception;
2326 case CONSTANT_Methodref:
2327 case CONSTANT_InterfaceMethodref:
2328 fmi = (constant_FMIref *) c->cpinfos[i];
2329 index = fmi->p.index;
2331 (constant_classref *) class_getconstant(c, index,
2333 if (!fmi->p.classref)
2334 goto return_exception;
2335 fmi->parseddesc.md =
2336 descriptor_pool_parse_method_descriptor(descpool,
2340 if (!fmi->parseddesc.md)
2341 goto return_exception;
2346 RT_TIMING_GET_TIME(time_parsecpool);
2348 #ifdef ENABLE_VERIFIER
2349 /* Check if all fields and methods can be uniquely
2350 * identified by (name,descriptor). */
2353 /* We use a hash table here to avoid making the
2354 * average case quadratic in # of methods, fields.
2356 static int shift = 0;
2358 u2 *next; /* for chaining colliding hash entries */
2364 /* Allocate hashtable */
2365 len = c->methodscount;
2366 if (len < c->fieldscount) len = c->fieldscount;
2368 hashtab = MNEW(u2,(hashlen + len));
2369 next = hashtab + hashlen;
2371 /* Determine bitshift (to get good hash values) */
2381 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2383 for (i = 0; i < c->fieldscount; ++i) {
2384 fieldinfo *fi = c->fields + i;
2386 /* It's ok if we lose bits here */
2387 index = ((((size_t) fi->name) +
2388 ((size_t) fi->descriptor)) >> shift) % hashlen;
2390 if ((old = hashtab[index])) {
2394 if (c->fields[old].name == fi->name &&
2395 c->fields[old].descriptor == fi->descriptor) {
2396 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
2397 goto return_exception;
2399 } while ((old = next[old]));
2401 hashtab[index] = i + 1;
2405 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2407 for (i = 0; i < c->methodscount; ++i) {
2408 methodinfo *mi = c->methods + i;
2410 /* It's ok if we lose bits here */
2411 index = ((((size_t) mi->name) +
2412 ((size_t) mi->descriptor)) >> shift) % hashlen;
2416 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2417 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2421 if ((old = hashtab[index])) {
2425 if (c->methods[old].name == mi->name &&
2426 c->methods[old].descriptor == mi->descriptor) {
2427 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
2428 goto return_exception;
2430 } while ((old = next[old]));
2432 hashtab[index] = i + 1;
2435 MFREE(hashtab, u2, (hashlen + len));
2437 #endif /* ENABLE_VERIFIER */
2439 RT_TIMING_GET_TIME(time_verify);
2441 #if defined(ENABLE_STATISTICS)
2443 size_classinfo += sizeof(classinfo*) * c->interfacescount;
2444 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
2445 size_methodinfo += sizeof(methodinfo) * c->methodscount;
2449 /* load attribute structures */
2451 if (!class_load_attributes(cb))
2452 goto return_exception;
2454 /* Pre Java 1.5 version don't check this. This implementation is like
2455 Java 1.5 do it: for class file version 45.3 we don't check it, older
2456 versions are checked.
2459 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
2460 /* check if all data has been read */
2461 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
2463 if (classdata_left > 0) {
2464 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
2465 goto return_exception;
2469 RT_TIMING_GET_TIME(time_attrs);
2471 /* release dump area */
2473 dump_release(dumpsize);
2475 /* revert loading state and class is loaded */
2477 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2479 #if defined(ENABLE_JVMTI)
2480 /* fire Class Prepare JVMTI event */
2483 jvmti_ClassLoadPrepare(true, c);
2486 #if !defined(NDEBUG)
2488 log_message_class("Loading done class: ", c);
2491 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
2492 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
2493 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
2494 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
2495 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
2496 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
2497 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
2498 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
2499 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
2500 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
2501 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
2502 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
2503 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
2504 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
2505 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
2510 /* release dump area */
2512 dump_release(dumpsize);
2514 /* an exception has been thrown */
2520 /* load_newly_created_array ****************************************************
2522 Load a newly created array class.
2525 c....................the array class C has been loaded
2526 other classinfo......the array class was found in the class cache,
2528 NULL.................an exception has been thrown
2531 This is an internal function. Do not use it unless you know exactly
2534 Use one of the load_class_... functions for general array class loading.
2536 *******************************************************************************/
2538 classinfo *load_newly_created_array(classinfo *c, classloader *loader)
2540 classinfo *comp = NULL;
2542 methoddesc *clonedesc;
2543 constant_classref *classrefs;
2548 text = c->name->text;
2549 namelen = c->name->blength;
2551 /* Check array class name */
2553 if ((namelen < 2) || (text[0] != '[')) {
2554 exceptions_throw_noclassdeffounderror(c->name);
2558 /* Check the element type */
2562 /* c is an array of arrays. We have to create the component class. */
2564 u = utf_new(text + 1, namelen - 1);
2565 if (!(comp = load_class_from_classloader(u, loader)))
2568 assert(comp->state & CLASS_LOADED);
2574 /* the array's flags are that of the component class */
2575 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2576 c->classloader = comp->classloader;
2580 /* c is an array of objects. */
2582 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2583 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2584 exceptions_throw_noclassdeffounderror(c->name);
2588 u = utf_new(text + 2, namelen - 3);
2590 if (!(comp = load_class_from_classloader(u, loader)))
2593 assert(comp->state & CLASS_LOADED);
2599 /* the array's flags are that of the component class */
2600 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2601 c->classloader = comp->classloader;
2605 /* c is an array of a primitive type */
2607 /* check for cases like `[II' */
2609 exceptions_throw_noclassdeffounderror(c->name);
2613 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2614 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2615 c->classloader = NULL;
2618 assert(class_java_lang_Object);
2619 #if defined(ENABLE_JAVASE)
2620 assert(class_java_lang_Cloneable);
2621 assert(class_java_io_Serializable);
2624 /* setup the array class */
2626 c->super.cls = class_java_lang_Object;
2628 #if defined(ENABLE_JAVASE)
2629 c->interfacescount = 2;
2630 c->interfaces = MNEW(classref_or_classinfo, 2);
2635 tc = class_java_lang_Cloneable;
2636 assert(tc->state & CLASS_LOADED);
2637 list_add_first(&unlinkedclasses, tc);
2638 c->interfaces[0].cls = tc;
2640 tc = class_java_io_Serializable;
2641 assert(tc->state & CLASS_LOADED);
2642 list_add_first(&unlinkedclasses, tc);
2643 c->interfaces[1].cls = tc;
2646 c->interfaces[0].cls = class_java_lang_Cloneable;
2647 c->interfaces[1].cls = class_java_io_Serializable;
2649 #elif defined(ENABLE_JAVAME_CLDC1_1)
2650 c->interfacescount = 0;
2651 c->interfaces = NULL;
2653 #error unknow Java configuration
2656 c->methodscount = 1;
2657 c->methods = MNEW(methodinfo, c->methodscount);
2658 MZERO(c->methods, methodinfo, c->methodscount);
2660 classrefs = MNEW(constant_classref, 2);
2661 CLASSREF_INIT(classrefs[0], c, c->name);
2662 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2664 /* create descriptor for clone method */
2665 /* we need one paramslot which is reserved for the 'this' parameter */
2666 clonedesc = NEW(methoddesc);
2667 clonedesc->returntype.type = TYPE_ADR;
2668 clonedesc->returntype.classref = classrefs + 1;
2669 clonedesc->returntype.arraydim = 0;
2670 /* initialize params to "empty", add real params below in
2671 descriptor_params_from_paramtypes */
2672 clonedesc->paramcount = 0;
2673 clonedesc->paramslots = 0;
2674 clonedesc->paramtypes[0].classref = classrefs + 0;
2675 clonedesc->params = NULL;
2677 /* create methodinfo */
2680 MSET(clone, 0, methodinfo, 1);
2682 /* ATTENTION: if you delete the ACC_NATIVE below, set
2683 clone->maxlocals=1 (interpreter related) */
2685 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2686 clone->name = utf_clone;
2687 clone->descriptor = utf_void__java_lang_Object;
2688 clone->parseddesc = clonedesc;
2691 /* parse the descriptor to get the register allocation */
2693 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2696 clone->code = codegen_createnativestub(BUILTIN_clone, clone);
2698 /* XXX: field: length? */
2700 /* array classes are not loaded from class files */
2702 c->state |= CLASS_LOADED;
2703 c->parseddescs = (u1 *) clonedesc;
2704 c->parseddescsize = sizeof(methodinfo);
2705 c->classrefs = classrefs;
2706 c->classrefcount = 1;
2708 /* insert class into the loaded class cache */
2709 /* XXX free classinfo if NULL returned? */
2711 return classcache_store(loader, c, true);
2715 /* loader_close ****************************************************************
2717 Frees all resources.
2719 *******************************************************************************/
2721 void loader_close(void)
2728 * These are local overrides for various environment variables in Emacs.
2729 * Please do not remove this and leave it at the end of the file, where
2730 * Emacs will automagically detect them.
2731 * ---------------------------------------------------------------------
2734 * indent-tabs-mode: t
2738 * vim:noexpandtab:sw=4:ts=4: