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
29 Changes: Andreas Krall
35 $Id: loader.c 5093 2006-07-10 13:36:47Z twisti $
48 #include "mm/memory.h"
49 #include "native/native.h"
50 #include "native/include/java_lang_Throwable.h"
52 #if defined(ENABLE_THREADS)
53 # include "threads/native/threads.h"
56 #include "toolbox/logging.h"
57 #include "vm/builtin.h"
58 #include "vm/classcache.h"
59 #include "vm/exceptions.h"
60 #include "vm/global.h"
61 #include "vm/linker.h"
62 #include "vm/loader.h"
63 #include "vm/options.h"
64 #include "vm/statistics.h"
65 #include "vm/stringlocal.h"
69 #if defined(ENABLE_ZLIB)
73 #include "vm/jit/asmpart.h"
74 #include "vm/jit/codegen-common.h"
75 #include "vm/rt-timing.h"
77 #if defined(ENABLE_JVMTI)
78 #include "native/jvmti/cacaodbg.h"
81 /******************************************************************************/
83 /******************************************************************************/
90 #define LOADER_ASSERT(cond) assert(cond)
92 #define LOADER_ASSERT(cond)
96 /* loader_init *****************************************************************
98 Initializes all lists and loads all classes required for the system
101 *******************************************************************************/
103 bool loader_init(void)
105 #if defined(ENABLE_THREADS)
106 list_classpath_entry *lce;
108 /* Initialize the monitor pointer for zip/jar file locking. */
110 for (lce = list_first(list_classpath_entries); lce != NULL;
111 lce = list_next(list_classpath_entries, lce))
112 if (lce->type == CLASSPATH_ARCHIVE)
113 lock_init_object_lock((java_objectheader *) lce);
116 /* load some important classes */
118 if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
121 if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
124 if (!(class_java_lang_Cloneable =
125 load_class_bootstrap(utf_java_lang_Cloneable)))
128 if (!(class_java_io_Serializable =
129 load_class_bootstrap(utf_java_io_Serializable)))
133 /* load classes for wrapping primitive types */
135 if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
138 if (!(class_java_lang_Boolean =
139 load_class_bootstrap(utf_java_lang_Boolean)))
142 if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
145 if (!(class_java_lang_Character =
146 load_class_bootstrap(utf_java_lang_Character)))
149 if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
152 if (!(class_java_lang_Integer =
153 load_class_bootstrap(utf_java_lang_Integer)))
156 if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
159 if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
162 if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
166 /* load some other important classes */
168 if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
171 if (!(class_java_lang_ClassLoader =
172 load_class_bootstrap(utf_java_lang_ClassLoader)))
175 if (!(class_java_lang_SecurityManager =
176 load_class_bootstrap(utf_java_lang_SecurityManager)))
179 if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
182 if (!(class_java_lang_Thread =
183 load_class_bootstrap(utf_new_char("java/lang/Thread"))))
186 if (!(class_java_lang_ThreadGroup =
187 load_class_bootstrap(utf_java_lang_ThreadGroup)))
190 if (!(class_java_lang_VMThread =
191 load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
195 /* some classes which may be used more often */
197 if (!(class_java_lang_StackTraceElement =
198 load_class_bootstrap(utf_java_lang_StackTraceElement)))
201 if (!(class_java_lang_reflect_Constructor =
202 load_class_bootstrap(utf_java_lang_reflect_Constructor)))
205 if (!(class_java_lang_reflect_Field =
206 load_class_bootstrap(utf_java_lang_reflect_Field)))
209 if (!(class_java_lang_reflect_Method =
210 load_class_bootstrap(utf_java_lang_reflect_Method)))
213 if (!(class_java_security_PrivilegedAction =
214 load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
217 if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
220 if (!(arrayclass_java_lang_Object =
221 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
228 /* loader_load_all_classes *****************************************************
230 Loads all classes specified in the BOOTCLASSPATH.
232 *******************************************************************************/
234 void loader_load_all_classes(void)
236 list_classpath_entry *lce;
237 #if defined(ENABLE_ZLIB)
240 hashtable_zipfile_entry *htzfe;
244 for (lce = list_first(list_classpath_entries); lce != NULL;
245 lce = list_next(list_classpath_entries, lce)) {
246 #if defined(ENABLE_ZLIB)
247 if (lce->type == CLASSPATH_ARCHIVE) {
248 /* get the classes hashtable */
252 for (slot = 0; slot < ht->size; slot++) {
253 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
255 for (; htzfe; htzfe = htzfe->hashlink) {
258 /* skip all entries in META-INF and .properties,
261 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
262 strstr(u->text, ".properties") ||
263 strstr(u->text, ".png"))
266 /* load class from bootstrap classloader */
268 if (!load_class_bootstrap(u)) {
269 fprintf(stderr, "Error loading: ");
270 utf_fprint_printable_ascii_classname(stderr, u);
271 fprintf(stderr, "\n");
274 /* print out exception and cause */
276 exceptions_print_exception(*exceptionptr);
284 #if defined(ENABLE_ZLIB)
291 /* skipattributebody ***********************************************************
293 Skips an attribute after the 16 bit reference to attribute_name has
296 *******************************************************************************/
298 static bool skipattributebody(classbuffer *cb)
302 if (!suck_check_classbuffer_size(cb, 4))
307 if (!suck_check_classbuffer_size(cb, len))
310 suck_skip_nbytes(cb, len);
316 /************************* Function: skipattributes ****************************
318 skips num attribute structures
320 *******************************************************************************/
322 static bool skipattributes(classbuffer *cb, u4 num)
327 for (i = 0; i < num; i++) {
328 if (!suck_check_classbuffer_size(cb, 2 + 4))
334 if (!suck_check_classbuffer_size(cb, len))
337 suck_skip_nbytes(cb, len);
344 /* load_constantpool ***********************************************************
346 Loads the constantpool of a class, the entries are transformed into
347 a simpler format by resolving references (a detailed overview of
348 the compact structures can be found in global.h).
350 *******************************************************************************/
352 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
355 /* The following structures are used to save information which cannot be
356 processed during the first pass. After the complete constantpool has
357 been traversed the references can be resolved.
358 (only in specific order) */
360 /* CONSTANT_Class entries */
361 typedef struct forward_class {
362 struct forward_class *next;
367 /* CONSTANT_String */
368 typedef struct forward_string {
369 struct forward_string *next;
374 /* CONSTANT_NameAndType */
375 typedef struct forward_nameandtype {
376 struct forward_nameandtype *next;
380 } forward_nameandtype;
382 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
383 typedef struct forward_fieldmethint {
384 struct forward_fieldmethint *next;
388 u2 nameandtype_index;
389 } forward_fieldmethint;
395 forward_class *forward_classes = NULL;
396 forward_string *forward_strings = NULL;
397 forward_nameandtype *forward_nameandtypes = NULL;
398 forward_fieldmethint *forward_fieldmethints = NULL;
402 forward_nameandtype *nfn;
403 forward_fieldmethint *nff;
411 /* number of entries in the constant_pool table plus one */
412 if (!suck_check_classbuffer_size(cb, 2))
415 cpcount = c->cpcount = suck_u2(cb);
417 /* allocate memory */
418 cptags = c->cptags = MNEW(u1, cpcount);
419 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
422 exceptions_throw_classformaterror(c, "Illegal constant pool size");
426 #if defined(ENABLE_STATISTICS)
428 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
431 /* initialize constantpool */
432 for (idx = 0; idx < cpcount; idx++) {
433 cptags[idx] = CONSTANT_UNUSED;
438 /******* first pass *******/
439 /* entries which cannot be resolved now are written into
440 temporary structures and traversed again later */
443 while (idx < cpcount) {
446 /* get constant type */
447 if (!suck_check_classbuffer_size(cb, 1))
454 nfc = DNEW(forward_class);
456 nfc->next = forward_classes;
457 forward_classes = nfc;
459 nfc->thisindex = idx;
460 /* reference to CONSTANT_NameAndType */
461 if (!suck_check_classbuffer_size(cb, 2))
464 nfc->name_index = suck_u2(cb);
469 case CONSTANT_String:
470 nfs = DNEW(forward_string);
472 nfs->next = forward_strings;
473 forward_strings = nfs;
475 nfs->thisindex = idx;
477 /* reference to CONSTANT_Utf8_info with string characters */
478 if (!suck_check_classbuffer_size(cb, 2))
481 nfs->string_index = suck_u2(cb);
486 case CONSTANT_NameAndType:
487 nfn = DNEW(forward_nameandtype);
489 nfn->next = forward_nameandtypes;
490 forward_nameandtypes = nfn;
492 nfn->thisindex = idx;
494 if (!suck_check_classbuffer_size(cb, 2 + 2))
497 /* reference to CONSTANT_Utf8_info containing simple name */
498 nfn->name_index = suck_u2(cb);
500 /* reference to CONSTANT_Utf8_info containing field or method
502 nfn->sig_index = suck_u2(cb);
507 case CONSTANT_Fieldref:
508 case CONSTANT_Methodref:
509 case CONSTANT_InterfaceMethodref:
510 nff = DNEW(forward_fieldmethint);
512 nff->next = forward_fieldmethints;
513 forward_fieldmethints = nff;
515 nff->thisindex = idx;
519 if (!suck_check_classbuffer_size(cb, 2 + 2))
522 /* class or interface type that contains the declaration of the
524 nff->class_index = suck_u2(cb);
526 /* name and descriptor of the field or method */
527 nff->nameandtype_index = suck_u2(cb);
532 case CONSTANT_Integer: {
533 constant_integer *ci = NEW(constant_integer);
535 #if defined(ENABLE_STATISTICS)
537 count_const_pool_len += sizeof(constant_integer);
540 if (!suck_check_classbuffer_size(cb, 4))
543 ci->value = suck_s4(cb);
544 cptags[idx] = CONSTANT_Integer;
551 case CONSTANT_Float: {
552 constant_float *cf = NEW(constant_float);
554 #if defined(ENABLE_STATISTICS)
556 count_const_pool_len += sizeof(constant_float);
559 if (!suck_check_classbuffer_size(cb, 4))
562 cf->value = suck_float(cb);
563 cptags[idx] = CONSTANT_Float;
570 case CONSTANT_Long: {
571 constant_long *cl = NEW(constant_long);
573 #if defined(ENABLE_STATISTICS)
575 count_const_pool_len += sizeof(constant_long);
578 if (!suck_check_classbuffer_size(cb, 8))
581 cl->value = suck_s8(cb);
582 cptags[idx] = CONSTANT_Long;
586 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
592 case CONSTANT_Double: {
593 constant_double *cd = NEW(constant_double);
595 #if defined(ENABLE_STATISTICS)
597 count_const_pool_len += sizeof(constant_double);
600 if (!suck_check_classbuffer_size(cb, 8))
603 cd->value = suck_double(cb);
604 cptags[idx] = CONSTANT_Double;
608 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
614 case CONSTANT_Utf8: {
617 /* number of bytes in the bytes array (not string-length) */
618 if (!suck_check_classbuffer_size(cb, 2))
621 length = suck_u2(cb);
622 cptags[idx] = CONSTANT_Utf8;
624 /* validate the string */
625 if (!suck_check_classbuffer_size(cb, length))
628 #ifdef ENABLE_VERIFIER
630 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
632 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
635 #endif /* ENABLE_VERIFIER */
636 /* insert utf-string into the utf-symboltable */
637 cpinfos[idx] = utf_new((char *) cb->pos, length);
639 /* skip bytes of the string (buffer size check above) */
640 suck_skip_nbytes(cb, length);
646 exceptions_throw_classformaterror(c, "Illegal constant pool type");
652 /* resolve entries in temporary structures */
654 while (forward_classes) {
656 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
660 #ifdef ENABLE_VERIFIER
661 if (opt_verify && !is_valid_name_utf(name)) {
662 exceptions_throw_classformaterror(c, "Class reference with invalid name");
665 #endif /* ENABLE_VERIFIER */
667 /* add all class references to the descriptor_pool */
669 if (!descriptor_pool_add_class(descpool, name))
672 cptags[forward_classes->thisindex] = CONSTANT_Class;
677 if (!(tc = load_class_bootstrap(name)))
680 /* link the class later, because we cannot link the class currently
682 list_add_first(&unlinkedclasses, tc);
685 /* the classref is created later */
686 cpinfos[forward_classes->thisindex] = name;
688 nfc = forward_classes;
689 forward_classes = forward_classes->next;
692 while (forward_strings) {
694 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
698 /* resolve utf-string */
699 cptags[forward_strings->thisindex] = CONSTANT_String;
700 cpinfos[forward_strings->thisindex] = text;
702 nfs = forward_strings;
703 forward_strings = forward_strings->next;
706 while (forward_nameandtypes) {
707 constant_nameandtype *cn = NEW(constant_nameandtype);
709 #if defined(ENABLE_STATISTICS)
711 count_const_pool_len += sizeof(constant_nameandtype);
714 /* resolve simple name and descriptor */
715 cn->name = class_getconstant(c,
716 forward_nameandtypes->name_index,
721 cn->descriptor = class_getconstant(c,
722 forward_nameandtypes->sig_index,
727 #ifdef ENABLE_VERIFIER
730 if (!is_valid_name_utf(cn->name)) {
731 exceptions_throw_classformaterror(c,
732 "Illegal Field name \"%s\"",
738 /* disallow referencing <clinit> among others */
739 if (cn->name->text[0] == '<' && cn->name != utf_init) {
740 exceptions_throw_classformaterror(c, "Illegal reference to special method");
744 #endif /* ENABLE_VERIFIER */
746 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
747 cpinfos[forward_nameandtypes->thisindex] = cn;
749 nfn = forward_nameandtypes;
750 forward_nameandtypes = forward_nameandtypes->next;
753 while (forward_fieldmethints) {
754 constant_nameandtype *nat;
755 constant_FMIref *fmi = NEW(constant_FMIref);
757 #if defined(ENABLE_STATISTICS)
759 count_const_pool_len += sizeof(constant_FMIref);
761 /* resolve simple name and descriptor */
763 nat = class_getconstant(c,
764 forward_fieldmethints->nameandtype_index,
765 CONSTANT_NameAndType);
769 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
771 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
774 /* the classref is created later */
776 fmi->p.index = forward_fieldmethints->class_index;
777 fmi->name = nat->name;
778 fmi->descriptor = nat->descriptor;
780 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
781 cpinfos[forward_fieldmethints->thisindex] = fmi;
783 nff = forward_fieldmethints;
784 forward_fieldmethints = forward_fieldmethints->next;
787 /* everything was ok */
793 /* load_field ******************************************************************
795 Load everything about a class field from the class file and fill a
796 'fieldinfo' structure. For static fields, space in the data segment
799 *******************************************************************************/
801 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
803 static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
808 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
813 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
816 f->flags = suck_u2(cb);
818 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
823 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
827 f->parseddesc = NULL;
829 if (!descriptor_pool_add(descpool, u, NULL))
832 /* descriptor_pool_add accepts method descriptors, so we have to check */
833 /* against them here before the call of descriptor_to_basic_type below. */
834 if (u->text[0] == '(') {
835 exceptions_throw_classformaterror(c, "Method descriptor used for field");
839 #ifdef ENABLE_VERIFIER
842 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<') {
843 exceptions_throw_classformaterror(c,
844 "Illegal Field name \"%s\"",
849 /* check flag consistency */
850 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
852 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
853 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
854 exceptions_throw_classformaterror(c,
855 "Illegal field modifiers: 0x%X",
860 if (c->flags & ACC_INTERFACE) {
861 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
862 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
863 f->flags & ACC_TRANSIENT) {
864 exceptions_throw_classformaterror(c,
865 "Illegal field modifiers: 0x%X",
871 #endif /* ENABLE_VERIFIER */
873 f->type = jtype = descriptor_to_basic_type(f->descriptor); /* data type */
874 f->offset = 0; /* offset from start of object */
878 case TYPE_INT: f->value.i = 0; break;
879 case TYPE_FLOAT: f->value.f = 0.0; break;
880 case TYPE_DOUBLE: f->value.d = 0.0; break;
881 case TYPE_ADDRESS: f->value.a = NULL;
882 if (!(f->flags & ACC_STATIC))
883 c->flags |= ACC_CLASS_HAS_POINTERS;
887 f->value.l = 0; break;
889 f->value.l.low = 0; f->value.l.high = 0; break;
893 /* read attributes */
894 if (!suck_check_classbuffer_size(cb, 2))
897 attrnum = suck_u2(cb);
898 for (i = 0; i < attrnum; i++) {
899 if (!suck_check_classbuffer_size(cb, 2))
902 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
905 if (u == utf_ConstantValue) {
906 if (!suck_check_classbuffer_size(cb, 4 + 2))
909 /* check attribute length */
910 if (suck_u4(cb) != 2) {
911 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
915 /* constant value attribute */
916 if (pindex != field_load_NOVALUE) {
917 exceptions_throw_classformaterror(c, "Multiple ConstantValue attributes");
921 /* index of value in constantpool */
922 pindex = suck_u2(cb);
924 /* initialize field with value from constantpool */
927 constant_integer *ci;
929 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
932 f->value.i = ci->value;
939 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
942 f->value.l = cl->value;
949 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
952 f->value.f = cf->value;
959 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
962 f->value.d = cd->value;
967 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
970 /* create javastring from compressed utf8-string */
971 f->value.a = literalstring_new(u);
975 log_text("Invalid Constant - Type");
979 /* unknown attribute */
980 if (!skipattributebody(cb))
985 /* everything was ok */
991 /* load_method *****************************************************************
993 Loads a method from the class file and fills an existing
994 'methodinfo' structure. For native methods, the function pointer
995 field is set to the real function pointer, for JavaVM methods a
996 pointer to the compiler is used preliminarily.
998 *******************************************************************************/
1000 static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpool)
1011 #if defined(ENABLE_THREADS)
1012 lock_init_object_lock(&m->header);
1015 #if defined(ENABLE_STATISTICS)
1017 count_all_methods++;
1020 /* all fields of m have been zeroed in load_class_from_classbuffer */
1024 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
1027 m->flags = suck_u2(cb);
1029 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1034 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1039 if (!descriptor_pool_add(descpool, u, &argcount))
1042 #ifdef ENABLE_VERIFIER
1044 if (!is_valid_name_utf(m->name)) {
1045 exceptions_throw_classformaterror(c, "Method with invalid name");
1049 if (m->name->text[0] == '<' &&
1050 m->name != utf_init && m->name != utf_clinit) {
1051 exceptions_throw_classformaterror(c, "Method with invalid special name");
1055 #endif /* ENABLE_VERIFIER */
1057 if (!(m->flags & ACC_STATIC))
1058 argcount++; /* count the 'this' argument */
1060 #ifdef ENABLE_VERIFIER
1062 if (argcount > 255) {
1063 exceptions_throw_classformaterror(c, "Too many arguments in signature");
1067 /* check flag consistency */
1068 if (m->name != utf_clinit) {
1069 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1071 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1072 exceptions_throw_classformaterror(c,
1073 "Illegal method modifiers: 0x%X",
1078 if (m->flags & ACC_ABSTRACT) {
1079 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1080 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1081 exceptions_throw_classformaterror(c,
1082 "Illegal method modifiers: 0x%X",
1088 if (c->flags & ACC_INTERFACE) {
1089 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1090 exceptions_throw_classformaterror(c,
1091 "Illegal method modifiers: 0x%X",
1097 if (m->name == utf_init) {
1098 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1099 ACC_NATIVE | ACC_ABSTRACT)) {
1100 exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
1106 #endif /* ENABLE_VERIFIER */
1108 if (!suck_check_classbuffer_size(cb, 2))
1111 attrnum = suck_u2(cb);
1112 for (i = 0; i < attrnum; i++) {
1115 if (!suck_check_classbuffer_size(cb, 2))
1118 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1121 if (aname == utf_Code) {
1122 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1123 exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
1128 exceptions_throw_classformaterror(c, "Multiple Code attributes");
1132 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1136 m->maxstack = suck_u2(cb);
1137 m->maxlocals = suck_u2(cb);
1139 if (m->maxlocals < argcount) {
1140 exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
1144 if (!suck_check_classbuffer_size(cb, 4))
1147 m->jcodelength = suck_u4(cb);
1149 if (m->jcodelength == 0) {
1150 exceptions_throw_classformaterror(c, "Code of a method has length 0");
1154 if (m->jcodelength > 65535) {
1155 exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
1159 if (!suck_check_classbuffer_size(cb, m->jcodelength))
1162 m->jcode = MNEW(u1, m->jcodelength);
1163 suck_nbytes(m->jcode, cb, m->jcodelength);
1165 if (!suck_check_classbuffer_size(cb, 2))
1168 m->exceptiontablelength = suck_u2(cb);
1169 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->exceptiontablelength))
1172 m->exceptiontable = MNEW(exceptiontable, m->exceptiontablelength);
1174 #if defined(ENABLE_STATISTICS)
1176 count_vmcode_len += m->jcodelength + 18;
1177 count_extable_len +=
1178 m->exceptiontablelength * sizeof(exceptiontable);
1182 for (j = 0; j < m->exceptiontablelength; j++) {
1184 m->exceptiontable[j].startpc = suck_u2(cb);
1185 m->exceptiontable[j].endpc = suck_u2(cb);
1186 m->exceptiontable[j].handlerpc = suck_u2(cb);
1190 m->exceptiontable[j].catchtype.any = NULL;
1193 /* the classref is created later */
1194 if (!(m->exceptiontable[j].catchtype.any =
1195 (utf*)class_getconstant(c, idx, CONSTANT_Class)))
1200 if (!suck_check_classbuffer_size(cb, 2))
1203 codeattrnum = suck_u2(cb);
1205 for (; codeattrnum > 0; codeattrnum--) {
1208 if (!suck_check_classbuffer_size(cb, 2))
1211 if (!(caname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1214 if (caname == utf_LineNumberTable) {
1217 if (!suck_check_classbuffer_size(cb, 4 + 2))
1221 m->linenumbercount = suck_u2(cb);
1223 if (!suck_check_classbuffer_size(cb,
1224 (2 + 2) * m->linenumbercount))
1227 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1229 for (lncid = 0; lncid < m->linenumbercount; lncid++) {
1230 m->linenumbers[lncid].start_pc = suck_u2(cb);
1231 m->linenumbers[lncid].line_number = suck_u2(cb);
1235 if (!skipattributes(cb, codeattrnum))
1241 if (!skipattributebody(cb))
1246 } else if (aname == utf_Exceptions) {
1249 if (m->thrownexceptions) {
1250 exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
1254 if (!suck_check_classbuffer_size(cb, 4 + 2))
1257 suck_u4(cb); /* length */
1258 m->thrownexceptionscount = suck_u2(cb);
1260 if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1263 m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
1265 for (j = 0; j < m->thrownexceptionscount; j++) {
1266 /* the classref is created later */
1267 if (!((m->thrownexceptions)[j].any =
1268 (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1273 if (!skipattributebody(cb))
1278 if (!m->jcode && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1279 exceptions_throw_classformaterror(c, "Missing Code attribute");
1283 /* everything was ok */
1289 /* load_attribute **************************************************************
1291 Read attributes from classfile.
1293 *******************************************************************************/
1295 static bool load_attributes(classbuffer *cb, u4 num)
1303 for (i = 0; i < num; i++) {
1304 /* retrieve attribute name */
1305 if (!suck_check_classbuffer_size(cb, 2))
1308 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1311 if (aname == utf_InnerClasses) {
1312 /* innerclasses attribute */
1313 if (c->innerclass) {
1314 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
1318 if (!suck_check_classbuffer_size(cb, 4 + 2))
1321 /* skip attribute length */
1324 /* number of records */
1325 c->innerclasscount = suck_u2(cb);
1327 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
1330 /* allocate memory for innerclass structure */
1331 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
1333 for (j = 0; j < c->innerclasscount; j++) {
1334 /* The innerclass structure contains a class with an encoded
1335 name, its defining scope, its simple name and a bitmask of
1336 the access flags. If an inner class is not a member, its
1337 outer_class is NULL, if a class is anonymous, its name is
1340 innerclassinfo *info = c->innerclass + j;
1342 info->inner_class.ref =
1343 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
1344 info->outer_class.ref =
1345 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
1347 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1348 info->flags = suck_u2(cb);
1351 } else if (aname == utf_SourceFile) {
1352 if (!suck_check_classbuffer_size(cb, 4 + 2))
1355 if (suck_u4(cb) != 2) {
1356 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
1360 if (c->sourcefile) {
1361 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
1365 if (!(c->sourcefile = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1369 /* unknown attribute */
1370 if (!skipattributebody(cb))
1379 /* load_class_from_sysloader ***************************************************
1381 Load the class with the given name using the system class loader
1384 name.............the classname
1387 the loaded class, or
1388 NULL if an exception has been thrown
1390 *******************************************************************************/
1392 classinfo *load_class_from_sysloader(utf *name)
1395 java_objectheader *cl;
1398 LOADER_ASSERT(class_java_lang_Object);
1399 LOADER_ASSERT(class_java_lang_ClassLoader);
1400 LOADER_ASSERT(class_java_lang_ClassLoader->state & CLASS_LINKED);
1402 m = class_resolveclassmethod(class_java_lang_ClassLoader,
1403 utf_getSystemClassLoader,
1404 utf_void__java_lang_ClassLoader,
1405 class_java_lang_Object,
1411 cl = vm_call_method(m, NULL);
1416 c = load_class_from_classloader(name, cl);
1422 /* load_class_from_classloader *************************************************
1424 Load the class with the given name using the given user-defined class loader.
1427 name.............the classname
1428 cl...............user-defined class loader
1431 the loaded class, or
1432 NULL if an exception has been thrown
1434 *******************************************************************************/
1436 classinfo *load_class_from_classloader(utf *name, java_objectheader *cl)
1438 java_objectheader *o;
1441 java_lang_String *s;
1442 #if defined(ENABLE_RT_TIMING)
1443 struct timespec time_start, time_lookup, time_prepare, time_java,
1447 RT_TIMING_GET_TIME(time_start);
1449 LOADER_ASSERT(name);
1451 /* lookup if this class has already been loaded */
1453 c = classcache_lookup(cl, name);
1455 RT_TIMING_GET_TIME(time_lookup);
1456 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1461 /* if other class loader than bootstrap, call it */
1469 namelen = name->blength;
1471 /* handle array classes */
1472 if (text[0] == '[') {
1478 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1479 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1480 *exceptionptr = new_noclassdeffounderror(name);
1484 u = utf_new(text + 2, namelen - 3);
1486 if (!(comp = load_class_from_classloader(u, cl)))
1489 /* create the array class */
1491 c = class_array_of(comp, false);
1493 tmpc = classcache_store(cl, c, true);
1496 /* exception, free the loaded class */
1497 c->state &= ~CLASS_LOADING;
1504 /* load the component class */
1506 u = utf_new(text + 1, namelen - 1);
1508 if (!(comp = load_class_from_classloader(u, cl)))
1511 /* create the array class */
1513 c = class_array_of(comp, false);
1515 tmpc = classcache_store(cl, c, true);
1518 /* exception, free the loaded class */
1519 c->state &= ~CLASS_LOADING;
1526 /* primitive array classes are loaded by the bootstrap loader */
1528 c = load_class_bootstrap(name);
1534 LOADER_ASSERT(class_java_lang_Object);
1536 lc = class_resolveclassmethod(cl->vftbl->class,
1538 utf_java_lang_String__java_lang_Class,
1539 class_java_lang_Object,
1543 return false; /* exception */
1545 /* move return value into `o' and cast it afterwards to a classinfo* */
1547 s = javastring_new_slash_to_dot(name);
1549 RT_TIMING_GET_TIME(time_prepare);
1551 o = vm_call_method(lc, cl, s);
1553 RT_TIMING_GET_TIME(time_java);
1555 c = (classinfo *) o;
1558 /* Store this class in the loaded class cache. If another
1559 class with the same (initloader,name) pair has been
1560 stored earlier it will be returned by classcache_store
1561 In this case classcache_store may not free the class
1562 because it has already been exposed to Java code which
1563 may have kept references to that class. */
1565 tmpc = classcache_store(cl, c, false);
1568 /* exception, free the loaded class */
1569 c->state &= ~CLASS_LOADING;
1576 /* loadClass has thrown an exception. We must convert
1577 ClassNotFoundException into
1578 NoClassDefFoundException. */
1580 /* XXX Maybe we should have a flag that avoids this
1581 conversion for calling load_class_from_classloader from
1582 Class.forName. Currently we do a double conversion in
1585 classnotfoundexception_to_noclassdeffounderror();
1588 RT_TIMING_GET_TIME(time_cache);
1590 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1591 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1592 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1594 /* SUN compatible -verbose:class output */
1596 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1598 utf_display_printable_ascii_classname(name);
1602 #if defined(ENABLE_JVMTI)
1603 /* fire Class Load JVMTI event */
1604 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1611 c = load_class_bootstrap(name);
1617 /* load_class_bootstrap ********************************************************
1619 Load the class with the given name using the bootstrap class loader.
1622 name.............the classname
1625 loaded classinfo, or
1626 NULL if an exception has been thrown
1629 load_class_bootstrap is synchronized. It can be treated as an
1632 *******************************************************************************/
1634 classinfo *load_class_bootstrap(utf *name)
1639 #if defined(ENABLE_RT_TIMING)
1640 struct timespec time_start, time_lookup, time_array, time_suck,
1641 time_load, time_cache;
1644 RT_TIMING_GET_TIME(time_start);
1648 LOADER_ASSERT(name);
1650 /* lookup if this class has already been loaded */
1652 if ((r = classcache_lookup(NULL, name))) {
1654 RT_TIMING_GET_TIME(time_lookup);
1655 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1660 RT_TIMING_GET_TIME(time_lookup);
1661 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1663 /* create the classinfo */
1665 c = class_create_classinfo(name);
1667 /* handle array classes */
1669 if (name->text[0] == '[') {
1670 c = load_newly_created_array(c, NULL);
1673 LOADER_ASSERT(c->state & CLASS_LOADED);
1675 RT_TIMING_GET_TIME(time_array);
1676 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1681 #if defined(ENABLE_STATISTICS)
1684 if (opt_getcompilingtime)
1685 compilingtime_stop();
1687 if (opt_getloadingtime)
1688 loadingtime_start();
1691 /* load classdata, throw exception on error */
1693 if ((cb = suck_start(c)) == NULL) {
1694 /* this normally means, the classpath was not set properly */
1696 if (name == utf_java_lang_Object)
1697 throw_cacao_exception_exit(string_java_lang_NoClassDefFoundError,
1698 "java/lang/Object");
1700 *exceptionptr = new_noclassdeffounderror(name);
1705 RT_TIMING_GET_TIME(time_suck);
1707 /* load the class from the buffer */
1709 r = load_class_from_classbuffer(cb);
1711 RT_TIMING_GET_TIME(time_load);
1714 /* the class could not be loaded, free the classinfo struct */
1719 /* Store this class in the loaded class cache this step also
1720 checks the loading constraints. If the class has been loaded
1721 before, the earlier loaded class is returned. */
1723 classinfo *res = classcache_store(NULL, c, true);
1733 RT_TIMING_GET_TIME(time_cache);
1735 /* SUN compatible -verbose:class output */
1737 if (opt_verboseclass && r) {
1739 utf_display_printable_ascii_classname(name);
1740 printf(" from %s]\n", cb->path);
1747 #if defined(ENABLE_STATISTICS)
1750 if (opt_getloadingtime)
1753 if (opt_getcompilingtime)
1754 compilingtime_start();
1757 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1758 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1759 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1760 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1766 /* load_class_from_classbuffer *************************************************
1768 Loads everything interesting about a class from the class file. The
1769 'classinfo' structure must have been allocated previously.
1771 The super class and the interfaces implemented by this class need
1772 not be loaded. The link is set later by the function 'class_link'.
1774 The loaded class is removed from the list 'unloadedclasses' and
1775 added to the list 'unlinkedclasses'.
1778 This function is NOT synchronized!
1780 *******************************************************************************/
1782 classinfo *load_class_from_classbuffer(classbuffer *cb)
1790 descriptor_pool *descpool;
1791 #if defined(ENABLE_STATISTICS)
1795 #if defined(ENABLE_RT_TIMING)
1796 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1797 time_setup, time_fields, time_methods, time_classrefs,
1798 time_descs, time_setrefs, time_parsefds, time_parsemds,
1799 time_parsecpool, time_verify, time_attrs;
1802 RT_TIMING_GET_TIME(time_start);
1804 /* get the classbuffer's class */
1808 /* the class is already loaded */
1810 if (c->state & CLASS_LOADED)
1813 #if defined(ENABLE_STATISTICS)
1815 count_class_loads++;
1818 #if !defined(NDEBUG)
1819 /* output for debugging purposes */
1822 log_message_class("Loading class: ", c);
1825 /* mark start of dump memory area */
1827 dumpsize = dump_size();
1829 /* class is currently loading */
1831 c->state |= CLASS_LOADING;
1833 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1834 goto return_exception;
1836 /* check signature */
1838 if (suck_u4(cb) != MAGIC) {
1839 exceptions_throw_classformaterror(c, "Bad magic number");
1841 goto return_exception;
1849 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1851 new_unsupportedclassversionerror(c,
1852 "Unsupported major.minor version %d.%d",
1855 goto return_exception;
1857 RT_TIMING_GET_TIME(time_checks);
1859 /* create a new descriptor pool */
1861 descpool = descriptor_pool_new(c);
1863 RT_TIMING_GET_TIME(time_ndpool);
1865 /* load the constant pool */
1867 if (!load_constantpool(cb, descpool))
1868 goto return_exception;
1870 RT_TIMING_GET_TIME(time_cpool);
1874 if (!suck_check_classbuffer_size(cb, 2))
1875 goto return_exception;
1877 c->flags = suck_u2(cb);
1879 /* check ACC flags consistency */
1881 if (c->flags & ACC_INTERFACE) {
1882 if (!(c->flags & ACC_ABSTRACT)) {
1883 /* We work around this because interfaces in JDK 1.1 are
1884 * not declared abstract. */
1886 c->flags |= ACC_ABSTRACT;
1889 if (c->flags & ACC_FINAL) {
1890 exceptions_throw_classformaterror(c,
1891 "Illegal class modifiers: 0x%X",
1893 goto return_exception;
1896 if (c->flags & ACC_SUPER) {
1897 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1901 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1902 exceptions_throw_classformaterror(c,
1903 "Illegal class modifiers: 0x%X",
1905 goto return_exception;
1908 if (!suck_check_classbuffer_size(cb, 2 + 2))
1909 goto return_exception;
1914 if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1915 goto return_exception;
1917 if (c->name == utf_not_named_yet) {
1918 /* we finally have a name for this class */
1920 class_set_packagename(c);
1922 } else if (name != c->name) {
1926 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
1927 utf_bytes(name) + strlen(")") + strlen("0");
1929 msg = MNEW(char, msglen);
1931 utf_copy_classname(msg, c->name);
1932 strcat(msg, " (wrong name: ");
1933 utf_cat_classname(msg, name);
1937 new_exception_message(string_java_lang_NoClassDefFoundError, msg);
1939 MFREE(msg, char, msglen);
1941 goto return_exception;
1944 /* retrieve superclass */
1946 c->super.any = NULL;
1947 if ((i = suck_u2(cb))) {
1948 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1949 goto return_exception;
1951 /* java.lang.Object may not have a super class. */
1953 if (c->name == utf_java_lang_Object) {
1955 new_exception_message(string_java_lang_ClassFormatError,
1956 "java.lang.Object with superclass");
1958 goto return_exception;
1961 /* Interfaces must have java.lang.Object as super class. */
1963 if ((c->flags & ACC_INTERFACE) &&
1964 supername != utf_java_lang_Object) {
1966 new_exception_message(string_java_lang_ClassFormatError,
1967 "Interfaces must have java.lang.Object as superclass");
1969 goto return_exception;
1975 /* This is only allowed for java.lang.Object. */
1977 if (c->name != utf_java_lang_Object) {
1978 exceptions_throw_classformaterror(c, "Bad superclass index");
1979 goto return_exception;
1983 /* retrieve interfaces */
1985 if (!suck_check_classbuffer_size(cb, 2))
1986 goto return_exception;
1988 c->interfacescount = suck_u2(cb);
1990 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1991 goto return_exception;
1993 c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
1994 for (i = 0; i < c->interfacescount; i++) {
1995 /* the classrefs are created later */
1996 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1997 goto return_exception;
2000 RT_TIMING_GET_TIME(time_setup);
2003 if (!suck_check_classbuffer_size(cb, 2))
2004 goto return_exception;
2006 c->fieldscount = suck_u2(cb);
2007 c->fields = GCNEW_UNCOLLECTABLE(fieldinfo, c->fieldscount);
2008 /* c->fields = MNEW(fieldinfo, c->fieldscount); */
2009 for (i = 0; i < c->fieldscount; i++) {
2010 if (!load_field(cb, &(c->fields[i]),descpool))
2011 goto return_exception;
2014 RT_TIMING_GET_TIME(time_fields);
2017 if (!suck_check_classbuffer_size(cb, 2))
2018 goto return_exception;
2020 c->methodscount = suck_u2(cb);
2021 /* c->methods = GCNEW(methodinfo, c->methodscount); */
2022 c->methods = MNEW(methodinfo, c->methodscount);
2024 MZERO(c->methods, methodinfo, c->methodscount);
2026 for (i = 0; i < c->methodscount; i++) {
2027 if (!load_method(cb, &(c->methods[i]),descpool))
2028 goto return_exception;
2031 RT_TIMING_GET_TIME(time_methods);
2033 /* create the class reference table */
2036 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
2038 RT_TIMING_GET_TIME(time_classrefs);
2040 /* allocate space for the parsed descriptors */
2042 descriptor_pool_alloc_parsed_descriptors(descpool);
2044 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
2046 #if defined(ENABLE_STATISTICS)
2048 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
2049 count_classref_len += classrefsize;
2050 count_parsed_desc_len += descsize;
2054 RT_TIMING_GET_TIME(time_descs);
2056 /* put the classrefs in the constant pool */
2057 for (i = 0; i < c->cpcount; i++) {
2058 if (c->cptags[i] == CONSTANT_Class) {
2059 utf *name = (utf *) c->cpinfos[i];
2060 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
2064 /* set the super class reference */
2067 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
2069 goto return_exception;
2072 /* set the super interfaces references */
2074 for (i = 0; i < c->interfacescount; i++) {
2075 c->interfaces[i].ref =
2076 descriptor_pool_lookup_classref(descpool,
2077 (utf *) c->interfaces[i].any);
2078 if (!c->interfaces[i].ref)
2079 goto return_exception;
2082 RT_TIMING_GET_TIME(time_setrefs);
2084 /* parse field descriptors */
2086 for (i = 0; i < c->fieldscount; i++) {
2087 c->fields[i].parseddesc =
2088 descriptor_pool_parse_field_descriptor(descpool,
2089 c->fields[i].descriptor);
2090 if (!c->fields[i].parseddesc)
2091 goto return_exception;
2094 RT_TIMING_GET_TIME(time_parsefds);
2096 /* parse method descriptors */
2098 for (i = 0; i < c->methodscount; i++) {
2099 methodinfo *m = &c->methods[i];
2101 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
2102 m->flags, class_get_self_classref(m->class));
2104 goto return_exception;
2106 for (j = 0; j < m->exceptiontablelength; j++) {
2107 if (!m->exceptiontable[j].catchtype.any)
2109 if ((m->exceptiontable[j].catchtype.ref =
2110 descriptor_pool_lookup_classref(descpool,
2111 (utf *) m->exceptiontable[j].catchtype.any)) == NULL)
2112 goto return_exception;
2115 for (j = 0; j < m->thrownexceptionscount; j++) {
2116 if (!m->thrownexceptions[j].any)
2118 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
2119 (utf *) m->thrownexceptions[j].any)) == NULL)
2120 goto return_exception;
2124 RT_TIMING_GET_TIME(time_parsemds);
2126 /* parse the loaded descriptors */
2128 for (i = 0; i < c->cpcount; i++) {
2129 constant_FMIref *fmi;
2132 switch (c->cptags[i]) {
2133 case CONSTANT_Fieldref:
2134 fmi = (constant_FMIref *) c->cpinfos[i];
2135 fmi->parseddesc.fd =
2136 descriptor_pool_parse_field_descriptor(descpool,
2138 if (!fmi->parseddesc.fd)
2139 goto return_exception;
2140 index = fmi->p.index;
2142 (constant_classref *) class_getconstant(c, index,
2144 if (!fmi->p.classref)
2145 goto return_exception;
2147 case CONSTANT_Methodref:
2148 case CONSTANT_InterfaceMethodref:
2149 fmi = (constant_FMIref *) c->cpinfos[i];
2150 index = fmi->p.index;
2152 (constant_classref *) class_getconstant(c, index,
2154 if (!fmi->p.classref)
2155 goto return_exception;
2156 fmi->parseddesc.md =
2157 descriptor_pool_parse_method_descriptor(descpool,
2161 if (!fmi->parseddesc.md)
2162 goto return_exception;
2167 RT_TIMING_GET_TIME(time_parsecpool);
2169 #ifdef ENABLE_VERIFIER
2170 /* Check if all fields and methods can be uniquely
2171 * identified by (name,descriptor). */
2174 /* We use a hash table here to avoid making the
2175 * average case quadratic in # of methods, fields.
2177 static int shift = 0;
2179 u2 *next; /* for chaining colliding hash entries */
2185 /* Allocate hashtable */
2186 len = c->methodscount;
2187 if (len < c->fieldscount) len = c->fieldscount;
2189 hashtab = MNEW(u2,(hashlen + len));
2190 next = hashtab + hashlen;
2192 /* Determine bitshift (to get good hash values) */
2202 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2204 for (i = 0; i < c->fieldscount; ++i) {
2205 fieldinfo *fi = c->fields + i;
2207 /* It's ok if we lose bits here */
2208 index = ((((size_t) fi->name) +
2209 ((size_t) fi->descriptor)) >> shift) % hashlen;
2211 if ((old = hashtab[index])) {
2215 if (c->fields[old].name == fi->name &&
2216 c->fields[old].descriptor == fi->descriptor) {
2217 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
2218 goto return_exception;
2220 } while ((old = next[old]));
2222 hashtab[index] = i + 1;
2226 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2228 for (i = 0; i < c->methodscount; ++i) {
2229 methodinfo *mi = c->methods + i;
2231 /* It's ok if we lose bits here */
2232 index = ((((size_t) mi->name) +
2233 ((size_t) mi->descriptor)) >> shift) % hashlen;
2237 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2238 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2242 if ((old = hashtab[index])) {
2246 if (c->methods[old].name == mi->name &&
2247 c->methods[old].descriptor == mi->descriptor) {
2248 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
2249 goto return_exception;
2251 } while ((old = next[old]));
2253 hashtab[index] = i + 1;
2256 MFREE(hashtab, u2, (hashlen + len));
2258 #endif /* ENABLE_VERIFIER */
2260 RT_TIMING_GET_TIME(time_verify);
2262 #if defined(ENABLE_STATISTICS)
2264 size_classinfo += sizeof(classinfo*) * c->interfacescount;
2265 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
2266 size_methodinfo += sizeof(methodinfo) * c->methodscount;
2270 /* load attribute structures */
2272 if (!suck_check_classbuffer_size(cb, 2))
2273 goto return_exception;
2275 if (!load_attributes(cb, suck_u2(cb)))
2276 goto return_exception;
2279 /* Pre java 1.5 version don't check this. This implementation is like
2280 java 1.5 do it: for class file version 45.3 we don't check it, older
2281 versions are checked.
2283 if ((ma == 45 && mi > 3) || ma > 45) {
2284 /* check if all data has been read */
2285 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
2287 if (classdata_left > 0) {
2288 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
2289 goto return_exception;
2294 RT_TIMING_GET_TIME(time_attrs);
2296 /* release dump area */
2298 dump_release(dumpsize);
2300 /* revert loading state and class is loaded */
2302 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2303 #if defined(ENABLE_JVMTI)
2304 /* fire Class Prepare JVMTI event */
2305 if (jvmti) jvmti_ClassLoadPrepare(true, c);
2309 #if !defined(NDEBUG)
2311 log_message_class("Loading done class: ", c);
2314 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
2315 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
2316 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
2317 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
2318 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
2319 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
2320 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
2321 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
2322 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
2323 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
2324 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
2325 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
2326 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
2327 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
2328 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
2333 /* release dump area */
2335 dump_release(dumpsize);
2337 /* an exception has been thrown */
2343 /* load_newly_created_array ****************************************************
2345 Load a newly created array class.
2348 c....................the array class C has been loaded
2349 other classinfo......the array class was found in the class cache,
2351 NULL.................an exception has been thrown
2354 This is an internal function. Do not use it unless you know exactly
2357 Use one of the load_class_... functions for general array class loading.
2359 *******************************************************************************/
2361 classinfo *load_newly_created_array(classinfo *c, java_objectheader *loader)
2363 classinfo *comp = NULL;
2365 methoddesc *clonedesc;
2366 constant_classref *classrefs;
2371 text = c->name->text;
2372 namelen = c->name->blength;
2374 /* Check array class name */
2376 if (namelen < 2 || text[0] != '[') {
2377 *exceptionptr = new_noclassdeffounderror(c->name);
2381 /* Check the element type */
2385 /* c is an array of arrays. We have to create the component class. */
2387 u = utf_new(text + 1, namelen - 1);
2388 if (!(comp = load_class_from_classloader(u, loader)))
2391 LOADER_ASSERT(comp->state & CLASS_LOADED);
2397 /* the array's flags are that of the component class */
2398 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2399 c->classloader = comp->classloader;
2403 /* c is an array of objects. */
2405 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2406 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
2407 *exceptionptr = new_noclassdeffounderror(c->name);
2411 u = utf_new(text + 2, namelen - 3);
2413 if (!(comp = load_class_from_classloader(u, loader)))
2416 LOADER_ASSERT(comp->state & CLASS_LOADED);
2422 /* the array's flags are that of the component class */
2423 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2424 c->classloader = comp->classloader;
2428 /* c is an array of a primitive type */
2430 /* check for cases like `[II' */
2432 *exceptionptr = new_noclassdeffounderror(c->name);
2436 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2437 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2438 c->classloader = NULL;
2441 LOADER_ASSERT(class_java_lang_Object);
2442 LOADER_ASSERT(class_java_lang_Cloneable);
2443 LOADER_ASSERT(class_java_io_Serializable);
2445 /* setup the array class */
2447 c->super.cls = class_java_lang_Object;
2449 c->interfacescount = 2;
2450 c->interfaces = MNEW(classref_or_classinfo, 2);
2455 tc = class_java_lang_Cloneable;
2456 LOADER_ASSERT(tc->state & CLASS_LOADED);
2457 list_add_first(&unlinkedclasses, tc);
2458 c->interfaces[0].cls = tc;
2460 tc = class_java_io_Serializable;
2461 LOADER_ASSERT(tc->state & CLASS_LOADED);
2462 list_add_first(&unlinkedclasses, tc);
2463 c->interfaces[1].cls = tc;
2466 c->interfaces[0].cls = class_java_lang_Cloneable;
2467 c->interfaces[1].cls = class_java_io_Serializable;
2470 c->methodscount = 1;
2471 c->methods = MNEW(methodinfo, c->methodscount);
2473 classrefs = MNEW(constant_classref, 2);
2474 CLASSREF_INIT(classrefs[0], c, c->name);
2475 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2477 /* create descriptor for clone method */
2478 /* we need one paramslot which is reserved for the 'this' parameter */
2479 clonedesc = NEW(methoddesc);
2480 clonedesc->returntype.type = TYPE_ADDRESS;
2481 clonedesc->returntype.classref = classrefs + 1;
2482 clonedesc->returntype.arraydim = 0;
2483 /* initialize params to "empty", add real params below in
2484 descriptor_params_from_paramtypes */
2485 clonedesc->paramcount = 0;
2486 clonedesc->paramslots = 0;
2487 clonedesc->paramtypes[0].classref = classrefs + 0;
2488 clonedesc->params = NULL;
2490 /* create methodinfo */
2493 MSET(clone, 0, methodinfo, 1);
2495 #if defined(ENABLE_THREADS)
2496 lock_init_object_lock(&clone->header);
2499 /* ATTENTION: if you delete the ACC_NATIVE below, set
2500 clone->maxlocals=1 (interpreter related) */
2502 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2503 clone->name = utf_clone;
2504 clone->descriptor = utf_void__java_lang_Object;
2505 clone->parseddesc = clonedesc;
2508 /* parse the descriptor to get the register allocation */
2510 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2514 codegen_createnativestub((functionptr) &builtin_clone_array, clone);
2516 /* XXX: field: length? */
2518 /* array classes are not loaded from class files */
2520 c->state |= CLASS_LOADED;
2521 c->parseddescs = (u1 *) clonedesc;
2522 c->parseddescsize = sizeof(methodinfo);
2523 c->classrefs = classrefs;
2524 c->classrefcount = 1;
2526 /* insert class into the loaded class cache */
2527 /* XXX free classinfo if NULL returned? */
2529 return classcache_store(loader, c, true);
2533 /* loader_close ****************************************************************
2535 Frees all resources.
2537 *******************************************************************************/
2539 void loader_close(void)
2546 * These are local overrides for various environment variables in Emacs.
2547 * Please do not remove this and leave it at the end of the file, where
2548 * Emacs will automagically detect them.
2549 * ---------------------------------------------------------------------
2552 * indent-tabs-mode: t
2556 * vim:noexpandtab:sw=4:ts=4: