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 4357 2006-01-22 23:33:38Z 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"
73 #if defined(ENABLE_ZLIB)
77 #include "vm/jit/asmpart.h"
78 #include "vm/jit/codegen-common.h"
81 /******************************************************************************/
83 /******************************************************************************/
90 #define LOADER_ASSERT(cond) assert(cond)
92 #define LOADER_ASSERT(cond)
96 /* loader_init *****************************************************************
98 Initializes all lists and loads all classes required for the system
101 *******************************************************************************/
103 bool loader_init(u1 *stackbottom)
105 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
106 list_classpath_entry *lce;
108 /* Initialize the monitor pointer for zip/jar file locking. */
110 for (lce = list_first(list_classpath_entries); lce != NULL;
111 lce = list_next(list_classpath_entries, lce))
112 if (lce->type == CLASSPATH_ARCHIVE)
113 initObjectLock((java_objectheader *) lce);
116 /* load some important classes */
118 if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
121 if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
124 if (!(class_java_lang_Cloneable =
125 load_class_bootstrap(utf_java_lang_Cloneable)))
128 if (!(class_java_io_Serializable =
129 load_class_bootstrap(utf_java_io_Serializable)))
133 /* load classes for wrapping primitive types */
135 if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
138 if (!(class_java_lang_Boolean =
139 load_class_bootstrap(utf_java_lang_Boolean)))
142 if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
145 if (!(class_java_lang_Character =
146 load_class_bootstrap(utf_java_lang_Character)))
149 if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
152 if (!(class_java_lang_Integer =
153 load_class_bootstrap(utf_java_lang_Integer)))
156 if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
159 if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
162 if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
166 /* load some other important classes */
168 if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
171 if (!(class_java_lang_ClassLoader =
172 load_class_bootstrap(utf_java_lang_ClassLoader)))
175 if (!(class_java_lang_SecurityManager =
176 load_class_bootstrap(utf_java_lang_SecurityManager)))
179 if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
182 if (!(class_java_lang_Thread =
183 load_class_bootstrap(utf_new_char("java/lang/Thread"))))
186 if (!(class_java_lang_ThreadGroup =
187 load_class_bootstrap(utf_java_lang_ThreadGroup)))
190 if (!(class_java_lang_VMThread =
191 load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
195 /* some classes which may be used more often */
197 if (!(class_java_lang_StackTraceElement =
198 load_class_bootstrap(utf_java_lang_StackTraceElement)))
201 if (!(class_java_lang_reflect_Constructor =
202 load_class_bootstrap(utf_java_lang_reflect_Constructor)))
205 if (!(class_java_lang_reflect_Field =
206 load_class_bootstrap(utf_java_lang_reflect_Field)))
209 if (!(class_java_lang_reflect_Method =
210 load_class_bootstrap(utf_java_lang_reflect_Method)))
213 if (!(class_java_security_PrivilegedAction =
214 load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
217 if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
220 if (!(arrayclass_java_lang_Object =
221 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
224 #if defined(USE_THREADS)
225 if (stackbottom != 0)
233 /* loader_load_all_classes *****************************************************
235 Loads all classes specified in the BOOTCLASSPATH.
237 *******************************************************************************/
239 void loader_load_all_classes(void)
241 list_classpath_entry *lce;
244 hashtable_zipfile_entry *htzfe;
247 for (lce = list_first(list_classpath_entries); lce != NULL;
248 lce = list_next(list_classpath_entries, lce)) {
249 #if defined(ENABLE_ZLIB)
250 if (lce->type == CLASSPATH_ARCHIVE) {
251 /* get the classes hashtable */
255 for (slot = 0; slot < ht->size; slot++) {
256 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
258 for (; htzfe; htzfe = htzfe->hashlink) {
261 /* skip all entries in META-INF and .properties,
264 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
265 strstr(u->text, ".properties") ||
266 strstr(u->text, ".png"))
269 /* load class from bootstrap classloader */
271 if (!load_class_bootstrap(u)) {
272 fprintf(stderr, "Error loading: ");
273 utf_fprint_classname(stderr, u);
274 fprintf(stderr, "\n");
276 /* print out exception and cause */
278 exceptions_print_exception(*exceptionptr);
285 #if defined(ENABLE_ZLIB)
292 /* skipattributebody ***********************************************************
294 Skips an attribute after the 16 bit reference to attribute_name has
297 *******************************************************************************/
299 static bool skipattributebody(classbuffer *cb)
303 if (!suck_check_classbuffer_size(cb, 4))
308 if (!suck_check_classbuffer_size(cb, len))
311 suck_skip_nbytes(cb, len);
317 /************************* Function: skipattributes ****************************
319 skips num attribute structures
321 *******************************************************************************/
323 static bool skipattributes(classbuffer *cb, u4 num)
328 for (i = 0; i < num; i++) {
329 if (!suck_check_classbuffer_size(cb, 2 + 4))
335 if (!suck_check_classbuffer_size(cb, len))
338 suck_skip_nbytes(cb, len);
345 /* load_constantpool ***********************************************************
347 Loads the constantpool of a class, the entries are transformed into
348 a simpler format by resolving references (a detailed overview of
349 the compact structures can be found in global.h).
351 *******************************************************************************/
353 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
356 /* The following structures are used to save information which cannot be
357 processed during the first pass. After the complete constantpool has
358 been traversed the references can be resolved.
359 (only in specific order) */
361 /* CONSTANT_Class entries */
362 typedef struct forward_class {
363 struct forward_class *next;
368 /* CONSTANT_String */
369 typedef struct forward_string {
370 struct forward_string *next;
375 /* CONSTANT_NameAndType */
376 typedef struct forward_nameandtype {
377 struct forward_nameandtype *next;
381 } forward_nameandtype;
383 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
384 typedef struct forward_fieldmethint {
385 struct forward_fieldmethint *next;
389 u2 nameandtype_index;
390 } forward_fieldmethint;
396 forward_class *forward_classes = NULL;
397 forward_string *forward_strings = NULL;
398 forward_nameandtype *forward_nameandtypes = NULL;
399 forward_fieldmethint *forward_fieldmethints = NULL;
403 forward_nameandtype *nfn;
404 forward_fieldmethint *nff;
412 /* number of entries in the constant_pool table plus one */
413 if (!suck_check_classbuffer_size(cb, 2))
416 cpcount = c->cpcount = suck_u2(cb);
418 /* allocate memory */
419 cptags = c->cptags = MNEW(u1, cpcount);
420 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
423 exceptions_throw_classformaterror(c, "Illegal constant pool size");
427 #if defined(ENABLE_STATISTICS)
429 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
432 /* initialize constantpool */
433 for (idx = 0; idx < cpcount; idx++) {
434 cptags[idx] = CONSTANT_UNUSED;
439 /******* first pass *******/
440 /* entries which cannot be resolved now are written into
441 temporary structures and traversed again later */
444 while (idx < cpcount) {
447 /* get constant type */
448 if (!suck_check_classbuffer_size(cb, 1))
455 nfc = DNEW(forward_class);
457 nfc->next = forward_classes;
458 forward_classes = nfc;
460 nfc->thisindex = idx;
461 /* reference to CONSTANT_NameAndType */
462 if (!suck_check_classbuffer_size(cb, 2))
465 nfc->name_index = suck_u2(cb);
470 case CONSTANT_String:
471 nfs = DNEW(forward_string);
473 nfs->next = forward_strings;
474 forward_strings = nfs;
476 nfs->thisindex = idx;
478 /* reference to CONSTANT_Utf8_info with string characters */
479 if (!suck_check_classbuffer_size(cb, 2))
482 nfs->string_index = suck_u2(cb);
487 case CONSTANT_NameAndType:
488 nfn = DNEW(forward_nameandtype);
490 nfn->next = forward_nameandtypes;
491 forward_nameandtypes = nfn;
493 nfn->thisindex = idx;
495 if (!suck_check_classbuffer_size(cb, 2 + 2))
498 /* reference to CONSTANT_Utf8_info containing simple name */
499 nfn->name_index = suck_u2(cb);
501 /* reference to CONSTANT_Utf8_info containing field or method
503 nfn->sig_index = suck_u2(cb);
508 case CONSTANT_Fieldref:
509 case CONSTANT_Methodref:
510 case CONSTANT_InterfaceMethodref:
511 nff = DNEW(forward_fieldmethint);
513 nff->next = forward_fieldmethints;
514 forward_fieldmethints = nff;
516 nff->thisindex = idx;
520 if (!suck_check_classbuffer_size(cb, 2 + 2))
523 /* class or interface type that contains the declaration of the
525 nff->class_index = suck_u2(cb);
527 /* name and descriptor of the field or method */
528 nff->nameandtype_index = suck_u2(cb);
533 case CONSTANT_Integer: {
534 constant_integer *ci = NEW(constant_integer);
536 #if defined(ENABLE_STATISTICS)
538 count_const_pool_len += sizeof(constant_integer);
541 if (!suck_check_classbuffer_size(cb, 4))
544 ci->value = suck_s4(cb);
545 cptags[idx] = CONSTANT_Integer;
552 case CONSTANT_Float: {
553 constant_float *cf = NEW(constant_float);
555 #if defined(ENABLE_STATISTICS)
557 count_const_pool_len += sizeof(constant_float);
560 if (!suck_check_classbuffer_size(cb, 4))
563 cf->value = suck_float(cb);
564 cptags[idx] = CONSTANT_Float;
571 case CONSTANT_Long: {
572 constant_long *cl = NEW(constant_long);
574 #if defined(ENABLE_STATISTICS)
576 count_const_pool_len += sizeof(constant_long);
579 if (!suck_check_classbuffer_size(cb, 8))
582 cl->value = suck_s8(cb);
583 cptags[idx] = CONSTANT_Long;
587 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
593 case CONSTANT_Double: {
594 constant_double *cd = NEW(constant_double);
596 #if defined(ENABLE_STATISTICS)
598 count_const_pool_len += sizeof(constant_double);
601 if (!suck_check_classbuffer_size(cb, 8))
604 cd->value = suck_double(cb);
605 cptags[idx] = CONSTANT_Double;
609 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
615 case CONSTANT_Utf8: {
618 /* number of bytes in the bytes array (not string-length) */
619 if (!suck_check_classbuffer_size(cb, 2))
622 length = suck_u2(cb);
623 cptags[idx] = CONSTANT_Utf8;
625 /* validate the string */
626 if (!suck_check_classbuffer_size(cb, length))
629 #ifdef ENABLE_VERIFIER
631 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
633 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
636 #endif /* ENABLE_VERIFIER */
637 /* insert utf-string into the utf-symboltable */
638 cpinfos[idx] = utf_new((char *) cb->pos, length);
640 /* skip bytes of the string (buffer size check above) */
641 suck_skip_nbytes(cb, length);
647 exceptions_throw_classformaterror(c, "Illegal constant pool type");
653 /* resolve entries in temporary structures */
655 while (forward_classes) {
657 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
661 #ifdef ENABLE_VERIFIER
662 if (opt_verify && !is_valid_name_utf(name)) {
663 exceptions_throw_classformaterror(c, "Class reference with invalid name");
666 #endif /* ENABLE_VERIFIER */
668 /* add all class references to the descriptor_pool */
670 if (!descriptor_pool_add_class(descpool, name))
673 cptags[forward_classes->thisindex] = CONSTANT_Class;
678 if (!(tc = load_class_bootstrap(name)))
681 /* link the class later, because we cannot link the class currently
683 list_addfirst(&unlinkedclasses, tc);
686 /* the classref is created later */
687 cpinfos[forward_classes->thisindex] = name;
689 nfc = forward_classes;
690 forward_classes = forward_classes->next;
693 while (forward_strings) {
695 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
699 /* resolve utf-string */
700 cptags[forward_strings->thisindex] = CONSTANT_String;
701 cpinfos[forward_strings->thisindex] = text;
703 nfs = forward_strings;
704 forward_strings = forward_strings->next;
707 while (forward_nameandtypes) {
708 constant_nameandtype *cn = NEW(constant_nameandtype);
710 #if defined(ENABLE_STATISTICS)
712 count_const_pool_len += sizeof(constant_nameandtype);
715 /* resolve simple name and descriptor */
716 cn->name = class_getconstant(c,
717 forward_nameandtypes->name_index,
722 cn->descriptor = class_getconstant(c,
723 forward_nameandtypes->sig_index,
728 #ifdef ENABLE_VERIFIER
731 if (!is_valid_name_utf(cn->name)) {
732 exceptions_throw_classformaterror(c,
733 "Illegal Field name \"%s\"",
739 /* disallow referencing <clinit> among others */
740 if (cn->name->text[0] == '<' && cn->name != utf_init) {
741 exceptions_throw_classformaterror(c, "Illegal reference to special method");
745 #endif /* ENABLE_VERIFIER */
747 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
748 cpinfos[forward_nameandtypes->thisindex] = cn;
750 nfn = forward_nameandtypes;
751 forward_nameandtypes = forward_nameandtypes->next;
754 while (forward_fieldmethints) {
755 constant_nameandtype *nat;
756 constant_FMIref *fmi = NEW(constant_FMIref);
758 #if defined(ENABLE_STATISTICS)
760 count_const_pool_len += sizeof(constant_FMIref);
762 /* resolve simple name and descriptor */
764 nat = class_getconstant(c,
765 forward_fieldmethints->nameandtype_index,
766 CONSTANT_NameAndType);
770 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
772 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
775 /* the classref is created later */
777 fmi->classref = (constant_classref *) (size_t) forward_fieldmethints->class_index;
778 fmi->name = nat->name;
779 fmi->descriptor = nat->descriptor;
781 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
782 cpinfos[forward_fieldmethints->thisindex] = fmi;
784 nff = forward_fieldmethints;
785 forward_fieldmethints = forward_fieldmethints->next;
788 /* everything was ok */
794 /* load_field ******************************************************************
796 Load everything about a class field from the class file and fill a
797 'fieldinfo' structure. For static fields, space in the data segment
800 *******************************************************************************/
802 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
804 static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
809 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
814 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
817 f->flags = suck_u2(cb);
819 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
824 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
828 f->parseddesc = NULL;
830 if (!descriptor_pool_add(descpool, u, NULL))
833 /* descriptor_pool_add accepts method descriptors, so we have to check */
834 /* against them here before the call of descriptor_to_basic_type below. */
835 if (u->text[0] == '(') {
836 exceptions_throw_classformaterror(c, "Method descriptor used for field");
840 #ifdef ENABLE_VERIFIER
843 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<') {
844 exceptions_throw_classformaterror(c,
845 "Illegal Field name \"%s\"",
850 /* check flag consistency */
851 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
853 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
854 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
855 exceptions_throw_classformaterror(c,
856 "Illegal field modifiers: 0x%X",
861 if (c->flags & ACC_INTERFACE) {
862 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
863 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
864 f->flags & ACC_TRANSIENT) {
865 exceptions_throw_classformaterror(c,
866 "Illegal field modifiers: 0x%X",
872 #endif /* ENABLE_VERIFIER */
874 f->type = jtype = descriptor_to_basic_type(f->descriptor); /* data type */
875 f->offset = 0; /* offset from start of object */
880 case TYPE_INT: f->value.i = 0; break;
881 case TYPE_FLOAT: f->value.f = 0.0; break;
882 case TYPE_DOUBLE: f->value.d = 0.0; break;
883 case TYPE_ADDRESS: f->value.a = NULL; break;
886 f->value.l = 0; break;
888 f->value.l.low = 0; f->value.l.high = 0; break;
892 /* read attributes */
893 if (!suck_check_classbuffer_size(cb, 2))
896 attrnum = suck_u2(cb);
897 for (i = 0; i < attrnum; i++) {
898 if (!suck_check_classbuffer_size(cb, 2))
901 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
904 if (u == utf_ConstantValue) {
905 if (!suck_check_classbuffer_size(cb, 4 + 2))
908 /* check attribute length */
909 if (suck_u4(cb) != 2) {
910 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
914 /* constant value attribute */
915 if (pindex != field_load_NOVALUE) {
916 exceptions_throw_classformaterror(c, "Multiple ConstantValue attributes");
920 /* index of value in constantpool */
921 pindex = suck_u2(cb);
923 /* initialize field with value from constantpool */
926 constant_integer *ci;
928 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
931 f->value.i = ci->value;
938 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
941 f->value.l = cl->value;
948 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
951 f->value.f = cf->value;
958 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
961 f->value.d = cd->value;
966 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
969 /* create javastring from compressed utf8-string */
970 f->value.a = literalstring_new(u);
974 log_text("Invalid Constant - Type");
978 /* unknown attribute */
979 if (!skipattributebody(cb))
984 /* everything was ok */
990 /* load_method *****************************************************************
992 Loads a method from the class file and fills an existing
993 'methodinfo' structure. For native methods, the function pointer
994 field is set to the real function pointer, for JavaVM methods a
995 pointer to the compiler is used preliminarily.
997 *******************************************************************************/
999 static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpool)
1010 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1011 initObjectLock(&m->header);
1014 #if defined(ENABLE_STATISTICS)
1016 count_all_methods++;
1019 m->thrownexceptionscount = 0;
1020 m->linenumbercount = 0;
1023 m->nativelyoverloaded = false;
1025 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
1028 m->flags = suck_u2(cb);
1030 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1035 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1039 m->parseddesc = NULL;
1041 if (!descriptor_pool_add(descpool, u, &argcount))
1044 #ifdef ENABLE_VERIFIER
1046 if (!is_valid_name_utf(m->name)) {
1047 exceptions_throw_classformaterror(c, "Method with invalid name");
1051 if (m->name->text[0] == '<' &&
1052 m->name != utf_init && m->name != utf_clinit) {
1053 exceptions_throw_classformaterror(c, "Method with invalid special name");
1057 #endif /* ENABLE_VERIFIER */
1059 if (!(m->flags & ACC_STATIC))
1060 argcount++; /* count the 'this' argument */
1062 #ifdef ENABLE_VERIFIER
1064 if (argcount > 255) {
1065 exceptions_throw_classformaterror(c, "Too many arguments in signature");
1069 /* check flag consistency */
1070 if (m->name != utf_clinit) {
1071 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1073 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1074 exceptions_throw_classformaterror(c,
1075 "Illegal method modifiers: 0x%X",
1080 if (m->flags & ACC_ABSTRACT) {
1081 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1082 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1083 exceptions_throw_classformaterror(c,
1084 "Illegal method modifiers: 0x%X",
1090 if (c->flags & ACC_INTERFACE) {
1091 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1092 exceptions_throw_classformaterror(c,
1093 "Illegal method modifiers: 0x%X",
1099 if (m->name == utf_init) {
1100 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1101 ACC_NATIVE | ACC_ABSTRACT)) {
1102 exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
1108 #endif /* ENABLE_VERIFIER */
1111 m->basicblockcount = 0;
1112 m->basicblocks = NULL;
1113 m->basicblockindex = NULL;
1114 m->instructioncount = 0;
1115 m->instructions = NULL;
1118 m->exceptiontable = NULL;
1119 m->stubroutine = NULL;
1121 m->entrypoint = NULL;
1122 m->methodUsed = NOTUSED;
1125 m->subRedefsUsed = 0;
1129 if (!suck_check_classbuffer_size(cb, 2))
1132 attrnum = suck_u2(cb);
1133 for (i = 0; i < attrnum; i++) {
1136 if (!suck_check_classbuffer_size(cb, 2))
1139 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1142 if (aname == utf_Code) {
1143 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1144 exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
1149 exceptions_throw_classformaterror(c, "Multiple Code attributes");
1153 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1157 m->maxstack = suck_u2(cb);
1158 m->maxlocals = suck_u2(cb);
1160 if (m->maxlocals < argcount) {
1161 exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
1165 if (!suck_check_classbuffer_size(cb, 4))
1168 m->jcodelength = suck_u4(cb);
1170 if (m->jcodelength == 0) {
1171 exceptions_throw_classformaterror(c, "Code of a method has length 0");
1175 if (m->jcodelength > 65535) {
1176 exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
1180 if (!suck_check_classbuffer_size(cb, m->jcodelength))
1183 m->jcode = MNEW(u1, m->jcodelength);
1184 suck_nbytes(m->jcode, cb, m->jcodelength);
1186 if (!suck_check_classbuffer_size(cb, 2))
1189 m->exceptiontablelength = suck_u2(cb);
1190 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->exceptiontablelength))
1193 m->exceptiontable = MNEW(exceptiontable, m->exceptiontablelength);
1195 #if defined(ENABLE_STATISTICS)
1197 count_vmcode_len += m->jcodelength + 18;
1198 count_extable_len +=
1199 m->exceptiontablelength * sizeof(exceptiontable);
1203 for (j = 0; j < m->exceptiontablelength; j++) {
1205 m->exceptiontable[j].startpc = suck_u2(cb);
1206 m->exceptiontable[j].endpc = suck_u2(cb);
1207 m->exceptiontable[j].handlerpc = suck_u2(cb);
1211 m->exceptiontable[j].catchtype.any = NULL;
1214 /* the classref is created later */
1215 if (!(m->exceptiontable[j].catchtype.any =
1216 (utf*)class_getconstant(c, idx, CONSTANT_Class)))
1221 if (!suck_check_classbuffer_size(cb, 2))
1224 codeattrnum = suck_u2(cb);
1226 for (; codeattrnum > 0; codeattrnum--) {
1229 if (!suck_check_classbuffer_size(cb, 2))
1232 if (!(caname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1235 if (caname == utf_LineNumberTable) {
1238 if (!suck_check_classbuffer_size(cb, 4 + 2))
1242 m->linenumbercount = suck_u2(cb);
1244 if (!suck_check_classbuffer_size(cb,
1245 (2 + 2) * m->linenumbercount))
1248 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1250 for (lncid = 0; lncid < m->linenumbercount; lncid++) {
1251 m->linenumbers[lncid].start_pc = suck_u2(cb);
1252 m->linenumbers[lncid].line_number = suck_u2(cb);
1256 if (!skipattributes(cb, codeattrnum))
1262 if (!skipattributebody(cb))
1267 } else if (aname == utf_Exceptions) {
1270 if (m->thrownexceptions) {
1271 exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
1275 if (!suck_check_classbuffer_size(cb, 4 + 2))
1278 suck_u4(cb); /* length */
1279 m->thrownexceptionscount = suck_u2(cb);
1281 if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1284 m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
1286 for (j = 0; j < m->thrownexceptionscount; j++) {
1287 /* the classref is created later */
1288 if (!((m->thrownexceptions)[j].any =
1289 (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1294 if (!skipattributebody(cb))
1299 if (!m->jcode && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1300 exceptions_throw_classformaterror(c, "Missing Code attribute");
1304 /* everything was ok */
1310 /* load_attribute **************************************************************
1312 Read attributes from classfile.
1314 *******************************************************************************/
1316 static bool load_attributes(classbuffer *cb, u4 num)
1324 for (i = 0; i < num; i++) {
1325 /* retrieve attribute name */
1326 if (!suck_check_classbuffer_size(cb, 2))
1329 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1332 if (aname == utf_InnerClasses) {
1333 /* innerclasses attribute */
1334 if (c->innerclass) {
1335 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
1339 if (!suck_check_classbuffer_size(cb, 4 + 2))
1342 /* skip attribute length */
1345 /* number of records */
1346 c->innerclasscount = suck_u2(cb);
1348 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
1351 /* allocate memory for innerclass structure */
1352 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
1354 for (j = 0; j < c->innerclasscount; j++) {
1355 /* The innerclass structure contains a class with an encoded
1356 name, its defining scope, its simple name and a bitmask of
1357 the access flags. If an inner class is not a member, its
1358 outer_class is NULL, if a class is anonymous, its name is
1361 innerclassinfo *info = c->innerclass + j;
1363 info->inner_class.ref =
1364 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
1365 info->outer_class.ref =
1366 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
1368 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1369 info->flags = suck_u2(cb);
1372 } else if (aname == utf_SourceFile) {
1373 if (!suck_check_classbuffer_size(cb, 4 + 2))
1376 if (suck_u4(cb) != 2) {
1377 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
1381 if (c->sourcefile) {
1382 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
1386 if (!(c->sourcefile = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1390 /* unknown attribute */
1391 if (!skipattributebody(cb))
1400 /* load_class_from_sysloader ***************************************************
1402 Load the class with the given name using the system class loader
1405 name.............the classname
1408 the loaded class, or
1409 NULL if an exception has been thrown
1411 *******************************************************************************/
1413 classinfo *load_class_from_sysloader(utf *name)
1416 java_objectheader *cl;
1419 LOADER_ASSERT(class_java_lang_Object);
1420 LOADER_ASSERT(class_java_lang_ClassLoader);
1421 LOADER_ASSERT(class_java_lang_ClassLoader->state & CLASS_LINKED);
1423 m = class_resolveclassmethod(class_java_lang_ClassLoader,
1424 utf_getSystemClassLoader,
1425 utf_void__java_lang_ClassLoader,
1426 class_java_lang_Object,
1432 ASM_CALLJAVAFUNCTION_ADR(cl, m, NULL, NULL, NULL, NULL);
1437 c = load_class_from_classloader(name, cl);
1443 /* load_class_from_classloader *************************************************
1445 Load the class with the given name using the given user-defined class loader.
1448 name.............the classname
1449 cl...............user-defined class loader
1452 the loaded class, or
1453 NULL if an exception has been thrown
1455 *******************************************************************************/
1457 classinfo *load_class_from_classloader(utf *name, java_objectheader *cl)
1459 java_objectheader *o;
1463 LOADER_ASSERT(name);
1465 /* lookup if this class has already been loaded */
1467 c = classcache_lookup(cl, name);
1472 /* if other class loader than bootstrap, call it */
1480 namelen = name->blength;
1482 /* handle array classes */
1483 if (text[0] == '[') {
1489 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1490 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1491 *exceptionptr = new_noclassdeffounderror(name);
1495 u = utf_new(text + 2, namelen - 3);
1497 if (!(comp = load_class_from_classloader(u, cl)))
1500 /* create the array class */
1502 c = class_array_of(comp, false);
1504 tmpc = classcache_store(cl, c, true);
1507 /* exception, free the loaded class */
1508 c->state &= ~CLASS_LOADING;
1515 /* load the component class */
1517 u = utf_new(text + 1, namelen - 1);
1519 if (!(comp = load_class_from_classloader(u, cl)))
1522 /* create the array class */
1524 c = class_array_of(comp, false);
1526 tmpc = classcache_store(cl, c, true);
1529 /* exception, free the loaded class */
1530 c->state &= ~CLASS_LOADING;
1537 /* primitive array classes are loaded by the bootstrap loader */
1539 c = load_class_bootstrap(name);
1545 LOADER_ASSERT(class_java_lang_Object);
1547 lc = class_resolveclassmethod(cl->vftbl->class,
1549 utf_java_lang_String__java_lang_Class,
1550 class_java_lang_Object,
1554 return false; /* exception */
1556 /* move return value into `o' and cast it afterwards to a classinfo* */
1558 ASM_CALLJAVAFUNCTION_ADR(o, lc, cl,
1559 javastring_new_slash_to_dot(name),
1562 c = (classinfo *) o;
1565 /* Store this class in the loaded class cache. If another
1566 class with the same (initloader,name) pair has been
1567 stored earlier it will be returned by classcache_store
1568 In this case classcache_store may not free the class
1569 because it has already been exposed to Java code which
1570 may have kept references to that class. */
1572 tmpc = classcache_store(cl, c, false);
1575 /* exception, free the loaded class */
1576 c->state &= ~CLASS_LOADING;
1583 /* loadClass has thrown an exception */
1584 /* we must convert ClassNotFoundException into NoClassDefFoundException */
1585 /* XXX maybe we should have a flag that avoids this conversion */
1586 /* for calling load_class_from_classloader from Class.forName */
1587 /* Currently we do a double conversion in these cases */
1588 classnotfoundexception_to_noclassdeffounderror();
1591 /* SUN compatible -verbose:class output */
1593 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1595 utf_display_classname(name);
1602 c = load_class_bootstrap(name);
1608 /* load_class_bootstrap ********************************************************
1610 Load the class with the given name using the bootstrap class loader.
1613 name.............the classname
1616 loaded classinfo, or
1617 NULL if an exception has been thrown
1620 load_class_bootstrap is synchronized. It can be treated as an
1623 *******************************************************************************/
1625 classinfo *load_class_bootstrap(utf *name)
1633 LOADER_ASSERT(name);
1635 /* lookup if this class has already been loaded */
1637 if ((r = classcache_lookup(NULL, name)))
1640 /* create the classinfo */
1642 c = class_create_classinfo(name);
1644 /* handle array classes */
1646 if (name->text[0] == '[') {
1647 c = load_newly_created_array(c, NULL);
1650 LOADER_ASSERT(c->state & CLASS_LOADED);
1654 #if defined(ENABLE_STATISTICS)
1657 if (getcompilingtime)
1658 compilingtime_stop();
1661 loadingtime_start();
1664 /* load classdata, throw exception on error */
1666 if ((cb = suck_start(c)) == NULL) {
1667 /* this normally means, the classpath was not set properly */
1669 if (name == utf_java_lang_Object)
1670 throw_cacao_exception_exit(string_java_lang_NoClassDefFoundError,
1671 "java/lang/Object");
1673 *exceptionptr = new_noclassdeffounderror(name);
1678 /* load the class from the buffer */
1680 r = load_class_from_classbuffer(cb);
1683 /* the class could not be loaded, free the classinfo struct */
1688 /* Store this class in the loaded class cache this step also
1689 checks the loading constraints. If the class has been loaded
1690 before, the earlier loaded class is returned. */
1692 classinfo *res = classcache_store(NULL, c, true);
1702 /* SUN compatible -verbose:class output */
1704 if (opt_verboseclass && r) {
1706 utf_display_classname(name);
1707 printf(" from %s]\n", cb->path);
1714 #if defined(ENABLE_STATISTICS)
1720 if (getcompilingtime)
1721 compilingtime_start();
1728 /* load_class_from_classbuffer *************************************************
1730 Loads everything interesting about a class from the class file. The
1731 'classinfo' structure must have been allocated previously.
1733 The super class and the interfaces implemented by this class need
1734 not be loaded. The link is set later by the function 'class_link'.
1736 The loaded class is removed from the list 'unloadedclasses' and
1737 added to the list 'unlinkedclasses'.
1740 This function is NOT synchronized!
1742 *******************************************************************************/
1744 classinfo *load_class_from_classbuffer(classbuffer *cb)
1752 descriptor_pool *descpool;
1753 #if defined(ENABLE_STATISTICS)
1758 /* get the classbuffer's class */
1762 /* the class is already loaded */
1764 if (c->state & CLASS_LOADED)
1767 #if defined(ENABLE_STATISTICS)
1769 count_class_loads++;
1772 #if !defined(NDEBUG)
1773 /* output for debugging purposes */
1776 log_message_class("Loading class: ", c);
1779 /* mark start of dump memory area */
1781 dumpsize = dump_size();
1783 /* class is currently loading */
1785 c->state |= CLASS_LOADING;
1787 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1788 goto return_exception;
1790 /* check signature */
1792 if (suck_u4(cb) != MAGIC) {
1793 exceptions_throw_classformaterror(c, "Bad magic number");
1795 goto return_exception;
1803 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1805 new_unsupportedclassversionerror(c,
1806 "Unsupported major.minor version %d.%d",
1809 goto return_exception;
1812 /* create a new descriptor pool */
1814 descpool = descriptor_pool_new(c);
1816 /* load the constant pool */
1818 if (!load_constantpool(cb, descpool))
1819 goto return_exception;
1821 c->classUsed = NOTUSED; /* not used initially CO-RT */
1826 if (!suck_check_classbuffer_size(cb, 2))
1827 goto return_exception;
1829 c->flags = suck_u2(cb);
1831 /* check ACC flags consistency */
1833 if (c->flags & ACC_INTERFACE) {
1834 if (!(c->flags & ACC_ABSTRACT)) {
1835 /* We work around this because interfaces in JDK 1.1 are
1836 * not declared abstract. */
1838 c->flags |= ACC_ABSTRACT;
1841 if (c->flags & ACC_FINAL) {
1842 exceptions_throw_classformaterror(c,
1843 "Illegal class modifiers: 0x%X",
1845 goto return_exception;
1848 if (c->flags & ACC_SUPER) {
1849 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1853 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1854 exceptions_throw_classformaterror(c,
1855 "Illegal class modifiers: 0x%X",
1857 goto return_exception;
1860 if (!suck_check_classbuffer_size(cb, 2 + 2))
1861 goto return_exception;
1866 if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1867 goto return_exception;
1869 if (c->name == utf_not_named_yet) {
1870 /* we finally have a name for this class */
1872 class_set_packagename(c);
1874 } else if (name != c->name) {
1878 msglen = utf_strlen(c->name) + strlen(" (wrong name: ") +
1879 utf_strlen(name) + strlen(")") + strlen("0");
1881 msg = MNEW(char, msglen);
1883 utf_sprint(msg, c->name);
1884 strcat(msg, " (wrong name: ");
1885 utf_strcat(msg, name);
1889 new_exception_message(string_java_lang_NoClassDefFoundError, msg);
1891 MFREE(msg, char, msglen);
1893 goto return_exception;
1896 /* retrieve superclass */
1898 c->super.any = NULL;
1899 if ((i = suck_u2(cb))) {
1900 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1901 goto return_exception;
1903 /* java.lang.Object may not have a super class. */
1905 if (c->name == utf_java_lang_Object) {
1907 new_exception_message(string_java_lang_ClassFormatError,
1908 "java.lang.Object with superclass");
1910 goto return_exception;
1913 /* Interfaces must have java.lang.Object as super class. */
1915 if ((c->flags & ACC_INTERFACE) &&
1916 supername != utf_java_lang_Object) {
1918 new_exception_message(string_java_lang_ClassFormatError,
1919 "Interfaces must have java.lang.Object as superclass");
1921 goto return_exception;
1927 /* This is only allowed for java.lang.Object. */
1929 if (c->name != utf_java_lang_Object) {
1930 exceptions_throw_classformaterror(c, "Bad superclass index");
1931 goto return_exception;
1935 /* retrieve interfaces */
1937 if (!suck_check_classbuffer_size(cb, 2))
1938 goto return_exception;
1940 c->interfacescount = suck_u2(cb);
1942 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1943 goto return_exception;
1945 c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
1946 for (i = 0; i < c->interfacescount; i++) {
1947 /* the classrefs are created later */
1948 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1949 goto return_exception;
1953 if (!suck_check_classbuffer_size(cb, 2))
1954 goto return_exception;
1956 c->fieldscount = suck_u2(cb);
1957 c->fields = GCNEW_UNCOLLECTABLE(fieldinfo, c->fieldscount);
1958 /* c->fields = MNEW(fieldinfo, c->fieldscount); */
1959 for (i = 0; i < c->fieldscount; i++) {
1960 if (!load_field(cb, &(c->fields[i]),descpool))
1961 goto return_exception;
1965 if (!suck_check_classbuffer_size(cb, 2))
1966 goto return_exception;
1968 c->methodscount = suck_u2(cb);
1969 /* c->methods = GCNEW(methodinfo, c->methodscount); */
1970 c->methods = MNEW(methodinfo, c->methodscount);
1971 for (i = 0; i < c->methodscount; i++) {
1972 if (!load_method(cb, &(c->methods[i]),descpool))
1973 goto return_exception;
1976 /* create the class reference table */
1979 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
1981 /* allocate space for the parsed descriptors */
1983 descriptor_pool_alloc_parsed_descriptors(descpool);
1985 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
1987 #if defined(ENABLE_STATISTICS)
1989 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
1990 count_classref_len += classrefsize;
1991 count_parsed_desc_len += descsize;
1995 /* put the classrefs in the constant pool */
1996 for (i = 0; i < c->cpcount; i++) {
1997 if (c->cptags[i] == CONSTANT_Class) {
1998 utf *name = (utf *) c->cpinfos[i];
1999 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
2003 /* set the super class reference */
2006 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
2008 goto return_exception;
2011 /* set the super interfaces references */
2013 for (i = 0; i < c->interfacescount; i++) {
2014 c->interfaces[i].ref =
2015 descriptor_pool_lookup_classref(descpool,
2016 (utf *) c->interfaces[i].any);
2017 if (!c->interfaces[i].ref)
2018 goto return_exception;
2021 /* parse field descriptors */
2023 for (i = 0; i < c->fieldscount; i++) {
2024 c->fields[i].parseddesc =
2025 descriptor_pool_parse_field_descriptor(descpool,
2026 c->fields[i].descriptor);
2027 if (!c->fields[i].parseddesc)
2028 goto return_exception;
2031 /* parse method descriptors */
2033 for (i = 0; i < c->methodscount; i++) {
2034 methodinfo *m = &c->methods[i];
2036 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
2037 m->flags, class_get_self_classref(m->class));
2039 goto return_exception;
2041 for (j = 0; j < m->exceptiontablelength; j++) {
2042 if (!m->exceptiontable[j].catchtype.any)
2044 if ((m->exceptiontable[j].catchtype.ref =
2045 descriptor_pool_lookup_classref(descpool,
2046 (utf *) m->exceptiontable[j].catchtype.any)) == NULL)
2047 goto return_exception;
2050 for (j = 0; j < m->thrownexceptionscount; j++) {
2051 if (!m->thrownexceptions[j].any)
2053 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
2054 (utf *) m->thrownexceptions[j].any)) == NULL)
2055 goto return_exception;
2059 /* parse the loaded descriptors */
2061 for (i = 0; i < c->cpcount; i++) {
2062 constant_FMIref *fmi;
2065 switch (c->cptags[i]) {
2066 case CONSTANT_Fieldref:
2067 fmi = (constant_FMIref *) c->cpinfos[i];
2068 fmi->parseddesc.fd =
2069 descriptor_pool_parse_field_descriptor(descpool,
2071 if (!fmi->parseddesc.fd)
2072 goto return_exception;
2073 index = (int) (size_t) fmi->classref;
2075 (constant_classref *) class_getconstant(c, index,
2078 goto return_exception;
2080 case CONSTANT_Methodref:
2081 case CONSTANT_InterfaceMethodref:
2082 fmi = (constant_FMIref *) c->cpinfos[i];
2083 index = (int) (size_t) fmi->classref;
2085 (constant_classref *) class_getconstant(c, index,
2088 goto return_exception;
2089 fmi->parseddesc.md =
2090 descriptor_pool_parse_method_descriptor(descpool,
2094 if (!fmi->parseddesc.md)
2095 goto return_exception;
2100 #ifdef ENABLE_VERIFIER
2101 /* Check if all fields and methods can be uniquely
2102 * identified by (name,descriptor). */
2105 /* We use a hash table here to avoid making the
2106 * average case quadratic in # of methods, fields.
2108 static int shift = 0;
2110 u2 *next; /* for chaining colliding hash entries */
2116 /* Allocate hashtable */
2117 len = c->methodscount;
2118 if (len < c->fieldscount) len = c->fieldscount;
2120 hashtab = MNEW(u2,(hashlen + len));
2121 next = hashtab + hashlen;
2123 /* Determine bitshift (to get good hash values) */
2133 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2135 for (i = 0; i < c->fieldscount; ++i) {
2136 fieldinfo *fi = c->fields + i;
2138 /* It's ok if we lose bits here */
2139 index = ((((size_t) fi->name) +
2140 ((size_t) fi->descriptor)) >> shift) % hashlen;
2142 if ((old = hashtab[index])) {
2146 if (c->fields[old].name == fi->name &&
2147 c->fields[old].descriptor == fi->descriptor) {
2148 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
2149 goto return_exception;
2151 } while ((old = next[old]));
2153 hashtab[index] = i + 1;
2157 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2159 for (i = 0; i < c->methodscount; ++i) {
2160 methodinfo *mi = c->methods + i;
2162 /* It's ok if we lose bits here */
2163 index = ((((size_t) mi->name) +
2164 ((size_t) mi->descriptor)) >> shift) % hashlen;
2168 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2169 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2173 if ((old = hashtab[index])) {
2177 if (c->methods[old].name == mi->name &&
2178 c->methods[old].descriptor == mi->descriptor) {
2179 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
2180 goto return_exception;
2182 } while ((old = next[old]));
2184 hashtab[index] = i + 1;
2187 MFREE(hashtab, u2, (hashlen + len));
2189 #endif /* ENABLE_VERIFIER */
2191 #if defined(ENABLE_STATISTICS)
2193 count_class_infos += sizeof(classinfo*) * c->interfacescount;
2194 count_class_infos += sizeof(fieldinfo) * c->fieldscount;
2195 count_class_infos += sizeof(methodinfo) * c->methodscount;
2199 /* load attribute structures */
2201 if (!suck_check_classbuffer_size(cb, 2))
2202 goto return_exception;
2204 if (!load_attributes(cb, suck_u2(cb)))
2205 goto return_exception;
2208 /* Pre java 1.5 version don't check this. This implementation is like
2209 java 1.5 do it: for class file version 45.3 we don't check it, older
2210 versions are checked.
2212 if ((ma == 45 && mi > 3) || ma > 45) {
2213 /* check if all data has been read */
2214 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
2216 if (classdata_left > 0) {
2217 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
2218 goto return_exception;
2223 /* release dump area */
2225 dump_release(dumpsize);
2227 /* revert loading state and class is loaded */
2229 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2231 #if !defined(NDEBUG)
2233 log_message_class("Loading done class: ", c);
2239 /* release dump area */
2241 dump_release(dumpsize);
2243 /* an exception has been thrown */
2249 /* load_newly_created_array ****************************************************
2251 Load a newly created array class.
2254 c....................the array class C has been loaded
2255 other classinfo......the array class was found in the class cache,
2257 NULL.................an exception has been thrown
2260 This is an internal function. Do not use it unless you know exactly
2263 Use one of the load_class_... functions for general array class loading.
2265 *******************************************************************************/
2267 classinfo *load_newly_created_array(classinfo *c, java_objectheader *loader)
2269 classinfo *comp = NULL;
2271 methoddesc *clonedesc;
2272 constant_classref *classrefs;
2277 text = c->name->text;
2278 namelen = c->name->blength;
2280 /* Check array class name */
2282 if (namelen < 2 || text[0] != '[') {
2283 *exceptionptr = new_noclassdeffounderror(c->name);
2287 /* Check the element type */
2291 /* c is an array of arrays. We have to create the component class. */
2293 u = utf_new(text + 1, namelen - 1);
2294 if (!(comp = load_class_from_classloader(u, loader)))
2297 LOADER_ASSERT(comp->state & CLASS_LOADED);
2303 /* the array's flags are that of the component class */
2304 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2305 c->classloader = comp->classloader;
2309 /* c is an array of objects. */
2311 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2312 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
2313 *exceptionptr = new_noclassdeffounderror(c->name);
2317 u = utf_new(text + 2, namelen - 3);
2319 if (!(comp = load_class_from_classloader(u, loader)))
2322 LOADER_ASSERT(comp->state & CLASS_LOADED);
2328 /* the array's flags are that of the component class */
2329 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2330 c->classloader = comp->classloader;
2334 /* c is an array of a primitive type */
2336 /* check for cases like `[II' */
2338 *exceptionptr = new_noclassdeffounderror(c->name);
2342 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2343 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2344 c->classloader = NULL;
2347 LOADER_ASSERT(class_java_lang_Object);
2348 LOADER_ASSERT(class_java_lang_Cloneable);
2349 LOADER_ASSERT(class_java_io_Serializable);
2351 /* setup the array class */
2353 c->super.cls = class_java_lang_Object;
2355 c->interfacescount = 2;
2356 c->interfaces = MNEW(classref_or_classinfo, 2);
2361 tc = class_java_lang_Cloneable;
2362 LOADER_ASSERT(tc->state & CLASS_LOADED);
2363 list_addfirst(&unlinkedclasses, tc);
2364 c->interfaces[0].cls = tc;
2366 tc = class_java_io_Serializable;
2367 LOADER_ASSERT(tc->state & CLASS_LOADED);
2368 list_addfirst(&unlinkedclasses, tc);
2369 c->interfaces[1].cls = tc;
2372 c->interfaces[0].cls = class_java_lang_Cloneable;
2373 c->interfaces[1].cls = class_java_io_Serializable;
2376 c->methodscount = 1;
2377 c->methods = MNEW(methodinfo, c->methodscount);
2379 classrefs = MNEW(constant_classref, 2);
2380 CLASSREF_INIT(classrefs[0], c, c->name);
2381 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2383 /* create descriptor for clone method */
2384 /* we need one paramslot which is reserved for the 'this' parameter */
2385 clonedesc = NEW(methoddesc);
2386 clonedesc->returntype.type = TYPE_ADDRESS;
2387 clonedesc->returntype.classref = classrefs + 1;
2388 clonedesc->returntype.arraydim = 0;
2389 /* initialize params to "empty", add real params below in
2390 descriptor_params_from_paramtypes */
2391 clonedesc->paramcount = 0;
2392 clonedesc->paramslots = 0;
2393 clonedesc->paramtypes[0].classref = classrefs + 0;
2395 /* create methodinfo */
2398 MSET(clone, 0, methodinfo, 1);
2400 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
2401 initObjectLock(&clone->header);
2404 /* if you delete the ACC_NATIVE below, set clone->maxlocals=1 (interpreter
2406 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2407 clone->name = utf_clone;
2408 clone->descriptor = utf_void__java_lang_Object;
2409 clone->parseddesc = clonedesc;
2411 clone->monoPoly = MONO;
2413 /* parse the descriptor to get the register allocation */
2415 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2419 codegen_createnativestub((functionptr) &builtin_clone_array, clone);
2421 /* XXX: field: length? */
2423 /* array classes are not loaded from class files */
2425 c->state |= CLASS_LOADED;
2426 c->parseddescs = (u1 *) clonedesc;
2427 c->parseddescsize = sizeof(methodinfo);
2428 c->classrefs = classrefs;
2429 c->classrefcount = 1;
2431 /* insert class into the loaded class cache */
2432 /* XXX free classinfo if NULL returned? */
2434 return classcache_store(loader, c, true);
2438 /* loader_close ****************************************************************
2440 Frees all resources.
2442 *******************************************************************************/
2444 void loader_close(void)
2451 * These are local overrides for various environment variables in Emacs.
2452 * Please do not remove this and leave it at the end of the file, where
2453 * Emacs will automagically detect them.
2454 * ---------------------------------------------------------------------
2457 * indent-tabs-mode: t