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 8227 2007-07-24 11:55:07Z twisti $
38 #include "mm/memory.h"
40 #include "threads/lock-common.h"
42 #include "toolbox/logging.h"
44 #include "vm/builtin.h"
45 #include "vm/exceptions.h"
46 #include "vm/global.h"
47 #include "vm/stringlocal.h"
50 #include "vm/jit_interface.h"
52 #if defined(ENABLE_JAVASE)
53 # include "vmcore/annotation.h"
54 # include "vmcore/stackmap.h"
57 #include "vmcore/classcache.h"
58 #include "vmcore/field.h"
59 #include "vmcore/linker.h"
60 #include "vmcore/loader.h"
61 #include "vmcore/options.h"
62 #include "vmcore/primitive.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(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 /* loader_load_method **********************************************************
824 Loads a method from the class file and fills an existing
825 'methodinfo' structure. For native methods, the function pointer
826 field is set to the real function pointer, for JavaVM methods a
827 pointer to the compiler is used preliminarily.
834 attribute_info attributes[attribute_count];
838 u2 attribute_name_index;
840 u1 info[attribute_length];
843 LineNumberTable_attribute {
844 u2 attribute_name_index;
846 u2 line_number_table_length;
850 } line_number_table[line_number_table_length];
853 *******************************************************************************/
855 static bool loader_load_method(classbuffer *cb, methodinfo *m,
856 descriptor_pool *descpool)
865 u2 attribute_name_index;
867 u2 code_attributes_count;
868 u2 code_attribute_name_index;
869 utf *code_attribute_name;
875 #if defined(ENABLE_THREADS)
876 lock_init_object_lock(&m->header);
879 #if defined(ENABLE_STATISTICS)
884 /* all fields of m have been zeroed in load_class_from_classbuffer */
888 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
893 m->flags = suck_u2(cb);
897 name_index = suck_u2(cb);
899 if (!(u = class_getconstant(c, name_index, CONSTANT_Utf8)))
906 descriptor_index = suck_u2(cb);
908 if (!(u = class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
913 if (!descriptor_pool_add(descpool, u, &argcount))
916 #ifdef ENABLE_VERIFIER
918 if (!is_valid_name_utf(m->name)) {
919 exceptions_throw_classformaterror(c, "Method with invalid name");
923 if (m->name->text[0] == '<' &&
924 m->name != utf_init && m->name != utf_clinit) {
925 exceptions_throw_classformaterror(c, "Method with invalid special name");
929 #endif /* ENABLE_VERIFIER */
931 if (!(m->flags & ACC_STATIC))
932 argcount++; /* count the 'this' argument */
934 #ifdef ENABLE_VERIFIER
936 if (argcount > 255) {
937 exceptions_throw_classformaterror(c, "Too many arguments in signature");
941 /* check flag consistency */
942 if (m->name != utf_clinit) {
943 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
945 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
946 exceptions_throw_classformaterror(c,
947 "Illegal method modifiers: 0x%X",
952 if (m->flags & ACC_ABSTRACT) {
953 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
954 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
955 exceptions_throw_classformaterror(c,
956 "Illegal method modifiers: 0x%X",
962 if (c->flags & ACC_INTERFACE) {
963 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
964 exceptions_throw_classformaterror(c,
965 "Illegal method modifiers: 0x%X",
971 if (m->name == utf_init) {
972 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
973 ACC_NATIVE | ACC_ABSTRACT)) {
974 exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
980 #endif /* ENABLE_VERIFIER */
982 /* mark the method as monomorphic until further notice */
984 m->flags |= ACC_METHOD_MONOMORPHIC;
986 /* non-abstract methods have an implementation in this class */
988 if (!(m->flags & ACC_ABSTRACT))
989 m->flags |= ACC_METHOD_IMPLEMENTED;
991 if (!suck_check_classbuffer_size(cb, 2))
994 /* attributes count */
996 attributes_count = suck_u2(cb);
998 for (i = 0; i < attributes_count; i++) {
999 if (!suck_check_classbuffer_size(cb, 2))
1002 /* attribute name index */
1004 attribute_name_index = suck_u2(cb);
1006 if (!(attribute_name = class_getconstant(c, attribute_name_index, CONSTANT_Utf8)))
1009 if (attribute_name == utf_Code) {
1011 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1012 exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
1017 exceptions_throw_classformaterror(c, "Multiple Code attributes");
1021 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1025 m->maxstack = suck_u2(cb);
1026 m->maxlocals = suck_u2(cb);
1028 if (m->maxlocals < argcount) {
1029 exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
1033 if (!suck_check_classbuffer_size(cb, 4))
1036 m->jcodelength = suck_u4(cb);
1038 if (m->jcodelength == 0) {
1039 exceptions_throw_classformaterror(c, "Code of a method has length 0");
1043 if (m->jcodelength > 65535) {
1044 exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
1048 if (!suck_check_classbuffer_size(cb, m->jcodelength))
1051 m->jcode = MNEW(u1, m->jcodelength);
1052 suck_nbytes(m->jcode, cb, m->jcodelength);
1054 if (!suck_check_classbuffer_size(cb, 2))
1057 m->rawexceptiontablelength = suck_u2(cb);
1058 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->rawexceptiontablelength))
1061 m->rawexceptiontable = MNEW(raw_exception_entry, m->rawexceptiontablelength);
1063 #if defined(ENABLE_STATISTICS)
1065 count_vmcode_len += m->jcodelength + 18;
1066 count_extable_len +=
1067 m->rawexceptiontablelength * sizeof(raw_exception_entry);
1071 for (j = 0; j < m->rawexceptiontablelength; j++) {
1073 m->rawexceptiontable[j].startpc = suck_u2(cb);
1074 m->rawexceptiontable[j].endpc = suck_u2(cb);
1075 m->rawexceptiontable[j].handlerpc = suck_u2(cb);
1079 m->rawexceptiontable[j].catchtype.any = NULL;
1082 /* the classref is created later */
1083 if (!(m->rawexceptiontable[j].catchtype.any =
1084 (utf*)class_getconstant(c, idx, CONSTANT_Class)))
1089 if (!suck_check_classbuffer_size(cb, 2))
1092 /* code attributes count */
1094 code_attributes_count = suck_u2(cb);
1096 for (k = 0; k < code_attributes_count; k++) {
1097 if (!suck_check_classbuffer_size(cb, 2))
1100 /* code attribute name index */
1102 code_attribute_name_index = suck_u2(cb);
1104 if (!(code_attribute_name = class_getconstant(c, code_attribute_name_index, CONSTANT_Utf8)))
1107 /* check which code attribute */
1109 if (code_attribute_name == utf_LineNumberTable) {
1110 /* LineNumberTable */
1111 if (!suck_check_classbuffer_size(cb, 4 + 2))
1114 /* attribute length */
1118 /* line number table length */
1120 m->linenumbercount = suck_u2(cb);
1122 if (!suck_check_classbuffer_size(cb,
1123 (2 + 2) * m->linenumbercount))
1126 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1128 #if defined(ENABLE_STATISTICS)
1130 size_lineinfo += sizeof(lineinfo) * m->linenumbercount;
1133 for (l = 0; l < m->linenumbercount; l++) {
1134 m->linenumbers[l].start_pc = suck_u2(cb);
1135 m->linenumbers[l].line_number = suck_u2(cb);
1138 #if defined(ENABLE_JAVASE)
1139 else if (code_attribute_name == utf_StackMapTable) {
1142 if (!stackmap_load_attribute_stackmaptable(cb, m))
1147 /* unknown code attribute */
1149 if (!loader_skip_attribute_body(cb))
1154 else if (attribute_name == utf_Exceptions) {
1157 if (m->thrownexceptions != NULL) {
1158 exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
1162 if (!suck_check_classbuffer_size(cb, 4 + 2))
1165 /* attribute length */
1169 m->thrownexceptionscount = suck_u2(cb);
1171 if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1174 m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
1176 for (j = 0; j < m->thrownexceptionscount; j++) {
1177 /* the classref is created later */
1178 if (!((m->thrownexceptions)[j].any =
1179 (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1183 #if defined(ENABLE_JAVASE)
1184 else if (attribute_name == utf_Signature) {
1187 if (!loader_load_attribute_signature(cb, &(m->signature)))
1192 /* unknown attribute */
1194 if (!loader_skip_attribute_body(cb))
1199 if ((m->jcode == NULL) && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1200 exceptions_throw_classformaterror(c, "Missing Code attribute");
1204 /* initialize the hit countdown field */
1206 #if defined(ENABLE_REPLACEMENT)
1207 m->hitcountdown = METHOD_INITIAL_HIT_COUNTDOWN;
1210 /* everything was ok */
1216 /* load_class_from_sysloader ***************************************************
1218 Load the class with the given name using the system class loader
1221 name.............the classname
1224 the loaded class, or
1225 NULL if an exception has been thrown
1227 *******************************************************************************/
1229 classinfo *load_class_from_sysloader(utf *name)
1232 java_objectheader *cl;
1235 assert(class_java_lang_Object);
1236 assert(class_java_lang_ClassLoader);
1237 assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
1239 m = class_resolveclassmethod(class_java_lang_ClassLoader,
1240 utf_getSystemClassLoader,
1241 utf_void__java_lang_ClassLoader,
1242 class_java_lang_Object,
1248 cl = vm_call_method(m, NULL);
1253 c = load_class_from_classloader(name, cl);
1259 /* load_class_from_classloader *************************************************
1261 Load the class with the given name using the given user-defined class loader.
1264 name.............the classname
1265 cl...............user-defined class loader
1268 the loaded class, or
1269 NULL if an exception has been thrown
1271 *******************************************************************************/
1273 classinfo *load_class_from_classloader(utf *name, java_objectheader *cl)
1275 java_objectheader *o;
1278 java_objectheader *string;
1279 #if defined(ENABLE_RT_TIMING)
1280 struct timespec time_start, time_lookup, time_prepare, time_java,
1284 RT_TIMING_GET_TIME(time_start);
1288 /* lookup if this class has already been loaded */
1290 c = classcache_lookup(cl, name);
1292 RT_TIMING_GET_TIME(time_lookup);
1293 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1298 /* if other class loader than bootstrap, call it */
1306 namelen = name->blength;
1308 /* handle array classes */
1309 if (text[0] == '[') {
1315 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1316 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1317 exceptions_throw_classnotfoundexception(name);
1321 u = utf_new(text + 2, namelen - 3);
1323 if (!(comp = load_class_from_classloader(u, cl)))
1326 /* create the array class */
1328 c = class_array_of(comp, false);
1330 tmpc = classcache_store(cl, c, true);
1333 /* exception, free the loaded class */
1334 c->state &= ~CLASS_LOADING;
1341 /* load the component class */
1343 u = utf_new(text + 1, namelen - 1);
1345 if (!(comp = load_class_from_classloader(u, cl)))
1348 /* create the array class */
1350 c = class_array_of(comp, false);
1352 tmpc = classcache_store(cl, c, true);
1355 /* exception, free the loaded class */
1356 c->state &= ~CLASS_LOADING;
1363 /* primitive array classes are loaded by the bootstrap loader */
1365 c = load_class_bootstrap(name);
1371 assert(class_java_lang_Object);
1373 lc = class_resolveclassmethod(cl->vftbl->class,
1375 utf_java_lang_String__java_lang_Class,
1376 class_java_lang_Object,
1380 return false; /* exception */
1382 /* move return value into `o' and cast it afterwards to a classinfo* */
1384 string = javastring_new_slash_to_dot(name);
1386 RT_TIMING_GET_TIME(time_prepare);
1388 o = vm_call_method(lc, cl, string);
1390 RT_TIMING_GET_TIME(time_java);
1392 c = (classinfo *) o;
1395 /* Store this class in the loaded class cache. If another
1396 class with the same (initloader,name) pair has been
1397 stored earlier it will be returned by classcache_store
1398 In this case classcache_store may not free the class
1399 because it has already been exposed to Java code which
1400 may have kept references to that class. */
1402 tmpc = classcache_store(cl, c, false);
1405 /* exception, free the loaded class */
1406 c->state &= ~CLASS_LOADING;
1413 RT_TIMING_GET_TIME(time_cache);
1415 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1416 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1417 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1419 /* SUN compatible -verbose:class output */
1421 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1423 utf_display_printable_ascii_classname(name);
1427 #if defined(ENABLE_JVMTI)
1428 /* fire Class Load JVMTI event */
1429 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1436 c = load_class_bootstrap(name);
1442 /* load_class_bootstrap ********************************************************
1444 Load the class with the given name using the bootstrap class loader.
1447 name.............the classname
1450 loaded classinfo, or
1451 NULL if an exception has been thrown
1454 load_class_bootstrap is synchronized. It can be treated as an
1457 *******************************************************************************/
1459 classinfo *load_class_bootstrap(utf *name)
1464 #if defined(ENABLE_RT_TIMING)
1465 struct timespec time_start, time_lookup, time_array, time_suck,
1466 time_load, time_cache;
1469 RT_TIMING_GET_TIME(time_start);
1475 /* lookup if this class has already been loaded */
1477 r = classcache_lookup(NULL, name);
1480 RT_TIMING_GET_TIME(time_lookup);
1481 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1486 RT_TIMING_GET_TIME(time_lookup);
1487 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1489 /* create the classinfo */
1491 c = class_create_classinfo(name);
1493 /* handle array classes */
1495 if (name->text[0] == '[') {
1496 c = load_newly_created_array(c, NULL);
1501 assert(c->state & CLASS_LOADED);
1503 RT_TIMING_GET_TIME(time_array);
1504 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1509 #if defined(ENABLE_STATISTICS)
1512 if (opt_getcompilingtime)
1513 compilingtime_stop();
1515 if (opt_getloadingtime)
1516 loadingtime_start();
1519 /* load classdata, throw exception on error */
1524 /* this normally means, the classpath was not set properly */
1526 if (name == utf_java_lang_Object)
1527 vm_abort("java/lang/NoClassDefFoundError: java/lang/Object");
1529 exceptions_throw_classnotfoundexception(name);
1534 RT_TIMING_GET_TIME(time_suck);
1536 /* load the class from the buffer */
1538 r = load_class_from_classbuffer(cb);
1540 RT_TIMING_GET_TIME(time_load);
1543 /* the class could not be loaded, free the classinfo struct */
1548 /* Store this class in the loaded class cache this step also
1549 checks the loading constraints. If the class has been loaded
1550 before, the earlier loaded class is returned. */
1552 classinfo *res = classcache_store(NULL, c, true);
1562 RT_TIMING_GET_TIME(time_cache);
1564 /* SUN compatible -verbose:class output */
1566 if (opt_verboseclass && r) {
1568 utf_display_printable_ascii_classname(name);
1569 printf(" from %s]\n", cb->path);
1576 #if defined(ENABLE_STATISTICS)
1579 if (opt_getloadingtime)
1582 if (opt_getcompilingtime)
1583 compilingtime_start();
1586 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1587 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1588 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1589 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1595 /* load_class_from_classbuffer *************************************************
1597 Loads everything interesting about a class from the class file. The
1598 'classinfo' structure must have been allocated previously.
1600 The super class and the interfaces implemented by this class need
1601 not be loaded. The link is set later by the function 'class_link'.
1603 The loaded class is removed from the list 'unloadedclasses' and
1604 added to the list 'unlinkedclasses'.
1607 This function is NOT synchronized!
1609 *******************************************************************************/
1611 classinfo *load_class_from_classbuffer(classbuffer *cb)
1619 descriptor_pool *descpool;
1620 #if defined(ENABLE_STATISTICS)
1624 #if defined(ENABLE_RT_TIMING)
1625 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1626 time_setup, time_fields, time_methods, time_classrefs,
1627 time_descs, time_setrefs, time_parsefds, time_parsemds,
1628 time_parsecpool, time_verify, time_attrs;
1631 RT_TIMING_GET_TIME(time_start);
1633 /* get the classbuffer's class */
1637 /* the class is already loaded */
1639 if (c->state & CLASS_LOADED)
1642 #if defined(ENABLE_STATISTICS)
1644 count_class_loads++;
1647 #if !defined(NDEBUG)
1648 /* output for debugging purposes */
1651 log_message_class("Loading class: ", c);
1654 /* mark start of dump memory area */
1656 dumpsize = dump_size();
1658 /* class is currently loading */
1660 c->state |= CLASS_LOADING;
1662 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1663 goto return_exception;
1665 /* check signature */
1667 if (suck_u4(cb) != MAGIC) {
1668 exceptions_throw_classformaterror(c, "Bad magic number");
1670 goto return_exception;
1678 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1679 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1680 goto return_exception;
1683 RT_TIMING_GET_TIME(time_checks);
1685 /* create a new descriptor pool */
1687 descpool = descriptor_pool_new(c);
1689 RT_TIMING_GET_TIME(time_ndpool);
1691 /* load the constant pool */
1693 if (!load_constantpool(cb, descpool))
1694 goto return_exception;
1696 RT_TIMING_GET_TIME(time_cpool);
1700 if (!suck_check_classbuffer_size(cb, 2))
1701 goto return_exception;
1703 /* We OR the flags here, as we set already some flags in
1704 class_create_classinfo. */
1706 c->flags |= suck_u2(cb);
1708 /* check ACC flags consistency */
1710 if (c->flags & ACC_INTERFACE) {
1711 if (!(c->flags & ACC_ABSTRACT)) {
1712 /* We work around this because interfaces in JDK 1.1 are
1713 * not declared abstract. */
1715 c->flags |= ACC_ABSTRACT;
1718 if (c->flags & ACC_FINAL) {
1719 exceptions_throw_classformaterror(c,
1720 "Illegal class modifiers: 0x%X",
1722 goto return_exception;
1725 if (c->flags & ACC_SUPER) {
1726 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1730 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1731 exceptions_throw_classformaterror(c,
1732 "Illegal class modifiers: 0x%X",
1734 goto return_exception;
1737 if (!suck_check_classbuffer_size(cb, 2 + 2))
1738 goto return_exception;
1744 if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1745 goto return_exception;
1747 if (c->name == utf_not_named_yet) {
1748 /* we finally have a name for this class */
1750 class_set_packagename(c);
1752 else if (name != c->name) {
1753 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
1754 goto return_exception;
1757 /* retrieve superclass */
1759 c->super.any = NULL;
1761 if ((i = suck_u2(cb))) {
1762 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1763 goto return_exception;
1765 /* java.lang.Object may not have a super class. */
1767 if (c->name == utf_java_lang_Object) {
1768 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
1769 goto return_exception;
1772 /* Interfaces must have java.lang.Object as super class. */
1774 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
1775 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
1776 goto return_exception;
1782 /* This is only allowed for java.lang.Object. */
1784 if (c->name != utf_java_lang_Object) {
1785 exceptions_throw_classformaterror(c, "Bad superclass index");
1786 goto return_exception;
1790 /* retrieve interfaces */
1792 if (!suck_check_classbuffer_size(cb, 2))
1793 goto return_exception;
1795 c->interfacescount = suck_u2(cb);
1797 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1798 goto return_exception;
1800 c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
1801 for (i = 0; i < c->interfacescount; i++) {
1802 /* the classrefs are created later */
1803 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1804 goto return_exception;
1807 RT_TIMING_GET_TIME(time_setup);
1810 if (!suck_check_classbuffer_size(cb, 2))
1811 goto return_exception;
1813 c->fieldscount = suck_u2(cb);
1814 #if defined(ENABLE_GC_CACAO)
1815 c->fields = MNEW(fieldinfo, c->fieldscount);
1816 MZERO(c->fields, fieldinfo, c->fieldscount);
1818 c->fields = GCNEW_UNCOLLECTABLE(fieldinfo, c->fieldscount);
1821 for (i = 0; i < c->fieldscount; i++) {
1822 if (!field_load(cb, &(c->fields[i]), descpool))
1823 goto return_exception;
1826 RT_TIMING_GET_TIME(time_fields);
1829 if (!suck_check_classbuffer_size(cb, 2))
1830 goto return_exception;
1832 c->methodscount = suck_u2(cb);
1833 c->methods = MNEW(methodinfo, c->methodscount);
1835 MZERO(c->methods, methodinfo, c->methodscount);
1837 for (i = 0; i < c->methodscount; i++) {
1838 if (!loader_load_method(cb, &(c->methods[i]), descpool))
1839 goto return_exception;
1842 RT_TIMING_GET_TIME(time_methods);
1844 /* create the class reference table */
1847 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
1849 RT_TIMING_GET_TIME(time_classrefs);
1851 /* allocate space for the parsed descriptors */
1853 descriptor_pool_alloc_parsed_descriptors(descpool);
1855 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
1857 #if defined(ENABLE_STATISTICS)
1859 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
1860 count_classref_len += classrefsize;
1861 count_parsed_desc_len += descsize;
1865 RT_TIMING_GET_TIME(time_descs);
1867 /* put the classrefs in the constant pool */
1868 for (i = 0; i < c->cpcount; i++) {
1869 if (c->cptags[i] == CONSTANT_Class) {
1870 utf *name = (utf *) c->cpinfos[i];
1871 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
1875 /* set the super class reference */
1878 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
1880 goto return_exception;
1883 /* set the super interfaces references */
1885 for (i = 0; i < c->interfacescount; i++) {
1886 c->interfaces[i].ref =
1887 descriptor_pool_lookup_classref(descpool,
1888 (utf *) c->interfaces[i].any);
1889 if (!c->interfaces[i].ref)
1890 goto return_exception;
1893 RT_TIMING_GET_TIME(time_setrefs);
1895 /* parse field descriptors */
1897 for (i = 0; i < c->fieldscount; i++) {
1898 c->fields[i].parseddesc =
1899 descriptor_pool_parse_field_descriptor(descpool,
1900 c->fields[i].descriptor);
1901 if (!c->fields[i].parseddesc)
1902 goto return_exception;
1905 RT_TIMING_GET_TIME(time_parsefds);
1907 /* parse method descriptors */
1909 for (i = 0; i < c->methodscount; i++) {
1910 methodinfo *m = &c->methods[i];
1912 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
1913 m->flags, class_get_self_classref(m->class));
1915 goto return_exception;
1917 for (j = 0; j < m->rawexceptiontablelength; j++) {
1918 if (!m->rawexceptiontable[j].catchtype.any)
1920 if ((m->rawexceptiontable[j].catchtype.ref =
1921 descriptor_pool_lookup_classref(descpool,
1922 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
1923 goto return_exception;
1926 for (j = 0; j < m->thrownexceptionscount; j++) {
1927 if (!m->thrownexceptions[j].any)
1929 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
1930 (utf *) m->thrownexceptions[j].any)) == NULL)
1931 goto return_exception;
1935 RT_TIMING_GET_TIME(time_parsemds);
1937 /* parse the loaded descriptors */
1939 for (i = 0; i < c->cpcount; i++) {
1940 constant_FMIref *fmi;
1943 switch (c->cptags[i]) {
1944 case CONSTANT_Fieldref:
1945 fmi = (constant_FMIref *) c->cpinfos[i];
1946 fmi->parseddesc.fd =
1947 descriptor_pool_parse_field_descriptor(descpool,
1949 if (!fmi->parseddesc.fd)
1950 goto return_exception;
1951 index = fmi->p.index;
1953 (constant_classref *) class_getconstant(c, index,
1955 if (!fmi->p.classref)
1956 goto return_exception;
1958 case CONSTANT_Methodref:
1959 case CONSTANT_InterfaceMethodref:
1960 fmi = (constant_FMIref *) c->cpinfos[i];
1961 index = fmi->p.index;
1963 (constant_classref *) class_getconstant(c, index,
1965 if (!fmi->p.classref)
1966 goto return_exception;
1967 fmi->parseddesc.md =
1968 descriptor_pool_parse_method_descriptor(descpool,
1972 if (!fmi->parseddesc.md)
1973 goto return_exception;
1978 RT_TIMING_GET_TIME(time_parsecpool);
1980 #ifdef ENABLE_VERIFIER
1981 /* Check if all fields and methods can be uniquely
1982 * identified by (name,descriptor). */
1985 /* We use a hash table here to avoid making the
1986 * average case quadratic in # of methods, fields.
1988 static int shift = 0;
1990 u2 *next; /* for chaining colliding hash entries */
1996 /* Allocate hashtable */
1997 len = c->methodscount;
1998 if (len < c->fieldscount) len = c->fieldscount;
2000 hashtab = MNEW(u2,(hashlen + len));
2001 next = hashtab + hashlen;
2003 /* Determine bitshift (to get good hash values) */
2013 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2015 for (i = 0; i < c->fieldscount; ++i) {
2016 fieldinfo *fi = c->fields + i;
2018 /* It's ok if we lose bits here */
2019 index = ((((size_t) fi->name) +
2020 ((size_t) fi->descriptor)) >> shift) % hashlen;
2022 if ((old = hashtab[index])) {
2026 if (c->fields[old].name == fi->name &&
2027 c->fields[old].descriptor == fi->descriptor) {
2028 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
2029 goto return_exception;
2031 } while ((old = next[old]));
2033 hashtab[index] = i + 1;
2037 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2039 for (i = 0; i < c->methodscount; ++i) {
2040 methodinfo *mi = c->methods + i;
2042 /* It's ok if we lose bits here */
2043 index = ((((size_t) mi->name) +
2044 ((size_t) mi->descriptor)) >> shift) % hashlen;
2048 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2049 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2053 if ((old = hashtab[index])) {
2057 if (c->methods[old].name == mi->name &&
2058 c->methods[old].descriptor == mi->descriptor) {
2059 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
2060 goto return_exception;
2062 } while ((old = next[old]));
2064 hashtab[index] = i + 1;
2067 MFREE(hashtab, u2, (hashlen + len));
2069 #endif /* ENABLE_VERIFIER */
2071 RT_TIMING_GET_TIME(time_verify);
2073 #if defined(ENABLE_STATISTICS)
2075 size_classinfo += sizeof(classinfo*) * c->interfacescount;
2076 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
2077 size_methodinfo += sizeof(methodinfo) * c->methodscount;
2081 /* load attribute structures */
2083 if (!class_load_attributes(cb))
2084 goto return_exception;
2086 /* Pre Java 1.5 version don't check this. This implementation is like
2087 Java 1.5 do it: for class file version 45.3 we don't check it, older
2088 versions are checked.
2091 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
2092 /* check if all data has been read */
2093 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
2095 if (classdata_left > 0) {
2096 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
2097 goto return_exception;
2101 RT_TIMING_GET_TIME(time_attrs);
2103 /* release dump area */
2105 dump_release(dumpsize);
2107 /* revert loading state and class is loaded */
2109 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2111 #if defined(ENABLE_JVMTI)
2112 /* fire Class Prepare JVMTI event */
2115 jvmti_ClassLoadPrepare(true, c);
2118 #if !defined(NDEBUG)
2120 log_message_class("Loading done class: ", c);
2123 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
2124 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
2125 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
2126 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
2127 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
2128 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
2129 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
2130 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
2131 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
2132 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
2133 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
2134 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
2135 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
2136 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
2137 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
2142 /* release dump area */
2144 dump_release(dumpsize);
2146 /* an exception has been thrown */
2152 /* load_newly_created_array ****************************************************
2154 Load a newly created array class.
2157 c....................the array class C has been loaded
2158 other classinfo......the array class was found in the class cache,
2160 NULL.................an exception has been thrown
2163 This is an internal function. Do not use it unless you know exactly
2166 Use one of the load_class_... functions for general array class loading.
2168 *******************************************************************************/
2170 classinfo *load_newly_created_array(classinfo *c, java_objectheader *loader)
2172 classinfo *comp = NULL;
2174 methoddesc *clonedesc;
2175 constant_classref *classrefs;
2180 text = c->name->text;
2181 namelen = c->name->blength;
2183 /* Check array class name */
2185 if ((namelen < 2) || (text[0] != '[')) {
2186 exceptions_throw_classnotfoundexception(c->name);
2190 /* Check the element type */
2194 /* c is an array of arrays. We have to create the component class. */
2196 u = utf_new(text + 1, namelen - 1);
2198 comp = load_class_from_classloader(u, loader);
2203 assert(comp->state & CLASS_LOADED);
2209 /* the array's flags are that of the component class */
2210 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2211 c->classloader = comp->classloader;
2215 /* c is an array of objects. */
2217 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2218 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2219 exceptions_throw_classnotfoundexception(c->name);
2223 u = utf_new(text + 2, namelen - 3);
2225 if (!(comp = load_class_from_classloader(u, loader)))
2228 assert(comp->state & CLASS_LOADED);
2234 /* the array's flags are that of the component class */
2235 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2236 c->classloader = comp->classloader;
2240 /* c is an array of a primitive type */
2242 /* check for cases like `[II' and whether the character is a
2243 valid primitive type */
2245 if ((namelen > 2) || (primitive_class_get_by_char(text[1]) == NULL)) {
2246 exceptions_throw_classnotfoundexception(c->name);
2250 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2251 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2252 c->classloader = NULL;
2255 assert(class_java_lang_Object);
2256 #if defined(ENABLE_JAVASE)
2257 assert(class_java_lang_Cloneable);
2258 assert(class_java_io_Serializable);
2261 /* setup the array class */
2263 c->super.cls = class_java_lang_Object;
2265 #if defined(ENABLE_JAVASE)
2266 c->interfacescount = 2;
2267 c->interfaces = MNEW(classref_or_classinfo, 2);
2272 tc = class_java_lang_Cloneable;
2273 assert(tc->state & CLASS_LOADED);
2274 list_add_first(&unlinkedclasses, tc);
2275 c->interfaces[0].cls = tc;
2277 tc = class_java_io_Serializable;
2278 assert(tc->state & CLASS_LOADED);
2279 list_add_first(&unlinkedclasses, tc);
2280 c->interfaces[1].cls = tc;
2283 c->interfaces[0].cls = class_java_lang_Cloneable;
2284 c->interfaces[1].cls = class_java_io_Serializable;
2286 #elif defined(ENABLE_JAVAME_CLDC1_1)
2287 c->interfacescount = 0;
2288 c->interfaces = NULL;
2290 #error unknow Java configuration
2293 c->methodscount = 1;
2294 c->methods = MNEW(methodinfo, c->methodscount);
2295 MZERO(c->methods, methodinfo, c->methodscount);
2297 classrefs = MNEW(constant_classref, 2);
2298 CLASSREF_INIT(classrefs[0], c, c->name);
2299 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2301 /* create descriptor for clone method */
2302 /* we need one paramslot which is reserved for the 'this' parameter */
2303 clonedesc = NEW(methoddesc);
2304 clonedesc->returntype.type = TYPE_ADR;
2305 clonedesc->returntype.classref = classrefs + 1;
2306 clonedesc->returntype.arraydim = 0;
2307 /* initialize params to "empty", add real params below in
2308 descriptor_params_from_paramtypes */
2309 clonedesc->paramcount = 0;
2310 clonedesc->paramslots = 0;
2311 clonedesc->paramtypes[0].classref = classrefs + 0;
2312 clonedesc->params = NULL;
2314 /* create methodinfo */
2317 MSET(clone, 0, methodinfo, 1);
2319 #if defined(ENABLE_THREADS)
2320 lock_init_object_lock(&clone->header);
2323 /* ATTENTION: if you delete the ACC_NATIVE below, set
2324 clone->maxlocals=1 (interpreter related) */
2326 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2327 clone->name = utf_clone;
2328 clone->descriptor = utf_void__java_lang_Object;
2329 clone->parseddesc = clonedesc;
2332 /* parse the descriptor to get the register allocation */
2334 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2337 clone->code = codegen_generate_stub_native(clone, BUILTIN_clone);
2339 /* XXX: field: length? */
2341 /* array classes are not loaded from class files */
2343 c->state |= CLASS_LOADED;
2344 c->parseddescs = (u1 *) clonedesc;
2345 c->parseddescsize = sizeof(methodinfo);
2346 c->classrefs = classrefs;
2347 c->classrefcount = 1;
2349 /* insert class into the loaded class cache */
2350 /* XXX free classinfo if NULL returned? */
2352 return classcache_store(loader, c, true);
2356 /* loader_close ****************************************************************
2358 Frees all resources.
2360 *******************************************************************************/
2362 void loader_close(void)
2369 * These are local overrides for various environment variables in Emacs.
2370 * Please do not remove this and leave it at the end of the file, where
2371 * Emacs will automagically detect them.
2372 * ---------------------------------------------------------------------
2375 * indent-tabs-mode: t
2379 * vim:noexpandtab:sw=4:ts=4: