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 7399 2007-02-23 23:29:13Z michi $
38 #include "mm/memory.h"
40 #if defined(ENABLE_THREADS)
41 # include "threads/native/lock.h"
43 # include "threads/none/lock.h"
46 #include "toolbox/hashtable.h"
47 #include "toolbox/logging.h"
49 #include "vm/builtin.h"
50 #include "vm/exceptions.h"
51 #include "vm/global.h"
52 #include "vm/stringlocal.h"
55 #include "vm/jit/asmpart.h"
56 #include "vm/jit/codegen-common.h"
58 #if defined(ENABLE_JAVASE)
59 # include "vmcore/annotation.h"
60 # include "vmcore/stackmap.h"
63 #include "vmcore/classcache.h"
64 #include "vmcore/linker.h"
65 #include "vmcore/loader.h"
66 #include "vmcore/options.h"
67 #include "vmcore/rt-timing.h"
69 #if defined(ENABLE_STATISTICS)
70 # include "vmcore/statistics.h"
73 #include "vmcore/suck.h"
75 #if defined(ENABLE_ZLIB)
76 # include "vmcore/zip.h"
79 #if defined(ENABLE_JVMTI)
80 # include "native/jvmti/cacaodbg.h"
84 /* global variables ***********************************************************/
86 hashtable *hashtable_classloader;
89 /* loader_init *****************************************************************
91 Initializes all lists and loads all classes required for the system
94 *******************************************************************************/
96 bool loader_init(void)
98 #if defined(ENABLE_THREADS)
99 list_classpath_entry *lce;
101 /* Initialize the monitor pointer for zip/jar file locking. */
103 for (lce = list_first(list_classpath_entries); lce != NULL;
104 lce = list_next(list_classpath_entries, lce))
105 if (lce->type == CLASSPATH_ARCHIVE)
106 lock_init_object_lock((java_objectheader *) lce);
109 /* initialize classloader hashtable, 10 entries should be enough */
111 hashtable_classloader = NEW(hashtable);
112 hashtable_create(hashtable_classloader, 10);
114 /* load some important classes */
116 if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
119 if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
122 #if defined(ENABLE_JAVASE)
123 if (!(class_java_lang_Cloneable =
124 load_class_bootstrap(utf_java_lang_Cloneable)))
127 if (!(class_java_io_Serializable =
128 load_class_bootstrap(utf_java_io_Serializable)))
132 /* load classes for wrapping primitive types */
134 #if defined(ENABLE_JAVASE)
135 if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
139 if (!(class_java_lang_Boolean =
140 load_class_bootstrap(utf_java_lang_Boolean)))
143 if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
146 if (!(class_java_lang_Character =
147 load_class_bootstrap(utf_java_lang_Character)))
150 if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
153 if (!(class_java_lang_Integer =
154 load_class_bootstrap(utf_java_lang_Integer)))
157 if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
160 if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
163 if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
167 /* load some other important classes */
169 if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
172 #if defined(ENABLE_JAVASE)
173 if (!(class_java_lang_ClassLoader =
174 load_class_bootstrap(utf_java_lang_ClassLoader)))
177 if (!(class_java_lang_SecurityManager =
178 load_class_bootstrap(utf_java_lang_SecurityManager)))
182 if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
185 if (!(class_java_lang_Thread =
186 load_class_bootstrap(utf_new_char("java/lang/Thread"))))
189 #if defined(ENABLE_JAVASE)
190 if (!(class_java_lang_ThreadGroup =
191 load_class_bootstrap(utf_java_lang_ThreadGroup)))
195 #if defined(WITH_CLASSPATH_GNU)
196 if (!(class_java_lang_VMSystem =
197 load_class_bootstrap(utf_new_char("java/lang/VMSystem"))))
201 if (!(class_java_lang_VMThread =
202 load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
207 /* some classes which may be used more often */
209 #if defined(ENABLE_JAVASE)
210 if (!(class_java_lang_StackTraceElement =
211 load_class_bootstrap(utf_java_lang_StackTraceElement)))
214 if (!(class_java_lang_reflect_Constructor =
215 load_class_bootstrap(utf_java_lang_reflect_Constructor)))
218 if (!(class_java_lang_reflect_Field =
219 load_class_bootstrap(utf_java_lang_reflect_Field)))
222 if (!(class_java_lang_reflect_Method =
223 load_class_bootstrap(utf_java_lang_reflect_Method)))
226 if (!(class_java_security_PrivilegedAction =
227 load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
230 if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
233 if (!(arrayclass_java_lang_Object =
234 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
242 /* loader_hashtable_classloader_add ********************************************
244 Adds an entry to the classloader hashtable.
246 REMEMBER: Also use this to register native loaders!
248 *******************************************************************************/
250 classloader *loader_hashtable_classloader_add(java_objectheader *cl)
252 hashtable_classloader_entry *cle;
259 LOCK_MONITOR_ENTER(hashtable_classloader->header);
261 /* key for entry is the hashcode of the classloader;
262 aligned to 16-byte boundaries */
264 #if defined(ENABLE_GC_CACAO)
265 key = heap_get_hashcode(cl) >> 4;
267 key = ((u4) (ptrint) cl) >> 4;
270 slot = key & (hashtable_classloader->size - 1);
271 cle = hashtable_classloader->ptr[slot];
273 /* search hashchain for existing entry */
274 /* XXX no GC collection is allowed here, make this a critical section */
277 if (cle->object == cl)
283 /* if no classloader was found, we create a new entry here */
286 cle = NEW(hashtable_classloader_entry);
290 /* insert entry into hashtable */
292 cle->hashlink = hashtable_classloader->ptr[slot];
293 hashtable_classloader->ptr[slot] = cle;
295 /* update number of entries */
297 hashtable_classloader->entries++;
301 LOCK_MONITOR_EXIT(hashtable_classloader->header);
307 /* loader_hashtable_classloader_find *******************************************
309 Find an entry in the classloader hashtable.
311 *******************************************************************************/
313 classloader *loader_hashtable_classloader_find(java_objectheader *cl)
315 hashtable_classloader_entry *cle;
322 /* key for entry is the hashcode of the classloader;
323 aligned to 16-byte boundaries */
325 #if defined(ENABLE_GC_CACAO)
326 key = heap_get_hashcode(cl) >> 4;
328 key = ((u4) (ptrint) cl) >> 4;
331 slot = key & (hashtable_classloader->size - 1);
332 cle = hashtable_classloader->ptr[slot];
334 /* search hashchain for existing entry */
335 /* XXX no GC collection is allowed here, make this a critical section */
338 if (cle->object == cl)
348 /* loader_load_all_classes *****************************************************
350 Loads all classes specified in the BOOTCLASSPATH.
352 *******************************************************************************/
354 void loader_load_all_classes(void)
356 list_classpath_entry *lce;
357 #if defined(ENABLE_ZLIB)
360 hashtable_zipfile_entry *htzfe;
364 for (lce = list_first(list_classpath_entries); lce != NULL;
365 lce = list_next(list_classpath_entries, lce)) {
366 #if defined(ENABLE_ZLIB)
367 if (lce->type == CLASSPATH_ARCHIVE) {
368 /* get the classes hashtable */
372 for (slot = 0; slot < ht->size; slot++) {
373 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
375 for (; htzfe; htzfe = htzfe->hashlink) {
378 /* skip all entries in META-INF and .properties,
381 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
382 strstr(u->text, ".properties") ||
383 strstr(u->text, ".png"))
386 /* load class from bootstrap classloader */
388 if (!load_class_bootstrap(u)) {
389 fprintf(stderr, "Error loading: ");
390 utf_fprint_printable_ascii_classname(stderr, u);
391 fprintf(stderr, "\n");
394 /* print out exception and cause */
396 exceptions_print_current_exception();
404 #if defined(ENABLE_ZLIB)
411 /* loader_skip_attribute_body **************************************************
413 Skips an attribute the attribute_name_index has already been read.
416 u2 attribute_name_index;
418 u1 info[attribute_length];
421 *******************************************************************************/
423 bool loader_skip_attribute_body(classbuffer *cb)
427 if (!suck_check_classbuffer_size(cb, 4))
430 attribute_length = suck_u4(cb);
432 if (!suck_check_classbuffer_size(cb, attribute_length))
435 suck_skip_nbytes(cb, attribute_length);
441 /* load_constantpool ***********************************************************
443 Loads the constantpool of a class, the entries are transformed into
444 a simpler format by resolving references (a detailed overview of
445 the compact structures can be found in global.h).
447 *******************************************************************************/
449 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
452 /* The following structures are used to save information which cannot be
453 processed during the first pass. After the complete constantpool has
454 been traversed the references can be resolved.
455 (only in specific order) */
457 /* CONSTANT_Class entries */
458 typedef struct forward_class {
459 struct forward_class *next;
464 /* CONSTANT_String */
465 typedef struct forward_string {
466 struct forward_string *next;
471 /* CONSTANT_NameAndType */
472 typedef struct forward_nameandtype {
473 struct forward_nameandtype *next;
477 } forward_nameandtype;
479 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
480 typedef struct forward_fieldmethint {
481 struct forward_fieldmethint *next;
485 u2 nameandtype_index;
486 } forward_fieldmethint;
492 forward_class *forward_classes = NULL;
493 forward_string *forward_strings = NULL;
494 forward_nameandtype *forward_nameandtypes = NULL;
495 forward_fieldmethint *forward_fieldmethints = NULL;
499 forward_nameandtype *nfn;
500 forward_fieldmethint *nff;
508 /* number of entries in the constant_pool table plus one */
509 if (!suck_check_classbuffer_size(cb, 2))
512 cpcount = c->cpcount = suck_u2(cb);
514 /* allocate memory */
515 cptags = c->cptags = MNEW(u1, cpcount);
516 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
519 exceptions_throw_classformaterror(c, "Illegal constant pool size");
523 #if defined(ENABLE_STATISTICS)
525 count_const_pool_len += (sizeof(u1) + sizeof(voidptr)) * cpcount;
528 /* initialize constantpool */
529 for (idx = 0; idx < cpcount; idx++) {
530 cptags[idx] = CONSTANT_UNUSED;
535 /******* first pass *******/
536 /* entries which cannot be resolved now are written into
537 temporary structures and traversed again later */
540 while (idx < cpcount) {
543 /* get constant type */
544 if (!suck_check_classbuffer_size(cb, 1))
551 nfc = DNEW(forward_class);
553 nfc->next = forward_classes;
554 forward_classes = nfc;
556 nfc->thisindex = idx;
557 /* reference to CONSTANT_NameAndType */
558 if (!suck_check_classbuffer_size(cb, 2))
561 nfc->name_index = suck_u2(cb);
566 case CONSTANT_String:
567 nfs = DNEW(forward_string);
569 nfs->next = forward_strings;
570 forward_strings = nfs;
572 nfs->thisindex = idx;
574 /* reference to CONSTANT_Utf8_info with string characters */
575 if (!suck_check_classbuffer_size(cb, 2))
578 nfs->string_index = suck_u2(cb);
583 case CONSTANT_NameAndType:
584 nfn = DNEW(forward_nameandtype);
586 nfn->next = forward_nameandtypes;
587 forward_nameandtypes = nfn;
589 nfn->thisindex = idx;
591 if (!suck_check_classbuffer_size(cb, 2 + 2))
594 /* reference to CONSTANT_Utf8_info containing simple name */
595 nfn->name_index = suck_u2(cb);
597 /* reference to CONSTANT_Utf8_info containing field or method
599 nfn->sig_index = suck_u2(cb);
604 case CONSTANT_Fieldref:
605 case CONSTANT_Methodref:
606 case CONSTANT_InterfaceMethodref:
607 nff = DNEW(forward_fieldmethint);
609 nff->next = forward_fieldmethints;
610 forward_fieldmethints = nff;
612 nff->thisindex = idx;
616 if (!suck_check_classbuffer_size(cb, 2 + 2))
619 /* class or interface type that contains the declaration of the
621 nff->class_index = suck_u2(cb);
623 /* name and descriptor of the field or method */
624 nff->nameandtype_index = suck_u2(cb);
629 case CONSTANT_Integer: {
630 constant_integer *ci = NEW(constant_integer);
632 #if defined(ENABLE_STATISTICS)
634 count_const_pool_len += sizeof(constant_integer);
637 if (!suck_check_classbuffer_size(cb, 4))
640 ci->value = suck_s4(cb);
641 cptags[idx] = CONSTANT_Integer;
648 case CONSTANT_Float: {
649 constant_float *cf = NEW(constant_float);
651 #if defined(ENABLE_STATISTICS)
653 count_const_pool_len += sizeof(constant_float);
656 if (!suck_check_classbuffer_size(cb, 4))
659 cf->value = suck_float(cb);
660 cptags[idx] = CONSTANT_Float;
667 case CONSTANT_Long: {
668 constant_long *cl = NEW(constant_long);
670 #if defined(ENABLE_STATISTICS)
672 count_const_pool_len += sizeof(constant_long);
675 if (!suck_check_classbuffer_size(cb, 8))
678 cl->value = suck_s8(cb);
679 cptags[idx] = CONSTANT_Long;
683 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
689 case CONSTANT_Double: {
690 constant_double *cd = NEW(constant_double);
692 #if defined(ENABLE_STATISTICS)
694 count_const_pool_len += sizeof(constant_double);
697 if (!suck_check_classbuffer_size(cb, 8))
700 cd->value = suck_double(cb);
701 cptags[idx] = CONSTANT_Double;
705 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
711 case CONSTANT_Utf8: {
714 /* number of bytes in the bytes array (not string-length) */
715 if (!suck_check_classbuffer_size(cb, 2))
718 length = suck_u2(cb);
719 cptags[idx] = CONSTANT_Utf8;
721 /* validate the string */
722 if (!suck_check_classbuffer_size(cb, length))
725 #ifdef ENABLE_VERIFIER
727 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
729 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
732 #endif /* ENABLE_VERIFIER */
733 /* insert utf-string into the utf-symboltable */
734 cpinfos[idx] = utf_new((char *) cb->pos, length);
736 /* skip bytes of the string (buffer size check above) */
737 suck_skip_nbytes(cb, length);
743 exceptions_throw_classformaterror(c, "Illegal constant pool type");
749 /* resolve entries in temporary structures */
751 while (forward_classes) {
753 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
757 #ifdef ENABLE_VERIFIER
758 if (opt_verify && !is_valid_name_utf(name)) {
759 exceptions_throw_classformaterror(c, "Class reference with invalid name");
762 #endif /* ENABLE_VERIFIER */
764 /* add all class references to the descriptor_pool */
766 if (!descriptor_pool_add_class(descpool, name))
769 cptags[forward_classes->thisindex] = CONSTANT_Class;
774 if (!(tc = load_class_bootstrap(name)))
777 /* link the class later, because we cannot link the class currently
779 list_add_first(&unlinkedclasses, tc);
782 /* the classref is created later */
783 cpinfos[forward_classes->thisindex] = name;
785 nfc = forward_classes;
786 forward_classes = forward_classes->next;
789 while (forward_strings) {
791 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
795 /* resolve utf-string */
796 cptags[forward_strings->thisindex] = CONSTANT_String;
797 cpinfos[forward_strings->thisindex] = text;
799 nfs = forward_strings;
800 forward_strings = forward_strings->next;
803 while (forward_nameandtypes) {
804 constant_nameandtype *cn = NEW(constant_nameandtype);
806 #if defined(ENABLE_STATISTICS)
808 count_const_pool_len += sizeof(constant_nameandtype);
811 /* resolve simple name and descriptor */
812 cn->name = class_getconstant(c,
813 forward_nameandtypes->name_index,
818 cn->descriptor = class_getconstant(c,
819 forward_nameandtypes->sig_index,
824 #ifdef ENABLE_VERIFIER
827 if (!is_valid_name_utf(cn->name)) {
828 exceptions_throw_classformaterror(c,
829 "Illegal Field name \"%s\"",
835 /* disallow referencing <clinit> among others */
836 if (cn->name->text[0] == '<' && cn->name != utf_init) {
837 exceptions_throw_classformaterror(c, "Illegal reference to special method");
841 #endif /* ENABLE_VERIFIER */
843 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
844 cpinfos[forward_nameandtypes->thisindex] = cn;
846 nfn = forward_nameandtypes;
847 forward_nameandtypes = forward_nameandtypes->next;
850 while (forward_fieldmethints) {
851 constant_nameandtype *nat;
852 constant_FMIref *fmi = NEW(constant_FMIref);
854 #if defined(ENABLE_STATISTICS)
856 count_const_pool_len += sizeof(constant_FMIref);
858 /* resolve simple name and descriptor */
860 nat = class_getconstant(c,
861 forward_fieldmethints->nameandtype_index,
862 CONSTANT_NameAndType);
866 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
868 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
871 /* the classref is created later */
873 fmi->p.index = forward_fieldmethints->class_index;
874 fmi->name = nat->name;
875 fmi->descriptor = nat->descriptor;
877 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
878 cpinfos[forward_fieldmethints->thisindex] = fmi;
880 nff = forward_fieldmethints;
881 forward_fieldmethints = forward_fieldmethints->next;
884 /* everything was ok */
890 /* loader_load_attribute_signature *********************************************
892 Signature_attribute {
893 u2 attribute_name_index;
898 *******************************************************************************/
900 #if defined(ENABLE_JAVASE)
901 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
911 /* check remaining bytecode */
913 if (!suck_check_classbuffer_size(cb, 4 + 2))
916 /* check attribute length */
918 attribute_length = suck_u4(cb);
920 if (attribute_length != 2) {
921 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
925 if (*signature != NULL) {
926 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
932 signature_index = suck_u2(cb);
934 if (!(*signature = class_getconstant(c, signature_index, CONSTANT_Utf8)))
939 #endif /* defined(ENABLE_JAVASE) */
942 /* load_field ******************************************************************
944 Load everything about a class field from the class file and fill a
945 'fieldinfo' structure. For static fields, space in the data segment
948 *******************************************************************************/
950 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
952 static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
957 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
962 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
965 f->flags = suck_u2(cb);
967 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
972 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
976 f->parseddesc = NULL;
978 if (!descriptor_pool_add(descpool, u, NULL))
981 /* descriptor_pool_add accepts method descriptors, so we have to check */
982 /* against them here before the call of descriptor_to_basic_type below. */
983 if (u->text[0] == '(') {
984 exceptions_throw_classformaterror(c, "Method descriptor used for field");
988 #ifdef ENABLE_VERIFIER
991 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<') {
992 exceptions_throw_classformaterror(c,
993 "Illegal Field name \"%s\"",
998 /* check flag consistency */
999 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
1001 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
1002 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
1003 exceptions_throw_classformaterror(c,
1004 "Illegal field modifiers: 0x%X",
1009 if (c->flags & ACC_INTERFACE) {
1010 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
1011 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
1012 f->flags & ACC_TRANSIENT) {
1013 exceptions_throw_classformaterror(c,
1014 "Illegal field modifiers: 0x%X",
1020 #endif /* ENABLE_VERIFIER */
1022 f->type = jtype = descriptor_to_basic_type(f->descriptor); /* data type */
1023 f->offset = 0; /* offset from start of object */
1041 if (!(f->flags & ACC_STATIC))
1042 c->flags |= ACC_CLASS_HAS_POINTERS;
1050 f->value.l.high = 0;
1055 /* read attributes */
1056 if (!suck_check_classbuffer_size(cb, 2))
1059 attrnum = suck_u2(cb);
1060 for (i = 0; i < attrnum; i++) {
1061 if (!suck_check_classbuffer_size(cb, 2))
1064 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1067 if (u == utf_ConstantValue) {
1068 if (!suck_check_classbuffer_size(cb, 4 + 2))
1071 /* check attribute length */
1073 if (suck_u4(cb) != 2) {
1074 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
1078 /* constant value attribute */
1080 if (pindex != field_load_NOVALUE) {
1081 exceptions_throw_classformaterror(c, "Multiple ConstantValue attributes");
1085 /* index of value in constantpool */
1087 pindex = suck_u2(cb);
1089 /* initialize field with value from constantpool */
1092 constant_integer *ci;
1094 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
1097 f->value.i = ci->value;
1104 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
1107 f->value.l = cl->value;
1114 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
1117 f->value.f = cf->value;
1122 constant_double *cd;
1124 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
1127 f->value.d = cd->value;
1132 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
1135 /* create javastring from compressed utf8-string */
1136 f->value.a = literalstring_new(u);
1140 log_text("Invalid Constant - Type");
1143 #if defined(ENABLE_JAVASE)
1144 else if (u == utf_Signature) {
1147 if (!loader_load_attribute_signature(cb, &(f->signature)))
1152 /* unknown attribute */
1154 if (!loader_skip_attribute_body(cb))
1159 /* everything was ok */
1165 /* loader_load_method **********************************************************
1167 Loads a method from the class file and fills an existing
1168 'methodinfo' structure. For native methods, the function pointer
1169 field is set to the real function pointer, for JavaVM methods a
1170 pointer to the compiler is used preliminarily.
1175 u2 descriptor_index;
1176 u2 attributes_count;
1177 attribute_info attributes[attribute_count];
1181 u2 attribute_name_index;
1182 u4 attribute_length;
1183 u1 info[attribute_length];
1186 LineNumberTable_attribute {
1187 u2 attribute_name_index;
1188 u4 attribute_length;
1189 u2 line_number_table_length;
1193 } line_number_table[line_number_table_length];
1196 *******************************************************************************/
1198 static bool loader_load_method(classbuffer *cb, methodinfo *m,
1199 descriptor_pool *descpool)
1206 u2 descriptor_index;
1207 u2 attributes_count;
1208 u2 attribute_name_index;
1209 utf *attribute_name;
1210 u2 code_attributes_count;
1211 u2 code_attribute_name_index;
1212 utf *code_attribute_name;
1218 #if defined(ENABLE_STATISTICS)
1220 count_all_methods++;
1223 /* all fields of m have been zeroed in load_class_from_classbuffer */
1227 if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
1232 m->flags = suck_u2(cb);
1236 name_index = suck_u2(cb);
1238 if (!(u = class_getconstant(c, name_index, CONSTANT_Utf8)))
1245 descriptor_index = suck_u2(cb);
1247 if (!(u = class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
1252 if (!descriptor_pool_add(descpool, u, &argcount))
1255 #ifdef ENABLE_VERIFIER
1257 if (!is_valid_name_utf(m->name)) {
1258 exceptions_throw_classformaterror(c, "Method with invalid name");
1262 if (m->name->text[0] == '<' &&
1263 m->name != utf_init && m->name != utf_clinit) {
1264 exceptions_throw_classformaterror(c, "Method with invalid special name");
1268 #endif /* ENABLE_VERIFIER */
1270 if (!(m->flags & ACC_STATIC))
1271 argcount++; /* count the 'this' argument */
1273 #ifdef ENABLE_VERIFIER
1275 if (argcount > 255) {
1276 exceptions_throw_classformaterror(c, "Too many arguments in signature");
1280 /* check flag consistency */
1281 if (m->name != utf_clinit) {
1282 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1284 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1285 exceptions_throw_classformaterror(c,
1286 "Illegal method modifiers: 0x%X",
1291 if (m->flags & ACC_ABSTRACT) {
1292 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1293 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1294 exceptions_throw_classformaterror(c,
1295 "Illegal method modifiers: 0x%X",
1301 if (c->flags & ACC_INTERFACE) {
1302 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1303 exceptions_throw_classformaterror(c,
1304 "Illegal method modifiers: 0x%X",
1310 if (m->name == utf_init) {
1311 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1312 ACC_NATIVE | ACC_ABSTRACT)) {
1313 exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
1319 #endif /* ENABLE_VERIFIER */
1321 /* mark the method as monomorphic until further notice */
1323 m->flags |= ACC_METHOD_MONOMORPHIC;
1325 /* non-abstract methods have an implementation in this class */
1327 if (!(m->flags & ACC_ABSTRACT))
1328 m->flags |= ACC_METHOD_IMPLEMENTED;
1330 if (!suck_check_classbuffer_size(cb, 2))
1333 /* attributes count */
1335 attributes_count = suck_u2(cb);
1337 for (i = 0; i < attributes_count; i++) {
1338 if (!suck_check_classbuffer_size(cb, 2))
1341 /* attribute name index */
1343 attribute_name_index = suck_u2(cb);
1345 if (!(attribute_name = class_getconstant(c, attribute_name_index, CONSTANT_Utf8)))
1348 if (attribute_name == utf_Code) {
1350 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1351 exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
1356 exceptions_throw_classformaterror(c, "Multiple Code attributes");
1360 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1364 m->maxstack = suck_u2(cb);
1365 m->maxlocals = suck_u2(cb);
1367 if (m->maxlocals < argcount) {
1368 exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
1372 if (!suck_check_classbuffer_size(cb, 4))
1375 m->jcodelength = suck_u4(cb);
1377 if (m->jcodelength == 0) {
1378 exceptions_throw_classformaterror(c, "Code of a method has length 0");
1382 if (m->jcodelength > 65535) {
1383 exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
1387 if (!suck_check_classbuffer_size(cb, m->jcodelength))
1390 m->jcode = MNEW(u1, m->jcodelength);
1391 suck_nbytes(m->jcode, cb, m->jcodelength);
1393 if (!suck_check_classbuffer_size(cb, 2))
1396 m->rawexceptiontablelength = suck_u2(cb);
1397 if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->rawexceptiontablelength))
1400 m->rawexceptiontable = MNEW(raw_exception_entry, m->rawexceptiontablelength);
1402 #if defined(ENABLE_STATISTICS)
1404 count_vmcode_len += m->jcodelength + 18;
1405 count_extable_len +=
1406 m->rawexceptiontablelength * sizeof(raw_exception_entry);
1410 for (j = 0; j < m->rawexceptiontablelength; j++) {
1412 m->rawexceptiontable[j].startpc = suck_u2(cb);
1413 m->rawexceptiontable[j].endpc = suck_u2(cb);
1414 m->rawexceptiontable[j].handlerpc = suck_u2(cb);
1418 m->rawexceptiontable[j].catchtype.any = NULL;
1421 /* the classref is created later */
1422 if (!(m->rawexceptiontable[j].catchtype.any =
1423 (utf*)class_getconstant(c, idx, CONSTANT_Class)))
1428 if (!suck_check_classbuffer_size(cb, 2))
1431 /* code attributes count */
1433 code_attributes_count = suck_u2(cb);
1435 for (k = 0; k < code_attributes_count; k++) {
1436 if (!suck_check_classbuffer_size(cb, 2))
1439 /* code attribute name index */
1441 code_attribute_name_index = suck_u2(cb);
1443 if (!(code_attribute_name = class_getconstant(c, code_attribute_name_index, CONSTANT_Utf8)))
1446 /* check which code attribute */
1448 if (code_attribute_name == utf_LineNumberTable) {
1449 /* LineNumberTable */
1450 if (!suck_check_classbuffer_size(cb, 4 + 2))
1453 /* attribute length */
1457 /* line number table length */
1459 m->linenumbercount = suck_u2(cb);
1461 if (!suck_check_classbuffer_size(cb,
1462 (2 + 2) * m->linenumbercount))
1465 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1467 #if defined(ENABLE_STATISTICS)
1469 size_lineinfo += sizeof(lineinfo) * m->linenumbercount;
1472 for (l = 0; l < m->linenumbercount; l++) {
1473 m->linenumbers[l].start_pc = suck_u2(cb);
1474 m->linenumbers[l].line_number = suck_u2(cb);
1477 #if defined(ENABLE_JAVASE)
1478 else if (code_attribute_name == utf_StackMapTable) {
1481 if (!stackmap_load_attribute_stackmaptable(cb, m))
1486 /* unknown code attribute */
1488 if (!loader_skip_attribute_body(cb))
1493 else if (attribute_name == utf_Exceptions) {
1496 if (m->thrownexceptions != NULL) {
1497 exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
1501 if (!suck_check_classbuffer_size(cb, 4 + 2))
1504 /* attribute length */
1508 m->thrownexceptionscount = suck_u2(cb);
1510 if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1513 m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
1515 for (j = 0; j < m->thrownexceptionscount; j++) {
1516 /* the classref is created later */
1517 if (!((m->thrownexceptions)[j].any =
1518 (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1522 #if defined(ENABLE_JAVASE)
1523 else if (attribute_name == utf_Signature) {
1526 if (!loader_load_attribute_signature(cb, &(m->signature)))
1531 /* unknown attribute */
1533 if (!loader_skip_attribute_body(cb))
1538 if ((m->jcode == NULL) && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1539 exceptions_throw_classformaterror(c, "Missing Code attribute");
1543 /* everything was ok */
1549 /* load_class_from_sysloader ***************************************************
1551 Load the class with the given name using the system class loader
1554 name.............the classname
1557 the loaded class, or
1558 NULL if an exception has been thrown
1560 *******************************************************************************/
1562 classinfo *load_class_from_sysloader(utf *name)
1565 java_objectheader *clo;
1569 assert(class_java_lang_Object);
1570 assert(class_java_lang_ClassLoader);
1571 assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
1573 m = class_resolveclassmethod(class_java_lang_ClassLoader,
1574 utf_getSystemClassLoader,
1575 utf_void__java_lang_ClassLoader,
1576 class_java_lang_Object,
1582 clo = vm_call_method(m, NULL);
1587 cl = loader_hashtable_classloader_add(clo);
1589 c = load_class_from_classloader(name, cl);
1595 /* load_class_from_classloader *************************************************
1597 Load the class with the given name using the given user-defined class loader.
1600 name.............the classname
1601 cl...............user-defined class loader
1604 the loaded class, or
1605 NULL if an exception has been thrown
1607 *******************************************************************************/
1609 classinfo *load_class_from_classloader(utf *name, classloader *cl)
1611 java_objectheader *o;
1614 java_objectheader *string;
1615 #if defined(ENABLE_RT_TIMING)
1616 struct timespec time_start, time_lookup, time_prepare, time_java,
1620 RT_TIMING_GET_TIME(time_start);
1624 /* lookup if this class has already been loaded */
1626 c = classcache_lookup(cl, name);
1628 RT_TIMING_GET_TIME(time_lookup);
1629 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1634 /* if other class loader than bootstrap, call it */
1642 namelen = name->blength;
1644 /* handle array classes */
1645 if (text[0] == '[') {
1651 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1652 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1653 exceptions_throw_noclassdeffounderror(name);
1657 u = utf_new(text + 2, namelen - 3);
1659 if (!(comp = load_class_from_classloader(u, cl)))
1662 /* create the array class */
1664 c = class_array_of(comp, false);
1666 tmpc = classcache_store(cl, c, true);
1669 /* exception, free the loaded class */
1670 c->state &= ~CLASS_LOADING;
1677 /* load the component class */
1679 u = utf_new(text + 1, namelen - 1);
1681 if (!(comp = load_class_from_classloader(u, cl)))
1684 /* create the array class */
1686 c = class_array_of(comp, false);
1688 tmpc = classcache_store(cl, c, true);
1691 /* exception, free the loaded class */
1692 c->state &= ~CLASS_LOADING;
1699 /* primitive array classes are loaded by the bootstrap loader */
1701 c = load_class_bootstrap(name);
1707 assert(class_java_lang_Object);
1709 lc = class_resolveclassmethod(cl->object->vftbl->class,
1711 utf_java_lang_String__java_lang_Class,
1712 class_java_lang_Object,
1716 return false; /* exception */
1718 /* move return value into `o' and cast it afterwards to a classinfo* */
1720 string = javastring_new_slash_to_dot(name);
1722 RT_TIMING_GET_TIME(time_prepare);
1724 o = vm_call_method(lc, cl->object, string);
1726 RT_TIMING_GET_TIME(time_java);
1728 c = (classinfo *) o;
1731 /* Store this class in the loaded class cache. If another
1732 class with the same (initloader,name) pair has been
1733 stored earlier it will be returned by classcache_store
1734 In this case classcache_store may not free the class
1735 because it has already been exposed to Java code which
1736 may have kept references to that class. */
1738 tmpc = classcache_store(cl, c, false);
1741 /* exception, free the loaded class */
1742 c->state &= ~CLASS_LOADING;
1749 /* loadClass has thrown an exception. We must convert
1750 ClassNotFoundException into
1751 NoClassDefFoundException. */
1753 /* XXX Maybe we should have a flag that avoids this
1754 conversion for calling load_class_from_classloader from
1755 Class.forName. Currently we do a double conversion in
1758 classnotfoundexception_to_noclassdeffounderror();
1761 RT_TIMING_GET_TIME(time_cache);
1763 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1764 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1765 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1767 /* SUN compatible -verbose:class output */
1769 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1771 utf_display_printable_ascii_classname(name);
1775 #if defined(ENABLE_JVMTI)
1776 /* fire Class Load JVMTI event */
1777 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1784 c = load_class_bootstrap(name);
1790 /* load_class_bootstrap ********************************************************
1792 Load the class with the given name using the bootstrap class loader.
1795 name.............the classname
1798 loaded classinfo, or
1799 NULL if an exception has been thrown
1802 load_class_bootstrap is synchronized. It can be treated as an
1805 *******************************************************************************/
1807 classinfo *load_class_bootstrap(utf *name)
1812 #if defined(ENABLE_RT_TIMING)
1813 struct timespec time_start, time_lookup, time_array, time_suck,
1814 time_load, time_cache;
1817 RT_TIMING_GET_TIME(time_start);
1823 /* lookup if this class has already been loaded */
1825 if ((r = classcache_lookup(NULL, name))) {
1827 RT_TIMING_GET_TIME(time_lookup);
1828 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1833 RT_TIMING_GET_TIME(time_lookup);
1834 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1836 /* create the classinfo */
1838 c = class_create_classinfo(name);
1840 /* handle array classes */
1842 if (name->text[0] == '[') {
1843 c = load_newly_created_array(c, NULL);
1846 assert(c->state & CLASS_LOADED);
1848 RT_TIMING_GET_TIME(time_array);
1849 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1854 #if defined(ENABLE_STATISTICS)
1857 if (opt_getcompilingtime)
1858 compilingtime_stop();
1860 if (opt_getloadingtime)
1861 loadingtime_start();
1864 /* load classdata, throw exception on error */
1869 /* this normally means, the classpath was not set properly */
1871 if (name == utf_java_lang_Object)
1872 vm_abort("java/lang/NoClassDefFoundError: java/lang/Object");
1874 exceptions_throw_noclassdeffounderror(name);
1879 RT_TIMING_GET_TIME(time_suck);
1881 /* load the class from the buffer */
1883 r = load_class_from_classbuffer(cb);
1885 RT_TIMING_GET_TIME(time_load);
1888 /* the class could not be loaded, free the classinfo struct */
1893 /* Store this class in the loaded class cache this step also
1894 checks the loading constraints. If the class has been loaded
1895 before, the earlier loaded class is returned. */
1897 classinfo *res = classcache_store(NULL, c, true);
1907 RT_TIMING_GET_TIME(time_cache);
1909 /* SUN compatible -verbose:class output */
1911 if (opt_verboseclass && r) {
1913 utf_display_printable_ascii_classname(name);
1914 printf(" from %s]\n", cb->path);
1921 #if defined(ENABLE_STATISTICS)
1924 if (opt_getloadingtime)
1927 if (opt_getcompilingtime)
1928 compilingtime_start();
1931 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1932 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1933 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1934 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1940 /* load_class_from_classbuffer *************************************************
1942 Loads everything interesting about a class from the class file. The
1943 'classinfo' structure must have been allocated previously.
1945 The super class and the interfaces implemented by this class need
1946 not be loaded. The link is set later by the function 'class_link'.
1948 The loaded class is removed from the list 'unloadedclasses' and
1949 added to the list 'unlinkedclasses'.
1952 This function is NOT synchronized!
1954 *******************************************************************************/
1956 classinfo *load_class_from_classbuffer(classbuffer *cb)
1964 descriptor_pool *descpool;
1965 #if defined(ENABLE_STATISTICS)
1969 #if defined(ENABLE_RT_TIMING)
1970 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1971 time_setup, time_fields, time_methods, time_classrefs,
1972 time_descs, time_setrefs, time_parsefds, time_parsemds,
1973 time_parsecpool, time_verify, time_attrs;
1976 RT_TIMING_GET_TIME(time_start);
1978 /* get the classbuffer's class */
1982 /* the class is already loaded */
1984 if (c->state & CLASS_LOADED)
1987 #if defined(ENABLE_STATISTICS)
1989 count_class_loads++;
1992 #if !defined(NDEBUG)
1993 /* output for debugging purposes */
1996 log_message_class("Loading class: ", c);
1999 /* mark start of dump memory area */
2001 dumpsize = dump_size();
2003 /* class is currently loading */
2005 c->state |= CLASS_LOADING;
2007 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
2008 goto return_exception;
2010 /* check signature */
2012 if (suck_u4(cb) != MAGIC) {
2013 exceptions_throw_classformaterror(c, "Bad magic number");
2015 goto return_exception;
2023 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
2024 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
2025 goto return_exception;
2028 RT_TIMING_GET_TIME(time_checks);
2030 /* create a new descriptor pool */
2032 descpool = descriptor_pool_new(c);
2034 RT_TIMING_GET_TIME(time_ndpool);
2036 /* load the constant pool */
2038 if (!load_constantpool(cb, descpool))
2039 goto return_exception;
2041 RT_TIMING_GET_TIME(time_cpool);
2045 if (!suck_check_classbuffer_size(cb, 2))
2046 goto return_exception;
2048 /* We OR the flags here, as we set already some flags in
2049 class_create_classinfo. */
2051 c->flags |= suck_u2(cb);
2053 /* check ACC flags consistency */
2055 if (c->flags & ACC_INTERFACE) {
2056 if (!(c->flags & ACC_ABSTRACT)) {
2057 /* We work around this because interfaces in JDK 1.1 are
2058 * not declared abstract. */
2060 c->flags |= ACC_ABSTRACT;
2063 if (c->flags & ACC_FINAL) {
2064 exceptions_throw_classformaterror(c,
2065 "Illegal class modifiers: 0x%X",
2067 goto return_exception;
2070 if (c->flags & ACC_SUPER) {
2071 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
2075 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
2076 exceptions_throw_classformaterror(c,
2077 "Illegal class modifiers: 0x%X",
2079 goto return_exception;
2082 if (!suck_check_classbuffer_size(cb, 2 + 2))
2083 goto return_exception;
2088 if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
2089 goto return_exception;
2091 if (c->name == utf_not_named_yet) {
2092 /* we finally have a name for this class */
2094 class_set_packagename(c);
2096 } else if (name != c->name) {
2097 /* TODO: i want to be an exceptions-function! */
2101 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
2102 utf_bytes(name) + strlen(")") + strlen("0");
2104 msg = MNEW(char, msglen);
2106 utf_copy_classname(msg, c->name);
2107 strcat(msg, " (wrong name: ");
2108 utf_cat_classname(msg, name);
2112 /* *exceptionptr = */
2113 /* new_exception_message("java/lang/NoClassDefFoundError", msg); */
2114 exceptions_throw_noclassdeffounderror(c->name);
2116 MFREE(msg, char, msglen);
2118 goto return_exception;
2121 /* retrieve superclass */
2123 c->super.any = NULL;
2124 if ((i = suck_u2(cb))) {
2125 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
2126 goto return_exception;
2128 /* java.lang.Object may not have a super class. */
2130 if (c->name == utf_java_lang_Object) {
2131 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
2132 goto return_exception;
2135 /* Interfaces must have java.lang.Object as super class. */
2137 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
2138 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
2139 goto return_exception;
2145 /* This is only allowed for java.lang.Object. */
2147 if (c->name != utf_java_lang_Object) {
2148 exceptions_throw_classformaterror(c, "Bad superclass index");
2149 goto return_exception;
2153 /* retrieve interfaces */
2155 if (!suck_check_classbuffer_size(cb, 2))
2156 goto return_exception;
2158 c->interfacescount = suck_u2(cb);
2160 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
2161 goto return_exception;
2163 c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
2164 for (i = 0; i < c->interfacescount; i++) {
2165 /* the classrefs are created later */
2166 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2167 goto return_exception;
2170 RT_TIMING_GET_TIME(time_setup);
2173 if (!suck_check_classbuffer_size(cb, 2))
2174 goto return_exception;
2176 c->fieldscount = suck_u2(cb);
2177 #if defined(ENABLE_GC_CACAO)
2178 c->fields = MNEW(fieldinfo, c->fieldscount);
2179 MZERO(c->fields, fieldinfo, c->fieldscount);
2181 c->fields = GCNEW_UNCOLLECTABLE(fieldinfo, c->fieldscount);
2184 for (i = 0; i < c->fieldscount; i++) {
2185 if (!load_field(cb, &(c->fields[i]),descpool))
2186 goto return_exception;
2189 RT_TIMING_GET_TIME(time_fields);
2192 if (!suck_check_classbuffer_size(cb, 2))
2193 goto return_exception;
2195 c->methodscount = suck_u2(cb);
2196 c->methods = MNEW(methodinfo, c->methodscount);
2198 MZERO(c->methods, methodinfo, c->methodscount);
2200 for (i = 0; i < c->methodscount; i++) {
2201 if (!loader_load_method(cb, &(c->methods[i]), descpool))
2202 goto return_exception;
2205 RT_TIMING_GET_TIME(time_methods);
2207 /* create the class reference table */
2210 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
2212 RT_TIMING_GET_TIME(time_classrefs);
2214 /* allocate space for the parsed descriptors */
2216 descriptor_pool_alloc_parsed_descriptors(descpool);
2218 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
2220 #if defined(ENABLE_STATISTICS)
2222 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
2223 count_classref_len += classrefsize;
2224 count_parsed_desc_len += descsize;
2228 RT_TIMING_GET_TIME(time_descs);
2230 /* put the classrefs in the constant pool */
2231 for (i = 0; i < c->cpcount; i++) {
2232 if (c->cptags[i] == CONSTANT_Class) {
2233 utf *name = (utf *) c->cpinfos[i];
2234 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
2238 /* set the super class reference */
2241 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
2243 goto return_exception;
2246 /* set the super interfaces references */
2248 for (i = 0; i < c->interfacescount; i++) {
2249 c->interfaces[i].ref =
2250 descriptor_pool_lookup_classref(descpool,
2251 (utf *) c->interfaces[i].any);
2252 if (!c->interfaces[i].ref)
2253 goto return_exception;
2256 RT_TIMING_GET_TIME(time_setrefs);
2258 /* parse field descriptors */
2260 for (i = 0; i < c->fieldscount; i++) {
2261 c->fields[i].parseddesc =
2262 descriptor_pool_parse_field_descriptor(descpool,
2263 c->fields[i].descriptor);
2264 if (!c->fields[i].parseddesc)
2265 goto return_exception;
2268 RT_TIMING_GET_TIME(time_parsefds);
2270 /* parse method descriptors */
2272 for (i = 0; i < c->methodscount; i++) {
2273 methodinfo *m = &c->methods[i];
2275 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
2276 m->flags, class_get_self_classref(m->class));
2278 goto return_exception;
2280 for (j = 0; j < m->rawexceptiontablelength; j++) {
2281 if (!m->rawexceptiontable[j].catchtype.any)
2283 if ((m->rawexceptiontable[j].catchtype.ref =
2284 descriptor_pool_lookup_classref(descpool,
2285 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
2286 goto return_exception;
2289 for (j = 0; j < m->thrownexceptionscount; j++) {
2290 if (!m->thrownexceptions[j].any)
2292 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
2293 (utf *) m->thrownexceptions[j].any)) == NULL)
2294 goto return_exception;
2298 RT_TIMING_GET_TIME(time_parsemds);
2300 /* parse the loaded descriptors */
2302 for (i = 0; i < c->cpcount; i++) {
2303 constant_FMIref *fmi;
2306 switch (c->cptags[i]) {
2307 case CONSTANT_Fieldref:
2308 fmi = (constant_FMIref *) c->cpinfos[i];
2309 fmi->parseddesc.fd =
2310 descriptor_pool_parse_field_descriptor(descpool,
2312 if (!fmi->parseddesc.fd)
2313 goto return_exception;
2314 index = fmi->p.index;
2316 (constant_classref *) class_getconstant(c, index,
2318 if (!fmi->p.classref)
2319 goto return_exception;
2321 case CONSTANT_Methodref:
2322 case CONSTANT_InterfaceMethodref:
2323 fmi = (constant_FMIref *) c->cpinfos[i];
2324 index = fmi->p.index;
2326 (constant_classref *) class_getconstant(c, index,
2328 if (!fmi->p.classref)
2329 goto return_exception;
2330 fmi->parseddesc.md =
2331 descriptor_pool_parse_method_descriptor(descpool,
2335 if (!fmi->parseddesc.md)
2336 goto return_exception;
2341 RT_TIMING_GET_TIME(time_parsecpool);
2343 #ifdef ENABLE_VERIFIER
2344 /* Check if all fields and methods can be uniquely
2345 * identified by (name,descriptor). */
2348 /* We use a hash table here to avoid making the
2349 * average case quadratic in # of methods, fields.
2351 static int shift = 0;
2353 u2 *next; /* for chaining colliding hash entries */
2359 /* Allocate hashtable */
2360 len = c->methodscount;
2361 if (len < c->fieldscount) len = c->fieldscount;
2363 hashtab = MNEW(u2,(hashlen + len));
2364 next = hashtab + hashlen;
2366 /* Determine bitshift (to get good hash values) */
2376 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2378 for (i = 0; i < c->fieldscount; ++i) {
2379 fieldinfo *fi = c->fields + i;
2381 /* It's ok if we lose bits here */
2382 index = ((((size_t) fi->name) +
2383 ((size_t) fi->descriptor)) >> shift) % hashlen;
2385 if ((old = hashtab[index])) {
2389 if (c->fields[old].name == fi->name &&
2390 c->fields[old].descriptor == fi->descriptor) {
2391 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
2392 goto return_exception;
2394 } while ((old = next[old]));
2396 hashtab[index] = i + 1;
2400 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2402 for (i = 0; i < c->methodscount; ++i) {
2403 methodinfo *mi = c->methods + i;
2405 /* It's ok if we lose bits here */
2406 index = ((((size_t) mi->name) +
2407 ((size_t) mi->descriptor)) >> shift) % hashlen;
2411 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2412 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2416 if ((old = hashtab[index])) {
2420 if (c->methods[old].name == mi->name &&
2421 c->methods[old].descriptor == mi->descriptor) {
2422 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
2423 goto return_exception;
2425 } while ((old = next[old]));
2427 hashtab[index] = i + 1;
2430 MFREE(hashtab, u2, (hashlen + len));
2432 #endif /* ENABLE_VERIFIER */
2434 RT_TIMING_GET_TIME(time_verify);
2436 #if defined(ENABLE_STATISTICS)
2438 size_classinfo += sizeof(classinfo*) * c->interfacescount;
2439 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
2440 size_methodinfo += sizeof(methodinfo) * c->methodscount;
2444 /* load attribute structures */
2446 if (!class_load_attributes(cb))
2447 goto return_exception;
2449 /* Pre Java 1.5 version don't check this. This implementation is like
2450 Java 1.5 do it: for class file version 45.3 we don't check it, older
2451 versions are checked.
2454 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
2455 /* check if all data has been read */
2456 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
2458 if (classdata_left > 0) {
2459 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
2460 goto return_exception;
2464 RT_TIMING_GET_TIME(time_attrs);
2466 /* release dump area */
2468 dump_release(dumpsize);
2470 /* revert loading state and class is loaded */
2472 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2474 #if defined(ENABLE_JVMTI)
2475 /* fire Class Prepare JVMTI event */
2478 jvmti_ClassLoadPrepare(true, c);
2481 #if !defined(NDEBUG)
2483 log_message_class("Loading done class: ", c);
2486 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
2487 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
2488 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
2489 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
2490 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
2491 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
2492 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
2493 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
2494 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
2495 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
2496 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
2497 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
2498 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
2499 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
2500 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
2505 /* release dump area */
2507 dump_release(dumpsize);
2509 /* an exception has been thrown */
2515 /* load_newly_created_array ****************************************************
2517 Load a newly created array class.
2520 c....................the array class C has been loaded
2521 other classinfo......the array class was found in the class cache,
2523 NULL.................an exception has been thrown
2526 This is an internal function. Do not use it unless you know exactly
2529 Use one of the load_class_... functions for general array class loading.
2531 *******************************************************************************/
2533 classinfo *load_newly_created_array(classinfo *c, classloader *loader)
2535 classinfo *comp = NULL;
2537 methoddesc *clonedesc;
2538 constant_classref *classrefs;
2543 text = c->name->text;
2544 namelen = c->name->blength;
2546 /* Check array class name */
2548 if ((namelen < 2) || (text[0] != '[')) {
2549 exceptions_throw_noclassdeffounderror(c->name);
2553 /* Check the element type */
2557 /* c is an array of arrays. We have to create the component class. */
2559 u = utf_new(text + 1, namelen - 1);
2560 if (!(comp = load_class_from_classloader(u, loader)))
2563 assert(comp->state & CLASS_LOADED);
2569 /* the array's flags are that of the component class */
2570 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2571 c->classloader = comp->classloader;
2575 /* c is an array of objects. */
2577 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2578 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2579 exceptions_throw_noclassdeffounderror(c->name);
2583 u = utf_new(text + 2, namelen - 3);
2585 if (!(comp = load_class_from_classloader(u, loader)))
2588 assert(comp->state & CLASS_LOADED);
2594 /* the array's flags are that of the component class */
2595 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2596 c->classloader = comp->classloader;
2600 /* c is an array of a primitive type */
2602 /* check for cases like `[II' */
2604 exceptions_throw_noclassdeffounderror(c->name);
2608 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2609 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2610 c->classloader = NULL;
2613 assert(class_java_lang_Object);
2614 #if defined(ENABLE_JAVASE)
2615 assert(class_java_lang_Cloneable);
2616 assert(class_java_io_Serializable);
2619 /* setup the array class */
2621 c->super.cls = class_java_lang_Object;
2623 #if defined(ENABLE_JAVASE)
2624 c->interfacescount = 2;
2625 c->interfaces = MNEW(classref_or_classinfo, 2);
2630 tc = class_java_lang_Cloneable;
2631 assert(tc->state & CLASS_LOADED);
2632 list_add_first(&unlinkedclasses, tc);
2633 c->interfaces[0].cls = tc;
2635 tc = class_java_io_Serializable;
2636 assert(tc->state & CLASS_LOADED);
2637 list_add_first(&unlinkedclasses, tc);
2638 c->interfaces[1].cls = tc;
2641 c->interfaces[0].cls = class_java_lang_Cloneable;
2642 c->interfaces[1].cls = class_java_io_Serializable;
2644 #elif defined(ENABLE_JAVAME_CLDC1_1)
2645 c->interfacescount = 0;
2646 c->interfaces = NULL;
2648 #error unknow Java configuration
2651 c->methodscount = 1;
2652 c->methods = MNEW(methodinfo, c->methodscount);
2653 MZERO(c->methods, methodinfo, c->methodscount);
2655 classrefs = MNEW(constant_classref, 2);
2656 CLASSREF_INIT(classrefs[0], c, c->name);
2657 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2659 /* create descriptor for clone method */
2660 /* we need one paramslot which is reserved for the 'this' parameter */
2661 clonedesc = NEW(methoddesc);
2662 clonedesc->returntype.type = TYPE_ADR;
2663 clonedesc->returntype.classref = classrefs + 1;
2664 clonedesc->returntype.arraydim = 0;
2665 /* initialize params to "empty", add real params below in
2666 descriptor_params_from_paramtypes */
2667 clonedesc->paramcount = 0;
2668 clonedesc->paramslots = 0;
2669 clonedesc->paramtypes[0].classref = classrefs + 0;
2670 clonedesc->params = NULL;
2672 /* create methodinfo */
2675 MSET(clone, 0, methodinfo, 1);
2677 /* ATTENTION: if you delete the ACC_NATIVE below, set
2678 clone->maxlocals=1 (interpreter related) */
2680 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2681 clone->name = utf_clone;
2682 clone->descriptor = utf_void__java_lang_Object;
2683 clone->parseddesc = clonedesc;
2686 /* parse the descriptor to get the register allocation */
2688 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2691 clone->code = codegen_createnativestub(BUILTIN_clone, clone);
2693 /* XXX: field: length? */
2695 /* array classes are not loaded from class files */
2697 c->state |= CLASS_LOADED;
2698 c->parseddescs = (u1 *) clonedesc;
2699 c->parseddescsize = sizeof(methodinfo);
2700 c->classrefs = classrefs;
2701 c->classrefcount = 1;
2703 /* insert class into the loaded class cache */
2704 /* XXX free classinfo if NULL returned? */
2706 return classcache_store(loader, c, true);
2710 /* loader_close ****************************************************************
2712 Frees all resources.
2714 *******************************************************************************/
2716 void loader_close(void)
2723 * These are local overrides for various environment variables in Emacs.
2724 * Please do not remove this and leave it at the end of the file, where
2725 * Emacs will automagically detect them.
2726 * ---------------------------------------------------------------------
2729 * indent-tabs-mode: t
2733 * vim:noexpandtab:sw=4:ts=4: