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 5184 2006-07-28 10:12:58Z 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 */
892 if (!(f->flags & ACC_STATIC))
893 c->flags |= ACC_CLASS_HAS_POINTERS;
906 /* read attributes */
907 if (!suck_check_classbuffer_size(cb, 2))
910 attrnum = suck_u2(cb);
911 for (i = 0; i < attrnum; i++) {
912 if (!suck_check_classbuffer_size(cb, 2))
915 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
918 if (u == utf_ConstantValue) {
919 if (!suck_check_classbuffer_size(cb, 4 + 2))
922 /* check attribute length */
923 if (suck_u4(cb) != 2) {
924 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
928 /* constant value attribute */
929 if (pindex != field_load_NOVALUE) {
930 exceptions_throw_classformaterror(c, "Multiple ConstantValue attributes");
934 /* index of value in constantpool */
935 pindex = suck_u2(cb);
937 /* initialize field with value from constantpool */
940 constant_integer *ci;
942 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
945 f->value.i = ci->value;
952 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
955 f->value.l = cl->value;
962 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
965 f->value.f = cf->value;
972 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
975 f->value.d = cd->value;
980 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
983 /* create javastring from compressed utf8-string */
984 f->value.a = literalstring_new(u);
988 log_text("Invalid Constant - Type");
992 /* unknown attribute */
993 if (!skipattributebody(cb))
998 /* everything was ok */
1004 /* load_method *****************************************************************
1006 Loads a method from the class file and fills an existing
1007 'methodinfo' structure. For native methods, the function pointer
1008 field is set to the real function pointer, for JavaVM methods a
1009 pointer to the compiler is used preliminarily.
1011 *******************************************************************************/
1013 static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpool)
1024 #if defined(ENABLE_THREADS)
1025 lock_init_object_lock(&m->header);
1028 #if defined(ENABLE_STATISTICS)
1030 count_all_methods++;
1033 /* all fields of m have been zeroed in load_class_from_classbuffer */
1037 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
1040 m->flags = suck_u2(cb);
1042 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1047 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1052 if (!descriptor_pool_add(descpool, u, &argcount))
1055 #ifdef ENABLE_VERIFIER
1057 if (!is_valid_name_utf(m->name)) {
1058 exceptions_throw_classformaterror(c, "Method with invalid name");
1062 if (m->name->text[0] == '<' &&
1063 m->name != utf_init && m->name != utf_clinit) {
1064 exceptions_throw_classformaterror(c, "Method with invalid special name");
1068 #endif /* ENABLE_VERIFIER */
1070 if (!(m->flags & ACC_STATIC))
1071 argcount++; /* count the 'this' argument */
1073 #ifdef ENABLE_VERIFIER
1075 if (argcount > 255) {
1076 exceptions_throw_classformaterror(c, "Too many arguments in signature");
1080 /* check flag consistency */
1081 if (m->name != utf_clinit) {
1082 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1084 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1085 exceptions_throw_classformaterror(c,
1086 "Illegal method modifiers: 0x%X",
1091 if (m->flags & ACC_ABSTRACT) {
1092 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1093 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1094 exceptions_throw_classformaterror(c,
1095 "Illegal method modifiers: 0x%X",
1101 if (c->flags & ACC_INTERFACE) {
1102 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1103 exceptions_throw_classformaterror(c,
1104 "Illegal method modifiers: 0x%X",
1110 if (m->name == utf_init) {
1111 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1112 ACC_NATIVE | ACC_ABSTRACT)) {
1113 exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
1119 #endif /* ENABLE_VERIFIER */
1121 if (!suck_check_classbuffer_size(cb, 2))
1124 attrnum = suck_u2(cb);
1125 for (i = 0; i < attrnum; i++) {
1128 if (!suck_check_classbuffer_size(cb, 2))
1131 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1134 if (aname == utf_Code) {
1135 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1136 exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
1141 exceptions_throw_classformaterror(c, "Multiple Code attributes");
1145 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1149 m->maxstack = suck_u2(cb);
1150 m->maxlocals = suck_u2(cb);
1152 if (m->maxlocals < argcount) {
1153 exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
1157 if (!suck_check_classbuffer_size(cb, 4))
1160 m->jcodelength = suck_u4(cb);
1162 if (m->jcodelength == 0) {
1163 exceptions_throw_classformaterror(c, "Code of a method has length 0");
1167 if (m->jcodelength > 65535) {
1168 exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
1172 if (!suck_check_classbuffer_size(cb, m->jcodelength))
1175 m->jcode = MNEW(u1, m->jcodelength);
1176 suck_nbytes(m->jcode, cb, m->jcodelength);
1178 if (!suck_check_classbuffer_size(cb, 2))
1181 m->exceptiontablelength = suck_u2(cb);
1182 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->exceptiontablelength))
1185 m->exceptiontable = MNEW(exceptiontable, m->exceptiontablelength);
1187 #if defined(ENABLE_STATISTICS)
1189 count_vmcode_len += m->jcodelength + 18;
1190 count_extable_len +=
1191 m->exceptiontablelength * sizeof(exceptiontable);
1195 for (j = 0; j < m->exceptiontablelength; j++) {
1197 m->exceptiontable[j].startpc = suck_u2(cb);
1198 m->exceptiontable[j].endpc = suck_u2(cb);
1199 m->exceptiontable[j].handlerpc = suck_u2(cb);
1203 m->exceptiontable[j].catchtype.any = NULL;
1206 /* the classref is created later */
1207 if (!(m->exceptiontable[j].catchtype.any =
1208 (utf*)class_getconstant(c, idx, CONSTANT_Class)))
1213 if (!suck_check_classbuffer_size(cb, 2))
1216 codeattrnum = suck_u2(cb);
1218 for (; codeattrnum > 0; codeattrnum--) {
1221 if (!suck_check_classbuffer_size(cb, 2))
1224 if (!(caname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1227 if (caname == utf_LineNumberTable) {
1230 if (!suck_check_classbuffer_size(cb, 4 + 2))
1234 m->linenumbercount = suck_u2(cb);
1236 if (!suck_check_classbuffer_size(cb,
1237 (2 + 2) * m->linenumbercount))
1240 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1242 for (lncid = 0; lncid < m->linenumbercount; lncid++) {
1243 m->linenumbers[lncid].start_pc = suck_u2(cb);
1244 m->linenumbers[lncid].line_number = suck_u2(cb);
1248 if (!skipattributes(cb, codeattrnum))
1254 if (!skipattributebody(cb))
1259 } else if (aname == utf_Exceptions) {
1262 if (m->thrownexceptions) {
1263 exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
1267 if (!suck_check_classbuffer_size(cb, 4 + 2))
1270 suck_u4(cb); /* length */
1271 m->thrownexceptionscount = suck_u2(cb);
1273 if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1276 m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
1278 for (j = 0; j < m->thrownexceptionscount; j++) {
1279 /* the classref is created later */
1280 if (!((m->thrownexceptions)[j].any =
1281 (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1286 if (!skipattributebody(cb))
1291 if (!m->jcode && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1292 exceptions_throw_classformaterror(c, "Missing Code attribute");
1296 /* everything was ok */
1302 /* load_attribute **************************************************************
1304 Read attributes from classfile.
1306 *******************************************************************************/
1308 static bool load_attributes(classbuffer *cb, u4 num)
1316 for (i = 0; i < num; i++) {
1317 /* retrieve attribute name */
1318 if (!suck_check_classbuffer_size(cb, 2))
1321 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1324 if (aname == utf_InnerClasses) {
1325 /* innerclasses attribute */
1326 if (c->innerclass) {
1327 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
1331 if (!suck_check_classbuffer_size(cb, 4 + 2))
1334 /* skip attribute length */
1337 /* number of records */
1338 c->innerclasscount = suck_u2(cb);
1340 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
1343 /* allocate memory for innerclass structure */
1344 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
1346 for (j = 0; j < c->innerclasscount; j++) {
1347 /* The innerclass structure contains a class with an encoded
1348 name, its defining scope, its simple name and a bitmask of
1349 the access flags. If an inner class is not a member, its
1350 outer_class is NULL, if a class is anonymous, its name is
1353 innerclassinfo *info = c->innerclass + j;
1355 info->inner_class.ref =
1356 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
1357 info->outer_class.ref =
1358 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
1360 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1361 info->flags = suck_u2(cb);
1364 } else if (aname == utf_SourceFile) {
1365 if (!suck_check_classbuffer_size(cb, 4 + 2))
1368 if (suck_u4(cb) != 2) {
1369 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
1373 if (c->sourcefile) {
1374 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
1378 if (!(c->sourcefile = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1382 /* unknown attribute */
1383 if (!skipattributebody(cb))
1392 /* load_class_from_sysloader ***************************************************
1394 Load the class with the given name using the system class loader
1397 name.............the classname
1400 the loaded class, or
1401 NULL if an exception has been thrown
1403 *******************************************************************************/
1405 classinfo *load_class_from_sysloader(utf *name)
1408 java_objectheader *cl;
1411 LOADER_ASSERT(class_java_lang_Object);
1412 LOADER_ASSERT(class_java_lang_ClassLoader);
1413 LOADER_ASSERT(class_java_lang_ClassLoader->state & CLASS_LINKED);
1415 m = class_resolveclassmethod(class_java_lang_ClassLoader,
1416 utf_getSystemClassLoader,
1417 utf_void__java_lang_ClassLoader,
1418 class_java_lang_Object,
1424 cl = vm_call_method(m, NULL);
1429 c = load_class_from_classloader(name, cl);
1435 /* load_class_from_classloader *************************************************
1437 Load the class with the given name using the given user-defined class loader.
1440 name.............the classname
1441 cl...............user-defined class loader
1444 the loaded class, or
1445 NULL if an exception has been thrown
1447 *******************************************************************************/
1449 classinfo *load_class_from_classloader(utf *name, java_objectheader *cl)
1451 java_objectheader *o;
1454 java_lang_String *s;
1455 #if defined(ENABLE_RT_TIMING)
1456 struct timespec time_start, time_lookup, time_prepare, time_java,
1460 RT_TIMING_GET_TIME(time_start);
1462 LOADER_ASSERT(name);
1464 /* lookup if this class has already been loaded */
1466 c = classcache_lookup(cl, name);
1468 RT_TIMING_GET_TIME(time_lookup);
1469 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1474 /* if other class loader than bootstrap, call it */
1482 namelen = name->blength;
1484 /* handle array classes */
1485 if (text[0] == '[') {
1491 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1492 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1493 *exceptionptr = new_noclassdeffounderror(name);
1497 u = utf_new(text + 2, namelen - 3);
1499 if (!(comp = load_class_from_classloader(u, cl)))
1502 /* create the array class */
1504 c = class_array_of(comp, false);
1506 tmpc = classcache_store(cl, c, true);
1509 /* exception, free the loaded class */
1510 c->state &= ~CLASS_LOADING;
1517 /* load the component class */
1519 u = utf_new(text + 1, namelen - 1);
1521 if (!(comp = load_class_from_classloader(u, cl)))
1524 /* create the array class */
1526 c = class_array_of(comp, false);
1528 tmpc = classcache_store(cl, c, true);
1531 /* exception, free the loaded class */
1532 c->state &= ~CLASS_LOADING;
1539 /* primitive array classes are loaded by the bootstrap loader */
1541 c = load_class_bootstrap(name);
1547 LOADER_ASSERT(class_java_lang_Object);
1549 lc = class_resolveclassmethod(cl->vftbl->class,
1551 utf_java_lang_String__java_lang_Class,
1552 class_java_lang_Object,
1556 return false; /* exception */
1558 /* move return value into `o' and cast it afterwards to a classinfo* */
1560 s = javastring_new_slash_to_dot(name);
1562 RT_TIMING_GET_TIME(time_prepare);
1564 o = vm_call_method(lc, cl, s);
1566 RT_TIMING_GET_TIME(time_java);
1568 c = (classinfo *) o;
1571 /* Store this class in the loaded class cache. If another
1572 class with the same (initloader,name) pair has been
1573 stored earlier it will be returned by classcache_store
1574 In this case classcache_store may not free the class
1575 because it has already been exposed to Java code which
1576 may have kept references to that class. */
1578 tmpc = classcache_store(cl, c, false);
1581 /* exception, free the loaded class */
1582 c->state &= ~CLASS_LOADING;
1589 /* loadClass has thrown an exception. We must convert
1590 ClassNotFoundException into
1591 NoClassDefFoundException. */
1593 /* XXX Maybe we should have a flag that avoids this
1594 conversion for calling load_class_from_classloader from
1595 Class.forName. Currently we do a double conversion in
1598 classnotfoundexception_to_noclassdeffounderror();
1601 RT_TIMING_GET_TIME(time_cache);
1603 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1604 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1605 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1607 /* SUN compatible -verbose:class output */
1609 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1611 utf_display_printable_ascii_classname(name);
1615 #if defined(ENABLE_JVMTI)
1616 /* fire Class Load JVMTI event */
1617 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1624 c = load_class_bootstrap(name);
1630 /* load_class_bootstrap ********************************************************
1632 Load the class with the given name using the bootstrap class loader.
1635 name.............the classname
1638 loaded classinfo, or
1639 NULL if an exception has been thrown
1642 load_class_bootstrap is synchronized. It can be treated as an
1645 *******************************************************************************/
1647 classinfo *load_class_bootstrap(utf *name)
1652 #if defined(ENABLE_RT_TIMING)
1653 struct timespec time_start, time_lookup, time_array, time_suck,
1654 time_load, time_cache;
1657 RT_TIMING_GET_TIME(time_start);
1661 LOADER_ASSERT(name);
1663 /* lookup if this class has already been loaded */
1665 if ((r = classcache_lookup(NULL, name))) {
1667 RT_TIMING_GET_TIME(time_lookup);
1668 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1673 RT_TIMING_GET_TIME(time_lookup);
1674 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1676 /* create the classinfo */
1678 c = class_create_classinfo(name);
1680 /* handle array classes */
1682 if (name->text[0] == '[') {
1683 c = load_newly_created_array(c, NULL);
1686 LOADER_ASSERT(c->state & CLASS_LOADED);
1688 RT_TIMING_GET_TIME(time_array);
1689 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1694 #if defined(ENABLE_STATISTICS)
1697 if (opt_getcompilingtime)
1698 compilingtime_stop();
1700 if (opt_getloadingtime)
1701 loadingtime_start();
1704 /* load classdata, throw exception on error */
1706 if ((cb = suck_start(c)) == NULL) {
1707 /* this normally means, the classpath was not set properly */
1709 if (name == utf_java_lang_Object)
1710 throw_cacao_exception_exit(string_java_lang_NoClassDefFoundError,
1711 "java/lang/Object");
1713 *exceptionptr = new_noclassdeffounderror(name);
1718 RT_TIMING_GET_TIME(time_suck);
1720 /* load the class from the buffer */
1722 r = load_class_from_classbuffer(cb);
1724 RT_TIMING_GET_TIME(time_load);
1727 /* the class could not be loaded, free the classinfo struct */
1732 /* Store this class in the loaded class cache this step also
1733 checks the loading constraints. If the class has been loaded
1734 before, the earlier loaded class is returned. */
1736 classinfo *res = classcache_store(NULL, c, true);
1746 RT_TIMING_GET_TIME(time_cache);
1748 /* SUN compatible -verbose:class output */
1750 if (opt_verboseclass && r) {
1752 utf_display_printable_ascii_classname(name);
1753 printf(" from %s]\n", cb->path);
1760 #if defined(ENABLE_STATISTICS)
1763 if (opt_getloadingtime)
1766 if (opt_getcompilingtime)
1767 compilingtime_start();
1770 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1771 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1772 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1773 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1779 /* load_class_from_classbuffer *************************************************
1781 Loads everything interesting about a class from the class file. The
1782 'classinfo' structure must have been allocated previously.
1784 The super class and the interfaces implemented by this class need
1785 not be loaded. The link is set later by the function 'class_link'.
1787 The loaded class is removed from the list 'unloadedclasses' and
1788 added to the list 'unlinkedclasses'.
1791 This function is NOT synchronized!
1793 *******************************************************************************/
1795 classinfo *load_class_from_classbuffer(classbuffer *cb)
1803 descriptor_pool *descpool;
1804 #if defined(ENABLE_STATISTICS)
1808 #if defined(ENABLE_RT_TIMING)
1809 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1810 time_setup, time_fields, time_methods, time_classrefs,
1811 time_descs, time_setrefs, time_parsefds, time_parsemds,
1812 time_parsecpool, time_verify, time_attrs;
1815 RT_TIMING_GET_TIME(time_start);
1817 /* get the classbuffer's class */
1821 /* the class is already loaded */
1823 if (c->state & CLASS_LOADED)
1826 #if defined(ENABLE_STATISTICS)
1828 count_class_loads++;
1831 #if !defined(NDEBUG)
1832 /* output for debugging purposes */
1835 log_message_class("Loading class: ", c);
1838 /* mark start of dump memory area */
1840 dumpsize = dump_size();
1842 /* class is currently loading */
1844 c->state |= CLASS_LOADING;
1846 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1847 goto return_exception;
1849 /* check signature */
1851 if (suck_u4(cb) != MAGIC) {
1852 exceptions_throw_classformaterror(c, "Bad magic number");
1854 goto return_exception;
1862 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1864 new_unsupportedclassversionerror(c,
1865 "Unsupported major.minor version %d.%d",
1868 goto return_exception;
1870 RT_TIMING_GET_TIME(time_checks);
1872 /* create a new descriptor pool */
1874 descpool = descriptor_pool_new(c);
1876 RT_TIMING_GET_TIME(time_ndpool);
1878 /* load the constant pool */
1880 if (!load_constantpool(cb, descpool))
1881 goto return_exception;
1883 RT_TIMING_GET_TIME(time_cpool);
1887 if (!suck_check_classbuffer_size(cb, 2))
1888 goto return_exception;
1890 c->flags = suck_u2(cb);
1892 /* check ACC flags consistency */
1894 if (c->flags & ACC_INTERFACE) {
1895 if (!(c->flags & ACC_ABSTRACT)) {
1896 /* We work around this because interfaces in JDK 1.1 are
1897 * not declared abstract. */
1899 c->flags |= ACC_ABSTRACT;
1902 if (c->flags & ACC_FINAL) {
1903 exceptions_throw_classformaterror(c,
1904 "Illegal class modifiers: 0x%X",
1906 goto return_exception;
1909 if (c->flags & ACC_SUPER) {
1910 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1914 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1915 exceptions_throw_classformaterror(c,
1916 "Illegal class modifiers: 0x%X",
1918 goto return_exception;
1921 if (!suck_check_classbuffer_size(cb, 2 + 2))
1922 goto return_exception;
1927 if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1928 goto return_exception;
1930 if (c->name == utf_not_named_yet) {
1931 /* we finally have a name for this class */
1933 class_set_packagename(c);
1935 } else if (name != c->name) {
1939 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
1940 utf_bytes(name) + strlen(")") + strlen("0");
1942 msg = MNEW(char, msglen);
1944 utf_copy_classname(msg, c->name);
1945 strcat(msg, " (wrong name: ");
1946 utf_cat_classname(msg, name);
1950 new_exception_message(string_java_lang_NoClassDefFoundError, msg);
1952 MFREE(msg, char, msglen);
1954 goto return_exception;
1957 /* retrieve superclass */
1959 c->super.any = NULL;
1960 if ((i = suck_u2(cb))) {
1961 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1962 goto return_exception;
1964 /* java.lang.Object may not have a super class. */
1966 if (c->name == utf_java_lang_Object) {
1968 new_exception_message(string_java_lang_ClassFormatError,
1969 "java.lang.Object with superclass");
1971 goto return_exception;
1974 /* Interfaces must have java.lang.Object as super class. */
1976 if ((c->flags & ACC_INTERFACE) &&
1977 supername != utf_java_lang_Object) {
1979 new_exception_message(string_java_lang_ClassFormatError,
1980 "Interfaces must have java.lang.Object as superclass");
1982 goto return_exception;
1988 /* This is only allowed for java.lang.Object. */
1990 if (c->name != utf_java_lang_Object) {
1991 exceptions_throw_classformaterror(c, "Bad superclass index");
1992 goto return_exception;
1996 /* retrieve interfaces */
1998 if (!suck_check_classbuffer_size(cb, 2))
1999 goto return_exception;
2001 c->interfacescount = suck_u2(cb);
2003 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
2004 goto return_exception;
2006 c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
2007 for (i = 0; i < c->interfacescount; i++) {
2008 /* the classrefs are created later */
2009 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2010 goto return_exception;
2013 RT_TIMING_GET_TIME(time_setup);
2016 if (!suck_check_classbuffer_size(cb, 2))
2017 goto return_exception;
2019 c->fieldscount = suck_u2(cb);
2020 c->fields = GCNEW_UNCOLLECTABLE(fieldinfo, c->fieldscount);
2021 /* c->fields = MNEW(fieldinfo, c->fieldscount); */
2022 for (i = 0; i < c->fieldscount; i++) {
2023 if (!load_field(cb, &(c->fields[i]),descpool))
2024 goto return_exception;
2027 RT_TIMING_GET_TIME(time_fields);
2030 if (!suck_check_classbuffer_size(cb, 2))
2031 goto return_exception;
2033 c->methodscount = suck_u2(cb);
2034 /* c->methods = GCNEW(methodinfo, c->methodscount); */
2035 c->methods = MNEW(methodinfo, c->methodscount);
2037 MZERO(c->methods, methodinfo, c->methodscount);
2039 for (i = 0; i < c->methodscount; i++) {
2040 if (!load_method(cb, &(c->methods[i]),descpool))
2041 goto return_exception;
2044 RT_TIMING_GET_TIME(time_methods);
2046 /* create the class reference table */
2049 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
2051 RT_TIMING_GET_TIME(time_classrefs);
2053 /* allocate space for the parsed descriptors */
2055 descriptor_pool_alloc_parsed_descriptors(descpool);
2057 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
2059 #if defined(ENABLE_STATISTICS)
2061 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
2062 count_classref_len += classrefsize;
2063 count_parsed_desc_len += descsize;
2067 RT_TIMING_GET_TIME(time_descs);
2069 /* put the classrefs in the constant pool */
2070 for (i = 0; i < c->cpcount; i++) {
2071 if (c->cptags[i] == CONSTANT_Class) {
2072 utf *name = (utf *) c->cpinfos[i];
2073 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
2077 /* set the super class reference */
2080 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
2082 goto return_exception;
2085 /* set the super interfaces references */
2087 for (i = 0; i < c->interfacescount; i++) {
2088 c->interfaces[i].ref =
2089 descriptor_pool_lookup_classref(descpool,
2090 (utf *) c->interfaces[i].any);
2091 if (!c->interfaces[i].ref)
2092 goto return_exception;
2095 RT_TIMING_GET_TIME(time_setrefs);
2097 /* parse field descriptors */
2099 for (i = 0; i < c->fieldscount; i++) {
2100 c->fields[i].parseddesc =
2101 descriptor_pool_parse_field_descriptor(descpool,
2102 c->fields[i].descriptor);
2103 if (!c->fields[i].parseddesc)
2104 goto return_exception;
2107 RT_TIMING_GET_TIME(time_parsefds);
2109 /* parse method descriptors */
2111 for (i = 0; i < c->methodscount; i++) {
2112 methodinfo *m = &c->methods[i];
2114 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
2115 m->flags, class_get_self_classref(m->class));
2117 goto return_exception;
2119 for (j = 0; j < m->exceptiontablelength; j++) {
2120 if (!m->exceptiontable[j].catchtype.any)
2122 if ((m->exceptiontable[j].catchtype.ref =
2123 descriptor_pool_lookup_classref(descpool,
2124 (utf *) m->exceptiontable[j].catchtype.any)) == NULL)
2125 goto return_exception;
2128 for (j = 0; j < m->thrownexceptionscount; j++) {
2129 if (!m->thrownexceptions[j].any)
2131 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
2132 (utf *) m->thrownexceptions[j].any)) == NULL)
2133 goto return_exception;
2137 RT_TIMING_GET_TIME(time_parsemds);
2139 /* parse the loaded descriptors */
2141 for (i = 0; i < c->cpcount; i++) {
2142 constant_FMIref *fmi;
2145 switch (c->cptags[i]) {
2146 case CONSTANT_Fieldref:
2147 fmi = (constant_FMIref *) c->cpinfos[i];
2148 fmi->parseddesc.fd =
2149 descriptor_pool_parse_field_descriptor(descpool,
2151 if (!fmi->parseddesc.fd)
2152 goto return_exception;
2153 index = fmi->p.index;
2155 (constant_classref *) class_getconstant(c, index,
2157 if (!fmi->p.classref)
2158 goto return_exception;
2160 case CONSTANT_Methodref:
2161 case CONSTANT_InterfaceMethodref:
2162 fmi = (constant_FMIref *) c->cpinfos[i];
2163 index = fmi->p.index;
2165 (constant_classref *) class_getconstant(c, index,
2167 if (!fmi->p.classref)
2168 goto return_exception;
2169 fmi->parseddesc.md =
2170 descriptor_pool_parse_method_descriptor(descpool,
2174 if (!fmi->parseddesc.md)
2175 goto return_exception;
2180 RT_TIMING_GET_TIME(time_parsecpool);
2182 #ifdef ENABLE_VERIFIER
2183 /* Check if all fields and methods can be uniquely
2184 * identified by (name,descriptor). */
2187 /* We use a hash table here to avoid making the
2188 * average case quadratic in # of methods, fields.
2190 static int shift = 0;
2192 u2 *next; /* for chaining colliding hash entries */
2198 /* Allocate hashtable */
2199 len = c->methodscount;
2200 if (len < c->fieldscount) len = c->fieldscount;
2202 hashtab = MNEW(u2,(hashlen + len));
2203 next = hashtab + hashlen;
2205 /* Determine bitshift (to get good hash values) */
2215 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2217 for (i = 0; i < c->fieldscount; ++i) {
2218 fieldinfo *fi = c->fields + i;
2220 /* It's ok if we lose bits here */
2221 index = ((((size_t) fi->name) +
2222 ((size_t) fi->descriptor)) >> shift) % hashlen;
2224 if ((old = hashtab[index])) {
2228 if (c->fields[old].name == fi->name &&
2229 c->fields[old].descriptor == fi->descriptor) {
2230 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
2231 goto return_exception;
2233 } while ((old = next[old]));
2235 hashtab[index] = i + 1;
2239 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2241 for (i = 0; i < c->methodscount; ++i) {
2242 methodinfo *mi = c->methods + i;
2244 /* It's ok if we lose bits here */
2245 index = ((((size_t) mi->name) +
2246 ((size_t) mi->descriptor)) >> shift) % hashlen;
2250 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2251 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2255 if ((old = hashtab[index])) {
2259 if (c->methods[old].name == mi->name &&
2260 c->methods[old].descriptor == mi->descriptor) {
2261 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
2262 goto return_exception;
2264 } while ((old = next[old]));
2266 hashtab[index] = i + 1;
2269 MFREE(hashtab, u2, (hashlen + len));
2271 #endif /* ENABLE_VERIFIER */
2273 RT_TIMING_GET_TIME(time_verify);
2275 #if defined(ENABLE_STATISTICS)
2277 size_classinfo += sizeof(classinfo*) * c->interfacescount;
2278 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
2279 size_methodinfo += sizeof(methodinfo) * c->methodscount;
2283 /* load attribute structures */
2285 if (!suck_check_classbuffer_size(cb, 2))
2286 goto return_exception;
2288 if (!load_attributes(cb, suck_u2(cb)))
2289 goto return_exception;
2291 /* Pre Java 1.5 version don't check this. This implementation is like
2292 Java 1.5 do it: for class file version 45.3 we don't check it, older
2293 versions are checked.
2296 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
2297 /* check if all data has been read */
2298 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
2300 if (classdata_left > 0) {
2301 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
2302 goto return_exception;
2306 RT_TIMING_GET_TIME(time_attrs);
2308 /* release dump area */
2310 dump_release(dumpsize);
2312 /* revert loading state and class is loaded */
2314 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2316 #if defined(ENABLE_JVMTI)
2317 /* fire Class Prepare JVMTI event */
2320 jvmti_ClassLoadPrepare(true, c);
2323 #if !defined(NDEBUG)
2325 log_message_class("Loading done class: ", c);
2328 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
2329 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
2330 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
2331 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
2332 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
2333 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
2334 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
2335 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
2336 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
2337 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
2338 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
2339 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
2340 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
2341 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
2342 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
2347 /* release dump area */
2349 dump_release(dumpsize);
2351 /* an exception has been thrown */
2357 /* load_newly_created_array ****************************************************
2359 Load a newly created array class.
2362 c....................the array class C has been loaded
2363 other classinfo......the array class was found in the class cache,
2365 NULL.................an exception has been thrown
2368 This is an internal function. Do not use it unless you know exactly
2371 Use one of the load_class_... functions for general array class loading.
2373 *******************************************************************************/
2375 classinfo *load_newly_created_array(classinfo *c, java_objectheader *loader)
2377 classinfo *comp = NULL;
2379 methoddesc *clonedesc;
2380 constant_classref *classrefs;
2385 text = c->name->text;
2386 namelen = c->name->blength;
2388 /* Check array class name */
2390 if (namelen < 2 || text[0] != '[') {
2391 *exceptionptr = new_noclassdeffounderror(c->name);
2395 /* Check the element type */
2399 /* c is an array of arrays. We have to create the component class. */
2401 u = utf_new(text + 1, namelen - 1);
2402 if (!(comp = load_class_from_classloader(u, loader)))
2405 LOADER_ASSERT(comp->state & CLASS_LOADED);
2411 /* the array's flags are that of the component class */
2412 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2413 c->classloader = comp->classloader;
2417 /* c is an array of objects. */
2419 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2420 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
2421 *exceptionptr = new_noclassdeffounderror(c->name);
2425 u = utf_new(text + 2, namelen - 3);
2427 if (!(comp = load_class_from_classloader(u, loader)))
2430 LOADER_ASSERT(comp->state & CLASS_LOADED);
2436 /* the array's flags are that of the component class */
2437 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2438 c->classloader = comp->classloader;
2442 /* c is an array of a primitive type */
2444 /* check for cases like `[II' */
2446 *exceptionptr = new_noclassdeffounderror(c->name);
2450 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2451 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2452 c->classloader = NULL;
2455 LOADER_ASSERT(class_java_lang_Object);
2456 LOADER_ASSERT(class_java_lang_Cloneable);
2457 LOADER_ASSERT(class_java_io_Serializable);
2459 /* setup the array class */
2461 c->super.cls = class_java_lang_Object;
2463 c->interfacescount = 2;
2464 c->interfaces = MNEW(classref_or_classinfo, 2);
2469 tc = class_java_lang_Cloneable;
2470 LOADER_ASSERT(tc->state & CLASS_LOADED);
2471 list_add_first(&unlinkedclasses, tc);
2472 c->interfaces[0].cls = tc;
2474 tc = class_java_io_Serializable;
2475 LOADER_ASSERT(tc->state & CLASS_LOADED);
2476 list_add_first(&unlinkedclasses, tc);
2477 c->interfaces[1].cls = tc;
2480 c->interfaces[0].cls = class_java_lang_Cloneable;
2481 c->interfaces[1].cls = class_java_io_Serializable;
2484 c->methodscount = 1;
2485 c->methods = MNEW(methodinfo, c->methodscount);
2487 classrefs = MNEW(constant_classref, 2);
2488 CLASSREF_INIT(classrefs[0], c, c->name);
2489 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2491 /* create descriptor for clone method */
2492 /* we need one paramslot which is reserved for the 'this' parameter */
2493 clonedesc = NEW(methoddesc);
2494 clonedesc->returntype.type = TYPE_ADR;
2495 clonedesc->returntype.classref = classrefs + 1;
2496 clonedesc->returntype.arraydim = 0;
2497 /* initialize params to "empty", add real params below in
2498 descriptor_params_from_paramtypes */
2499 clonedesc->paramcount = 0;
2500 clonedesc->paramslots = 0;
2501 clonedesc->paramtypes[0].classref = classrefs + 0;
2502 clonedesc->params = NULL;
2504 /* create methodinfo */
2507 MSET(clone, 0, methodinfo, 1);
2509 #if defined(ENABLE_THREADS)
2510 lock_init_object_lock(&clone->header);
2513 /* ATTENTION: if you delete the ACC_NATIVE below, set
2514 clone->maxlocals=1 (interpreter related) */
2516 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2517 clone->name = utf_clone;
2518 clone->descriptor = utf_void__java_lang_Object;
2519 clone->parseddesc = clonedesc;
2522 /* parse the descriptor to get the register allocation */
2524 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2528 codegen_createnativestub((functionptr) &builtin_clone_array, clone);
2530 /* XXX: field: length? */
2532 /* array classes are not loaded from class files */
2534 c->state |= CLASS_LOADED;
2535 c->parseddescs = (u1 *) clonedesc;
2536 c->parseddescsize = sizeof(methodinfo);
2537 c->classrefs = classrefs;
2538 c->classrefcount = 1;
2540 /* insert class into the loaded class cache */
2541 /* XXX free classinfo if NULL returned? */
2543 return classcache_store(loader, c, true);
2547 /* loader_close ****************************************************************
2549 Frees all resources.
2551 *******************************************************************************/
2553 void loader_close(void)
2560 * These are local overrides for various environment variables in Emacs.
2561 * Please do not remove this and leave it at the end of the file, where
2562 * Emacs will automagically detect them.
2563 * ---------------------------------------------------------------------
2566 * indent-tabs-mode: t
2570 * vim:noexpandtab:sw=4:ts=4: