1 /* src/vmcore/loader.c - class loader functions
3 Copyright (C) 1996-2005, 2006, 2007 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 $Id: loader.c 7464 2007-03-06 00:26:31Z edwin $
38 #include "mm/memory.h"
40 #if defined(ENABLE_THREADS)
41 # include "threads/native/lock.h"
44 #include "toolbox/logging.h"
46 #include "vm/builtin.h"
47 #include "vm/exceptions.h"
48 #include "vm/global.h"
49 #include "vm/stringlocal.h"
52 #include "vm/jit_interface.h"
54 #if defined(ENABLE_JAVASE)
55 # include "vmcore/annotation.h"
56 # include "vmcore/stackmap.h"
59 #include "vmcore/classcache.h"
60 #include "vmcore/linker.h"
61 #include "vmcore/loader.h"
62 #include "vmcore/options.h"
63 #include "vmcore/rt-timing.h"
65 #if defined(ENABLE_STATISTICS)
66 # include "vmcore/statistics.h"
69 #include "vmcore/suck.h"
71 #if defined(ENABLE_ZLIB)
72 # include "vmcore/zip.h"
75 #if defined(ENABLE_JVMTI)
76 # include "native/jvmti/cacaodbg.h"
80 /* loader_init *****************************************************************
82 Initializes all lists and loads all classes required for the system
85 *******************************************************************************/
87 bool loader_init(void)
89 #if defined(ENABLE_THREADS)
90 list_classpath_entry *lce;
92 /* Initialize the monitor pointer for zip/jar file locking. */
94 for (lce = list_first(list_classpath_entries); lce != NULL;
95 lce = list_next(list_classpath_entries, lce))
96 if (lce->type == CLASSPATH_ARCHIVE)
97 lock_init_object_lock((java_objectheader *) lce);
100 /* load some important classes */
102 if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
105 if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
108 #if defined(ENABLE_JAVASE)
109 if (!(class_java_lang_Cloneable =
110 load_class_bootstrap(utf_java_lang_Cloneable)))
113 if (!(class_java_io_Serializable =
114 load_class_bootstrap(utf_java_io_Serializable)))
118 /* load classes for wrapping primitive types */
120 #if defined(ENABLE_JAVASE)
121 if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
125 if (!(class_java_lang_Boolean =
126 load_class_bootstrap(utf_java_lang_Boolean)))
129 if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
132 if (!(class_java_lang_Character =
133 load_class_bootstrap(utf_java_lang_Character)))
136 if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
139 if (!(class_java_lang_Integer =
140 load_class_bootstrap(utf_java_lang_Integer)))
143 if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
146 if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
149 if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
153 /* load some other important classes */
155 if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
158 #if defined(ENABLE_JAVASE)
159 if (!(class_java_lang_ClassLoader =
160 load_class_bootstrap(utf_java_lang_ClassLoader)))
163 if (!(class_java_lang_SecurityManager =
164 load_class_bootstrap(utf_java_lang_SecurityManager)))
168 if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
171 if (!(class_java_lang_Thread =
172 load_class_bootstrap(utf_new_char("java/lang/Thread"))))
175 #if defined(ENABLE_JAVASE)
176 if (!(class_java_lang_ThreadGroup =
177 load_class_bootstrap(utf_java_lang_ThreadGroup)))
181 #if defined(WITH_CLASSPATH_GNU)
182 if (!(class_java_lang_VMSystem =
183 load_class_bootstrap(utf_new_char("java/lang/VMSystem"))))
187 if (!(class_java_lang_VMThread =
188 load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
193 /* some classes which may be used more often */
195 #if defined(ENABLE_JAVASE)
196 if (!(class_java_lang_StackTraceElement =
197 load_class_bootstrap(utf_java_lang_StackTraceElement)))
200 if (!(class_java_lang_reflect_Constructor =
201 load_class_bootstrap(utf_java_lang_reflect_Constructor)))
204 if (!(class_java_lang_reflect_Field =
205 load_class_bootstrap(utf_java_lang_reflect_Field)))
208 if (!(class_java_lang_reflect_Method =
209 load_class_bootstrap(utf_java_lang_reflect_Method)))
212 if (!(class_java_security_PrivilegedAction =
213 load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
216 if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
219 if (!(arrayclass_java_lang_Object =
220 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
228 /* loader_load_all_classes *****************************************************
230 Loads all classes specified in the BOOTCLASSPATH.
232 *******************************************************************************/
234 void loader_load_all_classes(void)
236 list_classpath_entry *lce;
237 #if defined(ENABLE_ZLIB)
240 hashtable_zipfile_entry *htzfe;
244 for (lce = list_first(list_classpath_entries); lce != NULL;
245 lce = list_next(list_classpath_entries, lce)) {
246 #if defined(ENABLE_ZLIB)
247 if (lce->type == CLASSPATH_ARCHIVE) {
248 /* get the classes hashtable */
252 for (slot = 0; slot < ht->size; slot++) {
253 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
255 for (; htzfe; htzfe = htzfe->hashlink) {
258 /* skip all entries in META-INF and .properties,
261 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
262 strstr(u->text, ".properties") ||
263 strstr(u->text, ".png"))
266 /* load class from bootstrap classloader */
268 if (!load_class_bootstrap(u)) {
269 fprintf(stderr, "Error loading: ");
270 utf_fprint_printable_ascii_classname(stderr, u);
271 fprintf(stderr, "\n");
274 /* print out exception and cause */
276 exceptions_print_current_exception();
284 #if defined(ENABLE_ZLIB)
291 /* loader_skip_attribute_body **************************************************
293 Skips an attribute the attribute_name_index has already been read.
296 u2 attribute_name_index;
298 u1 info[attribute_length];
301 *******************************************************************************/
303 bool loader_skip_attribute_body(classbuffer *cb)
307 if (!suck_check_classbuffer_size(cb, 4))
310 attribute_length = suck_u4(cb);
312 if (!suck_check_classbuffer_size(cb, attribute_length))
315 suck_skip_nbytes(cb, attribute_length);
321 /* load_constantpool ***********************************************************
323 Loads the constantpool of a class, the entries are transformed into
324 a simpler format by resolving references (a detailed overview of
325 the compact structures can be found in global.h).
327 *******************************************************************************/
329 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
332 /* The following structures are used to save information which cannot be
333 processed during the first pass. After the complete constantpool has
334 been traversed the references can be resolved.
335 (only in specific order) */
337 /* CONSTANT_Class entries */
338 typedef struct forward_class {
339 struct forward_class *next;
344 /* CONSTANT_String */
345 typedef struct forward_string {
346 struct forward_string *next;
351 /* CONSTANT_NameAndType */
352 typedef struct forward_nameandtype {
353 struct forward_nameandtype *next;
357 } forward_nameandtype;
359 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
360 typedef struct forward_fieldmethint {
361 struct forward_fieldmethint *next;
365 u2 nameandtype_index;
366 } forward_fieldmethint;
372 forward_class *forward_classes = NULL;
373 forward_string *forward_strings = NULL;
374 forward_nameandtype *forward_nameandtypes = NULL;
375 forward_fieldmethint *forward_fieldmethints = NULL;
379 forward_nameandtype *nfn;
380 forward_fieldmethint *nff;
388 /* number of entries in the constant_pool table plus one */
389 if (!suck_check_classbuffer_size(cb, 2))
392 cpcount = c->cpcount = suck_u2(cb);
394 /* allocate memory */
395 cptags = c->cptags = MNEW(u1, cpcount);
396 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
399 exceptions_throw_classformaterror(c, "Illegal constant pool size");
403 #if defined(ENABLE_STATISTICS)
405 count_const_pool_len += (sizeof(u1) + sizeof(voidptr)) * cpcount;
408 /* initialize constantpool */
409 for (idx = 0; idx < cpcount; idx++) {
410 cptags[idx] = CONSTANT_UNUSED;
415 /******* first pass *******/
416 /* entries which cannot be resolved now are written into
417 temporary structures and traversed again later */
420 while (idx < cpcount) {
423 /* get constant type */
424 if (!suck_check_classbuffer_size(cb, 1))
431 nfc = DNEW(forward_class);
433 nfc->next = forward_classes;
434 forward_classes = nfc;
436 nfc->thisindex = idx;
437 /* reference to CONSTANT_NameAndType */
438 if (!suck_check_classbuffer_size(cb, 2))
441 nfc->name_index = suck_u2(cb);
446 case CONSTANT_String:
447 nfs = DNEW(forward_string);
449 nfs->next = forward_strings;
450 forward_strings = nfs;
452 nfs->thisindex = idx;
454 /* reference to CONSTANT_Utf8_info with string characters */
455 if (!suck_check_classbuffer_size(cb, 2))
458 nfs->string_index = suck_u2(cb);
463 case CONSTANT_NameAndType:
464 nfn = DNEW(forward_nameandtype);
466 nfn->next = forward_nameandtypes;
467 forward_nameandtypes = nfn;
469 nfn->thisindex = idx;
471 if (!suck_check_classbuffer_size(cb, 2 + 2))
474 /* reference to CONSTANT_Utf8_info containing simple name */
475 nfn->name_index = suck_u2(cb);
477 /* reference to CONSTANT_Utf8_info containing field or method
479 nfn->sig_index = suck_u2(cb);
484 case CONSTANT_Fieldref:
485 case CONSTANT_Methodref:
486 case CONSTANT_InterfaceMethodref:
487 nff = DNEW(forward_fieldmethint);
489 nff->next = forward_fieldmethints;
490 forward_fieldmethints = nff;
492 nff->thisindex = idx;
496 if (!suck_check_classbuffer_size(cb, 2 + 2))
499 /* class or interface type that contains the declaration of the
501 nff->class_index = suck_u2(cb);
503 /* name and descriptor of the field or method */
504 nff->nameandtype_index = suck_u2(cb);
509 case CONSTANT_Integer: {
510 constant_integer *ci = NEW(constant_integer);
512 #if defined(ENABLE_STATISTICS)
514 count_const_pool_len += sizeof(constant_integer);
517 if (!suck_check_classbuffer_size(cb, 4))
520 ci->value = suck_s4(cb);
521 cptags[idx] = CONSTANT_Integer;
528 case CONSTANT_Float: {
529 constant_float *cf = NEW(constant_float);
531 #if defined(ENABLE_STATISTICS)
533 count_const_pool_len += sizeof(constant_float);
536 if (!suck_check_classbuffer_size(cb, 4))
539 cf->value = suck_float(cb);
540 cptags[idx] = CONSTANT_Float;
547 case CONSTANT_Long: {
548 constant_long *cl = NEW(constant_long);
550 #if defined(ENABLE_STATISTICS)
552 count_const_pool_len += sizeof(constant_long);
555 if (!suck_check_classbuffer_size(cb, 8))
558 cl->value = suck_s8(cb);
559 cptags[idx] = CONSTANT_Long;
563 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
569 case CONSTANT_Double: {
570 constant_double *cd = NEW(constant_double);
572 #if defined(ENABLE_STATISTICS)
574 count_const_pool_len += sizeof(constant_double);
577 if (!suck_check_classbuffer_size(cb, 8))
580 cd->value = suck_double(cb);
581 cptags[idx] = CONSTANT_Double;
585 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
591 case CONSTANT_Utf8: {
594 /* number of bytes in the bytes array (not string-length) */
595 if (!suck_check_classbuffer_size(cb, 2))
598 length = suck_u2(cb);
599 cptags[idx] = CONSTANT_Utf8;
601 /* validate the string */
602 if (!suck_check_classbuffer_size(cb, length))
605 #ifdef ENABLE_VERIFIER
607 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
609 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
612 #endif /* ENABLE_VERIFIER */
613 /* insert utf-string into the utf-symboltable */
614 cpinfos[idx] = utf_new((char *) cb->pos, length);
616 /* skip bytes of the string (buffer size check above) */
617 suck_skip_nbytes(cb, length);
623 exceptions_throw_classformaterror(c, "Illegal constant pool type");
629 /* resolve entries in temporary structures */
631 while (forward_classes) {
633 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
637 #ifdef ENABLE_VERIFIER
638 if (opt_verify && !is_valid_name_utf(name)) {
639 exceptions_throw_classformaterror(c, "Class reference with invalid name");
642 #endif /* ENABLE_VERIFIER */
644 /* add all class references to the descriptor_pool */
646 if (!descriptor_pool_add_class(descpool, name))
649 cptags[forward_classes->thisindex] = CONSTANT_Class;
654 if (!(tc = load_class_bootstrap(name)))
657 /* link the class later, because we cannot link the class currently
659 list_add_first(&unlinkedclasses, tc);
662 /* the classref is created later */
663 cpinfos[forward_classes->thisindex] = name;
665 nfc = forward_classes;
666 forward_classes = forward_classes->next;
669 while (forward_strings) {
671 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
675 /* resolve utf-string */
676 cptags[forward_strings->thisindex] = CONSTANT_String;
677 cpinfos[forward_strings->thisindex] = text;
679 nfs = forward_strings;
680 forward_strings = forward_strings->next;
683 while (forward_nameandtypes) {
684 constant_nameandtype *cn = NEW(constant_nameandtype);
686 #if defined(ENABLE_STATISTICS)
688 count_const_pool_len += sizeof(constant_nameandtype);
691 /* resolve simple name and descriptor */
692 cn->name = class_getconstant(c,
693 forward_nameandtypes->name_index,
698 cn->descriptor = class_getconstant(c,
699 forward_nameandtypes->sig_index,
704 #ifdef ENABLE_VERIFIER
707 if (!is_valid_name_utf(cn->name)) {
708 exceptions_throw_classformaterror(c,
709 "Illegal Field name \"%s\"",
715 /* disallow referencing <clinit> among others */
716 if (cn->name->text[0] == '<' && cn->name != utf_init) {
717 exceptions_throw_classformaterror(c, "Illegal reference to special method");
721 #endif /* ENABLE_VERIFIER */
723 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
724 cpinfos[forward_nameandtypes->thisindex] = cn;
726 nfn = forward_nameandtypes;
727 forward_nameandtypes = forward_nameandtypes->next;
730 while (forward_fieldmethints) {
731 constant_nameandtype *nat;
732 constant_FMIref *fmi = NEW(constant_FMIref);
734 #if defined(ENABLE_STATISTICS)
736 count_const_pool_len += sizeof(constant_FMIref);
738 /* resolve simple name and descriptor */
740 nat = class_getconstant(c,
741 forward_fieldmethints->nameandtype_index,
742 CONSTANT_NameAndType);
746 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
748 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
751 /* the classref is created later */
753 fmi->p.index = forward_fieldmethints->class_index;
754 fmi->name = nat->name;
755 fmi->descriptor = nat->descriptor;
757 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
758 cpinfos[forward_fieldmethints->thisindex] = fmi;
760 nff = forward_fieldmethints;
761 forward_fieldmethints = forward_fieldmethints->next;
764 /* everything was ok */
770 /* loader_load_attribute_signature *********************************************
772 Signature_attribute {
773 u2 attribute_name_index;
778 *******************************************************************************/
780 #if defined(ENABLE_JAVASE)
781 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
791 /* check remaining bytecode */
793 if (!suck_check_classbuffer_size(cb, 4 + 2))
796 /* check attribute length */
798 attribute_length = suck_u4(cb);
800 if (attribute_length != 2) {
801 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
805 if (*signature != NULL) {
806 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
812 signature_index = suck_u2(cb);
814 if (!(*signature = class_getconstant(c, signature_index, CONSTANT_Utf8)))
819 #endif /* defined(ENABLE_JAVASE) */
822 /* load_field ******************************************************************
824 Load everything about a class field from the class file and fill a
825 'fieldinfo' structure. For static fields, space in the data segment
828 *******************************************************************************/
830 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
832 static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
837 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
842 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
845 f->flags = suck_u2(cb);
847 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
852 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
856 f->parseddesc = NULL;
858 if (!descriptor_pool_add(descpool, u, NULL))
861 /* descriptor_pool_add accepts method descriptors, so we have to check */
862 /* against them here before the call of descriptor_to_basic_type below. */
863 if (u->text[0] == '(') {
864 exceptions_throw_classformaterror(c, "Method descriptor used for field");
868 #ifdef ENABLE_VERIFIER
871 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<') {
872 exceptions_throw_classformaterror(c,
873 "Illegal Field name \"%s\"",
878 /* check flag consistency */
879 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
881 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
882 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
883 exceptions_throw_classformaterror(c,
884 "Illegal field modifiers: 0x%X",
889 if (c->flags & ACC_INTERFACE) {
890 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
891 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
892 f->flags & ACC_TRANSIENT) {
893 exceptions_throw_classformaterror(c,
894 "Illegal field modifiers: 0x%X",
900 #endif /* ENABLE_VERIFIER */
902 f->type = jtype = descriptor_to_basic_type(f->descriptor); /* data type */
903 f->offset = 0; /* offset from start of object */
921 if (!(f->flags & ACC_STATIC))
922 c->flags |= ACC_CLASS_HAS_POINTERS;
935 /* read attributes */
936 if (!suck_check_classbuffer_size(cb, 2))
939 attrnum = suck_u2(cb);
940 for (i = 0; i < attrnum; i++) {
941 if (!suck_check_classbuffer_size(cb, 2))
944 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
947 if (u == utf_ConstantValue) {
948 if (!suck_check_classbuffer_size(cb, 4 + 2))
951 /* check attribute length */
953 if (suck_u4(cb) != 2) {
954 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
958 /* constant value attribute */
960 if (pindex != field_load_NOVALUE) {
961 exceptions_throw_classformaterror(c, "Multiple ConstantValue attributes");
965 /* index of value in constantpool */
967 pindex = suck_u2(cb);
969 /* initialize field with value from constantpool */
972 constant_integer *ci;
974 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
977 f->value.i = ci->value;
984 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
987 f->value.l = cl->value;
994 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
997 f->value.f = cf->value;
1002 constant_double *cd;
1004 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
1007 f->value.d = cd->value;
1012 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
1015 /* create javastring from compressed utf8-string */
1016 f->value.a = literalstring_new(u);
1020 log_text("Invalid Constant - Type");
1023 #if defined(ENABLE_JAVASE)
1024 else if (u == utf_Signature) {
1027 if (!loader_load_attribute_signature(cb, &(f->signature)))
1032 /* unknown attribute */
1034 if (!loader_skip_attribute_body(cb))
1039 /* everything was ok */
1045 /* loader_load_method **********************************************************
1047 Loads a method from the class file and fills an existing
1048 'methodinfo' structure. For native methods, the function pointer
1049 field is set to the real function pointer, for JavaVM methods a
1050 pointer to the compiler is used preliminarily.
1055 u2 descriptor_index;
1056 u2 attributes_count;
1057 attribute_info attributes[attribute_count];
1061 u2 attribute_name_index;
1062 u4 attribute_length;
1063 u1 info[attribute_length];
1066 LineNumberTable_attribute {
1067 u2 attribute_name_index;
1068 u4 attribute_length;
1069 u2 line_number_table_length;
1073 } line_number_table[line_number_table_length];
1076 *******************************************************************************/
1078 static bool loader_load_method(classbuffer *cb, methodinfo *m,
1079 descriptor_pool *descpool)
1086 u2 descriptor_index;
1087 u2 attributes_count;
1088 u2 attribute_name_index;
1089 utf *attribute_name;
1090 u2 code_attributes_count;
1091 u2 code_attribute_name_index;
1092 utf *code_attribute_name;
1098 #if defined(ENABLE_STATISTICS)
1100 count_all_methods++;
1103 /* all fields of m have been zeroed in load_class_from_classbuffer */
1107 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
1112 m->flags = suck_u2(cb);
1116 name_index = suck_u2(cb);
1118 if (!(u = class_getconstant(c, name_index, CONSTANT_Utf8)))
1125 descriptor_index = suck_u2(cb);
1127 if (!(u = class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
1132 if (!descriptor_pool_add(descpool, u, &argcount))
1135 #ifdef ENABLE_VERIFIER
1137 if (!is_valid_name_utf(m->name)) {
1138 exceptions_throw_classformaterror(c, "Method with invalid name");
1142 if (m->name->text[0] == '<' &&
1143 m->name != utf_init && m->name != utf_clinit) {
1144 exceptions_throw_classformaterror(c, "Method with invalid special name");
1148 #endif /* ENABLE_VERIFIER */
1150 if (!(m->flags & ACC_STATIC))
1151 argcount++; /* count the 'this' argument */
1153 #ifdef ENABLE_VERIFIER
1155 if (argcount > 255) {
1156 exceptions_throw_classformaterror(c, "Too many arguments in signature");
1160 /* check flag consistency */
1161 if (m->name != utf_clinit) {
1162 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1164 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1165 exceptions_throw_classformaterror(c,
1166 "Illegal method modifiers: 0x%X",
1171 if (m->flags & ACC_ABSTRACT) {
1172 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1173 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1174 exceptions_throw_classformaterror(c,
1175 "Illegal method modifiers: 0x%X",
1181 if (c->flags & ACC_INTERFACE) {
1182 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1183 exceptions_throw_classformaterror(c,
1184 "Illegal method modifiers: 0x%X",
1190 if (m->name == utf_init) {
1191 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1192 ACC_NATIVE | ACC_ABSTRACT)) {
1193 exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
1199 #endif /* ENABLE_VERIFIER */
1201 /* mark the method as monomorphic until further notice */
1203 m->flags |= ACC_METHOD_MONOMORPHIC;
1205 /* non-abstract methods have an implementation in this class */
1207 if (!(m->flags & ACC_ABSTRACT))
1208 m->flags |= ACC_METHOD_IMPLEMENTED;
1210 if (!suck_check_classbuffer_size(cb, 2))
1213 /* attributes count */
1215 attributes_count = suck_u2(cb);
1217 for (i = 0; i < attributes_count; i++) {
1218 if (!suck_check_classbuffer_size(cb, 2))
1221 /* attribute name index */
1223 attribute_name_index = suck_u2(cb);
1225 if (!(attribute_name = class_getconstant(c, attribute_name_index, CONSTANT_Utf8)))
1228 if (attribute_name == utf_Code) {
1230 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1231 exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
1236 exceptions_throw_classformaterror(c, "Multiple Code attributes");
1240 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1244 m->maxstack = suck_u2(cb);
1245 m->maxlocals = suck_u2(cb);
1247 if (m->maxlocals < argcount) {
1248 exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
1252 if (!suck_check_classbuffer_size(cb, 4))
1255 m->jcodelength = suck_u4(cb);
1257 if (m->jcodelength == 0) {
1258 exceptions_throw_classformaterror(c, "Code of a method has length 0");
1262 if (m->jcodelength > 65535) {
1263 exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
1267 if (!suck_check_classbuffer_size(cb, m->jcodelength))
1270 m->jcode = MNEW(u1, m->jcodelength);
1271 suck_nbytes(m->jcode, cb, m->jcodelength);
1273 if (!suck_check_classbuffer_size(cb, 2))
1276 m->rawexceptiontablelength = suck_u2(cb);
1277 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->rawexceptiontablelength))
1280 m->rawexceptiontable = MNEW(raw_exception_entry, m->rawexceptiontablelength);
1282 #if defined(ENABLE_STATISTICS)
1284 count_vmcode_len += m->jcodelength + 18;
1285 count_extable_len +=
1286 m->rawexceptiontablelength * sizeof(raw_exception_entry);
1290 for (j = 0; j < m->rawexceptiontablelength; j++) {
1292 m->rawexceptiontable[j].startpc = suck_u2(cb);
1293 m->rawexceptiontable[j].endpc = suck_u2(cb);
1294 m->rawexceptiontable[j].handlerpc = suck_u2(cb);
1298 m->rawexceptiontable[j].catchtype.any = NULL;
1301 /* the classref is created later */
1302 if (!(m->rawexceptiontable[j].catchtype.any =
1303 (utf*)class_getconstant(c, idx, CONSTANT_Class)))
1308 if (!suck_check_classbuffer_size(cb, 2))
1311 /* code attributes count */
1313 code_attributes_count = suck_u2(cb);
1315 for (k = 0; k < code_attributes_count; k++) {
1316 if (!suck_check_classbuffer_size(cb, 2))
1319 /* code attribute name index */
1321 code_attribute_name_index = suck_u2(cb);
1323 if (!(code_attribute_name = class_getconstant(c, code_attribute_name_index, CONSTANT_Utf8)))
1326 /* check which code attribute */
1328 if (code_attribute_name == utf_LineNumberTable) {
1329 /* LineNumberTable */
1330 if (!suck_check_classbuffer_size(cb, 4 + 2))
1333 /* attribute length */
1337 /* line number table length */
1339 m->linenumbercount = suck_u2(cb);
1341 if (!suck_check_classbuffer_size(cb,
1342 (2 + 2) * m->linenumbercount))
1345 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1347 #if defined(ENABLE_STATISTICS)
1349 size_lineinfo += sizeof(lineinfo) * m->linenumbercount;
1352 for (l = 0; l < m->linenumbercount; l++) {
1353 m->linenumbers[l].start_pc = suck_u2(cb);
1354 m->linenumbers[l].line_number = suck_u2(cb);
1357 #if defined(ENABLE_JAVASE)
1358 else if (code_attribute_name == utf_StackMapTable) {
1361 if (!stackmap_load_attribute_stackmaptable(cb, m))
1366 /* unknown code attribute */
1368 if (!loader_skip_attribute_body(cb))
1373 else if (attribute_name == utf_Exceptions) {
1376 if (m->thrownexceptions != NULL) {
1377 exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
1381 if (!suck_check_classbuffer_size(cb, 4 + 2))
1384 /* attribute length */
1388 m->thrownexceptionscount = suck_u2(cb);
1390 if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1393 m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
1395 for (j = 0; j < m->thrownexceptionscount; j++) {
1396 /* the classref is created later */
1397 if (!((m->thrownexceptions)[j].any =
1398 (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1402 #if defined(ENABLE_JAVASE)
1403 else if (attribute_name == utf_Signature) {
1406 if (!loader_load_attribute_signature(cb, &(m->signature)))
1411 /* unknown attribute */
1413 if (!loader_skip_attribute_body(cb))
1418 if ((m->jcode == NULL) && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1419 exceptions_throw_classformaterror(c, "Missing Code attribute");
1423 /* initialize the hit countdown field */
1425 #if defined(ENABLE_REPLACEMENT)
1426 m->hitcountdown = METHOD_INITIAL_HIT_COUNTDOWN;
1429 /* everything was ok */
1435 /* load_class_from_sysloader ***************************************************
1437 Load the class with the given name using the system class loader
1440 name.............the classname
1443 the loaded class, or
1444 NULL if an exception has been thrown
1446 *******************************************************************************/
1448 classinfo *load_class_from_sysloader(utf *name)
1451 java_objectheader *cl;
1454 assert(class_java_lang_Object);
1455 assert(class_java_lang_ClassLoader);
1456 assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
1458 m = class_resolveclassmethod(class_java_lang_ClassLoader,
1459 utf_getSystemClassLoader,
1460 utf_void__java_lang_ClassLoader,
1461 class_java_lang_Object,
1467 cl = vm_call_method(m, NULL);
1472 c = load_class_from_classloader(name, cl);
1478 /* load_class_from_classloader *************************************************
1480 Load the class with the given name using the given user-defined class loader.
1483 name.............the classname
1484 cl...............user-defined class loader
1487 the loaded class, or
1488 NULL if an exception has been thrown
1490 *******************************************************************************/
1492 classinfo *load_class_from_classloader(utf *name, java_objectheader *cl)
1494 java_objectheader *o;
1497 java_objectheader *string;
1498 #if defined(ENABLE_RT_TIMING)
1499 struct timespec time_start, time_lookup, time_prepare, time_java,
1503 RT_TIMING_GET_TIME(time_start);
1507 /* lookup if this class has already been loaded */
1509 c = classcache_lookup(cl, name);
1511 RT_TIMING_GET_TIME(time_lookup);
1512 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1517 /* if other class loader than bootstrap, call it */
1525 namelen = name->blength;
1527 /* handle array classes */
1528 if (text[0] == '[') {
1534 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1535 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1536 exceptions_throw_noclassdeffounderror(name);
1540 u = utf_new(text + 2, namelen - 3);
1542 if (!(comp = load_class_from_classloader(u, cl)))
1545 /* create the array class */
1547 c = class_array_of(comp, false);
1549 tmpc = classcache_store(cl, c, true);
1552 /* exception, free the loaded class */
1553 c->state &= ~CLASS_LOADING;
1560 /* load the component class */
1562 u = utf_new(text + 1, namelen - 1);
1564 if (!(comp = load_class_from_classloader(u, cl)))
1567 /* create the array class */
1569 c = class_array_of(comp, false);
1571 tmpc = classcache_store(cl, c, true);
1574 /* exception, free the loaded class */
1575 c->state &= ~CLASS_LOADING;
1582 /* primitive array classes are loaded by the bootstrap loader */
1584 c = load_class_bootstrap(name);
1590 assert(class_java_lang_Object);
1592 lc = class_resolveclassmethod(cl->vftbl->class,
1594 utf_java_lang_String__java_lang_Class,
1595 class_java_lang_Object,
1599 return false; /* exception */
1601 /* move return value into `o' and cast it afterwards to a classinfo* */
1603 string = javastring_new_slash_to_dot(name);
1605 RT_TIMING_GET_TIME(time_prepare);
1607 o = vm_call_method(lc, cl, string);
1609 RT_TIMING_GET_TIME(time_java);
1611 c = (classinfo *) o;
1614 /* Store this class in the loaded class cache. If another
1615 class with the same (initloader,name) pair has been
1616 stored earlier it will be returned by classcache_store
1617 In this case classcache_store may not free the class
1618 because it has already been exposed to Java code which
1619 may have kept references to that class. */
1621 tmpc = classcache_store(cl, c, false);
1624 /* exception, free the loaded class */
1625 c->state &= ~CLASS_LOADING;
1632 /* loadClass has thrown an exception. We must convert
1633 ClassNotFoundException into
1634 NoClassDefFoundException. */
1636 /* XXX Maybe we should have a flag that avoids this
1637 conversion for calling load_class_from_classloader from
1638 Class.forName. Currently we do a double conversion in
1641 classnotfoundexception_to_noclassdeffounderror();
1644 RT_TIMING_GET_TIME(time_cache);
1646 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1647 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1648 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1650 /* SUN compatible -verbose:class output */
1652 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1654 utf_display_printable_ascii_classname(name);
1658 #if defined(ENABLE_JVMTI)
1659 /* fire Class Load JVMTI event */
1660 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1667 c = load_class_bootstrap(name);
1673 /* load_class_bootstrap ********************************************************
1675 Load the class with the given name using the bootstrap class loader.
1678 name.............the classname
1681 loaded classinfo, or
1682 NULL if an exception has been thrown
1685 load_class_bootstrap is synchronized. It can be treated as an
1688 *******************************************************************************/
1690 classinfo *load_class_bootstrap(utf *name)
1695 #if defined(ENABLE_RT_TIMING)
1696 struct timespec time_start, time_lookup, time_array, time_suck,
1697 time_load, time_cache;
1700 RT_TIMING_GET_TIME(time_start);
1706 /* lookup if this class has already been loaded */
1708 if ((r = classcache_lookup(NULL, name))) {
1710 RT_TIMING_GET_TIME(time_lookup);
1711 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1716 RT_TIMING_GET_TIME(time_lookup);
1717 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1719 /* create the classinfo */
1721 c = class_create_classinfo(name);
1723 /* handle array classes */
1725 if (name->text[0] == '[') {
1726 c = load_newly_created_array(c, NULL);
1729 assert(c->state & CLASS_LOADED);
1731 RT_TIMING_GET_TIME(time_array);
1732 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1737 #if defined(ENABLE_STATISTICS)
1740 if (opt_getcompilingtime)
1741 compilingtime_stop();
1743 if (opt_getloadingtime)
1744 loadingtime_start();
1747 /* load classdata, throw exception on error */
1752 /* this normally means, the classpath was not set properly */
1754 if (name == utf_java_lang_Object)
1755 vm_abort("java/lang/NoClassDefFoundError: java/lang/Object");
1757 exceptions_throw_noclassdeffounderror(name);
1762 RT_TIMING_GET_TIME(time_suck);
1764 /* load the class from the buffer */
1766 r = load_class_from_classbuffer(cb);
1768 RT_TIMING_GET_TIME(time_load);
1771 /* the class could not be loaded, free the classinfo struct */
1776 /* Store this class in the loaded class cache this step also
1777 checks the loading constraints. If the class has been loaded
1778 before, the earlier loaded class is returned. */
1780 classinfo *res = classcache_store(NULL, c, true);
1790 RT_TIMING_GET_TIME(time_cache);
1792 /* SUN compatible -verbose:class output */
1794 if (opt_verboseclass && r) {
1796 utf_display_printable_ascii_classname(name);
1797 printf(" from %s]\n", cb->path);
1804 #if defined(ENABLE_STATISTICS)
1807 if (opt_getloadingtime)
1810 if (opt_getcompilingtime)
1811 compilingtime_start();
1814 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1815 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1816 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1817 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1823 /* load_class_from_classbuffer *************************************************
1825 Loads everything interesting about a class from the class file. The
1826 'classinfo' structure must have been allocated previously.
1828 The super class and the interfaces implemented by this class need
1829 not be loaded. The link is set later by the function 'class_link'.
1831 The loaded class is removed from the list 'unloadedclasses' and
1832 added to the list 'unlinkedclasses'.
1835 This function is NOT synchronized!
1837 *******************************************************************************/
1839 classinfo *load_class_from_classbuffer(classbuffer *cb)
1847 descriptor_pool *descpool;
1848 #if defined(ENABLE_STATISTICS)
1852 #if defined(ENABLE_RT_TIMING)
1853 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1854 time_setup, time_fields, time_methods, time_classrefs,
1855 time_descs, time_setrefs, time_parsefds, time_parsemds,
1856 time_parsecpool, time_verify, time_attrs;
1859 RT_TIMING_GET_TIME(time_start);
1861 /* get the classbuffer's class */
1865 /* the class is already loaded */
1867 if (c->state & CLASS_LOADED)
1870 #if defined(ENABLE_STATISTICS)
1872 count_class_loads++;
1875 #if !defined(NDEBUG)
1876 /* output for debugging purposes */
1879 log_message_class("Loading class: ", c);
1882 /* mark start of dump memory area */
1884 dumpsize = dump_size();
1886 /* class is currently loading */
1888 c->state |= CLASS_LOADING;
1890 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1891 goto return_exception;
1893 /* check signature */
1895 if (suck_u4(cb) != MAGIC) {
1896 exceptions_throw_classformaterror(c, "Bad magic number");
1898 goto return_exception;
1906 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1907 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1908 goto return_exception;
1911 RT_TIMING_GET_TIME(time_checks);
1913 /* create a new descriptor pool */
1915 descpool = descriptor_pool_new(c);
1917 RT_TIMING_GET_TIME(time_ndpool);
1919 /* load the constant pool */
1921 if (!load_constantpool(cb, descpool))
1922 goto return_exception;
1924 RT_TIMING_GET_TIME(time_cpool);
1928 if (!suck_check_classbuffer_size(cb, 2))
1929 goto return_exception;
1931 /* We OR the flags here, as we set already some flags in
1932 class_create_classinfo. */
1934 c->flags |= suck_u2(cb);
1936 /* check ACC flags consistency */
1938 if (c->flags & ACC_INTERFACE) {
1939 if (!(c->flags & ACC_ABSTRACT)) {
1940 /* We work around this because interfaces in JDK 1.1 are
1941 * not declared abstract. */
1943 c->flags |= ACC_ABSTRACT;
1946 if (c->flags & ACC_FINAL) {
1947 exceptions_throw_classformaterror(c,
1948 "Illegal class modifiers: 0x%X",
1950 goto return_exception;
1953 if (c->flags & ACC_SUPER) {
1954 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1958 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1959 exceptions_throw_classformaterror(c,
1960 "Illegal class modifiers: 0x%X",
1962 goto return_exception;
1965 if (!suck_check_classbuffer_size(cb, 2 + 2))
1966 goto return_exception;
1971 if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1972 goto return_exception;
1974 if (c->name == utf_not_named_yet) {
1975 /* we finally have a name for this class */
1977 class_set_packagename(c);
1979 } else if (name != c->name) {
1980 /* TODO: i want to be an exceptions-function! */
1984 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
1985 utf_bytes(name) + strlen(")") + strlen("0");
1987 msg = MNEW(char, msglen);
1989 utf_copy_classname(msg, c->name);
1990 strcat(msg, " (wrong name: ");
1991 utf_cat_classname(msg, name);
1995 /* *exceptionptr = */
1996 /* new_exception_message("java/lang/NoClassDefFoundError", msg); */
1997 exceptions_throw_noclassdeffounderror(c->name);
1999 MFREE(msg, char, msglen);
2001 goto return_exception;
2004 /* retrieve superclass */
2006 c->super.any = NULL;
2007 if ((i = suck_u2(cb))) {
2008 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
2009 goto return_exception;
2011 /* java.lang.Object may not have a super class. */
2013 if (c->name == utf_java_lang_Object) {
2014 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
2015 goto return_exception;
2018 /* Interfaces must have java.lang.Object as super class. */
2020 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
2021 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
2022 goto return_exception;
2028 /* This is only allowed for java.lang.Object. */
2030 if (c->name != utf_java_lang_Object) {
2031 exceptions_throw_classformaterror(c, "Bad superclass index");
2032 goto return_exception;
2036 /* retrieve interfaces */
2038 if (!suck_check_classbuffer_size(cb, 2))
2039 goto return_exception;
2041 c->interfacescount = suck_u2(cb);
2043 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
2044 goto return_exception;
2046 c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
2047 for (i = 0; i < c->interfacescount; i++) {
2048 /* the classrefs are created later */
2049 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2050 goto return_exception;
2053 RT_TIMING_GET_TIME(time_setup);
2056 if (!suck_check_classbuffer_size(cb, 2))
2057 goto return_exception;
2059 c->fieldscount = suck_u2(cb);
2060 #if defined(ENABLE_GC_CACAO)
2061 c->fields = MNEW(fieldinfo, c->fieldscount);
2062 MZERO(c->fields, fieldinfo, c->fieldscount);
2064 c->fields = GCNEW_UNCOLLECTABLE(fieldinfo, c->fieldscount);
2067 for (i = 0; i < c->fieldscount; i++) {
2068 if (!load_field(cb, &(c->fields[i]),descpool))
2069 goto return_exception;
2072 RT_TIMING_GET_TIME(time_fields);
2075 if (!suck_check_classbuffer_size(cb, 2))
2076 goto return_exception;
2078 c->methodscount = suck_u2(cb);
2079 c->methods = MNEW(methodinfo, c->methodscount);
2081 MZERO(c->methods, methodinfo, c->methodscount);
2083 for (i = 0; i < c->methodscount; i++) {
2084 if (!loader_load_method(cb, &(c->methods[i]), descpool))
2085 goto return_exception;
2088 RT_TIMING_GET_TIME(time_methods);
2090 /* create the class reference table */
2093 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
2095 RT_TIMING_GET_TIME(time_classrefs);
2097 /* allocate space for the parsed descriptors */
2099 descriptor_pool_alloc_parsed_descriptors(descpool);
2101 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
2103 #if defined(ENABLE_STATISTICS)
2105 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
2106 count_classref_len += classrefsize;
2107 count_parsed_desc_len += descsize;
2111 RT_TIMING_GET_TIME(time_descs);
2113 /* put the classrefs in the constant pool */
2114 for (i = 0; i < c->cpcount; i++) {
2115 if (c->cptags[i] == CONSTANT_Class) {
2116 utf *name = (utf *) c->cpinfos[i];
2117 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
2121 /* set the super class reference */
2124 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
2126 goto return_exception;
2129 /* set the super interfaces references */
2131 for (i = 0; i < c->interfacescount; i++) {
2132 c->interfaces[i].ref =
2133 descriptor_pool_lookup_classref(descpool,
2134 (utf *) c->interfaces[i].any);
2135 if (!c->interfaces[i].ref)
2136 goto return_exception;
2139 RT_TIMING_GET_TIME(time_setrefs);
2141 /* parse field descriptors */
2143 for (i = 0; i < c->fieldscount; i++) {
2144 c->fields[i].parseddesc =
2145 descriptor_pool_parse_field_descriptor(descpool,
2146 c->fields[i].descriptor);
2147 if (!c->fields[i].parseddesc)
2148 goto return_exception;
2151 RT_TIMING_GET_TIME(time_parsefds);
2153 /* parse method descriptors */
2155 for (i = 0; i < c->methodscount; i++) {
2156 methodinfo *m = &c->methods[i];
2158 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
2159 m->flags, class_get_self_classref(m->class));
2161 goto return_exception;
2163 for (j = 0; j < m->rawexceptiontablelength; j++) {
2164 if (!m->rawexceptiontable[j].catchtype.any)
2166 if ((m->rawexceptiontable[j].catchtype.ref =
2167 descriptor_pool_lookup_classref(descpool,
2168 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
2169 goto return_exception;
2172 for (j = 0; j < m->thrownexceptionscount; j++) {
2173 if (!m->thrownexceptions[j].any)
2175 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
2176 (utf *) m->thrownexceptions[j].any)) == NULL)
2177 goto return_exception;
2181 RT_TIMING_GET_TIME(time_parsemds);
2183 /* parse the loaded descriptors */
2185 for (i = 0; i < c->cpcount; i++) {
2186 constant_FMIref *fmi;
2189 switch (c->cptags[i]) {
2190 case CONSTANT_Fieldref:
2191 fmi = (constant_FMIref *) c->cpinfos[i];
2192 fmi->parseddesc.fd =
2193 descriptor_pool_parse_field_descriptor(descpool,
2195 if (!fmi->parseddesc.fd)
2196 goto return_exception;
2197 index = fmi->p.index;
2199 (constant_classref *) class_getconstant(c, index,
2201 if (!fmi->p.classref)
2202 goto return_exception;
2204 case CONSTANT_Methodref:
2205 case CONSTANT_InterfaceMethodref:
2206 fmi = (constant_FMIref *) c->cpinfos[i];
2207 index = fmi->p.index;
2209 (constant_classref *) class_getconstant(c, index,
2211 if (!fmi->p.classref)
2212 goto return_exception;
2213 fmi->parseddesc.md =
2214 descriptor_pool_parse_method_descriptor(descpool,
2218 if (!fmi->parseddesc.md)
2219 goto return_exception;
2224 RT_TIMING_GET_TIME(time_parsecpool);
2226 #ifdef ENABLE_VERIFIER
2227 /* Check if all fields and methods can be uniquely
2228 * identified by (name,descriptor). */
2231 /* We use a hash table here to avoid making the
2232 * average case quadratic in # of methods, fields.
2234 static int shift = 0;
2236 u2 *next; /* for chaining colliding hash entries */
2242 /* Allocate hashtable */
2243 len = c->methodscount;
2244 if (len < c->fieldscount) len = c->fieldscount;
2246 hashtab = MNEW(u2,(hashlen + len));
2247 next = hashtab + hashlen;
2249 /* Determine bitshift (to get good hash values) */
2259 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2261 for (i = 0; i < c->fieldscount; ++i) {
2262 fieldinfo *fi = c->fields + i;
2264 /* It's ok if we lose bits here */
2265 index = ((((size_t) fi->name) +
2266 ((size_t) fi->descriptor)) >> shift) % hashlen;
2268 if ((old = hashtab[index])) {
2272 if (c->fields[old].name == fi->name &&
2273 c->fields[old].descriptor == fi->descriptor) {
2274 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
2275 goto return_exception;
2277 } while ((old = next[old]));
2279 hashtab[index] = i + 1;
2283 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2285 for (i = 0; i < c->methodscount; ++i) {
2286 methodinfo *mi = c->methods + i;
2288 /* It's ok if we lose bits here */
2289 index = ((((size_t) mi->name) +
2290 ((size_t) mi->descriptor)) >> shift) % hashlen;
2294 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2295 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2299 if ((old = hashtab[index])) {
2303 if (c->methods[old].name == mi->name &&
2304 c->methods[old].descriptor == mi->descriptor) {
2305 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
2306 goto return_exception;
2308 } while ((old = next[old]));
2310 hashtab[index] = i + 1;
2313 MFREE(hashtab, u2, (hashlen + len));
2315 #endif /* ENABLE_VERIFIER */
2317 RT_TIMING_GET_TIME(time_verify);
2319 #if defined(ENABLE_STATISTICS)
2321 size_classinfo += sizeof(classinfo*) * c->interfacescount;
2322 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
2323 size_methodinfo += sizeof(methodinfo) * c->methodscount;
2327 /* load attribute structures */
2329 if (!class_load_attributes(cb))
2330 goto return_exception;
2332 /* Pre Java 1.5 version don't check this. This implementation is like
2333 Java 1.5 do it: for class file version 45.3 we don't check it, older
2334 versions are checked.
2337 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
2338 /* check if all data has been read */
2339 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
2341 if (classdata_left > 0) {
2342 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
2343 goto return_exception;
2347 RT_TIMING_GET_TIME(time_attrs);
2349 /* release dump area */
2351 dump_release(dumpsize);
2353 /* revert loading state and class is loaded */
2355 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2357 #if defined(ENABLE_JVMTI)
2358 /* fire Class Prepare JVMTI event */
2361 jvmti_ClassLoadPrepare(true, c);
2364 #if !defined(NDEBUG)
2366 log_message_class("Loading done class: ", c);
2369 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
2370 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
2371 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
2372 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
2373 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
2374 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
2375 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
2376 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
2377 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
2378 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
2379 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
2380 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
2381 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
2382 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
2383 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
2388 /* release dump area */
2390 dump_release(dumpsize);
2392 /* an exception has been thrown */
2398 /* load_newly_created_array ****************************************************
2400 Load a newly created array class.
2403 c....................the array class C has been loaded
2404 other classinfo......the array class was found in the class cache,
2406 NULL.................an exception has been thrown
2409 This is an internal function. Do not use it unless you know exactly
2412 Use one of the load_class_... functions for general array class loading.
2414 *******************************************************************************/
2416 classinfo *load_newly_created_array(classinfo *c, java_objectheader *loader)
2418 classinfo *comp = NULL;
2420 methoddesc *clonedesc;
2421 constant_classref *classrefs;
2426 text = c->name->text;
2427 namelen = c->name->blength;
2429 /* Check array class name */
2431 if ((namelen < 2) || (text[0] != '[')) {
2432 exceptions_throw_noclassdeffounderror(c->name);
2436 /* Check the element type */
2440 /* c is an array of arrays. We have to create the component class. */
2442 u = utf_new(text + 1, namelen - 1);
2443 if (!(comp = load_class_from_classloader(u, loader)))
2446 assert(comp->state & CLASS_LOADED);
2452 /* the array's flags are that of the component class */
2453 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2454 c->classloader = comp->classloader;
2458 /* c is an array of objects. */
2460 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2461 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2462 exceptions_throw_noclassdeffounderror(c->name);
2466 u = utf_new(text + 2, namelen - 3);
2468 if (!(comp = load_class_from_classloader(u, loader)))
2471 assert(comp->state & CLASS_LOADED);
2477 /* the array's flags are that of the component class */
2478 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2479 c->classloader = comp->classloader;
2483 /* c is an array of a primitive type */
2485 /* check for cases like `[II' */
2487 exceptions_throw_noclassdeffounderror(c->name);
2491 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2492 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2493 c->classloader = NULL;
2496 assert(class_java_lang_Object);
2497 #if defined(ENABLE_JAVASE)
2498 assert(class_java_lang_Cloneable);
2499 assert(class_java_io_Serializable);
2502 /* setup the array class */
2504 c->super.cls = class_java_lang_Object;
2506 #if defined(ENABLE_JAVASE)
2507 c->interfacescount = 2;
2508 c->interfaces = MNEW(classref_or_classinfo, 2);
2513 tc = class_java_lang_Cloneable;
2514 assert(tc->state & CLASS_LOADED);
2515 list_add_first(&unlinkedclasses, tc);
2516 c->interfaces[0].cls = tc;
2518 tc = class_java_io_Serializable;
2519 assert(tc->state & CLASS_LOADED);
2520 list_add_first(&unlinkedclasses, tc);
2521 c->interfaces[1].cls = tc;
2524 c->interfaces[0].cls = class_java_lang_Cloneable;
2525 c->interfaces[1].cls = class_java_io_Serializable;
2527 #elif defined(ENABLE_JAVAME_CLDC1_1)
2528 c->interfacescount = 0;
2529 c->interfaces = NULL;
2531 #error unknow Java configuration
2534 c->methodscount = 1;
2535 c->methods = MNEW(methodinfo, c->methodscount);
2536 MZERO(c->methods, methodinfo, c->methodscount);
2538 classrefs = MNEW(constant_classref, 2);
2539 CLASSREF_INIT(classrefs[0], c, c->name);
2540 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2542 /* create descriptor for clone method */
2543 /* we need one paramslot which is reserved for the 'this' parameter */
2544 clonedesc = NEW(methoddesc);
2545 clonedesc->returntype.type = TYPE_ADR;
2546 clonedesc->returntype.classref = classrefs + 1;
2547 clonedesc->returntype.arraydim = 0;
2548 /* initialize params to "empty", add real params below in
2549 descriptor_params_from_paramtypes */
2550 clonedesc->paramcount = 0;
2551 clonedesc->paramslots = 0;
2552 clonedesc->paramtypes[0].classref = classrefs + 0;
2553 clonedesc->params = NULL;
2555 /* create methodinfo */
2558 MSET(clone, 0, methodinfo, 1);
2560 /* ATTENTION: if you delete the ACC_NATIVE below, set
2561 clone->maxlocals=1 (interpreter related) */
2563 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2564 clone->name = utf_clone;
2565 clone->descriptor = utf_void__java_lang_Object;
2566 clone->parseddesc = clonedesc;
2569 /* parse the descriptor to get the register allocation */
2571 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2574 clone->code = codegen_createnativestub(BUILTIN_clone, clone);
2576 /* XXX: field: length? */
2578 /* array classes are not loaded from class files */
2580 c->state |= CLASS_LOADED;
2581 c->parseddescs = (u1 *) clonedesc;
2582 c->parseddescsize = sizeof(methodinfo);
2583 c->classrefs = classrefs;
2584 c->classrefcount = 1;
2586 /* insert class into the loaded class cache */
2587 /* XXX free classinfo if NULL returned? */
2589 return classcache_store(loader, c, true);
2593 /* loader_close ****************************************************************
2595 Frees all resources.
2597 *******************************************************************************/
2599 void loader_close(void)
2606 * These are local overrides for various environment variables in Emacs.
2607 * Please do not remove this and leave it at the end of the file, where
2608 * Emacs will automagically detect them.
2609 * ---------------------------------------------------------------------
2612 * indent-tabs-mode: t
2616 * vim:noexpandtab:sw=4:ts=4: