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/hook.hpp"
53 #include "vm/javaobjects.hpp"
54 #include "vm/linker.hpp"
55 #include "vm/loader.hpp"
56 #include "vm/method.hpp"
57 #include "vm/options.h"
58 #include "vm/package.hpp"
59 #include "vm/primitive.hpp"
60 #include "vm/resolve.hpp"
61 #include "vm/rt-timing.h"
62 #include "vm/string.hpp"
63 #include "vm/suck.hpp"
67 #if defined(ENABLE_JAVASE)
68 # include "vm/annotation.hpp"
69 # include "vm/stackmap.h"
72 #if defined(ENABLE_STATISTICS)
73 # include "vm/statistics.h"
76 #if defined(ENABLE_ZLIB)
77 # include "vm/zip.hpp"
80 #include "vm/jit/stubs.hpp"
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 TRACESUBSYSTEMINITIALIZATION("loader_preinit");
102 #if defined(ENABLE_THREADS)
103 // Get current list of classpath entries.
104 SuckClasspath& suckclasspath = VM::get_current()->get_suckclasspath();
106 /* Initialize the monitor pointer for zip/jar file locking. */
108 for (SuckClasspath::iterator it = suckclasspath.begin(); it != suckclasspath.end(); it++) {
109 list_classpath_entry* lce = *it;
111 if (lce->type == CLASSPATH_ARCHIVE)
112 lce->mutex = new Mutex();
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 #if defined(ENABLE_ZLIB)
400 hashtable_zipfile_entry *htzfe;
404 // Get current list of classpath entries.
405 SuckClasspath& suckclasspath = VM::get_current()->get_suckclasspath();
407 for (SuckClasspath::iterator it = suckclasspath.begin(); it != suckclasspath.end(); it++) {
408 list_classpath_entry* lce = *it;
410 #if defined(ENABLE_ZLIB)
411 if (lce->type == CLASSPATH_ARCHIVE) {
412 /* get the classes hashtable */
416 for (uint32_t slot = 0; slot < ht->size; slot++) {
417 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
419 for (; htzfe; htzfe = htzfe->hashlink) {
422 /* skip all entries in META-INF and .properties,
425 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
426 strstr(u->text, ".properties") ||
427 strstr(u->text, ".png"))
430 /* load class from bootstrap classloader */
432 if (!load_class_bootstrap(u)) {
433 fprintf(stderr, "Error loading: ");
434 utf_fprint_printable_ascii_classname(stderr, u);
435 fprintf(stderr, "\n");
438 /* print out exception and cause */
440 exceptions_print_current_exception();
448 #if defined(ENABLE_ZLIB)
455 /* loader_skip_attribute_body **************************************************
457 Skips an attribute the attribute_name_index has already been read.
460 u2 attribute_name_index;
462 u1 info[attribute_length];
465 *******************************************************************************/
467 bool loader_skip_attribute_body(classbuffer *cb)
471 if (!suck_check_classbuffer_size(cb, 4))
474 attribute_length = suck_u4(cb);
476 if (!suck_check_classbuffer_size(cb, attribute_length))
479 suck_skip_nbytes(cb, attribute_length);
485 /* load_constantpool ***********************************************************
487 Loads the constantpool of a class, the entries are transformed into
488 a simpler format by resolving references (a detailed overview of
489 the compact structures can be found in global.h).
491 *******************************************************************************/
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 (only in specific order). */
497 /* CONSTANT_Class entries */
498 typedef struct forward_class {
503 /* CONSTANT_String */
504 typedef struct forward_string {
509 /* CONSTANT_NameAndType */
510 typedef struct forward_nameandtype {
514 } forward_nameandtype;
516 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
517 typedef struct forward_fieldmethint {
521 u2 nameandtype_index;
522 } forward_fieldmethint;
524 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
529 DumpList<forward_class> forward_classes;
530 DumpList<forward_string> forward_strings;
531 DumpList<forward_nameandtype> forward_nameandtypes;
532 DumpList<forward_fieldmethint> forward_fieldmethints;
536 forward_nameandtype nfn;
537 forward_fieldmethint nff;
545 /* number of entries in the constant_pool table plus one */
546 if (!suck_check_classbuffer_size(cb, 2))
549 cpcount = c->cpcount = suck_u2(cb);
551 /* allocate memory */
552 cptags = c->cptags = MNEW(u1, cpcount);
553 cpinfos = c->cpinfos = MNEW(void*, cpcount);
556 exceptions_throw_classformaterror(c, "Illegal constant pool size");
560 #if defined(ENABLE_STATISTICS)
562 count_const_pool_len += (sizeof(u1) + sizeof(void*)) * cpcount;
565 /* initialize constantpool */
566 for (idx = 0; idx < cpcount; idx++) {
567 cptags[idx] = CONSTANT_UNUSED;
572 /******* first pass *******/
573 /* entries which cannot be resolved now are written into
574 temporary structures and traversed again later */
577 while (idx < cpcount) {
580 /* get constant type */
581 if (!suck_check_classbuffer_size(cb, 1))
590 /* reference to CONSTANT_NameAndType */
591 if (!suck_check_classbuffer_size(cb, 2))
594 nfc.name_index = suck_u2(cb);
596 forward_classes.push_front(nfc);
601 case CONSTANT_String:
604 /* reference to CONSTANT_Utf8_info with string characters */
605 if (!suck_check_classbuffer_size(cb, 2))
608 nfs.string_index = suck_u2(cb);
610 forward_strings.push_front(nfs);
615 case CONSTANT_NameAndType:
618 if (!suck_check_classbuffer_size(cb, 2 + 2))
621 /* reference to CONSTANT_Utf8_info containing simple name */
622 nfn.name_index = suck_u2(cb);
624 /* reference to CONSTANT_Utf8_info containing field or method
626 nfn.sig_index = suck_u2(cb);
628 forward_nameandtypes.push_front(nfn);
633 case CONSTANT_Fieldref:
634 case CONSTANT_Methodref:
635 case CONSTANT_InterfaceMethodref:
640 if (!suck_check_classbuffer_size(cb, 2 + 2))
643 /* class or interface type that contains the declaration of the
645 nff.class_index = suck_u2(cb);
647 /* name and descriptor of the field or method */
648 nff.nameandtype_index = suck_u2(cb);
650 forward_fieldmethints.push_front(nff);
655 case CONSTANT_Integer: {
656 constant_integer *ci = NEW(constant_integer);
658 #if defined(ENABLE_STATISTICS)
660 count_const_pool_len += sizeof(constant_integer);
663 if (!suck_check_classbuffer_size(cb, 4))
666 ci->value = suck_s4(cb);
667 cptags[idx] = CONSTANT_Integer;
674 case CONSTANT_Float: {
675 constant_float *cf = NEW(constant_float);
677 #if defined(ENABLE_STATISTICS)
679 count_const_pool_len += sizeof(constant_float);
682 if (!suck_check_classbuffer_size(cb, 4))
685 cf->value = suck_float(cb);
686 cptags[idx] = CONSTANT_Float;
693 case CONSTANT_Long: {
694 constant_long *cl = NEW(constant_long);
696 #if defined(ENABLE_STATISTICS)
698 count_const_pool_len += sizeof(constant_long);
701 if (!suck_check_classbuffer_size(cb, 8))
704 cl->value = suck_s8(cb);
705 cptags[idx] = CONSTANT_Long;
709 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
715 case CONSTANT_Double: {
716 constant_double *cd = NEW(constant_double);
718 #if defined(ENABLE_STATISTICS)
720 count_const_pool_len += sizeof(constant_double);
723 if (!suck_check_classbuffer_size(cb, 8))
726 cd->value = suck_double(cb);
727 cptags[idx] = CONSTANT_Double;
731 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
737 case CONSTANT_Utf8: {
740 /* number of bytes in the bytes array (not string-length) */
741 if (!suck_check_classbuffer_size(cb, 2))
744 length = suck_u2(cb);
745 cptags[idx] = CONSTANT_Utf8;
747 /* validate the string */
748 if (!suck_check_classbuffer_size(cb, length))
751 #ifdef ENABLE_VERIFIER
753 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
755 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
758 #endif /* ENABLE_VERIFIER */
759 /* insert utf-string into the utf-symboltable */
760 cpinfos[idx] = utf_new((char *) cb->pos, length);
762 /* skip bytes of the string (buffer size check above) */
763 suck_skip_nbytes(cb, length);
769 exceptions_throw_classformaterror(c, "Illegal constant pool type");
775 /* resolve entries in temporary structures */
777 for (DumpList<forward_class>::iterator it = forward_classes.begin();
778 it != forward_classes.end(); ++it) {
780 utf *name = (utf*) class_getconstant(c, it->name_index, CONSTANT_Utf8);
784 #ifdef ENABLE_VERIFIER
785 if (opt_verify && !is_valid_name_utf(name)) {
786 exceptions_throw_classformaterror(c, "Class reference with invalid name");
789 #endif /* ENABLE_VERIFIER */
791 /* add all class references to the descriptor_pool */
793 if (!descriptor_pool_add_class(descpool, name))
796 cptags[it->thisindex] = CONSTANT_Class;
798 /* the classref is created later */
799 cpinfos[it->thisindex] = name;
802 for (DumpList<forward_string>::iterator it = forward_strings.begin();
803 it != forward_strings.end(); ++it) {
805 utf *text = (utf*) class_getconstant(c, it->string_index, CONSTANT_Utf8);
810 /* resolve utf-string */
811 cptags[it->thisindex] = CONSTANT_String;
812 cpinfos[it->thisindex] = text;
815 for (DumpList<forward_nameandtype>::iterator it = forward_nameandtypes.begin();
816 it != forward_nameandtypes.end(); ++it) {
818 constant_nameandtype *cn = NEW(constant_nameandtype);
820 #if defined(ENABLE_STATISTICS)
822 count_const_pool_len += sizeof(constant_nameandtype);
825 /* resolve simple name and descriptor */
826 cn->name = (utf*) class_getconstant(c,
832 cn->descriptor = (utf*) class_getconstant(c,
838 #ifdef ENABLE_VERIFIER
841 if (!is_valid_name_utf(cn->name)) {
842 exceptions_throw_classformaterror(c,
843 "Illegal Field name \"%s\"",
849 /* disallow referencing <clinit> among others */
850 if (cn->name->text[0] == '<' && cn->name != utf_init) {
851 exceptions_throw_classformaterror(c, "Illegal reference to special method");
855 #endif /* ENABLE_VERIFIER */
857 cptags[it->thisindex] = CONSTANT_NameAndType;
858 cpinfos[it->thisindex] = cn;
861 for (DumpList<forward_fieldmethint>::iterator it = forward_fieldmethints.begin();
862 it != forward_fieldmethints.end(); ++it) {
864 constant_nameandtype *nat;
865 constant_FMIref *fmi = NEW(constant_FMIref);
867 #if defined(ENABLE_STATISTICS)
869 count_const_pool_len += sizeof(constant_FMIref);
871 /* resolve simple name and descriptor */
873 nat = (constant_nameandtype*) class_getconstant(c,
874 it->nameandtype_index,
875 CONSTANT_NameAndType);
880 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
882 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
885 /* the classref is created later */
887 fmi->p.index = it->class_index;
888 fmi->name = nat->name;
889 fmi->descriptor = nat->descriptor;
891 cptags[it->thisindex] = it->tag;
892 cpinfos[it->thisindex] = fmi;
895 /* everything was ok */
901 /* loader_load_attribute_signature *********************************************
903 Signature_attribute {
904 u2 attribute_name_index;
909 *******************************************************************************/
911 #if defined(ENABLE_JAVASE)
912 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
922 /* check remaining bytecode */
924 if (!suck_check_classbuffer_size(cb, 4 + 2))
927 /* check attribute length */
929 attribute_length = suck_u4(cb);
931 if (attribute_length != 2) {
932 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
936 if (*signature != NULL) {
937 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
943 signature_index = suck_u2(cb);
945 *signature = (utf*) class_getconstant(c, signature_index, CONSTANT_Utf8);
947 if (*signature == NULL)
952 #endif /* defined(ENABLE_JAVASE) */
955 /* load_class_from_sysloader ***************************************************
957 Load the class with the given name using the system class loader
960 name.............the classname
964 NULL if an exception has been thrown
966 *******************************************************************************/
968 #if defined(ENABLE_JAVASE)
969 classinfo *load_class_from_sysloader(utf *name)
974 cl = java_lang_ClassLoader::invoke_getSystemClassLoader();
979 c = load_class_from_classloader(name, cl);
983 #endif /* defined(ENABLE_JAVASE) */
986 /* load_class_from_classloader *************************************************
988 Load the class with the given name using the given user-defined class loader.
991 name.............the classname
992 cl...............user-defined class loader
996 NULL if an exception has been thrown
998 *******************************************************************************/
1000 classinfo *load_class_from_classloader(utf *name, classloader_t *cl)
1005 java_handle_t *string;
1006 #if defined(ENABLE_RT_TIMING)
1007 struct timespec time_start, time_lookup, time_prepare, time_java,
1011 RT_TIMING_GET_TIME(time_start);
1015 /* lookup if this class has already been loaded */
1017 c = classcache_lookup(cl, name);
1019 RT_TIMING_GET_TIME(time_lookup);
1020 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1025 /* if other class loader than bootstrap, call it */
1033 namelen = name->blength;
1035 /* handle array classes */
1036 if (text[0] == '[') {
1042 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1043 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1044 exceptions_throw_classnotfoundexception(name);
1048 u = utf_new(text + 2, namelen - 3);
1050 if (!(comp = load_class_from_classloader(u, cl)))
1053 /* create the array class */
1055 c = class_array_of(comp, false);
1057 tmpc = classcache_store(cl, c, true);
1060 /* exception, free the loaded class */
1061 c->state &= ~CLASS_LOADING;
1068 /* load the component class */
1070 u = utf_new(text + 1, namelen - 1);
1072 if (!(comp = load_class_from_classloader(u, cl)))
1075 /* create the array class */
1077 c = class_array_of(comp, false);
1079 tmpc = classcache_store(cl, c, true);
1082 /* exception, free the loaded class */
1083 c->state &= ~CLASS_LOADING;
1090 /* primitive array classes are loaded by the bootstrap loader */
1092 c = load_class_bootstrap(name);
1098 LLNI_class_get(cl, c);
1100 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1101 /* OpenJDK uses this internal function because it's
1104 lc = class_resolveclassmethod(c,
1105 utf_loadClassInternal,
1106 utf_java_lang_String__java_lang_Class,
1110 lc = class_resolveclassmethod(c,
1112 utf_java_lang_String__java_lang_Class,
1118 return false; /* exception */
1120 /* move return value into `o' and cast it afterwards to a classinfo* */
1122 string = javastring_new_slash_to_dot(name);
1124 RT_TIMING_GET_TIME(time_prepare);
1126 o = vm_call_method(lc, (java_handle_t *) cl, string);
1128 RT_TIMING_GET_TIME(time_java);
1130 c = LLNI_classinfo_unwrap(o);
1133 /* Store this class in the loaded class cache. If another
1134 class with the same (initloader,name) pair has been
1135 stored earlier it will be returned by classcache_store
1136 In this case classcache_store may not free the class
1137 because it has already been exposed to Java code which
1138 may have kept references to that class. */
1140 tmpc = classcache_store(cl, c, false);
1143 /* exception, free the loaded class */
1144 c->state &= ~CLASS_LOADING;
1151 // Expected behavior for the classloader is to throw an exception
1152 // and never return NULL. If the classloader shows a different
1153 // behavior, we are correcting it here (see PR126).
1154 if (exceptions_get_exception() == NULL) {
1155 #if !defined(NDEBUG)
1156 if (opt_PrintWarnings)
1157 log_message_utf("load_class_from_classloader: Correcting faulty classloader behavior (PR126) for ", name);
1159 exceptions_throw_classnotfoundexception(name);
1163 RT_TIMING_GET_TIME(time_cache);
1165 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1166 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1167 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1169 /* SUN compatible -verbose:class output */
1171 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1173 utf_display_printable_ascii_classname(name);
1180 c = load_class_bootstrap(name);
1186 /* load_class_bootstrap ********************************************************
1188 Load the class with the given name using the bootstrap class loader.
1191 name.............the classname
1194 loaded classinfo, or
1195 NULL if an exception has been thrown
1198 load_class_bootstrap is synchronized. It can be treated as an
1201 *******************************************************************************/
1203 classinfo *load_class_bootstrap(utf *name)
1208 #if defined(ENABLE_RT_TIMING)
1209 struct timespec time_start, time_lookup, time_array, time_suck,
1210 time_load, time_cache;
1213 RT_TIMING_GET_TIME(time_start);
1219 /* lookup if this class has already been loaded */
1221 r = classcache_lookup(NULL, name);
1224 RT_TIMING_GET_TIME(time_lookup);
1225 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1230 RT_TIMING_GET_TIME(time_lookup);
1231 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1233 /* create the classinfo */
1235 c = class_create_classinfo(name);
1237 /* handle array classes */
1239 if (name->text[0] == '[') {
1240 c = load_newly_created_array(c, NULL);
1245 assert(c->state & CLASS_LOADED);
1247 RT_TIMING_GET_TIME(time_array);
1248 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1253 #if defined(ENABLE_STATISTICS)
1256 if (opt_getcompilingtime)
1257 compilingtime_stop();
1259 if (opt_getloadingtime)
1260 loadingtime_start();
1263 /* load classdata, throw exception on error */
1268 exceptions_throw_classnotfoundexception(name);
1272 RT_TIMING_GET_TIME(time_suck);
1274 /* load the class from the buffer */
1276 r = load_class_from_classbuffer(cb);
1278 RT_TIMING_GET_TIME(time_load);
1281 /* the class could not be loaded, free the classinfo struct */
1286 /* Store this class in the loaded class cache this step also
1287 checks the loading constraints. If the class has been
1288 loaded before, the earlier loaded class is returned. */
1290 classinfo *res = classcache_store(NULL, c, true);
1297 // Add the package name to the boot packages.
1298 Package::add(c->packagename);
1304 RT_TIMING_GET_TIME(time_cache);
1306 /* SUN compatible -verbose:class output */
1308 if (opt_verboseclass && r) {
1310 utf_display_printable_ascii_classname(name);
1311 printf(" from %s]\n", cb->path);
1318 #if defined(ENABLE_STATISTICS)
1321 if (opt_getloadingtime)
1324 if (opt_getcompilingtime)
1325 compilingtime_start();
1328 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1329 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1330 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1331 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1337 /* load_class_from_classbuffer_intern ******************************************
1339 Loads a class from a classbuffer into a given classinfo structure.
1340 Super-classes are also loaded at this point and some verfication
1344 This function is NOT synchronized!
1346 *******************************************************************************/
1348 static bool load_class_from_classbuffer_intern(classbuffer *cb)
1354 utf **interfacesnames;
1356 constant_classref *cr;
1360 descriptor_pool *descpool;
1361 #if defined(ENABLE_STATISTICS)
1365 #if defined(ENABLE_RT_TIMING)
1366 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1367 time_setup, time_fields, time_methods, time_classrefs,
1368 time_descs, time_setrefs, time_parsefds, time_parsemds,
1369 time_parsecpool, time_verify, time_attrs;
1372 // Create new dump memory area.
1375 RT_TIMING_GET_TIME(time_start);
1377 /* Get the classbuffer's class. */
1381 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1384 /* check signature */
1386 if (suck_u4(cb) != MAGIC) {
1387 exceptions_throw_classformaterror(c, "Bad magic number");
1396 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1397 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1401 RT_TIMING_GET_TIME(time_checks);
1403 /* create a new descriptor pool */
1405 descpool = descriptor_pool_new(c);
1407 RT_TIMING_GET_TIME(time_ndpool);
1409 /* load the constant pool */
1411 if (!load_constantpool(cb, descpool))
1414 RT_TIMING_GET_TIME(time_cpool);
1418 if (!suck_check_classbuffer_size(cb, 2))
1421 /* We OR the flags here, as we set already some flags in
1422 class_create_classinfo. */
1424 c->flags |= suck_u2(cb);
1426 /* check ACC flags consistency */
1428 if (c->flags & ACC_INTERFACE) {
1429 if (!(c->flags & ACC_ABSTRACT)) {
1430 /* We work around this because interfaces in JDK 1.1 are
1431 * not declared abstract. */
1433 c->flags |= ACC_ABSTRACT;
1436 if (c->flags & ACC_FINAL) {
1437 exceptions_throw_classformaterror(c,
1438 "Illegal class modifiers: 0x%X",
1443 if (c->flags & ACC_SUPER) {
1444 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1448 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1449 exceptions_throw_classformaterror(c,
1450 "Illegal class modifiers: 0x%X",
1455 if (!suck_check_classbuffer_size(cb, 2 + 2))
1460 index = suck_u2(cb);
1462 name = (utf *) class_getconstant(c, index, CONSTANT_Class);
1467 if (c->name == utf_not_named_yet) {
1468 /* we finally have a name for this class */
1470 class_set_packagename(c);
1472 else if (name != c->name) {
1473 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
1477 /* Retrieve superclass. */
1481 index = suck_u2(cb);
1486 /* This is only allowed for java.lang.Object. */
1488 if (c->name != utf_java_lang_Object) {
1489 exceptions_throw_classformaterror(c, "Bad superclass index");
1494 supername = (utf *) class_getconstant(c, index, CONSTANT_Class);
1496 if (supername == NULL)
1499 /* java.lang.Object may not have a super class. */
1501 if (c->name == utf_java_lang_Object) {
1502 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
1506 /* Detect circularity. */
1508 if (supername == c->name) {
1509 exceptions_throw_classcircularityerror(c);
1513 /* Interfaces must have java.lang.Object as super class. */
1515 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
1516 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
1521 /* Parse the super interfaces. */
1523 if (!suck_check_classbuffer_size(cb, 2))
1526 c->interfacescount = suck_u2(cb);
1528 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1531 c->interfaces = MNEW(classinfo*, c->interfacescount);
1533 /* Get the names of the super interfaces. */
1535 interfacesnames = (utf**) DumpMemory::allocate(sizeof(utf*) * c->interfacescount);
1537 for (int32_t i = 0; i < c->interfacescount; i++) {
1538 index = suck_u2(cb);
1540 u = (utf *) class_getconstant(c, index, CONSTANT_Class);
1545 interfacesnames[i] = u;
1548 RT_TIMING_GET_TIME(time_setup);
1552 if (!suck_check_classbuffer_size(cb, 2))
1555 c->fieldscount = suck_u2(cb);
1556 c->fields = MNEW(fieldinfo, c->fieldscount);
1558 MZERO(c->fields, fieldinfo, c->fieldscount);
1560 for (int32_t i = 0; i < c->fieldscount; i++) {
1561 if (!field_load(cb, &(c->fields[i]), descpool))
1565 RT_TIMING_GET_TIME(time_fields);
1567 /* Parse methods. */
1569 if (!suck_check_classbuffer_size(cb, 2))
1572 c->methodscount = suck_u2(cb);
1573 c->methods = MNEW(methodinfo, c->methodscount);
1575 MZERO(c->methods, methodinfo, c->methodscount);
1577 for (int32_t i = 0; i < c->methodscount; i++) {
1578 if (!method_load(cb, &(c->methods[i]), descpool))
1582 RT_TIMING_GET_TIME(time_methods);
1584 /* create the class reference table */
1587 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
1589 RT_TIMING_GET_TIME(time_classrefs);
1591 /* allocate space for the parsed descriptors */
1593 descriptor_pool_alloc_parsed_descriptors(descpool);
1594 c->parseddescs = (u1*) descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
1596 #if defined(ENABLE_STATISTICS)
1598 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
1599 count_classref_len += classrefsize;
1600 count_parsed_desc_len += descsize;
1604 RT_TIMING_GET_TIME(time_descs);
1606 /* put the classrefs in the constant pool */
1608 for (int32_t i = 0; i < c->cpcount; i++) {
1609 if (c->cptags[i] == CONSTANT_Class) {
1610 utf *name = (utf *) c->cpinfos[i];
1611 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
1615 /* Resolve the super class. */
1617 if (supername != NULL) {
1618 cr = descriptor_pool_lookup_classref(descpool, supername);
1623 /* XXX This should be done better. */
1624 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1627 resolve_handle_pending_exception(true);
1631 /* Interfaces are not allowed as super classes. */
1633 if (tc->flags & ACC_INTERFACE) {
1634 exceptions_throw_incompatibleclasschangeerror(c, "class %s has interface %s as super class");
1638 /* Don't allow extending final classes */
1640 if (tc->flags & ACC_FINAL) {
1641 exceptions_throw_verifyerror(NULL,
1642 "Cannot inherit from final class");
1646 /* Store the super class. */
1651 /* Resolve the super interfaces. */
1653 for (int32_t i = 0; i < c->interfacescount; i++) {
1654 u = interfacesnames[i];
1655 cr = descriptor_pool_lookup_classref(descpool, u);
1660 /* XXX This should be done better. */
1661 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1664 resolve_handle_pending_exception(true);
1668 /* Detect circularity. */
1671 exceptions_throw_classcircularityerror(c);
1675 if (!(tc->flags & ACC_INTERFACE)) {
1676 exceptions_throw_incompatibleclasschangeerror(tc,
1677 "Implementing class");
1681 /* Store the super interface. */
1683 c->interfaces[i] = tc;
1686 RT_TIMING_GET_TIME(time_setrefs);
1688 /* Parse the field descriptors. */
1690 for (int32_t i = 0; i < c->fieldscount; i++) {
1691 c->fields[i].parseddesc =
1692 descriptor_pool_parse_field_descriptor(descpool,
1693 c->fields[i].descriptor);
1694 if (!c->fields[i].parseddesc)
1698 RT_TIMING_GET_TIME(time_parsefds);
1700 /* parse method descriptors */
1702 for (int32_t i = 0; i < c->methodscount; i++) {
1703 methodinfo *m = &c->methods[i];
1705 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
1706 m->flags, class_get_self_classref(m->clazz));
1710 for (int32_t j = 0; j < m->rawexceptiontablelength; j++) {
1711 if (!m->rawexceptiontable[j].catchtype.any)
1714 if ((m->rawexceptiontable[j].catchtype.ref =
1715 descriptor_pool_lookup_classref(descpool,
1716 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
1720 for (int32_t j = 0; j < m->thrownexceptionscount; j++) {
1721 if (!m->thrownexceptions[j].any)
1724 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
1725 (utf *) m->thrownexceptions[j].any)) == NULL)
1730 RT_TIMING_GET_TIME(time_parsemds);
1732 /* parse the loaded descriptors */
1734 for (int32_t i = 0; i < c->cpcount; i++) {
1735 constant_FMIref *fmi;
1738 switch (c->cptags[i]) {
1739 case CONSTANT_Fieldref:
1740 fmi = (constant_FMIref *) c->cpinfos[i];
1741 fmi->parseddesc.fd =
1742 descriptor_pool_parse_field_descriptor(descpool,
1744 if (!fmi->parseddesc.fd)
1747 index = fmi->p.index;
1749 (constant_classref *) class_getconstant(c, index,
1751 if (!fmi->p.classref)
1754 case CONSTANT_Methodref:
1755 case CONSTANT_InterfaceMethodref:
1756 fmi = (constant_FMIref *) c->cpinfos[i];
1757 index = fmi->p.index;
1759 (constant_classref *) class_getconstant(c, index,
1761 if (!fmi->p.classref)
1763 fmi->parseddesc.md =
1764 descriptor_pool_parse_method_descriptor(descpool,
1768 if (!fmi->parseddesc.md)
1774 RT_TIMING_GET_TIME(time_parsecpool);
1776 #ifdef ENABLE_VERIFIER
1777 /* Check if all fields and methods can be uniquely
1778 * identified by (name,descriptor). */
1781 /* We use a hash table here to avoid making the
1782 * average case quadratic in # of methods, fields.
1784 static int shift = 0;
1786 u2 *next; /* for chaining colliding hash entries */
1792 /* Allocate hashtable */
1793 len = c->methodscount;
1794 if (len < c->fieldscount) len = c->fieldscount;
1796 hashtab = MNEW(u2,(hashlen + len));
1797 next = hashtab + hashlen;
1799 /* Determine bitshift (to get good hash values) */
1809 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
1811 for (int32_t i = 0; i < c->fieldscount; ++i) {
1812 fieldinfo *fi = c->fields + i;
1814 /* It's ok if we lose bits here */
1815 index = ((((size_t) fi->name) +
1816 ((size_t) fi->descriptor)) >> shift) % hashlen;
1818 if ((old = hashtab[index])) {
1822 if (c->fields[old].name == fi->name &&
1823 c->fields[old].descriptor == fi->descriptor) {
1824 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
1827 } while ((old = next[old]));
1829 hashtab[index] = i + 1;
1833 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
1835 for (int32_t i = 0; i < c->methodscount; ++i) {
1836 methodinfo *mi = c->methods + i;
1838 /* It's ok if we lose bits here */
1839 index = ((((size_t) mi->name) +
1840 ((size_t) mi->descriptor)) >> shift) % hashlen;
1842 if ((old = hashtab[index])) {
1846 if (c->methods[old].name == mi->name &&
1847 c->methods[old].descriptor == mi->descriptor) {
1848 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
1851 } while ((old = next[old]));
1853 hashtab[index] = i + 1;
1856 MFREE(hashtab, u2, (hashlen + len));
1858 #endif /* ENABLE_VERIFIER */
1860 RT_TIMING_GET_TIME(time_verify);
1862 #if defined(ENABLE_STATISTICS)
1864 size_classinfo += sizeof(classinfo*) * c->interfacescount;
1865 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
1866 size_methodinfo += sizeof(methodinfo) * c->methodscount;
1870 /* load attribute structures */
1872 if (!class_load_attributes(cb))
1875 /* Pre Java 1.5 version don't check this. This implementation is
1876 like Java 1.5 do it: for class file version 45.3 we don't check
1877 it, older versions are checked. */
1879 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
1880 /* check if all data has been read */
1881 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
1883 if (classdata_left > 0) {
1884 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
1889 RT_TIMING_GET_TIME(time_attrs);
1891 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
1892 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
1893 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
1894 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
1895 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
1896 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
1897 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
1898 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
1899 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
1900 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
1901 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
1902 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
1903 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
1904 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
1905 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
1911 /* load_class_from_classbuffer *************************************************
1913 Convenience wrapper for load_class_from_classbuffer.
1916 This function is NOT synchronized!
1918 *******************************************************************************/
1920 classinfo *load_class_from_classbuffer(classbuffer *cb)
1925 /* Get the classbuffer's class. */
1929 /* Check if the class is already loaded. */
1931 if (c->state & CLASS_LOADED)
1934 #if defined(ENABLE_STATISTICS)
1936 count_class_loads++;
1939 #if !defined(NDEBUG)
1941 log_message_class("Loading class: ", c);
1944 /* Class is currently loading. */
1946 c->state |= CLASS_LOADING;
1948 /* Parse the classbuffer. */
1950 result = load_class_from_classbuffer_intern(cb);
1952 /* An error occurred. */
1954 if (result == false) {
1955 /* Revert loading state. */
1957 c->state = (c->state & ~CLASS_LOADING);
1962 /* Revert loading state and set loaded. */
1964 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
1966 #if !defined(NDEBUG)
1968 log_message_class("Loading done class: ", c);
1971 // Hook point just after a class was loaded.
1972 Hook::class_loaded(c);
1978 /* load_newly_created_array ****************************************************
1980 Load a newly created array class.
1983 c....................the array class C has been loaded
1984 other classinfo......the array class was found in the class cache,
1986 NULL.................an exception has been thrown
1989 This is an internal function. Do not use it unless you know exactly
1992 Use one of the load_class_... functions for general array class loading.
1994 *******************************************************************************/
1996 classinfo *load_newly_created_array(classinfo *c, classloader_t *loader)
1998 classinfo *comp = NULL;
2000 methoddesc *clonedesc;
2001 constant_classref *classrefs;
2006 text = c->name->text;
2007 namelen = c->name->blength;
2009 /* Check array class name */
2011 if ((namelen < 2) || (text[0] != '[')) {
2012 exceptions_throw_classnotfoundexception(c->name);
2016 /* Check the element type */
2020 /* c is an array of arrays. We have to create the component class. */
2022 u = utf_new(text + 1, namelen - 1);
2024 comp = load_class_from_classloader(u, loader);
2029 assert(comp->state & CLASS_LOADED);
2031 /* the array's flags are that of the component class */
2032 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2033 c->classloader = comp->classloader;
2037 /* c is an array of objects. */
2039 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2040 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2041 exceptions_throw_classnotfoundexception(c->name);
2045 u = utf_new(text + 2, namelen - 3);
2047 if (!(comp = load_class_from_classloader(u, loader)))
2050 assert(comp->state & CLASS_LOADED);
2052 /* the array's flags are that of the component class */
2053 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2054 c->classloader = comp->classloader;
2058 /* c is an array of a primitive type */
2060 /* check for cases like `[II' and whether the character is a
2061 valid primitive type */
2063 if ((namelen > 2) || (Primitive::get_class_by_char(text[1]) == NULL)) {
2064 exceptions_throw_classnotfoundexception(c->name);
2068 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2069 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2070 c->classloader = NULL;
2073 assert(class_java_lang_Object);
2074 #if defined(ENABLE_JAVASE)
2075 assert(class_java_lang_Cloneable);
2076 assert(class_java_io_Serializable);
2079 /* Setup the array class. */
2081 c->super = class_java_lang_Object;
2083 #if defined(ENABLE_JAVASE)
2085 c->interfacescount = 2;
2086 c->interfaces = MNEW(classinfo*, 2);
2087 c->interfaces[0] = class_java_lang_Cloneable;
2088 c->interfaces[1] = class_java_io_Serializable;
2090 #elif defined(ENABLE_JAVAME_CLDC1_1)
2092 c->interfacescount = 0;
2093 c->interfaces = NULL;
2096 # error unknow Java configuration
2099 c->methodscount = 1;
2100 c->methods = MNEW(methodinfo, c->methodscount);
2102 MZERO(c->methods, methodinfo, c->methodscount);
2104 classrefs = MNEW(constant_classref, 2);
2106 CLASSREF_INIT(classrefs[0], c, c->name);
2107 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2109 /* create descriptor for clone method */
2110 /* we need one paramslot which is reserved for the 'this' parameter */
2111 clonedesc = NEW(methoddesc);
2112 clonedesc->returntype.type = TYPE_ADR;
2113 clonedesc->returntype.classref = classrefs + 1;
2114 clonedesc->returntype.arraydim = 0;
2115 /* initialize params to "empty", add real params below in
2116 descriptor_params_from_paramtypes */
2117 clonedesc->paramcount = 0;
2118 clonedesc->paramslots = 0;
2119 clonedesc->paramtypes[0].classref = classrefs + 0;
2120 clonedesc->params = NULL;
2122 /* create methodinfo */
2125 MSET(clone, 0, methodinfo, 1);
2127 /* ATTENTION: if you delete the ACC_NATIVE below, set
2128 clone->maxlocals=1 (interpreter related) */
2130 clone->mutex = new Mutex();
2131 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2132 clone->name = utf_clone;
2133 clone->descriptor = utf_void__java_lang_Object;
2134 clone->parseddesc = clonedesc;
2137 /* parse the descriptor to get the register allocation */
2139 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2142 clone->code = NativeStub::generate(clone, BUILTIN_clone);
2144 /* XXX: field: length? */
2146 /* array classes are not loaded from class files */
2148 c->state |= CLASS_LOADED;
2149 c->parseddescs = (u1 *) clonedesc;
2150 c->parseddescsize = sizeof(methodinfo);
2151 c->classrefs = classrefs;
2152 c->classrefcount = 1;
2154 /* insert class into the loaded class cache */
2155 /* XXX free classinfo if NULL returned? */
2157 return classcache_store(loader, c, true);
2161 /* loader_close ****************************************************************
2163 Frees all resources.
2165 *******************************************************************************/
2167 void loader_close(void)
2174 * These are local overrides for various environment variables in Emacs.
2175 * Please do not remove this and leave it at the end of the file, where
2176 * Emacs will automagically detect them.
2177 * ---------------------------------------------------------------------
2180 * indent-tabs-mode: t
2184 * vim:noexpandtab:sw=4:ts=4: