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 4690 2006-03-27 11:37:46Z twisti $
48 #include "mm/memory.h"
49 #include "native/native.h"
50 #include "native/include/java_lang_Throwable.h"
52 #if defined(USE_THREADS)
53 # if defined(NATIVE_THREADS)
54 # include "threads/native/threads.h"
56 # include "threads/green/threads.h"
57 # include "threads/green/locks.h"
61 #include "toolbox/logging.h"
62 #include "vm/builtin.h"
63 #include "vm/classcache.h"
64 #include "vm/exceptions.h"
65 #include "vm/global.h"
66 #include "vm/linker.h"
67 #include "vm/loader.h"
68 #include "vm/options.h"
69 #include "vm/statistics.h"
70 #include "vm/stringlocal.h"
74 #if defined(ENABLE_ZLIB)
78 #include "vm/jit/asmpart.h"
79 #include "vm/jit/codegen-common.h"
82 /******************************************************************************/
84 /******************************************************************************/
91 #define LOADER_ASSERT(cond) assert(cond)
93 #define LOADER_ASSERT(cond)
97 /* loader_init *****************************************************************
99 Initializes all lists and loads all classes required for the system
102 *******************************************************************************/
104 bool loader_init(u1 *stackbottom)
106 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
107 list_classpath_entry *lce;
109 /* Initialize the monitor pointer for zip/jar file locking. */
111 for (lce = list_first(list_classpath_entries); lce != NULL;
112 lce = list_next(list_classpath_entries, lce))
113 if (lce->type == CLASSPATH_ARCHIVE)
114 initObjectLock((java_objectheader *) lce);
117 /* load some important classes */
119 if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
122 if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
125 if (!(class_java_lang_Cloneable =
126 load_class_bootstrap(utf_java_lang_Cloneable)))
129 if (!(class_java_io_Serializable =
130 load_class_bootstrap(utf_java_io_Serializable)))
134 /* load classes for wrapping primitive types */
136 if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
139 if (!(class_java_lang_Boolean =
140 load_class_bootstrap(utf_java_lang_Boolean)))
143 if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
146 if (!(class_java_lang_Character =
147 load_class_bootstrap(utf_java_lang_Character)))
150 if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
153 if (!(class_java_lang_Integer =
154 load_class_bootstrap(utf_java_lang_Integer)))
157 if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
160 if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
163 if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
167 /* load some other important classes */
169 if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
172 if (!(class_java_lang_ClassLoader =
173 load_class_bootstrap(utf_java_lang_ClassLoader)))
176 if (!(class_java_lang_SecurityManager =
177 load_class_bootstrap(utf_java_lang_SecurityManager)))
180 if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
183 if (!(class_java_lang_Thread =
184 load_class_bootstrap(utf_new_char("java/lang/Thread"))))
187 if (!(class_java_lang_ThreadGroup =
188 load_class_bootstrap(utf_java_lang_ThreadGroup)))
191 if (!(class_java_lang_VMThread =
192 load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
196 /* some classes which may be used more often */
198 if (!(class_java_lang_StackTraceElement =
199 load_class_bootstrap(utf_java_lang_StackTraceElement)))
202 if (!(class_java_lang_reflect_Constructor =
203 load_class_bootstrap(utf_java_lang_reflect_Constructor)))
206 if (!(class_java_lang_reflect_Field =
207 load_class_bootstrap(utf_java_lang_reflect_Field)))
210 if (!(class_java_lang_reflect_Method =
211 load_class_bootstrap(utf_java_lang_reflect_Method)))
214 if (!(class_java_security_PrivilegedAction =
215 load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
218 if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
221 if (!(arrayclass_java_lang_Object =
222 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
225 #if defined(USE_THREADS)
226 if (stackbottom != 0)
234 /* loader_load_all_classes *****************************************************
236 Loads all classes specified in the BOOTCLASSPATH.
238 *******************************************************************************/
240 void loader_load_all_classes(void)
242 list_classpath_entry *lce;
243 #if defined(ENABLE_ZLIB)
246 hashtable_zipfile_entry *htzfe;
250 for (lce = list_first(list_classpath_entries); lce != NULL;
251 lce = list_next(list_classpath_entries, lce)) {
252 #if defined(ENABLE_ZLIB)
253 if (lce->type == CLASSPATH_ARCHIVE) {
254 /* get the classes hashtable */
258 for (slot = 0; slot < ht->size; slot++) {
259 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
261 for (; htzfe; htzfe = htzfe->hashlink) {
264 /* skip all entries in META-INF and .properties,
267 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
268 strstr(u->text, ".properties") ||
269 strstr(u->text, ".png"))
272 /* load class from bootstrap classloader */
274 if (!load_class_bootstrap(u)) {
275 fprintf(stderr, "Error loading: ");
276 utf_fprint_classname(stderr, u);
277 fprintf(stderr, "\n");
280 /* print out exception and cause */
282 exceptions_print_exception(*exceptionptr);
290 #if defined(ENABLE_ZLIB)
297 /* skipattributebody ***********************************************************
299 Skips an attribute after the 16 bit reference to attribute_name has
302 *******************************************************************************/
304 static bool skipattributebody(classbuffer *cb)
308 if (!suck_check_classbuffer_size(cb, 4))
313 if (!suck_check_classbuffer_size(cb, len))
316 suck_skip_nbytes(cb, len);
322 /************************* Function: skipattributes ****************************
324 skips num attribute structures
326 *******************************************************************************/
328 static bool skipattributes(classbuffer *cb, u4 num)
333 for (i = 0; i < num; i++) {
334 if (!suck_check_classbuffer_size(cb, 2 + 4))
340 if (!suck_check_classbuffer_size(cb, len))
343 suck_skip_nbytes(cb, len);
350 /* load_constantpool ***********************************************************
352 Loads the constantpool of a class, the entries are transformed into
353 a simpler format by resolving references (a detailed overview of
354 the compact structures can be found in global.h).
356 *******************************************************************************/
358 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
361 /* The following structures are used to save information which cannot be
362 processed during the first pass. After the complete constantpool has
363 been traversed the references can be resolved.
364 (only in specific order) */
366 /* CONSTANT_Class entries */
367 typedef struct forward_class {
368 struct forward_class *next;
373 /* CONSTANT_String */
374 typedef struct forward_string {
375 struct forward_string *next;
380 /* CONSTANT_NameAndType */
381 typedef struct forward_nameandtype {
382 struct forward_nameandtype *next;
386 } forward_nameandtype;
388 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
389 typedef struct forward_fieldmethint {
390 struct forward_fieldmethint *next;
394 u2 nameandtype_index;
395 } forward_fieldmethint;
401 forward_class *forward_classes = NULL;
402 forward_string *forward_strings = NULL;
403 forward_nameandtype *forward_nameandtypes = NULL;
404 forward_fieldmethint *forward_fieldmethints = NULL;
408 forward_nameandtype *nfn;
409 forward_fieldmethint *nff;
417 /* number of entries in the constant_pool table plus one */
418 if (!suck_check_classbuffer_size(cb, 2))
421 cpcount = c->cpcount = suck_u2(cb);
423 /* allocate memory */
424 cptags = c->cptags = MNEW(u1, cpcount);
425 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
428 exceptions_throw_classformaterror(c, "Illegal constant pool size");
432 #if defined(ENABLE_STATISTICS)
434 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
437 /* initialize constantpool */
438 for (idx = 0; idx < cpcount; idx++) {
439 cptags[idx] = CONSTANT_UNUSED;
444 /******* first pass *******/
445 /* entries which cannot be resolved now are written into
446 temporary structures and traversed again later */
449 while (idx < cpcount) {
452 /* get constant type */
453 if (!suck_check_classbuffer_size(cb, 1))
460 nfc = DNEW(forward_class);
462 nfc->next = forward_classes;
463 forward_classes = nfc;
465 nfc->thisindex = idx;
466 /* reference to CONSTANT_NameAndType */
467 if (!suck_check_classbuffer_size(cb, 2))
470 nfc->name_index = suck_u2(cb);
475 case CONSTANT_String:
476 nfs = DNEW(forward_string);
478 nfs->next = forward_strings;
479 forward_strings = nfs;
481 nfs->thisindex = idx;
483 /* reference to CONSTANT_Utf8_info with string characters */
484 if (!suck_check_classbuffer_size(cb, 2))
487 nfs->string_index = suck_u2(cb);
492 case CONSTANT_NameAndType:
493 nfn = DNEW(forward_nameandtype);
495 nfn->next = forward_nameandtypes;
496 forward_nameandtypes = nfn;
498 nfn->thisindex = idx;
500 if (!suck_check_classbuffer_size(cb, 2 + 2))
503 /* reference to CONSTANT_Utf8_info containing simple name */
504 nfn->name_index = suck_u2(cb);
506 /* reference to CONSTANT_Utf8_info containing field or method
508 nfn->sig_index = suck_u2(cb);
513 case CONSTANT_Fieldref:
514 case CONSTANT_Methodref:
515 case CONSTANT_InterfaceMethodref:
516 nff = DNEW(forward_fieldmethint);
518 nff->next = forward_fieldmethints;
519 forward_fieldmethints = nff;
521 nff->thisindex = idx;
525 if (!suck_check_classbuffer_size(cb, 2 + 2))
528 /* class or interface type that contains the declaration of the
530 nff->class_index = suck_u2(cb);
532 /* name and descriptor of the field or method */
533 nff->nameandtype_index = suck_u2(cb);
538 case CONSTANT_Integer: {
539 constant_integer *ci = NEW(constant_integer);
541 #if defined(ENABLE_STATISTICS)
543 count_const_pool_len += sizeof(constant_integer);
546 if (!suck_check_classbuffer_size(cb, 4))
549 ci->value = suck_s4(cb);
550 cptags[idx] = CONSTANT_Integer;
557 case CONSTANT_Float: {
558 constant_float *cf = NEW(constant_float);
560 #if defined(ENABLE_STATISTICS)
562 count_const_pool_len += sizeof(constant_float);
565 if (!suck_check_classbuffer_size(cb, 4))
568 cf->value = suck_float(cb);
569 cptags[idx] = CONSTANT_Float;
576 case CONSTANT_Long: {
577 constant_long *cl = NEW(constant_long);
579 #if defined(ENABLE_STATISTICS)
581 count_const_pool_len += sizeof(constant_long);
584 if (!suck_check_classbuffer_size(cb, 8))
587 cl->value = suck_s8(cb);
588 cptags[idx] = CONSTANT_Long;
592 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
598 case CONSTANT_Double: {
599 constant_double *cd = NEW(constant_double);
601 #if defined(ENABLE_STATISTICS)
603 count_const_pool_len += sizeof(constant_double);
606 if (!suck_check_classbuffer_size(cb, 8))
609 cd->value = suck_double(cb);
610 cptags[idx] = CONSTANT_Double;
614 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
620 case CONSTANT_Utf8: {
623 /* number of bytes in the bytes array (not string-length) */
624 if (!suck_check_classbuffer_size(cb, 2))
627 length = suck_u2(cb);
628 cptags[idx] = CONSTANT_Utf8;
630 /* validate the string */
631 if (!suck_check_classbuffer_size(cb, length))
634 #ifdef ENABLE_VERIFIER
636 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
638 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
641 #endif /* ENABLE_VERIFIER */
642 /* insert utf-string into the utf-symboltable */
643 cpinfos[idx] = utf_new((char *) cb->pos, length);
645 /* skip bytes of the string (buffer size check above) */
646 suck_skip_nbytes(cb, length);
652 exceptions_throw_classformaterror(c, "Illegal constant pool type");
658 /* resolve entries in temporary structures */
660 while (forward_classes) {
662 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
666 #ifdef ENABLE_VERIFIER
667 if (opt_verify && !is_valid_name_utf(name)) {
668 exceptions_throw_classformaterror(c, "Class reference with invalid name");
671 #endif /* ENABLE_VERIFIER */
673 /* add all class references to the descriptor_pool */
675 if (!descriptor_pool_add_class(descpool, name))
678 cptags[forward_classes->thisindex] = CONSTANT_Class;
683 if (!(tc = load_class_bootstrap(name)))
686 /* link the class later, because we cannot link the class currently
688 list_addfirst(&unlinkedclasses, tc);
691 /* the classref is created later */
692 cpinfos[forward_classes->thisindex] = name;
694 nfc = forward_classes;
695 forward_classes = forward_classes->next;
698 while (forward_strings) {
700 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
704 /* resolve utf-string */
705 cptags[forward_strings->thisindex] = CONSTANT_String;
706 cpinfos[forward_strings->thisindex] = text;
708 nfs = forward_strings;
709 forward_strings = forward_strings->next;
712 while (forward_nameandtypes) {
713 constant_nameandtype *cn = NEW(constant_nameandtype);
715 #if defined(ENABLE_STATISTICS)
717 count_const_pool_len += sizeof(constant_nameandtype);
720 /* resolve simple name and descriptor */
721 cn->name = class_getconstant(c,
722 forward_nameandtypes->name_index,
727 cn->descriptor = class_getconstant(c,
728 forward_nameandtypes->sig_index,
733 #ifdef ENABLE_VERIFIER
736 if (!is_valid_name_utf(cn->name)) {
737 exceptions_throw_classformaterror(c,
738 "Illegal Field name \"%s\"",
744 /* disallow referencing <clinit> among others */
745 if (cn->name->text[0] == '<' && cn->name != utf_init) {
746 exceptions_throw_classformaterror(c, "Illegal reference to special method");
750 #endif /* ENABLE_VERIFIER */
752 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
753 cpinfos[forward_nameandtypes->thisindex] = cn;
755 nfn = forward_nameandtypes;
756 forward_nameandtypes = forward_nameandtypes->next;
759 while (forward_fieldmethints) {
760 constant_nameandtype *nat;
761 constant_FMIref *fmi = NEW(constant_FMIref);
763 #if defined(ENABLE_STATISTICS)
765 count_const_pool_len += sizeof(constant_FMIref);
767 /* resolve simple name and descriptor */
769 nat = class_getconstant(c,
770 forward_fieldmethints->nameandtype_index,
771 CONSTANT_NameAndType);
775 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
777 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
780 /* the classref is created later */
782 fmi->classref = (constant_classref *) (size_t) forward_fieldmethints->class_index;
783 fmi->name = nat->name;
784 fmi->descriptor = nat->descriptor;
786 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
787 cpinfos[forward_fieldmethints->thisindex] = fmi;
789 nff = forward_fieldmethints;
790 forward_fieldmethints = forward_fieldmethints->next;
793 /* everything was ok */
799 /* load_field ******************************************************************
801 Load everything about a class field from the class file and fill a
802 'fieldinfo' structure. For static fields, space in the data segment
805 *******************************************************************************/
807 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
809 static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
814 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
819 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
822 f->flags = suck_u2(cb);
824 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
829 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
833 f->parseddesc = NULL;
835 if (!descriptor_pool_add(descpool, u, NULL))
838 /* descriptor_pool_add accepts method descriptors, so we have to check */
839 /* against them here before the call of descriptor_to_basic_type below. */
840 if (u->text[0] == '(') {
841 exceptions_throw_classformaterror(c, "Method descriptor used for field");
845 #ifdef ENABLE_VERIFIER
848 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<') {
849 exceptions_throw_classformaterror(c,
850 "Illegal Field name \"%s\"",
855 /* check flag consistency */
856 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
858 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
859 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
860 exceptions_throw_classformaterror(c,
861 "Illegal field modifiers: 0x%X",
866 if (c->flags & ACC_INTERFACE) {
867 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
868 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
869 f->flags & ACC_TRANSIENT) {
870 exceptions_throw_classformaterror(c,
871 "Illegal field modifiers: 0x%X",
877 #endif /* ENABLE_VERIFIER */
879 f->type = jtype = descriptor_to_basic_type(f->descriptor); /* data type */
880 f->offset = 0; /* offset from start of object */
884 case TYPE_INT: f->value.i = 0; break;
885 case TYPE_FLOAT: f->value.f = 0.0; break;
886 case TYPE_DOUBLE: f->value.d = 0.0; break;
887 case TYPE_ADDRESS: f->value.a = NULL; break;
890 f->value.l = 0; break;
892 f->value.l.low = 0; f->value.l.high = 0; break;
896 /* read attributes */
897 if (!suck_check_classbuffer_size(cb, 2))
900 attrnum = suck_u2(cb);
901 for (i = 0; i < attrnum; i++) {
902 if (!suck_check_classbuffer_size(cb, 2))
905 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
908 if (u == utf_ConstantValue) {
909 if (!suck_check_classbuffer_size(cb, 4 + 2))
912 /* check attribute length */
913 if (suck_u4(cb) != 2) {
914 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
918 /* constant value attribute */
919 if (pindex != field_load_NOVALUE) {
920 exceptions_throw_classformaterror(c, "Multiple ConstantValue attributes");
924 /* index of value in constantpool */
925 pindex = suck_u2(cb);
927 /* initialize field with value from constantpool */
930 constant_integer *ci;
932 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
935 f->value.i = ci->value;
942 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
945 f->value.l = cl->value;
952 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
955 f->value.f = cf->value;
962 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
965 f->value.d = cd->value;
970 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
973 /* create javastring from compressed utf8-string */
974 f->value.a = literalstring_new(u);
978 log_text("Invalid Constant - Type");
982 /* unknown attribute */
983 if (!skipattributebody(cb))
988 /* everything was ok */
994 /* load_method *****************************************************************
996 Loads a method from the class file and fills an existing
997 'methodinfo' structure. For native methods, the function pointer
998 field is set to the real function pointer, for JavaVM methods a
999 pointer to the compiler is used preliminarily.
1001 *******************************************************************************/
1003 static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpool)
1014 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1015 initObjectLock(&m->header);
1018 #if defined(ENABLE_STATISTICS)
1020 count_all_methods++;
1023 m->thrownexceptionscount = 0;
1024 m->linenumbercount = 0;
1028 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
1031 m->flags = suck_u2(cb);
1033 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1038 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1042 m->parseddesc = NULL;
1044 if (!descriptor_pool_add(descpool, u, &argcount))
1047 #ifdef ENABLE_VERIFIER
1049 if (!is_valid_name_utf(m->name)) {
1050 exceptions_throw_classformaterror(c, "Method with invalid name");
1054 if (m->name->text[0] == '<' &&
1055 m->name != utf_init && m->name != utf_clinit) {
1056 exceptions_throw_classformaterror(c, "Method with invalid special name");
1060 #endif /* ENABLE_VERIFIER */
1062 if (!(m->flags & ACC_STATIC))
1063 argcount++; /* count the 'this' argument */
1065 #ifdef ENABLE_VERIFIER
1067 if (argcount > 255) {
1068 exceptions_throw_classformaterror(c, "Too many arguments in signature");
1072 /* check flag consistency */
1073 if (m->name != utf_clinit) {
1074 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1076 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1077 exceptions_throw_classformaterror(c,
1078 "Illegal method modifiers: 0x%X",
1083 if (m->flags & ACC_ABSTRACT) {
1084 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1085 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1086 exceptions_throw_classformaterror(c,
1087 "Illegal method modifiers: 0x%X",
1093 if (c->flags & ACC_INTERFACE) {
1094 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1095 exceptions_throw_classformaterror(c,
1096 "Illegal method modifiers: 0x%X",
1102 if (m->name == utf_init) {
1103 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1104 ACC_NATIVE | ACC_ABSTRACT)) {
1105 exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
1111 #endif /* ENABLE_VERIFIER */
1114 m->basicblockcount = 0;
1115 m->basicblocks = NULL;
1116 m->basicblockindex = NULL;
1117 m->instructioncount = 0;
1118 m->instructions = NULL;
1121 m->exceptiontable = NULL;
1122 m->stubroutine = NULL;
1125 if (!suck_check_classbuffer_size(cb, 2))
1128 attrnum = suck_u2(cb);
1129 for (i = 0; i < attrnum; i++) {
1132 if (!suck_check_classbuffer_size(cb, 2))
1135 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1138 if (aname == utf_Code) {
1139 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1140 exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
1145 exceptions_throw_classformaterror(c, "Multiple Code attributes");
1149 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1153 m->maxstack = suck_u2(cb);
1154 m->maxlocals = suck_u2(cb);
1156 if (m->maxlocals < argcount) {
1157 exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
1161 if (!suck_check_classbuffer_size(cb, 4))
1164 m->jcodelength = suck_u4(cb);
1166 if (m->jcodelength == 0) {
1167 exceptions_throw_classformaterror(c, "Code of a method has length 0");
1171 if (m->jcodelength > 65535) {
1172 exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
1176 if (!suck_check_classbuffer_size(cb, m->jcodelength))
1179 m->jcode = MNEW(u1, m->jcodelength);
1180 suck_nbytes(m->jcode, cb, m->jcodelength);
1182 if (!suck_check_classbuffer_size(cb, 2))
1185 m->exceptiontablelength = suck_u2(cb);
1186 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->exceptiontablelength))
1189 m->exceptiontable = MNEW(exceptiontable, m->exceptiontablelength);
1191 #if defined(ENABLE_STATISTICS)
1193 count_vmcode_len += m->jcodelength + 18;
1194 count_extable_len +=
1195 m->exceptiontablelength * sizeof(exceptiontable);
1199 for (j = 0; j < m->exceptiontablelength; j++) {
1201 m->exceptiontable[j].startpc = suck_u2(cb);
1202 m->exceptiontable[j].endpc = suck_u2(cb);
1203 m->exceptiontable[j].handlerpc = suck_u2(cb);
1207 m->exceptiontable[j].catchtype.any = NULL;
1210 /* the classref is created later */
1211 if (!(m->exceptiontable[j].catchtype.any =
1212 (utf*)class_getconstant(c, idx, CONSTANT_Class)))
1217 if (!suck_check_classbuffer_size(cb, 2))
1220 codeattrnum = suck_u2(cb);
1222 for (; codeattrnum > 0; codeattrnum--) {
1225 if (!suck_check_classbuffer_size(cb, 2))
1228 if (!(caname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1231 if (caname == utf_LineNumberTable) {
1234 if (!suck_check_classbuffer_size(cb, 4 + 2))
1238 m->linenumbercount = suck_u2(cb);
1240 if (!suck_check_classbuffer_size(cb,
1241 (2 + 2) * m->linenumbercount))
1244 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1246 for (lncid = 0; lncid < m->linenumbercount; lncid++) {
1247 m->linenumbers[lncid].start_pc = suck_u2(cb);
1248 m->linenumbers[lncid].line_number = suck_u2(cb);
1252 if (!skipattributes(cb, codeattrnum))
1258 if (!skipattributebody(cb))
1263 } else if (aname == utf_Exceptions) {
1266 if (m->thrownexceptions) {
1267 exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
1271 if (!suck_check_classbuffer_size(cb, 4 + 2))
1274 suck_u4(cb); /* length */
1275 m->thrownexceptionscount = suck_u2(cb);
1277 if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1280 m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
1282 for (j = 0; j < m->thrownexceptionscount; j++) {
1283 /* the classref is created later */
1284 if (!((m->thrownexceptions)[j].any =
1285 (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1290 if (!skipattributebody(cb))
1295 if (!m->jcode && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1296 exceptions_throw_classformaterror(c, "Missing Code attribute");
1300 /* everything was ok */
1306 /* load_attribute **************************************************************
1308 Read attributes from classfile.
1310 *******************************************************************************/
1312 static bool load_attributes(classbuffer *cb, u4 num)
1320 for (i = 0; i < num; i++) {
1321 /* retrieve attribute name */
1322 if (!suck_check_classbuffer_size(cb, 2))
1325 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1328 if (aname == utf_InnerClasses) {
1329 /* innerclasses attribute */
1330 if (c->innerclass) {
1331 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
1335 if (!suck_check_classbuffer_size(cb, 4 + 2))
1338 /* skip attribute length */
1341 /* number of records */
1342 c->innerclasscount = suck_u2(cb);
1344 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
1347 /* allocate memory for innerclass structure */
1348 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
1350 for (j = 0; j < c->innerclasscount; j++) {
1351 /* The innerclass structure contains a class with an encoded
1352 name, its defining scope, its simple name and a bitmask of
1353 the access flags. If an inner class is not a member, its
1354 outer_class is NULL, if a class is anonymous, its name is
1357 innerclassinfo *info = c->innerclass + j;
1359 info->inner_class.ref =
1360 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
1361 info->outer_class.ref =
1362 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
1364 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1365 info->flags = suck_u2(cb);
1368 } else if (aname == utf_SourceFile) {
1369 if (!suck_check_classbuffer_size(cb, 4 + 2))
1372 if (suck_u4(cb) != 2) {
1373 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
1377 if (c->sourcefile) {
1378 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
1382 if (!(c->sourcefile = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1386 /* unknown attribute */
1387 if (!skipattributebody(cb))
1396 /* load_class_from_sysloader ***************************************************
1398 Load the class with the given name using the system class loader
1401 name.............the classname
1404 the loaded class, or
1405 NULL if an exception has been thrown
1407 *******************************************************************************/
1409 classinfo *load_class_from_sysloader(utf *name)
1412 java_objectheader *cl;
1415 LOADER_ASSERT(class_java_lang_Object);
1416 LOADER_ASSERT(class_java_lang_ClassLoader);
1417 LOADER_ASSERT(class_java_lang_ClassLoader->state & CLASS_LINKED);
1419 m = class_resolveclassmethod(class_java_lang_ClassLoader,
1420 utf_getSystemClassLoader,
1421 utf_void__java_lang_ClassLoader,
1422 class_java_lang_Object,
1428 cl = vm_call_method(m, NULL);
1433 c = load_class_from_classloader(name, cl);
1439 /* load_class_from_classloader *************************************************
1441 Load the class with the given name using the given user-defined class loader.
1444 name.............the classname
1445 cl...............user-defined class loader
1448 the loaded class, or
1449 NULL if an exception has been thrown
1451 *******************************************************************************/
1453 classinfo *load_class_from_classloader(utf *name, java_objectheader *cl)
1455 java_objectheader *o;
1458 java_lang_String *s;
1460 LOADER_ASSERT(name);
1462 /* lookup if this class has already been loaded */
1464 c = classcache_lookup(cl, name);
1469 /* if other class loader than bootstrap, call it */
1477 namelen = name->blength;
1479 /* handle array classes */
1480 if (text[0] == '[') {
1486 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1487 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1488 *exceptionptr = new_noclassdeffounderror(name);
1492 u = utf_new(text + 2, namelen - 3);
1494 if (!(comp = load_class_from_classloader(u, cl)))
1497 /* create the array class */
1499 c = class_array_of(comp, false);
1501 tmpc = classcache_store(cl, c, true);
1504 /* exception, free the loaded class */
1505 c->state &= ~CLASS_LOADING;
1512 /* load the component class */
1514 u = utf_new(text + 1, namelen - 1);
1516 if (!(comp = load_class_from_classloader(u, cl)))
1519 /* create the array class */
1521 c = class_array_of(comp, false);
1523 tmpc = classcache_store(cl, c, true);
1526 /* exception, free the loaded class */
1527 c->state &= ~CLASS_LOADING;
1534 /* primitive array classes are loaded by the bootstrap loader */
1536 c = load_class_bootstrap(name);
1542 LOADER_ASSERT(class_java_lang_Object);
1544 lc = class_resolveclassmethod(cl->vftbl->class,
1546 utf_java_lang_String__java_lang_Class,
1547 class_java_lang_Object,
1551 return false; /* exception */
1553 /* move return value into `o' and cast it afterwards to a classinfo* */
1555 s = javastring_new_slash_to_dot(name);
1557 o = vm_call_method(lc, cl, s);
1559 c = (classinfo *) o;
1562 /* Store this class in the loaded class cache. If another
1563 class with the same (initloader,name) pair has been
1564 stored earlier it will be returned by classcache_store
1565 In this case classcache_store may not free the class
1566 because it has already been exposed to Java code which
1567 may have kept references to that class. */
1569 tmpc = classcache_store(cl, c, false);
1572 /* exception, free the loaded class */
1573 c->state &= ~CLASS_LOADING;
1580 /* loadClass has thrown an exception. We must convert
1581 ClassNotFoundException into
1582 NoClassDefFoundException. */
1584 /* XXX Maybe we should have a flag that avoids this
1585 conversion for calling load_class_from_classloader from
1586 Class.forName. Currently we do a double conversion in
1589 classnotfoundexception_to_noclassdeffounderror();
1592 /* SUN compatible -verbose:class output */
1594 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1596 utf_display_classname(name);
1603 c = load_class_bootstrap(name);
1609 /* load_class_bootstrap ********************************************************
1611 Load the class with the given name using the bootstrap class loader.
1614 name.............the classname
1617 loaded classinfo, or
1618 NULL if an exception has been thrown
1621 load_class_bootstrap is synchronized. It can be treated as an
1624 *******************************************************************************/
1626 classinfo *load_class_bootstrap(utf *name)
1634 LOADER_ASSERT(name);
1636 /* lookup if this class has already been loaded */
1638 if ((r = classcache_lookup(NULL, name)))
1641 /* create the classinfo */
1643 c = class_create_classinfo(name);
1645 /* handle array classes */
1647 if (name->text[0] == '[') {
1648 c = load_newly_created_array(c, NULL);
1651 LOADER_ASSERT(c->state & CLASS_LOADED);
1655 #if defined(ENABLE_STATISTICS)
1658 if (getcompilingtime)
1659 compilingtime_stop();
1662 loadingtime_start();
1665 /* load classdata, throw exception on error */
1667 if ((cb = suck_start(c)) == NULL) {
1668 /* this normally means, the classpath was not set properly */
1670 if (name == utf_java_lang_Object)
1671 throw_cacao_exception_exit(string_java_lang_NoClassDefFoundError,
1672 "java/lang/Object");
1674 *exceptionptr = new_noclassdeffounderror(name);
1679 /* load the class from the buffer */
1681 r = load_class_from_classbuffer(cb);
1684 /* the class could not be loaded, free the classinfo struct */
1689 /* Store this class in the loaded class cache this step also
1690 checks the loading constraints. If the class has been loaded
1691 before, the earlier loaded class is returned. */
1693 classinfo *res = classcache_store(NULL, c, true);
1703 /* SUN compatible -verbose:class output */
1705 if (opt_verboseclass && r) {
1707 utf_display_classname(name);
1708 printf(" from %s]\n", cb->path);
1715 #if defined(ENABLE_STATISTICS)
1721 if (getcompilingtime)
1722 compilingtime_start();
1729 /* load_class_from_classbuffer *************************************************
1731 Loads everything interesting about a class from the class file. The
1732 'classinfo' structure must have been allocated previously.
1734 The super class and the interfaces implemented by this class need
1735 not be loaded. The link is set later by the function 'class_link'.
1737 The loaded class is removed from the list 'unloadedclasses' and
1738 added to the list 'unlinkedclasses'.
1741 This function is NOT synchronized!
1743 *******************************************************************************/
1745 classinfo *load_class_from_classbuffer(classbuffer *cb)
1753 descriptor_pool *descpool;
1754 #if defined(ENABLE_STATISTICS)
1759 /* get the classbuffer's class */
1763 /* the class is already loaded */
1765 if (c->state & CLASS_LOADED)
1768 #if defined(ENABLE_STATISTICS)
1770 count_class_loads++;
1773 #if !defined(NDEBUG)
1774 /* output for debugging purposes */
1777 log_message_class("Loading class: ", c);
1780 /* mark start of dump memory area */
1782 dumpsize = dump_size();
1784 /* class is currently loading */
1786 c->state |= CLASS_LOADING;
1788 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1789 goto return_exception;
1791 /* check signature */
1793 if (suck_u4(cb) != MAGIC) {
1794 exceptions_throw_classformaterror(c, "Bad magic number");
1796 goto return_exception;
1804 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1806 new_unsupportedclassversionerror(c,
1807 "Unsupported major.minor version %d.%d",
1810 goto return_exception;
1813 /* create a new descriptor pool */
1815 descpool = descriptor_pool_new(c);
1817 /* load the constant pool */
1819 if (!load_constantpool(cb, descpool))
1820 goto return_exception;
1824 if (!suck_check_classbuffer_size(cb, 2))
1825 goto return_exception;
1827 c->flags = suck_u2(cb);
1829 /* check ACC flags consistency */
1831 if (c->flags & ACC_INTERFACE) {
1832 if (!(c->flags & ACC_ABSTRACT)) {
1833 /* We work around this because interfaces in JDK 1.1 are
1834 * not declared abstract. */
1836 c->flags |= ACC_ABSTRACT;
1839 if (c->flags & ACC_FINAL) {
1840 exceptions_throw_classformaterror(c,
1841 "Illegal class modifiers: 0x%X",
1843 goto return_exception;
1846 if (c->flags & ACC_SUPER) {
1847 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1851 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1852 exceptions_throw_classformaterror(c,
1853 "Illegal class modifiers: 0x%X",
1855 goto return_exception;
1858 if (!suck_check_classbuffer_size(cb, 2 + 2))
1859 goto return_exception;
1864 if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1865 goto return_exception;
1867 if (c->name == utf_not_named_yet) {
1868 /* we finally have a name for this class */
1870 class_set_packagename(c);
1872 } else if (name != c->name) {
1876 msglen = utf_strlen(c->name) + strlen(" (wrong name: ") +
1877 utf_strlen(name) + strlen(")") + strlen("0");
1879 msg = MNEW(char, msglen);
1881 utf_sprint(msg, c->name);
1882 strcat(msg, " (wrong name: ");
1883 utf_strcat(msg, name);
1887 new_exception_message(string_java_lang_NoClassDefFoundError, msg);
1889 MFREE(msg, char, msglen);
1891 goto return_exception;
1894 /* retrieve superclass */
1896 c->super.any = NULL;
1897 if ((i = suck_u2(cb))) {
1898 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1899 goto return_exception;
1901 /* java.lang.Object may not have a super class. */
1903 if (c->name == utf_java_lang_Object) {
1905 new_exception_message(string_java_lang_ClassFormatError,
1906 "java.lang.Object with superclass");
1908 goto return_exception;
1911 /* Interfaces must have java.lang.Object as super class. */
1913 if ((c->flags & ACC_INTERFACE) &&
1914 supername != utf_java_lang_Object) {
1916 new_exception_message(string_java_lang_ClassFormatError,
1917 "Interfaces must have java.lang.Object as superclass");
1919 goto return_exception;
1925 /* This is only allowed for java.lang.Object. */
1927 if (c->name != utf_java_lang_Object) {
1928 exceptions_throw_classformaterror(c, "Bad superclass index");
1929 goto return_exception;
1933 /* retrieve interfaces */
1935 if (!suck_check_classbuffer_size(cb, 2))
1936 goto return_exception;
1938 c->interfacescount = suck_u2(cb);
1940 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1941 goto return_exception;
1943 c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
1944 for (i = 0; i < c->interfacescount; i++) {
1945 /* the classrefs are created later */
1946 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1947 goto return_exception;
1951 if (!suck_check_classbuffer_size(cb, 2))
1952 goto return_exception;
1954 c->fieldscount = suck_u2(cb);
1955 c->fields = GCNEW_UNCOLLECTABLE(fieldinfo, c->fieldscount);
1956 /* c->fields = MNEW(fieldinfo, c->fieldscount); */
1957 for (i = 0; i < c->fieldscount; i++) {
1958 if (!load_field(cb, &(c->fields[i]),descpool))
1959 goto return_exception;
1963 if (!suck_check_classbuffer_size(cb, 2))
1964 goto return_exception;
1966 c->methodscount = suck_u2(cb);
1967 /* c->methods = GCNEW(methodinfo, c->methodscount); */
1968 c->methods = MNEW(methodinfo, c->methodscount);
1969 for (i = 0; i < c->methodscount; i++) {
1970 if (!load_method(cb, &(c->methods[i]),descpool))
1971 goto return_exception;
1974 /* create the class reference table */
1977 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
1979 /* allocate space for the parsed descriptors */
1981 descriptor_pool_alloc_parsed_descriptors(descpool);
1983 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
1985 #if defined(ENABLE_STATISTICS)
1987 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
1988 count_classref_len += classrefsize;
1989 count_parsed_desc_len += descsize;
1993 /* put the classrefs in the constant pool */
1994 for (i = 0; i < c->cpcount; i++) {
1995 if (c->cptags[i] == CONSTANT_Class) {
1996 utf *name = (utf *) c->cpinfos[i];
1997 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
2001 /* set the super class reference */
2004 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
2006 goto return_exception;
2009 /* set the super interfaces references */
2011 for (i = 0; i < c->interfacescount; i++) {
2012 c->interfaces[i].ref =
2013 descriptor_pool_lookup_classref(descpool,
2014 (utf *) c->interfaces[i].any);
2015 if (!c->interfaces[i].ref)
2016 goto return_exception;
2019 /* parse field descriptors */
2021 for (i = 0; i < c->fieldscount; i++) {
2022 c->fields[i].parseddesc =
2023 descriptor_pool_parse_field_descriptor(descpool,
2024 c->fields[i].descriptor);
2025 if (!c->fields[i].parseddesc)
2026 goto return_exception;
2029 /* parse method descriptors */
2031 for (i = 0; i < c->methodscount; i++) {
2032 methodinfo *m = &c->methods[i];
2034 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
2035 m->flags, class_get_self_classref(m->class));
2037 goto return_exception;
2039 for (j = 0; j < m->exceptiontablelength; j++) {
2040 if (!m->exceptiontable[j].catchtype.any)
2042 if ((m->exceptiontable[j].catchtype.ref =
2043 descriptor_pool_lookup_classref(descpool,
2044 (utf *) m->exceptiontable[j].catchtype.any)) == NULL)
2045 goto return_exception;
2048 for (j = 0; j < m->thrownexceptionscount; j++) {
2049 if (!m->thrownexceptions[j].any)
2051 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
2052 (utf *) m->thrownexceptions[j].any)) == NULL)
2053 goto return_exception;
2057 /* parse the loaded descriptors */
2059 for (i = 0; i < c->cpcount; i++) {
2060 constant_FMIref *fmi;
2063 switch (c->cptags[i]) {
2064 case CONSTANT_Fieldref:
2065 fmi = (constant_FMIref *) c->cpinfos[i];
2066 fmi->parseddesc.fd =
2067 descriptor_pool_parse_field_descriptor(descpool,
2069 if (!fmi->parseddesc.fd)
2070 goto return_exception;
2071 index = (int) (size_t) fmi->classref;
2073 (constant_classref *) class_getconstant(c, index,
2076 goto return_exception;
2078 case CONSTANT_Methodref:
2079 case CONSTANT_InterfaceMethodref:
2080 fmi = (constant_FMIref *) c->cpinfos[i];
2081 index = (int) (size_t) fmi->classref;
2083 (constant_classref *) class_getconstant(c, index,
2086 goto return_exception;
2087 fmi->parseddesc.md =
2088 descriptor_pool_parse_method_descriptor(descpool,
2092 if (!fmi->parseddesc.md)
2093 goto return_exception;
2098 #ifdef ENABLE_VERIFIER
2099 /* Check if all fields and methods can be uniquely
2100 * identified by (name,descriptor). */
2103 /* We use a hash table here to avoid making the
2104 * average case quadratic in # of methods, fields.
2106 static int shift = 0;
2108 u2 *next; /* for chaining colliding hash entries */
2114 /* Allocate hashtable */
2115 len = c->methodscount;
2116 if (len < c->fieldscount) len = c->fieldscount;
2118 hashtab = MNEW(u2,(hashlen + len));
2119 next = hashtab + hashlen;
2121 /* Determine bitshift (to get good hash values) */
2131 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2133 for (i = 0; i < c->fieldscount; ++i) {
2134 fieldinfo *fi = c->fields + i;
2136 /* It's ok if we lose bits here */
2137 index = ((((size_t) fi->name) +
2138 ((size_t) fi->descriptor)) >> shift) % hashlen;
2140 if ((old = hashtab[index])) {
2144 if (c->fields[old].name == fi->name &&
2145 c->fields[old].descriptor == fi->descriptor) {
2146 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
2147 goto return_exception;
2149 } while ((old = next[old]));
2151 hashtab[index] = i + 1;
2155 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2157 for (i = 0; i < c->methodscount; ++i) {
2158 methodinfo *mi = c->methods + i;
2160 /* It's ok if we lose bits here */
2161 index = ((((size_t) mi->name) +
2162 ((size_t) mi->descriptor)) >> shift) % hashlen;
2166 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2167 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2171 if ((old = hashtab[index])) {
2175 if (c->methods[old].name == mi->name &&
2176 c->methods[old].descriptor == mi->descriptor) {
2177 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
2178 goto return_exception;
2180 } while ((old = next[old]));
2182 hashtab[index] = i + 1;
2185 MFREE(hashtab, u2, (hashlen + len));
2187 #endif /* ENABLE_VERIFIER */
2189 #if defined(ENABLE_STATISTICS)
2191 count_class_infos += sizeof(classinfo*) * c->interfacescount;
2192 count_class_infos += sizeof(fieldinfo) * c->fieldscount;
2193 count_class_infos += sizeof(methodinfo) * c->methodscount;
2197 /* load attribute structures */
2199 if (!suck_check_classbuffer_size(cb, 2))
2200 goto return_exception;
2202 if (!load_attributes(cb, suck_u2(cb)))
2203 goto return_exception;
2206 /* Pre java 1.5 version don't check this. This implementation is like
2207 java 1.5 do it: for class file version 45.3 we don't check it, older
2208 versions are checked.
2210 if ((ma == 45 && mi > 3) || ma > 45) {
2211 /* check if all data has been read */
2212 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
2214 if (classdata_left > 0) {
2215 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
2216 goto return_exception;
2221 /* release dump area */
2223 dump_release(dumpsize);
2225 /* revert loading state and class is loaded */
2227 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2229 #if !defined(NDEBUG)
2231 log_message_class("Loading done class: ", c);
2237 /* release dump area */
2239 dump_release(dumpsize);
2241 /* an exception has been thrown */
2247 /* load_newly_created_array ****************************************************
2249 Load a newly created array class.
2252 c....................the array class C has been loaded
2253 other classinfo......the array class was found in the class cache,
2255 NULL.................an exception has been thrown
2258 This is an internal function. Do not use it unless you know exactly
2261 Use one of the load_class_... functions for general array class loading.
2263 *******************************************************************************/
2265 classinfo *load_newly_created_array(classinfo *c, java_objectheader *loader)
2267 classinfo *comp = NULL;
2269 methoddesc *clonedesc;
2270 constant_classref *classrefs;
2275 text = c->name->text;
2276 namelen = c->name->blength;
2278 /* Check array class name */
2280 if (namelen < 2 || text[0] != '[') {
2281 *exceptionptr = new_noclassdeffounderror(c->name);
2285 /* Check the element type */
2289 /* c is an array of arrays. We have to create the component class. */
2291 u = utf_new(text + 1, namelen - 1);
2292 if (!(comp = load_class_from_classloader(u, loader)))
2295 LOADER_ASSERT(comp->state & CLASS_LOADED);
2301 /* the array's flags are that of the component class */
2302 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2303 c->classloader = comp->classloader;
2307 /* c is an array of objects. */
2309 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2310 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
2311 *exceptionptr = new_noclassdeffounderror(c->name);
2315 u = utf_new(text + 2, namelen - 3);
2317 if (!(comp = load_class_from_classloader(u, loader)))
2320 LOADER_ASSERT(comp->state & CLASS_LOADED);
2326 /* the array's flags are that of the component class */
2327 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2328 c->classloader = comp->classloader;
2332 /* c is an array of a primitive type */
2334 /* check for cases like `[II' */
2336 *exceptionptr = new_noclassdeffounderror(c->name);
2340 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2341 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2342 c->classloader = NULL;
2345 LOADER_ASSERT(class_java_lang_Object);
2346 LOADER_ASSERT(class_java_lang_Cloneable);
2347 LOADER_ASSERT(class_java_io_Serializable);
2349 /* setup the array class */
2351 c->super.cls = class_java_lang_Object;
2353 c->interfacescount = 2;
2354 c->interfaces = MNEW(classref_or_classinfo, 2);
2359 tc = class_java_lang_Cloneable;
2360 LOADER_ASSERT(tc->state & CLASS_LOADED);
2361 list_addfirst(&unlinkedclasses, tc);
2362 c->interfaces[0].cls = tc;
2364 tc = class_java_io_Serializable;
2365 LOADER_ASSERT(tc->state & CLASS_LOADED);
2366 list_addfirst(&unlinkedclasses, tc);
2367 c->interfaces[1].cls = tc;
2370 c->interfaces[0].cls = class_java_lang_Cloneable;
2371 c->interfaces[1].cls = class_java_io_Serializable;
2374 c->methodscount = 1;
2375 c->methods = MNEW(methodinfo, c->methodscount);
2377 classrefs = MNEW(constant_classref, 2);
2378 CLASSREF_INIT(classrefs[0], c, c->name);
2379 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2381 /* create descriptor for clone method */
2382 /* we need one paramslot which is reserved for the 'this' parameter */
2383 clonedesc = NEW(methoddesc);
2384 clonedesc->returntype.type = TYPE_ADDRESS;
2385 clonedesc->returntype.classref = classrefs + 1;
2386 clonedesc->returntype.arraydim = 0;
2387 /* initialize params to "empty", add real params below in
2388 descriptor_params_from_paramtypes */
2389 clonedesc->paramcount = 0;
2390 clonedesc->paramslots = 0;
2391 clonedesc->paramtypes[0].classref = classrefs + 0;
2393 /* create methodinfo */
2396 MSET(clone, 0, methodinfo, 1);
2398 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
2399 initObjectLock(&clone->header);
2402 /* ATTENTION: if you delete the ACC_NATIVE below, set
2403 clone->maxlocals=1 (interpreter related) */
2405 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2406 clone->name = utf_clone;
2407 clone->descriptor = utf_void__java_lang_Object;
2408 clone->parseddesc = clonedesc;
2411 /* parse the descriptor to get the register allocation */
2413 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2417 codegen_createnativestub((functionptr) &builtin_clone_array, clone);
2419 /* XXX: field: length? */
2421 /* array classes are not loaded from class files */
2423 c->state |= CLASS_LOADED;
2424 c->parseddescs = (u1 *) clonedesc;
2425 c->parseddescsize = sizeof(methodinfo);
2426 c->classrefs = classrefs;
2427 c->classrefcount = 1;
2429 /* insert class into the loaded class cache */
2430 /* XXX free classinfo if NULL returned? */
2432 return classcache_store(loader, c, true);
2436 /* loader_close ****************************************************************
2438 Frees all resources.
2440 *******************************************************************************/
2442 void loader_close(void)
2449 * These are local overrides for various environment variables in Emacs.
2450 * Please do not remove this and leave it at the end of the file, where
2451 * Emacs will automagically detect them.
2452 * ---------------------------------------------------------------------
2455 * indent-tabs-mode: t
2459 * vim:noexpandtab:sw=4:ts=4: