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 5845 2006-10-28 12:53:24Z edwin $
48 #include "mm/memory.h"
49 #include "native/native.h"
50 #include "native/include/java_lang_Throwable.h"
52 #if defined(ENABLE_THREADS)
53 # include "threads/native/threads.h"
56 #include "toolbox/logging.h"
57 #include "vm/builtin.h"
58 #include "vm/classcache.h"
59 #include "vm/exceptions.h"
60 #include "vm/global.h"
61 #include "vm/linker.h"
62 #include "vm/loader.h"
63 #include "vm/options.h"
64 #include "vm/statistics.h"
65 #include "vm/stringlocal.h"
69 #if defined(ENABLE_ZLIB)
73 #include "vm/jit/asmpart.h"
74 #include "vm/jit/codegen-common.h"
75 #include "vm/rt-timing.h"
77 #if defined(ENABLE_JVMTI)
78 #include "native/jvmti/cacaodbg.h"
82 /* loader_init *****************************************************************
84 Initializes all lists and loads all classes required for the system
87 *******************************************************************************/
89 bool loader_init(void)
91 #if defined(ENABLE_THREADS)
92 list_classpath_entry *lce;
94 /* Initialize the monitor pointer for zip/jar file locking. */
96 for (lce = list_first(list_classpath_entries); lce != NULL;
97 lce = list_next(list_classpath_entries, lce))
98 if (lce->type == CLASSPATH_ARCHIVE)
99 lock_init_object_lock((java_objectheader *) lce);
102 /* load some important classes */
104 if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
107 if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
110 if (!(class_java_lang_Cloneable =
111 load_class_bootstrap(utf_java_lang_Cloneable)))
114 if (!(class_java_io_Serializable =
115 load_class_bootstrap(utf_java_io_Serializable)))
119 /* load classes for wrapping primitive types */
121 if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
124 if (!(class_java_lang_Boolean =
125 load_class_bootstrap(utf_java_lang_Boolean)))
128 if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
131 if (!(class_java_lang_Character =
132 load_class_bootstrap(utf_java_lang_Character)))
135 if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
138 if (!(class_java_lang_Integer =
139 load_class_bootstrap(utf_java_lang_Integer)))
142 if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
145 if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
148 if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
152 /* load some other important classes */
154 if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
157 if (!(class_java_lang_ClassLoader =
158 load_class_bootstrap(utf_java_lang_ClassLoader)))
161 if (!(class_java_lang_SecurityManager =
162 load_class_bootstrap(utf_java_lang_SecurityManager)))
165 if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
168 if (!(class_java_lang_Thread =
169 load_class_bootstrap(utf_new_char("java/lang/Thread"))))
172 if (!(class_java_lang_ThreadGroup =
173 load_class_bootstrap(utf_java_lang_ThreadGroup)))
176 if (!(class_java_lang_VMSystem =
177 load_class_bootstrap(utf_new_char("java/lang/VMSystem"))))
180 if (!(class_java_lang_VMThread =
181 load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
185 /* some classes which may be used more often */
187 if (!(class_java_lang_StackTraceElement =
188 load_class_bootstrap(utf_java_lang_StackTraceElement)))
191 if (!(class_java_lang_reflect_Constructor =
192 load_class_bootstrap(utf_java_lang_reflect_Constructor)))
195 if (!(class_java_lang_reflect_Field =
196 load_class_bootstrap(utf_java_lang_reflect_Field)))
199 if (!(class_java_lang_reflect_Method =
200 load_class_bootstrap(utf_java_lang_reflect_Method)))
203 if (!(class_java_security_PrivilegedAction =
204 load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
207 if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
210 if (!(arrayclass_java_lang_Object =
211 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
218 /* loader_load_all_classes *****************************************************
220 Loads all classes specified in the BOOTCLASSPATH.
222 *******************************************************************************/
224 void loader_load_all_classes(void)
226 list_classpath_entry *lce;
227 #if defined(ENABLE_ZLIB)
230 hashtable_zipfile_entry *htzfe;
234 for (lce = list_first(list_classpath_entries); lce != NULL;
235 lce = list_next(list_classpath_entries, lce)) {
236 #if defined(ENABLE_ZLIB)
237 if (lce->type == CLASSPATH_ARCHIVE) {
238 /* get the classes hashtable */
242 for (slot = 0; slot < ht->size; slot++) {
243 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
245 for (; htzfe; htzfe = htzfe->hashlink) {
248 /* skip all entries in META-INF and .properties,
251 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
252 strstr(u->text, ".properties") ||
253 strstr(u->text, ".png"))
256 /* load class from bootstrap classloader */
258 if (!load_class_bootstrap(u)) {
259 fprintf(stderr, "Error loading: ");
260 utf_fprint_printable_ascii_classname(stderr, u);
261 fprintf(stderr, "\n");
264 /* print out exception and cause */
266 exceptions_print_exception(*exceptionptr);
274 #if defined(ENABLE_ZLIB)
281 /* skipattributebody ***********************************************************
283 Skips an attribute after the 16 bit reference to attribute_name has
286 *******************************************************************************/
288 static bool skipattributebody(classbuffer *cb)
292 if (!suck_check_classbuffer_size(cb, 4))
297 if (!suck_check_classbuffer_size(cb, len))
300 suck_skip_nbytes(cb, len);
306 /************************* Function: skipattributes ****************************
308 skips num attribute structures
310 *******************************************************************************/
312 static bool skipattributes(classbuffer *cb, u4 num)
317 for (i = 0; i < num; i++) {
318 if (!suck_check_classbuffer_size(cb, 2 + 4))
324 if (!suck_check_classbuffer_size(cb, len))
327 suck_skip_nbytes(cb, len);
334 /* load_constantpool ***********************************************************
336 Loads the constantpool of a class, the entries are transformed into
337 a simpler format by resolving references (a detailed overview of
338 the compact structures can be found in global.h).
340 *******************************************************************************/
342 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
345 /* The following structures are used to save information which cannot be
346 processed during the first pass. After the complete constantpool has
347 been traversed the references can be resolved.
348 (only in specific order) */
350 /* CONSTANT_Class entries */
351 typedef struct forward_class {
352 struct forward_class *next;
357 /* CONSTANT_String */
358 typedef struct forward_string {
359 struct forward_string *next;
364 /* CONSTANT_NameAndType */
365 typedef struct forward_nameandtype {
366 struct forward_nameandtype *next;
370 } forward_nameandtype;
372 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
373 typedef struct forward_fieldmethint {
374 struct forward_fieldmethint *next;
378 u2 nameandtype_index;
379 } forward_fieldmethint;
385 forward_class *forward_classes = NULL;
386 forward_string *forward_strings = NULL;
387 forward_nameandtype *forward_nameandtypes = NULL;
388 forward_fieldmethint *forward_fieldmethints = NULL;
392 forward_nameandtype *nfn;
393 forward_fieldmethint *nff;
401 /* number of entries in the constant_pool table plus one */
402 if (!suck_check_classbuffer_size(cb, 2))
405 cpcount = c->cpcount = suck_u2(cb);
407 /* allocate memory */
408 cptags = c->cptags = MNEW(u1, cpcount);
409 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
412 exceptions_throw_classformaterror(c, "Illegal constant pool size");
416 #if defined(ENABLE_STATISTICS)
418 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
421 /* initialize constantpool */
422 for (idx = 0; idx < cpcount; idx++) {
423 cptags[idx] = CONSTANT_UNUSED;
428 /******* first pass *******/
429 /* entries which cannot be resolved now are written into
430 temporary structures and traversed again later */
433 while (idx < cpcount) {
436 /* get constant type */
437 if (!suck_check_classbuffer_size(cb, 1))
444 nfc = DNEW(forward_class);
446 nfc->next = forward_classes;
447 forward_classes = nfc;
449 nfc->thisindex = idx;
450 /* reference to CONSTANT_NameAndType */
451 if (!suck_check_classbuffer_size(cb, 2))
454 nfc->name_index = suck_u2(cb);
459 case CONSTANT_String:
460 nfs = DNEW(forward_string);
462 nfs->next = forward_strings;
463 forward_strings = nfs;
465 nfs->thisindex = idx;
467 /* reference to CONSTANT_Utf8_info with string characters */
468 if (!suck_check_classbuffer_size(cb, 2))
471 nfs->string_index = suck_u2(cb);
476 case CONSTANT_NameAndType:
477 nfn = DNEW(forward_nameandtype);
479 nfn->next = forward_nameandtypes;
480 forward_nameandtypes = nfn;
482 nfn->thisindex = idx;
484 if (!suck_check_classbuffer_size(cb, 2 + 2))
487 /* reference to CONSTANT_Utf8_info containing simple name */
488 nfn->name_index = suck_u2(cb);
490 /* reference to CONSTANT_Utf8_info containing field or method
492 nfn->sig_index = suck_u2(cb);
497 case CONSTANT_Fieldref:
498 case CONSTANT_Methodref:
499 case CONSTANT_InterfaceMethodref:
500 nff = DNEW(forward_fieldmethint);
502 nff->next = forward_fieldmethints;
503 forward_fieldmethints = nff;
505 nff->thisindex = idx;
509 if (!suck_check_classbuffer_size(cb, 2 + 2))
512 /* class or interface type that contains the declaration of the
514 nff->class_index = suck_u2(cb);
516 /* name and descriptor of the field or method */
517 nff->nameandtype_index = suck_u2(cb);
522 case CONSTANT_Integer: {
523 constant_integer *ci = NEW(constant_integer);
525 #if defined(ENABLE_STATISTICS)
527 count_const_pool_len += sizeof(constant_integer);
530 if (!suck_check_classbuffer_size(cb, 4))
533 ci->value = suck_s4(cb);
534 cptags[idx] = CONSTANT_Integer;
541 case CONSTANT_Float: {
542 constant_float *cf = NEW(constant_float);
544 #if defined(ENABLE_STATISTICS)
546 count_const_pool_len += sizeof(constant_float);
549 if (!suck_check_classbuffer_size(cb, 4))
552 cf->value = suck_float(cb);
553 cptags[idx] = CONSTANT_Float;
560 case CONSTANT_Long: {
561 constant_long *cl = NEW(constant_long);
563 #if defined(ENABLE_STATISTICS)
565 count_const_pool_len += sizeof(constant_long);
568 if (!suck_check_classbuffer_size(cb, 8))
571 cl->value = suck_s8(cb);
572 cptags[idx] = CONSTANT_Long;
576 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
582 case CONSTANT_Double: {
583 constant_double *cd = NEW(constant_double);
585 #if defined(ENABLE_STATISTICS)
587 count_const_pool_len += sizeof(constant_double);
590 if (!suck_check_classbuffer_size(cb, 8))
593 cd->value = suck_double(cb);
594 cptags[idx] = CONSTANT_Double;
598 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
604 case CONSTANT_Utf8: {
607 /* number of bytes in the bytes array (not string-length) */
608 if (!suck_check_classbuffer_size(cb, 2))
611 length = suck_u2(cb);
612 cptags[idx] = CONSTANT_Utf8;
614 /* validate the string */
615 if (!suck_check_classbuffer_size(cb, length))
618 #ifdef ENABLE_VERIFIER
620 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
622 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
625 #endif /* ENABLE_VERIFIER */
626 /* insert utf-string into the utf-symboltable */
627 cpinfos[idx] = utf_new((char *) cb->pos, length);
629 /* skip bytes of the string (buffer size check above) */
630 suck_skip_nbytes(cb, length);
636 exceptions_throw_classformaterror(c, "Illegal constant pool type");
642 /* resolve entries in temporary structures */
644 while (forward_classes) {
646 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
650 #ifdef ENABLE_VERIFIER
651 if (opt_verify && !is_valid_name_utf(name)) {
652 exceptions_throw_classformaterror(c, "Class reference with invalid name");
655 #endif /* ENABLE_VERIFIER */
657 /* add all class references to the descriptor_pool */
659 if (!descriptor_pool_add_class(descpool, name))
662 cptags[forward_classes->thisindex] = CONSTANT_Class;
667 if (!(tc = load_class_bootstrap(name)))
670 /* link the class later, because we cannot link the class currently
672 list_add_first(&unlinkedclasses, tc);
675 /* the classref is created later */
676 cpinfos[forward_classes->thisindex] = name;
678 nfc = forward_classes;
679 forward_classes = forward_classes->next;
682 while (forward_strings) {
684 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
688 /* resolve utf-string */
689 cptags[forward_strings->thisindex] = CONSTANT_String;
690 cpinfos[forward_strings->thisindex] = text;
692 nfs = forward_strings;
693 forward_strings = forward_strings->next;
696 while (forward_nameandtypes) {
697 constant_nameandtype *cn = NEW(constant_nameandtype);
699 #if defined(ENABLE_STATISTICS)
701 count_const_pool_len += sizeof(constant_nameandtype);
704 /* resolve simple name and descriptor */
705 cn->name = class_getconstant(c,
706 forward_nameandtypes->name_index,
711 cn->descriptor = class_getconstant(c,
712 forward_nameandtypes->sig_index,
717 #ifdef ENABLE_VERIFIER
720 if (!is_valid_name_utf(cn->name)) {
721 exceptions_throw_classformaterror(c,
722 "Illegal Field name \"%s\"",
728 /* disallow referencing <clinit> among others */
729 if (cn->name->text[0] == '<' && cn->name != utf_init) {
730 exceptions_throw_classformaterror(c, "Illegal reference to special method");
734 #endif /* ENABLE_VERIFIER */
736 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
737 cpinfos[forward_nameandtypes->thisindex] = cn;
739 nfn = forward_nameandtypes;
740 forward_nameandtypes = forward_nameandtypes->next;
743 while (forward_fieldmethints) {
744 constant_nameandtype *nat;
745 constant_FMIref *fmi = NEW(constant_FMIref);
747 #if defined(ENABLE_STATISTICS)
749 count_const_pool_len += sizeof(constant_FMIref);
751 /* resolve simple name and descriptor */
753 nat = class_getconstant(c,
754 forward_fieldmethints->nameandtype_index,
755 CONSTANT_NameAndType);
759 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
761 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
764 /* the classref is created later */
766 fmi->p.index = forward_fieldmethints->class_index;
767 fmi->name = nat->name;
768 fmi->descriptor = nat->descriptor;
770 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
771 cpinfos[forward_fieldmethints->thisindex] = fmi;
773 nff = forward_fieldmethints;
774 forward_fieldmethints = forward_fieldmethints->next;
777 /* everything was ok */
783 /* load_field ******************************************************************
785 Load everything about a class field from the class file and fill a
786 'fieldinfo' structure. For static fields, space in the data segment
789 *******************************************************************************/
791 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
793 static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
798 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
803 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
806 f->flags = suck_u2(cb);
808 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
813 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
817 f->parseddesc = NULL;
819 if (!descriptor_pool_add(descpool, u, NULL))
822 /* descriptor_pool_add accepts method descriptors, so we have to check */
823 /* against them here before the call of descriptor_to_basic_type below. */
824 if (u->text[0] == '(') {
825 exceptions_throw_classformaterror(c, "Method descriptor used for field");
829 #ifdef ENABLE_VERIFIER
832 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<') {
833 exceptions_throw_classformaterror(c,
834 "Illegal Field name \"%s\"",
839 /* check flag consistency */
840 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
842 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
843 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
844 exceptions_throw_classformaterror(c,
845 "Illegal field modifiers: 0x%X",
850 if (c->flags & ACC_INTERFACE) {
851 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
852 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
853 f->flags & ACC_TRANSIENT) {
854 exceptions_throw_classformaterror(c,
855 "Illegal field modifiers: 0x%X",
861 #endif /* ENABLE_VERIFIER */
863 f->type = jtype = descriptor_to_basic_type(f->descriptor); /* data type */
864 f->offset = 0; /* offset from start of object */
882 if (!(f->flags & ACC_STATIC))
883 c->flags |= ACC_CLASS_HAS_POINTERS;
896 /* read attributes */
897 if (!suck_check_classbuffer_size(cb, 2))
900 attrnum = suck_u2(cb);
901 for (i = 0; i < attrnum; i++) {
902 if (!suck_check_classbuffer_size(cb, 2))
905 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
908 if (u == utf_ConstantValue) {
909 if (!suck_check_classbuffer_size(cb, 4 + 2))
912 /* check attribute length */
913 if (suck_u4(cb) != 2) {
914 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
918 /* constant value attribute */
919 if (pindex != field_load_NOVALUE) {
920 exceptions_throw_classformaterror(c, "Multiple ConstantValue attributes");
924 /* index of value in constantpool */
925 pindex = suck_u2(cb);
927 /* initialize field with value from constantpool */
930 constant_integer *ci;
932 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
935 f->value.i = ci->value;
942 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
945 f->value.l = cl->value;
952 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
955 f->value.f = cf->value;
962 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
965 f->value.d = cd->value;
970 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
973 /* create javastring from compressed utf8-string */
974 f->value.a = literalstring_new(u);
978 log_text("Invalid Constant - Type");
982 /* unknown attribute */
983 if (!skipattributebody(cb))
988 /* everything was ok */
994 /* load_method *****************************************************************
996 Loads a method from the class file and fills an existing
997 'methodinfo' structure. For native methods, the function pointer
998 field is set to the real function pointer, for JavaVM methods a
999 pointer to the compiler is used preliminarily.
1001 *******************************************************************************/
1003 static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpool)
1014 #if defined(ENABLE_THREADS)
1015 lock_init_object_lock(&m->header);
1018 #if defined(ENABLE_STATISTICS)
1020 count_all_methods++;
1023 /* all fields of m have been zeroed in load_class_from_classbuffer */
1027 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
1030 m->flags = suck_u2(cb);
1032 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1037 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
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 */
1111 if (!suck_check_classbuffer_size(cb, 2))
1114 attrnum = suck_u2(cb);
1115 for (i = 0; i < attrnum; i++) {
1118 if (!suck_check_classbuffer_size(cb, 2))
1121 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1124 if (aname == utf_Code) {
1125 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1126 exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
1131 exceptions_throw_classformaterror(c, "Multiple Code attributes");
1135 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1139 m->maxstack = suck_u2(cb);
1140 m->maxlocals = suck_u2(cb);
1142 if (m->maxlocals < argcount) {
1143 exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
1147 if (!suck_check_classbuffer_size(cb, 4))
1150 m->jcodelength = suck_u4(cb);
1152 if (m->jcodelength == 0) {
1153 exceptions_throw_classformaterror(c, "Code of a method has length 0");
1157 if (m->jcodelength > 65535) {
1158 exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
1162 if (!suck_check_classbuffer_size(cb, m->jcodelength))
1165 m->jcode = MNEW(u1, m->jcodelength);
1166 suck_nbytes(m->jcode, cb, m->jcodelength);
1168 if (!suck_check_classbuffer_size(cb, 2))
1171 m->rawexceptiontablelength = suck_u2(cb);
1172 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->rawexceptiontablelength))
1175 m->rawexceptiontable = MNEW(raw_exception_entry, m->rawexceptiontablelength);
1177 #if defined(ENABLE_STATISTICS)
1179 count_vmcode_len += m->jcodelength + 18;
1180 count_extable_len +=
1181 m->rawexceptiontablelength * sizeof(raw_exception_entry);
1185 for (j = 0; j < m->rawexceptiontablelength; j++) {
1187 m->rawexceptiontable[j].startpc = suck_u2(cb);
1188 m->rawexceptiontable[j].endpc = suck_u2(cb);
1189 m->rawexceptiontable[j].handlerpc = suck_u2(cb);
1193 m->rawexceptiontable[j].catchtype.any = NULL;
1196 /* the classref is created later */
1197 if (!(m->rawexceptiontable[j].catchtype.any =
1198 (utf*)class_getconstant(c, idx, CONSTANT_Class)))
1203 if (!suck_check_classbuffer_size(cb, 2))
1206 codeattrnum = suck_u2(cb);
1208 for (; codeattrnum > 0; codeattrnum--) {
1211 if (!suck_check_classbuffer_size(cb, 2))
1214 if (!(caname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1217 if (caname == utf_LineNumberTable) {
1220 if (!suck_check_classbuffer_size(cb, 4 + 2))
1224 m->linenumbercount = suck_u2(cb);
1226 if (!suck_check_classbuffer_size(cb,
1227 (2 + 2) * m->linenumbercount))
1230 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1232 for (lncid = 0; lncid < m->linenumbercount; lncid++) {
1233 m->linenumbers[lncid].start_pc = suck_u2(cb);
1234 m->linenumbers[lncid].line_number = suck_u2(cb);
1238 if (!skipattributes(cb, codeattrnum))
1244 if (!skipattributebody(cb))
1249 } else if (aname == utf_Exceptions) {
1252 if (m->thrownexceptions) {
1253 exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
1257 if (!suck_check_classbuffer_size(cb, 4 + 2))
1260 suck_u4(cb); /* length */
1261 m->thrownexceptionscount = suck_u2(cb);
1263 if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1266 m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
1268 for (j = 0; j < m->thrownexceptionscount; j++) {
1269 /* the classref is created later */
1270 if (!((m->thrownexceptions)[j].any =
1271 (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1276 if (!skipattributebody(cb))
1281 if (!m->jcode && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1282 exceptions_throw_classformaterror(c, "Missing Code attribute");
1286 /* everything was ok */
1292 /* load_attribute **************************************************************
1294 Read attributes from classfile.
1296 *******************************************************************************/
1298 static bool load_attributes(classbuffer *cb, u4 num)
1306 for (i = 0; i < num; i++) {
1307 /* retrieve attribute name */
1308 if (!suck_check_classbuffer_size(cb, 2))
1311 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1314 if (aname == utf_InnerClasses) {
1315 /* innerclasses attribute */
1316 if (c->innerclass) {
1317 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
1321 if (!suck_check_classbuffer_size(cb, 4 + 2))
1324 /* skip attribute length */
1327 /* number of records */
1328 c->innerclasscount = suck_u2(cb);
1330 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
1333 /* allocate memory for innerclass structure */
1334 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
1336 for (j = 0; j < c->innerclasscount; j++) {
1337 /* The innerclass structure contains a class with an encoded
1338 name, its defining scope, its simple name and a bitmask of
1339 the access flags. If an inner class is not a member, its
1340 outer_class is NULL, if a class is anonymous, its name is
1343 innerclassinfo *info = c->innerclass + j;
1345 info->inner_class.ref =
1346 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
1347 info->outer_class.ref =
1348 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
1350 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1351 info->flags = suck_u2(cb);
1354 } else if (aname == utf_SourceFile) {
1355 if (!suck_check_classbuffer_size(cb, 4 + 2))
1358 if (suck_u4(cb) != 2) {
1359 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
1363 if (c->sourcefile) {
1364 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
1368 if (!(c->sourcefile = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1372 /* unknown attribute */
1373 if (!skipattributebody(cb))
1382 /* load_class_from_sysloader ***************************************************
1384 Load the class with the given name using the system class loader
1387 name.............the classname
1390 the loaded class, or
1391 NULL if an exception has been thrown
1393 *******************************************************************************/
1395 classinfo *load_class_from_sysloader(utf *name)
1398 java_objectheader *cl;
1401 assert(class_java_lang_Object);
1402 assert(class_java_lang_ClassLoader);
1403 assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
1405 m = class_resolveclassmethod(class_java_lang_ClassLoader,
1406 utf_getSystemClassLoader,
1407 utf_void__java_lang_ClassLoader,
1408 class_java_lang_Object,
1414 cl = vm_call_method(m, NULL);
1419 c = load_class_from_classloader(name, cl);
1425 /* load_class_from_classloader *************************************************
1427 Load the class with the given name using the given user-defined class loader.
1430 name.............the classname
1431 cl...............user-defined class loader
1434 the loaded class, or
1435 NULL if an exception has been thrown
1437 *******************************************************************************/
1439 classinfo *load_class_from_classloader(utf *name, java_objectheader *cl)
1441 java_objectheader *o;
1444 java_lang_String *s;
1445 #if defined(ENABLE_RT_TIMING)
1446 struct timespec time_start, time_lookup, time_prepare, time_java,
1450 RT_TIMING_GET_TIME(time_start);
1454 /* lookup if this class has already been loaded */
1456 c = classcache_lookup(cl, name);
1458 RT_TIMING_GET_TIME(time_lookup);
1459 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1464 /* if other class loader than bootstrap, call it */
1472 namelen = name->blength;
1474 /* handle array classes */
1475 if (text[0] == '[') {
1481 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1482 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1483 *exceptionptr = new_noclassdeffounderror(name);
1487 u = utf_new(text + 2, namelen - 3);
1489 if (!(comp = load_class_from_classloader(u, cl)))
1492 /* create the array class */
1494 c = class_array_of(comp, false);
1496 tmpc = classcache_store(cl, c, true);
1499 /* exception, free the loaded class */
1500 c->state &= ~CLASS_LOADING;
1507 /* load the component class */
1509 u = utf_new(text + 1, namelen - 1);
1511 if (!(comp = load_class_from_classloader(u, cl)))
1514 /* create the array class */
1516 c = class_array_of(comp, false);
1518 tmpc = classcache_store(cl, c, true);
1521 /* exception, free the loaded class */
1522 c->state &= ~CLASS_LOADING;
1529 /* primitive array classes are loaded by the bootstrap loader */
1531 c = load_class_bootstrap(name);
1537 assert(class_java_lang_Object);
1539 lc = class_resolveclassmethod(cl->vftbl->class,
1541 utf_java_lang_String__java_lang_Class,
1542 class_java_lang_Object,
1546 return false; /* exception */
1548 /* move return value into `o' and cast it afterwards to a classinfo* */
1550 s = javastring_new_slash_to_dot(name);
1552 RT_TIMING_GET_TIME(time_prepare);
1554 o = vm_call_method(lc, cl, s);
1556 RT_TIMING_GET_TIME(time_java);
1558 c = (classinfo *) o;
1561 /* Store this class in the loaded class cache. If another
1562 class with the same (initloader,name) pair has been
1563 stored earlier it will be returned by classcache_store
1564 In this case classcache_store may not free the class
1565 because it has already been exposed to Java code which
1566 may have kept references to that class. */
1568 tmpc = classcache_store(cl, c, false);
1571 /* exception, free the loaded class */
1572 c->state &= ~CLASS_LOADING;
1579 /* loadClass has thrown an exception. We must convert
1580 ClassNotFoundException into
1581 NoClassDefFoundException. */
1583 /* XXX Maybe we should have a flag that avoids this
1584 conversion for calling load_class_from_classloader from
1585 Class.forName. Currently we do a double conversion in
1588 classnotfoundexception_to_noclassdeffounderror();
1591 RT_TIMING_GET_TIME(time_cache);
1593 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1594 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1595 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1597 /* SUN compatible -verbose:class output */
1599 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1601 utf_display_printable_ascii_classname(name);
1605 #if defined(ENABLE_JVMTI)
1606 /* fire Class Load JVMTI event */
1607 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1614 c = load_class_bootstrap(name);
1620 /* load_class_bootstrap ********************************************************
1622 Load the class with the given name using the bootstrap class loader.
1625 name.............the classname
1628 loaded classinfo, or
1629 NULL if an exception has been thrown
1632 load_class_bootstrap is synchronized. It can be treated as an
1635 *******************************************************************************/
1637 classinfo *load_class_bootstrap(utf *name)
1642 #if defined(ENABLE_RT_TIMING)
1643 struct timespec time_start, time_lookup, time_array, time_suck,
1644 time_load, time_cache;
1647 RT_TIMING_GET_TIME(time_start);
1653 /* lookup if this class has already been loaded */
1655 if ((r = classcache_lookup(NULL, name))) {
1657 RT_TIMING_GET_TIME(time_lookup);
1658 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1663 RT_TIMING_GET_TIME(time_lookup);
1664 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1666 /* create the classinfo */
1668 c = class_create_classinfo(name);
1670 /* handle array classes */
1672 if (name->text[0] == '[') {
1673 c = load_newly_created_array(c, NULL);
1676 assert(c->state & CLASS_LOADED);
1678 RT_TIMING_GET_TIME(time_array);
1679 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1684 #if defined(ENABLE_STATISTICS)
1687 if (opt_getcompilingtime)
1688 compilingtime_stop();
1690 if (opt_getloadingtime)
1691 loadingtime_start();
1694 /* load classdata, throw exception on error */
1696 if ((cb = suck_start(c)) == NULL) {
1697 /* this normally means, the classpath was not set properly */
1699 if (name == utf_java_lang_Object)
1700 throw_cacao_exception_exit(string_java_lang_NoClassDefFoundError,
1701 "java/lang/Object");
1703 *exceptionptr = new_noclassdeffounderror(name);
1708 RT_TIMING_GET_TIME(time_suck);
1710 /* load the class from the buffer */
1712 r = load_class_from_classbuffer(cb);
1714 RT_TIMING_GET_TIME(time_load);
1717 /* the class could not be loaded, free the classinfo struct */
1722 /* Store this class in the loaded class cache this step also
1723 checks the loading constraints. If the class has been loaded
1724 before, the earlier loaded class is returned. */
1726 classinfo *res = classcache_store(NULL, c, true);
1736 RT_TIMING_GET_TIME(time_cache);
1738 /* SUN compatible -verbose:class output */
1740 if (opt_verboseclass && r) {
1742 utf_display_printable_ascii_classname(name);
1743 printf(" from %s]\n", cb->path);
1750 #if defined(ENABLE_STATISTICS)
1753 if (opt_getloadingtime)
1756 if (opt_getcompilingtime)
1757 compilingtime_start();
1760 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1761 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1762 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1763 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1769 /* load_class_from_classbuffer *************************************************
1771 Loads everything interesting about a class from the class file. The
1772 'classinfo' structure must have been allocated previously.
1774 The super class and the interfaces implemented by this class need
1775 not be loaded. The link is set later by the function 'class_link'.
1777 The loaded class is removed from the list 'unloadedclasses' and
1778 added to the list 'unlinkedclasses'.
1781 This function is NOT synchronized!
1783 *******************************************************************************/
1785 classinfo *load_class_from_classbuffer(classbuffer *cb)
1793 descriptor_pool *descpool;
1794 #if defined(ENABLE_STATISTICS)
1798 #if defined(ENABLE_RT_TIMING)
1799 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1800 time_setup, time_fields, time_methods, time_classrefs,
1801 time_descs, time_setrefs, time_parsefds, time_parsemds,
1802 time_parsecpool, time_verify, time_attrs;
1805 RT_TIMING_GET_TIME(time_start);
1807 /* get the classbuffer's class */
1811 /* the class is already loaded */
1813 if (c->state & CLASS_LOADED)
1816 #if defined(ENABLE_STATISTICS)
1818 count_class_loads++;
1821 #if !defined(NDEBUG)
1822 /* output for debugging purposes */
1825 log_message_class("Loading class: ", c);
1828 /* mark start of dump memory area */
1830 dumpsize = dump_size();
1832 /* class is currently loading */
1834 c->state |= CLASS_LOADING;
1836 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1837 goto return_exception;
1839 /* check signature */
1841 if (suck_u4(cb) != MAGIC) {
1842 exceptions_throw_classformaterror(c, "Bad magic number");
1844 goto return_exception;
1852 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1854 new_unsupportedclassversionerror(c,
1855 "Unsupported major.minor version %d.%d",
1858 goto return_exception;
1860 RT_TIMING_GET_TIME(time_checks);
1862 /* create a new descriptor pool */
1864 descpool = descriptor_pool_new(c);
1866 RT_TIMING_GET_TIME(time_ndpool);
1868 /* load the constant pool */
1870 if (!load_constantpool(cb, descpool))
1871 goto return_exception;
1873 RT_TIMING_GET_TIME(time_cpool);
1877 if (!suck_check_classbuffer_size(cb, 2))
1878 goto return_exception;
1880 c->flags = suck_u2(cb);
1882 /* check ACC flags consistency */
1884 if (c->flags & ACC_INTERFACE) {
1885 if (!(c->flags & ACC_ABSTRACT)) {
1886 /* We work around this because interfaces in JDK 1.1 are
1887 * not declared abstract. */
1889 c->flags |= ACC_ABSTRACT;
1892 if (c->flags & ACC_FINAL) {
1893 exceptions_throw_classformaterror(c,
1894 "Illegal class modifiers: 0x%X",
1896 goto return_exception;
1899 if (c->flags & ACC_SUPER) {
1900 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1904 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1905 exceptions_throw_classformaterror(c,
1906 "Illegal class modifiers: 0x%X",
1908 goto return_exception;
1911 if (!suck_check_classbuffer_size(cb, 2 + 2))
1912 goto return_exception;
1917 if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1918 goto return_exception;
1920 if (c->name == utf_not_named_yet) {
1921 /* we finally have a name for this class */
1923 class_set_packagename(c);
1925 } else if (name != c->name) {
1929 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
1930 utf_bytes(name) + strlen(")") + strlen("0");
1932 msg = MNEW(char, msglen);
1934 utf_copy_classname(msg, c->name);
1935 strcat(msg, " (wrong name: ");
1936 utf_cat_classname(msg, name);
1940 new_exception_message(string_java_lang_NoClassDefFoundError, msg);
1942 MFREE(msg, char, msglen);
1944 goto return_exception;
1947 /* retrieve superclass */
1949 c->super.any = NULL;
1950 if ((i = suck_u2(cb))) {
1951 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1952 goto return_exception;
1954 /* java.lang.Object may not have a super class. */
1956 if (c->name == utf_java_lang_Object) {
1958 new_exception_message(string_java_lang_ClassFormatError,
1959 "java.lang.Object with superclass");
1961 goto return_exception;
1964 /* Interfaces must have java.lang.Object as super class. */
1966 if ((c->flags & ACC_INTERFACE) &&
1967 supername != utf_java_lang_Object) {
1969 new_exception_message(string_java_lang_ClassFormatError,
1970 "Interfaces must have java.lang.Object as superclass");
1972 goto return_exception;
1978 /* This is only allowed for java.lang.Object. */
1980 if (c->name != utf_java_lang_Object) {
1981 exceptions_throw_classformaterror(c, "Bad superclass index");
1982 goto return_exception;
1986 /* retrieve interfaces */
1988 if (!suck_check_classbuffer_size(cb, 2))
1989 goto return_exception;
1991 c->interfacescount = suck_u2(cb);
1993 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1994 goto return_exception;
1996 c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
1997 for (i = 0; i < c->interfacescount; i++) {
1998 /* the classrefs are created later */
1999 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2000 goto return_exception;
2003 RT_TIMING_GET_TIME(time_setup);
2006 if (!suck_check_classbuffer_size(cb, 2))
2007 goto return_exception;
2009 c->fieldscount = suck_u2(cb);
2010 c->fields = GCNEW_UNCOLLECTABLE(fieldinfo, c->fieldscount);
2011 /* c->fields = MNEW(fieldinfo, c->fieldscount); */
2012 for (i = 0; i < c->fieldscount; i++) {
2013 if (!load_field(cb, &(c->fields[i]),descpool))
2014 goto return_exception;
2017 RT_TIMING_GET_TIME(time_fields);
2020 if (!suck_check_classbuffer_size(cb, 2))
2021 goto return_exception;
2023 c->methodscount = suck_u2(cb);
2024 /* c->methods = GCNEW(methodinfo, c->methodscount); */
2025 c->methods = MNEW(methodinfo, c->methodscount);
2027 MZERO(c->methods, methodinfo, c->methodscount);
2029 for (i = 0; i < c->methodscount; i++) {
2030 if (!load_method(cb, &(c->methods[i]),descpool))
2031 goto return_exception;
2034 RT_TIMING_GET_TIME(time_methods);
2036 /* create the class reference table */
2039 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
2041 RT_TIMING_GET_TIME(time_classrefs);
2043 /* allocate space for the parsed descriptors */
2045 descriptor_pool_alloc_parsed_descriptors(descpool);
2047 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
2049 #if defined(ENABLE_STATISTICS)
2051 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
2052 count_classref_len += classrefsize;
2053 count_parsed_desc_len += descsize;
2057 RT_TIMING_GET_TIME(time_descs);
2059 /* put the classrefs in the constant pool */
2060 for (i = 0; i < c->cpcount; i++) {
2061 if (c->cptags[i] == CONSTANT_Class) {
2062 utf *name = (utf *) c->cpinfos[i];
2063 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
2067 /* set the super class reference */
2070 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
2072 goto return_exception;
2075 /* set the super interfaces references */
2077 for (i = 0; i < c->interfacescount; i++) {
2078 c->interfaces[i].ref =
2079 descriptor_pool_lookup_classref(descpool,
2080 (utf *) c->interfaces[i].any);
2081 if (!c->interfaces[i].ref)
2082 goto return_exception;
2085 RT_TIMING_GET_TIME(time_setrefs);
2087 /* parse field descriptors */
2089 for (i = 0; i < c->fieldscount; i++) {
2090 c->fields[i].parseddesc =
2091 descriptor_pool_parse_field_descriptor(descpool,
2092 c->fields[i].descriptor);
2093 if (!c->fields[i].parseddesc)
2094 goto return_exception;
2097 RT_TIMING_GET_TIME(time_parsefds);
2099 /* parse method descriptors */
2101 for (i = 0; i < c->methodscount; i++) {
2102 methodinfo *m = &c->methods[i];
2104 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
2105 m->flags, class_get_self_classref(m->class));
2107 goto return_exception;
2109 for (j = 0; j < m->rawexceptiontablelength; j++) {
2110 if (!m->rawexceptiontable[j].catchtype.any)
2112 if ((m->rawexceptiontable[j].catchtype.ref =
2113 descriptor_pool_lookup_classref(descpool,
2114 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
2115 goto return_exception;
2118 for (j = 0; j < m->thrownexceptionscount; j++) {
2119 if (!m->thrownexceptions[j].any)
2121 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
2122 (utf *) m->thrownexceptions[j].any)) == NULL)
2123 goto return_exception;
2127 RT_TIMING_GET_TIME(time_parsemds);
2129 /* parse the loaded descriptors */
2131 for (i = 0; i < c->cpcount; i++) {
2132 constant_FMIref *fmi;
2135 switch (c->cptags[i]) {
2136 case CONSTANT_Fieldref:
2137 fmi = (constant_FMIref *) c->cpinfos[i];
2138 fmi->parseddesc.fd =
2139 descriptor_pool_parse_field_descriptor(descpool,
2141 if (!fmi->parseddesc.fd)
2142 goto return_exception;
2143 index = fmi->p.index;
2145 (constant_classref *) class_getconstant(c, index,
2147 if (!fmi->p.classref)
2148 goto return_exception;
2150 case CONSTANT_Methodref:
2151 case CONSTANT_InterfaceMethodref:
2152 fmi = (constant_FMIref *) c->cpinfos[i];
2153 index = fmi->p.index;
2155 (constant_classref *) class_getconstant(c, index,
2157 if (!fmi->p.classref)
2158 goto return_exception;
2159 fmi->parseddesc.md =
2160 descriptor_pool_parse_method_descriptor(descpool,
2164 if (!fmi->parseddesc.md)
2165 goto return_exception;
2170 RT_TIMING_GET_TIME(time_parsecpool);
2172 #ifdef ENABLE_VERIFIER
2173 /* Check if all fields and methods can be uniquely
2174 * identified by (name,descriptor). */
2177 /* We use a hash table here to avoid making the
2178 * average case quadratic in # of methods, fields.
2180 static int shift = 0;
2182 u2 *next; /* for chaining colliding hash entries */
2188 /* Allocate hashtable */
2189 len = c->methodscount;
2190 if (len < c->fieldscount) len = c->fieldscount;
2192 hashtab = MNEW(u2,(hashlen + len));
2193 next = hashtab + hashlen;
2195 /* Determine bitshift (to get good hash values) */
2205 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2207 for (i = 0; i < c->fieldscount; ++i) {
2208 fieldinfo *fi = c->fields + i;
2210 /* It's ok if we lose bits here */
2211 index = ((((size_t) fi->name) +
2212 ((size_t) fi->descriptor)) >> shift) % hashlen;
2214 if ((old = hashtab[index])) {
2218 if (c->fields[old].name == fi->name &&
2219 c->fields[old].descriptor == fi->descriptor) {
2220 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
2221 goto return_exception;
2223 } while ((old = next[old]));
2225 hashtab[index] = i + 1;
2229 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2231 for (i = 0; i < c->methodscount; ++i) {
2232 methodinfo *mi = c->methods + i;
2234 /* It's ok if we lose bits here */
2235 index = ((((size_t) mi->name) +
2236 ((size_t) mi->descriptor)) >> shift) % hashlen;
2240 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2241 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2245 if ((old = hashtab[index])) {
2249 if (c->methods[old].name == mi->name &&
2250 c->methods[old].descriptor == mi->descriptor) {
2251 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
2252 goto return_exception;
2254 } while ((old = next[old]));
2256 hashtab[index] = i + 1;
2259 MFREE(hashtab, u2, (hashlen + len));
2261 #endif /* ENABLE_VERIFIER */
2263 RT_TIMING_GET_TIME(time_verify);
2265 #if defined(ENABLE_STATISTICS)
2267 size_classinfo += sizeof(classinfo*) * c->interfacescount;
2268 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
2269 size_methodinfo += sizeof(methodinfo) * c->methodscount;
2273 /* load attribute structures */
2275 if (!suck_check_classbuffer_size(cb, 2))
2276 goto return_exception;
2278 if (!load_attributes(cb, suck_u2(cb)))
2279 goto return_exception;
2281 /* Pre Java 1.5 version don't check this. This implementation is like
2282 Java 1.5 do it: for class file version 45.3 we don't check it, older
2283 versions are checked.
2286 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
2287 /* check if all data has been read */
2288 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
2290 if (classdata_left > 0) {
2291 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
2292 goto return_exception;
2296 RT_TIMING_GET_TIME(time_attrs);
2298 /* release dump area */
2300 dump_release(dumpsize);
2302 /* revert loading state and class is loaded */
2304 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2306 #if defined(ENABLE_JVMTI)
2307 /* fire Class Prepare JVMTI event */
2310 jvmti_ClassLoadPrepare(true, c);
2313 #if !defined(NDEBUG)
2315 log_message_class("Loading done class: ", c);
2318 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
2319 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
2320 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
2321 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
2322 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
2323 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
2324 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
2325 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
2326 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
2327 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
2328 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
2329 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
2330 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
2331 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
2332 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
2337 /* release dump area */
2339 dump_release(dumpsize);
2341 /* an exception has been thrown */
2347 /* load_newly_created_array ****************************************************
2349 Load a newly created array class.
2352 c....................the array class C has been loaded
2353 other classinfo......the array class was found in the class cache,
2355 NULL.................an exception has been thrown
2358 This is an internal function. Do not use it unless you know exactly
2361 Use one of the load_class_... functions for general array class loading.
2363 *******************************************************************************/
2365 classinfo *load_newly_created_array(classinfo *c, java_objectheader *loader)
2367 classinfo *comp = NULL;
2369 methoddesc *clonedesc;
2370 constant_classref *classrefs;
2375 text = c->name->text;
2376 namelen = c->name->blength;
2378 /* Check array class name */
2380 if (namelen < 2 || text[0] != '[') {
2381 *exceptionptr = new_noclassdeffounderror(c->name);
2385 /* Check the element type */
2389 /* c is an array of arrays. We have to create the component class. */
2391 u = utf_new(text + 1, namelen - 1);
2392 if (!(comp = load_class_from_classloader(u, loader)))
2395 assert(comp->state & CLASS_LOADED);
2401 /* the array's flags are that of the component class */
2402 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2403 c->classloader = comp->classloader;
2407 /* c is an array of objects. */
2409 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2410 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
2411 *exceptionptr = new_noclassdeffounderror(c->name);
2415 u = utf_new(text + 2, namelen - 3);
2417 if (!(comp = load_class_from_classloader(u, loader)))
2420 assert(comp->state & CLASS_LOADED);
2426 /* the array's flags are that of the component class */
2427 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2428 c->classloader = comp->classloader;
2432 /* c is an array of a primitive type */
2434 /* check for cases like `[II' */
2436 *exceptionptr = new_noclassdeffounderror(c->name);
2440 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2441 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2442 c->classloader = NULL;
2445 assert(class_java_lang_Object);
2446 assert(class_java_lang_Cloneable);
2447 assert(class_java_io_Serializable);
2449 /* setup the array class */
2451 c->super.cls = class_java_lang_Object;
2453 c->interfacescount = 2;
2454 c->interfaces = MNEW(classref_or_classinfo, 2);
2459 tc = class_java_lang_Cloneable;
2460 assert(tc->state & CLASS_LOADED);
2461 list_add_first(&unlinkedclasses, tc);
2462 c->interfaces[0].cls = tc;
2464 tc = class_java_io_Serializable;
2465 assert(tc->state & CLASS_LOADED);
2466 list_add_first(&unlinkedclasses, tc);
2467 c->interfaces[1].cls = tc;
2470 c->interfaces[0].cls = class_java_lang_Cloneable;
2471 c->interfaces[1].cls = class_java_io_Serializable;
2474 c->methodscount = 1;
2475 c->methods = MNEW(methodinfo, c->methodscount);
2477 classrefs = MNEW(constant_classref, 2);
2478 CLASSREF_INIT(classrefs[0], c, c->name);
2479 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2481 /* create descriptor for clone method */
2482 /* we need one paramslot which is reserved for the 'this' parameter */
2483 clonedesc = NEW(methoddesc);
2484 clonedesc->returntype.type = TYPE_ADR;
2485 clonedesc->returntype.classref = classrefs + 1;
2486 clonedesc->returntype.arraydim = 0;
2487 /* initialize params to "empty", add real params below in
2488 descriptor_params_from_paramtypes */
2489 clonedesc->paramcount = 0;
2490 clonedesc->paramslots = 0;
2491 clonedesc->paramtypes[0].classref = classrefs + 0;
2492 clonedesc->params = NULL;
2494 /* create methodinfo */
2497 MSET(clone, 0, methodinfo, 1);
2499 #if defined(ENABLE_THREADS)
2500 lock_init_object_lock(&clone->header);
2503 /* ATTENTION: if you delete the ACC_NATIVE below, set
2504 clone->maxlocals=1 (interpreter related) */
2506 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2507 clone->name = utf_clone;
2508 clone->descriptor = utf_void__java_lang_Object;
2509 clone->parseddesc = clonedesc;
2512 /* parse the descriptor to get the register allocation */
2514 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2518 codegen_createnativestub((functionptr) &builtin_clone_array, clone);
2520 /* XXX: field: length? */
2522 /* array classes are not loaded from class files */
2524 c->state |= CLASS_LOADED;
2525 c->parseddescs = (u1 *) clonedesc;
2526 c->parseddescsize = sizeof(methodinfo);
2527 c->classrefs = classrefs;
2528 c->classrefcount = 1;
2530 /* insert class into the loaded class cache */
2531 /* XXX free classinfo if NULL returned? */
2533 return classcache_store(loader, c, true);
2537 /* loader_close ****************************************************************
2539 Frees all resources.
2541 *******************************************************************************/
2543 void loader_close(void)
2550 * These are local overrides for various environment variables in Emacs.
2551 * Please do not remove this and leave it at the end of the file, where
2552 * Emacs will automagically detect them.
2553 * ---------------------------------------------------------------------
2556 * indent-tabs-mode: t
2560 * vim:noexpandtab:sw=4:ts=4: