1 /* src/vm/loader.c - class loader functions
3 Copyright (C) 1996-2005, 2006 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 Contact: cacao@cacaojvm.org
27 Authors: Reinhard Grafl
34 $Id: loader.c 7240 2007-01-27 13:01:35Z twisti $
47 #include "mm/memory.h"
48 #include "native/native.h"
49 #include "native/include/java_lang_Throwable.h"
51 #if defined(ENABLE_THREADS)
52 # include "threads/native/threads.h"
55 #include "toolbox/logging.h"
57 #if defined(ENABLE_JAVASE)
58 # include "vm/annotation.h"
59 # include "vm/stackmap.h"
62 #include "vm/builtin.h"
63 #include "vm/classcache.h"
64 #include "vm/exceptions.h"
65 #include "vm/global.h"
66 #include "vm/linker.h"
67 #include "vm/loader.h"
68 #include "vm/options.h"
69 #include "vm/statistics.h"
70 #include "vm/stringlocal.h"
74 #if defined(ENABLE_ZLIB)
78 #include "vm/jit/asmpart.h"
79 #include "vm/jit/codegen-common.h"
80 #include "vm/rt-timing.h"
82 #if defined(ENABLE_JVMTI)
83 #include "native/jvmti/cacaodbg.h"
87 /* loader_init *****************************************************************
89 Initializes all lists and loads all classes required for the system
92 *******************************************************************************/
94 bool loader_init(void)
96 #if defined(ENABLE_THREADS)
97 list_classpath_entry *lce;
99 /* Initialize the monitor pointer for zip/jar file locking. */
101 for (lce = list_first(list_classpath_entries); lce != NULL;
102 lce = list_next(list_classpath_entries, lce))
103 if (lce->type == CLASSPATH_ARCHIVE)
104 lock_init_object_lock((java_objectheader *) lce);
107 /* load some important classes */
109 if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
112 if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
115 #if defined(ENABLE_JAVASE)
116 if (!(class_java_lang_Cloneable =
117 load_class_bootstrap(utf_java_lang_Cloneable)))
120 if (!(class_java_io_Serializable =
121 load_class_bootstrap(utf_java_io_Serializable)))
125 /* load classes for wrapping primitive types */
127 #if defined(ENABLE_JAVASE)
128 if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
132 if (!(class_java_lang_Boolean =
133 load_class_bootstrap(utf_java_lang_Boolean)))
136 if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
139 if (!(class_java_lang_Character =
140 load_class_bootstrap(utf_java_lang_Character)))
143 if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
146 if (!(class_java_lang_Integer =
147 load_class_bootstrap(utf_java_lang_Integer)))
150 if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
153 if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
156 if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
160 /* load some other important classes */
162 if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
165 #if defined(ENABLE_JAVASE)
166 if (!(class_java_lang_ClassLoader =
167 load_class_bootstrap(utf_java_lang_ClassLoader)))
170 if (!(class_java_lang_SecurityManager =
171 load_class_bootstrap(utf_java_lang_SecurityManager)))
175 if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
178 if (!(class_java_lang_Thread =
179 load_class_bootstrap(utf_new_char("java/lang/Thread"))))
182 #if defined(ENABLE_JAVASE)
183 if (!(class_java_lang_ThreadGroup =
184 load_class_bootstrap(utf_java_lang_ThreadGroup)))
188 #if defined(WITH_CLASSPATH_GNU)
189 if (!(class_java_lang_VMSystem =
190 load_class_bootstrap(utf_new_char("java/lang/VMSystem"))))
194 if (!(class_java_lang_VMThread =
195 load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
200 /* some classes which may be used more often */
202 #if defined(ENABLE_JAVASE)
203 if (!(class_java_lang_StackTraceElement =
204 load_class_bootstrap(utf_java_lang_StackTraceElement)))
207 if (!(class_java_lang_reflect_Constructor =
208 load_class_bootstrap(utf_java_lang_reflect_Constructor)))
211 if (!(class_java_lang_reflect_Field =
212 load_class_bootstrap(utf_java_lang_reflect_Field)))
215 if (!(class_java_lang_reflect_Method =
216 load_class_bootstrap(utf_java_lang_reflect_Method)))
219 if (!(class_java_security_PrivilegedAction =
220 load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
223 if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
226 if (!(arrayclass_java_lang_Object =
227 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
235 /* loader_load_all_classes *****************************************************
237 Loads all classes specified in the BOOTCLASSPATH.
239 *******************************************************************************/
241 void loader_load_all_classes(void)
243 list_classpath_entry *lce;
244 #if defined(ENABLE_ZLIB)
247 hashtable_zipfile_entry *htzfe;
251 for (lce = list_first(list_classpath_entries); lce != NULL;
252 lce = list_next(list_classpath_entries, lce)) {
253 #if defined(ENABLE_ZLIB)
254 if (lce->type == CLASSPATH_ARCHIVE) {
255 /* get the classes hashtable */
259 for (slot = 0; slot < ht->size; slot++) {
260 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
262 for (; htzfe; htzfe = htzfe->hashlink) {
265 /* skip all entries in META-INF and .properties,
268 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
269 strstr(u->text, ".properties") ||
270 strstr(u->text, ".png"))
273 /* load class from bootstrap classloader */
275 if (!load_class_bootstrap(u)) {
276 fprintf(stderr, "Error loading: ");
277 utf_fprint_printable_ascii_classname(stderr, u);
278 fprintf(stderr, "\n");
281 /* print out exception and cause */
283 exceptions_print_exception(*exceptionptr);
291 #if defined(ENABLE_ZLIB)
298 /* loader_skip_attribute_body **************************************************
300 Skips an attribute the attribute_name_index has already been read.
303 u2 attribute_name_index;
305 u1 info[attribute_length];
308 *******************************************************************************/
310 bool loader_skip_attribute_body(classbuffer *cb)
314 if (!suck_check_classbuffer_size(cb, 4))
317 attribute_length = suck_u4(cb);
319 if (!suck_check_classbuffer_size(cb, attribute_length))
322 suck_skip_nbytes(cb, attribute_length);
328 /* load_constantpool ***********************************************************
330 Loads the constantpool of a class, the entries are transformed into
331 a simpler format by resolving references (a detailed overview of
332 the compact structures can be found in global.h).
334 *******************************************************************************/
336 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
339 /* The following structures are used to save information which cannot be
340 processed during the first pass. After the complete constantpool has
341 been traversed the references can be resolved.
342 (only in specific order) */
344 /* CONSTANT_Class entries */
345 typedef struct forward_class {
346 struct forward_class *next;
351 /* CONSTANT_String */
352 typedef struct forward_string {
353 struct forward_string *next;
358 /* CONSTANT_NameAndType */
359 typedef struct forward_nameandtype {
360 struct forward_nameandtype *next;
364 } forward_nameandtype;
366 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
367 typedef struct forward_fieldmethint {
368 struct forward_fieldmethint *next;
372 u2 nameandtype_index;
373 } forward_fieldmethint;
379 forward_class *forward_classes = NULL;
380 forward_string *forward_strings = NULL;
381 forward_nameandtype *forward_nameandtypes = NULL;
382 forward_fieldmethint *forward_fieldmethints = NULL;
386 forward_nameandtype *nfn;
387 forward_fieldmethint *nff;
395 /* number of entries in the constant_pool table plus one */
396 if (!suck_check_classbuffer_size(cb, 2))
399 cpcount = c->cpcount = suck_u2(cb);
401 /* allocate memory */
402 cptags = c->cptags = MNEW(u1, cpcount);
403 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
406 exceptions_throw_classformaterror(c, "Illegal constant pool size");
410 #if defined(ENABLE_STATISTICS)
412 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
415 /* initialize constantpool */
416 for (idx = 0; idx < cpcount; idx++) {
417 cptags[idx] = CONSTANT_UNUSED;
422 /******* first pass *******/
423 /* entries which cannot be resolved now are written into
424 temporary structures and traversed again later */
427 while (idx < cpcount) {
430 /* get constant type */
431 if (!suck_check_classbuffer_size(cb, 1))
438 nfc = DNEW(forward_class);
440 nfc->next = forward_classes;
441 forward_classes = nfc;
443 nfc->thisindex = idx;
444 /* reference to CONSTANT_NameAndType */
445 if (!suck_check_classbuffer_size(cb, 2))
448 nfc->name_index = suck_u2(cb);
453 case CONSTANT_String:
454 nfs = DNEW(forward_string);
456 nfs->next = forward_strings;
457 forward_strings = nfs;
459 nfs->thisindex = idx;
461 /* reference to CONSTANT_Utf8_info with string characters */
462 if (!suck_check_classbuffer_size(cb, 2))
465 nfs->string_index = suck_u2(cb);
470 case CONSTANT_NameAndType:
471 nfn = DNEW(forward_nameandtype);
473 nfn->next = forward_nameandtypes;
474 forward_nameandtypes = nfn;
476 nfn->thisindex = idx;
478 if (!suck_check_classbuffer_size(cb, 2 + 2))
481 /* reference to CONSTANT_Utf8_info containing simple name */
482 nfn->name_index = suck_u2(cb);
484 /* reference to CONSTANT_Utf8_info containing field or method
486 nfn->sig_index = suck_u2(cb);
491 case CONSTANT_Fieldref:
492 case CONSTANT_Methodref:
493 case CONSTANT_InterfaceMethodref:
494 nff = DNEW(forward_fieldmethint);
496 nff->next = forward_fieldmethints;
497 forward_fieldmethints = nff;
499 nff->thisindex = idx;
503 if (!suck_check_classbuffer_size(cb, 2 + 2))
506 /* class or interface type that contains the declaration of the
508 nff->class_index = suck_u2(cb);
510 /* name and descriptor of the field or method */
511 nff->nameandtype_index = suck_u2(cb);
516 case CONSTANT_Integer: {
517 constant_integer *ci = NEW(constant_integer);
519 #if defined(ENABLE_STATISTICS)
521 count_const_pool_len += sizeof(constant_integer);
524 if (!suck_check_classbuffer_size(cb, 4))
527 ci->value = suck_s4(cb);
528 cptags[idx] = CONSTANT_Integer;
535 case CONSTANT_Float: {
536 constant_float *cf = NEW(constant_float);
538 #if defined(ENABLE_STATISTICS)
540 count_const_pool_len += sizeof(constant_float);
543 if (!suck_check_classbuffer_size(cb, 4))
546 cf->value = suck_float(cb);
547 cptags[idx] = CONSTANT_Float;
554 case CONSTANT_Long: {
555 constant_long *cl = NEW(constant_long);
557 #if defined(ENABLE_STATISTICS)
559 count_const_pool_len += sizeof(constant_long);
562 if (!suck_check_classbuffer_size(cb, 8))
565 cl->value = suck_s8(cb);
566 cptags[idx] = CONSTANT_Long;
570 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
576 case CONSTANT_Double: {
577 constant_double *cd = NEW(constant_double);
579 #if defined(ENABLE_STATISTICS)
581 count_const_pool_len += sizeof(constant_double);
584 if (!suck_check_classbuffer_size(cb, 8))
587 cd->value = suck_double(cb);
588 cptags[idx] = CONSTANT_Double;
592 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
598 case CONSTANT_Utf8: {
601 /* number of bytes in the bytes array (not string-length) */
602 if (!suck_check_classbuffer_size(cb, 2))
605 length = suck_u2(cb);
606 cptags[idx] = CONSTANT_Utf8;
608 /* validate the string */
609 if (!suck_check_classbuffer_size(cb, length))
612 #ifdef ENABLE_VERIFIER
614 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
616 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
619 #endif /* ENABLE_VERIFIER */
620 /* insert utf-string into the utf-symboltable */
621 cpinfos[idx] = utf_new((char *) cb->pos, length);
623 /* skip bytes of the string (buffer size check above) */
624 suck_skip_nbytes(cb, length);
630 exceptions_throw_classformaterror(c, "Illegal constant pool type");
636 /* resolve entries in temporary structures */
638 while (forward_classes) {
640 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
644 #ifdef ENABLE_VERIFIER
645 if (opt_verify && !is_valid_name_utf(name)) {
646 exceptions_throw_classformaterror(c, "Class reference with invalid name");
649 #endif /* ENABLE_VERIFIER */
651 /* add all class references to the descriptor_pool */
653 if (!descriptor_pool_add_class(descpool, name))
656 cptags[forward_classes->thisindex] = CONSTANT_Class;
661 if (!(tc = load_class_bootstrap(name)))
664 /* link the class later, because we cannot link the class currently
666 list_add_first(&unlinkedclasses, tc);
669 /* the classref is created later */
670 cpinfos[forward_classes->thisindex] = name;
672 nfc = forward_classes;
673 forward_classes = forward_classes->next;
676 while (forward_strings) {
678 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
682 /* resolve utf-string */
683 cptags[forward_strings->thisindex] = CONSTANT_String;
684 cpinfos[forward_strings->thisindex] = text;
686 nfs = forward_strings;
687 forward_strings = forward_strings->next;
690 while (forward_nameandtypes) {
691 constant_nameandtype *cn = NEW(constant_nameandtype);
693 #if defined(ENABLE_STATISTICS)
695 count_const_pool_len += sizeof(constant_nameandtype);
698 /* resolve simple name and descriptor */
699 cn->name = class_getconstant(c,
700 forward_nameandtypes->name_index,
705 cn->descriptor = class_getconstant(c,
706 forward_nameandtypes->sig_index,
711 #ifdef ENABLE_VERIFIER
714 if (!is_valid_name_utf(cn->name)) {
715 exceptions_throw_classformaterror(c,
716 "Illegal Field name \"%s\"",
722 /* disallow referencing <clinit> among others */
723 if (cn->name->text[0] == '<' && cn->name != utf_init) {
724 exceptions_throw_classformaterror(c, "Illegal reference to special method");
728 #endif /* ENABLE_VERIFIER */
730 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
731 cpinfos[forward_nameandtypes->thisindex] = cn;
733 nfn = forward_nameandtypes;
734 forward_nameandtypes = forward_nameandtypes->next;
737 while (forward_fieldmethints) {
738 constant_nameandtype *nat;
739 constant_FMIref *fmi = NEW(constant_FMIref);
741 #if defined(ENABLE_STATISTICS)
743 count_const_pool_len += sizeof(constant_FMIref);
745 /* resolve simple name and descriptor */
747 nat = class_getconstant(c,
748 forward_fieldmethints->nameandtype_index,
749 CONSTANT_NameAndType);
753 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
755 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
758 /* the classref is created later */
760 fmi->p.index = forward_fieldmethints->class_index;
761 fmi->name = nat->name;
762 fmi->descriptor = nat->descriptor;
764 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
765 cpinfos[forward_fieldmethints->thisindex] = fmi;
767 nff = forward_fieldmethints;
768 forward_fieldmethints = forward_fieldmethints->next;
771 /* everything was ok */
777 /* loader_load_attribute_signature *********************************************
779 Signature_attribute {
780 u2 attribute_name_index;
785 *******************************************************************************/
787 #if defined(ENABLE_JAVASE)
788 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
798 /* check remaining bytecode */
800 if (!suck_check_classbuffer_size(cb, 4 + 2))
803 /* check attribute length */
805 attribute_length = suck_u4(cb);
807 if (attribute_length != 2) {
808 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
812 if (*signature != NULL) {
813 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
819 signature_index = suck_u2(cb);
821 if (!(*signature = class_getconstant(c, signature_index, CONSTANT_Utf8)))
826 #endif /* defined(ENABLE_JAVASE) */
829 /* load_field ******************************************************************
831 Load everything about a class field from the class file and fill a
832 'fieldinfo' structure. For static fields, space in the data segment
835 *******************************************************************************/
837 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
839 static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
844 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
849 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
852 f->flags = suck_u2(cb);
854 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
859 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
863 f->parseddesc = NULL;
865 if (!descriptor_pool_add(descpool, u, NULL))
868 /* descriptor_pool_add accepts method descriptors, so we have to check */
869 /* against them here before the call of descriptor_to_basic_type below. */
870 if (u->text[0] == '(') {
871 exceptions_throw_classformaterror(c, "Method descriptor used for field");
875 #ifdef ENABLE_VERIFIER
878 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<') {
879 exceptions_throw_classformaterror(c,
880 "Illegal Field name \"%s\"",
885 /* check flag consistency */
886 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
888 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
889 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
890 exceptions_throw_classformaterror(c,
891 "Illegal field modifiers: 0x%X",
896 if (c->flags & ACC_INTERFACE) {
897 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
898 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
899 f->flags & ACC_TRANSIENT) {
900 exceptions_throw_classformaterror(c,
901 "Illegal field modifiers: 0x%X",
907 #endif /* ENABLE_VERIFIER */
909 f->type = jtype = descriptor_to_basic_type(f->descriptor); /* data type */
910 f->offset = 0; /* offset from start of object */
928 if (!(f->flags & ACC_STATIC))
929 c->flags |= ACC_CLASS_HAS_POINTERS;
942 /* read attributes */
943 if (!suck_check_classbuffer_size(cb, 2))
946 attrnum = suck_u2(cb);
947 for (i = 0; i < attrnum; i++) {
948 if (!suck_check_classbuffer_size(cb, 2))
951 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
954 if (u == utf_ConstantValue) {
955 if (!suck_check_classbuffer_size(cb, 4 + 2))
958 /* check attribute length */
960 if (suck_u4(cb) != 2) {
961 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
965 /* constant value attribute */
967 if (pindex != field_load_NOVALUE) {
968 exceptions_throw_classformaterror(c, "Multiple ConstantValue attributes");
972 /* index of value in constantpool */
974 pindex = suck_u2(cb);
976 /* initialize field with value from constantpool */
979 constant_integer *ci;
981 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
984 f->value.i = ci->value;
991 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
994 f->value.l = cl->value;
1001 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
1004 f->value.f = cf->value;
1009 constant_double *cd;
1011 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
1014 f->value.d = cd->value;
1019 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
1022 /* create javastring from compressed utf8-string */
1023 f->value.a = literalstring_new(u);
1027 log_text("Invalid Constant - Type");
1030 #if defined(ENABLE_JAVASE)
1031 else if (u == utf_Signature) {
1034 if (!loader_load_attribute_signature(cb, &(f->signature)))
1039 /* unknown attribute */
1041 if (!loader_skip_attribute_body(cb))
1046 /* everything was ok */
1052 /* loader_load_method **********************************************************
1054 Loads a method from the class file and fills an existing
1055 'methodinfo' structure. For native methods, the function pointer
1056 field is set to the real function pointer, for JavaVM methods a
1057 pointer to the compiler is used preliminarily.
1062 u2 descriptor_index;
1063 u2 attributes_count;
1064 attribute_info attributes[attribute_count];
1068 u2 attribute_name_index;
1069 u4 attribute_length;
1070 u1 info[attribute_length];
1073 LineNumberTable_attribute {
1074 u2 attribute_name_index;
1075 u4 attribute_length;
1076 u2 line_number_table_length;
1080 } line_number_table[line_number_table_length];
1083 *******************************************************************************/
1085 static bool loader_load_method(classbuffer *cb, methodinfo *m,
1086 descriptor_pool *descpool)
1093 u2 descriptor_index;
1094 u2 attributes_count;
1095 u2 attribute_name_index;
1096 utf *attribute_name;
1097 u2 code_attributes_count;
1098 u2 code_attribute_name_index;
1099 utf *code_attribute_name;
1105 #if defined(ENABLE_THREADS)
1106 lock_init_object_lock(&m->header);
1109 #if defined(ENABLE_STATISTICS)
1111 count_all_methods++;
1114 /* all fields of m have been zeroed in load_class_from_classbuffer */
1118 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
1123 m->flags = suck_u2(cb);
1127 name_index = suck_u2(cb);
1129 if (!(u = class_getconstant(c, name_index, CONSTANT_Utf8)))
1136 descriptor_index = suck_u2(cb);
1138 if (!(u = class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
1143 if (!descriptor_pool_add(descpool, u, &argcount))
1146 #ifdef ENABLE_VERIFIER
1148 if (!is_valid_name_utf(m->name)) {
1149 exceptions_throw_classformaterror(c, "Method with invalid name");
1153 if (m->name->text[0] == '<' &&
1154 m->name != utf_init && m->name != utf_clinit) {
1155 exceptions_throw_classformaterror(c, "Method with invalid special name");
1159 #endif /* ENABLE_VERIFIER */
1161 if (!(m->flags & ACC_STATIC))
1162 argcount++; /* count the 'this' argument */
1164 #ifdef ENABLE_VERIFIER
1166 if (argcount > 255) {
1167 exceptions_throw_classformaterror(c, "Too many arguments in signature");
1171 /* check flag consistency */
1172 if (m->name != utf_clinit) {
1173 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1175 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1176 exceptions_throw_classformaterror(c,
1177 "Illegal method modifiers: 0x%X",
1182 if (m->flags & ACC_ABSTRACT) {
1183 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1184 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1185 exceptions_throw_classformaterror(c,
1186 "Illegal method modifiers: 0x%X",
1192 if (c->flags & ACC_INTERFACE) {
1193 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1194 exceptions_throw_classformaterror(c,
1195 "Illegal method modifiers: 0x%X",
1201 if (m->name == utf_init) {
1202 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1203 ACC_NATIVE | ACC_ABSTRACT)) {
1204 exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
1210 #endif /* ENABLE_VERIFIER */
1212 /* mark the method as monomorphic until further notice */
1214 m->flags |= ACC_METHOD_MONOMORPHIC;
1216 /* non-abstract methods have an implementation in this class */
1218 if (!(m->flags & ACC_ABSTRACT))
1219 m->flags |= ACC_METHOD_IMPLEMENTED;
1221 if (!suck_check_classbuffer_size(cb, 2))
1224 /* attributes count */
1226 attributes_count = suck_u2(cb);
1228 for (i = 0; i < attributes_count; i++) {
1229 if (!suck_check_classbuffer_size(cb, 2))
1232 /* attribute name index */
1234 attribute_name_index = suck_u2(cb);
1236 if (!(attribute_name = class_getconstant(c, attribute_name_index, CONSTANT_Utf8)))
1239 if (attribute_name == utf_Code) {
1241 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1242 exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
1247 exceptions_throw_classformaterror(c, "Multiple Code attributes");
1251 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1255 m->maxstack = suck_u2(cb);
1256 m->maxlocals = suck_u2(cb);
1258 if (m->maxlocals < argcount) {
1259 exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
1263 if (!suck_check_classbuffer_size(cb, 4))
1266 m->jcodelength = suck_u4(cb);
1268 if (m->jcodelength == 0) {
1269 exceptions_throw_classformaterror(c, "Code of a method has length 0");
1273 if (m->jcodelength > 65535) {
1274 exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
1278 if (!suck_check_classbuffer_size(cb, m->jcodelength))
1281 m->jcode = MNEW(u1, m->jcodelength);
1282 suck_nbytes(m->jcode, cb, m->jcodelength);
1284 if (!suck_check_classbuffer_size(cb, 2))
1287 m->rawexceptiontablelength = suck_u2(cb);
1288 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->rawexceptiontablelength))
1291 m->rawexceptiontable = MNEW(raw_exception_entry, m->rawexceptiontablelength);
1293 #if defined(ENABLE_STATISTICS)
1295 count_vmcode_len += m->jcodelength + 18;
1296 count_extable_len +=
1297 m->rawexceptiontablelength * sizeof(raw_exception_entry);
1301 for (j = 0; j < m->rawexceptiontablelength; j++) {
1303 m->rawexceptiontable[j].startpc = suck_u2(cb);
1304 m->rawexceptiontable[j].endpc = suck_u2(cb);
1305 m->rawexceptiontable[j].handlerpc = suck_u2(cb);
1309 m->rawexceptiontable[j].catchtype.any = NULL;
1312 /* the classref is created later */
1313 if (!(m->rawexceptiontable[j].catchtype.any =
1314 (utf*)class_getconstant(c, idx, CONSTANT_Class)))
1319 if (!suck_check_classbuffer_size(cb, 2))
1322 /* code attributes count */
1324 code_attributes_count = suck_u2(cb);
1326 for (k = 0; k < code_attributes_count; k++) {
1327 if (!suck_check_classbuffer_size(cb, 2))
1330 /* code attribute name index */
1332 code_attribute_name_index = suck_u2(cb);
1334 if (!(code_attribute_name = class_getconstant(c, code_attribute_name_index, CONSTANT_Utf8)))
1337 /* check which code attribute */
1339 if (code_attribute_name == utf_LineNumberTable) {
1340 /* LineNumberTable */
1341 if (!suck_check_classbuffer_size(cb, 4 + 2))
1344 /* attribute length */
1348 /* line number table length */
1350 m->linenumbercount = suck_u2(cb);
1352 if (!suck_check_classbuffer_size(cb,
1353 (2 + 2) * m->linenumbercount))
1356 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1358 for (l = 0; l < m->linenumbercount; l++) {
1359 m->linenumbers[l].start_pc = suck_u2(cb);
1360 m->linenumbers[l].line_number = suck_u2(cb);
1363 #if defined(ENABLE_JAVASE)
1364 else if (code_attribute_name == utf_StackMapTable) {
1367 if (!stackmap_load_attribute_stackmaptable(cb, m))
1372 /* unknown code attribute */
1374 if (!loader_skip_attribute_body(cb))
1379 else if (attribute_name == utf_Exceptions) {
1382 if (m->thrownexceptions != NULL) {
1383 exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
1387 if (!suck_check_classbuffer_size(cb, 4 + 2))
1390 /* attribute length */
1394 m->thrownexceptionscount = suck_u2(cb);
1396 if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1399 m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
1401 for (j = 0; j < m->thrownexceptionscount; j++) {
1402 /* the classref is created later */
1403 if (!((m->thrownexceptions)[j].any =
1404 (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1408 #if defined(ENABLE_JAVASE)
1409 else if (attribute_name == utf_Signature) {
1412 if (!loader_load_attribute_signature(cb, &(m->signature)))
1417 /* unknown attribute */
1419 if (!loader_skip_attribute_body(cb))
1424 if ((m->jcode == NULL) && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1425 exceptions_throw_classformaterror(c, "Missing Code attribute");
1429 /* everything was ok */
1435 /* load_class_from_sysloader ***************************************************
1437 Load the class with the given name using the system class loader
1440 name.............the classname
1443 the loaded class, or
1444 NULL if an exception has been thrown
1446 *******************************************************************************/
1448 classinfo *load_class_from_sysloader(utf *name)
1451 java_objectheader *cl;
1454 assert(class_java_lang_Object);
1455 assert(class_java_lang_ClassLoader);
1456 assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
1458 m = class_resolveclassmethod(class_java_lang_ClassLoader,
1459 utf_getSystemClassLoader,
1460 utf_void__java_lang_ClassLoader,
1461 class_java_lang_Object,
1467 cl = vm_call_method(m, NULL);
1472 c = load_class_from_classloader(name, cl);
1478 /* load_class_from_classloader *************************************************
1480 Load the class with the given name using the given user-defined class loader.
1483 name.............the classname
1484 cl...............user-defined class loader
1487 the loaded class, or
1488 NULL if an exception has been thrown
1490 *******************************************************************************/
1492 classinfo *load_class_from_classloader(utf *name, java_objectheader *cl)
1494 java_objectheader *o;
1497 java_lang_String *s;
1498 #if defined(ENABLE_RT_TIMING)
1499 struct timespec time_start, time_lookup, time_prepare, time_java,
1503 RT_TIMING_GET_TIME(time_start);
1507 /* lookup if this class has already been loaded */
1509 c = classcache_lookup(cl, name);
1511 RT_TIMING_GET_TIME(time_lookup);
1512 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1517 /* if other class loader than bootstrap, call it */
1525 namelen = name->blength;
1527 /* handle array classes */
1528 if (text[0] == '[') {
1534 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1535 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1536 *exceptionptr = new_noclassdeffounderror(name);
1540 u = utf_new(text + 2, namelen - 3);
1542 if (!(comp = load_class_from_classloader(u, cl)))
1545 /* create the array class */
1547 c = class_array_of(comp, false);
1549 tmpc = classcache_store(cl, c, true);
1552 /* exception, free the loaded class */
1553 c->state &= ~CLASS_LOADING;
1560 /* load the component class */
1562 u = utf_new(text + 1, namelen - 1);
1564 if (!(comp = load_class_from_classloader(u, cl)))
1567 /* create the array class */
1569 c = class_array_of(comp, false);
1571 tmpc = classcache_store(cl, c, true);
1574 /* exception, free the loaded class */
1575 c->state &= ~CLASS_LOADING;
1582 /* primitive array classes are loaded by the bootstrap loader */
1584 c = load_class_bootstrap(name);
1590 assert(class_java_lang_Object);
1592 lc = class_resolveclassmethod(cl->vftbl->class,
1594 utf_java_lang_String__java_lang_Class,
1595 class_java_lang_Object,
1599 return false; /* exception */
1601 /* move return value into `o' and cast it afterwards to a classinfo* */
1603 s = javastring_new_slash_to_dot(name);
1605 RT_TIMING_GET_TIME(time_prepare);
1607 o = vm_call_method(lc, cl, s);
1609 RT_TIMING_GET_TIME(time_java);
1611 c = (classinfo *) o;
1614 /* Store this class in the loaded class cache. If another
1615 class with the same (initloader,name) pair has been
1616 stored earlier it will be returned by classcache_store
1617 In this case classcache_store may not free the class
1618 because it has already been exposed to Java code which
1619 may have kept references to that class. */
1621 tmpc = classcache_store(cl, c, false);
1624 /* exception, free the loaded class */
1625 c->state &= ~CLASS_LOADING;
1632 /* loadClass has thrown an exception. We must convert
1633 ClassNotFoundException into
1634 NoClassDefFoundException. */
1636 /* XXX Maybe we should have a flag that avoids this
1637 conversion for calling load_class_from_classloader from
1638 Class.forName. Currently we do a double conversion in
1641 classnotfoundexception_to_noclassdeffounderror();
1644 RT_TIMING_GET_TIME(time_cache);
1646 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1647 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1648 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1650 /* SUN compatible -verbose:class output */
1652 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1654 utf_display_printable_ascii_classname(name);
1658 #if defined(ENABLE_JVMTI)
1659 /* fire Class Load JVMTI event */
1660 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1667 c = load_class_bootstrap(name);
1673 /* load_class_bootstrap ********************************************************
1675 Load the class with the given name using the bootstrap class loader.
1678 name.............the classname
1681 loaded classinfo, or
1682 NULL if an exception has been thrown
1685 load_class_bootstrap is synchronized. It can be treated as an
1688 *******************************************************************************/
1690 classinfo *load_class_bootstrap(utf *name)
1695 #if defined(ENABLE_RT_TIMING)
1696 struct timespec time_start, time_lookup, time_array, time_suck,
1697 time_load, time_cache;
1700 RT_TIMING_GET_TIME(time_start);
1706 /* lookup if this class has already been loaded */
1708 if ((r = classcache_lookup(NULL, name))) {
1710 RT_TIMING_GET_TIME(time_lookup);
1711 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1716 RT_TIMING_GET_TIME(time_lookup);
1717 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1719 /* create the classinfo */
1721 c = class_create_classinfo(name);
1723 /* handle array classes */
1725 if (name->text[0] == '[') {
1726 c = load_newly_created_array(c, NULL);
1729 assert(c->state & CLASS_LOADED);
1731 RT_TIMING_GET_TIME(time_array);
1732 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1737 #if defined(ENABLE_STATISTICS)
1740 if (opt_getcompilingtime)
1741 compilingtime_stop();
1743 if (opt_getloadingtime)
1744 loadingtime_start();
1747 /* load classdata, throw exception on error */
1749 if ((cb = suck_start(c)) == NULL) {
1750 /* this normally means, the classpath was not set properly */
1752 if (name == utf_java_lang_Object)
1753 vm_abort("%s: java/lang/Object", string_java_lang_NoClassDefFoundError);
1755 *exceptionptr = new_noclassdeffounderror(name);
1760 RT_TIMING_GET_TIME(time_suck);
1762 /* load the class from the buffer */
1764 r = load_class_from_classbuffer(cb);
1766 RT_TIMING_GET_TIME(time_load);
1769 /* the class could not be loaded, free the classinfo struct */
1774 /* Store this class in the loaded class cache this step also
1775 checks the loading constraints. If the class has been loaded
1776 before, the earlier loaded class is returned. */
1778 classinfo *res = classcache_store(NULL, c, true);
1788 RT_TIMING_GET_TIME(time_cache);
1790 /* SUN compatible -verbose:class output */
1792 if (opt_verboseclass && r) {
1794 utf_display_printable_ascii_classname(name);
1795 printf(" from %s]\n", cb->path);
1802 #if defined(ENABLE_STATISTICS)
1805 if (opt_getloadingtime)
1808 if (opt_getcompilingtime)
1809 compilingtime_start();
1812 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1813 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1814 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1815 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1821 /* load_class_from_classbuffer *************************************************
1823 Loads everything interesting about a class from the class file. The
1824 'classinfo' structure must have been allocated previously.
1826 The super class and the interfaces implemented by this class need
1827 not be loaded. The link is set later by the function 'class_link'.
1829 The loaded class is removed from the list 'unloadedclasses' and
1830 added to the list 'unlinkedclasses'.
1833 This function is NOT synchronized!
1835 *******************************************************************************/
1837 classinfo *load_class_from_classbuffer(classbuffer *cb)
1845 descriptor_pool *descpool;
1846 #if defined(ENABLE_STATISTICS)
1850 #if defined(ENABLE_RT_TIMING)
1851 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1852 time_setup, time_fields, time_methods, time_classrefs,
1853 time_descs, time_setrefs, time_parsefds, time_parsemds,
1854 time_parsecpool, time_verify, time_attrs;
1857 RT_TIMING_GET_TIME(time_start);
1859 /* get the classbuffer's class */
1863 /* the class is already loaded */
1865 if (c->state & CLASS_LOADED)
1868 #if defined(ENABLE_STATISTICS)
1870 count_class_loads++;
1873 #if !defined(NDEBUG)
1874 /* output for debugging purposes */
1877 log_message_class("Loading class: ", c);
1880 /* mark start of dump memory area */
1882 dumpsize = dump_size();
1884 /* class is currently loading */
1886 c->state |= CLASS_LOADING;
1888 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1889 goto return_exception;
1891 /* check signature */
1893 if (suck_u4(cb) != MAGIC) {
1894 exceptions_throw_classformaterror(c, "Bad magic number");
1896 goto return_exception;
1904 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1906 new_unsupportedclassversionerror(c,
1907 "Unsupported major.minor version %d.%d",
1910 goto return_exception;
1912 RT_TIMING_GET_TIME(time_checks);
1914 /* create a new descriptor pool */
1916 descpool = descriptor_pool_new(c);
1918 RT_TIMING_GET_TIME(time_ndpool);
1920 /* load the constant pool */
1922 if (!load_constantpool(cb, descpool))
1923 goto return_exception;
1925 RT_TIMING_GET_TIME(time_cpool);
1929 if (!suck_check_classbuffer_size(cb, 2))
1930 goto return_exception;
1932 c->flags = suck_u2(cb);
1934 /* check ACC flags consistency */
1936 if (c->flags & ACC_INTERFACE) {
1937 if (!(c->flags & ACC_ABSTRACT)) {
1938 /* We work around this because interfaces in JDK 1.1 are
1939 * not declared abstract. */
1941 c->flags |= ACC_ABSTRACT;
1944 if (c->flags & ACC_FINAL) {
1945 exceptions_throw_classformaterror(c,
1946 "Illegal class modifiers: 0x%X",
1948 goto return_exception;
1951 if (c->flags & ACC_SUPER) {
1952 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1956 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1957 exceptions_throw_classformaterror(c,
1958 "Illegal class modifiers: 0x%X",
1960 goto return_exception;
1963 if (!suck_check_classbuffer_size(cb, 2 + 2))
1964 goto return_exception;
1969 if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1970 goto return_exception;
1972 if (c->name == utf_not_named_yet) {
1973 /* we finally have a name for this class */
1975 class_set_packagename(c);
1977 } else if (name != c->name) {
1981 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
1982 utf_bytes(name) + strlen(")") + strlen("0");
1984 msg = MNEW(char, msglen);
1986 utf_copy_classname(msg, c->name);
1987 strcat(msg, " (wrong name: ");
1988 utf_cat_classname(msg, name);
1992 new_exception_message(string_java_lang_NoClassDefFoundError, msg);
1994 MFREE(msg, char, msglen);
1996 goto return_exception;
1999 /* retrieve superclass */
2001 c->super.any = NULL;
2002 if ((i = suck_u2(cb))) {
2003 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
2004 goto return_exception;
2006 /* java.lang.Object may not have a super class. */
2008 if (c->name == utf_java_lang_Object) {
2010 new_exception_message(string_java_lang_ClassFormatError,
2011 "java.lang.Object with superclass");
2013 goto return_exception;
2016 /* Interfaces must have java.lang.Object as super class. */
2018 if ((c->flags & ACC_INTERFACE) &&
2019 supername != utf_java_lang_Object) {
2021 new_exception_message(string_java_lang_ClassFormatError,
2022 "Interfaces must have java.lang.Object as superclass");
2024 goto return_exception;
2030 /* This is only allowed for java.lang.Object. */
2032 if (c->name != utf_java_lang_Object) {
2033 exceptions_throw_classformaterror(c, "Bad superclass index");
2034 goto return_exception;
2038 /* retrieve interfaces */
2040 if (!suck_check_classbuffer_size(cb, 2))
2041 goto return_exception;
2043 c->interfacescount = suck_u2(cb);
2045 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
2046 goto return_exception;
2048 c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
2049 for (i = 0; i < c->interfacescount; i++) {
2050 /* the classrefs are created later */
2051 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2052 goto return_exception;
2055 RT_TIMING_GET_TIME(time_setup);
2058 if (!suck_check_classbuffer_size(cb, 2))
2059 goto return_exception;
2061 c->fieldscount = suck_u2(cb);
2062 #if defined(ENABLE_GC_CACAO)
2063 c->fields = MNEW(fieldinfo, c->fieldscount);
2064 MZERO(c->fields, fieldinfo, c->fieldscount);
2066 c->fields = GCNEW_UNCOLLECTABLE(fieldinfo, c->fieldscount);
2069 for (i = 0; i < c->fieldscount; i++) {
2070 if (!load_field(cb, &(c->fields[i]),descpool))
2071 goto return_exception;
2074 RT_TIMING_GET_TIME(time_fields);
2077 if (!suck_check_classbuffer_size(cb, 2))
2078 goto return_exception;
2080 c->methodscount = suck_u2(cb);
2081 c->methods = MNEW(methodinfo, c->methodscount);
2083 MZERO(c->methods, methodinfo, c->methodscount);
2085 for (i = 0; i < c->methodscount; i++) {
2086 if (!loader_load_method(cb, &(c->methods[i]), descpool))
2087 goto return_exception;
2090 RT_TIMING_GET_TIME(time_methods);
2092 /* create the class reference table */
2095 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
2097 RT_TIMING_GET_TIME(time_classrefs);
2099 /* allocate space for the parsed descriptors */
2101 descriptor_pool_alloc_parsed_descriptors(descpool);
2103 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
2105 #if defined(ENABLE_STATISTICS)
2107 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
2108 count_classref_len += classrefsize;
2109 count_parsed_desc_len += descsize;
2113 RT_TIMING_GET_TIME(time_descs);
2115 /* put the classrefs in the constant pool */
2116 for (i = 0; i < c->cpcount; i++) {
2117 if (c->cptags[i] == CONSTANT_Class) {
2118 utf *name = (utf *) c->cpinfos[i];
2119 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
2123 /* set the super class reference */
2126 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
2128 goto return_exception;
2131 /* set the super interfaces references */
2133 for (i = 0; i < c->interfacescount; i++) {
2134 c->interfaces[i].ref =
2135 descriptor_pool_lookup_classref(descpool,
2136 (utf *) c->interfaces[i].any);
2137 if (!c->interfaces[i].ref)
2138 goto return_exception;
2141 RT_TIMING_GET_TIME(time_setrefs);
2143 /* parse field descriptors */
2145 for (i = 0; i < c->fieldscount; i++) {
2146 c->fields[i].parseddesc =
2147 descriptor_pool_parse_field_descriptor(descpool,
2148 c->fields[i].descriptor);
2149 if (!c->fields[i].parseddesc)
2150 goto return_exception;
2153 RT_TIMING_GET_TIME(time_parsefds);
2155 /* parse method descriptors */
2157 for (i = 0; i < c->methodscount; i++) {
2158 methodinfo *m = &c->methods[i];
2160 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
2161 m->flags, class_get_self_classref(m->class));
2163 goto return_exception;
2165 for (j = 0; j < m->rawexceptiontablelength; j++) {
2166 if (!m->rawexceptiontable[j].catchtype.any)
2168 if ((m->rawexceptiontable[j].catchtype.ref =
2169 descriptor_pool_lookup_classref(descpool,
2170 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
2171 goto return_exception;
2174 for (j = 0; j < m->thrownexceptionscount; j++) {
2175 if (!m->thrownexceptions[j].any)
2177 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
2178 (utf *) m->thrownexceptions[j].any)) == NULL)
2179 goto return_exception;
2183 RT_TIMING_GET_TIME(time_parsemds);
2185 /* parse the loaded descriptors */
2187 for (i = 0; i < c->cpcount; i++) {
2188 constant_FMIref *fmi;
2191 switch (c->cptags[i]) {
2192 case CONSTANT_Fieldref:
2193 fmi = (constant_FMIref *) c->cpinfos[i];
2194 fmi->parseddesc.fd =
2195 descriptor_pool_parse_field_descriptor(descpool,
2197 if (!fmi->parseddesc.fd)
2198 goto return_exception;
2199 index = fmi->p.index;
2201 (constant_classref *) class_getconstant(c, index,
2203 if (!fmi->p.classref)
2204 goto return_exception;
2206 case CONSTANT_Methodref:
2207 case CONSTANT_InterfaceMethodref:
2208 fmi = (constant_FMIref *) c->cpinfos[i];
2209 index = fmi->p.index;
2211 (constant_classref *) class_getconstant(c, index,
2213 if (!fmi->p.classref)
2214 goto return_exception;
2215 fmi->parseddesc.md =
2216 descriptor_pool_parse_method_descriptor(descpool,
2220 if (!fmi->parseddesc.md)
2221 goto return_exception;
2226 RT_TIMING_GET_TIME(time_parsecpool);
2228 #ifdef ENABLE_VERIFIER
2229 /* Check if all fields and methods can be uniquely
2230 * identified by (name,descriptor). */
2233 /* We use a hash table here to avoid making the
2234 * average case quadratic in # of methods, fields.
2236 static int shift = 0;
2238 u2 *next; /* for chaining colliding hash entries */
2244 /* Allocate hashtable */
2245 len = c->methodscount;
2246 if (len < c->fieldscount) len = c->fieldscount;
2248 hashtab = MNEW(u2,(hashlen + len));
2249 next = hashtab + hashlen;
2251 /* Determine bitshift (to get good hash values) */
2261 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2263 for (i = 0; i < c->fieldscount; ++i) {
2264 fieldinfo *fi = c->fields + i;
2266 /* It's ok if we lose bits here */
2267 index = ((((size_t) fi->name) +
2268 ((size_t) fi->descriptor)) >> shift) % hashlen;
2270 if ((old = hashtab[index])) {
2274 if (c->fields[old].name == fi->name &&
2275 c->fields[old].descriptor == fi->descriptor) {
2276 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
2277 goto return_exception;
2279 } while ((old = next[old]));
2281 hashtab[index] = i + 1;
2285 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2287 for (i = 0; i < c->methodscount; ++i) {
2288 methodinfo *mi = c->methods + i;
2290 /* It's ok if we lose bits here */
2291 index = ((((size_t) mi->name) +
2292 ((size_t) mi->descriptor)) >> shift) % hashlen;
2296 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2297 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2301 if ((old = hashtab[index])) {
2305 if (c->methods[old].name == mi->name &&
2306 c->methods[old].descriptor == mi->descriptor) {
2307 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
2308 goto return_exception;
2310 } while ((old = next[old]));
2312 hashtab[index] = i + 1;
2315 MFREE(hashtab, u2, (hashlen + len));
2317 #endif /* ENABLE_VERIFIER */
2319 RT_TIMING_GET_TIME(time_verify);
2321 #if defined(ENABLE_STATISTICS)
2323 size_classinfo += sizeof(classinfo*) * c->interfacescount;
2324 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
2325 size_methodinfo += sizeof(methodinfo) * c->methodscount;
2329 /* load attribute structures */
2331 if (!class_load_attributes(cb))
2332 goto return_exception;
2334 /* Pre Java 1.5 version don't check this. This implementation is like
2335 Java 1.5 do it: for class file version 45.3 we don't check it, older
2336 versions are checked.
2339 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
2340 /* check if all data has been read */
2341 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
2343 if (classdata_left > 0) {
2344 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
2345 goto return_exception;
2349 RT_TIMING_GET_TIME(time_attrs);
2351 /* release dump area */
2353 dump_release(dumpsize);
2355 /* revert loading state and class is loaded */
2357 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2359 #if defined(ENABLE_JVMTI)
2360 /* fire Class Prepare JVMTI event */
2363 jvmti_ClassLoadPrepare(true, c);
2366 #if !defined(NDEBUG)
2368 log_message_class("Loading done class: ", c);
2371 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
2372 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
2373 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
2374 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
2375 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
2376 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
2377 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
2378 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
2379 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
2380 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
2381 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
2382 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
2383 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
2384 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
2385 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
2390 /* release dump area */
2392 dump_release(dumpsize);
2394 /* an exception has been thrown */
2400 /* load_newly_created_array ****************************************************
2402 Load a newly created array class.
2405 c....................the array class C has been loaded
2406 other classinfo......the array class was found in the class cache,
2408 NULL.................an exception has been thrown
2411 This is an internal function. Do not use it unless you know exactly
2414 Use one of the load_class_... functions for general array class loading.
2416 *******************************************************************************/
2418 classinfo *load_newly_created_array(classinfo *c, java_objectheader *loader)
2420 classinfo *comp = NULL;
2422 methoddesc *clonedesc;
2423 constant_classref *classrefs;
2428 text = c->name->text;
2429 namelen = c->name->blength;
2431 /* Check array class name */
2433 if (namelen < 2 || text[0] != '[') {
2434 *exceptionptr = new_noclassdeffounderror(c->name);
2438 /* Check the element type */
2442 /* c is an array of arrays. We have to create the component class. */
2444 u = utf_new(text + 1, namelen - 1);
2445 if (!(comp = load_class_from_classloader(u, loader)))
2448 assert(comp->state & CLASS_LOADED);
2454 /* the array's flags are that of the component class */
2455 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2456 c->classloader = comp->classloader;
2460 /* c is an array of objects. */
2462 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2463 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
2464 *exceptionptr = new_noclassdeffounderror(c->name);
2468 u = utf_new(text + 2, namelen - 3);
2470 if (!(comp = load_class_from_classloader(u, loader)))
2473 assert(comp->state & CLASS_LOADED);
2479 /* the array's flags are that of the component class */
2480 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2481 c->classloader = comp->classloader;
2485 /* c is an array of a primitive type */
2487 /* check for cases like `[II' */
2489 *exceptionptr = new_noclassdeffounderror(c->name);
2493 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2494 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2495 c->classloader = NULL;
2498 assert(class_java_lang_Object);
2499 #if defined(ENABLE_JAVASE)
2500 assert(class_java_lang_Cloneable);
2501 assert(class_java_io_Serializable);
2504 /* setup the array class */
2506 c->super.cls = class_java_lang_Object;
2508 #if defined(ENABLE_JAVASE)
2509 c->interfacescount = 2;
2510 c->interfaces = MNEW(classref_or_classinfo, 2);
2515 tc = class_java_lang_Cloneable;
2516 assert(tc->state & CLASS_LOADED);
2517 list_add_first(&unlinkedclasses, tc);
2518 c->interfaces[0].cls = tc;
2520 tc = class_java_io_Serializable;
2521 assert(tc->state & CLASS_LOADED);
2522 list_add_first(&unlinkedclasses, tc);
2523 c->interfaces[1].cls = tc;
2526 c->interfaces[0].cls = class_java_lang_Cloneable;
2527 c->interfaces[1].cls = class_java_io_Serializable;
2529 #elif defined(ENABLE_JAVAME_CLDC1_1)
2530 c->interfacescount = 0;
2531 c->interfaces = NULL;
2533 #error unknow java configuration
2536 c->methodscount = 1;
2537 c->methods = MNEW(methodinfo, c->methodscount);
2538 MZERO(c->methods, methodinfo, c->methodscount);
2540 classrefs = MNEW(constant_classref, 2);
2541 CLASSREF_INIT(classrefs[0], c, c->name);
2542 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2544 /* create descriptor for clone method */
2545 /* we need one paramslot which is reserved for the 'this' parameter */
2546 clonedesc = NEW(methoddesc);
2547 clonedesc->returntype.type = TYPE_ADR;
2548 clonedesc->returntype.classref = classrefs + 1;
2549 clonedesc->returntype.arraydim = 0;
2550 /* initialize params to "empty", add real params below in
2551 descriptor_params_from_paramtypes */
2552 clonedesc->paramcount = 0;
2553 clonedesc->paramslots = 0;
2554 clonedesc->paramtypes[0].classref = classrefs + 0;
2555 clonedesc->params = NULL;
2557 /* create methodinfo */
2560 MSET(clone, 0, methodinfo, 1);
2562 #if defined(ENABLE_THREADS)
2563 lock_init_object_lock(&clone->header);
2566 /* ATTENTION: if you delete the ACC_NATIVE below, set
2567 clone->maxlocals=1 (interpreter related) */
2569 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2570 clone->name = utf_clone;
2571 clone->descriptor = utf_void__java_lang_Object;
2572 clone->parseddesc = clonedesc;
2575 /* parse the descriptor to get the register allocation */
2577 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2580 clone->code = codegen_createnativestub(BUILTIN_clone, clone);
2582 /* XXX: field: length? */
2584 /* array classes are not loaded from class files */
2586 c->state |= CLASS_LOADED;
2587 c->parseddescs = (u1 *) clonedesc;
2588 c->parseddescsize = sizeof(methodinfo);
2589 c->classrefs = classrefs;
2590 c->classrefcount = 1;
2592 /* insert class into the loaded class cache */
2593 /* XXX free classinfo if NULL returned? */
2595 return classcache_store(loader, c, true);
2599 /* loader_close ****************************************************************
2601 Frees all resources.
2603 *******************************************************************************/
2605 void loader_close(void)
2612 * These are local overrides for various environment variables in Emacs.
2613 * Please do not remove this and leave it at the end of the file, where
2614 * Emacs will automagically detect them.
2615 * ---------------------------------------------------------------------
2618 * indent-tabs-mode: t
2622 * vim:noexpandtab:sw=4:ts=4: