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 7575 2007-03-25 20:30:50Z twisti $
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_THREADS)
1099 lock_init_object_lock(&m->header);
1102 #if defined(ENABLE_STATISTICS)
1104 count_all_methods++;
1107 /* all fields of m have been zeroed in load_class_from_classbuffer */
1111 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
1116 m->flags = suck_u2(cb);
1120 name_index = suck_u2(cb);
1122 if (!(u = class_getconstant(c, name_index, CONSTANT_Utf8)))
1129 descriptor_index = suck_u2(cb);
1131 if (!(u = class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
1136 if (!descriptor_pool_add(descpool, u, &argcount))
1139 #ifdef ENABLE_VERIFIER
1141 if (!is_valid_name_utf(m->name)) {
1142 exceptions_throw_classformaterror(c, "Method with invalid name");
1146 if (m->name->text[0] == '<' &&
1147 m->name != utf_init && m->name != utf_clinit) {
1148 exceptions_throw_classformaterror(c, "Method with invalid special name");
1152 #endif /* ENABLE_VERIFIER */
1154 if (!(m->flags & ACC_STATIC))
1155 argcount++; /* count the 'this' argument */
1157 #ifdef ENABLE_VERIFIER
1159 if (argcount > 255) {
1160 exceptions_throw_classformaterror(c, "Too many arguments in signature");
1164 /* check flag consistency */
1165 if (m->name != utf_clinit) {
1166 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1168 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1169 exceptions_throw_classformaterror(c,
1170 "Illegal method modifiers: 0x%X",
1175 if (m->flags & ACC_ABSTRACT) {
1176 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1177 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1178 exceptions_throw_classformaterror(c,
1179 "Illegal method modifiers: 0x%X",
1185 if (c->flags & ACC_INTERFACE) {
1186 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1187 exceptions_throw_classformaterror(c,
1188 "Illegal method modifiers: 0x%X",
1194 if (m->name == utf_init) {
1195 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1196 ACC_NATIVE | ACC_ABSTRACT)) {
1197 exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
1203 #endif /* ENABLE_VERIFIER */
1205 /* mark the method as monomorphic until further notice */
1207 m->flags |= ACC_METHOD_MONOMORPHIC;
1209 /* non-abstract methods have an implementation in this class */
1211 if (!(m->flags & ACC_ABSTRACT))
1212 m->flags |= ACC_METHOD_IMPLEMENTED;
1214 if (!suck_check_classbuffer_size(cb, 2))
1217 /* attributes count */
1219 attributes_count = suck_u2(cb);
1221 for (i = 0; i < attributes_count; i++) {
1222 if (!suck_check_classbuffer_size(cb, 2))
1225 /* attribute name index */
1227 attribute_name_index = suck_u2(cb);
1229 if (!(attribute_name = class_getconstant(c, attribute_name_index, CONSTANT_Utf8)))
1232 if (attribute_name == utf_Code) {
1234 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1235 exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
1240 exceptions_throw_classformaterror(c, "Multiple Code attributes");
1244 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1248 m->maxstack = suck_u2(cb);
1249 m->maxlocals = suck_u2(cb);
1251 if (m->maxlocals < argcount) {
1252 exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
1256 if (!suck_check_classbuffer_size(cb, 4))
1259 m->jcodelength = suck_u4(cb);
1261 if (m->jcodelength == 0) {
1262 exceptions_throw_classformaterror(c, "Code of a method has length 0");
1266 if (m->jcodelength > 65535) {
1267 exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
1271 if (!suck_check_classbuffer_size(cb, m->jcodelength))
1274 m->jcode = MNEW(u1, m->jcodelength);
1275 suck_nbytes(m->jcode, cb, m->jcodelength);
1277 if (!suck_check_classbuffer_size(cb, 2))
1280 m->rawexceptiontablelength = suck_u2(cb);
1281 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->rawexceptiontablelength))
1284 m->rawexceptiontable = MNEW(raw_exception_entry, m->rawexceptiontablelength);
1286 #if defined(ENABLE_STATISTICS)
1288 count_vmcode_len += m->jcodelength + 18;
1289 count_extable_len +=
1290 m->rawexceptiontablelength * sizeof(raw_exception_entry);
1294 for (j = 0; j < m->rawexceptiontablelength; j++) {
1296 m->rawexceptiontable[j].startpc = suck_u2(cb);
1297 m->rawexceptiontable[j].endpc = suck_u2(cb);
1298 m->rawexceptiontable[j].handlerpc = suck_u2(cb);
1302 m->rawexceptiontable[j].catchtype.any = NULL;
1305 /* the classref is created later */
1306 if (!(m->rawexceptiontable[j].catchtype.any =
1307 (utf*)class_getconstant(c, idx, CONSTANT_Class)))
1312 if (!suck_check_classbuffer_size(cb, 2))
1315 /* code attributes count */
1317 code_attributes_count = suck_u2(cb);
1319 for (k = 0; k < code_attributes_count; k++) {
1320 if (!suck_check_classbuffer_size(cb, 2))
1323 /* code attribute name index */
1325 code_attribute_name_index = suck_u2(cb);
1327 if (!(code_attribute_name = class_getconstant(c, code_attribute_name_index, CONSTANT_Utf8)))
1330 /* check which code attribute */
1332 if (code_attribute_name == utf_LineNumberTable) {
1333 /* LineNumberTable */
1334 if (!suck_check_classbuffer_size(cb, 4 + 2))
1337 /* attribute length */
1341 /* line number table length */
1343 m->linenumbercount = suck_u2(cb);
1345 if (!suck_check_classbuffer_size(cb,
1346 (2 + 2) * m->linenumbercount))
1349 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1351 #if defined(ENABLE_STATISTICS)
1353 size_lineinfo += sizeof(lineinfo) * m->linenumbercount;
1356 for (l = 0; l < m->linenumbercount; l++) {
1357 m->linenumbers[l].start_pc = suck_u2(cb);
1358 m->linenumbers[l].line_number = suck_u2(cb);
1361 #if defined(ENABLE_JAVASE)
1362 else if (code_attribute_name == utf_StackMapTable) {
1365 if (!stackmap_load_attribute_stackmaptable(cb, m))
1370 /* unknown code attribute */
1372 if (!loader_skip_attribute_body(cb))
1377 else if (attribute_name == utf_Exceptions) {
1380 if (m->thrownexceptions != NULL) {
1381 exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
1385 if (!suck_check_classbuffer_size(cb, 4 + 2))
1388 /* attribute length */
1392 m->thrownexceptionscount = suck_u2(cb);
1394 if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1397 m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
1399 for (j = 0; j < m->thrownexceptionscount; j++) {
1400 /* the classref is created later */
1401 if (!((m->thrownexceptions)[j].any =
1402 (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1406 #if defined(ENABLE_JAVASE)
1407 else if (attribute_name == utf_Signature) {
1410 if (!loader_load_attribute_signature(cb, &(m->signature)))
1415 /* unknown attribute */
1417 if (!loader_skip_attribute_body(cb))
1422 if ((m->jcode == NULL) && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1423 exceptions_throw_classformaterror(c, "Missing Code attribute");
1427 /* initialize the hit countdown field */
1429 #if defined(ENABLE_REPLACEMENT)
1430 m->hitcountdown = METHOD_INITIAL_HIT_COUNTDOWN;
1433 /* everything was ok */
1439 /* load_class_from_sysloader ***************************************************
1441 Load the class with the given name using the system class loader
1444 name.............the classname
1447 the loaded class, or
1448 NULL if an exception has been thrown
1450 *******************************************************************************/
1452 classinfo *load_class_from_sysloader(utf *name)
1455 java_objectheader *cl;
1458 assert(class_java_lang_Object);
1459 assert(class_java_lang_ClassLoader);
1460 assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
1462 m = class_resolveclassmethod(class_java_lang_ClassLoader,
1463 utf_getSystemClassLoader,
1464 utf_void__java_lang_ClassLoader,
1465 class_java_lang_Object,
1471 cl = vm_call_method(m, NULL);
1476 c = load_class_from_classloader(name, cl);
1482 /* load_class_from_classloader *************************************************
1484 Load the class with the given name using the given user-defined class loader.
1487 name.............the classname
1488 cl...............user-defined class loader
1491 the loaded class, or
1492 NULL if an exception has been thrown
1494 *******************************************************************************/
1496 classinfo *load_class_from_classloader(utf *name, java_objectheader *cl)
1498 java_objectheader *o;
1501 java_objectheader *string;
1502 #if defined(ENABLE_RT_TIMING)
1503 struct timespec time_start, time_lookup, time_prepare, time_java,
1507 RT_TIMING_GET_TIME(time_start);
1511 /* lookup if this class has already been loaded */
1513 c = classcache_lookup(cl, name);
1515 RT_TIMING_GET_TIME(time_lookup);
1516 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1521 /* if other class loader than bootstrap, call it */
1529 namelen = name->blength;
1531 /* handle array classes */
1532 if (text[0] == '[') {
1538 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1539 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1540 exceptions_throw_noclassdeffounderror(name);
1544 u = utf_new(text + 2, namelen - 3);
1546 if (!(comp = load_class_from_classloader(u, cl)))
1549 /* create the array class */
1551 c = class_array_of(comp, false);
1553 tmpc = classcache_store(cl, c, true);
1556 /* exception, free the loaded class */
1557 c->state &= ~CLASS_LOADING;
1564 /* load the component class */
1566 u = utf_new(text + 1, namelen - 1);
1568 if (!(comp = load_class_from_classloader(u, cl)))
1571 /* create the array class */
1573 c = class_array_of(comp, false);
1575 tmpc = classcache_store(cl, c, true);
1578 /* exception, free the loaded class */
1579 c->state &= ~CLASS_LOADING;
1586 /* primitive array classes are loaded by the bootstrap loader */
1588 c = load_class_bootstrap(name);
1594 assert(class_java_lang_Object);
1596 lc = class_resolveclassmethod(cl->vftbl->class,
1598 utf_java_lang_String__java_lang_Class,
1599 class_java_lang_Object,
1603 return false; /* exception */
1605 /* move return value into `o' and cast it afterwards to a classinfo* */
1607 string = javastring_new_slash_to_dot(name);
1609 RT_TIMING_GET_TIME(time_prepare);
1611 o = vm_call_method(lc, cl, string);
1613 RT_TIMING_GET_TIME(time_java);
1615 c = (classinfo *) o;
1618 /* Store this class in the loaded class cache. If another
1619 class with the same (initloader,name) pair has been
1620 stored earlier it will be returned by classcache_store
1621 In this case classcache_store may not free the class
1622 because it has already been exposed to Java code which
1623 may have kept references to that class. */
1625 tmpc = classcache_store(cl, c, false);
1628 /* exception, free the loaded class */
1629 c->state &= ~CLASS_LOADING;
1636 /* loadClass has thrown an exception. We must convert
1637 ClassNotFoundException into
1638 NoClassDefFoundException. */
1640 /* XXX Maybe we should have a flag that avoids this
1641 conversion for calling load_class_from_classloader from
1642 Class.forName. Currently we do a double conversion in
1645 classnotfoundexception_to_noclassdeffounderror();
1648 RT_TIMING_GET_TIME(time_cache);
1650 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1651 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1652 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1654 /* SUN compatible -verbose:class output */
1656 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1658 utf_display_printable_ascii_classname(name);
1662 #if defined(ENABLE_JVMTI)
1663 /* fire Class Load JVMTI event */
1664 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1671 c = load_class_bootstrap(name);
1677 /* load_class_bootstrap ********************************************************
1679 Load the class with the given name using the bootstrap class loader.
1682 name.............the classname
1685 loaded classinfo, or
1686 NULL if an exception has been thrown
1689 load_class_bootstrap is synchronized. It can be treated as an
1692 *******************************************************************************/
1694 classinfo *load_class_bootstrap(utf *name)
1699 #if defined(ENABLE_RT_TIMING)
1700 struct timespec time_start, time_lookup, time_array, time_suck,
1701 time_load, time_cache;
1704 RT_TIMING_GET_TIME(time_start);
1710 /* lookup if this class has already been loaded */
1712 if ((r = classcache_lookup(NULL, name))) {
1714 RT_TIMING_GET_TIME(time_lookup);
1715 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1720 RT_TIMING_GET_TIME(time_lookup);
1721 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1723 /* create the classinfo */
1725 c = class_create_classinfo(name);
1727 /* handle array classes */
1729 if (name->text[0] == '[') {
1730 c = load_newly_created_array(c, NULL);
1733 assert(c->state & CLASS_LOADED);
1735 RT_TIMING_GET_TIME(time_array);
1736 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1741 #if defined(ENABLE_STATISTICS)
1744 if (opt_getcompilingtime)
1745 compilingtime_stop();
1747 if (opt_getloadingtime)
1748 loadingtime_start();
1751 /* load classdata, throw exception on error */
1756 /* this normally means, the classpath was not set properly */
1758 if (name == utf_java_lang_Object)
1759 vm_abort("java/lang/NoClassDefFoundError: java/lang/Object");
1761 exceptions_throw_noclassdeffounderror(name);
1766 RT_TIMING_GET_TIME(time_suck);
1768 /* load the class from the buffer */
1770 r = load_class_from_classbuffer(cb);
1772 RT_TIMING_GET_TIME(time_load);
1775 /* the class could not be loaded, free the classinfo struct */
1780 /* Store this class in the loaded class cache this step also
1781 checks the loading constraints. If the class has been loaded
1782 before, the earlier loaded class is returned. */
1784 classinfo *res = classcache_store(NULL, c, true);
1794 RT_TIMING_GET_TIME(time_cache);
1796 /* SUN compatible -verbose:class output */
1798 if (opt_verboseclass && r) {
1800 utf_display_printable_ascii_classname(name);
1801 printf(" from %s]\n", cb->path);
1808 #if defined(ENABLE_STATISTICS)
1811 if (opt_getloadingtime)
1814 if (opt_getcompilingtime)
1815 compilingtime_start();
1818 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1819 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1820 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1821 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1827 /* load_class_from_classbuffer *************************************************
1829 Loads everything interesting about a class from the class file. The
1830 'classinfo' structure must have been allocated previously.
1832 The super class and the interfaces implemented by this class need
1833 not be loaded. The link is set later by the function 'class_link'.
1835 The loaded class is removed from the list 'unloadedclasses' and
1836 added to the list 'unlinkedclasses'.
1839 This function is NOT synchronized!
1841 *******************************************************************************/
1843 classinfo *load_class_from_classbuffer(classbuffer *cb)
1851 descriptor_pool *descpool;
1852 #if defined(ENABLE_STATISTICS)
1856 #if defined(ENABLE_RT_TIMING)
1857 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1858 time_setup, time_fields, time_methods, time_classrefs,
1859 time_descs, time_setrefs, time_parsefds, time_parsemds,
1860 time_parsecpool, time_verify, time_attrs;
1863 RT_TIMING_GET_TIME(time_start);
1865 /* get the classbuffer's class */
1869 /* the class is already loaded */
1871 if (c->state & CLASS_LOADED)
1874 #if defined(ENABLE_STATISTICS)
1876 count_class_loads++;
1879 #if !defined(NDEBUG)
1880 /* output for debugging purposes */
1883 log_message_class("Loading class: ", c);
1886 /* mark start of dump memory area */
1888 dumpsize = dump_size();
1890 /* class is currently loading */
1892 c->state |= CLASS_LOADING;
1894 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1895 goto return_exception;
1897 /* check signature */
1899 if (suck_u4(cb) != MAGIC) {
1900 exceptions_throw_classformaterror(c, "Bad magic number");
1902 goto return_exception;
1910 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1911 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1912 goto return_exception;
1915 RT_TIMING_GET_TIME(time_checks);
1917 /* create a new descriptor pool */
1919 descpool = descriptor_pool_new(c);
1921 RT_TIMING_GET_TIME(time_ndpool);
1923 /* load the constant pool */
1925 if (!load_constantpool(cb, descpool))
1926 goto return_exception;
1928 RT_TIMING_GET_TIME(time_cpool);
1932 if (!suck_check_classbuffer_size(cb, 2))
1933 goto return_exception;
1935 /* We OR the flags here, as we set already some flags in
1936 class_create_classinfo. */
1938 c->flags |= suck_u2(cb);
1940 /* check ACC flags consistency */
1942 if (c->flags & ACC_INTERFACE) {
1943 if (!(c->flags & ACC_ABSTRACT)) {
1944 /* We work around this because interfaces in JDK 1.1 are
1945 * not declared abstract. */
1947 c->flags |= ACC_ABSTRACT;
1950 if (c->flags & ACC_FINAL) {
1951 exceptions_throw_classformaterror(c,
1952 "Illegal class modifiers: 0x%X",
1954 goto return_exception;
1957 if (c->flags & ACC_SUPER) {
1958 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1962 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1963 exceptions_throw_classformaterror(c,
1964 "Illegal class modifiers: 0x%X",
1966 goto return_exception;
1969 if (!suck_check_classbuffer_size(cb, 2 + 2))
1970 goto return_exception;
1975 if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1976 goto return_exception;
1978 if (c->name == utf_not_named_yet) {
1979 /* we finally have a name for this class */
1981 class_set_packagename(c);
1983 } else if (name != c->name) {
1984 /* TODO: i want to be an exceptions-function! */
1988 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
1989 utf_bytes(name) + strlen(")") + strlen("0");
1991 msg = MNEW(char, msglen);
1993 utf_copy_classname(msg, c->name);
1994 strcat(msg, " (wrong name: ");
1995 utf_cat_classname(msg, name);
1999 /* *exceptionptr = */
2000 /* new_exception_message("java/lang/NoClassDefFoundError", msg); */
2001 exceptions_throw_noclassdeffounderror(c->name);
2003 MFREE(msg, char, msglen);
2005 goto return_exception;
2008 /* retrieve superclass */
2010 c->super.any = NULL;
2011 if ((i = suck_u2(cb))) {
2012 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
2013 goto return_exception;
2015 /* java.lang.Object may not have a super class. */
2017 if (c->name == utf_java_lang_Object) {
2018 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
2019 goto return_exception;
2022 /* Interfaces must have java.lang.Object as super class. */
2024 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
2025 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
2026 goto return_exception;
2032 /* This is only allowed for java.lang.Object. */
2034 if (c->name != utf_java_lang_Object) {
2035 exceptions_throw_classformaterror(c, "Bad superclass index");
2036 goto return_exception;
2040 /* retrieve interfaces */
2042 if (!suck_check_classbuffer_size(cb, 2))
2043 goto return_exception;
2045 c->interfacescount = suck_u2(cb);
2047 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
2048 goto return_exception;
2050 c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
2051 for (i = 0; i < c->interfacescount; i++) {
2052 /* the classrefs are created later */
2053 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2054 goto return_exception;
2057 RT_TIMING_GET_TIME(time_setup);
2060 if (!suck_check_classbuffer_size(cb, 2))
2061 goto return_exception;
2063 c->fieldscount = suck_u2(cb);
2064 #if defined(ENABLE_GC_CACAO)
2065 c->fields = MNEW(fieldinfo, c->fieldscount);
2066 MZERO(c->fields, fieldinfo, c->fieldscount);
2068 c->fields = GCNEW_UNCOLLECTABLE(fieldinfo, c->fieldscount);
2071 for (i = 0; i < c->fieldscount; i++) {
2072 if (!load_field(cb, &(c->fields[i]),descpool))
2073 goto return_exception;
2076 RT_TIMING_GET_TIME(time_fields);
2079 if (!suck_check_classbuffer_size(cb, 2))
2080 goto return_exception;
2082 c->methodscount = suck_u2(cb);
2083 c->methods = MNEW(methodinfo, c->methodscount);
2085 MZERO(c->methods, methodinfo, c->methodscount);
2087 for (i = 0; i < c->methodscount; i++) {
2088 if (!loader_load_method(cb, &(c->methods[i]), descpool))
2089 goto return_exception;
2092 RT_TIMING_GET_TIME(time_methods);
2094 /* create the class reference table */
2097 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
2099 RT_TIMING_GET_TIME(time_classrefs);
2101 /* allocate space for the parsed descriptors */
2103 descriptor_pool_alloc_parsed_descriptors(descpool);
2105 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
2107 #if defined(ENABLE_STATISTICS)
2109 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
2110 count_classref_len += classrefsize;
2111 count_parsed_desc_len += descsize;
2115 RT_TIMING_GET_TIME(time_descs);
2117 /* put the classrefs in the constant pool */
2118 for (i = 0; i < c->cpcount; i++) {
2119 if (c->cptags[i] == CONSTANT_Class) {
2120 utf *name = (utf *) c->cpinfos[i];
2121 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
2125 /* set the super class reference */
2128 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
2130 goto return_exception;
2133 /* set the super interfaces references */
2135 for (i = 0; i < c->interfacescount; i++) {
2136 c->interfaces[i].ref =
2137 descriptor_pool_lookup_classref(descpool,
2138 (utf *) c->interfaces[i].any);
2139 if (!c->interfaces[i].ref)
2140 goto return_exception;
2143 RT_TIMING_GET_TIME(time_setrefs);
2145 /* parse field descriptors */
2147 for (i = 0; i < c->fieldscount; i++) {
2148 c->fields[i].parseddesc =
2149 descriptor_pool_parse_field_descriptor(descpool,
2150 c->fields[i].descriptor);
2151 if (!c->fields[i].parseddesc)
2152 goto return_exception;
2155 RT_TIMING_GET_TIME(time_parsefds);
2157 /* parse method descriptors */
2159 for (i = 0; i < c->methodscount; i++) {
2160 methodinfo *m = &c->methods[i];
2162 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
2163 m->flags, class_get_self_classref(m->class));
2165 goto return_exception;
2167 for (j = 0; j < m->rawexceptiontablelength; j++) {
2168 if (!m->rawexceptiontable[j].catchtype.any)
2170 if ((m->rawexceptiontable[j].catchtype.ref =
2171 descriptor_pool_lookup_classref(descpool,
2172 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
2173 goto return_exception;
2176 for (j = 0; j < m->thrownexceptionscount; j++) {
2177 if (!m->thrownexceptions[j].any)
2179 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
2180 (utf *) m->thrownexceptions[j].any)) == NULL)
2181 goto return_exception;
2185 RT_TIMING_GET_TIME(time_parsemds);
2187 /* parse the loaded descriptors */
2189 for (i = 0; i < c->cpcount; i++) {
2190 constant_FMIref *fmi;
2193 switch (c->cptags[i]) {
2194 case CONSTANT_Fieldref:
2195 fmi = (constant_FMIref *) c->cpinfos[i];
2196 fmi->parseddesc.fd =
2197 descriptor_pool_parse_field_descriptor(descpool,
2199 if (!fmi->parseddesc.fd)
2200 goto return_exception;
2201 index = fmi->p.index;
2203 (constant_classref *) class_getconstant(c, index,
2205 if (!fmi->p.classref)
2206 goto return_exception;
2208 case CONSTANT_Methodref:
2209 case CONSTANT_InterfaceMethodref:
2210 fmi = (constant_FMIref *) c->cpinfos[i];
2211 index = fmi->p.index;
2213 (constant_classref *) class_getconstant(c, index,
2215 if (!fmi->p.classref)
2216 goto return_exception;
2217 fmi->parseddesc.md =
2218 descriptor_pool_parse_method_descriptor(descpool,
2222 if (!fmi->parseddesc.md)
2223 goto return_exception;
2228 RT_TIMING_GET_TIME(time_parsecpool);
2230 #ifdef ENABLE_VERIFIER
2231 /* Check if all fields and methods can be uniquely
2232 * identified by (name,descriptor). */
2235 /* We use a hash table here to avoid making the
2236 * average case quadratic in # of methods, fields.
2238 static int shift = 0;
2240 u2 *next; /* for chaining colliding hash entries */
2246 /* Allocate hashtable */
2247 len = c->methodscount;
2248 if (len < c->fieldscount) len = c->fieldscount;
2250 hashtab = MNEW(u2,(hashlen + len));
2251 next = hashtab + hashlen;
2253 /* Determine bitshift (to get good hash values) */
2263 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2265 for (i = 0; i < c->fieldscount; ++i) {
2266 fieldinfo *fi = c->fields + i;
2268 /* It's ok if we lose bits here */
2269 index = ((((size_t) fi->name) +
2270 ((size_t) fi->descriptor)) >> shift) % hashlen;
2272 if ((old = hashtab[index])) {
2276 if (c->fields[old].name == fi->name &&
2277 c->fields[old].descriptor == fi->descriptor) {
2278 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
2279 goto return_exception;
2281 } while ((old = next[old]));
2283 hashtab[index] = i + 1;
2287 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2289 for (i = 0; i < c->methodscount; ++i) {
2290 methodinfo *mi = c->methods + i;
2292 /* It's ok if we lose bits here */
2293 index = ((((size_t) mi->name) +
2294 ((size_t) mi->descriptor)) >> shift) % hashlen;
2298 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2299 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2303 if ((old = hashtab[index])) {
2307 if (c->methods[old].name == mi->name &&
2308 c->methods[old].descriptor == mi->descriptor) {
2309 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
2310 goto return_exception;
2312 } while ((old = next[old]));
2314 hashtab[index] = i + 1;
2317 MFREE(hashtab, u2, (hashlen + len));
2319 #endif /* ENABLE_VERIFIER */
2321 RT_TIMING_GET_TIME(time_verify);
2323 #if defined(ENABLE_STATISTICS)
2325 size_classinfo += sizeof(classinfo*) * c->interfacescount;
2326 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
2327 size_methodinfo += sizeof(methodinfo) * c->methodscount;
2331 /* load attribute structures */
2333 if (!class_load_attributes(cb))
2334 goto return_exception;
2336 /* Pre Java 1.5 version don't check this. This implementation is like
2337 Java 1.5 do it: for class file version 45.3 we don't check it, older
2338 versions are checked.
2341 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
2342 /* check if all data has been read */
2343 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
2345 if (classdata_left > 0) {
2346 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
2347 goto return_exception;
2351 RT_TIMING_GET_TIME(time_attrs);
2353 /* release dump area */
2355 dump_release(dumpsize);
2357 /* revert loading state and class is loaded */
2359 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2361 #if defined(ENABLE_JVMTI)
2362 /* fire Class Prepare JVMTI event */
2365 jvmti_ClassLoadPrepare(true, c);
2368 #if !defined(NDEBUG)
2370 log_message_class("Loading done class: ", c);
2373 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
2374 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
2375 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
2376 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
2377 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
2378 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
2379 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
2380 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
2381 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
2382 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
2383 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
2384 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
2385 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
2386 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
2387 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
2392 /* release dump area */
2394 dump_release(dumpsize);
2396 /* an exception has been thrown */
2402 /* load_newly_created_array ****************************************************
2404 Load a newly created array class.
2407 c....................the array class C has been loaded
2408 other classinfo......the array class was found in the class cache,
2410 NULL.................an exception has been thrown
2413 This is an internal function. Do not use it unless you know exactly
2416 Use one of the load_class_... functions for general array class loading.
2418 *******************************************************************************/
2420 classinfo *load_newly_created_array(classinfo *c, java_objectheader *loader)
2422 classinfo *comp = NULL;
2424 methoddesc *clonedesc;
2425 constant_classref *classrefs;
2430 text = c->name->text;
2431 namelen = c->name->blength;
2433 /* Check array class name */
2435 if ((namelen < 2) || (text[0] != '[')) {
2436 exceptions_throw_noclassdeffounderror(c->name);
2440 /* Check the element type */
2444 /* c is an array of arrays. We have to create the component class. */
2446 u = utf_new(text + 1, namelen - 1);
2447 if (!(comp = load_class_from_classloader(u, loader)))
2450 assert(comp->state & CLASS_LOADED);
2456 /* the array's flags are that of the component class */
2457 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2458 c->classloader = comp->classloader;
2462 /* c is an array of objects. */
2464 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2465 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2466 exceptions_throw_noclassdeffounderror(c->name);
2470 u = utf_new(text + 2, namelen - 3);
2472 if (!(comp = load_class_from_classloader(u, loader)))
2475 assert(comp->state & CLASS_LOADED);
2481 /* the array's flags are that of the component class */
2482 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2483 c->classloader = comp->classloader;
2487 /* c is an array of a primitive type */
2489 /* check for cases like `[II' */
2491 exceptions_throw_noclassdeffounderror(c->name);
2495 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2496 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2497 c->classloader = NULL;
2500 assert(class_java_lang_Object);
2501 #if defined(ENABLE_JAVASE)
2502 assert(class_java_lang_Cloneable);
2503 assert(class_java_io_Serializable);
2506 /* setup the array class */
2508 c->super.cls = class_java_lang_Object;
2510 #if defined(ENABLE_JAVASE)
2511 c->interfacescount = 2;
2512 c->interfaces = MNEW(classref_or_classinfo, 2);
2517 tc = class_java_lang_Cloneable;
2518 assert(tc->state & CLASS_LOADED);
2519 list_add_first(&unlinkedclasses, tc);
2520 c->interfaces[0].cls = tc;
2522 tc = class_java_io_Serializable;
2523 assert(tc->state & CLASS_LOADED);
2524 list_add_first(&unlinkedclasses, tc);
2525 c->interfaces[1].cls = tc;
2528 c->interfaces[0].cls = class_java_lang_Cloneable;
2529 c->interfaces[1].cls = class_java_io_Serializable;
2531 #elif defined(ENABLE_JAVAME_CLDC1_1)
2532 c->interfacescount = 0;
2533 c->interfaces = NULL;
2535 #error unknow Java configuration
2538 c->methodscount = 1;
2539 c->methods = MNEW(methodinfo, c->methodscount);
2540 MZERO(c->methods, methodinfo, c->methodscount);
2542 classrefs = MNEW(constant_classref, 2);
2543 CLASSREF_INIT(classrefs[0], c, c->name);
2544 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2546 /* create descriptor for clone method */
2547 /* we need one paramslot which is reserved for the 'this' parameter */
2548 clonedesc = NEW(methoddesc);
2549 clonedesc->returntype.type = TYPE_ADR;
2550 clonedesc->returntype.classref = classrefs + 1;
2551 clonedesc->returntype.arraydim = 0;
2552 /* initialize params to "empty", add real params below in
2553 descriptor_params_from_paramtypes */
2554 clonedesc->paramcount = 0;
2555 clonedesc->paramslots = 0;
2556 clonedesc->paramtypes[0].classref = classrefs + 0;
2557 clonedesc->params = NULL;
2559 /* create methodinfo */
2562 MSET(clone, 0, methodinfo, 1);
2564 #if defined(ENABLE_THREADS)
2565 lock_init_object_lock(&clone->header);
2568 /* ATTENTION: if you delete the ACC_NATIVE below, set
2569 clone->maxlocals=1 (interpreter related) */
2571 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2572 clone->name = utf_clone;
2573 clone->descriptor = utf_void__java_lang_Object;
2574 clone->parseddesc = clonedesc;
2577 /* parse the descriptor to get the register allocation */
2579 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2582 clone->code = codegen_createnativestub(BUILTIN_clone, clone);
2584 /* XXX: field: length? */
2586 /* array classes are not loaded from class files */
2588 c->state |= CLASS_LOADED;
2589 c->parseddescs = (u1 *) clonedesc;
2590 c->parseddescsize = sizeof(methodinfo);
2591 c->classrefs = classrefs;
2592 c->classrefcount = 1;
2594 /* insert class into the loaded class cache */
2595 /* XXX free classinfo if NULL returned? */
2597 return classcache_store(loader, c, true);
2601 /* loader_close ****************************************************************
2603 Frees all resources.
2605 *******************************************************************************/
2607 void loader_close(void)
2614 * These are local overrides for various environment variables in Emacs.
2615 * Please do not remove this and leave it at the end of the file, where
2616 * Emacs will automagically detect them.
2617 * ---------------------------------------------------------------------
2620 * indent-tabs-mode: t
2624 * vim:noexpandtab:sw=4:ts=4: