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
36 #include "mm/memory.h"
38 #include "native/llni.h"
40 #include "threads/lock-common.h"
42 #include "toolbox/hashtable.h"
43 #include "toolbox/logging.h"
45 #include "vm/builtin.h"
46 #include "vm/exceptions.h"
47 #include "vm/global.h"
48 #include "vm/primitive.h"
49 #include "vm/resolve.h"
50 #include "vm/stringlocal.h"
53 #include "vm/jit_interface.h"
55 #if defined(ENABLE_JAVASE)
56 # include "vmcore/annotation.h"
57 # include "vmcore/stackmap.h"
60 #include "vmcore/classcache.h"
61 #include "vmcore/field.h"
62 #include "vmcore/linker.h"
63 #include "vmcore/loader.h"
64 #include "vmcore/method.h"
65 #include "vmcore/options.h"
66 #include "vmcore/rt-timing.h"
68 #if defined(ENABLE_STATISTICS)
69 # include "vmcore/statistics.h"
72 #include "vmcore/suck.h"
74 #if defined(ENABLE_ZLIB)
75 # include "vmcore/zip.h"
78 #if defined(ENABLE_JVMTI)
79 # include "native/jvmti/cacaodbg.h"
83 /* global variables ***********************************************************/
85 static hashtable *hashtable_classloader;
88 /* loader_preinit **************************************************************
90 Initializes the classpath list and loads classes required for the
93 *******************************************************************************/
95 void loader_preinit(void)
97 #if defined(ENABLE_THREADS)
98 list_classpath_entry *lce;
100 /* Initialize the monitor pointer for zip/jar file locking. */
102 for (lce = list_first(list_classpath_entries); lce != NULL;
103 lce = list_next(list_classpath_entries, lce)) {
104 if (lce->type == CLASSPATH_ARCHIVE)
105 LOCK_INIT_OBJECT_LOCK(lce);
109 /* initialize classloader hashtable, 10 entries should be enough */
111 hashtable_classloader = NEW(hashtable);
112 hashtable_create(hashtable_classloader, 10);
114 /* Load the most basic class. */
116 if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
117 vm_abort("loader_preinit: loading java/lang/Object failed");
119 #if defined(ENABLE_JAVASE)
120 if (!(class_java_lang_Cloneable =
121 load_class_bootstrap(utf_java_lang_Cloneable)))
122 vm_abort("loader_preinit: loading java/lang/Cloneable failed");
124 if (!(class_java_io_Serializable =
125 load_class_bootstrap(utf_java_io_Serializable)))
126 vm_abort("loader_preinit: loading java/io/Serializable failed");
131 /* loader_init *****************************************************************
133 Loads all classes required in the VM.
135 *******************************************************************************/
137 void loader_init(void)
139 /* Load primitive-type wrapping classes. */
141 #if defined(ENABLE_JAVASE)
142 if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
143 vm_abort("loader_init: loading failed");
146 if (!(class_java_lang_Boolean =
147 load_class_bootstrap(utf_java_lang_Boolean)))
148 vm_abort("loader_init: loading failed");
150 if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
151 vm_abort("loader_init: loading failed");
153 if (!(class_java_lang_Character =
154 load_class_bootstrap(utf_java_lang_Character)))
155 vm_abort("loader_init: loading failed");
157 if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
158 vm_abort("loader_init: loading failed");
160 if (!(class_java_lang_Integer =
161 load_class_bootstrap(utf_java_lang_Integer)))
162 vm_abort("loader_init: loading failed");
164 if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
165 vm_abort("loader_init: loading failed");
167 if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
168 vm_abort("loader_init: loading failed");
170 if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
171 vm_abort("loader_init: loading failed");
173 /* Load important system classes. */
175 if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
176 vm_abort("loader_init: loading failed");
178 if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
179 vm_abort("loader_init: loading failed");
181 #if defined(ENABLE_JAVASE)
182 if (!(class_java_lang_ClassLoader =
183 load_class_bootstrap(utf_java_lang_ClassLoader)))
184 vm_abort("loader_init: loading failed");
186 if (!(class_java_lang_SecurityManager =
187 load_class_bootstrap(utf_java_lang_SecurityManager)))
188 vm_abort("loader_init: loading failed");
191 if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
192 vm_abort("loader_init: loading failed");
194 if (!(class_java_lang_Thread =
195 load_class_bootstrap(utf_new_char("java/lang/Thread"))))
196 vm_abort("loader_init: loading failed");
198 #if defined(ENABLE_JAVASE)
199 if (!(class_java_lang_ThreadGroup =
200 load_class_bootstrap(utf_java_lang_ThreadGroup)))
201 vm_abort("loader_init: loading failed");
204 #if defined(WITH_CLASSPATH_GNU)
205 if (!(class_java_lang_VMSystem =
206 load_class_bootstrap(utf_new_char("java/lang/VMSystem"))))
207 vm_abort("loader_init: loading failed");
209 if (!(class_java_lang_VMThread =
210 load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
211 vm_abort("loader_init: loading failed");
215 /* some classes which may be used more often */
217 #if defined(ENABLE_JAVASE)
218 if (!(class_java_lang_StackTraceElement =
219 load_class_bootstrap(utf_java_lang_StackTraceElement)))
220 vm_abort("loader_init: loading failed");
222 if (!(class_java_lang_reflect_Constructor =
223 load_class_bootstrap(utf_java_lang_reflect_Constructor)))
224 vm_abort("loader_init: loading failed");
226 if (!(class_java_lang_reflect_Field =
227 load_class_bootstrap(utf_java_lang_reflect_Field)))
228 vm_abort("loader_init: loading failed");
230 if (!(class_java_lang_reflect_Method =
231 load_class_bootstrap(utf_java_lang_reflect_Method)))
232 vm_abort("loader_init: loading failed");
234 if (!(class_java_security_PrivilegedAction =
235 load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
236 vm_abort("loader_init: loading failed");
238 if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
239 vm_abort("loader_init: loading failed");
241 # if defined(WITH_CLASSPATH_SUN)
242 if (!(class_sun_reflect_MagicAccessorImpl =
243 load_class_bootstrap(utf_new_char("sun/reflect/MagicAccessorImpl"))))
244 vm_abort("loader_init: loading failed");
247 if (!(arrayclass_java_lang_Object =
248 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
249 vm_abort("loader_init: loading failed");
251 # if defined(ENABLE_ANNOTATIONS)
252 /* needed by annotation support */
253 if (!(class_sun_reflect_ConstantPool =
254 load_class_bootstrap(utf_new_char("sun/reflect/ConstantPool"))))
255 vm_abort("loader_init: loading failed");
257 # if defined(WITH_CLASSPATH_GNU)
258 /* needed by GNU Classpaths annotation support */
259 if (!(class_sun_reflect_annotation_AnnotationParser =
260 load_class_bootstrap(utf_new_char("sun/reflect/annotation/AnnotationParser"))))
261 vm_abort("loader_init: loading failed");
268 /* loader_hashtable_classloader_add ********************************************
270 Adds an entry to the classloader hashtable.
272 REMEMBER: Also use this to register native loaders!
274 *******************************************************************************/
276 classloader *loader_hashtable_classloader_add(java_handle_t *cl)
278 hashtable_classloader_entry *cle;
285 LOCK_MONITOR_ENTER(hashtable_classloader->header);
289 /* key for entry is the hashcode of the classloader;
290 aligned to 16-byte boundaries */
292 #if defined(ENABLE_GC_CACAO)
293 key = heap_get_hashcode(LLNI_DIRECT(cl)) >> 4;
295 key = ((u4) (ptrint) cl) >> 4;
298 slot = key & (hashtable_classloader->size - 1);
299 cle = hashtable_classloader->ptr[slot];
301 /* search hashchain for existing entry */
304 if (cle->object == LLNI_DIRECT(cl))
312 /* if no classloader was found, we create a new entry here */
315 cle = NEW(hashtable_classloader_entry);
317 #if defined(ENABLE_GC_CACAO)
318 /* register the classloader object with the GC */
320 gc_reference_register(&(cle->object), GC_REFTYPE_CLASSLOADER);
325 cle->object = LLNI_DIRECT(cl);
329 /* insert entry into hashtable */
331 cle->hashlink = hashtable_classloader->ptr[slot];
332 hashtable_classloader->ptr[slot] = cle;
334 /* update number of entries */
336 hashtable_classloader->entries++;
340 LOCK_MONITOR_EXIT(hashtable_classloader->header);
346 /* loader_hashtable_classloader_find *******************************************
348 Find an entry in the classloader hashtable.
350 *******************************************************************************/
352 classloader *loader_hashtable_classloader_find(java_handle_t *cl)
354 hashtable_classloader_entry *cle;
363 /* key for entry is the hashcode of the classloader;
364 aligned to 16-byte boundaries */
366 #if defined(ENABLE_GC_CACAO)
367 key = heap_get_hashcode(LLNI_DIRECT(cl)) >> 4;
369 key = ((u4) (ptrint) cl) >> 4;
372 slot = key & (hashtable_classloader->size - 1);
373 cle = hashtable_classloader->ptr[slot];
375 /* search hashchain for existing entry */
378 if (cle->object == LLNI_DIRECT(cl))
390 /* loader_load_all_classes *****************************************************
392 Loads all classes specified in the BOOTCLASSPATH.
394 *******************************************************************************/
396 void loader_load_all_classes(void)
398 list_classpath_entry *lce;
399 #if defined(ENABLE_ZLIB)
402 hashtable_zipfile_entry *htzfe;
406 for (lce = list_first(list_classpath_entries); lce != NULL;
407 lce = list_next(list_classpath_entries, lce)) {
408 #if defined(ENABLE_ZLIB)
409 if (lce->type == CLASSPATH_ARCHIVE) {
410 /* get the classes hashtable */
414 for (slot = 0; slot < ht->size; slot++) {
415 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
417 for (; htzfe; htzfe = htzfe->hashlink) {
420 /* skip all entries in META-INF and .properties,
423 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
424 strstr(u->text, ".properties") ||
425 strstr(u->text, ".png"))
428 /* load class from bootstrap classloader */
430 if (!load_class_bootstrap(u)) {
431 fprintf(stderr, "Error loading: ");
432 utf_fprint_printable_ascii_classname(stderr, u);
433 fprintf(stderr, "\n");
436 /* print out exception and cause */
438 exceptions_print_current_exception();
446 #if defined(ENABLE_ZLIB)
453 /* loader_skip_attribute_body **************************************************
455 Skips an attribute the attribute_name_index has already been read.
458 u2 attribute_name_index;
460 u1 info[attribute_length];
463 *******************************************************************************/
465 bool loader_skip_attribute_body(classbuffer *cb)
469 if (!suck_check_classbuffer_size(cb, 4))
472 attribute_length = suck_u4(cb);
474 if (!suck_check_classbuffer_size(cb, attribute_length))
477 suck_skip_nbytes(cb, attribute_length);
483 /* load_constantpool ***********************************************************
485 Loads the constantpool of a class, the entries are transformed into
486 a simpler format by resolving references (a detailed overview of
487 the compact structures can be found in global.h).
489 *******************************************************************************/
491 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
494 /* The following structures are used to save information which cannot be
495 processed during the first pass. After the complete constantpool has
496 been traversed the references can be resolved.
497 (only in specific order) */
499 /* CONSTANT_Class entries */
500 typedef struct forward_class {
501 struct forward_class *next;
506 /* CONSTANT_String */
507 typedef struct forward_string {
508 struct forward_string *next;
513 /* CONSTANT_NameAndType */
514 typedef struct forward_nameandtype {
515 struct forward_nameandtype *next;
519 } forward_nameandtype;
521 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
522 typedef struct forward_fieldmethint {
523 struct forward_fieldmethint *next;
527 u2 nameandtype_index;
528 } forward_fieldmethint;
534 forward_class *forward_classes = NULL;
535 forward_string *forward_strings = NULL;
536 forward_nameandtype *forward_nameandtypes = NULL;
537 forward_fieldmethint *forward_fieldmethints = NULL;
541 forward_nameandtype *nfn;
542 forward_fieldmethint *nff;
550 /* number of entries in the constant_pool table plus one */
551 if (!suck_check_classbuffer_size(cb, 2))
554 cpcount = c->cpcount = suck_u2(cb);
556 /* allocate memory */
557 cptags = c->cptags = MNEW(u1, cpcount);
558 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
561 exceptions_throw_classformaterror(c, "Illegal constant pool size");
565 #if defined(ENABLE_STATISTICS)
567 count_const_pool_len += (sizeof(u1) + sizeof(voidptr)) * cpcount;
570 /* initialize constantpool */
571 for (idx = 0; idx < cpcount; idx++) {
572 cptags[idx] = CONSTANT_UNUSED;
577 /******* first pass *******/
578 /* entries which cannot be resolved now are written into
579 temporary structures and traversed again later */
582 while (idx < cpcount) {
585 /* get constant type */
586 if (!suck_check_classbuffer_size(cb, 1))
593 nfc = DNEW(forward_class);
595 nfc->next = forward_classes;
596 forward_classes = nfc;
598 nfc->thisindex = idx;
599 /* reference to CONSTANT_NameAndType */
600 if (!suck_check_classbuffer_size(cb, 2))
603 nfc->name_index = suck_u2(cb);
608 case CONSTANT_String:
609 nfs = DNEW(forward_string);
611 nfs->next = forward_strings;
612 forward_strings = nfs;
614 nfs->thisindex = idx;
616 /* reference to CONSTANT_Utf8_info with string characters */
617 if (!suck_check_classbuffer_size(cb, 2))
620 nfs->string_index = suck_u2(cb);
625 case CONSTANT_NameAndType:
626 nfn = DNEW(forward_nameandtype);
628 nfn->next = forward_nameandtypes;
629 forward_nameandtypes = nfn;
631 nfn->thisindex = idx;
633 if (!suck_check_classbuffer_size(cb, 2 + 2))
636 /* reference to CONSTANT_Utf8_info containing simple name */
637 nfn->name_index = suck_u2(cb);
639 /* reference to CONSTANT_Utf8_info containing field or method
641 nfn->sig_index = suck_u2(cb);
646 case CONSTANT_Fieldref:
647 case CONSTANT_Methodref:
648 case CONSTANT_InterfaceMethodref:
649 nff = DNEW(forward_fieldmethint);
651 nff->next = forward_fieldmethints;
652 forward_fieldmethints = nff;
654 nff->thisindex = idx;
658 if (!suck_check_classbuffer_size(cb, 2 + 2))
661 /* class or interface type that contains the declaration of the
663 nff->class_index = suck_u2(cb);
665 /* name and descriptor of the field or method */
666 nff->nameandtype_index = suck_u2(cb);
671 case CONSTANT_Integer: {
672 constant_integer *ci = NEW(constant_integer);
674 #if defined(ENABLE_STATISTICS)
676 count_const_pool_len += sizeof(constant_integer);
679 if (!suck_check_classbuffer_size(cb, 4))
682 ci->value = suck_s4(cb);
683 cptags[idx] = CONSTANT_Integer;
690 case CONSTANT_Float: {
691 constant_float *cf = NEW(constant_float);
693 #if defined(ENABLE_STATISTICS)
695 count_const_pool_len += sizeof(constant_float);
698 if (!suck_check_classbuffer_size(cb, 4))
701 cf->value = suck_float(cb);
702 cptags[idx] = CONSTANT_Float;
709 case CONSTANT_Long: {
710 constant_long *cl = NEW(constant_long);
712 #if defined(ENABLE_STATISTICS)
714 count_const_pool_len += sizeof(constant_long);
717 if (!suck_check_classbuffer_size(cb, 8))
720 cl->value = suck_s8(cb);
721 cptags[idx] = CONSTANT_Long;
725 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
731 case CONSTANT_Double: {
732 constant_double *cd = NEW(constant_double);
734 #if defined(ENABLE_STATISTICS)
736 count_const_pool_len += sizeof(constant_double);
739 if (!suck_check_classbuffer_size(cb, 8))
742 cd->value = suck_double(cb);
743 cptags[idx] = CONSTANT_Double;
747 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
753 case CONSTANT_Utf8: {
756 /* number of bytes in the bytes array (not string-length) */
757 if (!suck_check_classbuffer_size(cb, 2))
760 length = suck_u2(cb);
761 cptags[idx] = CONSTANT_Utf8;
763 /* validate the string */
764 if (!suck_check_classbuffer_size(cb, length))
767 #ifdef ENABLE_VERIFIER
769 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
771 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
774 #endif /* ENABLE_VERIFIER */
775 /* insert utf-string into the utf-symboltable */
776 cpinfos[idx] = utf_new((char *) cb->pos, length);
778 /* skip bytes of the string (buffer size check above) */
779 suck_skip_nbytes(cb, length);
785 exceptions_throw_classformaterror(c, "Illegal constant pool type");
791 /* resolve entries in temporary structures */
793 while (forward_classes) {
795 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
799 #ifdef ENABLE_VERIFIER
800 if (opt_verify && !is_valid_name_utf(name)) {
801 exceptions_throw_classformaterror(c, "Class reference with invalid name");
804 #endif /* ENABLE_VERIFIER */
806 /* add all class references to the descriptor_pool */
808 if (!descriptor_pool_add_class(descpool, name))
811 cptags[forward_classes->thisindex] = CONSTANT_Class;
813 /* the classref is created later */
814 cpinfos[forward_classes->thisindex] = name;
816 nfc = forward_classes;
817 forward_classes = forward_classes->next;
820 while (forward_strings) {
822 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
826 /* resolve utf-string */
827 cptags[forward_strings->thisindex] = CONSTANT_String;
828 cpinfos[forward_strings->thisindex] = text;
830 nfs = forward_strings;
831 forward_strings = forward_strings->next;
834 while (forward_nameandtypes) {
835 constant_nameandtype *cn = NEW(constant_nameandtype);
837 #if defined(ENABLE_STATISTICS)
839 count_const_pool_len += sizeof(constant_nameandtype);
842 /* resolve simple name and descriptor */
843 cn->name = class_getconstant(c,
844 forward_nameandtypes->name_index,
849 cn->descriptor = class_getconstant(c,
850 forward_nameandtypes->sig_index,
855 #ifdef ENABLE_VERIFIER
858 if (!is_valid_name_utf(cn->name)) {
859 exceptions_throw_classformaterror(c,
860 "Illegal Field name \"%s\"",
866 /* disallow referencing <clinit> among others */
867 if (cn->name->text[0] == '<' && cn->name != utf_init) {
868 exceptions_throw_classformaterror(c, "Illegal reference to special method");
872 #endif /* ENABLE_VERIFIER */
874 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
875 cpinfos[forward_nameandtypes->thisindex] = cn;
877 nfn = forward_nameandtypes;
878 forward_nameandtypes = forward_nameandtypes->next;
881 while (forward_fieldmethints) {
882 constant_nameandtype *nat;
883 constant_FMIref *fmi = NEW(constant_FMIref);
885 #if defined(ENABLE_STATISTICS)
887 count_const_pool_len += sizeof(constant_FMIref);
889 /* resolve simple name and descriptor */
891 nat = class_getconstant(c,
892 forward_fieldmethints->nameandtype_index,
893 CONSTANT_NameAndType);
897 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
899 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
902 /* the classref is created later */
904 fmi->p.index = forward_fieldmethints->class_index;
905 fmi->name = nat->name;
906 fmi->descriptor = nat->descriptor;
908 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
909 cpinfos[forward_fieldmethints->thisindex] = fmi;
911 nff = forward_fieldmethints;
912 forward_fieldmethints = forward_fieldmethints->next;
915 /* everything was ok */
921 /* loader_load_attribute_signature *********************************************
923 Signature_attribute {
924 u2 attribute_name_index;
929 *******************************************************************************/
931 #if defined(ENABLE_JAVASE)
932 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
942 /* check remaining bytecode */
944 if (!suck_check_classbuffer_size(cb, 4 + 2))
947 /* check attribute length */
949 attribute_length = suck_u4(cb);
951 if (attribute_length != 2) {
952 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
956 if (*signature != NULL) {
957 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
963 signature_index = suck_u2(cb);
965 if (!(*signature = class_getconstant(c, signature_index, CONSTANT_Utf8)))
970 #endif /* defined(ENABLE_JAVASE) */
973 /* load_class_from_sysloader ***************************************************
975 Load the class with the given name using the system class loader
978 name.............the classname
982 NULL if an exception has been thrown
984 *******************************************************************************/
986 classinfo *load_class_from_sysloader(utf *name)
993 assert(class_java_lang_Object);
994 assert(class_java_lang_ClassLoader);
995 assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
997 m = class_resolveclassmethod(class_java_lang_ClassLoader,
998 utf_getSystemClassLoader,
999 utf_void__java_lang_ClassLoader,
1000 class_java_lang_Object,
1006 clo = vm_call_method(m, NULL);
1011 cl = loader_hashtable_classloader_add(clo);
1013 c = load_class_from_classloader(name, cl);
1019 /* load_class_from_classloader *************************************************
1021 Load the class with the given name using the given user-defined class loader.
1024 name.............the classname
1025 cl...............user-defined class loader
1028 the loaded class, or
1029 NULL if an exception has been thrown
1031 *******************************************************************************/
1033 classinfo *load_class_from_classloader(utf *name, classloader *cl)
1038 java_handle_t *string;
1039 #if defined(ENABLE_RT_TIMING)
1040 struct timespec time_start, time_lookup, time_prepare, time_java,
1044 RT_TIMING_GET_TIME(time_start);
1048 /* lookup if this class has already been loaded */
1050 c = classcache_lookup(cl, name);
1052 RT_TIMING_GET_TIME(time_lookup);
1053 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1058 /* if other class loader than bootstrap, call it */
1066 namelen = name->blength;
1068 /* handle array classes */
1069 if (text[0] == '[') {
1075 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1076 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1077 exceptions_throw_classnotfoundexception(name);
1081 u = utf_new(text + 2, namelen - 3);
1083 if (!(comp = load_class_from_classloader(u, cl)))
1086 /* create the array class */
1088 c = class_array_of(comp, false);
1090 tmpc = classcache_store(cl, c, true);
1093 /* exception, free the loaded class */
1094 c->state &= ~CLASS_LOADING;
1101 /* load the component class */
1103 u = utf_new(text + 1, namelen - 1);
1105 if (!(comp = load_class_from_classloader(u, cl)))
1108 /* create the array class */
1110 c = class_array_of(comp, false);
1112 tmpc = classcache_store(cl, c, true);
1115 /* exception, free the loaded class */
1116 c->state &= ~CLASS_LOADING;
1123 /* primitive array classes are loaded by the bootstrap loader */
1125 c = load_class_bootstrap(name);
1131 #if defined(WITH_CLASSPATH_SUN)
1132 /* OpenJDK uses this internal function because it's
1135 lc = class_resolveclassmethod(cl->object->vftbl->class,
1136 utf_loadClassInternal,
1137 utf_java_lang_String__java_lang_Class,
1141 lc = class_resolveclassmethod(cl->object->vftbl->class,
1143 utf_java_lang_String__java_lang_Class,
1149 return false; /* exception */
1151 /* move return value into `o' and cast it afterwards to a classinfo* */
1153 string = javastring_new_slash_to_dot(name);
1155 RT_TIMING_GET_TIME(time_prepare);
1157 #if defined(ENABLE_HANDLES)
1158 o = vm_call_method(lc, (java_handle_t *) cl, string);
1160 o = vm_call_method(lc, cl->object, string);
1163 RT_TIMING_GET_TIME(time_java);
1165 c = LLNI_classinfo_unwrap(o);
1168 /* Store this class in the loaded class cache. If another
1169 class with the same (initloader,name) pair has been
1170 stored earlier it will be returned by classcache_store
1171 In this case classcache_store may not free the class
1172 because it has already been exposed to Java code which
1173 may have kept references to that class. */
1175 tmpc = classcache_store(cl, c, false);
1178 /* exception, free the loaded class */
1179 c->state &= ~CLASS_LOADING;
1186 RT_TIMING_GET_TIME(time_cache);
1188 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1189 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1190 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1192 /* SUN compatible -verbose:class output */
1194 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1196 utf_display_printable_ascii_classname(name);
1200 #if defined(ENABLE_JVMTI)
1201 /* fire Class Load JVMTI event */
1202 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1209 c = load_class_bootstrap(name);
1215 /* load_class_bootstrap ********************************************************
1217 Load the class with the given name using the bootstrap class loader.
1220 name.............the classname
1223 loaded classinfo, or
1224 NULL if an exception has been thrown
1227 load_class_bootstrap is synchronized. It can be treated as an
1230 *******************************************************************************/
1232 classinfo *load_class_bootstrap(utf *name)
1237 #if defined(ENABLE_RT_TIMING)
1238 struct timespec time_start, time_lookup, time_array, time_suck,
1239 time_load, time_cache;
1242 RT_TIMING_GET_TIME(time_start);
1248 /* lookup if this class has already been loaded */
1250 r = classcache_lookup(NULL, name);
1253 RT_TIMING_GET_TIME(time_lookup);
1254 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1259 RT_TIMING_GET_TIME(time_lookup);
1260 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1262 /* create the classinfo */
1264 c = class_create_classinfo(name);
1266 /* handle array classes */
1268 if (name->text[0] == '[') {
1269 c = load_newly_created_array(c, NULL);
1274 assert(c->state & CLASS_LOADED);
1276 RT_TIMING_GET_TIME(time_array);
1277 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1282 #if defined(ENABLE_STATISTICS)
1285 if (opt_getcompilingtime)
1286 compilingtime_stop();
1288 if (opt_getloadingtime)
1289 loadingtime_start();
1292 /* load classdata, throw exception on error */
1297 /* this normally means, the classpath was not set properly */
1299 if (name == utf_java_lang_Object)
1300 vm_abort("java/lang/NoClassDefFoundError: java/lang/Object");
1302 exceptions_throw_classnotfoundexception(name);
1307 RT_TIMING_GET_TIME(time_suck);
1309 /* load the class from the buffer */
1311 r = load_class_from_classbuffer(cb);
1313 RT_TIMING_GET_TIME(time_load);
1316 /* the class could not be loaded, free the classinfo struct */
1321 /* Store this class in the loaded class cache this step also
1322 checks the loading constraints. If the class has been loaded
1323 before, the earlier loaded class is returned. */
1325 classinfo *res = classcache_store(NULL, c, true);
1335 RT_TIMING_GET_TIME(time_cache);
1337 /* SUN compatible -verbose:class output */
1339 if (opt_verboseclass && r) {
1341 utf_display_printable_ascii_classname(name);
1342 printf(" from %s]\n", cb->path);
1349 #if defined(ENABLE_STATISTICS)
1352 if (opt_getloadingtime)
1355 if (opt_getcompilingtime)
1356 compilingtime_start();
1359 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1360 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1361 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1362 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1368 /* load_class_from_classbuffer_intern ******************************************
1370 Loads a class from a classbuffer into a given classinfo structure.
1371 Super-classes are also loaded at this point and some verfication
1375 This function is NOT synchronized!
1377 *******************************************************************************/
1379 static bool load_class_from_classbuffer_intern(classbuffer *cb)
1385 utf **interfacesnames;
1387 constant_classref *cr;
1392 descriptor_pool *descpool;
1393 #if defined(ENABLE_STATISTICS)
1397 #if defined(ENABLE_RT_TIMING)
1398 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1399 time_setup, time_fields, time_methods, time_classrefs,
1400 time_descs, time_setrefs, time_parsefds, time_parsemds,
1401 time_parsecpool, time_verify, time_attrs;
1404 RT_TIMING_GET_TIME(time_start);
1406 /* Get the classbuffer's class. */
1410 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1413 /* check signature */
1415 if (suck_u4(cb) != MAGIC) {
1416 exceptions_throw_classformaterror(c, "Bad magic number");
1425 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1426 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1430 RT_TIMING_GET_TIME(time_checks);
1432 /* create a new descriptor pool */
1434 descpool = descriptor_pool_new(c);
1436 RT_TIMING_GET_TIME(time_ndpool);
1438 /* load the constant pool */
1440 if (!load_constantpool(cb, descpool))
1443 RT_TIMING_GET_TIME(time_cpool);
1447 if (!suck_check_classbuffer_size(cb, 2))
1450 /* We OR the flags here, as we set already some flags in
1451 class_create_classinfo. */
1453 c->flags |= suck_u2(cb);
1455 /* check ACC flags consistency */
1457 if (c->flags & ACC_INTERFACE) {
1458 if (!(c->flags & ACC_ABSTRACT)) {
1459 /* We work around this because interfaces in JDK 1.1 are
1460 * not declared abstract. */
1462 c->flags |= ACC_ABSTRACT;
1465 if (c->flags & ACC_FINAL) {
1466 exceptions_throw_classformaterror(c,
1467 "Illegal class modifiers: 0x%X",
1472 if (c->flags & ACC_SUPER) {
1473 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1477 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1478 exceptions_throw_classformaterror(c,
1479 "Illegal class modifiers: 0x%X",
1484 if (!suck_check_classbuffer_size(cb, 2 + 2))
1489 index = suck_u2(cb);
1491 name = (utf *) class_getconstant(c, index, CONSTANT_Class);
1496 if (c->name == utf_not_named_yet) {
1497 /* we finally have a name for this class */
1499 class_set_packagename(c);
1501 else if (name != c->name) {
1502 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
1506 /* Retrieve superclass. */
1510 index = suck_u2(cb);
1515 /* This is only allowed for java.lang.Object. */
1517 if (c->name != utf_java_lang_Object) {
1518 exceptions_throw_classformaterror(c, "Bad superclass index");
1523 supername = (utf *) class_getconstant(c, index, CONSTANT_Class);
1525 if (supername == NULL)
1528 /* java.lang.Object may not have a super class. */
1530 if (c->name == utf_java_lang_Object) {
1531 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
1535 /* Detect circularity. */
1537 if (supername == c->name) {
1538 exceptions_throw_classcircularityerror(c);
1542 /* Interfaces must have java.lang.Object as super class. */
1544 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
1545 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
1550 /* Parse the super interfaces. */
1552 if (!suck_check_classbuffer_size(cb, 2))
1555 c->interfacescount = suck_u2(cb);
1557 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1560 c->interfaces = MNEW(classinfo*, c->interfacescount);
1562 /* Get the names of the super interfaces. */
1564 interfacesnames = DMNEW(utf*, c->interfacescount);
1566 for (i = 0; i < c->interfacescount; i++) {
1567 index = suck_u2(cb);
1569 u = (utf *) class_getconstant(c, index, CONSTANT_Class);
1574 interfacesnames[i] = u;
1577 RT_TIMING_GET_TIME(time_setup);
1581 if (!suck_check_classbuffer_size(cb, 2))
1584 c->fieldscount = suck_u2(cb);
1585 c->fields = MNEW(fieldinfo, c->fieldscount);
1587 MZERO(c->fields, fieldinfo, c->fieldscount);
1589 for (i = 0; i < c->fieldscount; i++) {
1590 if (!field_load(cb, &(c->fields[i]), descpool))
1594 RT_TIMING_GET_TIME(time_fields);
1596 /* Parse methods. */
1598 if (!suck_check_classbuffer_size(cb, 2))
1601 c->methodscount = suck_u2(cb);
1602 c->methods = MNEW(methodinfo, c->methodscount);
1604 MZERO(c->methods, methodinfo, c->methodscount);
1606 for (i = 0; i < c->methodscount; i++) {
1607 if (!method_load(cb, &(c->methods[i]), descpool))
1611 RT_TIMING_GET_TIME(time_methods);
1613 /* create the class reference table */
1616 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
1618 RT_TIMING_GET_TIME(time_classrefs);
1620 /* allocate space for the parsed descriptors */
1622 descriptor_pool_alloc_parsed_descriptors(descpool);
1624 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
1626 #if defined(ENABLE_STATISTICS)
1628 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
1629 count_classref_len += classrefsize;
1630 count_parsed_desc_len += descsize;
1634 RT_TIMING_GET_TIME(time_descs);
1636 /* put the classrefs in the constant pool */
1638 for (i = 0; i < c->cpcount; i++) {
1639 if (c->cptags[i] == CONSTANT_Class) {
1640 utf *name = (utf *) c->cpinfos[i];
1641 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
1645 /* Resolve the super class. */
1647 if (supername != NULL) {
1648 cr = descriptor_pool_lookup_classref(descpool, supername);
1653 /* XXX This should be done better. */
1654 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1659 /* Interfaces are not allowed as super classes. */
1661 if (tc->flags & ACC_INTERFACE) {
1662 exceptions_throw_incompatibleclasschangeerror(c, "class %s has interface %s as super class");
1666 /* Don't allow extending final classes */
1668 if (tc->flags & ACC_FINAL) {
1669 exceptions_throw_verifyerror(NULL,
1670 "Cannot inherit from final class");
1674 /* Store the super class. */
1679 /* Resolve the super interfaces. */
1681 for (i = 0; i < c->interfacescount; i++) {
1682 u = interfacesnames[i];
1683 cr = descriptor_pool_lookup_classref(descpool, u);
1688 /* XXX This should be done better. */
1689 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1694 /* Detect circularity. */
1697 exceptions_throw_classcircularityerror(c);
1701 if (!(tc->flags & ACC_INTERFACE)) {
1702 exceptions_throw_incompatibleclasschangeerror(tc,
1703 "Implementing class");
1707 /* Store the super interface. */
1709 c->interfaces[i] = tc;
1712 RT_TIMING_GET_TIME(time_setrefs);
1714 /* Parse the field descriptors. */
1716 for (i = 0; i < c->fieldscount; i++) {
1717 c->fields[i].parseddesc =
1718 descriptor_pool_parse_field_descriptor(descpool,
1719 c->fields[i].descriptor);
1720 if (!c->fields[i].parseddesc)
1724 RT_TIMING_GET_TIME(time_parsefds);
1726 /* parse method descriptors */
1728 for (i = 0; i < c->methodscount; i++) {
1729 methodinfo *m = &c->methods[i];
1731 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
1732 m->flags, class_get_self_classref(m->class));
1736 for (j = 0; j < m->rawexceptiontablelength; j++) {
1737 if (!m->rawexceptiontable[j].catchtype.any)
1740 if ((m->rawexceptiontable[j].catchtype.ref =
1741 descriptor_pool_lookup_classref(descpool,
1742 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
1746 for (j = 0; j < m->thrownexceptionscount; j++) {
1747 if (!m->thrownexceptions[j].any)
1750 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
1751 (utf *) m->thrownexceptions[j].any)) == NULL)
1756 RT_TIMING_GET_TIME(time_parsemds);
1758 /* parse the loaded descriptors */
1760 for (i = 0; i < c->cpcount; i++) {
1761 constant_FMIref *fmi;
1764 switch (c->cptags[i]) {
1765 case CONSTANT_Fieldref:
1766 fmi = (constant_FMIref *) c->cpinfos[i];
1767 fmi->parseddesc.fd =
1768 descriptor_pool_parse_field_descriptor(descpool,
1770 if (!fmi->parseddesc.fd)
1773 index = fmi->p.index;
1775 (constant_classref *) class_getconstant(c, index,
1777 if (!fmi->p.classref)
1780 case CONSTANT_Methodref:
1781 case CONSTANT_InterfaceMethodref:
1782 fmi = (constant_FMIref *) c->cpinfos[i];
1783 index = fmi->p.index;
1785 (constant_classref *) class_getconstant(c, index,
1787 if (!fmi->p.classref)
1789 fmi->parseddesc.md =
1790 descriptor_pool_parse_method_descriptor(descpool,
1794 if (!fmi->parseddesc.md)
1800 RT_TIMING_GET_TIME(time_parsecpool);
1802 #ifdef ENABLE_VERIFIER
1803 /* Check if all fields and methods can be uniquely
1804 * identified by (name,descriptor). */
1807 /* We use a hash table here to avoid making the
1808 * average case quadratic in # of methods, fields.
1810 static int shift = 0;
1812 u2 *next; /* for chaining colliding hash entries */
1818 /* Allocate hashtable */
1819 len = c->methodscount;
1820 if (len < c->fieldscount) len = c->fieldscount;
1822 hashtab = MNEW(u2,(hashlen + len));
1823 next = hashtab + hashlen;
1825 /* Determine bitshift (to get good hash values) */
1835 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
1837 for (i = 0; i < c->fieldscount; ++i) {
1838 fieldinfo *fi = c->fields + i;
1840 /* It's ok if we lose bits here */
1841 index = ((((size_t) fi->name) +
1842 ((size_t) fi->descriptor)) >> shift) % hashlen;
1844 if ((old = hashtab[index])) {
1848 if (c->fields[old].name == fi->name &&
1849 c->fields[old].descriptor == fi->descriptor) {
1850 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
1853 } while ((old = next[old]));
1855 hashtab[index] = i + 1;
1859 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
1861 for (i = 0; i < c->methodscount; ++i) {
1862 methodinfo *mi = c->methods + i;
1864 /* It's ok if we lose bits here */
1865 index = ((((size_t) mi->name) +
1866 ((size_t) mi->descriptor)) >> shift) % hashlen;
1868 if ((old = hashtab[index])) {
1872 if (c->methods[old].name == mi->name &&
1873 c->methods[old].descriptor == mi->descriptor) {
1874 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
1877 } while ((old = next[old]));
1879 hashtab[index] = i + 1;
1882 MFREE(hashtab, u2, (hashlen + len));
1884 #endif /* ENABLE_VERIFIER */
1886 RT_TIMING_GET_TIME(time_verify);
1888 #if defined(ENABLE_STATISTICS)
1890 size_classinfo += sizeof(classinfo*) * c->interfacescount;
1891 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
1892 size_methodinfo += sizeof(methodinfo) * c->methodscount;
1896 /* load attribute structures */
1898 if (!class_load_attributes(cb))
1901 /* Pre Java 1.5 version don't check this. This implementation is
1902 like Java 1.5 do it: for class file version 45.3 we don't check
1903 it, older versions are checked. */
1905 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
1906 /* check if all data has been read */
1907 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
1909 if (classdata_left > 0) {
1910 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
1915 RT_TIMING_GET_TIME(time_attrs);
1917 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
1918 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
1919 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
1920 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
1921 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
1922 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
1923 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
1924 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
1925 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
1926 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
1927 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
1928 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
1929 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
1930 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
1931 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
1937 /* load_class_from_classbuffer *************************************************
1939 Convenience wrapper for load_class_from_classbuffer.
1942 This function is NOT synchronized!
1944 *******************************************************************************/
1946 classinfo *load_class_from_classbuffer(classbuffer *cb)
1952 /* Get the classbuffer's class. */
1956 /* Check if the class is already loaded. */
1958 if (c->state & CLASS_LOADED)
1961 #if defined(ENABLE_STATISTICS)
1963 count_class_loads++;
1966 #if !defined(NDEBUG)
1968 log_message_class("Loading class: ", c);
1971 /* Mark start of dump memory area. */
1973 dumpsize = dump_size();
1975 /* Class is currently loading. */
1977 c->state |= CLASS_LOADING;
1979 /* Parse the classbuffer. */
1981 result = load_class_from_classbuffer_intern(cb);
1983 /* Release dump area. */
1985 dump_release(dumpsize);
1987 /* An error occurred. */
1989 if (result == false) {
1990 /* Revert loading state. */
1992 c->state = (c->state & ~CLASS_LOADING);
1997 /* Revert loading state and set loaded. */
1999 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2001 #if defined(ENABLE_JVMTI)
2002 /* fire Class Prepare JVMTI event */
2005 jvmti_ClassLoadPrepare(true, c);
2008 #if !defined(NDEBUG)
2010 log_message_class("Loading done class: ", c);
2017 /* load_newly_created_array ****************************************************
2019 Load a newly created array class.
2022 c....................the array class C has been loaded
2023 other classinfo......the array class was found in the class cache,
2025 NULL.................an exception has been thrown
2028 This is an internal function. Do not use it unless you know exactly
2031 Use one of the load_class_... functions for general array class loading.
2033 *******************************************************************************/
2035 classinfo *load_newly_created_array(classinfo *c, classloader *loader)
2037 classinfo *comp = NULL;
2039 methoddesc *clonedesc;
2040 constant_classref *classrefs;
2045 text = c->name->text;
2046 namelen = c->name->blength;
2048 /* Check array class name */
2050 if ((namelen < 2) || (text[0] != '[')) {
2051 exceptions_throw_classnotfoundexception(c->name);
2055 /* Check the element type */
2059 /* c is an array of arrays. We have to create the component class. */
2061 u = utf_new(text + 1, namelen - 1);
2063 comp = load_class_from_classloader(u, loader);
2068 assert(comp->state & CLASS_LOADED);
2070 /* the array's flags are that of the component class */
2071 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2072 c->classloader = comp->classloader;
2076 /* c is an array of objects. */
2078 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2079 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2080 exceptions_throw_classnotfoundexception(c->name);
2084 u = utf_new(text + 2, namelen - 3);
2086 if (!(comp = load_class_from_classloader(u, loader)))
2089 assert(comp->state & CLASS_LOADED);
2091 /* the array's flags are that of the component class */
2092 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2093 c->classloader = comp->classloader;
2097 /* c is an array of a primitive type */
2099 /* check for cases like `[II' and whether the character is a
2100 valid primitive type */
2102 if ((namelen > 2) || (primitive_class_get_by_char(text[1]) == NULL)) {
2103 exceptions_throw_classnotfoundexception(c->name);
2107 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2108 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2109 c->classloader = NULL;
2112 assert(class_java_lang_Object);
2113 #if defined(ENABLE_JAVASE)
2114 assert(class_java_lang_Cloneable);
2115 assert(class_java_io_Serializable);
2118 /* Setup the array class. */
2120 c->super = class_java_lang_Object;
2122 #if defined(ENABLE_JAVASE)
2124 c->interfacescount = 2;
2125 c->interfaces = MNEW(classinfo*, 2);
2126 c->interfaces[0] = class_java_lang_Cloneable;
2127 c->interfaces[1] = class_java_io_Serializable;
2129 #elif defined(ENABLE_JAVAME_CLDC1_1)
2131 c->interfacescount = 0;
2132 c->interfaces = NULL;
2135 # error unknow Java configuration
2138 c->methodscount = 1;
2139 c->methods = MNEW(methodinfo, c->methodscount);
2141 MZERO(c->methods, methodinfo, c->methodscount);
2143 classrefs = MNEW(constant_classref, 2);
2145 CLASSREF_INIT(classrefs[0], c, c->name);
2146 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2148 /* create descriptor for clone method */
2149 /* we need one paramslot which is reserved for the 'this' parameter */
2150 clonedesc = NEW(methoddesc);
2151 clonedesc->returntype.type = TYPE_ADR;
2152 clonedesc->returntype.classref = classrefs + 1;
2153 clonedesc->returntype.arraydim = 0;
2154 /* initialize params to "empty", add real params below in
2155 descriptor_params_from_paramtypes */
2156 clonedesc->paramcount = 0;
2157 clonedesc->paramslots = 0;
2158 clonedesc->paramtypes[0].classref = classrefs + 0;
2159 clonedesc->params = NULL;
2161 /* create methodinfo */
2164 MSET(clone, 0, methodinfo, 1);
2166 #if defined(ENABLE_THREADS)
2167 lock_init_object_lock(&clone->header);
2170 /* ATTENTION: if you delete the ACC_NATIVE below, set
2171 clone->maxlocals=1 (interpreter related) */
2173 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2174 clone->name = utf_clone;
2175 clone->descriptor = utf_void__java_lang_Object;
2176 clone->parseddesc = clonedesc;
2179 /* parse the descriptor to get the register allocation */
2181 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2184 clone->code = codegen_generate_stub_native(clone, BUILTIN_clone);
2186 /* XXX: field: length? */
2188 /* array classes are not loaded from class files */
2190 c->state |= CLASS_LOADED;
2191 c->parseddescs = (u1 *) clonedesc;
2192 c->parseddescsize = sizeof(methodinfo);
2193 c->classrefs = classrefs;
2194 c->classrefcount = 1;
2196 /* insert class into the loaded class cache */
2197 /* XXX free classinfo if NULL returned? */
2199 return classcache_store(loader, c, true);
2203 /* loader_close ****************************************************************
2205 Frees all resources.
2207 *******************************************************************************/
2209 void loader_close(void)
2216 * These are local overrides for various environment variables in Emacs.
2217 * Please do not remove this and leave it at the end of the file, where
2218 * Emacs will automagically detect them.
2219 * ---------------------------------------------------------------------
2222 * indent-tabs-mode: t
2226 * vim:noexpandtab:sw=4:ts=4: