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 4598 2006-03-14 22:16:47Z edwin $
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");
279 /* print out exception and cause */
281 exceptions_print_exception(*exceptionptr);
288 #if defined(ENABLE_ZLIB)
295 /* skipattributebody ***********************************************************
297 Skips an attribute after the 16 bit reference to attribute_name has
300 *******************************************************************************/
302 static bool skipattributebody(classbuffer *cb)
306 if (!suck_check_classbuffer_size(cb, 4))
311 if (!suck_check_classbuffer_size(cb, len))
314 suck_skip_nbytes(cb, len);
320 /************************* Function: skipattributes ****************************
322 skips num attribute structures
324 *******************************************************************************/
326 static bool skipattributes(classbuffer *cb, u4 num)
331 for (i = 0; i < num; i++) {
332 if (!suck_check_classbuffer_size(cb, 2 + 4))
338 if (!suck_check_classbuffer_size(cb, len))
341 suck_skip_nbytes(cb, len);
348 /* load_constantpool ***********************************************************
350 Loads the constantpool of a class, the entries are transformed into
351 a simpler format by resolving references (a detailed overview of
352 the compact structures can be found in global.h).
354 *******************************************************************************/
356 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
359 /* The following structures are used to save information which cannot be
360 processed during the first pass. After the complete constantpool has
361 been traversed the references can be resolved.
362 (only in specific order) */
364 /* CONSTANT_Class entries */
365 typedef struct forward_class {
366 struct forward_class *next;
371 /* CONSTANT_String */
372 typedef struct forward_string {
373 struct forward_string *next;
378 /* CONSTANT_NameAndType */
379 typedef struct forward_nameandtype {
380 struct forward_nameandtype *next;
384 } forward_nameandtype;
386 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
387 typedef struct forward_fieldmethint {
388 struct forward_fieldmethint *next;
392 u2 nameandtype_index;
393 } forward_fieldmethint;
399 forward_class *forward_classes = NULL;
400 forward_string *forward_strings = NULL;
401 forward_nameandtype *forward_nameandtypes = NULL;
402 forward_fieldmethint *forward_fieldmethints = NULL;
406 forward_nameandtype *nfn;
407 forward_fieldmethint *nff;
415 /* number of entries in the constant_pool table plus one */
416 if (!suck_check_classbuffer_size(cb, 2))
419 cpcount = c->cpcount = suck_u2(cb);
421 /* allocate memory */
422 cptags = c->cptags = MNEW(u1, cpcount);
423 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
426 exceptions_throw_classformaterror(c, "Illegal constant pool size");
430 #if defined(ENABLE_STATISTICS)
432 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
435 /* initialize constantpool */
436 for (idx = 0; idx < cpcount; idx++) {
437 cptags[idx] = CONSTANT_UNUSED;
442 /******* first pass *******/
443 /* entries which cannot be resolved now are written into
444 temporary structures and traversed again later */
447 while (idx < cpcount) {
450 /* get constant type */
451 if (!suck_check_classbuffer_size(cb, 1))
458 nfc = DNEW(forward_class);
460 nfc->next = forward_classes;
461 forward_classes = nfc;
463 nfc->thisindex = idx;
464 /* reference to CONSTANT_NameAndType */
465 if (!suck_check_classbuffer_size(cb, 2))
468 nfc->name_index = suck_u2(cb);
473 case CONSTANT_String:
474 nfs = DNEW(forward_string);
476 nfs->next = forward_strings;
477 forward_strings = nfs;
479 nfs->thisindex = idx;
481 /* reference to CONSTANT_Utf8_info with string characters */
482 if (!suck_check_classbuffer_size(cb, 2))
485 nfs->string_index = suck_u2(cb);
490 case CONSTANT_NameAndType:
491 nfn = DNEW(forward_nameandtype);
493 nfn->next = forward_nameandtypes;
494 forward_nameandtypes = nfn;
496 nfn->thisindex = idx;
498 if (!suck_check_classbuffer_size(cb, 2 + 2))
501 /* reference to CONSTANT_Utf8_info containing simple name */
502 nfn->name_index = suck_u2(cb);
504 /* reference to CONSTANT_Utf8_info containing field or method
506 nfn->sig_index = suck_u2(cb);
511 case CONSTANT_Fieldref:
512 case CONSTANT_Methodref:
513 case CONSTANT_InterfaceMethodref:
514 nff = DNEW(forward_fieldmethint);
516 nff->next = forward_fieldmethints;
517 forward_fieldmethints = nff;
519 nff->thisindex = idx;
523 if (!suck_check_classbuffer_size(cb, 2 + 2))
526 /* class or interface type that contains the declaration of the
528 nff->class_index = suck_u2(cb);
530 /* name and descriptor of the field or method */
531 nff->nameandtype_index = suck_u2(cb);
536 case CONSTANT_Integer: {
537 constant_integer *ci = NEW(constant_integer);
539 #if defined(ENABLE_STATISTICS)
541 count_const_pool_len += sizeof(constant_integer);
544 if (!suck_check_classbuffer_size(cb, 4))
547 ci->value = suck_s4(cb);
548 cptags[idx] = CONSTANT_Integer;
555 case CONSTANT_Float: {
556 constant_float *cf = NEW(constant_float);
558 #if defined(ENABLE_STATISTICS)
560 count_const_pool_len += sizeof(constant_float);
563 if (!suck_check_classbuffer_size(cb, 4))
566 cf->value = suck_float(cb);
567 cptags[idx] = CONSTANT_Float;
574 case CONSTANT_Long: {
575 constant_long *cl = NEW(constant_long);
577 #if defined(ENABLE_STATISTICS)
579 count_const_pool_len += sizeof(constant_long);
582 if (!suck_check_classbuffer_size(cb, 8))
585 cl->value = suck_s8(cb);
586 cptags[idx] = CONSTANT_Long;
590 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
596 case CONSTANT_Double: {
597 constant_double *cd = NEW(constant_double);
599 #if defined(ENABLE_STATISTICS)
601 count_const_pool_len += sizeof(constant_double);
604 if (!suck_check_classbuffer_size(cb, 8))
607 cd->value = suck_double(cb);
608 cptags[idx] = CONSTANT_Double;
612 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
618 case CONSTANT_Utf8: {
621 /* number of bytes in the bytes array (not string-length) */
622 if (!suck_check_classbuffer_size(cb, 2))
625 length = suck_u2(cb);
626 cptags[idx] = CONSTANT_Utf8;
628 /* validate the string */
629 if (!suck_check_classbuffer_size(cb, length))
632 #ifdef ENABLE_VERIFIER
634 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
636 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
639 #endif /* ENABLE_VERIFIER */
640 /* insert utf-string into the utf-symboltable */
641 cpinfos[idx] = utf_new((char *) cb->pos, length);
643 /* skip bytes of the string (buffer size check above) */
644 suck_skip_nbytes(cb, length);
650 exceptions_throw_classformaterror(c, "Illegal constant pool type");
656 /* resolve entries in temporary structures */
658 while (forward_classes) {
660 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
664 #ifdef ENABLE_VERIFIER
665 if (opt_verify && !is_valid_name_utf(name)) {
666 exceptions_throw_classformaterror(c, "Class reference with invalid name");
669 #endif /* ENABLE_VERIFIER */
671 /* add all class references to the descriptor_pool */
673 if (!descriptor_pool_add_class(descpool, name))
676 cptags[forward_classes->thisindex] = CONSTANT_Class;
681 if (!(tc = load_class_bootstrap(name)))
684 /* link the class later, because we cannot link the class currently
686 list_addfirst(&unlinkedclasses, tc);
689 /* the classref is created later */
690 cpinfos[forward_classes->thisindex] = name;
692 nfc = forward_classes;
693 forward_classes = forward_classes->next;
696 while (forward_strings) {
698 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
702 /* resolve utf-string */
703 cptags[forward_strings->thisindex] = CONSTANT_String;
704 cpinfos[forward_strings->thisindex] = text;
706 nfs = forward_strings;
707 forward_strings = forward_strings->next;
710 while (forward_nameandtypes) {
711 constant_nameandtype *cn = NEW(constant_nameandtype);
713 #if defined(ENABLE_STATISTICS)
715 count_const_pool_len += sizeof(constant_nameandtype);
718 /* resolve simple name and descriptor */
719 cn->name = class_getconstant(c,
720 forward_nameandtypes->name_index,
725 cn->descriptor = class_getconstant(c,
726 forward_nameandtypes->sig_index,
731 #ifdef ENABLE_VERIFIER
734 if (!is_valid_name_utf(cn->name)) {
735 exceptions_throw_classformaterror(c,
736 "Illegal Field name \"%s\"",
742 /* disallow referencing <clinit> among others */
743 if (cn->name->text[0] == '<' && cn->name != utf_init) {
744 exceptions_throw_classformaterror(c, "Illegal reference to special method");
748 #endif /* ENABLE_VERIFIER */
750 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
751 cpinfos[forward_nameandtypes->thisindex] = cn;
753 nfn = forward_nameandtypes;
754 forward_nameandtypes = forward_nameandtypes->next;
757 while (forward_fieldmethints) {
758 constant_nameandtype *nat;
759 constant_FMIref *fmi = NEW(constant_FMIref);
761 #if defined(ENABLE_STATISTICS)
763 count_const_pool_len += sizeof(constant_FMIref);
765 /* resolve simple name and descriptor */
767 nat = class_getconstant(c,
768 forward_fieldmethints->nameandtype_index,
769 CONSTANT_NameAndType);
773 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
775 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
778 /* the classref is created later */
780 fmi->classref = (constant_classref *) (size_t) forward_fieldmethints->class_index;
781 fmi->name = nat->name;
782 fmi->descriptor = nat->descriptor;
784 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
785 cpinfos[forward_fieldmethints->thisindex] = fmi;
787 nff = forward_fieldmethints;
788 forward_fieldmethints = forward_fieldmethints->next;
791 /* everything was ok */
797 /* load_field ******************************************************************
799 Load everything about a class field from the class file and fill a
800 'fieldinfo' structure. For static fields, space in the data segment
803 *******************************************************************************/
805 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
807 static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
812 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
817 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
820 f->flags = suck_u2(cb);
822 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
827 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
831 f->parseddesc = NULL;
833 if (!descriptor_pool_add(descpool, u, NULL))
836 /* descriptor_pool_add accepts method descriptors, so we have to check */
837 /* against them here before the call of descriptor_to_basic_type below. */
838 if (u->text[0] == '(') {
839 exceptions_throw_classformaterror(c, "Method descriptor used for field");
843 #ifdef ENABLE_VERIFIER
846 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<') {
847 exceptions_throw_classformaterror(c,
848 "Illegal Field name \"%s\"",
853 /* check flag consistency */
854 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
856 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
857 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
858 exceptions_throw_classformaterror(c,
859 "Illegal field modifiers: 0x%X",
864 if (c->flags & ACC_INTERFACE) {
865 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
866 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
867 f->flags & ACC_TRANSIENT) {
868 exceptions_throw_classformaterror(c,
869 "Illegal field modifiers: 0x%X",
875 #endif /* ENABLE_VERIFIER */
877 f->type = jtype = descriptor_to_basic_type(f->descriptor); /* data type */
878 f->offset = 0; /* offset from start of object */
882 case TYPE_INT: f->value.i = 0; break;
883 case TYPE_FLOAT: f->value.f = 0.0; break;
884 case TYPE_DOUBLE: f->value.d = 0.0; break;
885 case TYPE_ADDRESS: f->value.a = NULL; break;
888 f->value.l = 0; break;
890 f->value.l.low = 0; f->value.l.high = 0; break;
894 /* read attributes */
895 if (!suck_check_classbuffer_size(cb, 2))
898 attrnum = suck_u2(cb);
899 for (i = 0; i < attrnum; i++) {
900 if (!suck_check_classbuffer_size(cb, 2))
903 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
906 if (u == utf_ConstantValue) {
907 if (!suck_check_classbuffer_size(cb, 4 + 2))
910 /* check attribute length */
911 if (suck_u4(cb) != 2) {
912 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
916 /* constant value attribute */
917 if (pindex != field_load_NOVALUE) {
918 exceptions_throw_classformaterror(c, "Multiple ConstantValue attributes");
922 /* index of value in constantpool */
923 pindex = suck_u2(cb);
925 /* initialize field with value from constantpool */
928 constant_integer *ci;
930 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
933 f->value.i = ci->value;
940 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
943 f->value.l = cl->value;
950 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
953 f->value.f = cf->value;
960 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
963 f->value.d = cd->value;
968 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
971 /* create javastring from compressed utf8-string */
972 f->value.a = literalstring_new(u);
976 log_text("Invalid Constant - Type");
980 /* unknown attribute */
981 if (!skipattributebody(cb))
986 /* everything was ok */
992 /* load_method *****************************************************************
994 Loads a method from the class file and fills an existing
995 'methodinfo' structure. For native methods, the function pointer
996 field is set to the real function pointer, for JavaVM methods a
997 pointer to the compiler is used preliminarily.
999 *******************************************************************************/
1001 static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpool)
1012 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1013 initObjectLock(&m->header);
1016 #if defined(ENABLE_STATISTICS)
1018 count_all_methods++;
1021 m->thrownexceptionscount = 0;
1022 m->linenumbercount = 0;
1026 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
1029 m->flags = suck_u2(cb);
1031 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1036 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1040 m->parseddesc = NULL;
1042 if (!descriptor_pool_add(descpool, u, &argcount))
1045 #ifdef ENABLE_VERIFIER
1047 if (!is_valid_name_utf(m->name)) {
1048 exceptions_throw_classformaterror(c, "Method with invalid name");
1052 if (m->name->text[0] == '<' &&
1053 m->name != utf_init && m->name != utf_clinit) {
1054 exceptions_throw_classformaterror(c, "Method with invalid special name");
1058 #endif /* ENABLE_VERIFIER */
1060 if (!(m->flags & ACC_STATIC))
1061 argcount++; /* count the 'this' argument */
1063 #ifdef ENABLE_VERIFIER
1065 if (argcount > 255) {
1066 exceptions_throw_classformaterror(c, "Too many arguments in signature");
1070 /* check flag consistency */
1071 if (m->name != utf_clinit) {
1072 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1074 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1075 exceptions_throw_classformaterror(c,
1076 "Illegal method modifiers: 0x%X",
1081 if (m->flags & ACC_ABSTRACT) {
1082 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1083 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1084 exceptions_throw_classformaterror(c,
1085 "Illegal method modifiers: 0x%X",
1091 if (c->flags & ACC_INTERFACE) {
1092 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1093 exceptions_throw_classformaterror(c,
1094 "Illegal method modifiers: 0x%X",
1100 if (m->name == utf_init) {
1101 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1102 ACC_NATIVE | ACC_ABSTRACT)) {
1103 exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
1109 #endif /* ENABLE_VERIFIER */
1112 m->basicblockcount = 0;
1113 m->basicblocks = NULL;
1114 m->basicblockindex = NULL;
1115 m->instructioncount = 0;
1116 m->instructions = NULL;
1119 m->exceptiontable = NULL;
1120 m->stubroutine = NULL;
1123 if (!suck_check_classbuffer_size(cb, 2))
1126 attrnum = suck_u2(cb);
1127 for (i = 0; i < attrnum; i++) {
1130 if (!suck_check_classbuffer_size(cb, 2))
1133 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1136 if (aname == utf_Code) {
1137 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1138 exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
1143 exceptions_throw_classformaterror(c, "Multiple Code attributes");
1147 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1151 m->maxstack = suck_u2(cb);
1152 m->maxlocals = suck_u2(cb);
1154 if (m->maxlocals < argcount) {
1155 exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
1159 if (!suck_check_classbuffer_size(cb, 4))
1162 m->jcodelength = suck_u4(cb);
1164 if (m->jcodelength == 0) {
1165 exceptions_throw_classformaterror(c, "Code of a method has length 0");
1169 if (m->jcodelength > 65535) {
1170 exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
1174 if (!suck_check_classbuffer_size(cb, m->jcodelength))
1177 m->jcode = MNEW(u1, m->jcodelength);
1178 suck_nbytes(m->jcode, cb, m->jcodelength);
1180 if (!suck_check_classbuffer_size(cb, 2))
1183 m->exceptiontablelength = suck_u2(cb);
1184 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->exceptiontablelength))
1187 m->exceptiontable = MNEW(exceptiontable, m->exceptiontablelength);
1189 #if defined(ENABLE_STATISTICS)
1191 count_vmcode_len += m->jcodelength + 18;
1192 count_extable_len +=
1193 m->exceptiontablelength * sizeof(exceptiontable);
1197 for (j = 0; j < m->exceptiontablelength; j++) {
1199 m->exceptiontable[j].startpc = suck_u2(cb);
1200 m->exceptiontable[j].endpc = suck_u2(cb);
1201 m->exceptiontable[j].handlerpc = suck_u2(cb);
1205 m->exceptiontable[j].catchtype.any = NULL;
1208 /* the classref is created later */
1209 if (!(m->exceptiontable[j].catchtype.any =
1210 (utf*)class_getconstant(c, idx, CONSTANT_Class)))
1215 if (!suck_check_classbuffer_size(cb, 2))
1218 codeattrnum = suck_u2(cb);
1220 for (; codeattrnum > 0; codeattrnum--) {
1223 if (!suck_check_classbuffer_size(cb, 2))
1226 if (!(caname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1229 if (caname == utf_LineNumberTable) {
1232 if (!suck_check_classbuffer_size(cb, 4 + 2))
1236 m->linenumbercount = suck_u2(cb);
1238 if (!suck_check_classbuffer_size(cb,
1239 (2 + 2) * m->linenumbercount))
1242 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1244 for (lncid = 0; lncid < m->linenumbercount; lncid++) {
1245 m->linenumbers[lncid].start_pc = suck_u2(cb);
1246 m->linenumbers[lncid].line_number = suck_u2(cb);
1250 if (!skipattributes(cb, codeattrnum))
1256 if (!skipattributebody(cb))
1261 } else if (aname == utf_Exceptions) {
1264 if (m->thrownexceptions) {
1265 exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
1269 if (!suck_check_classbuffer_size(cb, 4 + 2))
1272 suck_u4(cb); /* length */
1273 m->thrownexceptionscount = suck_u2(cb);
1275 if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1278 m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
1280 for (j = 0; j < m->thrownexceptionscount; j++) {
1281 /* the classref is created later */
1282 if (!((m->thrownexceptions)[j].any =
1283 (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1288 if (!skipattributebody(cb))
1293 if (!m->jcode && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1294 exceptions_throw_classformaterror(c, "Missing Code attribute");
1298 /* everything was ok */
1304 /* load_attribute **************************************************************
1306 Read attributes from classfile.
1308 *******************************************************************************/
1310 static bool load_attributes(classbuffer *cb, u4 num)
1318 for (i = 0; i < num; i++) {
1319 /* retrieve attribute name */
1320 if (!suck_check_classbuffer_size(cb, 2))
1323 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1326 if (aname == utf_InnerClasses) {
1327 /* innerclasses attribute */
1328 if (c->innerclass) {
1329 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
1333 if (!suck_check_classbuffer_size(cb, 4 + 2))
1336 /* skip attribute length */
1339 /* number of records */
1340 c->innerclasscount = suck_u2(cb);
1342 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
1345 /* allocate memory for innerclass structure */
1346 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
1348 for (j = 0; j < c->innerclasscount; j++) {
1349 /* The innerclass structure contains a class with an encoded
1350 name, its defining scope, its simple name and a bitmask of
1351 the access flags. If an inner class is not a member, its
1352 outer_class is NULL, if a class is anonymous, its name is
1355 innerclassinfo *info = c->innerclass + j;
1357 info->inner_class.ref =
1358 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
1359 info->outer_class.ref =
1360 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
1362 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1363 info->flags = suck_u2(cb);
1366 } else if (aname == utf_SourceFile) {
1367 if (!suck_check_classbuffer_size(cb, 4 + 2))
1370 if (suck_u4(cb) != 2) {
1371 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
1375 if (c->sourcefile) {
1376 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
1380 if (!(c->sourcefile = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1384 /* unknown attribute */
1385 if (!skipattributebody(cb))
1394 /* load_class_from_sysloader ***************************************************
1396 Load the class with the given name using the system class loader
1399 name.............the classname
1402 the loaded class, or
1403 NULL if an exception has been thrown
1405 *******************************************************************************/
1407 classinfo *load_class_from_sysloader(utf *name)
1410 java_objectheader *cl;
1413 LOADER_ASSERT(class_java_lang_Object);
1414 LOADER_ASSERT(class_java_lang_ClassLoader);
1415 LOADER_ASSERT(class_java_lang_ClassLoader->state & CLASS_LINKED);
1417 m = class_resolveclassmethod(class_java_lang_ClassLoader,
1418 utf_getSystemClassLoader,
1419 utf_void__java_lang_ClassLoader,
1420 class_java_lang_Object,
1426 cl = vm_call_method(m, NULL);
1431 c = load_class_from_classloader(name, cl);
1437 /* load_class_from_classloader *************************************************
1439 Load the class with the given name using the given user-defined class loader.
1442 name.............the classname
1443 cl...............user-defined class loader
1446 the loaded class, or
1447 NULL if an exception has been thrown
1449 *******************************************************************************/
1451 classinfo *load_class_from_classloader(utf *name, java_objectheader *cl)
1453 java_objectheader *o;
1456 java_lang_String *s;
1458 LOADER_ASSERT(name);
1460 /* lookup if this class has already been loaded */
1462 c = classcache_lookup(cl, name);
1467 /* if other class loader than bootstrap, call it */
1475 namelen = name->blength;
1477 /* handle array classes */
1478 if (text[0] == '[') {
1484 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1485 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1486 *exceptionptr = new_noclassdeffounderror(name);
1490 u = utf_new(text + 2, namelen - 3);
1492 if (!(comp = load_class_from_classloader(u, cl)))
1495 /* create the array class */
1497 c = class_array_of(comp, false);
1499 tmpc = classcache_store(cl, c, true);
1502 /* exception, free the loaded class */
1503 c->state &= ~CLASS_LOADING;
1510 /* load the component class */
1512 u = utf_new(text + 1, namelen - 1);
1514 if (!(comp = load_class_from_classloader(u, cl)))
1517 /* create the array class */
1519 c = class_array_of(comp, false);
1521 tmpc = classcache_store(cl, c, true);
1524 /* exception, free the loaded class */
1525 c->state &= ~CLASS_LOADING;
1532 /* primitive array classes are loaded by the bootstrap loader */
1534 c = load_class_bootstrap(name);
1540 LOADER_ASSERT(class_java_lang_Object);
1542 lc = class_resolveclassmethod(cl->vftbl->class,
1544 utf_java_lang_String__java_lang_Class,
1545 class_java_lang_Object,
1549 return false; /* exception */
1551 /* move return value into `o' and cast it afterwards to a classinfo* */
1553 s = javastring_new_slash_to_dot(name);
1555 o = vm_call_method(lc, cl, s);
1557 c = (classinfo *) o;
1560 /* Store this class in the loaded class cache. If another
1561 class with the same (initloader,name) pair has been
1562 stored earlier it will be returned by classcache_store
1563 In this case classcache_store may not free the class
1564 because it has already been exposed to Java code which
1565 may have kept references to that class. */
1567 tmpc = classcache_store(cl, c, false);
1570 /* exception, free the loaded class */
1571 c->state &= ~CLASS_LOADING;
1578 /* loadClass has thrown an exception. We must convert
1579 ClassNotFoundException into
1580 NoClassDefFoundException. */
1582 /* XXX Maybe we should have a flag that avoids this
1583 conversion for calling load_class_from_classloader from
1584 Class.forName. Currently we do a double conversion in
1587 classnotfoundexception_to_noclassdeffounderror();
1590 /* SUN compatible -verbose:class output */
1592 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1594 utf_display_classname(name);
1601 c = load_class_bootstrap(name);
1607 /* load_class_bootstrap ********************************************************
1609 Load the class with the given name using the bootstrap class loader.
1612 name.............the classname
1615 loaded classinfo, or
1616 NULL if an exception has been thrown
1619 load_class_bootstrap is synchronized. It can be treated as an
1622 *******************************************************************************/
1624 classinfo *load_class_bootstrap(utf *name)
1632 LOADER_ASSERT(name);
1634 /* lookup if this class has already been loaded */
1636 if ((r = classcache_lookup(NULL, name)))
1639 /* create the classinfo */
1641 c = class_create_classinfo(name);
1643 /* handle array classes */
1645 if (name->text[0] == '[') {
1646 c = load_newly_created_array(c, NULL);
1649 LOADER_ASSERT(c->state & CLASS_LOADED);
1653 #if defined(ENABLE_STATISTICS)
1656 if (getcompilingtime)
1657 compilingtime_stop();
1660 loadingtime_start();
1663 /* load classdata, throw exception on error */
1665 if ((cb = suck_start(c)) == NULL) {
1666 /* this normally means, the classpath was not set properly */
1668 if (name == utf_java_lang_Object)
1669 throw_cacao_exception_exit(string_java_lang_NoClassDefFoundError,
1670 "java/lang/Object");
1672 *exceptionptr = new_noclassdeffounderror(name);
1677 /* load the class from the buffer */
1679 r = load_class_from_classbuffer(cb);
1682 /* the class could not be loaded, free the classinfo struct */
1687 /* Store this class in the loaded class cache this step also
1688 checks the loading constraints. If the class has been loaded
1689 before, the earlier loaded class is returned. */
1691 classinfo *res = classcache_store(NULL, c, true);
1701 /* SUN compatible -verbose:class output */
1703 if (opt_verboseclass && r) {
1705 utf_display_classname(name);
1706 printf(" from %s]\n", cb->path);
1713 #if defined(ENABLE_STATISTICS)
1719 if (getcompilingtime)
1720 compilingtime_start();
1727 /* load_class_from_classbuffer *************************************************
1729 Loads everything interesting about a class from the class file. The
1730 'classinfo' structure must have been allocated previously.
1732 The super class and the interfaces implemented by this class need
1733 not be loaded. The link is set later by the function 'class_link'.
1735 The loaded class is removed from the list 'unloadedclasses' and
1736 added to the list 'unlinkedclasses'.
1739 This function is NOT synchronized!
1741 *******************************************************************************/
1743 classinfo *load_class_from_classbuffer(classbuffer *cb)
1751 descriptor_pool *descpool;
1752 #if defined(ENABLE_STATISTICS)
1757 /* get the classbuffer's class */
1761 /* the class is already loaded */
1763 if (c->state & CLASS_LOADED)
1766 #if defined(ENABLE_STATISTICS)
1768 count_class_loads++;
1771 #if !defined(NDEBUG)
1772 /* output for debugging purposes */
1775 log_message_class("Loading class: ", c);
1778 /* mark start of dump memory area */
1780 dumpsize = dump_size();
1782 /* class is currently loading */
1784 c->state |= CLASS_LOADING;
1786 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1787 goto return_exception;
1789 /* check signature */
1791 if (suck_u4(cb) != MAGIC) {
1792 exceptions_throw_classformaterror(c, "Bad magic number");
1794 goto return_exception;
1802 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1804 new_unsupportedclassversionerror(c,
1805 "Unsupported major.minor version %d.%d",
1808 goto return_exception;
1811 /* create a new descriptor pool */
1813 descpool = descriptor_pool_new(c);
1815 /* load the constant pool */
1817 if (!load_constantpool(cb, descpool))
1818 goto return_exception;
1822 if (!suck_check_classbuffer_size(cb, 2))
1823 goto return_exception;
1825 c->flags = suck_u2(cb);
1827 /* check ACC flags consistency */
1829 if (c->flags & ACC_INTERFACE) {
1830 if (!(c->flags & ACC_ABSTRACT)) {
1831 /* We work around this because interfaces in JDK 1.1 are
1832 * not declared abstract. */
1834 c->flags |= ACC_ABSTRACT;
1837 if (c->flags & ACC_FINAL) {
1838 exceptions_throw_classformaterror(c,
1839 "Illegal class modifiers: 0x%X",
1841 goto return_exception;
1844 if (c->flags & ACC_SUPER) {
1845 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1849 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1850 exceptions_throw_classformaterror(c,
1851 "Illegal class modifiers: 0x%X",
1853 goto return_exception;
1856 if (!suck_check_classbuffer_size(cb, 2 + 2))
1857 goto return_exception;
1862 if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1863 goto return_exception;
1865 if (c->name == utf_not_named_yet) {
1866 /* we finally have a name for this class */
1868 class_set_packagename(c);
1870 } else if (name != c->name) {
1874 msglen = utf_strlen(c->name) + strlen(" (wrong name: ") +
1875 utf_strlen(name) + strlen(")") + strlen("0");
1877 msg = MNEW(char, msglen);
1879 utf_sprint(msg, c->name);
1880 strcat(msg, " (wrong name: ");
1881 utf_strcat(msg, name);
1885 new_exception_message(string_java_lang_NoClassDefFoundError, msg);
1887 MFREE(msg, char, msglen);
1889 goto return_exception;
1892 /* retrieve superclass */
1894 c->super.any = NULL;
1895 if ((i = suck_u2(cb))) {
1896 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1897 goto return_exception;
1899 /* java.lang.Object may not have a super class. */
1901 if (c->name == utf_java_lang_Object) {
1903 new_exception_message(string_java_lang_ClassFormatError,
1904 "java.lang.Object with superclass");
1906 goto return_exception;
1909 /* Interfaces must have java.lang.Object as super class. */
1911 if ((c->flags & ACC_INTERFACE) &&
1912 supername != utf_java_lang_Object) {
1914 new_exception_message(string_java_lang_ClassFormatError,
1915 "Interfaces must have java.lang.Object as superclass");
1917 goto return_exception;
1923 /* This is only allowed for java.lang.Object. */
1925 if (c->name != utf_java_lang_Object) {
1926 exceptions_throw_classformaterror(c, "Bad superclass index");
1927 goto return_exception;
1931 /* retrieve interfaces */
1933 if (!suck_check_classbuffer_size(cb, 2))
1934 goto return_exception;
1936 c->interfacescount = suck_u2(cb);
1938 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1939 goto return_exception;
1941 c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
1942 for (i = 0; i < c->interfacescount; i++) {
1943 /* the classrefs are created later */
1944 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1945 goto return_exception;
1949 if (!suck_check_classbuffer_size(cb, 2))
1950 goto return_exception;
1952 c->fieldscount = suck_u2(cb);
1953 c->fields = GCNEW_UNCOLLECTABLE(fieldinfo, c->fieldscount);
1954 /* c->fields = MNEW(fieldinfo, c->fieldscount); */
1955 for (i = 0; i < c->fieldscount; i++) {
1956 if (!load_field(cb, &(c->fields[i]),descpool))
1957 goto return_exception;
1961 if (!suck_check_classbuffer_size(cb, 2))
1962 goto return_exception;
1964 c->methodscount = suck_u2(cb);
1965 /* c->methods = GCNEW(methodinfo, c->methodscount); */
1966 c->methods = MNEW(methodinfo, c->methodscount);
1967 for (i = 0; i < c->methodscount; i++) {
1968 if (!load_method(cb, &(c->methods[i]),descpool))
1969 goto return_exception;
1972 /* create the class reference table */
1975 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
1977 /* allocate space for the parsed descriptors */
1979 descriptor_pool_alloc_parsed_descriptors(descpool);
1981 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
1983 #if defined(ENABLE_STATISTICS)
1985 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
1986 count_classref_len += classrefsize;
1987 count_parsed_desc_len += descsize;
1991 /* put the classrefs in the constant pool */
1992 for (i = 0; i < c->cpcount; i++) {
1993 if (c->cptags[i] == CONSTANT_Class) {
1994 utf *name = (utf *) c->cpinfos[i];
1995 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
1999 /* set the super class reference */
2002 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
2004 goto return_exception;
2007 /* set the super interfaces references */
2009 for (i = 0; i < c->interfacescount; i++) {
2010 c->interfaces[i].ref =
2011 descriptor_pool_lookup_classref(descpool,
2012 (utf *) c->interfaces[i].any);
2013 if (!c->interfaces[i].ref)
2014 goto return_exception;
2017 /* parse field descriptors */
2019 for (i = 0; i < c->fieldscount; i++) {
2020 c->fields[i].parseddesc =
2021 descriptor_pool_parse_field_descriptor(descpool,
2022 c->fields[i].descriptor);
2023 if (!c->fields[i].parseddesc)
2024 goto return_exception;
2027 /* parse method descriptors */
2029 for (i = 0; i < c->methodscount; i++) {
2030 methodinfo *m = &c->methods[i];
2032 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
2033 m->flags, class_get_self_classref(m->class));
2035 goto return_exception;
2037 for (j = 0; j < m->exceptiontablelength; j++) {
2038 if (!m->exceptiontable[j].catchtype.any)
2040 if ((m->exceptiontable[j].catchtype.ref =
2041 descriptor_pool_lookup_classref(descpool,
2042 (utf *) m->exceptiontable[j].catchtype.any)) == NULL)
2043 goto return_exception;
2046 for (j = 0; j < m->thrownexceptionscount; j++) {
2047 if (!m->thrownexceptions[j].any)
2049 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
2050 (utf *) m->thrownexceptions[j].any)) == NULL)
2051 goto return_exception;
2055 /* parse the loaded descriptors */
2057 for (i = 0; i < c->cpcount; i++) {
2058 constant_FMIref *fmi;
2061 switch (c->cptags[i]) {
2062 case CONSTANT_Fieldref:
2063 fmi = (constant_FMIref *) c->cpinfos[i];
2064 fmi->parseddesc.fd =
2065 descriptor_pool_parse_field_descriptor(descpool,
2067 if (!fmi->parseddesc.fd)
2068 goto return_exception;
2069 index = (int) (size_t) fmi->classref;
2071 (constant_classref *) class_getconstant(c, index,
2074 goto return_exception;
2076 case CONSTANT_Methodref:
2077 case CONSTANT_InterfaceMethodref:
2078 fmi = (constant_FMIref *) c->cpinfos[i];
2079 index = (int) (size_t) fmi->classref;
2081 (constant_classref *) class_getconstant(c, index,
2084 goto return_exception;
2085 fmi->parseddesc.md =
2086 descriptor_pool_parse_method_descriptor(descpool,
2090 if (!fmi->parseddesc.md)
2091 goto return_exception;
2096 #ifdef ENABLE_VERIFIER
2097 /* Check if all fields and methods can be uniquely
2098 * identified by (name,descriptor). */
2101 /* We use a hash table here to avoid making the
2102 * average case quadratic in # of methods, fields.
2104 static int shift = 0;
2106 u2 *next; /* for chaining colliding hash entries */
2112 /* Allocate hashtable */
2113 len = c->methodscount;
2114 if (len < c->fieldscount) len = c->fieldscount;
2116 hashtab = MNEW(u2,(hashlen + len));
2117 next = hashtab + hashlen;
2119 /* Determine bitshift (to get good hash values) */
2129 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2131 for (i = 0; i < c->fieldscount; ++i) {
2132 fieldinfo *fi = c->fields + i;
2134 /* It's ok if we lose bits here */
2135 index = ((((size_t) fi->name) +
2136 ((size_t) fi->descriptor)) >> shift) % hashlen;
2138 if ((old = hashtab[index])) {
2142 if (c->fields[old].name == fi->name &&
2143 c->fields[old].descriptor == fi->descriptor) {
2144 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
2145 goto return_exception;
2147 } while ((old = next[old]));
2149 hashtab[index] = i + 1;
2153 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2155 for (i = 0; i < c->methodscount; ++i) {
2156 methodinfo *mi = c->methods + i;
2158 /* It's ok if we lose bits here */
2159 index = ((((size_t) mi->name) +
2160 ((size_t) mi->descriptor)) >> shift) % hashlen;
2164 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2165 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2169 if ((old = hashtab[index])) {
2173 if (c->methods[old].name == mi->name &&
2174 c->methods[old].descriptor == mi->descriptor) {
2175 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
2176 goto return_exception;
2178 } while ((old = next[old]));
2180 hashtab[index] = i + 1;
2183 MFREE(hashtab, u2, (hashlen + len));
2185 #endif /* ENABLE_VERIFIER */
2187 #if defined(ENABLE_STATISTICS)
2189 count_class_infos += sizeof(classinfo*) * c->interfacescount;
2190 count_class_infos += sizeof(fieldinfo) * c->fieldscount;
2191 count_class_infos += sizeof(methodinfo) * c->methodscount;
2195 /* load attribute structures */
2197 if (!suck_check_classbuffer_size(cb, 2))
2198 goto return_exception;
2200 if (!load_attributes(cb, suck_u2(cb)))
2201 goto return_exception;
2204 /* Pre java 1.5 version don't check this. This implementation is like
2205 java 1.5 do it: for class file version 45.3 we don't check it, older
2206 versions are checked.
2208 if ((ma == 45 && mi > 3) || ma > 45) {
2209 /* check if all data has been read */
2210 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
2212 if (classdata_left > 0) {
2213 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
2214 goto return_exception;
2219 /* release dump area */
2221 dump_release(dumpsize);
2223 /* revert loading state and class is loaded */
2225 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2227 #if !defined(NDEBUG)
2229 log_message_class("Loading done class: ", c);
2235 /* release dump area */
2237 dump_release(dumpsize);
2239 /* an exception has been thrown */
2245 /* load_newly_created_array ****************************************************
2247 Load a newly created array class.
2250 c....................the array class C has been loaded
2251 other classinfo......the array class was found in the class cache,
2253 NULL.................an exception has been thrown
2256 This is an internal function. Do not use it unless you know exactly
2259 Use one of the load_class_... functions for general array class loading.
2261 *******************************************************************************/
2263 classinfo *load_newly_created_array(classinfo *c, java_objectheader *loader)
2265 classinfo *comp = NULL;
2267 methoddesc *clonedesc;
2268 constant_classref *classrefs;
2273 text = c->name->text;
2274 namelen = c->name->blength;
2276 /* Check array class name */
2278 if (namelen < 2 || text[0] != '[') {
2279 *exceptionptr = new_noclassdeffounderror(c->name);
2283 /* Check the element type */
2287 /* c is an array of arrays. We have to create the component class. */
2289 u = utf_new(text + 1, namelen - 1);
2290 if (!(comp = load_class_from_classloader(u, loader)))
2293 LOADER_ASSERT(comp->state & CLASS_LOADED);
2299 /* the array's flags are that of the component class */
2300 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2301 c->classloader = comp->classloader;
2305 /* c is an array of objects. */
2307 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2308 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
2309 *exceptionptr = new_noclassdeffounderror(c->name);
2313 u = utf_new(text + 2, namelen - 3);
2315 if (!(comp = load_class_from_classloader(u, loader)))
2318 LOADER_ASSERT(comp->state & CLASS_LOADED);
2324 /* the array's flags are that of the component class */
2325 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2326 c->classloader = comp->classloader;
2330 /* c is an array of a primitive type */
2332 /* check for cases like `[II' */
2334 *exceptionptr = new_noclassdeffounderror(c->name);
2338 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2339 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2340 c->classloader = NULL;
2343 LOADER_ASSERT(class_java_lang_Object);
2344 LOADER_ASSERT(class_java_lang_Cloneable);
2345 LOADER_ASSERT(class_java_io_Serializable);
2347 /* setup the array class */
2349 c->super.cls = class_java_lang_Object;
2351 c->interfacescount = 2;
2352 c->interfaces = MNEW(classref_or_classinfo, 2);
2357 tc = class_java_lang_Cloneable;
2358 LOADER_ASSERT(tc->state & CLASS_LOADED);
2359 list_addfirst(&unlinkedclasses, tc);
2360 c->interfaces[0].cls = tc;
2362 tc = class_java_io_Serializable;
2363 LOADER_ASSERT(tc->state & CLASS_LOADED);
2364 list_addfirst(&unlinkedclasses, tc);
2365 c->interfaces[1].cls = tc;
2368 c->interfaces[0].cls = class_java_lang_Cloneable;
2369 c->interfaces[1].cls = class_java_io_Serializable;
2372 c->methodscount = 1;
2373 c->methods = MNEW(methodinfo, c->methodscount);
2375 classrefs = MNEW(constant_classref, 2);
2376 CLASSREF_INIT(classrefs[0], c, c->name);
2377 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2379 /* create descriptor for clone method */
2380 /* we need one paramslot which is reserved for the 'this' parameter */
2381 clonedesc = NEW(methoddesc);
2382 clonedesc->returntype.type = TYPE_ADDRESS;
2383 clonedesc->returntype.classref = classrefs + 1;
2384 clonedesc->returntype.arraydim = 0;
2385 /* initialize params to "empty", add real params below in
2386 descriptor_params_from_paramtypes */
2387 clonedesc->paramcount = 0;
2388 clonedesc->paramslots = 0;
2389 clonedesc->paramtypes[0].classref = classrefs + 0;
2391 /* create methodinfo */
2394 MSET(clone, 0, methodinfo, 1);
2396 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
2397 initObjectLock(&clone->header);
2400 /* ATTENTION: if you delete the ACC_NATIVE below, set
2401 clone->maxlocals=1 (interpreter related) */
2403 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2404 clone->name = utf_clone;
2405 clone->descriptor = utf_void__java_lang_Object;
2406 clone->parseddesc = clonedesc;
2409 /* parse the descriptor to get the register allocation */
2411 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2415 codegen_createnativestub((functionptr) &builtin_clone_array, clone);
2417 /* XXX: field: length? */
2419 /* array classes are not loaded from class files */
2421 c->state |= CLASS_LOADED;
2422 c->parseddescs = (u1 *) clonedesc;
2423 c->parseddescsize = sizeof(methodinfo);
2424 c->classrefs = classrefs;
2425 c->classrefcount = 1;
2427 /* insert class into the loaded class cache */
2428 /* XXX free classinfo if NULL returned? */
2430 return classcache_store(loader, c, true);
2434 /* loader_close ****************************************************************
2436 Frees all resources.
2438 *******************************************************************************/
2440 void loader_close(void)
2447 * These are local overrides for various environment variables in Emacs.
2448 * Please do not remove this and leave it at the end of the file, where
2449 * Emacs will automagically detect them.
2450 * ---------------------------------------------------------------------
2453 * indent-tabs-mode: t
2457 * vim:noexpandtab:sw=4:ts=4: