1 /* src/vm/loader.cpp - class loader functions
3 Copyright (C) 1996-2011
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"));
234 class_sun_reflect_MethodAccessorImpl = load_class_bootstrap(utf_new_char("sun/reflect/MethodAccessorImpl"));
235 class_sun_reflect_ConstructorAccessorImpl = load_class_bootstrap(utf_new_char("sun/reflect/ConstructorAccessorImpl"));
238 arrayclass_java_lang_Object =
239 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"));
241 # if defined(ENABLE_ANNOTATIONS)
242 /* needed by annotation support */
243 class_sun_reflect_ConstantPool =
244 load_class_bootstrap(utf_new_char("sun/reflect/ConstantPool"));
246 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
247 /* needed by GNU Classpaths annotation support */
248 class_sun_reflect_annotation_AnnotationParser =
249 load_class_bootstrap(utf_new_char("sun/reflect/annotation/AnnotationParser"));
256 /* loader_hashtable_classloader_add ********************************************
258 Adds an entry to the classloader hashtable.
260 REMEMBER: Also use this to register native loaders!
262 *******************************************************************************/
264 classloader_t *loader_hashtable_classloader_add(java_handle_t *cl)
266 hashtable_classloader_entry *cle;
273 hashtable_classloader->mutex->lock();
277 /* key for entry is the hashcode of the classloader;
278 aligned to 16-byte boundaries */
280 key = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
281 slot = key & (hashtable_classloader->size - 1);
282 cle = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
284 /* search hashchain for existing entry */
287 if (cle->object == LLNI_DIRECT(cl))
295 /* if no classloader was found, we create a new entry here */
298 cle = NEW(hashtable_classloader_entry);
300 #if defined(ENABLE_GC_CACAO)
301 /* register the classloader object with the GC */
303 gc_reference_register(&(cle->object), GC_REFTYPE_CLASSLOADER);
308 cle->object = LLNI_DIRECT(cl);
312 /*#define LOADER_DEBUG_CLASSLOADER*/
313 #ifdef LOADER_DEBUG_CLASSLOADER
314 printf("CLASSLOADER: adding new classloader entry %p for %p: ", cle, cl);
315 class_print(LLNI_vftbl_direct(cl)->class);
320 /* insert entry into hashtable */
322 cle->hashlink = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
323 hashtable_classloader->ptr[slot] = cle;
325 /* update number of entries */
327 hashtable_classloader->entries++;
330 hashtable_classloader->mutex->unlock();
332 #if defined(ENABLE_HANDLES)
340 /* loader_hashtable_classloader_find *******************************************
342 Find an entry in the classloader hashtable.
344 *******************************************************************************/
346 classloader_t *loader_hashtable_classloader_find(java_handle_t *cl)
348 hashtable_classloader_entry *cle;
357 /* key for entry is the hashcode of the classloader;
358 aligned to 16-byte boundaries */
360 key = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
361 slot = key & (hashtable_classloader->size - 1);
362 cle = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
364 /* search hashchain for existing entry */
367 if (cle->object == LLNI_DIRECT(cl))
373 #ifdef LOADER_DEBUG_CLASSLOADER
375 printf("CLASSLOADER: unable to find classloader entry for %p: ", cl);
376 class_print(LLNI_vftbl_direct(cl)->class);
384 #if defined(ENABLE_HANDLES)
392 /* loader_load_all_classes *****************************************************
394 Loads all classes specified in the BOOTCLASSPATH.
396 *******************************************************************************/
398 void loader_load_all_classes(void)
400 #if defined(ENABLE_ZLIB)
402 hashtable_zipfile_entry *htzfe;
406 // Get current list of classpath entries.
407 SuckClasspath& suckclasspath = VM::get_current()->get_suckclasspath();
409 for (SuckClasspath::iterator it = suckclasspath.begin(); it != suckclasspath.end(); it++) {
410 list_classpath_entry* lce = *it;
412 #if defined(ENABLE_ZLIB)
413 if (lce->type == CLASSPATH_ARCHIVE) {
414 /* get the classes hashtable */
418 for (uint32_t slot = 0; slot < ht->size; slot++) {
419 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
421 for (; htzfe; htzfe = htzfe->hashlink) {
424 /* skip all entries in META-INF and .properties,
427 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
428 strstr(u->text, ".properties") ||
429 strstr(u->text, ".png"))
432 /* load class from bootstrap classloader */
434 if (!load_class_bootstrap(u)) {
435 fprintf(stderr, "Error loading: ");
436 utf_fprint_printable_ascii_classname(stderr, u);
437 fprintf(stderr, "\n");
440 /* print out exception and cause */
442 exceptions_print_current_exception();
450 #if defined(ENABLE_ZLIB)
457 /* loader_skip_attribute_body **************************************************
459 Skips an attribute the attribute_name_index has already been read.
462 u2 attribute_name_index;
464 u1 info[attribute_length];
467 *******************************************************************************/
469 bool loader_skip_attribute_body(classbuffer *cb)
473 if (!suck_check_classbuffer_size(cb, 4))
476 attribute_length = suck_u4(cb);
478 if (!suck_check_classbuffer_size(cb, attribute_length))
481 suck_skip_nbytes(cb, attribute_length);
487 /* load_constantpool ***********************************************************
489 Loads the constantpool of a class, the entries are transformed into
490 a simpler format by resolving references (a detailed overview of
491 the compact structures can be found in global.h).
493 *******************************************************************************/
495 /* The following structures are used to save information which cannot be
496 processed during the first pass. After the complete constantpool has
497 been traversed the references can be resolved (only in specific order). */
499 /* CONSTANT_Class entries */
500 typedef struct forward_class {
505 /* CONSTANT_String */
506 typedef struct forward_string {
511 /* CONSTANT_NameAndType */
512 typedef struct forward_nameandtype {
516 } forward_nameandtype;
518 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
519 typedef struct forward_fieldmethint {
523 u2 nameandtype_index;
524 } forward_fieldmethint;
526 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
531 DumpList<forward_class> forward_classes;
532 DumpList<forward_string> forward_strings;
533 DumpList<forward_nameandtype> forward_nameandtypes;
534 DumpList<forward_fieldmethint> forward_fieldmethints;
538 forward_nameandtype nfn;
539 forward_fieldmethint nff;
547 /* number of entries in the constant_pool table plus one */
548 if (!suck_check_classbuffer_size(cb, 2))
551 cpcount = c->cpcount = suck_u2(cb);
553 /* allocate memory */
554 cptags = c->cptags = MNEW(u1, cpcount);
555 cpinfos = c->cpinfos = MNEW(void*, cpcount);
558 exceptions_throw_classformaterror(c, "Illegal constant pool size");
562 #if defined(ENABLE_STATISTICS)
564 count_const_pool_len += (sizeof(u1) + sizeof(void*)) * cpcount;
567 /* initialize constantpool */
568 for (idx = 0; idx < cpcount; idx++) {
569 cptags[idx] = CONSTANT_UNUSED;
574 /******* first pass *******/
575 /* entries which cannot be resolved now are written into
576 temporary structures and traversed again later */
579 while (idx < cpcount) {
582 /* get constant type */
583 if (!suck_check_classbuffer_size(cb, 1))
592 /* reference to CONSTANT_NameAndType */
593 if (!suck_check_classbuffer_size(cb, 2))
596 nfc.name_index = suck_u2(cb);
598 forward_classes.push_front(nfc);
603 case CONSTANT_String:
606 /* reference to CONSTANT_Utf8_info with string characters */
607 if (!suck_check_classbuffer_size(cb, 2))
610 nfs.string_index = suck_u2(cb);
612 forward_strings.push_front(nfs);
617 case CONSTANT_NameAndType:
620 if (!suck_check_classbuffer_size(cb, 2 + 2))
623 /* reference to CONSTANT_Utf8_info containing simple name */
624 nfn.name_index = suck_u2(cb);
626 /* reference to CONSTANT_Utf8_info containing field or method
628 nfn.sig_index = suck_u2(cb);
630 forward_nameandtypes.push_front(nfn);
635 case CONSTANT_Fieldref:
636 case CONSTANT_Methodref:
637 case CONSTANT_InterfaceMethodref:
642 if (!suck_check_classbuffer_size(cb, 2 + 2))
645 /* class or interface type that contains the declaration of the
647 nff.class_index = suck_u2(cb);
649 /* name and descriptor of the field or method */
650 nff.nameandtype_index = suck_u2(cb);
652 forward_fieldmethints.push_front(nff);
657 case CONSTANT_Integer: {
658 constant_integer *ci = NEW(constant_integer);
660 #if defined(ENABLE_STATISTICS)
662 count_const_pool_len += sizeof(constant_integer);
665 if (!suck_check_classbuffer_size(cb, 4))
668 ci->value = suck_s4(cb);
669 cptags[idx] = CONSTANT_Integer;
676 case CONSTANT_Float: {
677 constant_float *cf = NEW(constant_float);
679 #if defined(ENABLE_STATISTICS)
681 count_const_pool_len += sizeof(constant_float);
684 if (!suck_check_classbuffer_size(cb, 4))
687 cf->value = suck_float(cb);
688 cptags[idx] = CONSTANT_Float;
695 case CONSTANT_Long: {
696 constant_long *cl = NEW(constant_long);
698 #if defined(ENABLE_STATISTICS)
700 count_const_pool_len += sizeof(constant_long);
703 if (!suck_check_classbuffer_size(cb, 8))
706 cl->value = suck_s8(cb);
707 cptags[idx] = CONSTANT_Long;
711 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
717 case CONSTANT_Double: {
718 constant_double *cd = NEW(constant_double);
720 #if defined(ENABLE_STATISTICS)
722 count_const_pool_len += sizeof(constant_double);
725 if (!suck_check_classbuffer_size(cb, 8))
728 cd->value = suck_double(cb);
729 cptags[idx] = CONSTANT_Double;
733 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
739 case CONSTANT_Utf8: {
742 /* number of bytes in the bytes array (not string-length) */
743 if (!suck_check_classbuffer_size(cb, 2))
746 length = suck_u2(cb);
747 cptags[idx] = CONSTANT_Utf8;
749 /* validate the string */
750 if (!suck_check_classbuffer_size(cb, length))
753 #ifdef ENABLE_VERIFIER
755 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
757 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
760 #endif /* ENABLE_VERIFIER */
761 /* insert utf-string into the utf-symboltable */
762 cpinfos[idx] = utf_new((char *) cb->pos, length);
764 /* skip bytes of the string (buffer size check above) */
765 suck_skip_nbytes(cb, length);
771 exceptions_throw_classformaterror(c, "Illegal constant pool type");
777 /* resolve entries in temporary structures */
779 for (DumpList<forward_class>::iterator it = forward_classes.begin();
780 it != forward_classes.end(); ++it) {
782 utf *name = (utf*) class_getconstant(c, it->name_index, CONSTANT_Utf8);
786 #ifdef ENABLE_VERIFIER
787 if (opt_verify && !is_valid_name_utf(name)) {
788 exceptions_throw_classformaterror(c, "Class reference with invalid name");
791 #endif /* ENABLE_VERIFIER */
793 /* add all class references to the descriptor_pool */
795 if (!descriptor_pool_add_class(descpool, name))
798 cptags[it->thisindex] = CONSTANT_Class;
800 /* the classref is created later */
801 cpinfos[it->thisindex] = name;
804 for (DumpList<forward_string>::iterator it = forward_strings.begin();
805 it != forward_strings.end(); ++it) {
807 utf *text = (utf*) class_getconstant(c, it->string_index, CONSTANT_Utf8);
812 /* resolve utf-string */
813 cptags[it->thisindex] = CONSTANT_String;
814 cpinfos[it->thisindex] = text;
817 for (DumpList<forward_nameandtype>::iterator it = forward_nameandtypes.begin();
818 it != forward_nameandtypes.end(); ++it) {
820 constant_nameandtype *cn = NEW(constant_nameandtype);
822 #if defined(ENABLE_STATISTICS)
824 count_const_pool_len += sizeof(constant_nameandtype);
827 /* resolve simple name and descriptor */
828 cn->name = (utf*) class_getconstant(c,
834 cn->descriptor = (utf*) class_getconstant(c,
840 #ifdef ENABLE_VERIFIER
843 if (!is_valid_name_utf(cn->name)) {
844 exceptions_throw_classformaterror(c,
845 "Illegal Field name \"%s\"",
851 /* disallow referencing <clinit> among others */
852 if (cn->name->text[0] == '<' && cn->name != utf_init) {
853 exceptions_throw_classformaterror(c, "Illegal reference to special method");
857 #endif /* ENABLE_VERIFIER */
859 cptags[it->thisindex] = CONSTANT_NameAndType;
860 cpinfos[it->thisindex] = cn;
863 for (DumpList<forward_fieldmethint>::iterator it = forward_fieldmethints.begin();
864 it != forward_fieldmethints.end(); ++it) {
866 constant_nameandtype *nat;
867 constant_FMIref *fmi = NEW(constant_FMIref);
869 #if defined(ENABLE_STATISTICS)
871 count_const_pool_len += sizeof(constant_FMIref);
873 /* resolve simple name and descriptor */
875 nat = (constant_nameandtype*) class_getconstant(c,
876 it->nameandtype_index,
877 CONSTANT_NameAndType);
882 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
884 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
887 /* the classref is created later */
889 fmi->p.index = it->class_index;
890 fmi->name = nat->name;
891 fmi->descriptor = nat->descriptor;
893 cptags[it->thisindex] = it->tag;
894 cpinfos[it->thisindex] = fmi;
897 /* everything was ok */
903 /* loader_load_attribute_signature *********************************************
905 Signature_attribute {
906 u2 attribute_name_index;
911 *******************************************************************************/
913 #if defined(ENABLE_JAVASE)
914 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
924 /* check remaining bytecode */
926 if (!suck_check_classbuffer_size(cb, 4 + 2))
929 /* check attribute length */
931 attribute_length = suck_u4(cb);
933 if (attribute_length != 2) {
934 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
938 if (*signature != NULL) {
939 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
945 signature_index = suck_u2(cb);
947 *signature = (utf*) class_getconstant(c, signature_index, CONSTANT_Utf8);
949 if (*signature == NULL)
954 #endif /* defined(ENABLE_JAVASE) */
957 /* load_class_from_sysloader ***************************************************
959 Load the class with the given name using the system class loader
962 name.............the classname
966 NULL if an exception has been thrown
968 *******************************************************************************/
970 #if defined(ENABLE_JAVASE)
971 classinfo *load_class_from_sysloader(utf *name)
976 cl = java_lang_ClassLoader::invoke_getSystemClassLoader();
981 c = load_class_from_classloader(name, cl);
985 #endif /* defined(ENABLE_JAVASE) */
988 /* load_class_from_classloader *************************************************
990 Load the class with the given name using the given user-defined class loader.
993 name.............the classname
994 cl...............user-defined class loader
998 NULL if an exception has been thrown
1000 *******************************************************************************/
1002 classinfo *load_class_from_classloader(utf *name, classloader_t *cl)
1007 java_handle_t *string;
1008 #if defined(ENABLE_RT_TIMING)
1009 struct timespec time_start, time_lookup, time_prepare, time_java,
1013 RT_TIMING_GET_TIME(time_start);
1017 /* lookup if this class has already been loaded */
1019 c = classcache_lookup(cl, name);
1021 RT_TIMING_GET_TIME(time_lookup);
1022 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1027 /* if other class loader than bootstrap, call it */
1035 namelen = name->blength;
1037 /* handle array classes */
1038 if (text[0] == '[') {
1044 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1045 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1046 exceptions_throw_classnotfoundexception(name);
1050 u = utf_new(text + 2, namelen - 3);
1052 if (!(comp = load_class_from_classloader(u, cl)))
1055 /* create the array class */
1057 c = class_array_of(comp, false);
1059 tmpc = classcache_store(cl, c, true);
1062 /* exception, free the loaded class */
1063 c->state &= ~CLASS_LOADING;
1070 /* load the component class */
1072 u = utf_new(text + 1, namelen - 1);
1074 if (!(comp = load_class_from_classloader(u, cl)))
1077 /* create the array class */
1079 c = class_array_of(comp, false);
1081 tmpc = classcache_store(cl, c, true);
1084 /* exception, free the loaded class */
1085 c->state &= ~CLASS_LOADING;
1092 /* primitive array classes are loaded by the bootstrap loader */
1094 c = load_class_bootstrap(name);
1100 LLNI_class_get(cl, c);
1102 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1103 /* OpenJDK uses this internal function because it's
1106 lc = class_resolveclassmethod(c,
1107 utf_loadClassInternal,
1108 utf_java_lang_String__java_lang_Class,
1112 lc = class_resolveclassmethod(c,
1114 utf_java_lang_String__java_lang_Class,
1120 return false; /* exception */
1122 /* move return value into `o' and cast it afterwards to a classinfo* */
1124 string = javastring_new_slash_to_dot(name);
1126 RT_TIMING_GET_TIME(time_prepare);
1128 o = vm_call_method(lc, (java_handle_t *) cl, string);
1130 RT_TIMING_GET_TIME(time_java);
1132 c = LLNI_classinfo_unwrap(o);
1135 /* Store this class in the loaded class cache. If another
1136 class with the same (initloader,name) pair has been
1137 stored earlier it will be returned by classcache_store
1138 In this case classcache_store may not free the class
1139 because it has already been exposed to Java code which
1140 may have kept references to that class. */
1142 tmpc = classcache_store(cl, c, false);
1145 /* exception, free the loaded class */
1146 c->state &= ~CLASS_LOADING;
1153 // Expected behavior for the classloader is to throw an exception
1154 // and never return NULL. If the classloader shows a different
1155 // behavior, we are correcting it here (see PR126).
1156 if (exceptions_get_exception() == NULL) {
1157 #if !defined(NDEBUG)
1158 if (opt_PrintWarnings)
1159 log_message_utf("load_class_from_classloader: Correcting faulty classloader behavior (PR126) for ", name);
1161 exceptions_throw_classnotfoundexception(name);
1165 RT_TIMING_GET_TIME(time_cache);
1167 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1168 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1169 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1171 /* SUN compatible -verbose:class output */
1173 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1175 utf_display_printable_ascii_classname(name);
1182 c = load_class_bootstrap(name);
1188 /* load_class_bootstrap ********************************************************
1190 Load the class with the given name using the bootstrap class loader.
1193 name.............the classname
1196 loaded classinfo, or
1197 NULL if an exception has been thrown
1200 load_class_bootstrap is synchronized. It can be treated as an
1203 *******************************************************************************/
1205 classinfo *load_class_bootstrap(utf *name)
1210 #if defined(ENABLE_RT_TIMING)
1211 struct timespec time_start, time_lookup, time_array, time_suck,
1212 time_load, time_cache;
1215 RT_TIMING_GET_TIME(time_start);
1221 /* lookup if this class has already been loaded */
1223 r = classcache_lookup(NULL, name);
1226 RT_TIMING_GET_TIME(time_lookup);
1227 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1232 RT_TIMING_GET_TIME(time_lookup);
1233 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1235 /* create the classinfo */
1237 c = class_create_classinfo(name);
1239 /* handle array classes */
1241 if (name->text[0] == '[') {
1242 c = load_newly_created_array(c, NULL);
1247 assert(c->state & CLASS_LOADED);
1249 RT_TIMING_GET_TIME(time_array);
1250 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1255 #if defined(ENABLE_STATISTICS)
1258 if (opt_getcompilingtime)
1259 compilingtime_stop();
1261 if (opt_getloadingtime)
1262 loadingtime_start();
1265 /* load classdata, throw exception on error */
1270 exceptions_throw_classnotfoundexception(name);
1274 RT_TIMING_GET_TIME(time_suck);
1276 /* load the class from the buffer */
1278 r = load_class_from_classbuffer(cb);
1280 RT_TIMING_GET_TIME(time_load);
1283 /* the class could not be loaded, free the classinfo struct */
1288 /* Store this class in the loaded class cache this step also
1289 checks the loading constraints. If the class has been
1290 loaded before, the earlier loaded class is returned. */
1292 classinfo *res = classcache_store(NULL, c, true);
1299 // Add the package name to the boot packages.
1300 Package::add(c->packagename);
1306 RT_TIMING_GET_TIME(time_cache);
1308 /* SUN compatible -verbose:class output */
1310 if (opt_verboseclass && r) {
1312 utf_display_printable_ascii_classname(name);
1313 printf(" from %s]\n", cb->path);
1320 #if defined(ENABLE_STATISTICS)
1323 if (opt_getloadingtime)
1326 if (opt_getcompilingtime)
1327 compilingtime_start();
1330 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1331 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1332 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1333 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1339 /* load_class_from_classbuffer_intern ******************************************
1341 Loads a class from a classbuffer into a given classinfo structure.
1342 Super-classes are also loaded at this point and some verfication
1346 This function is NOT synchronized!
1348 *******************************************************************************/
1350 static bool load_class_from_classbuffer_intern(classbuffer *cb)
1356 utf **interfacesnames;
1358 constant_classref *cr;
1362 descriptor_pool *descpool;
1363 #if defined(ENABLE_STATISTICS)
1367 #if defined(ENABLE_RT_TIMING)
1368 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1369 time_setup, time_fields, time_methods, time_classrefs,
1370 time_descs, time_setrefs, time_parsefds, time_parsemds,
1371 time_parsecpool, time_verify, time_attrs;
1374 // Create new dump memory area.
1377 RT_TIMING_GET_TIME(time_start);
1379 /* Get the classbuffer's class. */
1383 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1386 /* check signature */
1388 if (suck_u4(cb) != MAGIC) {
1389 exceptions_throw_classformaterror(c, "Bad magic number");
1398 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1399 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1403 RT_TIMING_GET_TIME(time_checks);
1405 /* create a new descriptor pool */
1407 descpool = descriptor_pool_new(c);
1409 RT_TIMING_GET_TIME(time_ndpool);
1411 /* load the constant pool */
1413 if (!load_constantpool(cb, descpool))
1416 RT_TIMING_GET_TIME(time_cpool);
1420 if (!suck_check_classbuffer_size(cb, 2))
1423 /* We OR the flags here, as we set already some flags in
1424 class_create_classinfo. */
1426 c->flags |= suck_u2(cb);
1428 /* check ACC flags consistency */
1430 if (c->flags & ACC_INTERFACE) {
1431 if (!(c->flags & ACC_ABSTRACT)) {
1432 /* We work around this because interfaces in JDK 1.1 are
1433 * not declared abstract. */
1435 c->flags |= ACC_ABSTRACT;
1438 if (c->flags & ACC_FINAL) {
1439 exceptions_throw_classformaterror(c,
1440 "Illegal class modifiers: 0x%X",
1445 if (c->flags & ACC_SUPER) {
1446 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1450 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1451 exceptions_throw_classformaterror(c,
1452 "Illegal class modifiers: 0x%X",
1457 if (!suck_check_classbuffer_size(cb, 2 + 2))
1462 index = suck_u2(cb);
1464 name = (utf *) class_getconstant(c, index, CONSTANT_Class);
1469 if (c->name == utf_not_named_yet) {
1470 /* we finally have a name for this class */
1472 class_set_packagename(c);
1474 else if (name != c->name) {
1475 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
1479 /* Retrieve superclass. */
1483 index = suck_u2(cb);
1488 /* This is only allowed for java.lang.Object. */
1490 if (c->name != utf_java_lang_Object) {
1491 exceptions_throw_classformaterror(c, "Bad superclass index");
1496 supername = (utf *) class_getconstant(c, index, CONSTANT_Class);
1498 if (supername == NULL)
1501 /* java.lang.Object may not have a super class. */
1503 if (c->name == utf_java_lang_Object) {
1504 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
1508 /* Detect circularity. */
1510 if (supername == c->name) {
1511 exceptions_throw_classcircularityerror(c);
1515 /* Interfaces must have java.lang.Object as super class. */
1517 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
1518 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
1523 /* Parse the super interfaces. */
1525 if (!suck_check_classbuffer_size(cb, 2))
1528 c->interfacescount = suck_u2(cb);
1530 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1533 c->interfaces = MNEW(classinfo*, c->interfacescount);
1535 /* Get the names of the super interfaces. */
1537 interfacesnames = (utf**) DumpMemory::allocate(sizeof(utf*) * c->interfacescount);
1539 for (int32_t i = 0; i < c->interfacescount; i++) {
1540 index = suck_u2(cb);
1542 u = (utf *) class_getconstant(c, index, CONSTANT_Class);
1547 interfacesnames[i] = u;
1550 RT_TIMING_GET_TIME(time_setup);
1554 if (!suck_check_classbuffer_size(cb, 2))
1557 c->fieldscount = suck_u2(cb);
1558 c->fields = MNEW(fieldinfo, c->fieldscount);
1560 MZERO(c->fields, fieldinfo, c->fieldscount);
1562 for (int32_t i = 0; i < c->fieldscount; i++) {
1563 if (!field_load(cb, &(c->fields[i]), descpool))
1567 RT_TIMING_GET_TIME(time_fields);
1569 /* Parse methods. */
1571 if (!suck_check_classbuffer_size(cb, 2))
1574 c->methodscount = suck_u2(cb);
1575 c->methods = MNEW(methodinfo, c->methodscount);
1577 MZERO(c->methods, methodinfo, c->methodscount);
1579 for (int32_t i = 0; i < c->methodscount; i++) {
1580 if (!method_load(cb, &(c->methods[i]), descpool))
1584 RT_TIMING_GET_TIME(time_methods);
1586 /* create the class reference table */
1589 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
1591 RT_TIMING_GET_TIME(time_classrefs);
1593 /* allocate space for the parsed descriptors */
1595 descriptor_pool_alloc_parsed_descriptors(descpool);
1597 #if defined(ENABLE_STATISTICS)
1599 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
1600 count_classref_len += classrefsize;
1601 count_parsed_desc_len += descsize;
1605 RT_TIMING_GET_TIME(time_descs);
1607 /* put the classrefs in the constant pool */
1609 for (int32_t i = 0; i < c->cpcount; i++) {
1610 if (c->cptags[i] == CONSTANT_Class) {
1611 utf *name = (utf *) c->cpinfos[i];
1612 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
1616 /* Resolve the super class. */
1618 if (supername != NULL) {
1619 cr = descriptor_pool_lookup_classref(descpool, supername);
1624 /* XXX This should be done better. */
1625 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1628 resolve_handle_pending_exception(true);
1632 /* Interfaces are not allowed as super classes. */
1634 if (tc->flags & ACC_INTERFACE) {
1635 exceptions_throw_incompatibleclasschangeerror(c, "class %s has interface %s as super class");
1639 /* Don't allow extending final classes */
1641 if (tc->flags & ACC_FINAL) {
1642 exceptions_throw_verifyerror(NULL,
1643 "Cannot inherit from final class");
1647 /* Store the super class. */
1652 /* Resolve the super interfaces. */
1654 for (int32_t i = 0; i < c->interfacescount; i++) {
1655 u = interfacesnames[i];
1656 cr = descriptor_pool_lookup_classref(descpool, u);
1661 /* XXX This should be done better. */
1662 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1665 resolve_handle_pending_exception(true);
1669 /* Detect circularity. */
1672 exceptions_throw_classcircularityerror(c);
1676 if (!(tc->flags & ACC_INTERFACE)) {
1677 exceptions_throw_incompatibleclasschangeerror(tc,
1678 "Implementing class");
1682 /* Store the super interface. */
1684 c->interfaces[i] = tc;
1687 RT_TIMING_GET_TIME(time_setrefs);
1689 /* Parse the field descriptors. */
1691 for (int32_t i = 0; i < c->fieldscount; i++) {
1692 c->fields[i].parseddesc =
1693 descriptor_pool_parse_field_descriptor(descpool,
1694 c->fields[i].descriptor);
1695 if (!c->fields[i].parseddesc)
1699 RT_TIMING_GET_TIME(time_parsefds);
1701 /* parse method descriptors */
1703 for (int32_t i = 0; i < c->methodscount; i++) {
1704 methodinfo *m = &c->methods[i];
1706 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
1707 m->flags, class_get_self_classref(m->clazz));
1711 for (int32_t j = 0; j < m->rawexceptiontablelength; j++) {
1712 if (!m->rawexceptiontable[j].catchtype.any)
1715 if ((m->rawexceptiontable[j].catchtype.ref =
1716 descriptor_pool_lookup_classref(descpool,
1717 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
1721 for (int32_t j = 0; j < m->thrownexceptionscount; j++) {
1722 if (!m->thrownexceptions[j].any)
1725 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
1726 (utf *) m->thrownexceptions[j].any)) == NULL)
1731 RT_TIMING_GET_TIME(time_parsemds);
1733 /* parse the loaded descriptors */
1735 for (int32_t i = 0; i < c->cpcount; i++) {
1736 constant_FMIref *fmi;
1739 switch (c->cptags[i]) {
1740 case CONSTANT_Fieldref:
1741 fmi = (constant_FMIref *) c->cpinfos[i];
1742 fmi->parseddesc.fd =
1743 descriptor_pool_parse_field_descriptor(descpool,
1745 if (!fmi->parseddesc.fd)
1748 index = fmi->p.index;
1750 (constant_classref *) class_getconstant(c, index,
1752 if (!fmi->p.classref)
1755 case CONSTANT_Methodref:
1756 case CONSTANT_InterfaceMethodref:
1757 fmi = (constant_FMIref *) c->cpinfos[i];
1758 index = fmi->p.index;
1760 (constant_classref *) class_getconstant(c, index,
1762 if (!fmi->p.classref)
1764 fmi->parseddesc.md =
1765 descriptor_pool_parse_method_descriptor(descpool,
1769 if (!fmi->parseddesc.md)
1775 RT_TIMING_GET_TIME(time_parsecpool);
1777 #ifdef ENABLE_VERIFIER
1778 /* Check if all fields and methods can be uniquely
1779 * identified by (name,descriptor). */
1782 /* We use a hash table here to avoid making the
1783 * average case quadratic in # of methods, fields.
1785 static int shift = 0;
1787 u2 *next; /* for chaining colliding hash entries */
1793 /* Allocate hashtable */
1794 len = c->methodscount;
1795 if (len < c->fieldscount) len = c->fieldscount;
1797 hashtab = MNEW(u2,(hashlen + len));
1798 next = hashtab + hashlen;
1800 /* Determine bitshift (to get good hash values) */
1810 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
1812 for (int32_t i = 0; i < c->fieldscount; ++i) {
1813 fieldinfo *fi = c->fields + i;
1815 /* It's ok if we lose bits here */
1816 index = ((((size_t) fi->name) +
1817 ((size_t) fi->descriptor)) >> shift) % hashlen;
1819 if ((old = hashtab[index])) {
1823 if (c->fields[old].name == fi->name &&
1824 c->fields[old].descriptor == fi->descriptor) {
1825 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
1828 } while ((old = next[old]));
1830 hashtab[index] = i + 1;
1834 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
1836 for (int32_t i = 0; i < c->methodscount; ++i) {
1837 methodinfo *mi = c->methods + i;
1839 /* It's ok if we lose bits here */
1840 index = ((((size_t) mi->name) +
1841 ((size_t) mi->descriptor)) >> shift) % hashlen;
1843 if ((old = hashtab[index])) {
1847 if (c->methods[old].name == mi->name &&
1848 c->methods[old].descriptor == mi->descriptor) {
1849 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
1852 } while ((old = next[old]));
1854 hashtab[index] = i + 1;
1857 MFREE(hashtab, u2, (hashlen + len));
1859 #endif /* ENABLE_VERIFIER */
1861 RT_TIMING_GET_TIME(time_verify);
1863 #if defined(ENABLE_STATISTICS)
1865 size_classinfo += sizeof(classinfo*) * c->interfacescount;
1866 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
1867 size_methodinfo += sizeof(methodinfo) * c->methodscount;
1871 /* load attribute structures */
1873 if (!class_load_attributes(cb))
1876 /* Pre Java 1.5 version don't check this. This implementation is
1877 like Java 1.5 do it: for class file version 45.3 we don't check
1878 it, older versions are checked. */
1880 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
1881 /* check if all data has been read */
1882 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
1884 if (classdata_left > 0) {
1885 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
1890 RT_TIMING_GET_TIME(time_attrs);
1892 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
1893 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
1894 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
1895 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
1896 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
1897 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
1898 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
1899 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
1900 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
1901 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
1902 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
1903 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
1904 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
1905 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
1906 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
1912 /* load_class_from_classbuffer *************************************************
1914 Convenience wrapper for load_class_from_classbuffer.
1917 This function is NOT synchronized!
1919 *******************************************************************************/
1921 classinfo *load_class_from_classbuffer(classbuffer *cb)
1926 /* Get the classbuffer's class. */
1930 /* Check if the class is already loaded. */
1932 if (c->state & CLASS_LOADED)
1935 #if defined(ENABLE_STATISTICS)
1937 count_class_loads++;
1940 #if !defined(NDEBUG)
1942 log_message_class("Loading class: ", c);
1945 /* Class is currently loading. */
1947 c->state |= CLASS_LOADING;
1949 /* Parse the classbuffer. */
1951 result = load_class_from_classbuffer_intern(cb);
1953 /* An error occurred. */
1955 if (result == false) {
1956 /* Revert loading state. */
1958 c->state = (c->state & ~CLASS_LOADING);
1963 /* Revert loading state and set loaded. */
1965 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
1967 #if !defined(NDEBUG)
1969 log_message_class("Loading done class: ", c);
1972 // Hook point just after a class was loaded.
1973 Hook::class_loaded(c);
1979 /* load_newly_created_array ****************************************************
1981 Load a newly created array class.
1984 c....................the array class C has been loaded
1985 other classinfo......the array class was found in the class cache,
1987 NULL.................an exception has been thrown
1990 This is an internal function. Do not use it unless you know exactly
1993 Use one of the load_class_... functions for general array class loading.
1995 *******************************************************************************/
1997 classinfo *load_newly_created_array(classinfo *c, classloader_t *loader)
1999 classinfo *comp = NULL;
2001 methoddesc *clonedesc;
2002 constant_classref *classrefs;
2007 text = c->name->text;
2008 namelen = c->name->blength;
2010 /* Check array class name */
2012 if ((namelen < 2) || (text[0] != '[')) {
2013 exceptions_throw_classnotfoundexception(c->name);
2017 /* Check the element type */
2021 /* c is an array of arrays. We have to create the component class. */
2023 u = utf_new(text + 1, namelen - 1);
2025 comp = load_class_from_classloader(u, loader);
2030 assert(comp->state & CLASS_LOADED);
2032 /* the array's flags are that of the component class */
2033 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2034 c->classloader = comp->classloader;
2038 /* c is an array of objects. */
2040 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2041 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2042 exceptions_throw_classnotfoundexception(c->name);
2046 u = utf_new(text + 2, namelen - 3);
2048 if (!(comp = load_class_from_classloader(u, loader)))
2051 assert(comp->state & CLASS_LOADED);
2053 /* the array's flags are that of the component class */
2054 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2055 c->classloader = comp->classloader;
2059 /* c is an array of a primitive type */
2061 /* check for cases like `[II' and whether the character is a
2062 valid primitive type */
2064 if ((namelen > 2) || (Primitive::get_class_by_char(text[1]) == NULL)) {
2065 exceptions_throw_classnotfoundexception(c->name);
2069 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2070 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2071 c->classloader = NULL;
2074 assert(class_java_lang_Object);
2075 #if defined(ENABLE_JAVASE)
2076 assert(class_java_lang_Cloneable);
2077 assert(class_java_io_Serializable);
2080 /* Setup the array class. */
2082 c->super = class_java_lang_Object;
2084 #if defined(ENABLE_JAVASE)
2086 c->interfacescount = 2;
2087 c->interfaces = MNEW(classinfo*, 2);
2088 c->interfaces[0] = class_java_lang_Cloneable;
2089 c->interfaces[1] = class_java_io_Serializable;
2091 #elif defined(ENABLE_JAVAME_CLDC1_1)
2093 c->interfacescount = 0;
2094 c->interfaces = NULL;
2097 # error unknow Java configuration
2100 c->methodscount = 1;
2101 c->methods = MNEW(methodinfo, c->methodscount);
2103 MZERO(c->methods, methodinfo, c->methodscount);
2105 classrefs = MNEW(constant_classref, 2);
2107 CLASSREF_INIT(classrefs[0], c, c->name);
2108 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2110 /* create descriptor for clone method */
2111 /* we need one paramslot which is reserved for the 'this' parameter */
2112 clonedesc = NEW(methoddesc);
2113 clonedesc->returntype.type = TYPE_ADR;
2114 clonedesc->returntype.classref = classrefs + 1;
2115 clonedesc->returntype.arraydim = 0;
2116 /* initialize params to "empty", add real params below in
2117 descriptor_params_from_paramtypes */
2118 clonedesc->paramcount = 0;
2119 clonedesc->paramslots = 0;
2120 clonedesc->paramtypes[0].classref = classrefs + 0;
2121 clonedesc->params = NULL;
2123 /* create methodinfo */
2126 MSET(clone, 0, methodinfo, 1);
2128 /* ATTENTION: if you delete the ACC_NATIVE below, set
2129 clone->maxlocals=1 (interpreter related) */
2131 clone->mutex = new Mutex();
2132 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2133 clone->name = utf_clone;
2134 clone->descriptor = utf_void__java_lang_Object;
2135 clone->parseddesc = clonedesc;
2138 /* parse the descriptor to get the register allocation */
2140 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->classrefs = classrefs;
2150 c->classrefcount = 1;
2152 /* insert class into the loaded class cache */
2153 /* XXX free classinfo if NULL returned? */
2155 return classcache_store(loader, c, true);
2159 /* loader_close ****************************************************************
2161 Frees all resources.
2163 *******************************************************************************/
2165 void loader_close(void)
2172 * These are local overrides for various environment variables in Emacs.
2173 * Please do not remove this and leave it at the end of the file, where
2174 * Emacs will automagically detect them.
2175 * ---------------------------------------------------------------------
2178 * indent-tabs-mode: t
2182 * vim:noexpandtab:sw=4:ts=4: