1 /* src/vm/loader.cpp - class loader functions
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
34 #include "mm/dumpmemory.hpp"
35 #include "mm/memory.h"
37 #include "native/llni.h"
39 #include "threads/mutex.hpp"
41 #include "toolbox/hashtable.h"
42 #include "toolbox/logging.h"
44 #include "vm/jit/builtin.hpp"
45 #include "vm/classcache.h"
46 #include "vm/exceptions.hpp"
47 #include "vm/field.hpp"
48 #include "vm/global.h"
49 #include "vm/globals.hpp"
50 #include "vm/linker.h"
51 #include "vm/loader.hpp"
52 #include "vm/method.h"
53 #include "vm/options.h"
54 #include "vm/package.hpp"
55 #include "vm/primitive.hpp"
56 #include "vm/resolve.h"
57 #include "vm/rt-timing.h"
58 #include "vm/string.hpp"
63 #if defined(ENABLE_JAVASE)
64 # include "vm/annotation.h"
65 # include "vm/stackmap.h"
68 #if defined(ENABLE_STATISTICS)
69 # include "vm/statistics.h"
72 #if defined(ENABLE_ZLIB)
76 #include "vm/jit/stubs.hpp"
78 #if defined(ENABLE_JVMTI)
79 # include "native/jvmti/cacaodbg.h"
83 /* global variables ***********************************************************/
85 static hashtable *hashtable_classloader;
88 /* loader_preinit **************************************************************
90 Initializes the classpath list and loads classes required for the
93 NOTE: Exceptions thrown during VM initialization are caught in the
94 exception functions themselves.
96 *******************************************************************************/
98 void loader_preinit(void)
100 #if defined(ENABLE_THREADS)
101 list_classpath_entry *lce;
104 TRACESUBSYSTEMINITIALIZATION("loader_preinit");
106 #if defined(ENABLE_THREADS)
107 /* Initialize the monitor pointer for zip/jar file locking. */
109 for (lce = (list_classpath_entry*) list_first(list_classpath_entries); lce != NULL;
110 lce = (list_classpath_entry*) list_next(list_classpath_entries, lce)) {
111 if (lce->type == CLASSPATH_ARCHIVE)
112 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 list_classpath_entry *lce;
399 #if defined(ENABLE_ZLIB)
401 hashtable_zipfile_entry *htzfe;
405 for (lce = (list_classpath_entry*) list_first(list_classpath_entries); lce != NULL;
406 lce = (list_classpath_entry*) list_next(list_classpath_entries, lce)) {
407 #if defined(ENABLE_ZLIB)
408 if (lce->type == CLASSPATH_ARCHIVE) {
409 /* get the classes hashtable */
413 for (uint32_t slot = 0; slot < ht->size; slot++) {
414 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
416 for (; htzfe; htzfe = htzfe->hashlink) {
419 /* skip all entries in META-INF and .properties,
422 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
423 strstr(u->text, ".properties") ||
424 strstr(u->text, ".png"))
427 /* load class from bootstrap classloader */
429 if (!load_class_bootstrap(u)) {
430 fprintf(stderr, "Error loading: ");
431 utf_fprint_printable_ascii_classname(stderr, u);
432 fprintf(stderr, "\n");
435 /* print out exception and cause */
437 exceptions_print_current_exception();
445 #if defined(ENABLE_ZLIB)
452 /* loader_skip_attribute_body **************************************************
454 Skips an attribute the attribute_name_index has already been read.
457 u2 attribute_name_index;
459 u1 info[attribute_length];
462 *******************************************************************************/
464 bool loader_skip_attribute_body(classbuffer *cb)
468 if (!suck_check_classbuffer_size(cb, 4))
471 attribute_length = suck_u4(cb);
473 if (!suck_check_classbuffer_size(cb, attribute_length))
476 suck_skip_nbytes(cb, attribute_length);
482 /* load_constantpool ***********************************************************
484 Loads the constantpool of a class, the entries are transformed into
485 a simpler format by resolving references (a detailed overview of
486 the compact structures can be found in global.h).
488 *******************************************************************************/
490 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
493 /* The following structures are used to save information which cannot be
494 processed during the first pass. After the complete constantpool has
495 been traversed the references can be resolved.
496 (only in specific order) */
498 /* CONSTANT_Class entries */
499 typedef struct forward_class {
500 struct forward_class *next;
505 /* CONSTANT_String */
506 typedef struct forward_string {
507 struct forward_string *next;
512 /* CONSTANT_NameAndType */
513 typedef struct forward_nameandtype {
514 struct forward_nameandtype *next;
518 } forward_nameandtype;
520 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
521 typedef struct forward_fieldmethint {
522 struct forward_fieldmethint *next;
526 u2 nameandtype_index;
527 } forward_fieldmethint;
533 forward_class *forward_classes = NULL;
534 forward_string *forward_strings = NULL;
535 forward_nameandtype *forward_nameandtypes = NULL;
536 forward_fieldmethint *forward_fieldmethints = NULL;
540 forward_nameandtype *nfn;
541 forward_fieldmethint *nff;
549 /* number of entries in the constant_pool table plus one */
550 if (!suck_check_classbuffer_size(cb, 2))
553 cpcount = c->cpcount = suck_u2(cb);
555 /* allocate memory */
556 cptags = c->cptags = MNEW(u1, cpcount);
557 cpinfos = c->cpinfos = MNEW(void*, cpcount);
560 exceptions_throw_classformaterror(c, "Illegal constant pool size");
564 #if defined(ENABLE_STATISTICS)
566 count_const_pool_len += (sizeof(u1) + sizeof(void*)) * cpcount;
569 /* initialize constantpool */
570 for (idx = 0; idx < cpcount; idx++) {
571 cptags[idx] = CONSTANT_UNUSED;
576 /******* first pass *******/
577 /* entries which cannot be resolved now are written into
578 temporary structures and traversed again later */
581 while (idx < cpcount) {
584 /* get constant type */
585 if (!suck_check_classbuffer_size(cb, 1))
593 nfc = (forward_class*) DumpMemory::allocate(sizeof(forward_class));
595 nfc->next = forward_classes;
596 forward_classes = nfc;
598 nfc->thisindex = idx;
599 /* reference to CONSTANT_NameAndType */
600 if (!suck_check_classbuffer_size(cb, 2))
603 nfc->name_index = suck_u2(cb);
608 case CONSTANT_String:
610 nfs = (forward_string*) DumpMemory::allocate(sizeof(forward_string));
612 nfs->next = forward_strings;
613 forward_strings = nfs;
615 nfs->thisindex = idx;
617 /* reference to CONSTANT_Utf8_info with string characters */
618 if (!suck_check_classbuffer_size(cb, 2))
621 nfs->string_index = suck_u2(cb);
626 case CONSTANT_NameAndType:
628 nfn = (forward_nameandtype*) DumpMemory::allocate(sizeof(forward_nameandtype));
630 nfn->next = forward_nameandtypes;
631 forward_nameandtypes = nfn;
633 nfn->thisindex = idx;
635 if (!suck_check_classbuffer_size(cb, 2 + 2))
638 /* reference to CONSTANT_Utf8_info containing simple name */
639 nfn->name_index = suck_u2(cb);
641 /* reference to CONSTANT_Utf8_info containing field or method
643 nfn->sig_index = suck_u2(cb);
648 case CONSTANT_Fieldref:
649 case CONSTANT_Methodref:
650 case CONSTANT_InterfaceMethodref:
652 nff = (forward_fieldmethint*) DumpMemory::allocate(sizeof(forward_fieldmethint));
654 nff->next = forward_fieldmethints;
655 forward_fieldmethints = nff;
657 nff->thisindex = idx;
661 if (!suck_check_classbuffer_size(cb, 2 + 2))
664 /* class or interface type that contains the declaration of the
666 nff->class_index = suck_u2(cb);
668 /* name and descriptor of the field or method */
669 nff->nameandtype_index = suck_u2(cb);
674 case CONSTANT_Integer: {
675 constant_integer *ci = NEW(constant_integer);
677 #if defined(ENABLE_STATISTICS)
679 count_const_pool_len += sizeof(constant_integer);
682 if (!suck_check_classbuffer_size(cb, 4))
685 ci->value = suck_s4(cb);
686 cptags[idx] = CONSTANT_Integer;
693 case CONSTANT_Float: {
694 constant_float *cf = NEW(constant_float);
696 #if defined(ENABLE_STATISTICS)
698 count_const_pool_len += sizeof(constant_float);
701 if (!suck_check_classbuffer_size(cb, 4))
704 cf->value = suck_float(cb);
705 cptags[idx] = CONSTANT_Float;
712 case CONSTANT_Long: {
713 constant_long *cl = NEW(constant_long);
715 #if defined(ENABLE_STATISTICS)
717 count_const_pool_len += sizeof(constant_long);
720 if (!suck_check_classbuffer_size(cb, 8))
723 cl->value = suck_s8(cb);
724 cptags[idx] = CONSTANT_Long;
728 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
734 case CONSTANT_Double: {
735 constant_double *cd = NEW(constant_double);
737 #if defined(ENABLE_STATISTICS)
739 count_const_pool_len += sizeof(constant_double);
742 if (!suck_check_classbuffer_size(cb, 8))
745 cd->value = suck_double(cb);
746 cptags[idx] = CONSTANT_Double;
750 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
756 case CONSTANT_Utf8: {
759 /* number of bytes in the bytes array (not string-length) */
760 if (!suck_check_classbuffer_size(cb, 2))
763 length = suck_u2(cb);
764 cptags[idx] = CONSTANT_Utf8;
766 /* validate the string */
767 if (!suck_check_classbuffer_size(cb, length))
770 #ifdef ENABLE_VERIFIER
772 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
774 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
777 #endif /* ENABLE_VERIFIER */
778 /* insert utf-string into the utf-symboltable */
779 cpinfos[idx] = utf_new((char *) cb->pos, length);
781 /* skip bytes of the string (buffer size check above) */
782 suck_skip_nbytes(cb, length);
788 exceptions_throw_classformaterror(c, "Illegal constant pool type");
794 /* resolve entries in temporary structures */
796 while (forward_classes) {
797 utf *name = (utf*) class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
801 #ifdef ENABLE_VERIFIER
802 if (opt_verify && !is_valid_name_utf(name)) {
803 exceptions_throw_classformaterror(c, "Class reference with invalid name");
806 #endif /* ENABLE_VERIFIER */
808 /* add all class references to the descriptor_pool */
810 if (!descriptor_pool_add_class(descpool, name))
813 cptags[forward_classes->thisindex] = CONSTANT_Class;
815 /* the classref is created later */
816 cpinfos[forward_classes->thisindex] = name;
818 nfc = forward_classes;
819 forward_classes = forward_classes->next;
822 while (forward_strings) {
823 utf *text = (utf*) class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
828 /* resolve utf-string */
829 cptags[forward_strings->thisindex] = CONSTANT_String;
830 cpinfos[forward_strings->thisindex] = text;
832 nfs = forward_strings;
833 forward_strings = forward_strings->next;
836 while (forward_nameandtypes) {
837 constant_nameandtype *cn = NEW(constant_nameandtype);
839 #if defined(ENABLE_STATISTICS)
841 count_const_pool_len += sizeof(constant_nameandtype);
844 /* resolve simple name and descriptor */
845 cn->name = (utf*) class_getconstant(c,
846 forward_nameandtypes->name_index,
851 cn->descriptor = (utf*) class_getconstant(c,
852 forward_nameandtypes->sig_index,
857 #ifdef ENABLE_VERIFIER
860 if (!is_valid_name_utf(cn->name)) {
861 exceptions_throw_classformaterror(c,
862 "Illegal Field name \"%s\"",
868 /* disallow referencing <clinit> among others */
869 if (cn->name->text[0] == '<' && cn->name != utf_init) {
870 exceptions_throw_classformaterror(c, "Illegal reference to special method");
874 #endif /* ENABLE_VERIFIER */
876 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
877 cpinfos[forward_nameandtypes->thisindex] = cn;
879 nfn = forward_nameandtypes;
880 forward_nameandtypes = forward_nameandtypes->next;
883 while (forward_fieldmethints) {
884 constant_nameandtype *nat;
885 constant_FMIref *fmi = NEW(constant_FMIref);
887 #if defined(ENABLE_STATISTICS)
889 count_const_pool_len += sizeof(constant_FMIref);
891 /* resolve simple name and descriptor */
893 nat = (constant_nameandtype*) class_getconstant(c,
894 forward_fieldmethints->nameandtype_index,
895 CONSTANT_NameAndType);
900 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
902 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
905 /* the classref is created later */
907 fmi->p.index = forward_fieldmethints->class_index;
908 fmi->name = nat->name;
909 fmi->descriptor = nat->descriptor;
911 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
912 cpinfos[forward_fieldmethints->thisindex] = fmi;
914 nff = forward_fieldmethints;
915 forward_fieldmethints = forward_fieldmethints->next;
918 /* everything was ok */
924 /* loader_load_attribute_signature *********************************************
926 Signature_attribute {
927 u2 attribute_name_index;
932 *******************************************************************************/
934 #if defined(ENABLE_JAVASE)
935 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
945 /* check remaining bytecode */
947 if (!suck_check_classbuffer_size(cb, 4 + 2))
950 /* check attribute length */
952 attribute_length = suck_u4(cb);
954 if (attribute_length != 2) {
955 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
959 if (*signature != NULL) {
960 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
966 signature_index = suck_u2(cb);
968 *signature = (utf*) class_getconstant(c, signature_index, CONSTANT_Utf8);
970 if (*signature == NULL)
975 #endif /* defined(ENABLE_JAVASE) */
978 /* load_class_from_sysloader ***************************************************
980 Load the class with the given name using the system class loader
983 name.............the classname
987 NULL if an exception has been thrown
989 *******************************************************************************/
991 classinfo *load_class_from_sysloader(utf *name)
998 assert(class_java_lang_Object);
999 assert(class_java_lang_ClassLoader);
1000 assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
1002 m = class_resolveclassmethod(class_java_lang_ClassLoader,
1003 utf_getSystemClassLoader,
1004 utf_void__java_lang_ClassLoader,
1005 class_java_lang_Object,
1011 clo = vm_call_method(m, NULL);
1016 cl = loader_hashtable_classloader_add(clo);
1018 c = load_class_from_classloader(name, cl);
1024 /* load_class_from_classloader *************************************************
1026 Load the class with the given name using the given user-defined class loader.
1029 name.............the classname
1030 cl...............user-defined class loader
1033 the loaded class, or
1034 NULL if an exception has been thrown
1036 *******************************************************************************/
1038 classinfo *load_class_from_classloader(utf *name, classloader_t *cl)
1043 java_handle_t *string;
1044 #if defined(ENABLE_RT_TIMING)
1045 struct timespec time_start, time_lookup, time_prepare, time_java,
1049 RT_TIMING_GET_TIME(time_start);
1053 /* lookup if this class has already been loaded */
1055 c = classcache_lookup(cl, name);
1057 RT_TIMING_GET_TIME(time_lookup);
1058 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1063 /* if other class loader than bootstrap, call it */
1071 namelen = name->blength;
1073 /* handle array classes */
1074 if (text[0] == '[') {
1080 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1081 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1082 exceptions_throw_classnotfoundexception(name);
1086 u = utf_new(text + 2, namelen - 3);
1088 if (!(comp = load_class_from_classloader(u, cl)))
1091 /* create the array class */
1093 c = class_array_of(comp, false);
1095 tmpc = classcache_store(cl, c, true);
1098 /* exception, free the loaded class */
1099 c->state &= ~CLASS_LOADING;
1106 /* load the component class */
1108 u = utf_new(text + 1, namelen - 1);
1110 if (!(comp = load_class_from_classloader(u, cl)))
1113 /* create the array class */
1115 c = class_array_of(comp, false);
1117 tmpc = classcache_store(cl, c, true);
1120 /* exception, free the loaded class */
1121 c->state &= ~CLASS_LOADING;
1128 /* primitive array classes are loaded by the bootstrap loader */
1130 c = load_class_bootstrap(name);
1136 LLNI_class_get(cl, c);
1138 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1139 /* OpenJDK uses this internal function because it's
1142 lc = class_resolveclassmethod(c,
1143 utf_loadClassInternal,
1144 utf_java_lang_String__java_lang_Class,
1148 lc = class_resolveclassmethod(c,
1150 utf_java_lang_String__java_lang_Class,
1156 return false; /* exception */
1158 /* move return value into `o' and cast it afterwards to a classinfo* */
1160 string = javastring_new_slash_to_dot(name);
1162 RT_TIMING_GET_TIME(time_prepare);
1164 o = vm_call_method(lc, (java_handle_t *) cl, string);
1166 RT_TIMING_GET_TIME(time_java);
1168 c = LLNI_classinfo_unwrap(o);
1171 /* Store this class in the loaded class cache. If another
1172 class with the same (initloader,name) pair has been
1173 stored earlier it will be returned by classcache_store
1174 In this case classcache_store may not free the class
1175 because it has already been exposed to Java code which
1176 may have kept references to that class. */
1178 tmpc = classcache_store(cl, c, false);
1181 /* exception, free the loaded class */
1182 c->state &= ~CLASS_LOADING;
1189 RT_TIMING_GET_TIME(time_cache);
1191 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1192 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1193 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1195 /* SUN compatible -verbose:class output */
1197 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1199 utf_display_printable_ascii_classname(name);
1203 #if defined(ENABLE_JVMTI)
1204 /* fire Class Load JVMTI event */
1205 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1212 c = load_class_bootstrap(name);
1218 /* load_class_bootstrap ********************************************************
1220 Load the class with the given name using the bootstrap class loader.
1223 name.............the classname
1226 loaded classinfo, or
1227 NULL if an exception has been thrown
1230 load_class_bootstrap is synchronized. It can be treated as an
1233 *******************************************************************************/
1235 classinfo *load_class_bootstrap(utf *name)
1240 #if defined(ENABLE_RT_TIMING)
1241 struct timespec time_start, time_lookup, time_array, time_suck,
1242 time_load, time_cache;
1245 RT_TIMING_GET_TIME(time_start);
1251 /* lookup if this class has already been loaded */
1253 r = classcache_lookup(NULL, name);
1256 RT_TIMING_GET_TIME(time_lookup);
1257 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1262 RT_TIMING_GET_TIME(time_lookup);
1263 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1265 /* create the classinfo */
1267 c = class_create_classinfo(name);
1269 /* handle array classes */
1271 if (name->text[0] == '[') {
1272 c = load_newly_created_array(c, NULL);
1277 assert(c->state & CLASS_LOADED);
1279 RT_TIMING_GET_TIME(time_array);
1280 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1285 #if defined(ENABLE_STATISTICS)
1288 if (opt_getcompilingtime)
1289 compilingtime_stop();
1291 if (opt_getloadingtime)
1292 loadingtime_start();
1295 /* load classdata, throw exception on error */
1300 exceptions_throw_classnotfoundexception(name);
1304 RT_TIMING_GET_TIME(time_suck);
1306 /* load the class from the buffer */
1308 r = load_class_from_classbuffer(cb);
1310 RT_TIMING_GET_TIME(time_load);
1313 /* the class could not be loaded, free the classinfo struct */
1318 /* Store this class in the loaded class cache this step also
1319 checks the loading constraints. If the class has been
1320 loaded before, the earlier loaded class is returned. */
1322 classinfo *res = classcache_store(NULL, c, true);
1329 // Add the package name to the boot packages.
1330 Package::add(c->packagename);
1336 RT_TIMING_GET_TIME(time_cache);
1338 /* SUN compatible -verbose:class output */
1340 if (opt_verboseclass && r) {
1342 utf_display_printable_ascii_classname(name);
1343 printf(" from %s]\n", cb->path);
1350 #if defined(ENABLE_STATISTICS)
1353 if (opt_getloadingtime)
1356 if (opt_getcompilingtime)
1357 compilingtime_start();
1360 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1361 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1362 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1363 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1369 /* load_class_from_classbuffer_intern ******************************************
1371 Loads a class from a classbuffer into a given classinfo structure.
1372 Super-classes are also loaded at this point and some verfication
1376 This function is NOT synchronized!
1378 *******************************************************************************/
1380 static bool load_class_from_classbuffer_intern(classbuffer *cb)
1386 utf **interfacesnames;
1388 constant_classref *cr;
1392 descriptor_pool *descpool;
1393 #if defined(ENABLE_STATISTICS)
1397 #if defined(ENABLE_RT_TIMING)
1398 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1399 time_setup, time_fields, time_methods, time_classrefs,
1400 time_descs, time_setrefs, time_parsefds, time_parsemds,
1401 time_parsecpool, time_verify, time_attrs;
1404 // Create new dump memory area.
1407 RT_TIMING_GET_TIME(time_start);
1409 /* Get the classbuffer's class. */
1413 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1416 /* check signature */
1418 if (suck_u4(cb) != MAGIC) {
1419 exceptions_throw_classformaterror(c, "Bad magic number");
1428 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1429 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1433 RT_TIMING_GET_TIME(time_checks);
1435 /* create a new descriptor pool */
1437 descpool = descriptor_pool_new(c);
1439 RT_TIMING_GET_TIME(time_ndpool);
1441 /* load the constant pool */
1443 if (!load_constantpool(cb, descpool))
1446 RT_TIMING_GET_TIME(time_cpool);
1450 if (!suck_check_classbuffer_size(cb, 2))
1453 /* We OR the flags here, as we set already some flags in
1454 class_create_classinfo. */
1456 c->flags |= suck_u2(cb);
1458 /* check ACC flags consistency */
1460 if (c->flags & ACC_INTERFACE) {
1461 if (!(c->flags & ACC_ABSTRACT)) {
1462 /* We work around this because interfaces in JDK 1.1 are
1463 * not declared abstract. */
1465 c->flags |= ACC_ABSTRACT;
1468 if (c->flags & ACC_FINAL) {
1469 exceptions_throw_classformaterror(c,
1470 "Illegal class modifiers: 0x%X",
1475 if (c->flags & ACC_SUPER) {
1476 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1480 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1481 exceptions_throw_classformaterror(c,
1482 "Illegal class modifiers: 0x%X",
1487 if (!suck_check_classbuffer_size(cb, 2 + 2))
1492 index = suck_u2(cb);
1494 name = (utf *) class_getconstant(c, index, CONSTANT_Class);
1499 if (c->name == utf_not_named_yet) {
1500 /* we finally have a name for this class */
1502 class_set_packagename(c);
1504 else if (name != c->name) {
1505 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
1509 /* Retrieve superclass. */
1513 index = suck_u2(cb);
1518 /* This is only allowed for java.lang.Object. */
1520 if (c->name != utf_java_lang_Object) {
1521 exceptions_throw_classformaterror(c, "Bad superclass index");
1526 supername = (utf *) class_getconstant(c, index, CONSTANT_Class);
1528 if (supername == NULL)
1531 /* java.lang.Object may not have a super class. */
1533 if (c->name == utf_java_lang_Object) {
1534 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
1538 /* Detect circularity. */
1540 if (supername == c->name) {
1541 exceptions_throw_classcircularityerror(c);
1545 /* Interfaces must have java.lang.Object as super class. */
1547 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
1548 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
1553 /* Parse the super interfaces. */
1555 if (!suck_check_classbuffer_size(cb, 2))
1558 c->interfacescount = suck_u2(cb);
1560 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1563 c->interfaces = MNEW(classinfo*, c->interfacescount);
1565 /* Get the names of the super interfaces. */
1567 interfacesnames = (utf**) DumpMemory::allocate(sizeof(utf*) * c->interfacescount);
1569 for (int32_t i = 0; i < c->interfacescount; i++) {
1570 index = suck_u2(cb);
1572 u = (utf *) class_getconstant(c, index, CONSTANT_Class);
1577 interfacesnames[i] = u;
1580 RT_TIMING_GET_TIME(time_setup);
1584 if (!suck_check_classbuffer_size(cb, 2))
1587 c->fieldscount = suck_u2(cb);
1588 c->fields = MNEW(fieldinfo, c->fieldscount);
1590 MZERO(c->fields, fieldinfo, c->fieldscount);
1592 for (int32_t i = 0; i < c->fieldscount; i++) {
1593 if (!field_load(cb, &(c->fields[i]), descpool))
1597 RT_TIMING_GET_TIME(time_fields);
1599 /* Parse methods. */
1601 if (!suck_check_classbuffer_size(cb, 2))
1604 c->methodscount = suck_u2(cb);
1605 c->methods = MNEW(methodinfo, c->methodscount);
1607 MZERO(c->methods, methodinfo, c->methodscount);
1609 for (int32_t i = 0; i < c->methodscount; i++) {
1610 if (!method_load(cb, &(c->methods[i]), descpool))
1614 RT_TIMING_GET_TIME(time_methods);
1616 /* create the class reference table */
1619 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
1621 RT_TIMING_GET_TIME(time_classrefs);
1623 /* allocate space for the parsed descriptors */
1625 descriptor_pool_alloc_parsed_descriptors(descpool);
1626 c->parseddescs = (u1*) descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
1628 #if defined(ENABLE_STATISTICS)
1630 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
1631 count_classref_len += classrefsize;
1632 count_parsed_desc_len += descsize;
1636 RT_TIMING_GET_TIME(time_descs);
1638 /* put the classrefs in the constant pool */
1640 for (int32_t i = 0; i < c->cpcount; i++) {
1641 if (c->cptags[i] == CONSTANT_Class) {
1642 utf *name = (utf *) c->cpinfos[i];
1643 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
1647 /* Resolve the super class. */
1649 if (supername != NULL) {
1650 cr = descriptor_pool_lookup_classref(descpool, supername);
1655 /* XXX This should be done better. */
1656 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1659 resolve_handle_pending_exception(true);
1663 /* Interfaces are not allowed as super classes. */
1665 if (tc->flags & ACC_INTERFACE) {
1666 exceptions_throw_incompatibleclasschangeerror(c, "class %s has interface %s as super class");
1670 /* Don't allow extending final classes */
1672 if (tc->flags & ACC_FINAL) {
1673 exceptions_throw_verifyerror(NULL,
1674 "Cannot inherit from final class");
1678 /* Store the super class. */
1683 /* Resolve the super interfaces. */
1685 for (int32_t i = 0; i < c->interfacescount; i++) {
1686 u = interfacesnames[i];
1687 cr = descriptor_pool_lookup_classref(descpool, u);
1692 /* XXX This should be done better. */
1693 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1696 resolve_handle_pending_exception(true);
1700 /* Detect circularity. */
1703 exceptions_throw_classcircularityerror(c);
1707 if (!(tc->flags & ACC_INTERFACE)) {
1708 exceptions_throw_incompatibleclasschangeerror(tc,
1709 "Implementing class");
1713 /* Store the super interface. */
1715 c->interfaces[i] = tc;
1718 RT_TIMING_GET_TIME(time_setrefs);
1720 /* Parse the field descriptors. */
1722 for (int32_t i = 0; i < c->fieldscount; i++) {
1723 c->fields[i].parseddesc =
1724 descriptor_pool_parse_field_descriptor(descpool,
1725 c->fields[i].descriptor);
1726 if (!c->fields[i].parseddesc)
1730 RT_TIMING_GET_TIME(time_parsefds);
1732 /* parse method descriptors */
1734 for (int32_t i = 0; i < c->methodscount; i++) {
1735 methodinfo *m = &c->methods[i];
1737 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
1738 m->flags, class_get_self_classref(m->clazz));
1742 for (int32_t j = 0; j < m->rawexceptiontablelength; j++) {
1743 if (!m->rawexceptiontable[j].catchtype.any)
1746 if ((m->rawexceptiontable[j].catchtype.ref =
1747 descriptor_pool_lookup_classref(descpool,
1748 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
1752 for (int32_t j = 0; j < m->thrownexceptionscount; j++) {
1753 if (!m->thrownexceptions[j].any)
1756 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
1757 (utf *) m->thrownexceptions[j].any)) == NULL)
1762 RT_TIMING_GET_TIME(time_parsemds);
1764 /* parse the loaded descriptors */
1766 for (int32_t i = 0; i < c->cpcount; i++) {
1767 constant_FMIref *fmi;
1770 switch (c->cptags[i]) {
1771 case CONSTANT_Fieldref:
1772 fmi = (constant_FMIref *) c->cpinfos[i];
1773 fmi->parseddesc.fd =
1774 descriptor_pool_parse_field_descriptor(descpool,
1776 if (!fmi->parseddesc.fd)
1779 index = fmi->p.index;
1781 (constant_classref *) class_getconstant(c, index,
1783 if (!fmi->p.classref)
1786 case CONSTANT_Methodref:
1787 case CONSTANT_InterfaceMethodref:
1788 fmi = (constant_FMIref *) c->cpinfos[i];
1789 index = fmi->p.index;
1791 (constant_classref *) class_getconstant(c, index,
1793 if (!fmi->p.classref)
1795 fmi->parseddesc.md =
1796 descriptor_pool_parse_method_descriptor(descpool,
1800 if (!fmi->parseddesc.md)
1806 RT_TIMING_GET_TIME(time_parsecpool);
1808 #ifdef ENABLE_VERIFIER
1809 /* Check if all fields and methods can be uniquely
1810 * identified by (name,descriptor). */
1813 /* We use a hash table here to avoid making the
1814 * average case quadratic in # of methods, fields.
1816 static int shift = 0;
1818 u2 *next; /* for chaining colliding hash entries */
1824 /* Allocate hashtable */
1825 len = c->methodscount;
1826 if (len < c->fieldscount) len = c->fieldscount;
1828 hashtab = MNEW(u2,(hashlen + len));
1829 next = hashtab + hashlen;
1831 /* Determine bitshift (to get good hash values) */
1841 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
1843 for (int32_t i = 0; i < c->fieldscount; ++i) {
1844 fieldinfo *fi = c->fields + i;
1846 /* It's ok if we lose bits here */
1847 index = ((((size_t) fi->name) +
1848 ((size_t) fi->descriptor)) >> shift) % hashlen;
1850 if ((old = hashtab[index])) {
1854 if (c->fields[old].name == fi->name &&
1855 c->fields[old].descriptor == fi->descriptor) {
1856 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
1859 } while ((old = next[old]));
1861 hashtab[index] = i + 1;
1865 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
1867 for (int32_t i = 0; i < c->methodscount; ++i) {
1868 methodinfo *mi = c->methods + i;
1870 /* It's ok if we lose bits here */
1871 index = ((((size_t) mi->name) +
1872 ((size_t) mi->descriptor)) >> shift) % hashlen;
1874 if ((old = hashtab[index])) {
1878 if (c->methods[old].name == mi->name &&
1879 c->methods[old].descriptor == mi->descriptor) {
1880 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
1883 } while ((old = next[old]));
1885 hashtab[index] = i + 1;
1888 MFREE(hashtab, u2, (hashlen + len));
1890 #endif /* ENABLE_VERIFIER */
1892 RT_TIMING_GET_TIME(time_verify);
1894 #if defined(ENABLE_STATISTICS)
1896 size_classinfo += sizeof(classinfo*) * c->interfacescount;
1897 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
1898 size_methodinfo += sizeof(methodinfo) * c->methodscount;
1902 /* load attribute structures */
1904 if (!class_load_attributes(cb))
1907 /* Pre Java 1.5 version don't check this. This implementation is
1908 like Java 1.5 do it: for class file version 45.3 we don't check
1909 it, older versions are checked. */
1911 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
1912 /* check if all data has been read */
1913 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
1915 if (classdata_left > 0) {
1916 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
1921 RT_TIMING_GET_TIME(time_attrs);
1923 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
1924 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
1925 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
1926 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
1927 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
1928 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
1929 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
1930 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
1931 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
1932 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
1933 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
1934 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
1935 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
1936 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
1937 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
1943 /* load_class_from_classbuffer *************************************************
1945 Convenience wrapper for load_class_from_classbuffer.
1948 This function is NOT synchronized!
1950 *******************************************************************************/
1952 classinfo *load_class_from_classbuffer(classbuffer *cb)
1957 /* Get the classbuffer's class. */
1961 /* Check if the class is already loaded. */
1963 if (c->state & CLASS_LOADED)
1966 #if defined(ENABLE_STATISTICS)
1968 count_class_loads++;
1971 #if !defined(NDEBUG)
1973 log_message_class("Loading class: ", c);
1976 /* Class is currently loading. */
1978 c->state |= CLASS_LOADING;
1980 /* Parse the classbuffer. */
1982 result = load_class_from_classbuffer_intern(cb);
1984 /* An error occurred. */
1986 if (result == false) {
1987 /* Revert loading state. */
1989 c->state = (c->state & ~CLASS_LOADING);
1994 /* Revert loading state and set loaded. */
1996 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
1998 #if defined(ENABLE_JVMTI)
1999 /* fire Class Prepare JVMTI event */
2002 jvmti_ClassLoadPrepare(true, c);
2005 #if !defined(NDEBUG)
2007 log_message_class("Loading done class: ", c);
2014 /* load_newly_created_array ****************************************************
2016 Load a newly created array class.
2019 c....................the array class C has been loaded
2020 other classinfo......the array class was found in the class cache,
2022 NULL.................an exception has been thrown
2025 This is an internal function. Do not use it unless you know exactly
2028 Use one of the load_class_... functions for general array class loading.
2030 *******************************************************************************/
2032 classinfo *load_newly_created_array(classinfo *c, classloader_t *loader)
2034 classinfo *comp = NULL;
2036 methoddesc *clonedesc;
2037 constant_classref *classrefs;
2042 text = c->name->text;
2043 namelen = c->name->blength;
2045 /* Check array class name */
2047 if ((namelen < 2) || (text[0] != '[')) {
2048 exceptions_throw_classnotfoundexception(c->name);
2052 /* Check the element type */
2056 /* c is an array of arrays. We have to create the component class. */
2058 u = utf_new(text + 1, namelen - 1);
2060 comp = load_class_from_classloader(u, loader);
2065 assert(comp->state & CLASS_LOADED);
2067 /* the array's flags are that of the component class */
2068 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2069 c->classloader = comp->classloader;
2073 /* c is an array of objects. */
2075 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2076 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2077 exceptions_throw_classnotfoundexception(c->name);
2081 u = utf_new(text + 2, namelen - 3);
2083 if (!(comp = load_class_from_classloader(u, loader)))
2086 assert(comp->state & CLASS_LOADED);
2088 /* the array's flags are that of the component class */
2089 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2090 c->classloader = comp->classloader;
2094 /* c is an array of a primitive type */
2096 /* check for cases like `[II' and whether the character is a
2097 valid primitive type */
2099 if ((namelen > 2) || (Primitive::get_class_by_char(text[1]) == NULL)) {
2100 exceptions_throw_classnotfoundexception(c->name);
2104 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2105 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2106 c->classloader = NULL;
2109 assert(class_java_lang_Object);
2110 #if defined(ENABLE_JAVASE)
2111 assert(class_java_lang_Cloneable);
2112 assert(class_java_io_Serializable);
2115 /* Setup the array class. */
2117 c->super = class_java_lang_Object;
2119 #if defined(ENABLE_JAVASE)
2121 c->interfacescount = 2;
2122 c->interfaces = MNEW(classinfo*, 2);
2123 c->interfaces[0] = class_java_lang_Cloneable;
2124 c->interfaces[1] = class_java_io_Serializable;
2126 #elif defined(ENABLE_JAVAME_CLDC1_1)
2128 c->interfacescount = 0;
2129 c->interfaces = NULL;
2132 # error unknow Java configuration
2135 c->methodscount = 1;
2136 c->methods = MNEW(methodinfo, c->methodscount);
2138 MZERO(c->methods, methodinfo, c->methodscount);
2140 classrefs = MNEW(constant_classref, 2);
2142 CLASSREF_INIT(classrefs[0], c, c->name);
2143 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2145 /* create descriptor for clone method */
2146 /* we need one paramslot which is reserved for the 'this' parameter */
2147 clonedesc = NEW(methoddesc);
2148 clonedesc->returntype.type = TYPE_ADR;
2149 clonedesc->returntype.classref = classrefs + 1;
2150 clonedesc->returntype.arraydim = 0;
2151 /* initialize params to "empty", add real params below in
2152 descriptor_params_from_paramtypes */
2153 clonedesc->paramcount = 0;
2154 clonedesc->paramslots = 0;
2155 clonedesc->paramtypes[0].classref = classrefs + 0;
2156 clonedesc->params = NULL;
2158 /* create methodinfo */
2161 MSET(clone, 0, methodinfo, 1);
2163 /* ATTENTION: if you delete the ACC_NATIVE below, set
2164 clone->maxlocals=1 (interpreter related) */
2166 clone->mutex = new Mutex();
2167 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2168 clone->name = utf_clone;
2169 clone->descriptor = utf_void__java_lang_Object;
2170 clone->parseddesc = clonedesc;
2173 /* parse the descriptor to get the register allocation */
2175 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2178 clone->code = NativeStub::generate(clone, BUILTIN_clone);
2180 /* XXX: field: length? */
2182 /* array classes are not loaded from class files */
2184 c->state |= CLASS_LOADED;
2185 c->parseddescs = (u1 *) clonedesc;
2186 c->parseddescsize = sizeof(methodinfo);
2187 c->classrefs = classrefs;
2188 c->classrefcount = 1;
2190 /* insert class into the loaded class cache */
2191 /* XXX free classinfo if NULL returned? */
2193 return classcache_store(loader, c, true);
2197 /* loader_close ****************************************************************
2199 Frees all resources.
2201 *******************************************************************************/
2203 void loader_close(void)
2210 * These are local overrides for various environment variables in Emacs.
2211 * Please do not remove this and leave it at the end of the file, where
2212 * Emacs will automagically detect them.
2213 * ---------------------------------------------------------------------
2216 * indent-tabs-mode: t
2220 * vim:noexpandtab:sw=4:ts=4: