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 5972 2006-11-12 15:00:41Z edwin $
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"
56 #include "vm/builtin.h"
57 #include "vm/classcache.h"
58 #include "vm/exceptions.h"
59 #include "vm/global.h"
60 #include "vm/linker.h"
61 #include "vm/loader.h"
62 #include "vm/options.h"
63 #include "vm/statistics.h"
64 #include "vm/stringlocal.h"
68 #if defined(ENABLE_ZLIB)
72 #include "vm/jit/asmpart.h"
73 #include "vm/jit/codegen-common.h"
74 #include "vm/rt-timing.h"
76 #if defined(ENABLE_JVMTI)
77 #include "native/jvmti/cacaodbg.h"
81 /* loader_init *****************************************************************
83 Initializes all lists and loads all classes required for the system
86 *******************************************************************************/
88 bool loader_init(void)
90 #if defined(ENABLE_THREADS)
91 list_classpath_entry *lce;
93 /* Initialize the monitor pointer for zip/jar file locking. */
95 for (lce = list_first(list_classpath_entries); lce != NULL;
96 lce = list_next(list_classpath_entries, lce))
97 if (lce->type == CLASSPATH_ARCHIVE)
98 lock_init_object_lock((java_objectheader *) lce);
101 /* load some important classes */
103 if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
106 if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
109 if (!(class_java_lang_Cloneable =
110 load_class_bootstrap(utf_java_lang_Cloneable)))
113 if (!(class_java_io_Serializable =
114 load_class_bootstrap(utf_java_io_Serializable)))
118 /* load classes for wrapping primitive types */
120 if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
123 if (!(class_java_lang_Boolean =
124 load_class_bootstrap(utf_java_lang_Boolean)))
127 if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
130 if (!(class_java_lang_Character =
131 load_class_bootstrap(utf_java_lang_Character)))
134 if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
137 if (!(class_java_lang_Integer =
138 load_class_bootstrap(utf_java_lang_Integer)))
141 if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
144 if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
147 if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
151 /* load some other important classes */
153 if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
156 if (!(class_java_lang_ClassLoader =
157 load_class_bootstrap(utf_java_lang_ClassLoader)))
160 if (!(class_java_lang_SecurityManager =
161 load_class_bootstrap(utf_java_lang_SecurityManager)))
164 if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
167 if (!(class_java_lang_Thread =
168 load_class_bootstrap(utf_new_char("java/lang/Thread"))))
171 if (!(class_java_lang_ThreadGroup =
172 load_class_bootstrap(utf_java_lang_ThreadGroup)))
175 if (!(class_java_lang_VMSystem =
176 load_class_bootstrap(utf_new_char("java/lang/VMSystem"))))
179 if (!(class_java_lang_VMThread =
180 load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
184 /* some classes which may be used more often */
186 if (!(class_java_lang_StackTraceElement =
187 load_class_bootstrap(utf_java_lang_StackTraceElement)))
190 if (!(class_java_lang_reflect_Constructor =
191 load_class_bootstrap(utf_java_lang_reflect_Constructor)))
194 if (!(class_java_lang_reflect_Field =
195 load_class_bootstrap(utf_java_lang_reflect_Field)))
198 if (!(class_java_lang_reflect_Method =
199 load_class_bootstrap(utf_java_lang_reflect_Method)))
202 if (!(class_java_security_PrivilegedAction =
203 load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
206 if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
209 if (!(arrayclass_java_lang_Object =
210 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
217 /* loader_load_all_classes *****************************************************
219 Loads all classes specified in the BOOTCLASSPATH.
221 *******************************************************************************/
223 void loader_load_all_classes(void)
225 list_classpath_entry *lce;
226 #if defined(ENABLE_ZLIB)
229 hashtable_zipfile_entry *htzfe;
233 for (lce = list_first(list_classpath_entries); lce != NULL;
234 lce = list_next(list_classpath_entries, lce)) {
235 #if defined(ENABLE_ZLIB)
236 if (lce->type == CLASSPATH_ARCHIVE) {
237 /* get the classes hashtable */
241 for (slot = 0; slot < ht->size; slot++) {
242 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
244 for (; htzfe; htzfe = htzfe->hashlink) {
247 /* skip all entries in META-INF and .properties,
250 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
251 strstr(u->text, ".properties") ||
252 strstr(u->text, ".png"))
255 /* load class from bootstrap classloader */
257 if (!load_class_bootstrap(u)) {
258 fprintf(stderr, "Error loading: ");
259 utf_fprint_printable_ascii_classname(stderr, u);
260 fprintf(stderr, "\n");
263 /* print out exception and cause */
265 exceptions_print_exception(*exceptionptr);
273 #if defined(ENABLE_ZLIB)
280 /* skipattributebody ***********************************************************
282 Skips an attribute after the 16 bit reference to attribute_name has
285 *******************************************************************************/
287 static bool skipattributebody(classbuffer *cb)
291 if (!suck_check_classbuffer_size(cb, 4))
296 if (!suck_check_classbuffer_size(cb, len))
299 suck_skip_nbytes(cb, len);
305 /************************* Function: skipattributes ****************************
307 skips num attribute structures
309 *******************************************************************************/
311 static bool skipattributes(classbuffer *cb, u4 num)
316 for (i = 0; i < num; i++) {
317 if (!suck_check_classbuffer_size(cb, 2 + 4))
323 if (!suck_check_classbuffer_size(cb, len))
326 suck_skip_nbytes(cb, len);
333 /* load_constantpool ***********************************************************
335 Loads the constantpool of a class, the entries are transformed into
336 a simpler format by resolving references (a detailed overview of
337 the compact structures can be found in global.h).
339 *******************************************************************************/
341 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
344 /* The following structures are used to save information which cannot be
345 processed during the first pass. After the complete constantpool has
346 been traversed the references can be resolved.
347 (only in specific order) */
349 /* CONSTANT_Class entries */
350 typedef struct forward_class {
351 struct forward_class *next;
356 /* CONSTANT_String */
357 typedef struct forward_string {
358 struct forward_string *next;
363 /* CONSTANT_NameAndType */
364 typedef struct forward_nameandtype {
365 struct forward_nameandtype *next;
369 } forward_nameandtype;
371 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
372 typedef struct forward_fieldmethint {
373 struct forward_fieldmethint *next;
377 u2 nameandtype_index;
378 } forward_fieldmethint;
384 forward_class *forward_classes = NULL;
385 forward_string *forward_strings = NULL;
386 forward_nameandtype *forward_nameandtypes = NULL;
387 forward_fieldmethint *forward_fieldmethints = NULL;
391 forward_nameandtype *nfn;
392 forward_fieldmethint *nff;
400 /* number of entries in the constant_pool table plus one */
401 if (!suck_check_classbuffer_size(cb, 2))
404 cpcount = c->cpcount = suck_u2(cb);
406 /* allocate memory */
407 cptags = c->cptags = MNEW(u1, cpcount);
408 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
411 exceptions_throw_classformaterror(c, "Illegal constant pool size");
415 #if defined(ENABLE_STATISTICS)
417 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
420 /* initialize constantpool */
421 for (idx = 0; idx < cpcount; idx++) {
422 cptags[idx] = CONSTANT_UNUSED;
427 /******* first pass *******/
428 /* entries which cannot be resolved now are written into
429 temporary structures and traversed again later */
432 while (idx < cpcount) {
435 /* get constant type */
436 if (!suck_check_classbuffer_size(cb, 1))
443 nfc = DNEW(forward_class);
445 nfc->next = forward_classes;
446 forward_classes = nfc;
448 nfc->thisindex = idx;
449 /* reference to CONSTANT_NameAndType */
450 if (!suck_check_classbuffer_size(cb, 2))
453 nfc->name_index = suck_u2(cb);
458 case CONSTANT_String:
459 nfs = DNEW(forward_string);
461 nfs->next = forward_strings;
462 forward_strings = nfs;
464 nfs->thisindex = idx;
466 /* reference to CONSTANT_Utf8_info with string characters */
467 if (!suck_check_classbuffer_size(cb, 2))
470 nfs->string_index = suck_u2(cb);
475 case CONSTANT_NameAndType:
476 nfn = DNEW(forward_nameandtype);
478 nfn->next = forward_nameandtypes;
479 forward_nameandtypes = nfn;
481 nfn->thisindex = idx;
483 if (!suck_check_classbuffer_size(cb, 2 + 2))
486 /* reference to CONSTANT_Utf8_info containing simple name */
487 nfn->name_index = suck_u2(cb);
489 /* reference to CONSTANT_Utf8_info containing field or method
491 nfn->sig_index = suck_u2(cb);
496 case CONSTANT_Fieldref:
497 case CONSTANT_Methodref:
498 case CONSTANT_InterfaceMethodref:
499 nff = DNEW(forward_fieldmethint);
501 nff->next = forward_fieldmethints;
502 forward_fieldmethints = nff;
504 nff->thisindex = idx;
508 if (!suck_check_classbuffer_size(cb, 2 + 2))
511 /* class or interface type that contains the declaration of the
513 nff->class_index = suck_u2(cb);
515 /* name and descriptor of the field or method */
516 nff->nameandtype_index = suck_u2(cb);
521 case CONSTANT_Integer: {
522 constant_integer *ci = NEW(constant_integer);
524 #if defined(ENABLE_STATISTICS)
526 count_const_pool_len += sizeof(constant_integer);
529 if (!suck_check_classbuffer_size(cb, 4))
532 ci->value = suck_s4(cb);
533 cptags[idx] = CONSTANT_Integer;
540 case CONSTANT_Float: {
541 constant_float *cf = NEW(constant_float);
543 #if defined(ENABLE_STATISTICS)
545 count_const_pool_len += sizeof(constant_float);
548 if (!suck_check_classbuffer_size(cb, 4))
551 cf->value = suck_float(cb);
552 cptags[idx] = CONSTANT_Float;
559 case CONSTANT_Long: {
560 constant_long *cl = NEW(constant_long);
562 #if defined(ENABLE_STATISTICS)
564 count_const_pool_len += sizeof(constant_long);
567 if (!suck_check_classbuffer_size(cb, 8))
570 cl->value = suck_s8(cb);
571 cptags[idx] = CONSTANT_Long;
575 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
581 case CONSTANT_Double: {
582 constant_double *cd = NEW(constant_double);
584 #if defined(ENABLE_STATISTICS)
586 count_const_pool_len += sizeof(constant_double);
589 if (!suck_check_classbuffer_size(cb, 8))
592 cd->value = suck_double(cb);
593 cptags[idx] = CONSTANT_Double;
597 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
603 case CONSTANT_Utf8: {
606 /* number of bytes in the bytes array (not string-length) */
607 if (!suck_check_classbuffer_size(cb, 2))
610 length = suck_u2(cb);
611 cptags[idx] = CONSTANT_Utf8;
613 /* validate the string */
614 if (!suck_check_classbuffer_size(cb, length))
617 #ifdef ENABLE_VERIFIER
619 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
621 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
624 #endif /* ENABLE_VERIFIER */
625 /* insert utf-string into the utf-symboltable */
626 cpinfos[idx] = utf_new((char *) cb->pos, length);
628 /* skip bytes of the string (buffer size check above) */
629 suck_skip_nbytes(cb, length);
635 exceptions_throw_classformaterror(c, "Illegal constant pool type");
641 /* resolve entries in temporary structures */
643 while (forward_classes) {
645 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
649 #ifdef ENABLE_VERIFIER
650 if (opt_verify && !is_valid_name_utf(name)) {
651 exceptions_throw_classformaterror(c, "Class reference with invalid name");
654 #endif /* ENABLE_VERIFIER */
656 /* add all class references to the descriptor_pool */
658 if (!descriptor_pool_add_class(descpool, name))
661 cptags[forward_classes->thisindex] = CONSTANT_Class;
666 if (!(tc = load_class_bootstrap(name)))
669 /* link the class later, because we cannot link the class currently
671 list_add_first(&unlinkedclasses, tc);
674 /* the classref is created later */
675 cpinfos[forward_classes->thisindex] = name;
677 nfc = forward_classes;
678 forward_classes = forward_classes->next;
681 while (forward_strings) {
683 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
687 /* resolve utf-string */
688 cptags[forward_strings->thisindex] = CONSTANT_String;
689 cpinfos[forward_strings->thisindex] = text;
691 nfs = forward_strings;
692 forward_strings = forward_strings->next;
695 while (forward_nameandtypes) {
696 constant_nameandtype *cn = NEW(constant_nameandtype);
698 #if defined(ENABLE_STATISTICS)
700 count_const_pool_len += sizeof(constant_nameandtype);
703 /* resolve simple name and descriptor */
704 cn->name = class_getconstant(c,
705 forward_nameandtypes->name_index,
710 cn->descriptor = class_getconstant(c,
711 forward_nameandtypes->sig_index,
716 #ifdef ENABLE_VERIFIER
719 if (!is_valid_name_utf(cn->name)) {
720 exceptions_throw_classformaterror(c,
721 "Illegal Field name \"%s\"",
727 /* disallow referencing <clinit> among others */
728 if (cn->name->text[0] == '<' && cn->name != utf_init) {
729 exceptions_throw_classformaterror(c, "Illegal reference to special method");
733 #endif /* ENABLE_VERIFIER */
735 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
736 cpinfos[forward_nameandtypes->thisindex] = cn;
738 nfn = forward_nameandtypes;
739 forward_nameandtypes = forward_nameandtypes->next;
742 while (forward_fieldmethints) {
743 constant_nameandtype *nat;
744 constant_FMIref *fmi = NEW(constant_FMIref);
746 #if defined(ENABLE_STATISTICS)
748 count_const_pool_len += sizeof(constant_FMIref);
750 /* resolve simple name and descriptor */
752 nat = class_getconstant(c,
753 forward_fieldmethints->nameandtype_index,
754 CONSTANT_NameAndType);
758 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
760 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
763 /* the classref is created later */
765 fmi->p.index = forward_fieldmethints->class_index;
766 fmi->name = nat->name;
767 fmi->descriptor = nat->descriptor;
769 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
770 cpinfos[forward_fieldmethints->thisindex] = fmi;
772 nff = forward_fieldmethints;
773 forward_fieldmethints = forward_fieldmethints->next;
776 /* everything was ok */
782 /* load_field ******************************************************************
784 Load everything about a class field from the class file and fill a
785 'fieldinfo' structure. For static fields, space in the data segment
788 *******************************************************************************/
790 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
792 static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
797 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
802 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
805 f->flags = suck_u2(cb);
807 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
812 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
816 f->parseddesc = NULL;
818 if (!descriptor_pool_add(descpool, u, NULL))
821 /* descriptor_pool_add accepts method descriptors, so we have to check */
822 /* against them here before the call of descriptor_to_basic_type below. */
823 if (u->text[0] == '(') {
824 exceptions_throw_classformaterror(c, "Method descriptor used for field");
828 #ifdef ENABLE_VERIFIER
831 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<') {
832 exceptions_throw_classformaterror(c,
833 "Illegal Field name \"%s\"",
838 /* check flag consistency */
839 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
841 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
842 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
843 exceptions_throw_classformaterror(c,
844 "Illegal field modifiers: 0x%X",
849 if (c->flags & ACC_INTERFACE) {
850 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
851 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
852 f->flags & ACC_TRANSIENT) {
853 exceptions_throw_classformaterror(c,
854 "Illegal field modifiers: 0x%X",
860 #endif /* ENABLE_VERIFIER */
862 f->type = jtype = descriptor_to_basic_type(f->descriptor); /* data type */
863 f->offset = 0; /* offset from start of object */
881 if (!(f->flags & ACC_STATIC))
882 c->flags |= ACC_CLASS_HAS_POINTERS;
895 /* read attributes */
896 if (!suck_check_classbuffer_size(cb, 2))
899 attrnum = suck_u2(cb);
900 for (i = 0; i < attrnum; i++) {
901 if (!suck_check_classbuffer_size(cb, 2))
904 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
907 if (u == utf_ConstantValue) {
908 if (!suck_check_classbuffer_size(cb, 4 + 2))
911 /* check attribute length */
913 if (suck_u4(cb) != 2) {
914 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
918 /* constant value attribute */
920 if (pindex != field_load_NOVALUE) {
921 exceptions_throw_classformaterror(c, "Multiple ConstantValue attributes");
925 /* index of value in constantpool */
927 pindex = suck_u2(cb);
929 /* initialize field with value from constantpool */
932 constant_integer *ci;
934 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
937 f->value.i = ci->value;
944 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
947 f->value.l = cl->value;
954 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
957 f->value.f = cf->value;
964 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
967 f->value.d = cd->value;
972 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
975 /* create javastring from compressed utf8-string */
976 f->value.a = literalstring_new(u);
980 log_text("Invalid Constant - Type");
983 else if (u == utf_Signature) {
984 if (!suck_check_classbuffer_size(cb, 4 + 2))
987 /* check attribute length */
989 if (suck_u4(cb) != 2) {
990 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
994 if (f->signature != NULL) {
995 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
999 if (!(f->signature = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1003 /* unknown attribute */
1004 if (!skipattributebody(cb))
1009 /* everything was ok */
1015 /* load_method *****************************************************************
1017 Loads a method from the class file and fills an existing
1018 'methodinfo' structure. For native methods, the function pointer
1019 field is set to the real function pointer, for JavaVM methods a
1020 pointer to the compiler is used preliminarily.
1022 *******************************************************************************/
1024 static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpool)
1035 #if defined(ENABLE_THREADS)
1036 lock_init_object_lock(&m->header);
1039 #if defined(ENABLE_STATISTICS)
1041 count_all_methods++;
1044 /* all fields of m have been zeroed in load_class_from_classbuffer */
1048 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
1051 m->flags = suck_u2(cb);
1053 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1058 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1063 if (!descriptor_pool_add(descpool, u, &argcount))
1066 #ifdef ENABLE_VERIFIER
1068 if (!is_valid_name_utf(m->name)) {
1069 exceptions_throw_classformaterror(c, "Method with invalid name");
1073 if (m->name->text[0] == '<' &&
1074 m->name != utf_init && m->name != utf_clinit) {
1075 exceptions_throw_classformaterror(c, "Method with invalid special name");
1079 #endif /* ENABLE_VERIFIER */
1081 if (!(m->flags & ACC_STATIC))
1082 argcount++; /* count the 'this' argument */
1084 #ifdef ENABLE_VERIFIER
1086 if (argcount > 255) {
1087 exceptions_throw_classformaterror(c, "Too many arguments in signature");
1091 /* check flag consistency */
1092 if (m->name != utf_clinit) {
1093 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1095 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1096 exceptions_throw_classformaterror(c,
1097 "Illegal method modifiers: 0x%X",
1102 if (m->flags & ACC_ABSTRACT) {
1103 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1104 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1105 exceptions_throw_classformaterror(c,
1106 "Illegal method modifiers: 0x%X",
1112 if (c->flags & ACC_INTERFACE) {
1113 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1114 exceptions_throw_classformaterror(c,
1115 "Illegal method modifiers: 0x%X",
1121 if (m->name == utf_init) {
1122 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1123 ACC_NATIVE | ACC_ABSTRACT)) {
1124 exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
1130 #endif /* ENABLE_VERIFIER */
1132 /* mark the method as monomorphic until further notice */
1134 m->flags |= ACC_METHOD_MONOMORPHIC;
1136 /* non-abstract methods have an implementation in this class */
1138 if (!(m->flags & ACC_ABSTRACT))
1139 m->flags |= ACC_METHOD_IMPLEMENTED;
1141 if (!suck_check_classbuffer_size(cb, 2))
1144 attrnum = suck_u2(cb);
1145 for (i = 0; i < attrnum; i++) {
1148 if (!suck_check_classbuffer_size(cb, 2))
1151 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1154 if (aname == utf_Code) {
1155 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1156 exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
1161 exceptions_throw_classformaterror(c, "Multiple Code attributes");
1165 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1169 m->maxstack = suck_u2(cb);
1170 m->maxlocals = suck_u2(cb);
1172 if (m->maxlocals < argcount) {
1173 exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
1177 if (!suck_check_classbuffer_size(cb, 4))
1180 m->jcodelength = suck_u4(cb);
1182 if (m->jcodelength == 0) {
1183 exceptions_throw_classformaterror(c, "Code of a method has length 0");
1187 if (m->jcodelength > 65535) {
1188 exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
1192 if (!suck_check_classbuffer_size(cb, m->jcodelength))
1195 m->jcode = MNEW(u1, m->jcodelength);
1196 suck_nbytes(m->jcode, cb, m->jcodelength);
1198 if (!suck_check_classbuffer_size(cb, 2))
1201 m->rawexceptiontablelength = suck_u2(cb);
1202 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->rawexceptiontablelength))
1205 m->rawexceptiontable = MNEW(raw_exception_entry, m->rawexceptiontablelength);
1207 #if defined(ENABLE_STATISTICS)
1209 count_vmcode_len += m->jcodelength + 18;
1210 count_extable_len +=
1211 m->rawexceptiontablelength * sizeof(raw_exception_entry);
1215 for (j = 0; j < m->rawexceptiontablelength; j++) {
1217 m->rawexceptiontable[j].startpc = suck_u2(cb);
1218 m->rawexceptiontable[j].endpc = suck_u2(cb);
1219 m->rawexceptiontable[j].handlerpc = suck_u2(cb);
1223 m->rawexceptiontable[j].catchtype.any = NULL;
1226 /* the classref is created later */
1227 if (!(m->rawexceptiontable[j].catchtype.any =
1228 (utf*)class_getconstant(c, idx, CONSTANT_Class)))
1233 if (!suck_check_classbuffer_size(cb, 2))
1236 codeattrnum = suck_u2(cb);
1238 for (; codeattrnum > 0; codeattrnum--) {
1241 if (!suck_check_classbuffer_size(cb, 2))
1244 if (!(caname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1247 if (caname == utf_LineNumberTable) {
1250 if (!suck_check_classbuffer_size(cb, 4 + 2))
1254 m->linenumbercount = suck_u2(cb);
1256 if (!suck_check_classbuffer_size(cb,
1257 (2 + 2) * m->linenumbercount))
1260 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1262 for (lncid = 0; lncid < m->linenumbercount; lncid++) {
1263 m->linenumbers[lncid].start_pc = suck_u2(cb);
1264 m->linenumbers[lncid].line_number = suck_u2(cb);
1268 if (!skipattributes(cb, codeattrnum))
1274 if (!skipattributebody(cb))
1279 else if (aname == utf_Exceptions) {
1282 if (m->thrownexceptions) {
1283 exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
1287 if (!suck_check_classbuffer_size(cb, 4 + 2))
1290 suck_u4(cb); /* length */
1291 m->thrownexceptionscount = suck_u2(cb);
1293 if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1296 m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
1298 for (j = 0; j < m->thrownexceptionscount; j++) {
1299 /* the classref is created later */
1300 if (!((m->thrownexceptions)[j].any =
1301 (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1305 else if (aname == utf_Signature) {
1306 if (!suck_check_classbuffer_size(cb, 4 + 2))
1309 /* check attribute length */
1311 if (suck_u4(cb) != 2) {
1312 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
1316 if (m->signature != NULL) {
1317 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
1321 if (!(m->signature = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1325 if (!skipattributebody(cb))
1330 if (!m->jcode && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1331 exceptions_throw_classformaterror(c, "Missing Code attribute");
1335 /* everything was ok */
1341 /* load_attribute **************************************************************
1343 Read attributes from classfile.
1345 *******************************************************************************/
1347 static bool load_attributes(classbuffer *cb, u4 num)
1355 for (i = 0; i < num; i++) {
1356 /* retrieve attribute name */
1358 if (!suck_check_classbuffer_size(cb, 2))
1361 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1364 if (aname == utf_InnerClasses) {
1365 /* InnerClasses attribute */
1367 if (c->innerclass != NULL) {
1368 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
1372 if (!suck_check_classbuffer_size(cb, 4 + 2))
1375 /* skip attribute length */
1378 /* number of records */
1379 c->innerclasscount = suck_u2(cb);
1381 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
1384 /* allocate memory for innerclass structure */
1385 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
1387 for (j = 0; j < c->innerclasscount; j++) {
1388 /* The innerclass structure contains a class with an encoded
1389 name, its defining scope, its simple name and a bitmask of
1390 the access flags. If an inner class is not a member, its
1391 outer_class is NULL, if a class is anonymous, its name is
1394 innerclassinfo *info = c->innerclass + j;
1396 info->inner_class.ref =
1397 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
1398 info->outer_class.ref =
1399 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
1401 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1402 info->flags = suck_u2(cb);
1405 else if (aname == utf_SourceFile) {
1406 /* SourceFile attribute */
1408 if (!suck_check_classbuffer_size(cb, 4 + 2))
1411 if (suck_u4(cb) != 2) {
1412 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
1416 if (c->sourcefile != NULL) {
1417 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
1421 if (!(c->sourcefile = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1424 else if (aname == utf_Signature) {
1425 /* Signature attribute */
1427 if (!suck_check_classbuffer_size(cb, 4 + 2))
1430 if (suck_u4(cb) != 2) {
1431 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
1435 if (c->signature != NULL) {
1436 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
1440 if (!(c->signature = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1444 /* unknown attribute */
1446 if (!skipattributebody(cb))
1455 /* load_class_from_sysloader ***************************************************
1457 Load the class with the given name using the system class loader
1460 name.............the classname
1463 the loaded class, or
1464 NULL if an exception has been thrown
1466 *******************************************************************************/
1468 classinfo *load_class_from_sysloader(utf *name)
1471 java_objectheader *cl;
1474 assert(class_java_lang_Object);
1475 assert(class_java_lang_ClassLoader);
1476 assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
1478 m = class_resolveclassmethod(class_java_lang_ClassLoader,
1479 utf_getSystemClassLoader,
1480 utf_void__java_lang_ClassLoader,
1481 class_java_lang_Object,
1487 cl = vm_call_method(m, NULL);
1492 c = load_class_from_classloader(name, cl);
1498 /* load_class_from_classloader *************************************************
1500 Load the class with the given name using the given user-defined class loader.
1503 name.............the classname
1504 cl...............user-defined class loader
1507 the loaded class, or
1508 NULL if an exception has been thrown
1510 *******************************************************************************/
1512 classinfo *load_class_from_classloader(utf *name, java_objectheader *cl)
1514 java_objectheader *o;
1517 java_lang_String *s;
1518 #if defined(ENABLE_RT_TIMING)
1519 struct timespec time_start, time_lookup, time_prepare, time_java,
1523 RT_TIMING_GET_TIME(time_start);
1527 /* lookup if this class has already been loaded */
1529 c = classcache_lookup(cl, name);
1531 RT_TIMING_GET_TIME(time_lookup);
1532 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1537 /* if other class loader than bootstrap, call it */
1545 namelen = name->blength;
1547 /* handle array classes */
1548 if (text[0] == '[') {
1554 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1555 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1556 *exceptionptr = new_noclassdeffounderror(name);
1560 u = utf_new(text + 2, namelen - 3);
1562 if (!(comp = load_class_from_classloader(u, cl)))
1565 /* create the array class */
1567 c = class_array_of(comp, false);
1569 tmpc = classcache_store(cl, c, true);
1572 /* exception, free the loaded class */
1573 c->state &= ~CLASS_LOADING;
1580 /* load the component class */
1582 u = utf_new(text + 1, namelen - 1);
1584 if (!(comp = load_class_from_classloader(u, cl)))
1587 /* create the array class */
1589 c = class_array_of(comp, false);
1591 tmpc = classcache_store(cl, c, true);
1594 /* exception, free the loaded class */
1595 c->state &= ~CLASS_LOADING;
1602 /* primitive array classes are loaded by the bootstrap loader */
1604 c = load_class_bootstrap(name);
1610 assert(class_java_lang_Object);
1612 lc = class_resolveclassmethod(cl->vftbl->class,
1614 utf_java_lang_String__java_lang_Class,
1615 class_java_lang_Object,
1619 return false; /* exception */
1621 /* move return value into `o' and cast it afterwards to a classinfo* */
1623 s = javastring_new_slash_to_dot(name);
1625 RT_TIMING_GET_TIME(time_prepare);
1627 o = vm_call_method(lc, cl, s);
1629 RT_TIMING_GET_TIME(time_java);
1631 c = (classinfo *) o;
1634 /* Store this class in the loaded class cache. If another
1635 class with the same (initloader,name) pair has been
1636 stored earlier it will be returned by classcache_store
1637 In this case classcache_store may not free the class
1638 because it has already been exposed to Java code which
1639 may have kept references to that class. */
1641 tmpc = classcache_store(cl, c, false);
1644 /* exception, free the loaded class */
1645 c->state &= ~CLASS_LOADING;
1652 /* loadClass has thrown an exception. We must convert
1653 ClassNotFoundException into
1654 NoClassDefFoundException. */
1656 /* XXX Maybe we should have a flag that avoids this
1657 conversion for calling load_class_from_classloader from
1658 Class.forName. Currently we do a double conversion in
1661 classnotfoundexception_to_noclassdeffounderror();
1664 RT_TIMING_GET_TIME(time_cache);
1666 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1667 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1668 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1670 /* SUN compatible -verbose:class output */
1672 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1674 utf_display_printable_ascii_classname(name);
1678 #if defined(ENABLE_JVMTI)
1679 /* fire Class Load JVMTI event */
1680 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1687 c = load_class_bootstrap(name);
1693 /* load_class_bootstrap ********************************************************
1695 Load the class with the given name using the bootstrap class loader.
1698 name.............the classname
1701 loaded classinfo, or
1702 NULL if an exception has been thrown
1705 load_class_bootstrap is synchronized. It can be treated as an
1708 *******************************************************************************/
1710 classinfo *load_class_bootstrap(utf *name)
1715 #if defined(ENABLE_RT_TIMING)
1716 struct timespec time_start, time_lookup, time_array, time_suck,
1717 time_load, time_cache;
1720 RT_TIMING_GET_TIME(time_start);
1726 /* lookup if this class has already been loaded */
1728 if ((r = classcache_lookup(NULL, name))) {
1730 RT_TIMING_GET_TIME(time_lookup);
1731 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1736 RT_TIMING_GET_TIME(time_lookup);
1737 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1739 /* create the classinfo */
1741 c = class_create_classinfo(name);
1743 /* handle array classes */
1745 if (name->text[0] == '[') {
1746 c = load_newly_created_array(c, NULL);
1749 assert(c->state & CLASS_LOADED);
1751 RT_TIMING_GET_TIME(time_array);
1752 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1757 #if defined(ENABLE_STATISTICS)
1760 if (opt_getcompilingtime)
1761 compilingtime_stop();
1763 if (opt_getloadingtime)
1764 loadingtime_start();
1767 /* load classdata, throw exception on error */
1769 if ((cb = suck_start(c)) == NULL) {
1770 /* this normally means, the classpath was not set properly */
1772 if (name == utf_java_lang_Object)
1773 throw_cacao_exception_exit(string_java_lang_NoClassDefFoundError,
1774 "java/lang/Object");
1776 *exceptionptr = new_noclassdeffounderror(name);
1781 RT_TIMING_GET_TIME(time_suck);
1783 /* load the class from the buffer */
1785 r = load_class_from_classbuffer(cb);
1787 RT_TIMING_GET_TIME(time_load);
1790 /* the class could not be loaded, free the classinfo struct */
1795 /* Store this class in the loaded class cache this step also
1796 checks the loading constraints. If the class has been loaded
1797 before, the earlier loaded class is returned. */
1799 classinfo *res = classcache_store(NULL, c, true);
1809 RT_TIMING_GET_TIME(time_cache);
1811 /* SUN compatible -verbose:class output */
1813 if (opt_verboseclass && r) {
1815 utf_display_printable_ascii_classname(name);
1816 printf(" from %s]\n", cb->path);
1823 #if defined(ENABLE_STATISTICS)
1826 if (opt_getloadingtime)
1829 if (opt_getcompilingtime)
1830 compilingtime_start();
1833 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1834 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1835 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1836 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1842 /* load_class_from_classbuffer *************************************************
1844 Loads everything interesting about a class from the class file. The
1845 'classinfo' structure must have been allocated previously.
1847 The super class and the interfaces implemented by this class need
1848 not be loaded. The link is set later by the function 'class_link'.
1850 The loaded class is removed from the list 'unloadedclasses' and
1851 added to the list 'unlinkedclasses'.
1854 This function is NOT synchronized!
1856 *******************************************************************************/
1858 classinfo *load_class_from_classbuffer(classbuffer *cb)
1866 descriptor_pool *descpool;
1867 #if defined(ENABLE_STATISTICS)
1871 #if defined(ENABLE_RT_TIMING)
1872 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1873 time_setup, time_fields, time_methods, time_classrefs,
1874 time_descs, time_setrefs, time_parsefds, time_parsemds,
1875 time_parsecpool, time_verify, time_attrs;
1878 RT_TIMING_GET_TIME(time_start);
1880 /* get the classbuffer's class */
1884 /* the class is already loaded */
1886 if (c->state & CLASS_LOADED)
1889 #if defined(ENABLE_STATISTICS)
1891 count_class_loads++;
1894 #if !defined(NDEBUG)
1895 /* output for debugging purposes */
1898 log_message_class("Loading class: ", c);
1901 /* mark start of dump memory area */
1903 dumpsize = dump_size();
1905 /* class is currently loading */
1907 c->state |= CLASS_LOADING;
1909 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1910 goto return_exception;
1912 /* check signature */
1914 if (suck_u4(cb) != MAGIC) {
1915 exceptions_throw_classformaterror(c, "Bad magic number");
1917 goto return_exception;
1925 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1927 new_unsupportedclassversionerror(c,
1928 "Unsupported major.minor version %d.%d",
1931 goto return_exception;
1933 RT_TIMING_GET_TIME(time_checks);
1935 /* create a new descriptor pool */
1937 descpool = descriptor_pool_new(c);
1939 RT_TIMING_GET_TIME(time_ndpool);
1941 /* load the constant pool */
1943 if (!load_constantpool(cb, descpool))
1944 goto return_exception;
1946 RT_TIMING_GET_TIME(time_cpool);
1950 if (!suck_check_classbuffer_size(cb, 2))
1951 goto return_exception;
1953 c->flags = suck_u2(cb);
1955 /* check ACC flags consistency */
1957 if (c->flags & ACC_INTERFACE) {
1958 if (!(c->flags & ACC_ABSTRACT)) {
1959 /* We work around this because interfaces in JDK 1.1 are
1960 * not declared abstract. */
1962 c->flags |= ACC_ABSTRACT;
1965 if (c->flags & ACC_FINAL) {
1966 exceptions_throw_classformaterror(c,
1967 "Illegal class modifiers: 0x%X",
1969 goto return_exception;
1972 if (c->flags & ACC_SUPER) {
1973 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1977 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1978 exceptions_throw_classformaterror(c,
1979 "Illegal class modifiers: 0x%X",
1981 goto return_exception;
1984 if (!suck_check_classbuffer_size(cb, 2 + 2))
1985 goto return_exception;
1990 if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1991 goto return_exception;
1993 if (c->name == utf_not_named_yet) {
1994 /* we finally have a name for this class */
1996 class_set_packagename(c);
1998 } else if (name != c->name) {
2002 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
2003 utf_bytes(name) + strlen(")") + strlen("0");
2005 msg = MNEW(char, msglen);
2007 utf_copy_classname(msg, c->name);
2008 strcat(msg, " (wrong name: ");
2009 utf_cat_classname(msg, name);
2013 new_exception_message(string_java_lang_NoClassDefFoundError, msg);
2015 MFREE(msg, char, msglen);
2017 goto return_exception;
2020 /* retrieve superclass */
2022 c->super.any = NULL;
2023 if ((i = suck_u2(cb))) {
2024 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
2025 goto return_exception;
2027 /* java.lang.Object may not have a super class. */
2029 if (c->name == utf_java_lang_Object) {
2031 new_exception_message(string_java_lang_ClassFormatError,
2032 "java.lang.Object with superclass");
2034 goto return_exception;
2037 /* Interfaces must have java.lang.Object as super class. */
2039 if ((c->flags & ACC_INTERFACE) &&
2040 supername != utf_java_lang_Object) {
2042 new_exception_message(string_java_lang_ClassFormatError,
2043 "Interfaces must have java.lang.Object as superclass");
2045 goto return_exception;
2051 /* This is only allowed for java.lang.Object. */
2053 if (c->name != utf_java_lang_Object) {
2054 exceptions_throw_classformaterror(c, "Bad superclass index");
2055 goto return_exception;
2059 /* retrieve interfaces */
2061 if (!suck_check_classbuffer_size(cb, 2))
2062 goto return_exception;
2064 c->interfacescount = suck_u2(cb);
2066 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
2067 goto return_exception;
2069 c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
2070 for (i = 0; i < c->interfacescount; i++) {
2071 /* the classrefs are created later */
2072 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2073 goto return_exception;
2076 RT_TIMING_GET_TIME(time_setup);
2079 if (!suck_check_classbuffer_size(cb, 2))
2080 goto return_exception;
2082 c->fieldscount = suck_u2(cb);
2083 c->fields = GCNEW_UNCOLLECTABLE(fieldinfo, c->fieldscount);
2084 /* c->fields = MNEW(fieldinfo, c->fieldscount); */
2085 for (i = 0; i < c->fieldscount; i++) {
2086 if (!load_field(cb, &(c->fields[i]),descpool))
2087 goto return_exception;
2090 RT_TIMING_GET_TIME(time_fields);
2093 if (!suck_check_classbuffer_size(cb, 2))
2094 goto return_exception;
2096 c->methodscount = suck_u2(cb);
2097 c->methods = MNEW(methodinfo, c->methodscount);
2099 MZERO(c->methods, methodinfo, c->methodscount);
2101 for (i = 0; i < c->methodscount; i++) {
2102 if (!load_method(cb, &(c->methods[i]),descpool))
2103 goto return_exception;
2106 RT_TIMING_GET_TIME(time_methods);
2108 /* create the class reference table */
2111 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
2113 RT_TIMING_GET_TIME(time_classrefs);
2115 /* allocate space for the parsed descriptors */
2117 descriptor_pool_alloc_parsed_descriptors(descpool);
2119 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
2121 #if defined(ENABLE_STATISTICS)
2123 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
2124 count_classref_len += classrefsize;
2125 count_parsed_desc_len += descsize;
2129 RT_TIMING_GET_TIME(time_descs);
2131 /* put the classrefs in the constant pool */
2132 for (i = 0; i < c->cpcount; i++) {
2133 if (c->cptags[i] == CONSTANT_Class) {
2134 utf *name = (utf *) c->cpinfos[i];
2135 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
2139 /* set the super class reference */
2142 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
2144 goto return_exception;
2147 /* set the super interfaces references */
2149 for (i = 0; i < c->interfacescount; i++) {
2150 c->interfaces[i].ref =
2151 descriptor_pool_lookup_classref(descpool,
2152 (utf *) c->interfaces[i].any);
2153 if (!c->interfaces[i].ref)
2154 goto return_exception;
2157 RT_TIMING_GET_TIME(time_setrefs);
2159 /* parse field descriptors */
2161 for (i = 0; i < c->fieldscount; i++) {
2162 c->fields[i].parseddesc =
2163 descriptor_pool_parse_field_descriptor(descpool,
2164 c->fields[i].descriptor);
2165 if (!c->fields[i].parseddesc)
2166 goto return_exception;
2169 RT_TIMING_GET_TIME(time_parsefds);
2171 /* parse method descriptors */
2173 for (i = 0; i < c->methodscount; i++) {
2174 methodinfo *m = &c->methods[i];
2176 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
2177 m->flags, class_get_self_classref(m->class));
2179 goto return_exception;
2181 for (j = 0; j < m->rawexceptiontablelength; j++) {
2182 if (!m->rawexceptiontable[j].catchtype.any)
2184 if ((m->rawexceptiontable[j].catchtype.ref =
2185 descriptor_pool_lookup_classref(descpool,
2186 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
2187 goto return_exception;
2190 for (j = 0; j < m->thrownexceptionscount; j++) {
2191 if (!m->thrownexceptions[j].any)
2193 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
2194 (utf *) m->thrownexceptions[j].any)) == NULL)
2195 goto return_exception;
2199 RT_TIMING_GET_TIME(time_parsemds);
2201 /* parse the loaded descriptors */
2203 for (i = 0; i < c->cpcount; i++) {
2204 constant_FMIref *fmi;
2207 switch (c->cptags[i]) {
2208 case CONSTANT_Fieldref:
2209 fmi = (constant_FMIref *) c->cpinfos[i];
2210 fmi->parseddesc.fd =
2211 descriptor_pool_parse_field_descriptor(descpool,
2213 if (!fmi->parseddesc.fd)
2214 goto return_exception;
2215 index = fmi->p.index;
2217 (constant_classref *) class_getconstant(c, index,
2219 if (!fmi->p.classref)
2220 goto return_exception;
2222 case CONSTANT_Methodref:
2223 case CONSTANT_InterfaceMethodref:
2224 fmi = (constant_FMIref *) c->cpinfos[i];
2225 index = fmi->p.index;
2227 (constant_classref *) class_getconstant(c, index,
2229 if (!fmi->p.classref)
2230 goto return_exception;
2231 fmi->parseddesc.md =
2232 descriptor_pool_parse_method_descriptor(descpool,
2236 if (!fmi->parseddesc.md)
2237 goto return_exception;
2242 RT_TIMING_GET_TIME(time_parsecpool);
2244 #ifdef ENABLE_VERIFIER
2245 /* Check if all fields and methods can be uniquely
2246 * identified by (name,descriptor). */
2249 /* We use a hash table here to avoid making the
2250 * average case quadratic in # of methods, fields.
2252 static int shift = 0;
2254 u2 *next; /* for chaining colliding hash entries */
2260 /* Allocate hashtable */
2261 len = c->methodscount;
2262 if (len < c->fieldscount) len = c->fieldscount;
2264 hashtab = MNEW(u2,(hashlen + len));
2265 next = hashtab + hashlen;
2267 /* Determine bitshift (to get good hash values) */
2277 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2279 for (i = 0; i < c->fieldscount; ++i) {
2280 fieldinfo *fi = c->fields + i;
2282 /* It's ok if we lose bits here */
2283 index = ((((size_t) fi->name) +
2284 ((size_t) fi->descriptor)) >> shift) % hashlen;
2286 if ((old = hashtab[index])) {
2290 if (c->fields[old].name == fi->name &&
2291 c->fields[old].descriptor == fi->descriptor) {
2292 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
2293 goto return_exception;
2295 } while ((old = next[old]));
2297 hashtab[index] = i + 1;
2301 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2303 for (i = 0; i < c->methodscount; ++i) {
2304 methodinfo *mi = c->methods + i;
2306 /* It's ok if we lose bits here */
2307 index = ((((size_t) mi->name) +
2308 ((size_t) mi->descriptor)) >> shift) % hashlen;
2312 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2313 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2317 if ((old = hashtab[index])) {
2321 if (c->methods[old].name == mi->name &&
2322 c->methods[old].descriptor == mi->descriptor) {
2323 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
2324 goto return_exception;
2326 } while ((old = next[old]));
2328 hashtab[index] = i + 1;
2331 MFREE(hashtab, u2, (hashlen + len));
2333 #endif /* ENABLE_VERIFIER */
2335 RT_TIMING_GET_TIME(time_verify);
2337 #if defined(ENABLE_STATISTICS)
2339 size_classinfo += sizeof(classinfo*) * c->interfacescount;
2340 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
2341 size_methodinfo += sizeof(methodinfo) * c->methodscount;
2345 /* load attribute structures */
2347 if (!suck_check_classbuffer_size(cb, 2))
2348 goto return_exception;
2350 if (!load_attributes(cb, suck_u2(cb)))
2351 goto return_exception;
2353 /* Pre Java 1.5 version don't check this. This implementation is like
2354 Java 1.5 do it: for class file version 45.3 we don't check it, older
2355 versions are checked.
2358 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
2359 /* check if all data has been read */
2360 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
2362 if (classdata_left > 0) {
2363 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
2364 goto return_exception;
2368 RT_TIMING_GET_TIME(time_attrs);
2370 /* release dump area */
2372 dump_release(dumpsize);
2374 /* revert loading state and class is loaded */
2376 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2378 #if defined(ENABLE_JVMTI)
2379 /* fire Class Prepare JVMTI event */
2382 jvmti_ClassLoadPrepare(true, c);
2385 #if !defined(NDEBUG)
2387 log_message_class("Loading done class: ", c);
2390 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
2391 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
2392 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
2393 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
2394 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
2395 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
2396 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
2397 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
2398 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
2399 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
2400 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
2401 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
2402 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
2403 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
2404 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
2409 /* release dump area */
2411 dump_release(dumpsize);
2413 /* an exception has been thrown */
2419 /* load_newly_created_array ****************************************************
2421 Load a newly created array class.
2424 c....................the array class C has been loaded
2425 other classinfo......the array class was found in the class cache,
2427 NULL.................an exception has been thrown
2430 This is an internal function. Do not use it unless you know exactly
2433 Use one of the load_class_... functions for general array class loading.
2435 *******************************************************************************/
2437 classinfo *load_newly_created_array(classinfo *c, java_objectheader *loader)
2439 classinfo *comp = NULL;
2441 methoddesc *clonedesc;
2442 constant_classref *classrefs;
2447 text = c->name->text;
2448 namelen = c->name->blength;
2450 /* Check array class name */
2452 if (namelen < 2 || text[0] != '[') {
2453 *exceptionptr = new_noclassdeffounderror(c->name);
2457 /* Check the element type */
2461 /* c is an array of arrays. We have to create the component class. */
2463 u = utf_new(text + 1, namelen - 1);
2464 if (!(comp = load_class_from_classloader(u, loader)))
2467 assert(comp->state & CLASS_LOADED);
2473 /* the array's flags are that of the component class */
2474 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2475 c->classloader = comp->classloader;
2479 /* c is an array of objects. */
2481 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2482 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
2483 *exceptionptr = new_noclassdeffounderror(c->name);
2487 u = utf_new(text + 2, namelen - 3);
2489 if (!(comp = load_class_from_classloader(u, loader)))
2492 assert(comp->state & CLASS_LOADED);
2498 /* the array's flags are that of the component class */
2499 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2500 c->classloader = comp->classloader;
2504 /* c is an array of a primitive type */
2506 /* check for cases like `[II' */
2508 *exceptionptr = new_noclassdeffounderror(c->name);
2512 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2513 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2514 c->classloader = NULL;
2517 assert(class_java_lang_Object);
2518 assert(class_java_lang_Cloneable);
2519 assert(class_java_io_Serializable);
2521 /* setup the array class */
2523 c->super.cls = class_java_lang_Object;
2525 c->interfacescount = 2;
2526 c->interfaces = MNEW(classref_or_classinfo, 2);
2531 tc = class_java_lang_Cloneable;
2532 assert(tc->state & CLASS_LOADED);
2533 list_add_first(&unlinkedclasses, tc);
2534 c->interfaces[0].cls = tc;
2536 tc = class_java_io_Serializable;
2537 assert(tc->state & CLASS_LOADED);
2538 list_add_first(&unlinkedclasses, tc);
2539 c->interfaces[1].cls = tc;
2542 c->interfaces[0].cls = class_java_lang_Cloneable;
2543 c->interfaces[1].cls = class_java_io_Serializable;
2546 c->methodscount = 1;
2547 c->methods = MNEW(methodinfo, c->methodscount);
2548 MZERO(c->methods, methodinfo, c->methodscount);
2550 classrefs = MNEW(constant_classref, 2);
2551 CLASSREF_INIT(classrefs[0], c, c->name);
2552 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2554 /* create descriptor for clone method */
2555 /* we need one paramslot which is reserved for the 'this' parameter */
2556 clonedesc = NEW(methoddesc);
2557 clonedesc->returntype.type = TYPE_ADR;
2558 clonedesc->returntype.classref = classrefs + 1;
2559 clonedesc->returntype.arraydim = 0;
2560 /* initialize params to "empty", add real params below in
2561 descriptor_params_from_paramtypes */
2562 clonedesc->paramcount = 0;
2563 clonedesc->paramslots = 0;
2564 clonedesc->paramtypes[0].classref = classrefs + 0;
2565 clonedesc->params = NULL;
2567 /* create methodinfo */
2570 MSET(clone, 0, methodinfo, 1);
2572 #if defined(ENABLE_THREADS)
2573 lock_init_object_lock(&clone->header);
2576 /* ATTENTION: if you delete the ACC_NATIVE below, set
2577 clone->maxlocals=1 (interpreter related) */
2579 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2580 clone->name = utf_clone;
2581 clone->descriptor = utf_void__java_lang_Object;
2582 clone->parseddesc = clonedesc;
2585 /* parse the descriptor to get the register allocation */
2587 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2591 codegen_createnativestub((functionptr) &builtin_clone_array, clone);
2593 /* XXX: field: length? */
2595 /* array classes are not loaded from class files */
2597 c->state |= CLASS_LOADED;
2598 c->parseddescs = (u1 *) clonedesc;
2599 c->parseddescsize = sizeof(methodinfo);
2600 c->classrefs = classrefs;
2601 c->classrefcount = 1;
2603 /* insert class into the loaded class cache */
2604 /* XXX free classinfo if NULL returned? */
2606 return classcache_store(loader, c, true);
2610 /* loader_close ****************************************************************
2612 Frees all resources.
2614 *******************************************************************************/
2616 void loader_close(void)
2623 * These are local overrides for various environment variables in Emacs.
2624 * Please do not remove this and leave it at the end of the file, where
2625 * Emacs will automagically detect them.
2626 * ---------------------------------------------------------------------
2629 * indent-tabs-mode: t
2633 * vim:noexpandtab:sw=4:ts=4: