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 /*#define LOADER_DEBUG_CLASSLOADER*/
330 #ifdef LOADER_DEBUG_CLASSLOADER
331 printf("CLASSLOADER: adding new classloader entry %p for %p: ", cle, cl);
332 class_print(LLNI_vftbl_direct(cl)->class);
337 /* insert entry into hashtable */
339 cle->hashlink = hashtable_classloader->ptr[slot];
340 hashtable_classloader->ptr[slot] = cle;
342 /* update number of entries */
344 hashtable_classloader->entries++;
348 LOCK_MONITOR_EXIT(hashtable_classloader->header);
350 #if defined(ENABLE_HANDLES)
358 /* loader_hashtable_classloader_find *******************************************
360 Find an entry in the classloader hashtable.
362 *******************************************************************************/
364 classloader *loader_hashtable_classloader_find(java_handle_t *cl)
366 hashtable_classloader_entry *cle;
375 /* key for entry is the hashcode of the classloader;
376 aligned to 16-byte boundaries */
378 #if defined(ENABLE_GC_CACAO)
379 key = heap_get_hashcode(LLNI_DIRECT(cl)) >> 4;
381 key = ((u4) (ptrint) cl) >> 4;
384 slot = key & (hashtable_classloader->size - 1);
385 cle = hashtable_classloader->ptr[slot];
387 /* search hashchain for existing entry */
390 if (cle->object == LLNI_DIRECT(cl))
396 #ifdef LOADER_DEBUG_CLASSLOADER
398 printf("CLASSLOADER: unable to find classloader entry for %p: ", cl);
399 class_print(LLNI_vftbl_direct(cl)->class);
407 #if defined(ENABLE_HANDLES)
415 /* loader_load_all_classes *****************************************************
417 Loads all classes specified in the BOOTCLASSPATH.
419 *******************************************************************************/
421 void loader_load_all_classes(void)
423 list_classpath_entry *lce;
424 #if defined(ENABLE_ZLIB)
427 hashtable_zipfile_entry *htzfe;
431 for (lce = list_first(list_classpath_entries); lce != NULL;
432 lce = list_next(list_classpath_entries, lce)) {
433 #if defined(ENABLE_ZLIB)
434 if (lce->type == CLASSPATH_ARCHIVE) {
435 /* get the classes hashtable */
439 for (slot = 0; slot < ht->size; slot++) {
440 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
442 for (; htzfe; htzfe = htzfe->hashlink) {
445 /* skip all entries in META-INF and .properties,
448 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
449 strstr(u->text, ".properties") ||
450 strstr(u->text, ".png"))
453 /* load class from bootstrap classloader */
455 if (!load_class_bootstrap(u)) {
456 fprintf(stderr, "Error loading: ");
457 utf_fprint_printable_ascii_classname(stderr, u);
458 fprintf(stderr, "\n");
461 /* print out exception and cause */
463 exceptions_print_current_exception();
471 #if defined(ENABLE_ZLIB)
478 /* loader_skip_attribute_body **************************************************
480 Skips an attribute the attribute_name_index has already been read.
483 u2 attribute_name_index;
485 u1 info[attribute_length];
488 *******************************************************************************/
490 bool loader_skip_attribute_body(classbuffer *cb)
494 if (!suck_check_classbuffer_size(cb, 4))
497 attribute_length = suck_u4(cb);
499 if (!suck_check_classbuffer_size(cb, attribute_length))
502 suck_skip_nbytes(cb, attribute_length);
508 /* load_constantpool ***********************************************************
510 Loads the constantpool of a class, the entries are transformed into
511 a simpler format by resolving references (a detailed overview of
512 the compact structures can be found in global.h).
514 *******************************************************************************/
516 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
519 /* The following structures are used to save information which cannot be
520 processed during the first pass. After the complete constantpool has
521 been traversed the references can be resolved.
522 (only in specific order) */
524 /* CONSTANT_Class entries */
525 typedef struct forward_class {
526 struct forward_class *next;
531 /* CONSTANT_String */
532 typedef struct forward_string {
533 struct forward_string *next;
538 /* CONSTANT_NameAndType */
539 typedef struct forward_nameandtype {
540 struct forward_nameandtype *next;
544 } forward_nameandtype;
546 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
547 typedef struct forward_fieldmethint {
548 struct forward_fieldmethint *next;
552 u2 nameandtype_index;
553 } forward_fieldmethint;
559 forward_class *forward_classes = NULL;
560 forward_string *forward_strings = NULL;
561 forward_nameandtype *forward_nameandtypes = NULL;
562 forward_fieldmethint *forward_fieldmethints = NULL;
566 forward_nameandtype *nfn;
567 forward_fieldmethint *nff;
575 /* number of entries in the constant_pool table plus one */
576 if (!suck_check_classbuffer_size(cb, 2))
579 cpcount = c->cpcount = suck_u2(cb);
581 /* allocate memory */
582 cptags = c->cptags = MNEW(u1, cpcount);
583 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
586 exceptions_throw_classformaterror(c, "Illegal constant pool size");
590 #if defined(ENABLE_STATISTICS)
592 count_const_pool_len += (sizeof(u1) + sizeof(voidptr)) * cpcount;
595 /* initialize constantpool */
596 for (idx = 0; idx < cpcount; idx++) {
597 cptags[idx] = CONSTANT_UNUSED;
602 /******* first pass *******/
603 /* entries which cannot be resolved now are written into
604 temporary structures and traversed again later */
607 while (idx < cpcount) {
610 /* get constant type */
611 if (!suck_check_classbuffer_size(cb, 1))
618 nfc = DNEW(forward_class);
620 nfc->next = forward_classes;
621 forward_classes = nfc;
623 nfc->thisindex = idx;
624 /* reference to CONSTANT_NameAndType */
625 if (!suck_check_classbuffer_size(cb, 2))
628 nfc->name_index = suck_u2(cb);
633 case CONSTANT_String:
634 nfs = DNEW(forward_string);
636 nfs->next = forward_strings;
637 forward_strings = nfs;
639 nfs->thisindex = idx;
641 /* reference to CONSTANT_Utf8_info with string characters */
642 if (!suck_check_classbuffer_size(cb, 2))
645 nfs->string_index = suck_u2(cb);
650 case CONSTANT_NameAndType:
651 nfn = DNEW(forward_nameandtype);
653 nfn->next = forward_nameandtypes;
654 forward_nameandtypes = nfn;
656 nfn->thisindex = idx;
658 if (!suck_check_classbuffer_size(cb, 2 + 2))
661 /* reference to CONSTANT_Utf8_info containing simple name */
662 nfn->name_index = suck_u2(cb);
664 /* reference to CONSTANT_Utf8_info containing field or method
666 nfn->sig_index = suck_u2(cb);
671 case CONSTANT_Fieldref:
672 case CONSTANT_Methodref:
673 case CONSTANT_InterfaceMethodref:
674 nff = DNEW(forward_fieldmethint);
676 nff->next = forward_fieldmethints;
677 forward_fieldmethints = nff;
679 nff->thisindex = idx;
683 if (!suck_check_classbuffer_size(cb, 2 + 2))
686 /* class or interface type that contains the declaration of the
688 nff->class_index = suck_u2(cb);
690 /* name and descriptor of the field or method */
691 nff->nameandtype_index = suck_u2(cb);
696 case CONSTANT_Integer: {
697 constant_integer *ci = NEW(constant_integer);
699 #if defined(ENABLE_STATISTICS)
701 count_const_pool_len += sizeof(constant_integer);
704 if (!suck_check_classbuffer_size(cb, 4))
707 ci->value = suck_s4(cb);
708 cptags[idx] = CONSTANT_Integer;
715 case CONSTANT_Float: {
716 constant_float *cf = NEW(constant_float);
718 #if defined(ENABLE_STATISTICS)
720 count_const_pool_len += sizeof(constant_float);
723 if (!suck_check_classbuffer_size(cb, 4))
726 cf->value = suck_float(cb);
727 cptags[idx] = CONSTANT_Float;
734 case CONSTANT_Long: {
735 constant_long *cl = NEW(constant_long);
737 #if defined(ENABLE_STATISTICS)
739 count_const_pool_len += sizeof(constant_long);
742 if (!suck_check_classbuffer_size(cb, 8))
745 cl->value = suck_s8(cb);
746 cptags[idx] = CONSTANT_Long;
750 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
756 case CONSTANT_Double: {
757 constant_double *cd = NEW(constant_double);
759 #if defined(ENABLE_STATISTICS)
761 count_const_pool_len += sizeof(constant_double);
764 if (!suck_check_classbuffer_size(cb, 8))
767 cd->value = suck_double(cb);
768 cptags[idx] = CONSTANT_Double;
772 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
778 case CONSTANT_Utf8: {
781 /* number of bytes in the bytes array (not string-length) */
782 if (!suck_check_classbuffer_size(cb, 2))
785 length = suck_u2(cb);
786 cptags[idx] = CONSTANT_Utf8;
788 /* validate the string */
789 if (!suck_check_classbuffer_size(cb, length))
792 #ifdef ENABLE_VERIFIER
794 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
796 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
799 #endif /* ENABLE_VERIFIER */
800 /* insert utf-string into the utf-symboltable */
801 cpinfos[idx] = utf_new((char *) cb->pos, length);
803 /* skip bytes of the string (buffer size check above) */
804 suck_skip_nbytes(cb, length);
810 exceptions_throw_classformaterror(c, "Illegal constant pool type");
816 /* resolve entries in temporary structures */
818 while (forward_classes) {
820 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
824 #ifdef ENABLE_VERIFIER
825 if (opt_verify && !is_valid_name_utf(name)) {
826 exceptions_throw_classformaterror(c, "Class reference with invalid name");
829 #endif /* ENABLE_VERIFIER */
831 /* add all class references to the descriptor_pool */
833 if (!descriptor_pool_add_class(descpool, name))
836 cptags[forward_classes->thisindex] = CONSTANT_Class;
838 /* the classref is created later */
839 cpinfos[forward_classes->thisindex] = name;
841 nfc = forward_classes;
842 forward_classes = forward_classes->next;
845 while (forward_strings) {
847 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
851 /* resolve utf-string */
852 cptags[forward_strings->thisindex] = CONSTANT_String;
853 cpinfos[forward_strings->thisindex] = text;
855 nfs = forward_strings;
856 forward_strings = forward_strings->next;
859 while (forward_nameandtypes) {
860 constant_nameandtype *cn = NEW(constant_nameandtype);
862 #if defined(ENABLE_STATISTICS)
864 count_const_pool_len += sizeof(constant_nameandtype);
867 /* resolve simple name and descriptor */
868 cn->name = class_getconstant(c,
869 forward_nameandtypes->name_index,
874 cn->descriptor = class_getconstant(c,
875 forward_nameandtypes->sig_index,
880 #ifdef ENABLE_VERIFIER
883 if (!is_valid_name_utf(cn->name)) {
884 exceptions_throw_classformaterror(c,
885 "Illegal Field name \"%s\"",
891 /* disallow referencing <clinit> among others */
892 if (cn->name->text[0] == '<' && cn->name != utf_init) {
893 exceptions_throw_classformaterror(c, "Illegal reference to special method");
897 #endif /* ENABLE_VERIFIER */
899 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
900 cpinfos[forward_nameandtypes->thisindex] = cn;
902 nfn = forward_nameandtypes;
903 forward_nameandtypes = forward_nameandtypes->next;
906 while (forward_fieldmethints) {
907 constant_nameandtype *nat;
908 constant_FMIref *fmi = NEW(constant_FMIref);
910 #if defined(ENABLE_STATISTICS)
912 count_const_pool_len += sizeof(constant_FMIref);
914 /* resolve simple name and descriptor */
916 nat = class_getconstant(c,
917 forward_fieldmethints->nameandtype_index,
918 CONSTANT_NameAndType);
922 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
924 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
927 /* the classref is created later */
929 fmi->p.index = forward_fieldmethints->class_index;
930 fmi->name = nat->name;
931 fmi->descriptor = nat->descriptor;
933 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
934 cpinfos[forward_fieldmethints->thisindex] = fmi;
936 nff = forward_fieldmethints;
937 forward_fieldmethints = forward_fieldmethints->next;
940 /* everything was ok */
946 /* loader_load_attribute_signature *********************************************
948 Signature_attribute {
949 u2 attribute_name_index;
954 *******************************************************************************/
956 #if defined(ENABLE_JAVASE)
957 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
967 /* check remaining bytecode */
969 if (!suck_check_classbuffer_size(cb, 4 + 2))
972 /* check attribute length */
974 attribute_length = suck_u4(cb);
976 if (attribute_length != 2) {
977 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
981 if (*signature != NULL) {
982 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
988 signature_index = suck_u2(cb);
990 if (!(*signature = class_getconstant(c, signature_index, CONSTANT_Utf8)))
995 #endif /* defined(ENABLE_JAVASE) */
998 /* load_class_from_sysloader ***************************************************
1000 Load the class with the given name using the system class loader
1003 name.............the classname
1006 the loaded class, or
1007 NULL if an exception has been thrown
1009 *******************************************************************************/
1011 classinfo *load_class_from_sysloader(utf *name)
1018 assert(class_java_lang_Object);
1019 assert(class_java_lang_ClassLoader);
1020 assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
1022 m = class_resolveclassmethod(class_java_lang_ClassLoader,
1023 utf_getSystemClassLoader,
1024 utf_void__java_lang_ClassLoader,
1025 class_java_lang_Object,
1031 clo = vm_call_method(m, NULL);
1036 cl = loader_hashtable_classloader_add(clo);
1038 c = load_class_from_classloader(name, cl);
1044 /* load_class_from_classloader *************************************************
1046 Load the class with the given name using the given user-defined class loader.
1049 name.............the classname
1050 cl...............user-defined class loader
1053 the loaded class, or
1054 NULL if an exception has been thrown
1056 *******************************************************************************/
1058 classinfo *load_class_from_classloader(utf *name, classloader *cl)
1063 java_handle_t *string;
1064 #if defined(ENABLE_RT_TIMING)
1065 struct timespec time_start, time_lookup, time_prepare, time_java,
1069 RT_TIMING_GET_TIME(time_start);
1073 /* lookup if this class has already been loaded */
1075 c = classcache_lookup(cl, name);
1077 RT_TIMING_GET_TIME(time_lookup);
1078 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1083 /* if other class loader than bootstrap, call it */
1091 namelen = name->blength;
1093 /* handle array classes */
1094 if (text[0] == '[') {
1100 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1101 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1102 exceptions_throw_classnotfoundexception(name);
1106 u = utf_new(text + 2, namelen - 3);
1108 if (!(comp = load_class_from_classloader(u, cl)))
1111 /* create the array class */
1113 c = class_array_of(comp, false);
1115 tmpc = classcache_store(cl, c, true);
1118 /* exception, free the loaded class */
1119 c->state &= ~CLASS_LOADING;
1126 /* load the component class */
1128 u = utf_new(text + 1, namelen - 1);
1130 if (!(comp = load_class_from_classloader(u, cl)))
1133 /* create the array class */
1135 c = class_array_of(comp, false);
1137 tmpc = classcache_store(cl, c, true);
1140 /* exception, free the loaded class */
1141 c->state &= ~CLASS_LOADING;
1148 /* primitive array classes are loaded by the bootstrap loader */
1150 c = load_class_bootstrap(name);
1156 LLNI_class_get(cl, c);
1158 #if defined(WITH_CLASSPATH_SUN)
1159 /* OpenJDK uses this internal function because it's
1162 lc = class_resolveclassmethod(c,
1163 utf_loadClassInternal,
1164 utf_java_lang_String__java_lang_Class,
1168 lc = class_resolveclassmethod(c,
1170 utf_java_lang_String__java_lang_Class,
1176 return false; /* exception */
1178 /* move return value into `o' and cast it afterwards to a classinfo* */
1180 string = javastring_new_slash_to_dot(name);
1182 RT_TIMING_GET_TIME(time_prepare);
1184 o = vm_call_method(lc, (java_handle_t *) cl, string);
1186 RT_TIMING_GET_TIME(time_java);
1188 c = LLNI_classinfo_unwrap(o);
1191 /* Store this class in the loaded class cache. If another
1192 class with the same (initloader,name) pair has been
1193 stored earlier it will be returned by classcache_store
1194 In this case classcache_store may not free the class
1195 because it has already been exposed to Java code which
1196 may have kept references to that class. */
1198 tmpc = classcache_store(cl, c, false);
1201 /* exception, free the loaded class */
1202 c->state &= ~CLASS_LOADING;
1209 RT_TIMING_GET_TIME(time_cache);
1211 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1212 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1213 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1215 /* SUN compatible -verbose:class output */
1217 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1219 utf_display_printable_ascii_classname(name);
1223 #if defined(ENABLE_JVMTI)
1224 /* fire Class Load JVMTI event */
1225 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1232 c = load_class_bootstrap(name);
1238 /* load_class_bootstrap ********************************************************
1240 Load the class with the given name using the bootstrap class loader.
1243 name.............the classname
1246 loaded classinfo, or
1247 NULL if an exception has been thrown
1250 load_class_bootstrap is synchronized. It can be treated as an
1253 *******************************************************************************/
1255 classinfo *load_class_bootstrap(utf *name)
1260 #if defined(ENABLE_RT_TIMING)
1261 struct timespec time_start, time_lookup, time_array, time_suck,
1262 time_load, time_cache;
1265 RT_TIMING_GET_TIME(time_start);
1271 /* lookup if this class has already been loaded */
1273 r = classcache_lookup(NULL, name);
1276 RT_TIMING_GET_TIME(time_lookup);
1277 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1282 RT_TIMING_GET_TIME(time_lookup);
1283 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1285 /* create the classinfo */
1287 c = class_create_classinfo(name);
1289 /* handle array classes */
1291 if (name->text[0] == '[') {
1292 c = load_newly_created_array(c, NULL);
1297 assert(c->state & CLASS_LOADED);
1299 RT_TIMING_GET_TIME(time_array);
1300 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1305 #if defined(ENABLE_STATISTICS)
1308 if (opt_getcompilingtime)
1309 compilingtime_stop();
1311 if (opt_getloadingtime)
1312 loadingtime_start();
1315 /* load classdata, throw exception on error */
1320 /* this normally means, the classpath was not set properly */
1322 if (name == utf_java_lang_Object)
1323 vm_abort("java/lang/NoClassDefFoundError: java/lang/Object");
1325 exceptions_throw_classnotfoundexception(name);
1330 RT_TIMING_GET_TIME(time_suck);
1332 /* load the class from the buffer */
1334 r = load_class_from_classbuffer(cb);
1336 RT_TIMING_GET_TIME(time_load);
1339 /* the class could not be loaded, free the classinfo struct */
1344 /* Store this class in the loaded class cache this step also
1345 checks the loading constraints. If the class has been loaded
1346 before, the earlier loaded class is returned. */
1348 classinfo *res = classcache_store(NULL, c, true);
1358 RT_TIMING_GET_TIME(time_cache);
1360 /* SUN compatible -verbose:class output */
1362 if (opt_verboseclass && r) {
1364 utf_display_printable_ascii_classname(name);
1365 printf(" from %s]\n", cb->path);
1372 #if defined(ENABLE_STATISTICS)
1375 if (opt_getloadingtime)
1378 if (opt_getcompilingtime)
1379 compilingtime_start();
1382 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1383 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1384 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1385 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1391 /* load_class_from_classbuffer_intern ******************************************
1393 Loads a class from a classbuffer into a given classinfo structure.
1394 Super-classes are also loaded at this point and some verfication
1398 This function is NOT synchronized!
1400 *******************************************************************************/
1402 static bool load_class_from_classbuffer_intern(classbuffer *cb)
1408 utf **interfacesnames;
1410 constant_classref *cr;
1415 descriptor_pool *descpool;
1416 #if defined(ENABLE_STATISTICS)
1420 #if defined(ENABLE_RT_TIMING)
1421 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1422 time_setup, time_fields, time_methods, time_classrefs,
1423 time_descs, time_setrefs, time_parsefds, time_parsemds,
1424 time_parsecpool, time_verify, time_attrs;
1427 RT_TIMING_GET_TIME(time_start);
1429 /* Get the classbuffer's class. */
1433 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1436 /* check signature */
1438 if (suck_u4(cb) != MAGIC) {
1439 exceptions_throw_classformaterror(c, "Bad magic number");
1448 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1449 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1453 RT_TIMING_GET_TIME(time_checks);
1455 /* create a new descriptor pool */
1457 descpool = descriptor_pool_new(c);
1459 RT_TIMING_GET_TIME(time_ndpool);
1461 /* load the constant pool */
1463 if (!load_constantpool(cb, descpool))
1466 RT_TIMING_GET_TIME(time_cpool);
1470 if (!suck_check_classbuffer_size(cb, 2))
1473 /* We OR the flags here, as we set already some flags in
1474 class_create_classinfo. */
1476 c->flags |= suck_u2(cb);
1478 /* check ACC flags consistency */
1480 if (c->flags & ACC_INTERFACE) {
1481 if (!(c->flags & ACC_ABSTRACT)) {
1482 /* We work around this because interfaces in JDK 1.1 are
1483 * not declared abstract. */
1485 c->flags |= ACC_ABSTRACT;
1488 if (c->flags & ACC_FINAL) {
1489 exceptions_throw_classformaterror(c,
1490 "Illegal class modifiers: 0x%X",
1495 if (c->flags & ACC_SUPER) {
1496 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1500 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1501 exceptions_throw_classformaterror(c,
1502 "Illegal class modifiers: 0x%X",
1507 if (!suck_check_classbuffer_size(cb, 2 + 2))
1512 index = suck_u2(cb);
1514 name = (utf *) class_getconstant(c, index, CONSTANT_Class);
1519 if (c->name == utf_not_named_yet) {
1520 /* we finally have a name for this class */
1522 class_set_packagename(c);
1524 else if (name != c->name) {
1525 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
1529 /* Retrieve superclass. */
1533 index = suck_u2(cb);
1538 /* This is only allowed for java.lang.Object. */
1540 if (c->name != utf_java_lang_Object) {
1541 exceptions_throw_classformaterror(c, "Bad superclass index");
1546 supername = (utf *) class_getconstant(c, index, CONSTANT_Class);
1548 if (supername == NULL)
1551 /* java.lang.Object may not have a super class. */
1553 if (c->name == utf_java_lang_Object) {
1554 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
1558 /* Detect circularity. */
1560 if (supername == c->name) {
1561 exceptions_throw_classcircularityerror(c);
1565 /* Interfaces must have java.lang.Object as super class. */
1567 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
1568 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
1573 /* Parse the super interfaces. */
1575 if (!suck_check_classbuffer_size(cb, 2))
1578 c->interfacescount = suck_u2(cb);
1580 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1583 c->interfaces = MNEW(classinfo*, c->interfacescount);
1585 /* Get the names of the super interfaces. */
1587 interfacesnames = DMNEW(utf*, c->interfacescount);
1589 for (i = 0; i < c->interfacescount; i++) {
1590 index = suck_u2(cb);
1592 u = (utf *) class_getconstant(c, index, CONSTANT_Class);
1597 interfacesnames[i] = u;
1600 RT_TIMING_GET_TIME(time_setup);
1604 if (!suck_check_classbuffer_size(cb, 2))
1607 c->fieldscount = suck_u2(cb);
1608 c->fields = MNEW(fieldinfo, c->fieldscount);
1610 MZERO(c->fields, fieldinfo, c->fieldscount);
1612 for (i = 0; i < c->fieldscount; i++) {
1613 if (!field_load(cb, &(c->fields[i]), descpool))
1617 RT_TIMING_GET_TIME(time_fields);
1619 /* Parse methods. */
1621 if (!suck_check_classbuffer_size(cb, 2))
1624 c->methodscount = suck_u2(cb);
1625 c->methods = MNEW(methodinfo, c->methodscount);
1627 MZERO(c->methods, methodinfo, c->methodscount);
1629 for (i = 0; i < c->methodscount; i++) {
1630 if (!method_load(cb, &(c->methods[i]), descpool))
1634 RT_TIMING_GET_TIME(time_methods);
1636 /* create the class reference table */
1639 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
1641 RT_TIMING_GET_TIME(time_classrefs);
1643 /* allocate space for the parsed descriptors */
1645 descriptor_pool_alloc_parsed_descriptors(descpool);
1647 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
1649 #if defined(ENABLE_STATISTICS)
1651 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
1652 count_classref_len += classrefsize;
1653 count_parsed_desc_len += descsize;
1657 RT_TIMING_GET_TIME(time_descs);
1659 /* put the classrefs in the constant pool */
1661 for (i = 0; i < c->cpcount; i++) {
1662 if (c->cptags[i] == CONSTANT_Class) {
1663 utf *name = (utf *) c->cpinfos[i];
1664 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
1668 /* Resolve the super class. */
1670 if (supername != NULL) {
1671 cr = descriptor_pool_lookup_classref(descpool, supername);
1676 /* XXX This should be done better. */
1677 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1682 /* Interfaces are not allowed as super classes. */
1684 if (tc->flags & ACC_INTERFACE) {
1685 exceptions_throw_incompatibleclasschangeerror(c, "class %s has interface %s as super class");
1689 /* Don't allow extending final classes */
1691 if (tc->flags & ACC_FINAL) {
1692 exceptions_throw_verifyerror(NULL,
1693 "Cannot inherit from final class");
1697 /* Store the super class. */
1702 /* Resolve the super interfaces. */
1704 for (i = 0; i < c->interfacescount; i++) {
1705 u = interfacesnames[i];
1706 cr = descriptor_pool_lookup_classref(descpool, u);
1711 /* XXX This should be done better. */
1712 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1717 /* Detect circularity. */
1720 exceptions_throw_classcircularityerror(c);
1724 if (!(tc->flags & ACC_INTERFACE)) {
1725 exceptions_throw_incompatibleclasschangeerror(tc,
1726 "Implementing class");
1730 /* Store the super interface. */
1732 c->interfaces[i] = tc;
1735 RT_TIMING_GET_TIME(time_setrefs);
1737 /* Parse the field descriptors. */
1739 for (i = 0; i < c->fieldscount; i++) {
1740 c->fields[i].parseddesc =
1741 descriptor_pool_parse_field_descriptor(descpool,
1742 c->fields[i].descriptor);
1743 if (!c->fields[i].parseddesc)
1747 RT_TIMING_GET_TIME(time_parsefds);
1749 /* parse method descriptors */
1751 for (i = 0; i < c->methodscount; i++) {
1752 methodinfo *m = &c->methods[i];
1754 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
1755 m->flags, class_get_self_classref(m->class));
1759 for (j = 0; j < m->rawexceptiontablelength; j++) {
1760 if (!m->rawexceptiontable[j].catchtype.any)
1763 if ((m->rawexceptiontable[j].catchtype.ref =
1764 descriptor_pool_lookup_classref(descpool,
1765 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
1769 for (j = 0; j < m->thrownexceptionscount; j++) {
1770 if (!m->thrownexceptions[j].any)
1773 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
1774 (utf *) m->thrownexceptions[j].any)) == NULL)
1779 RT_TIMING_GET_TIME(time_parsemds);
1781 /* parse the loaded descriptors */
1783 for (i = 0; i < c->cpcount; i++) {
1784 constant_FMIref *fmi;
1787 switch (c->cptags[i]) {
1788 case CONSTANT_Fieldref:
1789 fmi = (constant_FMIref *) c->cpinfos[i];
1790 fmi->parseddesc.fd =
1791 descriptor_pool_parse_field_descriptor(descpool,
1793 if (!fmi->parseddesc.fd)
1796 index = fmi->p.index;
1798 (constant_classref *) class_getconstant(c, index,
1800 if (!fmi->p.classref)
1803 case CONSTANT_Methodref:
1804 case CONSTANT_InterfaceMethodref:
1805 fmi = (constant_FMIref *) c->cpinfos[i];
1806 index = fmi->p.index;
1808 (constant_classref *) class_getconstant(c, index,
1810 if (!fmi->p.classref)
1812 fmi->parseddesc.md =
1813 descriptor_pool_parse_method_descriptor(descpool,
1817 if (!fmi->parseddesc.md)
1823 RT_TIMING_GET_TIME(time_parsecpool);
1825 #ifdef ENABLE_VERIFIER
1826 /* Check if all fields and methods can be uniquely
1827 * identified by (name,descriptor). */
1830 /* We use a hash table here to avoid making the
1831 * average case quadratic in # of methods, fields.
1833 static int shift = 0;
1835 u2 *next; /* for chaining colliding hash entries */
1841 /* Allocate hashtable */
1842 len = c->methodscount;
1843 if (len < c->fieldscount) len = c->fieldscount;
1845 hashtab = MNEW(u2,(hashlen + len));
1846 next = hashtab + hashlen;
1848 /* Determine bitshift (to get good hash values) */
1858 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
1860 for (i = 0; i < c->fieldscount; ++i) {
1861 fieldinfo *fi = c->fields + i;
1863 /* It's ok if we lose bits here */
1864 index = ((((size_t) fi->name) +
1865 ((size_t) fi->descriptor)) >> shift) % hashlen;
1867 if ((old = hashtab[index])) {
1871 if (c->fields[old].name == fi->name &&
1872 c->fields[old].descriptor == fi->descriptor) {
1873 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
1876 } while ((old = next[old]));
1878 hashtab[index] = i + 1;
1882 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
1884 for (i = 0; i < c->methodscount; ++i) {
1885 methodinfo *mi = c->methods + i;
1887 /* It's ok if we lose bits here */
1888 index = ((((size_t) mi->name) +
1889 ((size_t) mi->descriptor)) >> shift) % hashlen;
1891 if ((old = hashtab[index])) {
1895 if (c->methods[old].name == mi->name &&
1896 c->methods[old].descriptor == mi->descriptor) {
1897 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
1900 } while ((old = next[old]));
1902 hashtab[index] = i + 1;
1905 MFREE(hashtab, u2, (hashlen + len));
1907 #endif /* ENABLE_VERIFIER */
1909 RT_TIMING_GET_TIME(time_verify);
1911 #if defined(ENABLE_STATISTICS)
1913 size_classinfo += sizeof(classinfo*) * c->interfacescount;
1914 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
1915 size_methodinfo += sizeof(methodinfo) * c->methodscount;
1919 /* load attribute structures */
1921 if (!class_load_attributes(cb))
1924 /* Pre Java 1.5 version don't check this. This implementation is
1925 like Java 1.5 do it: for class file version 45.3 we don't check
1926 it, older versions are checked. */
1928 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
1929 /* check if all data has been read */
1930 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
1932 if (classdata_left > 0) {
1933 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
1938 RT_TIMING_GET_TIME(time_attrs);
1940 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
1941 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
1942 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
1943 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
1944 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
1945 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
1946 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
1947 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
1948 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
1949 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
1950 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
1951 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
1952 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
1953 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
1954 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
1960 /* load_class_from_classbuffer *************************************************
1962 Convenience wrapper for load_class_from_classbuffer.
1965 This function is NOT synchronized!
1967 *******************************************************************************/
1969 classinfo *load_class_from_classbuffer(classbuffer *cb)
1975 /* Get the classbuffer's class. */
1979 /* Check if the class is already loaded. */
1981 if (c->state & CLASS_LOADED)
1984 #if defined(ENABLE_STATISTICS)
1986 count_class_loads++;
1989 #if !defined(NDEBUG)
1991 log_message_class("Loading class: ", c);
1994 /* Mark start of dump memory area. */
1996 dumpsize = dump_size();
1998 /* Class is currently loading. */
2000 c->state |= CLASS_LOADING;
2002 /* Parse the classbuffer. */
2004 result = load_class_from_classbuffer_intern(cb);
2006 /* Release dump area. */
2008 dump_release(dumpsize);
2010 /* An error occurred. */
2012 if (result == false) {
2013 /* Revert loading state. */
2015 c->state = (c->state & ~CLASS_LOADING);
2020 /* Revert loading state and set loaded. */
2022 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2024 #if defined(ENABLE_JVMTI)
2025 /* fire Class Prepare JVMTI event */
2028 jvmti_ClassLoadPrepare(true, c);
2031 #if !defined(NDEBUG)
2033 log_message_class("Loading done class: ", c);
2040 /* load_newly_created_array ****************************************************
2042 Load a newly created array class.
2045 c....................the array class C has been loaded
2046 other classinfo......the array class was found in the class cache,
2048 NULL.................an exception has been thrown
2051 This is an internal function. Do not use it unless you know exactly
2054 Use one of the load_class_... functions for general array class loading.
2056 *******************************************************************************/
2058 classinfo *load_newly_created_array(classinfo *c, classloader *loader)
2060 classinfo *comp = NULL;
2062 methoddesc *clonedesc;
2063 constant_classref *classrefs;
2068 text = c->name->text;
2069 namelen = c->name->blength;
2071 /* Check array class name */
2073 if ((namelen < 2) || (text[0] != '[')) {
2074 exceptions_throw_classnotfoundexception(c->name);
2078 /* Check the element type */
2082 /* c is an array of arrays. We have to create the component class. */
2084 u = utf_new(text + 1, namelen - 1);
2086 comp = load_class_from_classloader(u, loader);
2091 assert(comp->state & CLASS_LOADED);
2093 /* the array's flags are that of the component class */
2094 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2095 c->classloader = comp->classloader;
2099 /* c is an array of objects. */
2101 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2102 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2103 exceptions_throw_classnotfoundexception(c->name);
2107 u = utf_new(text + 2, namelen - 3);
2109 if (!(comp = load_class_from_classloader(u, loader)))
2112 assert(comp->state & CLASS_LOADED);
2114 /* the array's flags are that of the component class */
2115 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2116 c->classloader = comp->classloader;
2120 /* c is an array of a primitive type */
2122 /* check for cases like `[II' and whether the character is a
2123 valid primitive type */
2125 if ((namelen > 2) || (primitive_class_get_by_char(text[1]) == NULL)) {
2126 exceptions_throw_classnotfoundexception(c->name);
2130 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2131 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2132 c->classloader = NULL;
2135 assert(class_java_lang_Object);
2136 #if defined(ENABLE_JAVASE)
2137 assert(class_java_lang_Cloneable);
2138 assert(class_java_io_Serializable);
2141 /* Setup the array class. */
2143 c->super = class_java_lang_Object;
2145 #if defined(ENABLE_JAVASE)
2147 c->interfacescount = 2;
2148 c->interfaces = MNEW(classinfo*, 2);
2149 c->interfaces[0] = class_java_lang_Cloneable;
2150 c->interfaces[1] = class_java_io_Serializable;
2152 #elif defined(ENABLE_JAVAME_CLDC1_1)
2154 c->interfacescount = 0;
2155 c->interfaces = NULL;
2158 # error unknow Java configuration
2161 c->methodscount = 1;
2162 c->methods = MNEW(methodinfo, c->methodscount);
2164 MZERO(c->methods, methodinfo, c->methodscount);
2166 classrefs = MNEW(constant_classref, 2);
2168 CLASSREF_INIT(classrefs[0], c, c->name);
2169 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2171 /* create descriptor for clone method */
2172 /* we need one paramslot which is reserved for the 'this' parameter */
2173 clonedesc = NEW(methoddesc);
2174 clonedesc->returntype.type = TYPE_ADR;
2175 clonedesc->returntype.classref = classrefs + 1;
2176 clonedesc->returntype.arraydim = 0;
2177 /* initialize params to "empty", add real params below in
2178 descriptor_params_from_paramtypes */
2179 clonedesc->paramcount = 0;
2180 clonedesc->paramslots = 0;
2181 clonedesc->paramtypes[0].classref = classrefs + 0;
2182 clonedesc->params = NULL;
2184 /* create methodinfo */
2187 MSET(clone, 0, methodinfo, 1);
2189 #if defined(ENABLE_THREADS)
2190 lock_init_object_lock(&clone->header);
2193 /* ATTENTION: if you delete the ACC_NATIVE below, set
2194 clone->maxlocals=1 (interpreter related) */
2196 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2197 clone->name = utf_clone;
2198 clone->descriptor = utf_void__java_lang_Object;
2199 clone->parseddesc = clonedesc;
2202 /* parse the descriptor to get the register allocation */
2204 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2207 clone->code = codegen_generate_stub_native(clone, BUILTIN_clone);
2209 /* XXX: field: length? */
2211 /* array classes are not loaded from class files */
2213 c->state |= CLASS_LOADED;
2214 c->parseddescs = (u1 *) clonedesc;
2215 c->parseddescsize = sizeof(methodinfo);
2216 c->classrefs = classrefs;
2217 c->classrefcount = 1;
2219 /* insert class into the loaded class cache */
2220 /* XXX free classinfo if NULL returned? */
2222 return classcache_store(loader, c, true);
2226 /* loader_close ****************************************************************
2228 Frees all resources.
2230 *******************************************************************************/
2232 void loader_close(void)
2239 * These are local overrides for various environment variables in Emacs.
2240 * Please do not remove this and leave it at the end of the file, where
2241 * Emacs will automagically detect them.
2242 * ---------------------------------------------------------------------
2245 * indent-tabs-mode: t
2249 * vim:noexpandtab:sw=4:ts=4: