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 7387 2007-02-21 23:26:24Z 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/asmpart.h"
53 #include "vm/jit/codegen-common.h"
55 #if defined(ENABLE_JAVASE)
56 # include "vmcore/annotation.h"
57 # include "vmcore/stackmap.h"
60 #include "vmcore/classcache.h"
61 #include "vmcore/linker.h"
62 #include "vmcore/loader.h"
63 #include "vmcore/options.h"
64 #include "vmcore/rt-timing.h"
66 #if defined(ENABLE_STATISTICS)
67 # include "vmcore/statistics.h"
70 #include "vmcore/suck.h"
72 #if defined(ENABLE_ZLIB)
73 # include "vmcore/zip.h"
76 #if defined(ENABLE_JVMTI)
77 # include "native/jvmti/cacaodbg.h"
81 /* loader_init *****************************************************************
83 Initializes all lists and loads all classes required for the system
86 *******************************************************************************/
88 bool loader_init(void)
90 #if defined(ENABLE_THREADS)
91 list_classpath_entry *lce;
93 /* Initialize the monitor pointer for zip/jar file locking. */
95 for (lce = list_first(list_classpath_entries); lce != NULL;
96 lce = list_next(list_classpath_entries, lce))
97 if (lce->type == CLASSPATH_ARCHIVE)
98 lock_init_object_lock((java_objectheader *) lce);
101 /* load some important classes */
103 if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
106 if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
109 #if defined(ENABLE_JAVASE)
110 if (!(class_java_lang_Cloneable =
111 load_class_bootstrap(utf_java_lang_Cloneable)))
114 if (!(class_java_io_Serializable =
115 load_class_bootstrap(utf_java_io_Serializable)))
119 /* load classes for wrapping primitive types */
121 #if defined(ENABLE_JAVASE)
122 if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
126 if (!(class_java_lang_Boolean =
127 load_class_bootstrap(utf_java_lang_Boolean)))
130 if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
133 if (!(class_java_lang_Character =
134 load_class_bootstrap(utf_java_lang_Character)))
137 if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
140 if (!(class_java_lang_Integer =
141 load_class_bootstrap(utf_java_lang_Integer)))
144 if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
147 if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
150 if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
154 /* load some other important classes */
156 if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
159 #if defined(ENABLE_JAVASE)
160 if (!(class_java_lang_ClassLoader =
161 load_class_bootstrap(utf_java_lang_ClassLoader)))
164 if (!(class_java_lang_SecurityManager =
165 load_class_bootstrap(utf_java_lang_SecurityManager)))
169 if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
172 if (!(class_java_lang_Thread =
173 load_class_bootstrap(utf_new_char("java/lang/Thread"))))
176 #if defined(ENABLE_JAVASE)
177 if (!(class_java_lang_ThreadGroup =
178 load_class_bootstrap(utf_java_lang_ThreadGroup)))
182 #if defined(WITH_CLASSPATH_GNU)
183 if (!(class_java_lang_VMSystem =
184 load_class_bootstrap(utf_new_char("java/lang/VMSystem"))))
188 if (!(class_java_lang_VMThread =
189 load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
194 /* some classes which may be used more often */
196 #if defined(ENABLE_JAVASE)
197 if (!(class_java_lang_StackTraceElement =
198 load_class_bootstrap(utf_java_lang_StackTraceElement)))
201 if (!(class_java_lang_reflect_Constructor =
202 load_class_bootstrap(utf_java_lang_reflect_Constructor)))
205 if (!(class_java_lang_reflect_Field =
206 load_class_bootstrap(utf_java_lang_reflect_Field)))
209 if (!(class_java_lang_reflect_Method =
210 load_class_bootstrap(utf_java_lang_reflect_Method)))
213 if (!(class_java_security_PrivilegedAction =
214 load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
217 if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
220 if (!(arrayclass_java_lang_Object =
221 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
229 /* loader_load_all_classes *****************************************************
231 Loads all classes specified in the BOOTCLASSPATH.
233 *******************************************************************************/
235 void loader_load_all_classes(void)
237 list_classpath_entry *lce;
238 #if defined(ENABLE_ZLIB)
241 hashtable_zipfile_entry *htzfe;
245 for (lce = list_first(list_classpath_entries); lce != NULL;
246 lce = list_next(list_classpath_entries, lce)) {
247 #if defined(ENABLE_ZLIB)
248 if (lce->type == CLASSPATH_ARCHIVE) {
249 /* get the classes hashtable */
253 for (slot = 0; slot < ht->size; slot++) {
254 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
256 for (; htzfe; htzfe = htzfe->hashlink) {
259 /* skip all entries in META-INF and .properties,
262 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
263 strstr(u->text, ".properties") ||
264 strstr(u->text, ".png"))
267 /* load class from bootstrap classloader */
269 if (!load_class_bootstrap(u)) {
270 fprintf(stderr, "Error loading: ");
271 utf_fprint_printable_ascii_classname(stderr, u);
272 fprintf(stderr, "\n");
275 /* print out exception and cause */
277 exceptions_print_current_exception();
285 #if defined(ENABLE_ZLIB)
292 /* loader_skip_attribute_body **************************************************
294 Skips an attribute the attribute_name_index has already been read.
297 u2 attribute_name_index;
299 u1 info[attribute_length];
302 *******************************************************************************/
304 bool loader_skip_attribute_body(classbuffer *cb)
308 if (!suck_check_classbuffer_size(cb, 4))
311 attribute_length = suck_u4(cb);
313 if (!suck_check_classbuffer_size(cb, attribute_length))
316 suck_skip_nbytes(cb, attribute_length);
322 /* load_constantpool ***********************************************************
324 Loads the constantpool of a class, the entries are transformed into
325 a simpler format by resolving references (a detailed overview of
326 the compact structures can be found in global.h).
328 *******************************************************************************/
330 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
333 /* The following structures are used to save information which cannot be
334 processed during the first pass. After the complete constantpool has
335 been traversed the references can be resolved.
336 (only in specific order) */
338 /* CONSTANT_Class entries */
339 typedef struct forward_class {
340 struct forward_class *next;
345 /* CONSTANT_String */
346 typedef struct forward_string {
347 struct forward_string *next;
352 /* CONSTANT_NameAndType */
353 typedef struct forward_nameandtype {
354 struct forward_nameandtype *next;
358 } forward_nameandtype;
360 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
361 typedef struct forward_fieldmethint {
362 struct forward_fieldmethint *next;
366 u2 nameandtype_index;
367 } forward_fieldmethint;
373 forward_class *forward_classes = NULL;
374 forward_string *forward_strings = NULL;
375 forward_nameandtype *forward_nameandtypes = NULL;
376 forward_fieldmethint *forward_fieldmethints = NULL;
380 forward_nameandtype *nfn;
381 forward_fieldmethint *nff;
389 /* number of entries in the constant_pool table plus one */
390 if (!suck_check_classbuffer_size(cb, 2))
393 cpcount = c->cpcount = suck_u2(cb);
395 /* allocate memory */
396 cptags = c->cptags = MNEW(u1, cpcount);
397 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
400 exceptions_throw_classformaterror(c, "Illegal constant pool size");
404 #if defined(ENABLE_STATISTICS)
406 count_const_pool_len += (sizeof(u1) + sizeof(voidptr)) * cpcount;
409 /* initialize constantpool */
410 for (idx = 0; idx < cpcount; idx++) {
411 cptags[idx] = CONSTANT_UNUSED;
416 /******* first pass *******/
417 /* entries which cannot be resolved now are written into
418 temporary structures and traversed again later */
421 while (idx < cpcount) {
424 /* get constant type */
425 if (!suck_check_classbuffer_size(cb, 1))
432 nfc = DNEW(forward_class);
434 nfc->next = forward_classes;
435 forward_classes = nfc;
437 nfc->thisindex = idx;
438 /* reference to CONSTANT_NameAndType */
439 if (!suck_check_classbuffer_size(cb, 2))
442 nfc->name_index = suck_u2(cb);
447 case CONSTANT_String:
448 nfs = DNEW(forward_string);
450 nfs->next = forward_strings;
451 forward_strings = nfs;
453 nfs->thisindex = idx;
455 /* reference to CONSTANT_Utf8_info with string characters */
456 if (!suck_check_classbuffer_size(cb, 2))
459 nfs->string_index = suck_u2(cb);
464 case CONSTANT_NameAndType:
465 nfn = DNEW(forward_nameandtype);
467 nfn->next = forward_nameandtypes;
468 forward_nameandtypes = nfn;
470 nfn->thisindex = idx;
472 if (!suck_check_classbuffer_size(cb, 2 + 2))
475 /* reference to CONSTANT_Utf8_info containing simple name */
476 nfn->name_index = suck_u2(cb);
478 /* reference to CONSTANT_Utf8_info containing field or method
480 nfn->sig_index = suck_u2(cb);
485 case CONSTANT_Fieldref:
486 case CONSTANT_Methodref:
487 case CONSTANT_InterfaceMethodref:
488 nff = DNEW(forward_fieldmethint);
490 nff->next = forward_fieldmethints;
491 forward_fieldmethints = nff;
493 nff->thisindex = idx;
497 if (!suck_check_classbuffer_size(cb, 2 + 2))
500 /* class or interface type that contains the declaration of the
502 nff->class_index = suck_u2(cb);
504 /* name and descriptor of the field or method */
505 nff->nameandtype_index = suck_u2(cb);
510 case CONSTANT_Integer: {
511 constant_integer *ci = NEW(constant_integer);
513 #if defined(ENABLE_STATISTICS)
515 count_const_pool_len += sizeof(constant_integer);
518 if (!suck_check_classbuffer_size(cb, 4))
521 ci->value = suck_s4(cb);
522 cptags[idx] = CONSTANT_Integer;
529 case CONSTANT_Float: {
530 constant_float *cf = NEW(constant_float);
532 #if defined(ENABLE_STATISTICS)
534 count_const_pool_len += sizeof(constant_float);
537 if (!suck_check_classbuffer_size(cb, 4))
540 cf->value = suck_float(cb);
541 cptags[idx] = CONSTANT_Float;
548 case CONSTANT_Long: {
549 constant_long *cl = NEW(constant_long);
551 #if defined(ENABLE_STATISTICS)
553 count_const_pool_len += sizeof(constant_long);
556 if (!suck_check_classbuffer_size(cb, 8))
559 cl->value = suck_s8(cb);
560 cptags[idx] = CONSTANT_Long;
564 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
570 case CONSTANT_Double: {
571 constant_double *cd = NEW(constant_double);
573 #if defined(ENABLE_STATISTICS)
575 count_const_pool_len += sizeof(constant_double);
578 if (!suck_check_classbuffer_size(cb, 8))
581 cd->value = suck_double(cb);
582 cptags[idx] = CONSTANT_Double;
586 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
592 case CONSTANT_Utf8: {
595 /* number of bytes in the bytes array (not string-length) */
596 if (!suck_check_classbuffer_size(cb, 2))
599 length = suck_u2(cb);
600 cptags[idx] = CONSTANT_Utf8;
602 /* validate the string */
603 if (!suck_check_classbuffer_size(cb, length))
606 #ifdef ENABLE_VERIFIER
608 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
610 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
613 #endif /* ENABLE_VERIFIER */
614 /* insert utf-string into the utf-symboltable */
615 cpinfos[idx] = utf_new((char *) cb->pos, length);
617 /* skip bytes of the string (buffer size check above) */
618 suck_skip_nbytes(cb, length);
624 exceptions_throw_classformaterror(c, "Illegal constant pool type");
630 /* resolve entries in temporary structures */
632 while (forward_classes) {
634 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
638 #ifdef ENABLE_VERIFIER
639 if (opt_verify && !is_valid_name_utf(name)) {
640 exceptions_throw_classformaterror(c, "Class reference with invalid name");
643 #endif /* ENABLE_VERIFIER */
645 /* add all class references to the descriptor_pool */
647 if (!descriptor_pool_add_class(descpool, name))
650 cptags[forward_classes->thisindex] = CONSTANT_Class;
655 if (!(tc = load_class_bootstrap(name)))
658 /* link the class later, because we cannot link the class currently
660 list_add_first(&unlinkedclasses, tc);
663 /* the classref is created later */
664 cpinfos[forward_classes->thisindex] = name;
666 nfc = forward_classes;
667 forward_classes = forward_classes->next;
670 while (forward_strings) {
672 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
676 /* resolve utf-string */
677 cptags[forward_strings->thisindex] = CONSTANT_String;
678 cpinfos[forward_strings->thisindex] = text;
680 nfs = forward_strings;
681 forward_strings = forward_strings->next;
684 while (forward_nameandtypes) {
685 constant_nameandtype *cn = NEW(constant_nameandtype);
687 #if defined(ENABLE_STATISTICS)
689 count_const_pool_len += sizeof(constant_nameandtype);
692 /* resolve simple name and descriptor */
693 cn->name = class_getconstant(c,
694 forward_nameandtypes->name_index,
699 cn->descriptor = class_getconstant(c,
700 forward_nameandtypes->sig_index,
705 #ifdef ENABLE_VERIFIER
708 if (!is_valid_name_utf(cn->name)) {
709 exceptions_throw_classformaterror(c,
710 "Illegal Field name \"%s\"",
716 /* disallow referencing <clinit> among others */
717 if (cn->name->text[0] == '<' && cn->name != utf_init) {
718 exceptions_throw_classformaterror(c, "Illegal reference to special method");
722 #endif /* ENABLE_VERIFIER */
724 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
725 cpinfos[forward_nameandtypes->thisindex] = cn;
727 nfn = forward_nameandtypes;
728 forward_nameandtypes = forward_nameandtypes->next;
731 while (forward_fieldmethints) {
732 constant_nameandtype *nat;
733 constant_FMIref *fmi = NEW(constant_FMIref);
735 #if defined(ENABLE_STATISTICS)
737 count_const_pool_len += sizeof(constant_FMIref);
739 /* resolve simple name and descriptor */
741 nat = class_getconstant(c,
742 forward_fieldmethints->nameandtype_index,
743 CONSTANT_NameAndType);
747 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
749 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
752 /* the classref is created later */
754 fmi->p.index = forward_fieldmethints->class_index;
755 fmi->name = nat->name;
756 fmi->descriptor = nat->descriptor;
758 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
759 cpinfos[forward_fieldmethints->thisindex] = fmi;
761 nff = forward_fieldmethints;
762 forward_fieldmethints = forward_fieldmethints->next;
765 /* everything was ok */
771 /* loader_load_attribute_signature *********************************************
773 Signature_attribute {
774 u2 attribute_name_index;
779 *******************************************************************************/
781 #if defined(ENABLE_JAVASE)
782 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
792 /* check remaining bytecode */
794 if (!suck_check_classbuffer_size(cb, 4 + 2))
797 /* check attribute length */
799 attribute_length = suck_u4(cb);
801 if (attribute_length != 2) {
802 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
806 if (*signature != NULL) {
807 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
813 signature_index = suck_u2(cb);
815 if (!(*signature = class_getconstant(c, signature_index, CONSTANT_Utf8)))
820 #endif /* defined(ENABLE_JAVASE) */
823 /* load_field ******************************************************************
825 Load everything about a class field from the class file and fill a
826 'fieldinfo' structure. For static fields, space in the data segment
829 *******************************************************************************/
831 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
833 static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
838 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
843 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
846 f->flags = suck_u2(cb);
848 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
853 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
857 f->parseddesc = NULL;
859 if (!descriptor_pool_add(descpool, u, NULL))
862 /* descriptor_pool_add accepts method descriptors, so we have to check */
863 /* against them here before the call of descriptor_to_basic_type below. */
864 if (u->text[0] == '(') {
865 exceptions_throw_classformaterror(c, "Method descriptor used for field");
869 #ifdef ENABLE_VERIFIER
872 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<') {
873 exceptions_throw_classformaterror(c,
874 "Illegal Field name \"%s\"",
879 /* check flag consistency */
880 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
882 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
883 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
884 exceptions_throw_classformaterror(c,
885 "Illegal field modifiers: 0x%X",
890 if (c->flags & ACC_INTERFACE) {
891 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
892 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
893 f->flags & ACC_TRANSIENT) {
894 exceptions_throw_classformaterror(c,
895 "Illegal field modifiers: 0x%X",
901 #endif /* ENABLE_VERIFIER */
903 f->type = jtype = descriptor_to_basic_type(f->descriptor); /* data type */
904 f->offset = 0; /* offset from start of object */
922 if (!(f->flags & ACC_STATIC))
923 c->flags |= ACC_CLASS_HAS_POINTERS;
936 /* read attributes */
937 if (!suck_check_classbuffer_size(cb, 2))
940 attrnum = suck_u2(cb);
941 for (i = 0; i < attrnum; i++) {
942 if (!suck_check_classbuffer_size(cb, 2))
945 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
948 if (u == utf_ConstantValue) {
949 if (!suck_check_classbuffer_size(cb, 4 + 2))
952 /* check attribute length */
954 if (suck_u4(cb) != 2) {
955 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
959 /* constant value attribute */
961 if (pindex != field_load_NOVALUE) {
962 exceptions_throw_classformaterror(c, "Multiple ConstantValue attributes");
966 /* index of value in constantpool */
968 pindex = suck_u2(cb);
970 /* initialize field with value from constantpool */
973 constant_integer *ci;
975 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
978 f->value.i = ci->value;
985 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
988 f->value.l = cl->value;
995 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
998 f->value.f = cf->value;
1003 constant_double *cd;
1005 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
1008 f->value.d = cd->value;
1013 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
1016 /* create javastring from compressed utf8-string */
1017 f->value.a = literalstring_new(u);
1021 log_text("Invalid Constant - Type");
1024 #if defined(ENABLE_JAVASE)
1025 else if (u == utf_Signature) {
1028 if (!loader_load_attribute_signature(cb, &(f->signature)))
1033 /* unknown attribute */
1035 if (!loader_skip_attribute_body(cb))
1040 /* everything was ok */
1046 /* loader_load_method **********************************************************
1048 Loads a method from the class file and fills an existing
1049 'methodinfo' structure. For native methods, the function pointer
1050 field is set to the real function pointer, for JavaVM methods a
1051 pointer to the compiler is used preliminarily.
1056 u2 descriptor_index;
1057 u2 attributes_count;
1058 attribute_info attributes[attribute_count];
1062 u2 attribute_name_index;
1063 u4 attribute_length;
1064 u1 info[attribute_length];
1067 LineNumberTable_attribute {
1068 u2 attribute_name_index;
1069 u4 attribute_length;
1070 u2 line_number_table_length;
1074 } line_number_table[line_number_table_length];
1077 *******************************************************************************/
1079 static bool loader_load_method(classbuffer *cb, methodinfo *m,
1080 descriptor_pool *descpool)
1087 u2 descriptor_index;
1088 u2 attributes_count;
1089 u2 attribute_name_index;
1090 utf *attribute_name;
1091 u2 code_attributes_count;
1092 u2 code_attribute_name_index;
1093 utf *code_attribute_name;
1099 #if defined(ENABLE_STATISTICS)
1101 count_all_methods++;
1104 /* all fields of m have been zeroed in load_class_from_classbuffer */
1108 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
1113 m->flags = suck_u2(cb);
1117 name_index = suck_u2(cb);
1119 if (!(u = class_getconstant(c, name_index, CONSTANT_Utf8)))
1126 descriptor_index = suck_u2(cb);
1128 if (!(u = class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
1133 if (!descriptor_pool_add(descpool, u, &argcount))
1136 #ifdef ENABLE_VERIFIER
1138 if (!is_valid_name_utf(m->name)) {
1139 exceptions_throw_classformaterror(c, "Method with invalid name");
1143 if (m->name->text[0] == '<' &&
1144 m->name != utf_init && m->name != utf_clinit) {
1145 exceptions_throw_classformaterror(c, "Method with invalid special name");
1149 #endif /* ENABLE_VERIFIER */
1151 if (!(m->flags & ACC_STATIC))
1152 argcount++; /* count the 'this' argument */
1154 #ifdef ENABLE_VERIFIER
1156 if (argcount > 255) {
1157 exceptions_throw_classformaterror(c, "Too many arguments in signature");
1161 /* check flag consistency */
1162 if (m->name != utf_clinit) {
1163 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1165 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1166 exceptions_throw_classformaterror(c,
1167 "Illegal method modifiers: 0x%X",
1172 if (m->flags & ACC_ABSTRACT) {
1173 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1174 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1175 exceptions_throw_classformaterror(c,
1176 "Illegal method modifiers: 0x%X",
1182 if (c->flags & ACC_INTERFACE) {
1183 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1184 exceptions_throw_classformaterror(c,
1185 "Illegal method modifiers: 0x%X",
1191 if (m->name == utf_init) {
1192 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1193 ACC_NATIVE | ACC_ABSTRACT)) {
1194 exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
1200 #endif /* ENABLE_VERIFIER */
1202 /* mark the method as monomorphic until further notice */
1204 m->flags |= ACC_METHOD_MONOMORPHIC;
1206 /* non-abstract methods have an implementation in this class */
1208 if (!(m->flags & ACC_ABSTRACT))
1209 m->flags |= ACC_METHOD_IMPLEMENTED;
1211 if (!suck_check_classbuffer_size(cb, 2))
1214 /* attributes count */
1216 attributes_count = suck_u2(cb);
1218 for (i = 0; i < attributes_count; i++) {
1219 if (!suck_check_classbuffer_size(cb, 2))
1222 /* attribute name index */
1224 attribute_name_index = suck_u2(cb);
1226 if (!(attribute_name = class_getconstant(c, attribute_name_index, CONSTANT_Utf8)))
1229 if (attribute_name == utf_Code) {
1231 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1232 exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
1237 exceptions_throw_classformaterror(c, "Multiple Code attributes");
1241 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1245 m->maxstack = suck_u2(cb);
1246 m->maxlocals = suck_u2(cb);
1248 if (m->maxlocals < argcount) {
1249 exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
1253 if (!suck_check_classbuffer_size(cb, 4))
1256 m->jcodelength = suck_u4(cb);
1258 if (m->jcodelength == 0) {
1259 exceptions_throw_classformaterror(c, "Code of a method has length 0");
1263 if (m->jcodelength > 65535) {
1264 exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
1268 if (!suck_check_classbuffer_size(cb, m->jcodelength))
1271 m->jcode = MNEW(u1, m->jcodelength);
1272 suck_nbytes(m->jcode, cb, m->jcodelength);
1274 if (!suck_check_classbuffer_size(cb, 2))
1277 m->rawexceptiontablelength = suck_u2(cb);
1278 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->rawexceptiontablelength))
1281 m->rawexceptiontable = MNEW(raw_exception_entry, m->rawexceptiontablelength);
1283 #if defined(ENABLE_STATISTICS)
1285 count_vmcode_len += m->jcodelength + 18;
1286 count_extable_len +=
1287 m->rawexceptiontablelength * sizeof(raw_exception_entry);
1291 for (j = 0; j < m->rawexceptiontablelength; j++) {
1293 m->rawexceptiontable[j].startpc = suck_u2(cb);
1294 m->rawexceptiontable[j].endpc = suck_u2(cb);
1295 m->rawexceptiontable[j].handlerpc = suck_u2(cb);
1299 m->rawexceptiontable[j].catchtype.any = NULL;
1302 /* the classref is created later */
1303 if (!(m->rawexceptiontable[j].catchtype.any =
1304 (utf*)class_getconstant(c, idx, CONSTANT_Class)))
1309 if (!suck_check_classbuffer_size(cb, 2))
1312 /* code attributes count */
1314 code_attributes_count = suck_u2(cb);
1316 for (k = 0; k < code_attributes_count; k++) {
1317 if (!suck_check_classbuffer_size(cb, 2))
1320 /* code attribute name index */
1322 code_attribute_name_index = suck_u2(cb);
1324 if (!(code_attribute_name = class_getconstant(c, code_attribute_name_index, CONSTANT_Utf8)))
1327 /* check which code attribute */
1329 if (code_attribute_name == utf_LineNumberTable) {
1330 /* LineNumberTable */
1331 if (!suck_check_classbuffer_size(cb, 4 + 2))
1334 /* attribute length */
1338 /* line number table length */
1340 m->linenumbercount = suck_u2(cb);
1342 if (!suck_check_classbuffer_size(cb,
1343 (2 + 2) * m->linenumbercount))
1346 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1348 #if defined(ENABLE_STATISTICS)
1350 size_lineinfo += sizeof(lineinfo) * m->linenumbercount;
1353 for (l = 0; l < m->linenumbercount; l++) {
1354 m->linenumbers[l].start_pc = suck_u2(cb);
1355 m->linenumbers[l].line_number = suck_u2(cb);
1358 #if defined(ENABLE_JAVASE)
1359 else if (code_attribute_name == utf_StackMapTable) {
1362 if (!stackmap_load_attribute_stackmaptable(cb, m))
1367 /* unknown code attribute */
1369 if (!loader_skip_attribute_body(cb))
1374 else if (attribute_name == utf_Exceptions) {
1377 if (m->thrownexceptions != NULL) {
1378 exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
1382 if (!suck_check_classbuffer_size(cb, 4 + 2))
1385 /* attribute length */
1389 m->thrownexceptionscount = suck_u2(cb);
1391 if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1394 m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
1396 for (j = 0; j < m->thrownexceptionscount; j++) {
1397 /* the classref is created later */
1398 if (!((m->thrownexceptions)[j].any =
1399 (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1403 #if defined(ENABLE_JAVASE)
1404 else if (attribute_name == utf_Signature) {
1407 if (!loader_load_attribute_signature(cb, &(m->signature)))
1412 /* unknown attribute */
1414 if (!loader_skip_attribute_body(cb))
1419 if ((m->jcode == NULL) && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1420 exceptions_throw_classformaterror(c, "Missing Code attribute");
1424 /* everything was ok */
1430 /* load_class_from_sysloader ***************************************************
1432 Load the class with the given name using the system class loader
1435 name.............the classname
1438 the loaded class, or
1439 NULL if an exception has been thrown
1441 *******************************************************************************/
1443 classinfo *load_class_from_sysloader(utf *name)
1446 java_objectheader *cl;
1449 assert(class_java_lang_Object);
1450 assert(class_java_lang_ClassLoader);
1451 assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
1453 m = class_resolveclassmethod(class_java_lang_ClassLoader,
1454 utf_getSystemClassLoader,
1455 utf_void__java_lang_ClassLoader,
1456 class_java_lang_Object,
1462 cl = vm_call_method(m, NULL);
1467 c = load_class_from_classloader(name, cl);
1473 /* load_class_from_classloader *************************************************
1475 Load the class with the given name using the given user-defined class loader.
1478 name.............the classname
1479 cl...............user-defined class loader
1482 the loaded class, or
1483 NULL if an exception has been thrown
1485 *******************************************************************************/
1487 classinfo *load_class_from_classloader(utf *name, java_objectheader *cl)
1489 java_objectheader *o;
1492 java_objectheader *string;
1493 #if defined(ENABLE_RT_TIMING)
1494 struct timespec time_start, time_lookup, time_prepare, time_java,
1498 RT_TIMING_GET_TIME(time_start);
1502 /* lookup if this class has already been loaded */
1504 c = classcache_lookup(cl, name);
1506 RT_TIMING_GET_TIME(time_lookup);
1507 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1512 /* if other class loader than bootstrap, call it */
1520 namelen = name->blength;
1522 /* handle array classes */
1523 if (text[0] == '[') {
1529 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1530 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1531 exceptions_throw_noclassdeffounderror(name);
1535 u = utf_new(text + 2, namelen - 3);
1537 if (!(comp = load_class_from_classloader(u, cl)))
1540 /* create the array class */
1542 c = class_array_of(comp, false);
1544 tmpc = classcache_store(cl, c, true);
1547 /* exception, free the loaded class */
1548 c->state &= ~CLASS_LOADING;
1555 /* load the component class */
1557 u = utf_new(text + 1, namelen - 1);
1559 if (!(comp = load_class_from_classloader(u, cl)))
1562 /* create the array class */
1564 c = class_array_of(comp, false);
1566 tmpc = classcache_store(cl, c, true);
1569 /* exception, free the loaded class */
1570 c->state &= ~CLASS_LOADING;
1577 /* primitive array classes are loaded by the bootstrap loader */
1579 c = load_class_bootstrap(name);
1585 assert(class_java_lang_Object);
1587 lc = class_resolveclassmethod(cl->vftbl->class,
1589 utf_java_lang_String__java_lang_Class,
1590 class_java_lang_Object,
1594 return false; /* exception */
1596 /* move return value into `o' and cast it afterwards to a classinfo* */
1598 string = javastring_new_slash_to_dot(name);
1600 RT_TIMING_GET_TIME(time_prepare);
1602 o = vm_call_method(lc, cl, string);
1604 RT_TIMING_GET_TIME(time_java);
1606 c = (classinfo *) o;
1609 /* Store this class in the loaded class cache. If another
1610 class with the same (initloader,name) pair has been
1611 stored earlier it will be returned by classcache_store
1612 In this case classcache_store may not free the class
1613 because it has already been exposed to Java code which
1614 may have kept references to that class. */
1616 tmpc = classcache_store(cl, c, false);
1619 /* exception, free the loaded class */
1620 c->state &= ~CLASS_LOADING;
1627 /* loadClass has thrown an exception. We must convert
1628 ClassNotFoundException into
1629 NoClassDefFoundException. */
1631 /* XXX Maybe we should have a flag that avoids this
1632 conversion for calling load_class_from_classloader from
1633 Class.forName. Currently we do a double conversion in
1636 classnotfoundexception_to_noclassdeffounderror();
1639 RT_TIMING_GET_TIME(time_cache);
1641 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1642 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1643 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1645 /* SUN compatible -verbose:class output */
1647 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1649 utf_display_printable_ascii_classname(name);
1653 #if defined(ENABLE_JVMTI)
1654 /* fire Class Load JVMTI event */
1655 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1662 c = load_class_bootstrap(name);
1668 /* load_class_bootstrap ********************************************************
1670 Load the class with the given name using the bootstrap class loader.
1673 name.............the classname
1676 loaded classinfo, or
1677 NULL if an exception has been thrown
1680 load_class_bootstrap is synchronized. It can be treated as an
1683 *******************************************************************************/
1685 classinfo *load_class_bootstrap(utf *name)
1690 #if defined(ENABLE_RT_TIMING)
1691 struct timespec time_start, time_lookup, time_array, time_suck,
1692 time_load, time_cache;
1695 RT_TIMING_GET_TIME(time_start);
1701 /* lookup if this class has already been loaded */
1703 if ((r = classcache_lookup(NULL, name))) {
1705 RT_TIMING_GET_TIME(time_lookup);
1706 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1711 RT_TIMING_GET_TIME(time_lookup);
1712 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1714 /* create the classinfo */
1716 c = class_create_classinfo(name);
1718 /* handle array classes */
1720 if (name->text[0] == '[') {
1721 c = load_newly_created_array(c, NULL);
1724 assert(c->state & CLASS_LOADED);
1726 RT_TIMING_GET_TIME(time_array);
1727 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1732 #if defined(ENABLE_STATISTICS)
1735 if (opt_getcompilingtime)
1736 compilingtime_stop();
1738 if (opt_getloadingtime)
1739 loadingtime_start();
1742 /* load classdata, throw exception on error */
1747 /* this normally means, the classpath was not set properly */
1749 if (name == utf_java_lang_Object)
1750 vm_abort("java/lang/NoClassDefFoundError: java/lang/Object");
1752 exceptions_throw_noclassdeffounderror(name);
1757 RT_TIMING_GET_TIME(time_suck);
1759 /* load the class from the buffer */
1761 r = load_class_from_classbuffer(cb);
1763 RT_TIMING_GET_TIME(time_load);
1766 /* the class could not be loaded, free the classinfo struct */
1771 /* Store this class in the loaded class cache this step also
1772 checks the loading constraints. If the class has been loaded
1773 before, the earlier loaded class is returned. */
1775 classinfo *res = classcache_store(NULL, c, true);
1785 RT_TIMING_GET_TIME(time_cache);
1787 /* SUN compatible -verbose:class output */
1789 if (opt_verboseclass && r) {
1791 utf_display_printable_ascii_classname(name);
1792 printf(" from %s]\n", cb->path);
1799 #if defined(ENABLE_STATISTICS)
1802 if (opt_getloadingtime)
1805 if (opt_getcompilingtime)
1806 compilingtime_start();
1809 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1810 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1811 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1812 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1818 /* load_class_from_classbuffer *************************************************
1820 Loads everything interesting about a class from the class file. The
1821 'classinfo' structure must have been allocated previously.
1823 The super class and the interfaces implemented by this class need
1824 not be loaded. The link is set later by the function 'class_link'.
1826 The loaded class is removed from the list 'unloadedclasses' and
1827 added to the list 'unlinkedclasses'.
1830 This function is NOT synchronized!
1832 *******************************************************************************/
1834 classinfo *load_class_from_classbuffer(classbuffer *cb)
1842 descriptor_pool *descpool;
1843 #if defined(ENABLE_STATISTICS)
1847 #if defined(ENABLE_RT_TIMING)
1848 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1849 time_setup, time_fields, time_methods, time_classrefs,
1850 time_descs, time_setrefs, time_parsefds, time_parsemds,
1851 time_parsecpool, time_verify, time_attrs;
1854 RT_TIMING_GET_TIME(time_start);
1856 /* get the classbuffer's class */
1860 /* the class is already loaded */
1862 if (c->state & CLASS_LOADED)
1865 #if defined(ENABLE_STATISTICS)
1867 count_class_loads++;
1870 #if !defined(NDEBUG)
1871 /* output for debugging purposes */
1874 log_message_class("Loading class: ", c);
1877 /* mark start of dump memory area */
1879 dumpsize = dump_size();
1881 /* class is currently loading */
1883 c->state |= CLASS_LOADING;
1885 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1886 goto return_exception;
1888 /* check signature */
1890 if (suck_u4(cb) != MAGIC) {
1891 exceptions_throw_classformaterror(c, "Bad magic number");
1893 goto return_exception;
1901 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1902 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1903 goto return_exception;
1906 RT_TIMING_GET_TIME(time_checks);
1908 /* create a new descriptor pool */
1910 descpool = descriptor_pool_new(c);
1912 RT_TIMING_GET_TIME(time_ndpool);
1914 /* load the constant pool */
1916 if (!load_constantpool(cb, descpool))
1917 goto return_exception;
1919 RT_TIMING_GET_TIME(time_cpool);
1923 if (!suck_check_classbuffer_size(cb, 2))
1924 goto return_exception;
1926 /* We OR the flags here, as we set already some flags in
1927 class_create_classinfo. */
1929 c->flags |= suck_u2(cb);
1931 /* check ACC flags consistency */
1933 if (c->flags & ACC_INTERFACE) {
1934 if (!(c->flags & ACC_ABSTRACT)) {
1935 /* We work around this because interfaces in JDK 1.1 are
1936 * not declared abstract. */
1938 c->flags |= ACC_ABSTRACT;
1941 if (c->flags & ACC_FINAL) {
1942 exceptions_throw_classformaterror(c,
1943 "Illegal class modifiers: 0x%X",
1945 goto return_exception;
1948 if (c->flags & ACC_SUPER) {
1949 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1953 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1954 exceptions_throw_classformaterror(c,
1955 "Illegal class modifiers: 0x%X",
1957 goto return_exception;
1960 if (!suck_check_classbuffer_size(cb, 2 + 2))
1961 goto return_exception;
1966 if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1967 goto return_exception;
1969 if (c->name == utf_not_named_yet) {
1970 /* we finally have a name for this class */
1972 class_set_packagename(c);
1974 } else if (name != c->name) {
1975 /* TODO: i want to be an exceptions-function! */
1979 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
1980 utf_bytes(name) + strlen(")") + strlen("0");
1982 msg = MNEW(char, msglen);
1984 utf_copy_classname(msg, c->name);
1985 strcat(msg, " (wrong name: ");
1986 utf_cat_classname(msg, name);
1990 /* *exceptionptr = */
1991 /* new_exception_message("java/lang/NoClassDefFoundError", msg); */
1992 exceptions_throw_noclassdeffounderror(c->name);
1994 MFREE(msg, char, msglen);
1996 goto return_exception;
1999 /* retrieve superclass */
2001 c->super.any = NULL;
2002 if ((i = suck_u2(cb))) {
2003 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
2004 goto return_exception;
2006 /* java.lang.Object may not have a super class. */
2008 if (c->name == utf_java_lang_Object) {
2009 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
2010 goto return_exception;
2013 /* Interfaces must have java.lang.Object as super class. */
2015 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
2016 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
2017 goto return_exception;
2023 /* This is only allowed for java.lang.Object. */
2025 if (c->name != utf_java_lang_Object) {
2026 exceptions_throw_classformaterror(c, "Bad superclass index");
2027 goto return_exception;
2031 /* retrieve interfaces */
2033 if (!suck_check_classbuffer_size(cb, 2))
2034 goto return_exception;
2036 c->interfacescount = suck_u2(cb);
2038 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
2039 goto return_exception;
2041 c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
2042 for (i = 0; i < c->interfacescount; i++) {
2043 /* the classrefs are created later */
2044 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2045 goto return_exception;
2048 RT_TIMING_GET_TIME(time_setup);
2051 if (!suck_check_classbuffer_size(cb, 2))
2052 goto return_exception;
2054 c->fieldscount = suck_u2(cb);
2055 #if defined(ENABLE_GC_CACAO)
2056 c->fields = MNEW(fieldinfo, c->fieldscount);
2057 MZERO(c->fields, fieldinfo, c->fieldscount);
2059 c->fields = GCNEW_UNCOLLECTABLE(fieldinfo, c->fieldscount);
2062 for (i = 0; i < c->fieldscount; i++) {
2063 if (!load_field(cb, &(c->fields[i]),descpool))
2064 goto return_exception;
2067 RT_TIMING_GET_TIME(time_fields);
2070 if (!suck_check_classbuffer_size(cb, 2))
2071 goto return_exception;
2073 c->methodscount = suck_u2(cb);
2074 c->methods = MNEW(methodinfo, c->methodscount);
2076 MZERO(c->methods, methodinfo, c->methodscount);
2078 for (i = 0; i < c->methodscount; i++) {
2079 if (!loader_load_method(cb, &(c->methods[i]), descpool))
2080 goto return_exception;
2083 RT_TIMING_GET_TIME(time_methods);
2085 /* create the class reference table */
2088 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
2090 RT_TIMING_GET_TIME(time_classrefs);
2092 /* allocate space for the parsed descriptors */
2094 descriptor_pool_alloc_parsed_descriptors(descpool);
2096 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
2098 #if defined(ENABLE_STATISTICS)
2100 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
2101 count_classref_len += classrefsize;
2102 count_parsed_desc_len += descsize;
2106 RT_TIMING_GET_TIME(time_descs);
2108 /* put the classrefs in the constant pool */
2109 for (i = 0; i < c->cpcount; i++) {
2110 if (c->cptags[i] == CONSTANT_Class) {
2111 utf *name = (utf *) c->cpinfos[i];
2112 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
2116 /* set the super class reference */
2119 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
2121 goto return_exception;
2124 /* set the super interfaces references */
2126 for (i = 0; i < c->interfacescount; i++) {
2127 c->interfaces[i].ref =
2128 descriptor_pool_lookup_classref(descpool,
2129 (utf *) c->interfaces[i].any);
2130 if (!c->interfaces[i].ref)
2131 goto return_exception;
2134 RT_TIMING_GET_TIME(time_setrefs);
2136 /* parse field descriptors */
2138 for (i = 0; i < c->fieldscount; i++) {
2139 c->fields[i].parseddesc =
2140 descriptor_pool_parse_field_descriptor(descpool,
2141 c->fields[i].descriptor);
2142 if (!c->fields[i].parseddesc)
2143 goto return_exception;
2146 RT_TIMING_GET_TIME(time_parsefds);
2148 /* parse method descriptors */
2150 for (i = 0; i < c->methodscount; i++) {
2151 methodinfo *m = &c->methods[i];
2153 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
2154 m->flags, class_get_self_classref(m->class));
2156 goto return_exception;
2158 for (j = 0; j < m->rawexceptiontablelength; j++) {
2159 if (!m->rawexceptiontable[j].catchtype.any)
2161 if ((m->rawexceptiontable[j].catchtype.ref =
2162 descriptor_pool_lookup_classref(descpool,
2163 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
2164 goto return_exception;
2167 for (j = 0; j < m->thrownexceptionscount; j++) {
2168 if (!m->thrownexceptions[j].any)
2170 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
2171 (utf *) m->thrownexceptions[j].any)) == NULL)
2172 goto return_exception;
2176 RT_TIMING_GET_TIME(time_parsemds);
2178 /* parse the loaded descriptors */
2180 for (i = 0; i < c->cpcount; i++) {
2181 constant_FMIref *fmi;
2184 switch (c->cptags[i]) {
2185 case CONSTANT_Fieldref:
2186 fmi = (constant_FMIref *) c->cpinfos[i];
2187 fmi->parseddesc.fd =
2188 descriptor_pool_parse_field_descriptor(descpool,
2190 if (!fmi->parseddesc.fd)
2191 goto return_exception;
2192 index = fmi->p.index;
2194 (constant_classref *) class_getconstant(c, index,
2196 if (!fmi->p.classref)
2197 goto return_exception;
2199 case CONSTANT_Methodref:
2200 case CONSTANT_InterfaceMethodref:
2201 fmi = (constant_FMIref *) c->cpinfos[i];
2202 index = fmi->p.index;
2204 (constant_classref *) class_getconstant(c, index,
2206 if (!fmi->p.classref)
2207 goto return_exception;
2208 fmi->parseddesc.md =
2209 descriptor_pool_parse_method_descriptor(descpool,
2213 if (!fmi->parseddesc.md)
2214 goto return_exception;
2219 RT_TIMING_GET_TIME(time_parsecpool);
2221 #ifdef ENABLE_VERIFIER
2222 /* Check if all fields and methods can be uniquely
2223 * identified by (name,descriptor). */
2226 /* We use a hash table here to avoid making the
2227 * average case quadratic in # of methods, fields.
2229 static int shift = 0;
2231 u2 *next; /* for chaining colliding hash entries */
2237 /* Allocate hashtable */
2238 len = c->methodscount;
2239 if (len < c->fieldscount) len = c->fieldscount;
2241 hashtab = MNEW(u2,(hashlen + len));
2242 next = hashtab + hashlen;
2244 /* Determine bitshift (to get good hash values) */
2254 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2256 for (i = 0; i < c->fieldscount; ++i) {
2257 fieldinfo *fi = c->fields + i;
2259 /* It's ok if we lose bits here */
2260 index = ((((size_t) fi->name) +
2261 ((size_t) fi->descriptor)) >> shift) % hashlen;
2263 if ((old = hashtab[index])) {
2267 if (c->fields[old].name == fi->name &&
2268 c->fields[old].descriptor == fi->descriptor) {
2269 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
2270 goto return_exception;
2272 } while ((old = next[old]));
2274 hashtab[index] = i + 1;
2278 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2280 for (i = 0; i < c->methodscount; ++i) {
2281 methodinfo *mi = c->methods + i;
2283 /* It's ok if we lose bits here */
2284 index = ((((size_t) mi->name) +
2285 ((size_t) mi->descriptor)) >> shift) % hashlen;
2289 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2290 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2294 if ((old = hashtab[index])) {
2298 if (c->methods[old].name == mi->name &&
2299 c->methods[old].descriptor == mi->descriptor) {
2300 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
2301 goto return_exception;
2303 } while ((old = next[old]));
2305 hashtab[index] = i + 1;
2308 MFREE(hashtab, u2, (hashlen + len));
2310 #endif /* ENABLE_VERIFIER */
2312 RT_TIMING_GET_TIME(time_verify);
2314 #if defined(ENABLE_STATISTICS)
2316 size_classinfo += sizeof(classinfo*) * c->interfacescount;
2317 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
2318 size_methodinfo += sizeof(methodinfo) * c->methodscount;
2322 /* load attribute structures */
2324 if (!class_load_attributes(cb))
2325 goto return_exception;
2327 /* Pre Java 1.5 version don't check this. This implementation is like
2328 Java 1.5 do it: for class file version 45.3 we don't check it, older
2329 versions are checked.
2332 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
2333 /* check if all data has been read */
2334 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
2336 if (classdata_left > 0) {
2337 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
2338 goto return_exception;
2342 RT_TIMING_GET_TIME(time_attrs);
2344 /* release dump area */
2346 dump_release(dumpsize);
2348 /* revert loading state and class is loaded */
2350 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2352 #if defined(ENABLE_JVMTI)
2353 /* fire Class Prepare JVMTI event */
2356 jvmti_ClassLoadPrepare(true, c);
2359 #if !defined(NDEBUG)
2361 log_message_class("Loading done class: ", c);
2364 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
2365 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
2366 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
2367 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
2368 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
2369 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
2370 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
2371 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
2372 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
2373 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
2374 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
2375 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
2376 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
2377 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
2378 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
2383 /* release dump area */
2385 dump_release(dumpsize);
2387 /* an exception has been thrown */
2393 /* load_newly_created_array ****************************************************
2395 Load a newly created array class.
2398 c....................the array class C has been loaded
2399 other classinfo......the array class was found in the class cache,
2401 NULL.................an exception has been thrown
2404 This is an internal function. Do not use it unless you know exactly
2407 Use one of the load_class_... functions for general array class loading.
2409 *******************************************************************************/
2411 classinfo *load_newly_created_array(classinfo *c, java_objectheader *loader)
2413 classinfo *comp = NULL;
2415 methoddesc *clonedesc;
2416 constant_classref *classrefs;
2421 text = c->name->text;
2422 namelen = c->name->blength;
2424 /* Check array class name */
2426 if ((namelen < 2) || (text[0] != '[')) {
2427 exceptions_throw_noclassdeffounderror(c->name);
2431 /* Check the element type */
2435 /* c is an array of arrays. We have to create the component class. */
2437 u = utf_new(text + 1, namelen - 1);
2438 if (!(comp = load_class_from_classloader(u, loader)))
2441 assert(comp->state & CLASS_LOADED);
2447 /* the array's flags are that of the component class */
2448 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2449 c->classloader = comp->classloader;
2453 /* c is an array of objects. */
2455 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2456 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2457 exceptions_throw_noclassdeffounderror(c->name);
2461 u = utf_new(text + 2, namelen - 3);
2463 if (!(comp = load_class_from_classloader(u, loader)))
2466 assert(comp->state & CLASS_LOADED);
2472 /* the array's flags are that of the component class */
2473 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2474 c->classloader = comp->classloader;
2478 /* c is an array of a primitive type */
2480 /* check for cases like `[II' */
2482 exceptions_throw_noclassdeffounderror(c->name);
2486 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2487 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2488 c->classloader = NULL;
2491 assert(class_java_lang_Object);
2492 #if defined(ENABLE_JAVASE)
2493 assert(class_java_lang_Cloneable);
2494 assert(class_java_io_Serializable);
2497 /* setup the array class */
2499 c->super.cls = class_java_lang_Object;
2501 #if defined(ENABLE_JAVASE)
2502 c->interfacescount = 2;
2503 c->interfaces = MNEW(classref_or_classinfo, 2);
2508 tc = class_java_lang_Cloneable;
2509 assert(tc->state & CLASS_LOADED);
2510 list_add_first(&unlinkedclasses, tc);
2511 c->interfaces[0].cls = tc;
2513 tc = class_java_io_Serializable;
2514 assert(tc->state & CLASS_LOADED);
2515 list_add_first(&unlinkedclasses, tc);
2516 c->interfaces[1].cls = tc;
2519 c->interfaces[0].cls = class_java_lang_Cloneable;
2520 c->interfaces[1].cls = class_java_io_Serializable;
2522 #elif defined(ENABLE_JAVAME_CLDC1_1)
2523 c->interfacescount = 0;
2524 c->interfaces = NULL;
2526 #error unknow Java configuration
2529 c->methodscount = 1;
2530 c->methods = MNEW(methodinfo, c->methodscount);
2531 MZERO(c->methods, methodinfo, c->methodscount);
2533 classrefs = MNEW(constant_classref, 2);
2534 CLASSREF_INIT(classrefs[0], c, c->name);
2535 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2537 /* create descriptor for clone method */
2538 /* we need one paramslot which is reserved for the 'this' parameter */
2539 clonedesc = NEW(methoddesc);
2540 clonedesc->returntype.type = TYPE_ADR;
2541 clonedesc->returntype.classref = classrefs + 1;
2542 clonedesc->returntype.arraydim = 0;
2543 /* initialize params to "empty", add real params below in
2544 descriptor_params_from_paramtypes */
2545 clonedesc->paramcount = 0;
2546 clonedesc->paramslots = 0;
2547 clonedesc->paramtypes[0].classref = classrefs + 0;
2548 clonedesc->params = NULL;
2550 /* create methodinfo */
2553 MSET(clone, 0, methodinfo, 1);
2555 /* ATTENTION: if you delete the ACC_NATIVE below, set
2556 clone->maxlocals=1 (interpreter related) */
2558 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2559 clone->name = utf_clone;
2560 clone->descriptor = utf_void__java_lang_Object;
2561 clone->parseddesc = clonedesc;
2564 /* parse the descriptor to get the register allocation */
2566 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2569 clone->code = codegen_createnativestub(BUILTIN_clone, clone);
2571 /* XXX: field: length? */
2573 /* array classes are not loaded from class files */
2575 c->state |= CLASS_LOADED;
2576 c->parseddescs = (u1 *) clonedesc;
2577 c->parseddescsize = sizeof(methodinfo);
2578 c->classrefs = classrefs;
2579 c->classrefcount = 1;
2581 /* insert class into the loaded class cache */
2582 /* XXX free classinfo if NULL returned? */
2584 return classcache_store(loader, c, true);
2588 /* loader_close ****************************************************************
2590 Frees all resources.
2592 *******************************************************************************/
2594 void loader_close(void)
2601 * These are local overrides for various environment variables in Emacs.
2602 * Please do not remove this and leave it at the end of the file, where
2603 * Emacs will automagically detect them.
2604 * ---------------------------------------------------------------------
2607 * indent-tabs-mode: t
2611 * vim:noexpandtab:sw=4:ts=4: