1 /* src/vmcore/loader.c - class loader functions
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
34 #include "mm/memory.h"
36 #include "native/llni.h"
38 #include "threads/lock-common.h"
40 #include "toolbox/hashtable.h"
41 #include "toolbox/logging.h"
43 #include "vm/builtin.h"
44 #include "vm/exceptions.h"
45 #include "vm/global.h"
46 #include "vm/package.h"
47 #include "vm/primitive.h"
48 #include "vm/resolve.h"
49 #include "vm/stringlocal.h"
52 #include "vm/jit_interface.h"
54 #if defined(ENABLE_JAVASE)
55 # include "vmcore/annotation.h"
56 # include "vmcore/stackmap.h"
59 #include "vmcore/classcache.h"
60 #include "vmcore/field.h"
61 #include "vmcore/linker.h"
62 #include "vmcore/loader.h"
63 #include "vmcore/method.h"
64 #include "vmcore/options.h"
65 #include "vmcore/rt-timing.h"
67 #if defined(ENABLE_STATISTICS)
68 # include "vmcore/statistics.h"
71 #include "vmcore/suck.h"
73 #if defined(ENABLE_ZLIB)
74 # include "vmcore/zip.h"
77 #if defined(ENABLE_JVMTI)
78 # include "native/jvmti/cacaodbg.h"
82 /* global variables ***********************************************************/
84 static hashtable *hashtable_classloader;
87 /* loader_preinit **************************************************************
89 Initializes the classpath list and loads classes required for the
92 NOTE: Exceptions thrown during VM initialization are caught in the
93 exception functions themselves.
95 *******************************************************************************/
97 void loader_preinit(void)
99 #if defined(ENABLE_THREADS)
100 list_classpath_entry *lce;
103 TRACESUBSYSTEMINITIALIZATION("loader_preinit");
105 #if defined(ENABLE_THREADS)
106 /* Initialize the monitor pointer for zip/jar file locking. */
108 for (lce = list_first(list_classpath_entries); lce != NULL;
109 lce = list_next(list_classpath_entries, lce)) {
110 if (lce->type == CLASSPATH_ARCHIVE)
111 LOCK_INIT_OBJECT_LOCK(lce);
115 /* initialize classloader hashtable, 10 entries should be enough */
117 hashtable_classloader = NEW(hashtable);
118 hashtable_create(hashtable_classloader, 10);
120 /* Load the most basic classes. */
122 assert(vm_initializing == true);
124 class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object);
126 #if defined(ENABLE_JAVASE)
127 class_java_lang_Cloneable = load_class_bootstrap(utf_java_lang_Cloneable);
128 class_java_io_Serializable = load_class_bootstrap(utf_java_io_Serializable);
133 /* loader_init *****************************************************************
135 Loads all classes required in the VM.
137 NOTE: Exceptions thrown during VM initialization are caught in the
138 exception functions themselves.
140 *******************************************************************************/
142 void loader_init(void)
144 TRACESUBSYSTEMINITIALIZATION("loader_init");
146 /* Load primitive-type wrapping classes. */
148 assert(vm_initializing == true);
150 #if defined(ENABLE_JAVASE)
151 class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void);
154 class_java_lang_Boolean = load_class_bootstrap(utf_java_lang_Boolean);
155 class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte);
156 class_java_lang_Character = load_class_bootstrap(utf_java_lang_Character);
157 class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short);
158 class_java_lang_Integer = load_class_bootstrap(utf_java_lang_Integer);
159 class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long);
160 class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float);
161 class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double);
163 /* Load important system classes. */
165 class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class);
166 class_java_lang_String = load_class_bootstrap(utf_java_lang_String);
168 #if defined(ENABLE_JAVASE)
169 class_java_lang_ClassLoader =
170 load_class_bootstrap(utf_java_lang_ClassLoader);
172 class_java_lang_SecurityManager =
173 load_class_bootstrap(utf_java_lang_SecurityManager);
176 class_java_lang_System =
177 load_class_bootstrap(utf_new_char("java/lang/System"));
179 class_java_lang_Thread =
180 load_class_bootstrap(utf_new_char("java/lang/Thread"));
182 #if defined(ENABLE_JAVASE)
183 class_java_lang_ThreadGroup =
184 load_class_bootstrap(utf_java_lang_ThreadGroup);
187 class_java_lang_Throwable = load_class_bootstrap(utf_java_lang_Throwable);
189 #if defined(WITH_CLASSPATH_GNU)
190 class_java_lang_VMSystem =
191 load_class_bootstrap(utf_new_char("java/lang/VMSystem"));
193 class_java_lang_VMThread =
194 load_class_bootstrap(utf_new_char("java/lang/VMThread"));
196 class_java_lang_VMThrowable =
197 load_class_bootstrap(utf_new_char("java/lang/VMThrowable"));
200 /* Important system exceptions. */
202 class_java_lang_Exception = load_class_bootstrap(utf_java_lang_Exception);
204 class_java_lang_ClassNotFoundException =
205 load_class_bootstrap(utf_java_lang_ClassNotFoundException);
207 class_java_lang_RuntimeException =
208 load_class_bootstrap(utf_java_lang_RuntimeException);
210 /* Some classes which may be used often. */
212 #if defined(ENABLE_JAVASE)
213 class_java_lang_StackTraceElement = load_class_bootstrap(utf_java_lang_StackTraceElement);
215 class_java_lang_reflect_Constructor = load_class_bootstrap(utf_java_lang_reflect_Constructor);
216 class_java_lang_reflect_Field = load_class_bootstrap(utf_java_lang_reflect_Field);
217 class_java_lang_reflect_Method = load_class_bootstrap(utf_java_lang_reflect_Method);
219 # if defined(WITH_CLASSPATH_GNU)
220 class_java_lang_reflect_VMConstructor = load_class_bootstrap(utf_java_lang_reflect_VMConstructor);
221 class_java_lang_reflect_VMField = load_class_bootstrap(utf_java_lang_reflect_VMField);
222 class_java_lang_reflect_VMMethod = load_class_bootstrap(utf_java_lang_reflect_VMMethod);
225 class_java_security_PrivilegedAction = load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"));
227 class_java_util_HashMap = load_class_bootstrap(utf_new_char("java/util/HashMap"));
228 class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector);
230 # if defined(WITH_CLASSPATH_SUN)
231 class_sun_reflect_MagicAccessorImpl =
232 load_class_bootstrap(utf_new_char("sun/reflect/MagicAccessorImpl"));
235 arrayclass_java_lang_Object =
236 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"));
238 # if defined(ENABLE_ANNOTATIONS)
239 /* needed by annotation support */
240 class_sun_reflect_ConstantPool =
241 load_class_bootstrap(utf_new_char("sun/reflect/ConstantPool"));
243 # if defined(WITH_CLASSPATH_GNU)
244 /* needed by GNU Classpaths annotation support */
245 class_sun_reflect_annotation_AnnotationParser =
246 load_class_bootstrap(utf_new_char("sun/reflect/annotation/AnnotationParser"));
253 /* loader_hashtable_classloader_add ********************************************
255 Adds an entry to the classloader hashtable.
257 REMEMBER: Also use this to register native loaders!
259 *******************************************************************************/
261 classloader_t *loader_hashtable_classloader_add(java_handle_t *cl)
263 hashtable_classloader_entry *cle;
270 LOCK_MONITOR_ENTER(hashtable_classloader->header);
274 /* key for entry is the hashcode of the classloader;
275 aligned to 16-byte boundaries */
277 key = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
278 slot = key & (hashtable_classloader->size - 1);
279 cle = hashtable_classloader->ptr[slot];
281 /* search hashchain for existing entry */
284 if (cle->object == LLNI_DIRECT(cl))
292 /* if no classloader was found, we create a new entry here */
295 cle = NEW(hashtable_classloader_entry);
297 #if defined(ENABLE_GC_CACAO)
298 /* register the classloader object with the GC */
300 gc_reference_register(&(cle->object), GC_REFTYPE_CLASSLOADER);
305 cle->object = LLNI_DIRECT(cl);
309 /*#define LOADER_DEBUG_CLASSLOADER*/
310 #ifdef LOADER_DEBUG_CLASSLOADER
311 printf("CLASSLOADER: adding new classloader entry %p for %p: ", cle, cl);
312 class_print(LLNI_vftbl_direct(cl)->class);
317 /* insert entry into hashtable */
319 cle->hashlink = hashtable_classloader->ptr[slot];
320 hashtable_classloader->ptr[slot] = cle;
322 /* update number of entries */
324 hashtable_classloader->entries++;
328 LOCK_MONITOR_EXIT(hashtable_classloader->header);
330 #if defined(ENABLE_HANDLES)
338 /* loader_hashtable_classloader_find *******************************************
340 Find an entry in the classloader hashtable.
342 *******************************************************************************/
344 classloader_t *loader_hashtable_classloader_find(java_handle_t *cl)
346 hashtable_classloader_entry *cle;
355 /* key for entry is the hashcode of the classloader;
356 aligned to 16-byte boundaries */
358 key = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
359 slot = key & (hashtable_classloader->size - 1);
360 cle = hashtable_classloader->ptr[slot];
362 /* search hashchain for existing entry */
365 if (cle->object == LLNI_DIRECT(cl))
371 #ifdef LOADER_DEBUG_CLASSLOADER
373 printf("CLASSLOADER: unable to find classloader entry for %p: ", cl);
374 class_print(LLNI_vftbl_direct(cl)->class);
382 #if defined(ENABLE_HANDLES)
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_t *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 LLNI_class_get(cl, c);
1133 #if defined(WITH_CLASSPATH_SUN)
1134 /* OpenJDK uses this internal function because it's
1137 lc = class_resolveclassmethod(c,
1138 utf_loadClassInternal,
1139 utf_java_lang_String__java_lang_Class,
1143 lc = class_resolveclassmethod(c,
1145 utf_java_lang_String__java_lang_Class,
1151 return false; /* exception */
1153 /* move return value into `o' and cast it afterwards to a classinfo* */
1155 string = javastring_new_slash_to_dot(name);
1157 RT_TIMING_GET_TIME(time_prepare);
1159 o = vm_call_method(lc, (java_handle_t *) cl, string);
1161 RT_TIMING_GET_TIME(time_java);
1163 c = LLNI_classinfo_unwrap(o);
1166 /* Store this class in the loaded class cache. If another
1167 class with the same (initloader,name) pair has been
1168 stored earlier it will be returned by classcache_store
1169 In this case classcache_store may not free the class
1170 because it has already been exposed to Java code which
1171 may have kept references to that class. */
1173 tmpc = classcache_store(cl, c, false);
1176 /* exception, free the loaded class */
1177 c->state &= ~CLASS_LOADING;
1184 RT_TIMING_GET_TIME(time_cache);
1186 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1187 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1188 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1190 /* SUN compatible -verbose:class output */
1192 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1194 utf_display_printable_ascii_classname(name);
1198 #if defined(ENABLE_JVMTI)
1199 /* fire Class Load JVMTI event */
1200 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1207 c = load_class_bootstrap(name);
1213 /* load_class_bootstrap ********************************************************
1215 Load the class with the given name using the bootstrap class loader.
1218 name.............the classname
1221 loaded classinfo, or
1222 NULL if an exception has been thrown
1225 load_class_bootstrap is synchronized. It can be treated as an
1228 *******************************************************************************/
1230 classinfo *load_class_bootstrap(utf *name)
1235 #if defined(ENABLE_RT_TIMING)
1236 struct timespec time_start, time_lookup, time_array, time_suck,
1237 time_load, time_cache;
1240 RT_TIMING_GET_TIME(time_start);
1246 /* lookup if this class has already been loaded */
1248 r = classcache_lookup(NULL, name);
1251 RT_TIMING_GET_TIME(time_lookup);
1252 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1257 RT_TIMING_GET_TIME(time_lookup);
1258 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1260 /* create the classinfo */
1262 c = class_create_classinfo(name);
1264 /* handle array classes */
1266 if (name->text[0] == '[') {
1267 c = load_newly_created_array(c, NULL);
1272 assert(c->state & CLASS_LOADED);
1274 RT_TIMING_GET_TIME(time_array);
1275 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1280 #if defined(ENABLE_STATISTICS)
1283 if (opt_getcompilingtime)
1284 compilingtime_stop();
1286 if (opt_getloadingtime)
1287 loadingtime_start();
1290 /* load classdata, throw exception on error */
1295 exceptions_throw_classnotfoundexception(name);
1299 RT_TIMING_GET_TIME(time_suck);
1301 /* load the class from the buffer */
1303 r = load_class_from_classbuffer(cb);
1305 RT_TIMING_GET_TIME(time_load);
1308 /* the class could not be loaded, free the classinfo struct */
1313 /* Store this class in the loaded class cache this step also
1314 checks the loading constraints. If the class has been
1315 loaded before, the earlier loaded class is returned. */
1317 classinfo *res = classcache_store(NULL, c, true);
1324 /* Add the package name to the boot packages. */
1326 package_add(c->packagename);
1332 RT_TIMING_GET_TIME(time_cache);
1334 /* SUN compatible -verbose:class output */
1336 if (opt_verboseclass && r) {
1338 utf_display_printable_ascii_classname(name);
1339 printf(" from %s]\n", cb->path);
1346 #if defined(ENABLE_STATISTICS)
1349 if (opt_getloadingtime)
1352 if (opt_getcompilingtime)
1353 compilingtime_start();
1356 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1357 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1358 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1359 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1365 /* load_class_from_classbuffer_intern ******************************************
1367 Loads a class from a classbuffer into a given classinfo structure.
1368 Super-classes are also loaded at this point and some verfication
1372 This function is NOT synchronized!
1374 *******************************************************************************/
1376 static bool load_class_from_classbuffer_intern(classbuffer *cb)
1382 utf **interfacesnames;
1384 constant_classref *cr;
1389 descriptor_pool *descpool;
1390 #if defined(ENABLE_STATISTICS)
1394 #if defined(ENABLE_RT_TIMING)
1395 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1396 time_setup, time_fields, time_methods, time_classrefs,
1397 time_descs, time_setrefs, time_parsefds, time_parsemds,
1398 time_parsecpool, time_verify, time_attrs;
1401 RT_TIMING_GET_TIME(time_start);
1403 /* Get the classbuffer's class. */
1407 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1410 /* check signature */
1412 if (suck_u4(cb) != MAGIC) {
1413 exceptions_throw_classformaterror(c, "Bad magic number");
1422 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1423 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1427 RT_TIMING_GET_TIME(time_checks);
1429 /* create a new descriptor pool */
1431 descpool = descriptor_pool_new(c);
1433 RT_TIMING_GET_TIME(time_ndpool);
1435 /* load the constant pool */
1437 if (!load_constantpool(cb, descpool))
1440 RT_TIMING_GET_TIME(time_cpool);
1444 if (!suck_check_classbuffer_size(cb, 2))
1447 /* We OR the flags here, as we set already some flags in
1448 class_create_classinfo. */
1450 c->flags |= suck_u2(cb);
1452 /* check ACC flags consistency */
1454 if (c->flags & ACC_INTERFACE) {
1455 if (!(c->flags & ACC_ABSTRACT)) {
1456 /* We work around this because interfaces in JDK 1.1 are
1457 * not declared abstract. */
1459 c->flags |= ACC_ABSTRACT;
1462 if (c->flags & ACC_FINAL) {
1463 exceptions_throw_classformaterror(c,
1464 "Illegal class modifiers: 0x%X",
1469 if (c->flags & ACC_SUPER) {
1470 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1474 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1475 exceptions_throw_classformaterror(c,
1476 "Illegal class modifiers: 0x%X",
1481 if (!suck_check_classbuffer_size(cb, 2 + 2))
1486 index = suck_u2(cb);
1488 name = (utf *) class_getconstant(c, index, CONSTANT_Class);
1493 if (c->name == utf_not_named_yet) {
1494 /* we finally have a name for this class */
1496 class_set_packagename(c);
1498 else if (name != c->name) {
1499 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
1503 /* Retrieve superclass. */
1507 index = suck_u2(cb);
1512 /* This is only allowed for java.lang.Object. */
1514 if (c->name != utf_java_lang_Object) {
1515 exceptions_throw_classformaterror(c, "Bad superclass index");
1520 supername = (utf *) class_getconstant(c, index, CONSTANT_Class);
1522 if (supername == NULL)
1525 /* java.lang.Object may not have a super class. */
1527 if (c->name == utf_java_lang_Object) {
1528 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
1532 /* Detect circularity. */
1534 if (supername == c->name) {
1535 exceptions_throw_classcircularityerror(c);
1539 /* Interfaces must have java.lang.Object as super class. */
1541 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
1542 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
1547 /* Parse the super interfaces. */
1549 if (!suck_check_classbuffer_size(cb, 2))
1552 c->interfacescount = suck_u2(cb);
1554 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1557 c->interfaces = MNEW(classinfo*, c->interfacescount);
1559 /* Get the names of the super interfaces. */
1561 interfacesnames = DMNEW(utf*, c->interfacescount);
1563 for (i = 0; i < c->interfacescount; i++) {
1564 index = suck_u2(cb);
1566 u = (utf *) class_getconstant(c, index, CONSTANT_Class);
1571 interfacesnames[i] = u;
1574 RT_TIMING_GET_TIME(time_setup);
1578 if (!suck_check_classbuffer_size(cb, 2))
1581 c->fieldscount = suck_u2(cb);
1582 c->fields = MNEW(fieldinfo, c->fieldscount);
1584 MZERO(c->fields, fieldinfo, c->fieldscount);
1586 for (i = 0; i < c->fieldscount; i++) {
1587 if (!field_load(cb, &(c->fields[i]), descpool))
1591 RT_TIMING_GET_TIME(time_fields);
1593 /* Parse methods. */
1595 if (!suck_check_classbuffer_size(cb, 2))
1598 c->methodscount = suck_u2(cb);
1599 c->methods = MNEW(methodinfo, c->methodscount);
1601 MZERO(c->methods, methodinfo, c->methodscount);
1603 for (i = 0; i < c->methodscount; i++) {
1604 if (!method_load(cb, &(c->methods[i]), descpool))
1608 RT_TIMING_GET_TIME(time_methods);
1610 /* create the class reference table */
1613 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
1615 RT_TIMING_GET_TIME(time_classrefs);
1617 /* allocate space for the parsed descriptors */
1619 descriptor_pool_alloc_parsed_descriptors(descpool);
1621 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
1623 #if defined(ENABLE_STATISTICS)
1625 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
1626 count_classref_len += classrefsize;
1627 count_parsed_desc_len += descsize;
1631 RT_TIMING_GET_TIME(time_descs);
1633 /* put the classrefs in the constant pool */
1635 for (i = 0; i < c->cpcount; i++) {
1636 if (c->cptags[i] == CONSTANT_Class) {
1637 utf *name = (utf *) c->cpinfos[i];
1638 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
1642 /* Resolve the super class. */
1644 if (supername != NULL) {
1645 cr = descriptor_pool_lookup_classref(descpool, supername);
1650 /* XXX This should be done better. */
1651 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1654 resolve_handle_pending_exception(true);
1658 /* Interfaces are not allowed as super classes. */
1660 if (tc->flags & ACC_INTERFACE) {
1661 exceptions_throw_incompatibleclasschangeerror(c, "class %s has interface %s as super class");
1665 /* Don't allow extending final classes */
1667 if (tc->flags & ACC_FINAL) {
1668 exceptions_throw_verifyerror(NULL,
1669 "Cannot inherit from final class");
1673 /* Store the super class. */
1678 /* Resolve the super interfaces. */
1680 for (i = 0; i < c->interfacescount; i++) {
1681 u = interfacesnames[i];
1682 cr = descriptor_pool_lookup_classref(descpool, u);
1687 /* XXX This should be done better. */
1688 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1691 resolve_handle_pending_exception(true);
1695 /* Detect circularity. */
1698 exceptions_throw_classcircularityerror(c);
1702 if (!(tc->flags & ACC_INTERFACE)) {
1703 exceptions_throw_incompatibleclasschangeerror(tc,
1704 "Implementing class");
1708 /* Store the super interface. */
1710 c->interfaces[i] = tc;
1713 RT_TIMING_GET_TIME(time_setrefs);
1715 /* Parse the field descriptors. */
1717 for (i = 0; i < c->fieldscount; i++) {
1718 c->fields[i].parseddesc =
1719 descriptor_pool_parse_field_descriptor(descpool,
1720 c->fields[i].descriptor);
1721 if (!c->fields[i].parseddesc)
1725 RT_TIMING_GET_TIME(time_parsefds);
1727 /* parse method descriptors */
1729 for (i = 0; i < c->methodscount; i++) {
1730 methodinfo *m = &c->methods[i];
1732 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
1733 m->flags, class_get_self_classref(m->clazz));
1737 for (j = 0; j < m->rawexceptiontablelength; j++) {
1738 if (!m->rawexceptiontable[j].catchtype.any)
1741 if ((m->rawexceptiontable[j].catchtype.ref =
1742 descriptor_pool_lookup_classref(descpool,
1743 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
1747 for (j = 0; j < m->thrownexceptionscount; j++) {
1748 if (!m->thrownexceptions[j].any)
1751 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
1752 (utf *) m->thrownexceptions[j].any)) == NULL)
1757 RT_TIMING_GET_TIME(time_parsemds);
1759 /* parse the loaded descriptors */
1761 for (i = 0; i < c->cpcount; i++) {
1762 constant_FMIref *fmi;
1765 switch (c->cptags[i]) {
1766 case CONSTANT_Fieldref:
1767 fmi = (constant_FMIref *) c->cpinfos[i];
1768 fmi->parseddesc.fd =
1769 descriptor_pool_parse_field_descriptor(descpool,
1771 if (!fmi->parseddesc.fd)
1774 index = fmi->p.index;
1776 (constant_classref *) class_getconstant(c, index,
1778 if (!fmi->p.classref)
1781 case CONSTANT_Methodref:
1782 case CONSTANT_InterfaceMethodref:
1783 fmi = (constant_FMIref *) c->cpinfos[i];
1784 index = fmi->p.index;
1786 (constant_classref *) class_getconstant(c, index,
1788 if (!fmi->p.classref)
1790 fmi->parseddesc.md =
1791 descriptor_pool_parse_method_descriptor(descpool,
1795 if (!fmi->parseddesc.md)
1801 RT_TIMING_GET_TIME(time_parsecpool);
1803 #ifdef ENABLE_VERIFIER
1804 /* Check if all fields and methods can be uniquely
1805 * identified by (name,descriptor). */
1808 /* We use a hash table here to avoid making the
1809 * average case quadratic in # of methods, fields.
1811 static int shift = 0;
1813 u2 *next; /* for chaining colliding hash entries */
1819 /* Allocate hashtable */
1820 len = c->methodscount;
1821 if (len < c->fieldscount) len = c->fieldscount;
1823 hashtab = MNEW(u2,(hashlen + len));
1824 next = hashtab + hashlen;
1826 /* Determine bitshift (to get good hash values) */
1836 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
1838 for (i = 0; i < c->fieldscount; ++i) {
1839 fieldinfo *fi = c->fields + i;
1841 /* It's ok if we lose bits here */
1842 index = ((((size_t) fi->name) +
1843 ((size_t) fi->descriptor)) >> shift) % hashlen;
1845 if ((old = hashtab[index])) {
1849 if (c->fields[old].name == fi->name &&
1850 c->fields[old].descriptor == fi->descriptor) {
1851 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
1854 } while ((old = next[old]));
1856 hashtab[index] = i + 1;
1860 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
1862 for (i = 0; i < c->methodscount; ++i) {
1863 methodinfo *mi = c->methods + i;
1865 /* It's ok if we lose bits here */
1866 index = ((((size_t) mi->name) +
1867 ((size_t) mi->descriptor)) >> shift) % hashlen;
1869 if ((old = hashtab[index])) {
1873 if (c->methods[old].name == mi->name &&
1874 c->methods[old].descriptor == mi->descriptor) {
1875 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
1878 } while ((old = next[old]));
1880 hashtab[index] = i + 1;
1883 MFREE(hashtab, u2, (hashlen + len));
1885 #endif /* ENABLE_VERIFIER */
1887 RT_TIMING_GET_TIME(time_verify);
1889 #if defined(ENABLE_STATISTICS)
1891 size_classinfo += sizeof(classinfo*) * c->interfacescount;
1892 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
1893 size_methodinfo += sizeof(methodinfo) * c->methodscount;
1897 /* load attribute structures */
1899 if (!class_load_attributes(cb))
1902 /* Pre Java 1.5 version don't check this. This implementation is
1903 like Java 1.5 do it: for class file version 45.3 we don't check
1904 it, older versions are checked. */
1906 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
1907 /* check if all data has been read */
1908 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
1910 if (classdata_left > 0) {
1911 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
1916 RT_TIMING_GET_TIME(time_attrs);
1918 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
1919 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
1920 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
1921 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
1922 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
1923 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
1924 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
1925 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
1926 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
1927 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
1928 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
1929 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
1930 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
1931 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
1932 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
1938 /* load_class_from_classbuffer *************************************************
1940 Convenience wrapper for load_class_from_classbuffer.
1943 This function is NOT synchronized!
1945 *******************************************************************************/
1947 classinfo *load_class_from_classbuffer(classbuffer *cb)
1953 /* Get the classbuffer's class. */
1957 /* Check if the class is already loaded. */
1959 if (c->state & CLASS_LOADED)
1962 #if defined(ENABLE_STATISTICS)
1964 count_class_loads++;
1967 #if !defined(NDEBUG)
1969 log_message_class("Loading class: ", c);
1972 /* Mark start of dump memory area. */
1976 /* Class is currently loading. */
1978 c->state |= CLASS_LOADING;
1980 /* Parse the classbuffer. */
1982 result = load_class_from_classbuffer_intern(cb);
1984 /* Release dump area. */
1988 /* An error occurred. */
1990 if (result == false) {
1991 /* Revert loading state. */
1993 c->state = (c->state & ~CLASS_LOADING);
1998 /* Revert loading state and set loaded. */
2000 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2002 #if defined(ENABLE_JVMTI)
2003 /* fire Class Prepare JVMTI event */
2006 jvmti_ClassLoadPrepare(true, c);
2009 #if !defined(NDEBUG)
2011 log_message_class("Loading done class: ", c);
2018 /* load_newly_created_array ****************************************************
2020 Load a newly created array class.
2023 c....................the array class C has been loaded
2024 other classinfo......the array class was found in the class cache,
2026 NULL.................an exception has been thrown
2029 This is an internal function. Do not use it unless you know exactly
2032 Use one of the load_class_... functions for general array class loading.
2034 *******************************************************************************/
2036 classinfo *load_newly_created_array(classinfo *c, classloader_t *loader)
2038 classinfo *comp = NULL;
2040 methoddesc *clonedesc;
2041 constant_classref *classrefs;
2046 text = c->name->text;
2047 namelen = c->name->blength;
2049 /* Check array class name */
2051 if ((namelen < 2) || (text[0] != '[')) {
2052 exceptions_throw_classnotfoundexception(c->name);
2056 /* Check the element type */
2060 /* c is an array of arrays. We have to create the component class. */
2062 u = utf_new(text + 1, namelen - 1);
2064 comp = load_class_from_classloader(u, loader);
2069 assert(comp->state & CLASS_LOADED);
2071 /* the array's flags are that of the component class */
2072 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2073 c->classloader = comp->classloader;
2077 /* c is an array of objects. */
2079 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2080 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2081 exceptions_throw_classnotfoundexception(c->name);
2085 u = utf_new(text + 2, namelen - 3);
2087 if (!(comp = load_class_from_classloader(u, loader)))
2090 assert(comp->state & CLASS_LOADED);
2092 /* the array's flags are that of the component class */
2093 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2094 c->classloader = comp->classloader;
2098 /* c is an array of a primitive type */
2100 /* check for cases like `[II' and whether the character is a
2101 valid primitive type */
2103 if ((namelen > 2) || (primitive_class_get_by_char(text[1]) == NULL)) {
2104 exceptions_throw_classnotfoundexception(c->name);
2108 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2109 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2110 c->classloader = NULL;
2113 assert(class_java_lang_Object);
2114 #if defined(ENABLE_JAVASE)
2115 assert(class_java_lang_Cloneable);
2116 assert(class_java_io_Serializable);
2119 /* Setup the array class. */
2121 c->super = class_java_lang_Object;
2123 #if defined(ENABLE_JAVASE)
2125 c->interfacescount = 2;
2126 c->interfaces = MNEW(classinfo*, 2);
2127 c->interfaces[0] = class_java_lang_Cloneable;
2128 c->interfaces[1] = class_java_io_Serializable;
2130 #elif defined(ENABLE_JAVAME_CLDC1_1)
2132 c->interfacescount = 0;
2133 c->interfaces = NULL;
2136 # error unknow Java configuration
2139 c->methodscount = 1;
2140 c->methods = MNEW(methodinfo, c->methodscount);
2142 MZERO(c->methods, methodinfo, c->methodscount);
2144 classrefs = MNEW(constant_classref, 2);
2146 CLASSREF_INIT(classrefs[0], c, c->name);
2147 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2149 /* create descriptor for clone method */
2150 /* we need one paramslot which is reserved for the 'this' parameter */
2151 clonedesc = NEW(methoddesc);
2152 clonedesc->returntype.type = TYPE_ADR;
2153 clonedesc->returntype.classref = classrefs + 1;
2154 clonedesc->returntype.arraydim = 0;
2155 /* initialize params to "empty", add real params below in
2156 descriptor_params_from_paramtypes */
2157 clonedesc->paramcount = 0;
2158 clonedesc->paramslots = 0;
2159 clonedesc->paramtypes[0].classref = classrefs + 0;
2160 clonedesc->params = NULL;
2162 /* create methodinfo */
2165 MSET(clone, 0, methodinfo, 1);
2167 #if defined(ENABLE_THREADS)
2168 lock_init_object_lock(&clone->header);
2171 /* ATTENTION: if you delete the ACC_NATIVE below, set
2172 clone->maxlocals=1 (interpreter related) */
2174 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2175 clone->name = utf_clone;
2176 clone->descriptor = utf_void__java_lang_Object;
2177 clone->parseddesc = clonedesc;
2180 /* parse the descriptor to get the register allocation */
2182 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2185 clone->code = codegen_generate_stub_native(clone, BUILTIN_clone);
2187 /* XXX: field: length? */
2189 /* array classes are not loaded from class files */
2191 c->state |= CLASS_LOADED;
2192 c->parseddescs = (u1 *) clonedesc;
2193 c->parseddescsize = sizeof(methodinfo);
2194 c->classrefs = classrefs;
2195 c->classrefcount = 1;
2197 /* insert class into the loaded class cache */
2198 /* XXX free classinfo if NULL returned? */
2200 return classcache_store(loader, c, true);
2204 /* loader_close ****************************************************************
2206 Frees all resources.
2208 *******************************************************************************/
2210 void loader_close(void)
2217 * These are local overrides for various environment variables in Emacs.
2218 * Please do not remove this and leave it at the end of the file, where
2219 * Emacs will automagically detect them.
2220 * ---------------------------------------------------------------------
2223 * indent-tabs-mode: t
2227 * vim:noexpandtab:sw=4:ts=4: