1 /* src/vm/loader.cpp - 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"
39 #include "threads/mutex.hpp"
41 #include "toolbox/hashtable.h"
42 #include "toolbox/logging.h"
44 #include "vm/jit/builtin.hpp"
45 #include "vm/classcache.h"
46 #include "vm/exceptions.hpp"
48 #include "vm/global.h"
49 #include "vm/globals.hpp"
50 #include "vm/linker.h"
51 #include "vm/loader.hpp"
52 #include "vm/method.h"
53 #include "vm/options.h"
54 #include "vm/package.hpp"
55 #include "vm/primitive.hpp"
56 #include "vm/resolve.h"
57 #include "vm/rt-timing.h"
58 #include "vm/string.hpp"
63 #if defined(ENABLE_JAVASE)
64 # include "vm/annotation.h"
65 # include "vm/stackmap.h"
68 #if defined(ENABLE_STATISTICS)
69 # include "vm/statistics.h"
72 #if defined(ENABLE_ZLIB)
76 #include "vm/jit/stubs.hpp"
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 NOTE: Exceptions thrown during VM initialization are caught in the
94 exception functions themselves.
96 *******************************************************************************/
98 void loader_preinit(void)
100 #if defined(ENABLE_THREADS)
101 list_classpath_entry *lce;
104 TRACESUBSYSTEMINITIALIZATION("loader_preinit");
106 #if defined(ENABLE_THREADS)
107 /* Initialize the monitor pointer for zip/jar file locking. */
109 for (lce = (list_classpath_entry*) list_first(list_classpath_entries); lce != NULL;
110 lce = (list_classpath_entry*) list_next(list_classpath_entries, lce)) {
111 if (lce->type == CLASSPATH_ARCHIVE)
112 LOCK_INIT_OBJECT_LOCK(lce);
116 /* initialize classloader hashtable, 10 entries should be enough */
118 hashtable_classloader = NEW(hashtable);
119 hashtable_create(hashtable_classloader, 10);
121 /* Load the most basic classes. */
123 assert(VM::get_current()->is_initializing() == true);
125 class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object);
127 #if defined(ENABLE_JAVASE)
128 class_java_lang_Cloneable = load_class_bootstrap(utf_java_lang_Cloneable);
129 class_java_io_Serializable = load_class_bootstrap(utf_java_io_Serializable);
134 /* loader_init *****************************************************************
136 Loads all classes required in the VM.
138 NOTE: Exceptions thrown during VM initialization are caught in the
139 exception functions themselves.
141 *******************************************************************************/
143 void loader_init(void)
145 TRACESUBSYSTEMINITIALIZATION("loader_init");
147 /* Load primitive-type wrapping classes. */
149 assert(VM::get_current()->is_initializing() == true);
151 #if defined(ENABLE_JAVASE)
152 class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void);
155 class_java_lang_Boolean = load_class_bootstrap(utf_java_lang_Boolean);
156 class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte);
157 class_java_lang_Character = load_class_bootstrap(utf_java_lang_Character);
158 class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short);
159 class_java_lang_Integer = load_class_bootstrap(utf_java_lang_Integer);
160 class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long);
161 class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float);
162 class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double);
164 /* Load important system classes. */
166 class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class);
167 class_java_lang_String = load_class_bootstrap(utf_java_lang_String);
169 #if defined(ENABLE_JAVASE)
170 class_java_lang_ClassLoader =
171 load_class_bootstrap(utf_java_lang_ClassLoader);
173 class_java_lang_SecurityManager =
174 load_class_bootstrap(utf_java_lang_SecurityManager);
177 class_java_lang_System =
178 load_class_bootstrap(utf_new_char("java/lang/System"));
180 class_java_lang_Thread =
181 load_class_bootstrap(utf_new_char("java/lang/Thread"));
183 #if defined(ENABLE_JAVASE)
184 class_java_lang_ThreadGroup =
185 load_class_bootstrap(utf_java_lang_ThreadGroup);
188 class_java_lang_Throwable = load_class_bootstrap(utf_java_lang_Throwable);
190 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
191 class_java_lang_VMSystem =
192 load_class_bootstrap(utf_new_char("java/lang/VMSystem"));
194 class_java_lang_VMThread =
195 load_class_bootstrap(utf_new_char("java/lang/VMThread"));
197 class_java_lang_VMThrowable =
198 load_class_bootstrap(utf_new_char("java/lang/VMThrowable"));
201 /* Important system exceptions. */
203 class_java_lang_Exception = load_class_bootstrap(utf_java_lang_Exception);
205 class_java_lang_ClassNotFoundException =
206 load_class_bootstrap(utf_java_lang_ClassNotFoundException);
208 class_java_lang_RuntimeException =
209 load_class_bootstrap(utf_java_lang_RuntimeException);
211 /* Some classes which may be used often. */
213 #if defined(ENABLE_JAVASE)
214 class_java_lang_StackTraceElement = load_class_bootstrap(utf_java_lang_StackTraceElement);
216 class_java_lang_reflect_Constructor = load_class_bootstrap(utf_java_lang_reflect_Constructor);
217 class_java_lang_reflect_Field = load_class_bootstrap(utf_java_lang_reflect_Field);
218 class_java_lang_reflect_Method = load_class_bootstrap(utf_java_lang_reflect_Method);
220 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
221 class_java_lang_reflect_VMConstructor = load_class_bootstrap(utf_java_lang_reflect_VMConstructor);
222 class_java_lang_reflect_VMField = load_class_bootstrap(utf_java_lang_reflect_VMField);
223 class_java_lang_reflect_VMMethod = load_class_bootstrap(utf_java_lang_reflect_VMMethod);
226 class_java_security_PrivilegedAction = load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"));
228 class_java_util_HashMap = load_class_bootstrap(utf_new_char("java/util/HashMap"));
229 class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector);
231 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
232 class_sun_misc_Signal = load_class_bootstrap(utf_new_char("sun/misc/Signal"));
233 class_sun_reflect_MagicAccessorImpl = load_class_bootstrap(utf_new_char("sun/reflect/MagicAccessorImpl"));
236 arrayclass_java_lang_Object =
237 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"));
239 # if defined(ENABLE_ANNOTATIONS)
240 /* needed by annotation support */
241 class_sun_reflect_ConstantPool =
242 load_class_bootstrap(utf_new_char("sun/reflect/ConstantPool"));
244 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
245 /* needed by GNU Classpaths annotation support */
246 class_sun_reflect_annotation_AnnotationParser =
247 load_class_bootstrap(utf_new_char("sun/reflect/annotation/AnnotationParser"));
254 /* loader_hashtable_classloader_add ********************************************
256 Adds an entry to the classloader hashtable.
258 REMEMBER: Also use this to register native loaders!
260 *******************************************************************************/
262 classloader_t *loader_hashtable_classloader_add(java_handle_t *cl)
264 hashtable_classloader_entry *cle;
271 hashtable_classloader->mutex->lock();
275 /* key for entry is the hashcode of the classloader;
276 aligned to 16-byte boundaries */
278 key = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
279 slot = key & (hashtable_classloader->size - 1);
280 cle = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
282 /* search hashchain for existing entry */
285 if (cle->object == LLNI_DIRECT(cl))
293 /* if no classloader was found, we create a new entry here */
296 cle = NEW(hashtable_classloader_entry);
298 #if defined(ENABLE_GC_CACAO)
299 /* register the classloader object with the GC */
301 gc_reference_register(&(cle->object), GC_REFTYPE_CLASSLOADER);
306 cle->object = LLNI_DIRECT(cl);
310 /*#define LOADER_DEBUG_CLASSLOADER*/
311 #ifdef LOADER_DEBUG_CLASSLOADER
312 printf("CLASSLOADER: adding new classloader entry %p for %p: ", cle, cl);
313 class_print(LLNI_vftbl_direct(cl)->class);
318 /* insert entry into hashtable */
320 cle->hashlink = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
321 hashtable_classloader->ptr[slot] = cle;
323 /* update number of entries */
325 hashtable_classloader->entries++;
328 hashtable_classloader->mutex->unlock();
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_entry*) 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)
401 hashtable_zipfile_entry *htzfe;
405 for (lce = (list_classpath_entry*) list_first(list_classpath_entries); lce != NULL;
406 lce = (list_classpath_entry*) list_next(list_classpath_entries, lce)) {
407 #if defined(ENABLE_ZLIB)
408 if (lce->type == CLASSPATH_ARCHIVE) {
409 /* get the classes hashtable */
413 for (uint32_t slot = 0; slot < ht->size; slot++) {
414 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
416 for (; htzfe; htzfe = htzfe->hashlink) {
419 /* skip all entries in META-INF and .properties,
422 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
423 strstr(u->text, ".properties") ||
424 strstr(u->text, ".png"))
427 /* load class from bootstrap classloader */
429 if (!load_class_bootstrap(u)) {
430 fprintf(stderr, "Error loading: ");
431 utf_fprint_printable_ascii_classname(stderr, u);
432 fprintf(stderr, "\n");
435 /* print out exception and cause */
437 exceptions_print_current_exception();
445 #if defined(ENABLE_ZLIB)
452 /* loader_skip_attribute_body **************************************************
454 Skips an attribute the attribute_name_index has already been read.
457 u2 attribute_name_index;
459 u1 info[attribute_length];
462 *******************************************************************************/
464 bool loader_skip_attribute_body(classbuffer *cb)
468 if (!suck_check_classbuffer_size(cb, 4))
471 attribute_length = suck_u4(cb);
473 if (!suck_check_classbuffer_size(cb, attribute_length))
476 suck_skip_nbytes(cb, attribute_length);
482 /* load_constantpool ***********************************************************
484 Loads the constantpool of a class, the entries are transformed into
485 a simpler format by resolving references (a detailed overview of
486 the compact structures can be found in global.h).
488 *******************************************************************************/
490 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
493 /* The following structures are used to save information which cannot be
494 processed during the first pass. After the complete constantpool has
495 been traversed the references can be resolved.
496 (only in specific order) */
498 /* CONSTANT_Class entries */
499 typedef struct forward_class {
500 struct forward_class *next;
505 /* CONSTANT_String */
506 typedef struct forward_string {
507 struct forward_string *next;
512 /* CONSTANT_NameAndType */
513 typedef struct forward_nameandtype {
514 struct forward_nameandtype *next;
518 } forward_nameandtype;
520 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
521 typedef struct forward_fieldmethint {
522 struct forward_fieldmethint *next;
526 u2 nameandtype_index;
527 } forward_fieldmethint;
533 forward_class *forward_classes = NULL;
534 forward_string *forward_strings = NULL;
535 forward_nameandtype *forward_nameandtypes = NULL;
536 forward_fieldmethint *forward_fieldmethints = NULL;
540 forward_nameandtype *nfn;
541 forward_fieldmethint *nff;
549 /* number of entries in the constant_pool table plus one */
550 if (!suck_check_classbuffer_size(cb, 2))
553 cpcount = c->cpcount = suck_u2(cb);
555 /* allocate memory */
556 cptags = c->cptags = MNEW(u1, cpcount);
557 cpinfos = c->cpinfos = MNEW(void*, cpcount);
560 exceptions_throw_classformaterror(c, "Illegal constant pool size");
564 #if defined(ENABLE_STATISTICS)
566 count_const_pool_len += (sizeof(u1) + sizeof(void*)) * cpcount;
569 /* initialize constantpool */
570 for (idx = 0; idx < cpcount; idx++) {
571 cptags[idx] = CONSTANT_UNUSED;
576 /******* first pass *******/
577 /* entries which cannot be resolved now are written into
578 temporary structures and traversed again later */
581 while (idx < cpcount) {
584 /* get constant type */
585 if (!suck_check_classbuffer_size(cb, 1))
592 nfc = DNEW(forward_class);
594 nfc->next = forward_classes;
595 forward_classes = nfc;
597 nfc->thisindex = idx;
598 /* reference to CONSTANT_NameAndType */
599 if (!suck_check_classbuffer_size(cb, 2))
602 nfc->name_index = suck_u2(cb);
607 case CONSTANT_String:
608 nfs = DNEW(forward_string);
610 nfs->next = forward_strings;
611 forward_strings = nfs;
613 nfs->thisindex = idx;
615 /* reference to CONSTANT_Utf8_info with string characters */
616 if (!suck_check_classbuffer_size(cb, 2))
619 nfs->string_index = suck_u2(cb);
624 case CONSTANT_NameAndType:
625 nfn = DNEW(forward_nameandtype);
627 nfn->next = forward_nameandtypes;
628 forward_nameandtypes = nfn;
630 nfn->thisindex = idx;
632 if (!suck_check_classbuffer_size(cb, 2 + 2))
635 /* reference to CONSTANT_Utf8_info containing simple name */
636 nfn->name_index = suck_u2(cb);
638 /* reference to CONSTANT_Utf8_info containing field or method
640 nfn->sig_index = suck_u2(cb);
645 case CONSTANT_Fieldref:
646 case CONSTANT_Methodref:
647 case CONSTANT_InterfaceMethodref:
648 nff = DNEW(forward_fieldmethint);
650 nff->next = forward_fieldmethints;
651 forward_fieldmethints = nff;
653 nff->thisindex = idx;
657 if (!suck_check_classbuffer_size(cb, 2 + 2))
660 /* class or interface type that contains the declaration of the
662 nff->class_index = suck_u2(cb);
664 /* name and descriptor of the field or method */
665 nff->nameandtype_index = suck_u2(cb);
670 case CONSTANT_Integer: {
671 constant_integer *ci = NEW(constant_integer);
673 #if defined(ENABLE_STATISTICS)
675 count_const_pool_len += sizeof(constant_integer);
678 if (!suck_check_classbuffer_size(cb, 4))
681 ci->value = suck_s4(cb);
682 cptags[idx] = CONSTANT_Integer;
689 case CONSTANT_Float: {
690 constant_float *cf = NEW(constant_float);
692 #if defined(ENABLE_STATISTICS)
694 count_const_pool_len += sizeof(constant_float);
697 if (!suck_check_classbuffer_size(cb, 4))
700 cf->value = suck_float(cb);
701 cptags[idx] = CONSTANT_Float;
708 case CONSTANT_Long: {
709 constant_long *cl = NEW(constant_long);
711 #if defined(ENABLE_STATISTICS)
713 count_const_pool_len += sizeof(constant_long);
716 if (!suck_check_classbuffer_size(cb, 8))
719 cl->value = suck_s8(cb);
720 cptags[idx] = CONSTANT_Long;
724 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
730 case CONSTANT_Double: {
731 constant_double *cd = NEW(constant_double);
733 #if defined(ENABLE_STATISTICS)
735 count_const_pool_len += sizeof(constant_double);
738 if (!suck_check_classbuffer_size(cb, 8))
741 cd->value = suck_double(cb);
742 cptags[idx] = CONSTANT_Double;
746 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
752 case CONSTANT_Utf8: {
755 /* number of bytes in the bytes array (not string-length) */
756 if (!suck_check_classbuffer_size(cb, 2))
759 length = suck_u2(cb);
760 cptags[idx] = CONSTANT_Utf8;
762 /* validate the string */
763 if (!suck_check_classbuffer_size(cb, length))
766 #ifdef ENABLE_VERIFIER
768 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
770 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
773 #endif /* ENABLE_VERIFIER */
774 /* insert utf-string into the utf-symboltable */
775 cpinfos[idx] = utf_new((char *) cb->pos, length);
777 /* skip bytes of the string (buffer size check above) */
778 suck_skip_nbytes(cb, length);
784 exceptions_throw_classformaterror(c, "Illegal constant pool type");
790 /* resolve entries in temporary structures */
792 while (forward_classes) {
793 utf *name = (utf*) class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
797 #ifdef ENABLE_VERIFIER
798 if (opt_verify && !is_valid_name_utf(name)) {
799 exceptions_throw_classformaterror(c, "Class reference with invalid name");
802 #endif /* ENABLE_VERIFIER */
804 /* add all class references to the descriptor_pool */
806 if (!descriptor_pool_add_class(descpool, name))
809 cptags[forward_classes->thisindex] = CONSTANT_Class;
811 /* the classref is created later */
812 cpinfos[forward_classes->thisindex] = name;
814 nfc = forward_classes;
815 forward_classes = forward_classes->next;
818 while (forward_strings) {
819 utf *text = (utf*) class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
824 /* resolve utf-string */
825 cptags[forward_strings->thisindex] = CONSTANT_String;
826 cpinfos[forward_strings->thisindex] = text;
828 nfs = forward_strings;
829 forward_strings = forward_strings->next;
832 while (forward_nameandtypes) {
833 constant_nameandtype *cn = NEW(constant_nameandtype);
835 #if defined(ENABLE_STATISTICS)
837 count_const_pool_len += sizeof(constant_nameandtype);
840 /* resolve simple name and descriptor */
841 cn->name = (utf*) class_getconstant(c,
842 forward_nameandtypes->name_index,
847 cn->descriptor = (utf*) class_getconstant(c,
848 forward_nameandtypes->sig_index,
853 #ifdef ENABLE_VERIFIER
856 if (!is_valid_name_utf(cn->name)) {
857 exceptions_throw_classformaterror(c,
858 "Illegal Field name \"%s\"",
864 /* disallow referencing <clinit> among others */
865 if (cn->name->text[0] == '<' && cn->name != utf_init) {
866 exceptions_throw_classformaterror(c, "Illegal reference to special method");
870 #endif /* ENABLE_VERIFIER */
872 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
873 cpinfos[forward_nameandtypes->thisindex] = cn;
875 nfn = forward_nameandtypes;
876 forward_nameandtypes = forward_nameandtypes->next;
879 while (forward_fieldmethints) {
880 constant_nameandtype *nat;
881 constant_FMIref *fmi = NEW(constant_FMIref);
883 #if defined(ENABLE_STATISTICS)
885 count_const_pool_len += sizeof(constant_FMIref);
887 /* resolve simple name and descriptor */
889 nat = (constant_nameandtype*) class_getconstant(c,
890 forward_fieldmethints->nameandtype_index,
891 CONSTANT_NameAndType);
896 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
898 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
901 /* the classref is created later */
903 fmi->p.index = forward_fieldmethints->class_index;
904 fmi->name = nat->name;
905 fmi->descriptor = nat->descriptor;
907 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
908 cpinfos[forward_fieldmethints->thisindex] = fmi;
910 nff = forward_fieldmethints;
911 forward_fieldmethints = forward_fieldmethints->next;
914 /* everything was ok */
920 /* loader_load_attribute_signature *********************************************
922 Signature_attribute {
923 u2 attribute_name_index;
928 *******************************************************************************/
930 #if defined(ENABLE_JAVASE)
931 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
941 /* check remaining bytecode */
943 if (!suck_check_classbuffer_size(cb, 4 + 2))
946 /* check attribute length */
948 attribute_length = suck_u4(cb);
950 if (attribute_length != 2) {
951 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
955 if (*signature != NULL) {
956 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
962 signature_index = suck_u2(cb);
964 *signature = (utf*) class_getconstant(c, signature_index, CONSTANT_Utf8);
966 if (*signature == NULL)
971 #endif /* defined(ENABLE_JAVASE) */
974 /* load_class_from_sysloader ***************************************************
976 Load the class with the given name using the system class loader
979 name.............the classname
983 NULL if an exception has been thrown
985 *******************************************************************************/
987 classinfo *load_class_from_sysloader(utf *name)
994 assert(class_java_lang_Object);
995 assert(class_java_lang_ClassLoader);
996 assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
998 m = class_resolveclassmethod(class_java_lang_ClassLoader,
999 utf_getSystemClassLoader,
1000 utf_void__java_lang_ClassLoader,
1001 class_java_lang_Object,
1007 clo = vm_call_method(m, NULL);
1012 cl = loader_hashtable_classloader_add(clo);
1014 c = load_class_from_classloader(name, cl);
1020 /* load_class_from_classloader *************************************************
1022 Load the class with the given name using the given user-defined class loader.
1025 name.............the classname
1026 cl...............user-defined class loader
1029 the loaded class, or
1030 NULL if an exception has been thrown
1032 *******************************************************************************/
1034 classinfo *load_class_from_classloader(utf *name, classloader_t *cl)
1039 java_handle_t *string;
1040 #if defined(ENABLE_RT_TIMING)
1041 struct timespec time_start, time_lookup, time_prepare, time_java,
1045 RT_TIMING_GET_TIME(time_start);
1049 /* lookup if this class has already been loaded */
1051 c = classcache_lookup(cl, name);
1053 RT_TIMING_GET_TIME(time_lookup);
1054 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1059 /* if other class loader than bootstrap, call it */
1067 namelen = name->blength;
1069 /* handle array classes */
1070 if (text[0] == '[') {
1076 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1077 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1078 exceptions_throw_classnotfoundexception(name);
1082 u = utf_new(text + 2, namelen - 3);
1084 if (!(comp = load_class_from_classloader(u, cl)))
1087 /* create the array class */
1089 c = class_array_of(comp, false);
1091 tmpc = classcache_store(cl, c, true);
1094 /* exception, free the loaded class */
1095 c->state &= ~CLASS_LOADING;
1102 /* load the component class */
1104 u = utf_new(text + 1, namelen - 1);
1106 if (!(comp = load_class_from_classloader(u, cl)))
1109 /* create the array class */
1111 c = class_array_of(comp, false);
1113 tmpc = classcache_store(cl, c, true);
1116 /* exception, free the loaded class */
1117 c->state &= ~CLASS_LOADING;
1124 /* primitive array classes are loaded by the bootstrap loader */
1126 c = load_class_bootstrap(name);
1132 LLNI_class_get(cl, c);
1134 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1135 /* OpenJDK uses this internal function because it's
1138 lc = class_resolveclassmethod(c,
1139 utf_loadClassInternal,
1140 utf_java_lang_String__java_lang_Class,
1144 lc = class_resolveclassmethod(c,
1146 utf_java_lang_String__java_lang_Class,
1152 return false; /* exception */
1154 /* move return value into `o' and cast it afterwards to a classinfo* */
1156 string = javastring_new_slash_to_dot(name);
1158 RT_TIMING_GET_TIME(time_prepare);
1160 o = vm_call_method(lc, (java_handle_t *) cl, string);
1162 RT_TIMING_GET_TIME(time_java);
1164 c = LLNI_classinfo_unwrap(o);
1167 /* Store this class in the loaded class cache. If another
1168 class with the same (initloader,name) pair has been
1169 stored earlier it will be returned by classcache_store
1170 In this case classcache_store may not free the class
1171 because it has already been exposed to Java code which
1172 may have kept references to that class. */
1174 tmpc = classcache_store(cl, c, false);
1177 /* exception, free the loaded class */
1178 c->state &= ~CLASS_LOADING;
1185 RT_TIMING_GET_TIME(time_cache);
1187 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1188 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1189 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1191 /* SUN compatible -verbose:class output */
1193 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1195 utf_display_printable_ascii_classname(name);
1199 #if defined(ENABLE_JVMTI)
1200 /* fire Class Load JVMTI event */
1201 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1208 c = load_class_bootstrap(name);
1214 /* load_class_bootstrap ********************************************************
1216 Load the class with the given name using the bootstrap class loader.
1219 name.............the classname
1222 loaded classinfo, or
1223 NULL if an exception has been thrown
1226 load_class_bootstrap is synchronized. It can be treated as an
1229 *******************************************************************************/
1231 classinfo *load_class_bootstrap(utf *name)
1236 #if defined(ENABLE_RT_TIMING)
1237 struct timespec time_start, time_lookup, time_array, time_suck,
1238 time_load, time_cache;
1241 RT_TIMING_GET_TIME(time_start);
1247 /* lookup if this class has already been loaded */
1249 r = classcache_lookup(NULL, name);
1252 RT_TIMING_GET_TIME(time_lookup);
1253 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1258 RT_TIMING_GET_TIME(time_lookup);
1259 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1261 /* create the classinfo */
1263 c = class_create_classinfo(name);
1265 /* handle array classes */
1267 if (name->text[0] == '[') {
1268 c = load_newly_created_array(c, NULL);
1273 assert(c->state & CLASS_LOADED);
1275 RT_TIMING_GET_TIME(time_array);
1276 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1281 #if defined(ENABLE_STATISTICS)
1284 if (opt_getcompilingtime)
1285 compilingtime_stop();
1287 if (opt_getloadingtime)
1288 loadingtime_start();
1291 /* load classdata, throw exception on error */
1296 exceptions_throw_classnotfoundexception(name);
1300 RT_TIMING_GET_TIME(time_suck);
1302 /* load the class from the buffer */
1304 r = load_class_from_classbuffer(cb);
1306 RT_TIMING_GET_TIME(time_load);
1309 /* the class could not be loaded, free the classinfo struct */
1314 /* Store this class in the loaded class cache this step also
1315 checks the loading constraints. If the class has been
1316 loaded before, the earlier loaded class is returned. */
1318 classinfo *res = classcache_store(NULL, c, true);
1325 // 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;
1388 descriptor_pool *descpool;
1389 #if defined(ENABLE_STATISTICS)
1393 #if defined(ENABLE_RT_TIMING)
1394 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1395 time_setup, time_fields, time_methods, time_classrefs,
1396 time_descs, time_setrefs, time_parsefds, time_parsemds,
1397 time_parsecpool, time_verify, time_attrs;
1400 RT_TIMING_GET_TIME(time_start);
1402 /* Get the classbuffer's class. */
1406 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1409 /* check signature */
1411 if (suck_u4(cb) != MAGIC) {
1412 exceptions_throw_classformaterror(c, "Bad magic number");
1421 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1422 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1426 RT_TIMING_GET_TIME(time_checks);
1428 /* create a new descriptor pool */
1430 descpool = descriptor_pool_new(c);
1432 RT_TIMING_GET_TIME(time_ndpool);
1434 /* load the constant pool */
1436 if (!load_constantpool(cb, descpool))
1439 RT_TIMING_GET_TIME(time_cpool);
1443 if (!suck_check_classbuffer_size(cb, 2))
1446 /* We OR the flags here, as we set already some flags in
1447 class_create_classinfo. */
1449 c->flags |= suck_u2(cb);
1451 /* check ACC flags consistency */
1453 if (c->flags & ACC_INTERFACE) {
1454 if (!(c->flags & ACC_ABSTRACT)) {
1455 /* We work around this because interfaces in JDK 1.1 are
1456 * not declared abstract. */
1458 c->flags |= ACC_ABSTRACT;
1461 if (c->flags & ACC_FINAL) {
1462 exceptions_throw_classformaterror(c,
1463 "Illegal class modifiers: 0x%X",
1468 if (c->flags & ACC_SUPER) {
1469 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1473 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1474 exceptions_throw_classformaterror(c,
1475 "Illegal class modifiers: 0x%X",
1480 if (!suck_check_classbuffer_size(cb, 2 + 2))
1485 index = suck_u2(cb);
1487 name = (utf *) class_getconstant(c, index, CONSTANT_Class);
1492 if (c->name == utf_not_named_yet) {
1493 /* we finally have a name for this class */
1495 class_set_packagename(c);
1497 else if (name != c->name) {
1498 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
1502 /* Retrieve superclass. */
1506 index = suck_u2(cb);
1511 /* This is only allowed for java.lang.Object. */
1513 if (c->name != utf_java_lang_Object) {
1514 exceptions_throw_classformaterror(c, "Bad superclass index");
1519 supername = (utf *) class_getconstant(c, index, CONSTANT_Class);
1521 if (supername == NULL)
1524 /* java.lang.Object may not have a super class. */
1526 if (c->name == utf_java_lang_Object) {
1527 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
1531 /* Detect circularity. */
1533 if (supername == c->name) {
1534 exceptions_throw_classcircularityerror(c);
1538 /* Interfaces must have java.lang.Object as super class. */
1540 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
1541 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
1546 /* Parse the super interfaces. */
1548 if (!suck_check_classbuffer_size(cb, 2))
1551 c->interfacescount = suck_u2(cb);
1553 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1556 c->interfaces = MNEW(classinfo*, c->interfacescount);
1558 /* Get the names of the super interfaces. */
1560 interfacesnames = DMNEW(utf*, c->interfacescount);
1562 for (int32_t i = 0; i < c->interfacescount; i++) {
1563 index = suck_u2(cb);
1565 u = (utf *) class_getconstant(c, index, CONSTANT_Class);
1570 interfacesnames[i] = u;
1573 RT_TIMING_GET_TIME(time_setup);
1577 if (!suck_check_classbuffer_size(cb, 2))
1580 c->fieldscount = suck_u2(cb);
1581 c->fields = MNEW(fieldinfo, c->fieldscount);
1583 MZERO(c->fields, fieldinfo, c->fieldscount);
1585 for (int32_t i = 0; i < c->fieldscount; i++) {
1586 if (!field_load(cb, &(c->fields[i]), descpool))
1590 RT_TIMING_GET_TIME(time_fields);
1592 /* Parse methods. */
1594 if (!suck_check_classbuffer_size(cb, 2))
1597 c->methodscount = suck_u2(cb);
1598 c->methods = MNEW(methodinfo, c->methodscount);
1600 MZERO(c->methods, methodinfo, c->methodscount);
1602 for (int32_t i = 0; i < c->methodscount; i++) {
1603 if (!method_load(cb, &(c->methods[i]), descpool))
1607 RT_TIMING_GET_TIME(time_methods);
1609 /* create the class reference table */
1612 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
1614 RT_TIMING_GET_TIME(time_classrefs);
1616 /* allocate space for the parsed descriptors */
1618 descriptor_pool_alloc_parsed_descriptors(descpool);
1619 c->parseddescs = (u1*) descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
1621 #if defined(ENABLE_STATISTICS)
1623 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
1624 count_classref_len += classrefsize;
1625 count_parsed_desc_len += descsize;
1629 RT_TIMING_GET_TIME(time_descs);
1631 /* put the classrefs in the constant pool */
1633 for (int32_t i = 0; i < c->cpcount; i++) {
1634 if (c->cptags[i] == CONSTANT_Class) {
1635 utf *name = (utf *) c->cpinfos[i];
1636 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
1640 /* Resolve the super class. */
1642 if (supername != NULL) {
1643 cr = descriptor_pool_lookup_classref(descpool, supername);
1648 /* XXX This should be done better. */
1649 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1652 resolve_handle_pending_exception(true);
1656 /* Interfaces are not allowed as super classes. */
1658 if (tc->flags & ACC_INTERFACE) {
1659 exceptions_throw_incompatibleclasschangeerror(c, "class %s has interface %s as super class");
1663 /* Don't allow extending final classes */
1665 if (tc->flags & ACC_FINAL) {
1666 exceptions_throw_verifyerror(NULL,
1667 "Cannot inherit from final class");
1671 /* Store the super class. */
1676 /* Resolve the super interfaces. */
1678 for (int32_t i = 0; i < c->interfacescount; i++) {
1679 u = interfacesnames[i];
1680 cr = descriptor_pool_lookup_classref(descpool, u);
1685 /* XXX This should be done better. */
1686 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1689 resolve_handle_pending_exception(true);
1693 /* Detect circularity. */
1696 exceptions_throw_classcircularityerror(c);
1700 if (!(tc->flags & ACC_INTERFACE)) {
1701 exceptions_throw_incompatibleclasschangeerror(tc,
1702 "Implementing class");
1706 /* Store the super interface. */
1708 c->interfaces[i] = tc;
1711 RT_TIMING_GET_TIME(time_setrefs);
1713 /* Parse the field descriptors. */
1715 for (int32_t i = 0; i < c->fieldscount; i++) {
1716 c->fields[i].parseddesc =
1717 descriptor_pool_parse_field_descriptor(descpool,
1718 c->fields[i].descriptor);
1719 if (!c->fields[i].parseddesc)
1723 RT_TIMING_GET_TIME(time_parsefds);
1725 /* parse method descriptors */
1727 for (int32_t i = 0; i < c->methodscount; i++) {
1728 methodinfo *m = &c->methods[i];
1730 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
1731 m->flags, class_get_self_classref(m->clazz));
1735 for (int32_t j = 0; j < m->rawexceptiontablelength; j++) {
1736 if (!m->rawexceptiontable[j].catchtype.any)
1739 if ((m->rawexceptiontable[j].catchtype.ref =
1740 descriptor_pool_lookup_classref(descpool,
1741 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
1745 for (int32_t j = 0; j < m->thrownexceptionscount; j++) {
1746 if (!m->thrownexceptions[j].any)
1749 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
1750 (utf *) m->thrownexceptions[j].any)) == NULL)
1755 RT_TIMING_GET_TIME(time_parsemds);
1757 /* parse the loaded descriptors */
1759 for (int32_t i = 0; i < c->cpcount; i++) {
1760 constant_FMIref *fmi;
1763 switch (c->cptags[i]) {
1764 case CONSTANT_Fieldref:
1765 fmi = (constant_FMIref *) c->cpinfos[i];
1766 fmi->parseddesc.fd =
1767 descriptor_pool_parse_field_descriptor(descpool,
1769 if (!fmi->parseddesc.fd)
1772 index = fmi->p.index;
1774 (constant_classref *) class_getconstant(c, index,
1776 if (!fmi->p.classref)
1779 case CONSTANT_Methodref:
1780 case CONSTANT_InterfaceMethodref:
1781 fmi = (constant_FMIref *) c->cpinfos[i];
1782 index = fmi->p.index;
1784 (constant_classref *) class_getconstant(c, index,
1786 if (!fmi->p.classref)
1788 fmi->parseddesc.md =
1789 descriptor_pool_parse_method_descriptor(descpool,
1793 if (!fmi->parseddesc.md)
1799 RT_TIMING_GET_TIME(time_parsecpool);
1801 #ifdef ENABLE_VERIFIER
1802 /* Check if all fields and methods can be uniquely
1803 * identified by (name,descriptor). */
1806 /* We use a hash table here to avoid making the
1807 * average case quadratic in # of methods, fields.
1809 static int shift = 0;
1811 u2 *next; /* for chaining colliding hash entries */
1817 /* Allocate hashtable */
1818 len = c->methodscount;
1819 if (len < c->fieldscount) len = c->fieldscount;
1821 hashtab = MNEW(u2,(hashlen + len));
1822 next = hashtab + hashlen;
1824 /* Determine bitshift (to get good hash values) */
1834 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
1836 for (int32_t i = 0; i < c->fieldscount; ++i) {
1837 fieldinfo *fi = c->fields + i;
1839 /* It's ok if we lose bits here */
1840 index = ((((size_t) fi->name) +
1841 ((size_t) fi->descriptor)) >> shift) % hashlen;
1843 if ((old = hashtab[index])) {
1847 if (c->fields[old].name == fi->name &&
1848 c->fields[old].descriptor == fi->descriptor) {
1849 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
1852 } while ((old = next[old]));
1854 hashtab[index] = i + 1;
1858 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
1860 for (int32_t i = 0; i < c->methodscount; ++i) {
1861 methodinfo *mi = c->methods + i;
1863 /* It's ok if we lose bits here */
1864 index = ((((size_t) mi->name) +
1865 ((size_t) mi->descriptor)) >> shift) % hashlen;
1867 if ((old = hashtab[index])) {
1871 if (c->methods[old].name == mi->name &&
1872 c->methods[old].descriptor == mi->descriptor) {
1873 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
1876 } while ((old = next[old]));
1878 hashtab[index] = i + 1;
1881 MFREE(hashtab, u2, (hashlen + len));
1883 #endif /* ENABLE_VERIFIER */
1885 RT_TIMING_GET_TIME(time_verify);
1887 #if defined(ENABLE_STATISTICS)
1889 size_classinfo += sizeof(classinfo*) * c->interfacescount;
1890 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
1891 size_methodinfo += sizeof(methodinfo) * c->methodscount;
1895 /* load attribute structures */
1897 if (!class_load_attributes(cb))
1900 /* Pre Java 1.5 version don't check this. This implementation is
1901 like Java 1.5 do it: for class file version 45.3 we don't check
1902 it, older versions are checked. */
1904 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
1905 /* check if all data has been read */
1906 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
1908 if (classdata_left > 0) {
1909 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
1914 RT_TIMING_GET_TIME(time_attrs);
1916 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
1917 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
1918 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
1919 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
1920 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
1921 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
1922 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
1923 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
1924 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
1925 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
1926 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
1927 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
1928 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
1929 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
1930 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
1936 /* load_class_from_classbuffer *************************************************
1938 Convenience wrapper for load_class_from_classbuffer.
1941 This function is NOT synchronized!
1943 *******************************************************************************/
1945 classinfo *load_class_from_classbuffer(classbuffer *cb)
1951 /* Get the classbuffer's class. */
1955 /* Check if the class is already loaded. */
1957 if (c->state & CLASS_LOADED)
1960 #if defined(ENABLE_STATISTICS)
1962 count_class_loads++;
1965 #if !defined(NDEBUG)
1967 log_message_class("Loading class: ", c);
1970 /* Mark start of dump memory area. */
1974 /* Class is currently loading. */
1976 c->state |= CLASS_LOADING;
1978 /* Parse the classbuffer. */
1980 result = load_class_from_classbuffer_intern(cb);
1982 /* Release dump area. */
1986 /* An error occurred. */
1988 if (result == false) {
1989 /* Revert loading state. */
1991 c->state = (c->state & ~CLASS_LOADING);
1996 /* Revert loading state and set loaded. */
1998 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2000 #if defined(ENABLE_JVMTI)
2001 /* fire Class Prepare JVMTI event */
2004 jvmti_ClassLoadPrepare(true, c);
2007 #if !defined(NDEBUG)
2009 log_message_class("Loading done class: ", c);
2016 /* load_newly_created_array ****************************************************
2018 Load a newly created array class.
2021 c....................the array class C has been loaded
2022 other classinfo......the array class was found in the class cache,
2024 NULL.................an exception has been thrown
2027 This is an internal function. Do not use it unless you know exactly
2030 Use one of the load_class_... functions for general array class loading.
2032 *******************************************************************************/
2034 classinfo *load_newly_created_array(classinfo *c, classloader_t *loader)
2036 classinfo *comp = NULL;
2038 methoddesc *clonedesc;
2039 constant_classref *classrefs;
2044 text = c->name->text;
2045 namelen = c->name->blength;
2047 /* Check array class name */
2049 if ((namelen < 2) || (text[0] != '[')) {
2050 exceptions_throw_classnotfoundexception(c->name);
2054 /* Check the element type */
2058 /* c is an array of arrays. We have to create the component class. */
2060 u = utf_new(text + 1, namelen - 1);
2062 comp = load_class_from_classloader(u, loader);
2067 assert(comp->state & CLASS_LOADED);
2069 /* the array's flags are that of the component class */
2070 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2071 c->classloader = comp->classloader;
2075 /* c is an array of objects. */
2077 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2078 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2079 exceptions_throw_classnotfoundexception(c->name);
2083 u = utf_new(text + 2, namelen - 3);
2085 if (!(comp = load_class_from_classloader(u, loader)))
2088 assert(comp->state & CLASS_LOADED);
2090 /* the array's flags are that of the component class */
2091 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2092 c->classloader = comp->classloader;
2096 /* c is an array of a primitive type */
2098 /* check for cases like `[II' and whether the character is a
2099 valid primitive type */
2101 if ((namelen > 2) || (Primitive::get_class_by_char(text[1]) == NULL)) {
2102 exceptions_throw_classnotfoundexception(c->name);
2106 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2107 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2108 c->classloader = NULL;
2111 assert(class_java_lang_Object);
2112 #if defined(ENABLE_JAVASE)
2113 assert(class_java_lang_Cloneable);
2114 assert(class_java_io_Serializable);
2117 /* Setup the array class. */
2119 c->super = class_java_lang_Object;
2121 #if defined(ENABLE_JAVASE)
2123 c->interfacescount = 2;
2124 c->interfaces = MNEW(classinfo*, 2);
2125 c->interfaces[0] = class_java_lang_Cloneable;
2126 c->interfaces[1] = class_java_io_Serializable;
2128 #elif defined(ENABLE_JAVAME_CLDC1_1)
2130 c->interfacescount = 0;
2131 c->interfaces = NULL;
2134 # error unknow Java configuration
2137 c->methodscount = 1;
2138 c->methods = MNEW(methodinfo, c->methodscount);
2140 MZERO(c->methods, methodinfo, c->methodscount);
2142 classrefs = MNEW(constant_classref, 2);
2144 CLASSREF_INIT(classrefs[0], c, c->name);
2145 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2147 /* create descriptor for clone method */
2148 /* we need one paramslot which is reserved for the 'this' parameter */
2149 clonedesc = NEW(methoddesc);
2150 clonedesc->returntype.type = TYPE_ADR;
2151 clonedesc->returntype.classref = classrefs + 1;
2152 clonedesc->returntype.arraydim = 0;
2153 /* initialize params to "empty", add real params below in
2154 descriptor_params_from_paramtypes */
2155 clonedesc->paramcount = 0;
2156 clonedesc->paramslots = 0;
2157 clonedesc->paramtypes[0].classref = classrefs + 0;
2158 clonedesc->params = NULL;
2160 /* create methodinfo */
2163 MSET(clone, 0, methodinfo, 1);
2165 #if defined(ENABLE_THREADS)
2166 lock_init_object_lock(&clone->header);
2169 /* ATTENTION: if you delete the ACC_NATIVE below, set
2170 clone->maxlocals=1 (interpreter related) */
2172 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2173 clone->name = utf_clone;
2174 clone->descriptor = utf_void__java_lang_Object;
2175 clone->parseddesc = clonedesc;
2178 /* parse the descriptor to get the register allocation */
2180 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2183 clone->code = NativeStub::generate(clone, BUILTIN_clone);
2185 /* XXX: field: length? */
2187 /* array classes are not loaded from class files */
2189 c->state |= CLASS_LOADED;
2190 c->parseddescs = (u1 *) clonedesc;
2191 c->parseddescsize = sizeof(methodinfo);
2192 c->classrefs = classrefs;
2193 c->classrefcount = 1;
2195 /* insert class into the loaded class cache */
2196 /* XXX free classinfo if NULL returned? */
2198 return classcache_store(loader, c, true);
2202 /* loader_close ****************************************************************
2204 Frees all resources.
2206 *******************************************************************************/
2208 void loader_close(void)
2215 * These are local overrides for various environment variables in Emacs.
2216 * Please do not remove this and leave it at the end of the file, where
2217 * Emacs will automagically detect them.
2218 * ---------------------------------------------------------------------
2221 * indent-tabs-mode: t
2225 * vim:noexpandtab:sw=4:ts=4: