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
5 Copyright (C) 2009 Theobroma Systems Ltd.
7 This file is part of CACAO.
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2, or (at
12 your option) any later version.
14 This program is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
35 #include "mm/dumpmemory.hpp"
36 #include "mm/memory.hpp"
38 #include "native/llni.h"
40 #include "threads/mutex.hpp"
42 #include "toolbox/hashtable.h"
43 #include "toolbox/list.hpp"
44 #include "toolbox/logging.hpp"
46 #include "vm/jit/builtin.hpp"
47 #include "vm/classcache.hpp"
48 #include "vm/exceptions.hpp"
49 #include "vm/field.hpp"
50 #include "vm/global.h"
51 #include "vm/globals.hpp"
52 #include "vm/javaobjects.hpp"
53 #include "vm/linker.hpp"
54 #include "vm/loader.hpp"
55 #include "vm/method.hpp"
56 #include "vm/options.h"
57 #include "vm/package.hpp"
58 #include "vm/primitive.hpp"
59 #include "vm/resolve.hpp"
60 #include "vm/rt-timing.h"
61 #include "vm/string.hpp"
62 #include "vm/suck.hpp"
66 #if defined(ENABLE_JAVASE)
67 # include "vm/annotation.hpp"
68 # include "vm/stackmap.h"
71 #if defined(ENABLE_STATISTICS)
72 # include "vm/statistics.h"
75 #if defined(ENABLE_ZLIB)
76 # include "vm/zip.hpp"
79 #include "vm/jit/stubs.hpp"
81 #if defined(ENABLE_JVMTI)
82 # include "native/jvmti/cacaodbg.h"
86 /* global variables ***********************************************************/
88 static hashtable *hashtable_classloader;
91 /* loader_preinit **************************************************************
93 Initializes the classpath list and loads classes required for the
96 NOTE: Exceptions thrown during VM initialization are caught in the
97 exception functions themselves.
99 *******************************************************************************/
101 void loader_preinit(void)
103 TRACESUBSYSTEMINITIALIZATION("loader_preinit");
105 #if defined(ENABLE_THREADS)
106 // Get current list of classpath entries.
107 SuckClasspath& suckclasspath = VM::get_current()->get_suckclasspath();
109 /* Initialize the monitor pointer for zip/jar file locking. */
111 for (SuckClasspath::iterator it = suckclasspath.begin(); it != suckclasspath.end(); it++) {
112 list_classpath_entry* lce = *it;
114 if (lce->type == CLASSPATH_ARCHIVE)
115 lce->mutex = new Mutex();
119 /* initialize classloader hashtable, 10 entries should be enough */
121 hashtable_classloader = NEW(hashtable);
122 hashtable_create(hashtable_classloader, 10);
124 /* Load the most basic classes. */
126 assert(VM::get_current()->is_initializing() == true);
128 class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object);
130 #if defined(ENABLE_JAVASE)
131 class_java_lang_Cloneable = load_class_bootstrap(utf_java_lang_Cloneable);
132 class_java_io_Serializable = load_class_bootstrap(utf_java_io_Serializable);
137 /* loader_init *****************************************************************
139 Loads all classes required in the VM.
141 NOTE: Exceptions thrown during VM initialization are caught in the
142 exception functions themselves.
144 *******************************************************************************/
146 void loader_init(void)
148 TRACESUBSYSTEMINITIALIZATION("loader_init");
150 /* Load primitive-type wrapping classes. */
152 assert(VM::get_current()->is_initializing() == true);
154 #if defined(ENABLE_JAVASE)
155 class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void);
158 class_java_lang_Boolean = load_class_bootstrap(utf_java_lang_Boolean);
159 class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte);
160 class_java_lang_Character = load_class_bootstrap(utf_java_lang_Character);
161 class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short);
162 class_java_lang_Integer = load_class_bootstrap(utf_java_lang_Integer);
163 class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long);
164 class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float);
165 class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double);
167 /* Load important system classes. */
169 class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class);
170 class_java_lang_String = load_class_bootstrap(utf_java_lang_String);
172 #if defined(ENABLE_JAVASE)
173 class_java_lang_ClassLoader =
174 load_class_bootstrap(utf_java_lang_ClassLoader);
176 class_java_lang_SecurityManager =
177 load_class_bootstrap(utf_java_lang_SecurityManager);
180 class_java_lang_System =
181 load_class_bootstrap(utf_new_char("java/lang/System"));
183 class_java_lang_Thread =
184 load_class_bootstrap(utf_new_char("java/lang/Thread"));
186 #if defined(ENABLE_JAVASE)
187 class_java_lang_ThreadGroup =
188 load_class_bootstrap(utf_java_lang_ThreadGroup);
191 class_java_lang_Throwable = load_class_bootstrap(utf_java_lang_Throwable);
193 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
194 class_java_lang_VMSystem =
195 load_class_bootstrap(utf_new_char("java/lang/VMSystem"));
197 class_java_lang_VMThread =
198 load_class_bootstrap(utf_new_char("java/lang/VMThread"));
200 class_java_lang_VMThrowable =
201 load_class_bootstrap(utf_new_char("java/lang/VMThrowable"));
204 /* Important system exceptions. */
206 class_java_lang_Exception = load_class_bootstrap(utf_java_lang_Exception);
208 class_java_lang_ClassNotFoundException =
209 load_class_bootstrap(utf_java_lang_ClassNotFoundException);
211 class_java_lang_RuntimeException =
212 load_class_bootstrap(utf_java_lang_RuntimeException);
214 /* Some classes which may be used often. */
216 #if defined(ENABLE_JAVASE)
217 class_java_lang_StackTraceElement = load_class_bootstrap(utf_java_lang_StackTraceElement);
219 class_java_lang_reflect_Constructor = load_class_bootstrap(utf_java_lang_reflect_Constructor);
220 class_java_lang_reflect_Field = load_class_bootstrap(utf_java_lang_reflect_Field);
221 class_java_lang_reflect_Method = load_class_bootstrap(utf_java_lang_reflect_Method);
223 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
224 class_java_lang_reflect_VMConstructor = load_class_bootstrap(utf_java_lang_reflect_VMConstructor);
225 class_java_lang_reflect_VMField = load_class_bootstrap(utf_java_lang_reflect_VMField);
226 class_java_lang_reflect_VMMethod = load_class_bootstrap(utf_java_lang_reflect_VMMethod);
229 class_java_security_PrivilegedAction = load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"));
231 class_java_util_HashMap = load_class_bootstrap(utf_new_char("java/util/HashMap"));
232 class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector);
234 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
235 class_sun_misc_Signal = load_class_bootstrap(utf_new_char("sun/misc/Signal"));
236 class_sun_reflect_MagicAccessorImpl = load_class_bootstrap(utf_new_char("sun/reflect/MagicAccessorImpl"));
239 arrayclass_java_lang_Object =
240 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"));
242 # if defined(ENABLE_ANNOTATIONS)
243 /* needed by annotation support */
244 class_sun_reflect_ConstantPool =
245 load_class_bootstrap(utf_new_char("sun/reflect/ConstantPool"));
247 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
248 /* needed by GNU Classpaths annotation support */
249 class_sun_reflect_annotation_AnnotationParser =
250 load_class_bootstrap(utf_new_char("sun/reflect/annotation/AnnotationParser"));
257 /* loader_hashtable_classloader_add ********************************************
259 Adds an entry to the classloader hashtable.
261 REMEMBER: Also use this to register native loaders!
263 *******************************************************************************/
265 classloader_t *loader_hashtable_classloader_add(java_handle_t *cl)
267 hashtable_classloader_entry *cle;
274 hashtable_classloader->mutex->lock();
278 /* key for entry is the hashcode of the classloader;
279 aligned to 16-byte boundaries */
281 key = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
282 slot = key & (hashtable_classloader->size - 1);
283 cle = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
285 /* search hashchain for existing entry */
288 if (cle->object == LLNI_DIRECT(cl))
296 /* if no classloader was found, we create a new entry here */
299 cle = NEW(hashtable_classloader_entry);
301 #if defined(ENABLE_GC_CACAO)
302 /* register the classloader object with the GC */
304 gc_reference_register(&(cle->object), GC_REFTYPE_CLASSLOADER);
309 cle->object = LLNI_DIRECT(cl);
313 /*#define LOADER_DEBUG_CLASSLOADER*/
314 #ifdef LOADER_DEBUG_CLASSLOADER
315 printf("CLASSLOADER: adding new classloader entry %p for %p: ", cle, cl);
316 class_print(LLNI_vftbl_direct(cl)->class);
321 /* insert entry into hashtable */
323 cle->hashlink = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
324 hashtable_classloader->ptr[slot] = cle;
326 /* update number of entries */
328 hashtable_classloader->entries++;
331 hashtable_classloader->mutex->unlock();
333 #if defined(ENABLE_HANDLES)
341 /* loader_hashtable_classloader_find *******************************************
343 Find an entry in the classloader hashtable.
345 *******************************************************************************/
347 classloader_t *loader_hashtable_classloader_find(java_handle_t *cl)
349 hashtable_classloader_entry *cle;
358 /* key for entry is the hashcode of the classloader;
359 aligned to 16-byte boundaries */
361 key = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
362 slot = key & (hashtable_classloader->size - 1);
363 cle = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
365 /* search hashchain for existing entry */
368 if (cle->object == LLNI_DIRECT(cl))
374 #ifdef LOADER_DEBUG_CLASSLOADER
376 printf("CLASSLOADER: unable to find classloader entry for %p: ", cl);
377 class_print(LLNI_vftbl_direct(cl)->class);
385 #if defined(ENABLE_HANDLES)
393 /* loader_load_all_classes *****************************************************
395 Loads all classes specified in the BOOTCLASSPATH.
397 *******************************************************************************/
399 void loader_load_all_classes(void)
401 #if defined(ENABLE_ZLIB)
403 hashtable_zipfile_entry *htzfe;
407 // Get current list of classpath entries.
408 SuckClasspath& suckclasspath = VM::get_current()->get_suckclasspath();
410 for (SuckClasspath::iterator it = suckclasspath.begin(); it != suckclasspath.end(); it++) {
411 list_classpath_entry* lce = *it;
413 #if defined(ENABLE_ZLIB)
414 if (lce->type == CLASSPATH_ARCHIVE) {
415 /* get the classes hashtable */
419 for (uint32_t slot = 0; slot < ht->size; slot++) {
420 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
422 for (; htzfe; htzfe = htzfe->hashlink) {
425 /* skip all entries in META-INF and .properties,
428 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
429 strstr(u->text, ".properties") ||
430 strstr(u->text, ".png"))
433 /* load class from bootstrap classloader */
435 if (!load_class_bootstrap(u)) {
436 fprintf(stderr, "Error loading: ");
437 utf_fprint_printable_ascii_classname(stderr, u);
438 fprintf(stderr, "\n");
441 /* print out exception and cause */
443 exceptions_print_current_exception();
451 #if defined(ENABLE_ZLIB)
458 /* loader_skip_attribute_body **************************************************
460 Skips an attribute the attribute_name_index has already been read.
463 u2 attribute_name_index;
465 u1 info[attribute_length];
468 *******************************************************************************/
470 bool loader_skip_attribute_body(classbuffer *cb)
474 if (!suck_check_classbuffer_size(cb, 4))
477 attribute_length = suck_u4(cb);
479 if (!suck_check_classbuffer_size(cb, attribute_length))
482 suck_skip_nbytes(cb, attribute_length);
488 /* load_constantpool ***********************************************************
490 Loads the constantpool of a class, the entries are transformed into
491 a simpler format by resolving references (a detailed overview of
492 the compact structures can be found in global.h).
494 *******************************************************************************/
496 /* The following structures are used to save information which cannot be
497 processed during the first pass. After the complete constantpool has
498 been traversed the references can be resolved (only in specific order). */
500 /* CONSTANT_Class entries */
501 typedef struct forward_class {
506 /* CONSTANT_String */
507 typedef struct forward_string {
512 /* CONSTANT_NameAndType */
513 typedef struct forward_nameandtype {
517 } forward_nameandtype;
519 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
520 typedef struct forward_fieldmethint {
524 u2 nameandtype_index;
525 } forward_fieldmethint;
527 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
532 DumpList<forward_class> forward_classes;
533 DumpList<forward_string> forward_strings;
534 DumpList<forward_nameandtype> forward_nameandtypes;
535 DumpList<forward_fieldmethint> forward_fieldmethints;
539 forward_nameandtype nfn;
540 forward_fieldmethint nff;
548 /* number of entries in the constant_pool table plus one */
549 if (!suck_check_classbuffer_size(cb, 2))
552 cpcount = c->cpcount = suck_u2(cb);
554 /* allocate memory */
555 cptags = c->cptags = MNEW(u1, cpcount);
556 cpinfos = c->cpinfos = MNEW(void*, cpcount);
559 exceptions_throw_classformaterror(c, "Illegal constant pool size");
563 #if defined(ENABLE_STATISTICS)
565 count_const_pool_len += (sizeof(u1) + sizeof(void*)) * cpcount;
568 /* initialize constantpool */
569 for (idx = 0; idx < cpcount; idx++) {
570 cptags[idx] = CONSTANT_UNUSED;
575 /******* first pass *******/
576 /* entries which cannot be resolved now are written into
577 temporary structures and traversed again later */
580 while (idx < cpcount) {
583 /* get constant type */
584 if (!suck_check_classbuffer_size(cb, 1))
593 /* reference to CONSTANT_NameAndType */
594 if (!suck_check_classbuffer_size(cb, 2))
597 nfc.name_index = suck_u2(cb);
599 forward_classes.push_front(nfc);
604 case CONSTANT_String:
607 /* reference to CONSTANT_Utf8_info with string characters */
608 if (!suck_check_classbuffer_size(cb, 2))
611 nfs.string_index = suck_u2(cb);
613 forward_strings.push_front(nfs);
618 case CONSTANT_NameAndType:
621 if (!suck_check_classbuffer_size(cb, 2 + 2))
624 /* reference to CONSTANT_Utf8_info containing simple name */
625 nfn.name_index = suck_u2(cb);
627 /* reference to CONSTANT_Utf8_info containing field or method
629 nfn.sig_index = suck_u2(cb);
631 forward_nameandtypes.push_front(nfn);
636 case CONSTANT_Fieldref:
637 case CONSTANT_Methodref:
638 case CONSTANT_InterfaceMethodref:
643 if (!suck_check_classbuffer_size(cb, 2 + 2))
646 /* class or interface type that contains the declaration of the
648 nff.class_index = suck_u2(cb);
650 /* name and descriptor of the field or method */
651 nff.nameandtype_index = suck_u2(cb);
653 forward_fieldmethints.push_front(nff);
658 case CONSTANT_Integer: {
659 constant_integer *ci = NEW(constant_integer);
661 #if defined(ENABLE_STATISTICS)
663 count_const_pool_len += sizeof(constant_integer);
666 if (!suck_check_classbuffer_size(cb, 4))
669 ci->value = suck_s4(cb);
670 cptags[idx] = CONSTANT_Integer;
677 case CONSTANT_Float: {
678 constant_float *cf = NEW(constant_float);
680 #if defined(ENABLE_STATISTICS)
682 count_const_pool_len += sizeof(constant_float);
685 if (!suck_check_classbuffer_size(cb, 4))
688 cf->value = suck_float(cb);
689 cptags[idx] = CONSTANT_Float;
696 case CONSTANT_Long: {
697 constant_long *cl = NEW(constant_long);
699 #if defined(ENABLE_STATISTICS)
701 count_const_pool_len += sizeof(constant_long);
704 if (!suck_check_classbuffer_size(cb, 8))
707 cl->value = suck_s8(cb);
708 cptags[idx] = CONSTANT_Long;
712 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
718 case CONSTANT_Double: {
719 constant_double *cd = NEW(constant_double);
721 #if defined(ENABLE_STATISTICS)
723 count_const_pool_len += sizeof(constant_double);
726 if (!suck_check_classbuffer_size(cb, 8))
729 cd->value = suck_double(cb);
730 cptags[idx] = CONSTANT_Double;
734 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
740 case CONSTANT_Utf8: {
743 /* number of bytes in the bytes array (not string-length) */
744 if (!suck_check_classbuffer_size(cb, 2))
747 length = suck_u2(cb);
748 cptags[idx] = CONSTANT_Utf8;
750 /* validate the string */
751 if (!suck_check_classbuffer_size(cb, length))
754 #ifdef ENABLE_VERIFIER
756 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
758 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
761 #endif /* ENABLE_VERIFIER */
762 /* insert utf-string into the utf-symboltable */
763 cpinfos[idx] = utf_new((char *) cb->pos, length);
765 /* skip bytes of the string (buffer size check above) */
766 suck_skip_nbytes(cb, length);
772 exceptions_throw_classformaterror(c, "Illegal constant pool type");
778 /* resolve entries in temporary structures */
780 for (DumpList<forward_class>::iterator it = forward_classes.begin();
781 it != forward_classes.end(); ++it) {
783 utf *name = (utf*) class_getconstant(c, it->name_index, CONSTANT_Utf8);
787 #ifdef ENABLE_VERIFIER
788 if (opt_verify && !is_valid_name_utf(name)) {
789 exceptions_throw_classformaterror(c, "Class reference with invalid name");
792 #endif /* ENABLE_VERIFIER */
794 /* add all class references to the descriptor_pool */
796 if (!descriptor_pool_add_class(descpool, name))
799 cptags[it->thisindex] = CONSTANT_Class;
801 /* the classref is created later */
802 cpinfos[it->thisindex] = name;
805 for (DumpList<forward_string>::iterator it = forward_strings.begin();
806 it != forward_strings.end(); ++it) {
808 utf *text = (utf*) class_getconstant(c, it->string_index, CONSTANT_Utf8);
813 /* resolve utf-string */
814 cptags[it->thisindex] = CONSTANT_String;
815 cpinfos[it->thisindex] = text;
818 for (DumpList<forward_nameandtype>::iterator it = forward_nameandtypes.begin();
819 it != forward_nameandtypes.end(); ++it) {
821 constant_nameandtype *cn = NEW(constant_nameandtype);
823 #if defined(ENABLE_STATISTICS)
825 count_const_pool_len += sizeof(constant_nameandtype);
828 /* resolve simple name and descriptor */
829 cn->name = (utf*) class_getconstant(c,
835 cn->descriptor = (utf*) class_getconstant(c,
841 #ifdef ENABLE_VERIFIER
844 if (!is_valid_name_utf(cn->name)) {
845 exceptions_throw_classformaterror(c,
846 "Illegal Field name \"%s\"",
852 /* disallow referencing <clinit> among others */
853 if (cn->name->text[0] == '<' && cn->name != utf_init) {
854 exceptions_throw_classformaterror(c, "Illegal reference to special method");
858 #endif /* ENABLE_VERIFIER */
860 cptags[it->thisindex] = CONSTANT_NameAndType;
861 cpinfos[it->thisindex] = cn;
864 for (DumpList<forward_fieldmethint>::iterator it = forward_fieldmethints.begin();
865 it != forward_fieldmethints.end(); ++it) {
867 constant_nameandtype *nat;
868 constant_FMIref *fmi = NEW(constant_FMIref);
870 #if defined(ENABLE_STATISTICS)
872 count_const_pool_len += sizeof(constant_FMIref);
874 /* resolve simple name and descriptor */
876 nat = (constant_nameandtype*) class_getconstant(c,
877 it->nameandtype_index,
878 CONSTANT_NameAndType);
883 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
885 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
888 /* the classref is created later */
890 fmi->p.index = it->class_index;
891 fmi->name = nat->name;
892 fmi->descriptor = nat->descriptor;
894 cptags[it->thisindex] = it->tag;
895 cpinfos[it->thisindex] = fmi;
898 /* everything was ok */
904 /* loader_load_attribute_signature *********************************************
906 Signature_attribute {
907 u2 attribute_name_index;
912 *******************************************************************************/
914 #if defined(ENABLE_JAVASE)
915 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
925 /* check remaining bytecode */
927 if (!suck_check_classbuffer_size(cb, 4 + 2))
930 /* check attribute length */
932 attribute_length = suck_u4(cb);
934 if (attribute_length != 2) {
935 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
939 if (*signature != NULL) {
940 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
946 signature_index = suck_u2(cb);
948 *signature = (utf*) class_getconstant(c, signature_index, CONSTANT_Utf8);
950 if (*signature == NULL)
955 #endif /* defined(ENABLE_JAVASE) */
958 /* load_class_from_sysloader ***************************************************
960 Load the class with the given name using the system class loader
963 name.............the classname
967 NULL if an exception has been thrown
969 *******************************************************************************/
971 #if defined(ENABLE_JAVASE)
972 classinfo *load_class_from_sysloader(utf *name)
977 cl = java_lang_ClassLoader::invoke_getSystemClassLoader();
982 c = load_class_from_classloader(name, cl);
986 #endif /* defined(ENABLE_JAVASE) */
989 /* load_class_from_classloader *************************************************
991 Load the class with the given name using the given user-defined class loader.
994 name.............the classname
995 cl...............user-defined class loader
999 NULL if an exception has been thrown
1001 *******************************************************************************/
1003 classinfo *load_class_from_classloader(utf *name, classloader_t *cl)
1008 java_handle_t *string;
1009 #if defined(ENABLE_RT_TIMING)
1010 struct timespec time_start, time_lookup, time_prepare, time_java,
1014 RT_TIMING_GET_TIME(time_start);
1018 /* lookup if this class has already been loaded */
1020 c = classcache_lookup(cl, name);
1022 RT_TIMING_GET_TIME(time_lookup);
1023 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1028 /* if other class loader than bootstrap, call it */
1036 namelen = name->blength;
1038 /* handle array classes */
1039 if (text[0] == '[') {
1045 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1046 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1047 exceptions_throw_classnotfoundexception(name);
1051 u = utf_new(text + 2, namelen - 3);
1053 if (!(comp = load_class_from_classloader(u, cl)))
1056 /* create the array class */
1058 c = class_array_of(comp, false);
1060 tmpc = classcache_store(cl, c, true);
1063 /* exception, free the loaded class */
1064 c->state &= ~CLASS_LOADING;
1071 /* load the component class */
1073 u = utf_new(text + 1, namelen - 1);
1075 if (!(comp = load_class_from_classloader(u, cl)))
1078 /* create the array class */
1080 c = class_array_of(comp, false);
1082 tmpc = classcache_store(cl, c, true);
1085 /* exception, free the loaded class */
1086 c->state &= ~CLASS_LOADING;
1093 /* primitive array classes are loaded by the bootstrap loader */
1095 c = load_class_bootstrap(name);
1101 LLNI_class_get(cl, c);
1103 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1104 /* OpenJDK uses this internal function because it's
1107 lc = class_resolveclassmethod(c,
1108 utf_loadClassInternal,
1109 utf_java_lang_String__java_lang_Class,
1113 lc = class_resolveclassmethod(c,
1115 utf_java_lang_String__java_lang_Class,
1121 return false; /* exception */
1123 /* move return value into `o' and cast it afterwards to a classinfo* */
1125 string = javastring_new_slash_to_dot(name);
1127 RT_TIMING_GET_TIME(time_prepare);
1129 o = vm_call_method(lc, (java_handle_t *) cl, string);
1131 RT_TIMING_GET_TIME(time_java);
1133 c = LLNI_classinfo_unwrap(o);
1136 /* Store this class in the loaded class cache. If another
1137 class with the same (initloader,name) pair has been
1138 stored earlier it will be returned by classcache_store
1139 In this case classcache_store may not free the class
1140 because it has already been exposed to Java code which
1141 may have kept references to that class. */
1143 tmpc = classcache_store(cl, c, false);
1146 /* exception, free the loaded class */
1147 c->state &= ~CLASS_LOADING;
1154 // Expected behavior for the classloader is to throw an exception
1155 // and never return NULL. If the classloader shows a different
1156 // behavior, we are correcting it here (see PR126).
1157 if (exceptions_get_exception() == NULL) {
1158 #if !defined(NDEBUG)
1159 if (opt_PrintWarnings)
1160 log_message_utf("load_class_from_classloader: Correcting faulty classloader behavior (PR126) for ", name);
1162 exceptions_throw_classnotfoundexception(name);
1166 RT_TIMING_GET_TIME(time_cache);
1168 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1169 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1170 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1172 /* SUN compatible -verbose:class output */
1174 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1176 utf_display_printable_ascii_classname(name);
1180 #if defined(ENABLE_JVMTI)
1181 /* fire Class Load JVMTI event */
1182 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1189 c = load_class_bootstrap(name);
1195 /* load_class_bootstrap ********************************************************
1197 Load the class with the given name using the bootstrap class loader.
1200 name.............the classname
1203 loaded classinfo, or
1204 NULL if an exception has been thrown
1207 load_class_bootstrap is synchronized. It can be treated as an
1210 *******************************************************************************/
1212 classinfo *load_class_bootstrap(utf *name)
1217 #if defined(ENABLE_RT_TIMING)
1218 struct timespec time_start, time_lookup, time_array, time_suck,
1219 time_load, time_cache;
1222 RT_TIMING_GET_TIME(time_start);
1228 /* lookup if this class has already been loaded */
1230 r = classcache_lookup(NULL, name);
1233 RT_TIMING_GET_TIME(time_lookup);
1234 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1239 RT_TIMING_GET_TIME(time_lookup);
1240 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1242 /* create the classinfo */
1244 c = class_create_classinfo(name);
1246 /* handle array classes */
1248 if (name->text[0] == '[') {
1249 c = load_newly_created_array(c, NULL);
1254 assert(c->state & CLASS_LOADED);
1256 RT_TIMING_GET_TIME(time_array);
1257 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1262 #if defined(ENABLE_STATISTICS)
1265 if (opt_getcompilingtime)
1266 compilingtime_stop();
1268 if (opt_getloadingtime)
1269 loadingtime_start();
1272 /* load classdata, throw exception on error */
1277 exceptions_throw_classnotfoundexception(name);
1281 RT_TIMING_GET_TIME(time_suck);
1283 /* load the class from the buffer */
1285 r = load_class_from_classbuffer(cb);
1287 RT_TIMING_GET_TIME(time_load);
1290 /* the class could not be loaded, free the classinfo struct */
1295 /* Store this class in the loaded class cache this step also
1296 checks the loading constraints. If the class has been
1297 loaded before, the earlier loaded class is returned. */
1299 classinfo *res = classcache_store(NULL, c, true);
1306 // Add the package name to the boot packages.
1307 Package::add(c->packagename);
1313 RT_TIMING_GET_TIME(time_cache);
1315 /* SUN compatible -verbose:class output */
1317 if (opt_verboseclass && r) {
1319 utf_display_printable_ascii_classname(name);
1320 printf(" from %s]\n", cb->path);
1327 #if defined(ENABLE_STATISTICS)
1330 if (opt_getloadingtime)
1333 if (opt_getcompilingtime)
1334 compilingtime_start();
1337 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1338 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1339 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1340 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1346 /* load_class_from_classbuffer_intern ******************************************
1348 Loads a class from a classbuffer into a given classinfo structure.
1349 Super-classes are also loaded at this point and some verfication
1353 This function is NOT synchronized!
1355 *******************************************************************************/
1357 static bool load_class_from_classbuffer_intern(classbuffer *cb)
1363 utf **interfacesnames;
1365 constant_classref *cr;
1369 descriptor_pool *descpool;
1370 #if defined(ENABLE_STATISTICS)
1374 #if defined(ENABLE_RT_TIMING)
1375 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1376 time_setup, time_fields, time_methods, time_classrefs,
1377 time_descs, time_setrefs, time_parsefds, time_parsemds,
1378 time_parsecpool, time_verify, time_attrs;
1381 // Create new dump memory area.
1384 RT_TIMING_GET_TIME(time_start);
1386 /* Get the classbuffer's class. */
1390 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1393 /* check signature */
1395 if (suck_u4(cb) != MAGIC) {
1396 exceptions_throw_classformaterror(c, "Bad magic number");
1405 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1406 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1410 RT_TIMING_GET_TIME(time_checks);
1412 /* create a new descriptor pool */
1414 descpool = descriptor_pool_new(c);
1416 RT_TIMING_GET_TIME(time_ndpool);
1418 /* load the constant pool */
1420 if (!load_constantpool(cb, descpool))
1423 RT_TIMING_GET_TIME(time_cpool);
1427 if (!suck_check_classbuffer_size(cb, 2))
1430 /* We OR the flags here, as we set already some flags in
1431 class_create_classinfo. */
1433 c->flags |= suck_u2(cb);
1435 /* check ACC flags consistency */
1437 if (c->flags & ACC_INTERFACE) {
1438 if (!(c->flags & ACC_ABSTRACT)) {
1439 /* We work around this because interfaces in JDK 1.1 are
1440 * not declared abstract. */
1442 c->flags |= ACC_ABSTRACT;
1445 if (c->flags & ACC_FINAL) {
1446 exceptions_throw_classformaterror(c,
1447 "Illegal class modifiers: 0x%X",
1452 if (c->flags & ACC_SUPER) {
1453 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1457 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1458 exceptions_throw_classformaterror(c,
1459 "Illegal class modifiers: 0x%X",
1464 if (!suck_check_classbuffer_size(cb, 2 + 2))
1469 index = suck_u2(cb);
1471 name = (utf *) class_getconstant(c, index, CONSTANT_Class);
1476 if (c->name == utf_not_named_yet) {
1477 /* we finally have a name for this class */
1479 class_set_packagename(c);
1481 else if (name != c->name) {
1482 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
1486 /* Retrieve superclass. */
1490 index = suck_u2(cb);
1495 /* This is only allowed for java.lang.Object. */
1497 if (c->name != utf_java_lang_Object) {
1498 exceptions_throw_classformaterror(c, "Bad superclass index");
1503 supername = (utf *) class_getconstant(c, index, CONSTANT_Class);
1505 if (supername == NULL)
1508 /* java.lang.Object may not have a super class. */
1510 if (c->name == utf_java_lang_Object) {
1511 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
1515 /* Detect circularity. */
1517 if (supername == c->name) {
1518 exceptions_throw_classcircularityerror(c);
1522 /* Interfaces must have java.lang.Object as super class. */
1524 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
1525 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
1530 /* Parse the super interfaces. */
1532 if (!suck_check_classbuffer_size(cb, 2))
1535 c->interfacescount = suck_u2(cb);
1537 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1540 c->interfaces = MNEW(classinfo*, c->interfacescount);
1542 /* Get the names of the super interfaces. */
1544 interfacesnames = (utf**) DumpMemory::allocate(sizeof(utf*) * c->interfacescount);
1546 for (int32_t i = 0; i < c->interfacescount; i++) {
1547 index = suck_u2(cb);
1549 u = (utf *) class_getconstant(c, index, CONSTANT_Class);
1554 interfacesnames[i] = u;
1557 RT_TIMING_GET_TIME(time_setup);
1561 if (!suck_check_classbuffer_size(cb, 2))
1564 c->fieldscount = suck_u2(cb);
1565 c->fields = MNEW(fieldinfo, c->fieldscount);
1567 MZERO(c->fields, fieldinfo, c->fieldscount);
1569 for (int32_t i = 0; i < c->fieldscount; i++) {
1570 if (!field_load(cb, &(c->fields[i]), descpool))
1574 RT_TIMING_GET_TIME(time_fields);
1576 /* Parse methods. */
1578 if (!suck_check_classbuffer_size(cb, 2))
1581 c->methodscount = suck_u2(cb);
1582 c->methods = MNEW(methodinfo, c->methodscount);
1584 MZERO(c->methods, methodinfo, c->methodscount);
1586 for (int32_t i = 0; i < c->methodscount; i++) {
1587 if (!method_load(cb, &(c->methods[i]), descpool))
1591 RT_TIMING_GET_TIME(time_methods);
1593 /* create the class reference table */
1596 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
1598 RT_TIMING_GET_TIME(time_classrefs);
1600 /* allocate space for the parsed descriptors */
1602 descriptor_pool_alloc_parsed_descriptors(descpool);
1603 c->parseddescs = (u1*) descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
1605 #if defined(ENABLE_STATISTICS)
1607 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
1608 count_classref_len += classrefsize;
1609 count_parsed_desc_len += descsize;
1613 RT_TIMING_GET_TIME(time_descs);
1615 /* put the classrefs in the constant pool */
1617 for (int32_t i = 0; i < c->cpcount; i++) {
1618 if (c->cptags[i] == CONSTANT_Class) {
1619 utf *name = (utf *) c->cpinfos[i];
1620 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
1624 /* Resolve the super class. */
1626 if (supername != NULL) {
1627 cr = descriptor_pool_lookup_classref(descpool, supername);
1632 /* XXX This should be done better. */
1633 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1636 resolve_handle_pending_exception(true);
1640 /* Interfaces are not allowed as super classes. */
1642 if (tc->flags & ACC_INTERFACE) {
1643 exceptions_throw_incompatibleclasschangeerror(c, "class %s has interface %s as super class");
1647 /* Don't allow extending final classes */
1649 if (tc->flags & ACC_FINAL) {
1650 exceptions_throw_verifyerror(NULL,
1651 "Cannot inherit from final class");
1655 /* Store the super class. */
1660 /* Resolve the super interfaces. */
1662 for (int32_t i = 0; i < c->interfacescount; i++) {
1663 u = interfacesnames[i];
1664 cr = descriptor_pool_lookup_classref(descpool, u);
1669 /* XXX This should be done better. */
1670 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1673 resolve_handle_pending_exception(true);
1677 /* Detect circularity. */
1680 exceptions_throw_classcircularityerror(c);
1684 if (!(tc->flags & ACC_INTERFACE)) {
1685 exceptions_throw_incompatibleclasschangeerror(tc,
1686 "Implementing class");
1690 /* Store the super interface. */
1692 c->interfaces[i] = tc;
1695 RT_TIMING_GET_TIME(time_setrefs);
1697 /* Parse the field descriptors. */
1699 for (int32_t i = 0; i < c->fieldscount; i++) {
1700 c->fields[i].parseddesc =
1701 descriptor_pool_parse_field_descriptor(descpool,
1702 c->fields[i].descriptor);
1703 if (!c->fields[i].parseddesc)
1707 RT_TIMING_GET_TIME(time_parsefds);
1709 /* parse method descriptors */
1711 for (int32_t i = 0; i < c->methodscount; i++) {
1712 methodinfo *m = &c->methods[i];
1714 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
1715 m->flags, class_get_self_classref(m->clazz));
1719 for (int32_t j = 0; j < m->rawexceptiontablelength; j++) {
1720 if (!m->rawexceptiontable[j].catchtype.any)
1723 if ((m->rawexceptiontable[j].catchtype.ref =
1724 descriptor_pool_lookup_classref(descpool,
1725 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
1729 for (int32_t j = 0; j < m->thrownexceptionscount; j++) {
1730 if (!m->thrownexceptions[j].any)
1733 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
1734 (utf *) m->thrownexceptions[j].any)) == NULL)
1739 RT_TIMING_GET_TIME(time_parsemds);
1741 /* parse the loaded descriptors */
1743 for (int32_t i = 0; i < c->cpcount; i++) {
1744 constant_FMIref *fmi;
1747 switch (c->cptags[i]) {
1748 case CONSTANT_Fieldref:
1749 fmi = (constant_FMIref *) c->cpinfos[i];
1750 fmi->parseddesc.fd =
1751 descriptor_pool_parse_field_descriptor(descpool,
1753 if (!fmi->parseddesc.fd)
1756 index = fmi->p.index;
1758 (constant_classref *) class_getconstant(c, index,
1760 if (!fmi->p.classref)
1763 case CONSTANT_Methodref:
1764 case CONSTANT_InterfaceMethodref:
1765 fmi = (constant_FMIref *) c->cpinfos[i];
1766 index = fmi->p.index;
1768 (constant_classref *) class_getconstant(c, index,
1770 if (!fmi->p.classref)
1772 fmi->parseddesc.md =
1773 descriptor_pool_parse_method_descriptor(descpool,
1777 if (!fmi->parseddesc.md)
1783 RT_TIMING_GET_TIME(time_parsecpool);
1785 #ifdef ENABLE_VERIFIER
1786 /* Check if all fields and methods can be uniquely
1787 * identified by (name,descriptor). */
1790 /* We use a hash table here to avoid making the
1791 * average case quadratic in # of methods, fields.
1793 static int shift = 0;
1795 u2 *next; /* for chaining colliding hash entries */
1801 /* Allocate hashtable */
1802 len = c->methodscount;
1803 if (len < c->fieldscount) len = c->fieldscount;
1805 hashtab = MNEW(u2,(hashlen + len));
1806 next = hashtab + hashlen;
1808 /* Determine bitshift (to get good hash values) */
1818 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
1820 for (int32_t i = 0; i < c->fieldscount; ++i) {
1821 fieldinfo *fi = c->fields + i;
1823 /* It's ok if we lose bits here */
1824 index = ((((size_t) fi->name) +
1825 ((size_t) fi->descriptor)) >> shift) % hashlen;
1827 if ((old = hashtab[index])) {
1831 if (c->fields[old].name == fi->name &&
1832 c->fields[old].descriptor == fi->descriptor) {
1833 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
1836 } while ((old = next[old]));
1838 hashtab[index] = i + 1;
1842 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
1844 for (int32_t i = 0; i < c->methodscount; ++i) {
1845 methodinfo *mi = c->methods + i;
1847 /* It's ok if we lose bits here */
1848 index = ((((size_t) mi->name) +
1849 ((size_t) mi->descriptor)) >> shift) % hashlen;
1851 if ((old = hashtab[index])) {
1855 if (c->methods[old].name == mi->name &&
1856 c->methods[old].descriptor == mi->descriptor) {
1857 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
1860 } while ((old = next[old]));
1862 hashtab[index] = i + 1;
1865 MFREE(hashtab, u2, (hashlen + len));
1867 #endif /* ENABLE_VERIFIER */
1869 RT_TIMING_GET_TIME(time_verify);
1871 #if defined(ENABLE_STATISTICS)
1873 size_classinfo += sizeof(classinfo*) * c->interfacescount;
1874 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
1875 size_methodinfo += sizeof(methodinfo) * c->methodscount;
1879 /* load attribute structures */
1881 if (!class_load_attributes(cb))
1884 /* Pre Java 1.5 version don't check this. This implementation is
1885 like Java 1.5 do it: for class file version 45.3 we don't check
1886 it, older versions are checked. */
1888 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
1889 /* check if all data has been read */
1890 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
1892 if (classdata_left > 0) {
1893 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
1898 RT_TIMING_GET_TIME(time_attrs);
1900 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
1901 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
1902 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
1903 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
1904 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
1905 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
1906 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
1907 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
1908 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
1909 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
1910 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
1911 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
1912 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
1913 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
1914 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
1920 /* load_class_from_classbuffer *************************************************
1922 Convenience wrapper for load_class_from_classbuffer.
1925 This function is NOT synchronized!
1927 *******************************************************************************/
1929 classinfo *load_class_from_classbuffer(classbuffer *cb)
1934 /* Get the classbuffer's class. */
1938 /* Check if the class is already loaded. */
1940 if (c->state & CLASS_LOADED)
1943 #if defined(ENABLE_STATISTICS)
1945 count_class_loads++;
1948 #if !defined(NDEBUG)
1950 log_message_class("Loading class: ", c);
1953 /* Class is currently loading. */
1955 c->state |= CLASS_LOADING;
1957 /* Parse the classbuffer. */
1959 result = load_class_from_classbuffer_intern(cb);
1961 /* An error occurred. */
1963 if (result == false) {
1964 /* Revert loading state. */
1966 c->state = (c->state & ~CLASS_LOADING);
1971 /* Revert loading state and set loaded. */
1973 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
1975 #if defined(ENABLE_JVMTI)
1976 /* fire Class Prepare JVMTI event */
1979 jvmti_ClassLoadPrepare(true, c);
1982 #if !defined(NDEBUG)
1984 log_message_class("Loading done class: ", c);
1991 /* load_newly_created_array ****************************************************
1993 Load a newly created array class.
1996 c....................the array class C has been loaded
1997 other classinfo......the array class was found in the class cache,
1999 NULL.................an exception has been thrown
2002 This is an internal function. Do not use it unless you know exactly
2005 Use one of the load_class_... functions for general array class loading.
2007 *******************************************************************************/
2009 classinfo *load_newly_created_array(classinfo *c, classloader_t *loader)
2011 classinfo *comp = NULL;
2013 methoddesc *clonedesc;
2014 constant_classref *classrefs;
2019 text = c->name->text;
2020 namelen = c->name->blength;
2022 /* Check array class name */
2024 if ((namelen < 2) || (text[0] != '[')) {
2025 exceptions_throw_classnotfoundexception(c->name);
2029 /* Check the element type */
2033 /* c is an array of arrays. We have to create the component class. */
2035 u = utf_new(text + 1, namelen - 1);
2037 comp = load_class_from_classloader(u, loader);
2042 assert(comp->state & CLASS_LOADED);
2044 /* the array's flags are that of the component class */
2045 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2046 c->classloader = comp->classloader;
2050 /* c is an array of objects. */
2052 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2053 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2054 exceptions_throw_classnotfoundexception(c->name);
2058 u = utf_new(text + 2, namelen - 3);
2060 if (!(comp = load_class_from_classloader(u, loader)))
2063 assert(comp->state & CLASS_LOADED);
2065 /* the array's flags are that of the component class */
2066 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2067 c->classloader = comp->classloader;
2071 /* c is an array of a primitive type */
2073 /* check for cases like `[II' and whether the character is a
2074 valid primitive type */
2076 if ((namelen > 2) || (Primitive::get_class_by_char(text[1]) == NULL)) {
2077 exceptions_throw_classnotfoundexception(c->name);
2081 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2082 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2083 c->classloader = NULL;
2086 assert(class_java_lang_Object);
2087 #if defined(ENABLE_JAVASE)
2088 assert(class_java_lang_Cloneable);
2089 assert(class_java_io_Serializable);
2092 /* Setup the array class. */
2094 c->super = class_java_lang_Object;
2096 #if defined(ENABLE_JAVASE)
2098 c->interfacescount = 2;
2099 c->interfaces = MNEW(classinfo*, 2);
2100 c->interfaces[0] = class_java_lang_Cloneable;
2101 c->interfaces[1] = class_java_io_Serializable;
2103 #elif defined(ENABLE_JAVAME_CLDC1_1)
2105 c->interfacescount = 0;
2106 c->interfaces = NULL;
2109 # error unknow Java configuration
2112 c->methodscount = 1;
2113 c->methods = MNEW(methodinfo, c->methodscount);
2115 MZERO(c->methods, methodinfo, c->methodscount);
2117 classrefs = MNEW(constant_classref, 2);
2119 CLASSREF_INIT(classrefs[0], c, c->name);
2120 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2122 /* create descriptor for clone method */
2123 /* we need one paramslot which is reserved for the 'this' parameter */
2124 clonedesc = NEW(methoddesc);
2125 clonedesc->returntype.type = TYPE_ADR;
2126 clonedesc->returntype.classref = classrefs + 1;
2127 clonedesc->returntype.arraydim = 0;
2128 /* initialize params to "empty", add real params below in
2129 descriptor_params_from_paramtypes */
2130 clonedesc->paramcount = 0;
2131 clonedesc->paramslots = 0;
2132 clonedesc->paramtypes[0].classref = classrefs + 0;
2133 clonedesc->params = NULL;
2135 /* create methodinfo */
2138 MSET(clone, 0, methodinfo, 1);
2140 /* ATTENTION: if you delete the ACC_NATIVE below, set
2141 clone->maxlocals=1 (interpreter related) */
2143 clone->mutex = new Mutex();
2144 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2145 clone->name = utf_clone;
2146 clone->descriptor = utf_void__java_lang_Object;
2147 clone->parseddesc = clonedesc;
2150 /* parse the descriptor to get the register allocation */
2152 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2155 clone->code = NativeStub::generate(clone, BUILTIN_clone);
2157 /* XXX: field: length? */
2159 /* array classes are not loaded from class files */
2161 c->state |= CLASS_LOADED;
2162 c->parseddescs = (u1 *) clonedesc;
2163 c->parseddescsize = sizeof(methodinfo);
2164 c->classrefs = classrefs;
2165 c->classrefcount = 1;
2167 /* insert class into the loaded class cache */
2168 /* XXX free classinfo if NULL returned? */
2170 return classcache_store(loader, c, true);
2174 /* loader_close ****************************************************************
2176 Frees all resources.
2178 *******************************************************************************/
2180 void loader_close(void)
2187 * These are local overrides for various environment variables in Emacs.
2188 * Please do not remove this and leave it at the end of the file, where
2189 * Emacs will automagically detect them.
2190 * ---------------------------------------------------------------------
2193 * indent-tabs-mode: t
2197 * vim:noexpandtab:sw=4:ts=4: