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.hpp"
46 #include "vm/exceptions.hpp"
47 #include "vm/field.hpp"
48 #include "vm/global.h"
49 #include "vm/globals.hpp"
50 #include "vm/linker.hpp"
51 #include "vm/loader.hpp"
52 #include "vm/method.hpp"
53 #include "vm/options.h"
54 #include "vm/package.hpp"
55 #include "vm/primitive.hpp"
56 #include "vm/resolve.hpp"
57 #include "vm/rt-timing.h"
58 #include "vm/string.hpp"
59 #include "vm/suck.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)
73 # include "vm/zip.hpp"
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 TRACESUBSYSTEMINITIALIZATION("loader_preinit");
102 #if defined(ENABLE_THREADS)
103 /* Initialize the monitor pointer for zip/jar file locking. */
105 for (List<list_classpath_entry*>::iterator it = list_classpath_entries->begin(); it != list_classpath_entries->end(); it++) {
106 list_classpath_entry* lce = *it;
108 if (lce->type == CLASSPATH_ARCHIVE)
109 lce->mutex = new Mutex();
113 /* initialize classloader hashtable, 10 entries should be enough */
115 hashtable_classloader = NEW(hashtable);
116 hashtable_create(hashtable_classloader, 10);
118 /* Load the most basic classes. */
120 assert(VM::get_current()->is_initializing() == true);
122 class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object);
124 #if defined(ENABLE_JAVASE)
125 class_java_lang_Cloneable = load_class_bootstrap(utf_java_lang_Cloneable);
126 class_java_io_Serializable = load_class_bootstrap(utf_java_io_Serializable);
131 /* loader_init *****************************************************************
133 Loads all classes required in the VM.
135 NOTE: Exceptions thrown during VM initialization are caught in the
136 exception functions themselves.
138 *******************************************************************************/
140 void loader_init(void)
142 TRACESUBSYSTEMINITIALIZATION("loader_init");
144 /* Load primitive-type wrapping classes. */
146 assert(VM::get_current()->is_initializing() == true);
148 #if defined(ENABLE_JAVASE)
149 class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void);
152 class_java_lang_Boolean = load_class_bootstrap(utf_java_lang_Boolean);
153 class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte);
154 class_java_lang_Character = load_class_bootstrap(utf_java_lang_Character);
155 class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short);
156 class_java_lang_Integer = load_class_bootstrap(utf_java_lang_Integer);
157 class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long);
158 class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float);
159 class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double);
161 /* Load important system classes. */
163 class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class);
164 class_java_lang_String = load_class_bootstrap(utf_java_lang_String);
166 #if defined(ENABLE_JAVASE)
167 class_java_lang_ClassLoader =
168 load_class_bootstrap(utf_java_lang_ClassLoader);
170 class_java_lang_SecurityManager =
171 load_class_bootstrap(utf_java_lang_SecurityManager);
174 class_java_lang_System =
175 load_class_bootstrap(utf_new_char("java/lang/System"));
177 class_java_lang_Thread =
178 load_class_bootstrap(utf_new_char("java/lang/Thread"));
180 #if defined(ENABLE_JAVASE)
181 class_java_lang_ThreadGroup =
182 load_class_bootstrap(utf_java_lang_ThreadGroup);
185 class_java_lang_Throwable = load_class_bootstrap(utf_java_lang_Throwable);
187 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
188 class_java_lang_VMSystem =
189 load_class_bootstrap(utf_new_char("java/lang/VMSystem"));
191 class_java_lang_VMThread =
192 load_class_bootstrap(utf_new_char("java/lang/VMThread"));
194 class_java_lang_VMThrowable =
195 load_class_bootstrap(utf_new_char("java/lang/VMThrowable"));
198 /* Important system exceptions. */
200 class_java_lang_Exception = load_class_bootstrap(utf_java_lang_Exception);
202 class_java_lang_ClassNotFoundException =
203 load_class_bootstrap(utf_java_lang_ClassNotFoundException);
205 class_java_lang_RuntimeException =
206 load_class_bootstrap(utf_java_lang_RuntimeException);
208 /* Some classes which may be used often. */
210 #if defined(ENABLE_JAVASE)
211 class_java_lang_StackTraceElement = load_class_bootstrap(utf_java_lang_StackTraceElement);
213 class_java_lang_reflect_Constructor = load_class_bootstrap(utf_java_lang_reflect_Constructor);
214 class_java_lang_reflect_Field = load_class_bootstrap(utf_java_lang_reflect_Field);
215 class_java_lang_reflect_Method = load_class_bootstrap(utf_java_lang_reflect_Method);
217 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
218 class_java_lang_reflect_VMConstructor = load_class_bootstrap(utf_java_lang_reflect_VMConstructor);
219 class_java_lang_reflect_VMField = load_class_bootstrap(utf_java_lang_reflect_VMField);
220 class_java_lang_reflect_VMMethod = load_class_bootstrap(utf_java_lang_reflect_VMMethod);
223 class_java_security_PrivilegedAction = load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"));
225 class_java_util_HashMap = load_class_bootstrap(utf_new_char("java/util/HashMap"));
226 class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector);
228 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
229 class_sun_misc_Signal = load_class_bootstrap(utf_new_char("sun/misc/Signal"));
230 class_sun_reflect_MagicAccessorImpl = load_class_bootstrap(utf_new_char("sun/reflect/MagicAccessorImpl"));
233 arrayclass_java_lang_Object =
234 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"));
236 # if defined(ENABLE_ANNOTATIONS)
237 /* needed by annotation support */
238 class_sun_reflect_ConstantPool =
239 load_class_bootstrap(utf_new_char("sun/reflect/ConstantPool"));
241 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
242 /* needed by GNU Classpaths annotation support */
243 class_sun_reflect_annotation_AnnotationParser =
244 load_class_bootstrap(utf_new_char("sun/reflect/annotation/AnnotationParser"));
251 /* loader_hashtable_classloader_add ********************************************
253 Adds an entry to the classloader hashtable.
255 REMEMBER: Also use this to register native loaders!
257 *******************************************************************************/
259 classloader_t *loader_hashtable_classloader_add(java_handle_t *cl)
261 hashtable_classloader_entry *cle;
268 hashtable_classloader->mutex->lock();
272 /* key for entry is the hashcode of the classloader;
273 aligned to 16-byte boundaries */
275 key = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
276 slot = key & (hashtable_classloader->size - 1);
277 cle = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
279 /* search hashchain for existing entry */
282 if (cle->object == LLNI_DIRECT(cl))
290 /* if no classloader was found, we create a new entry here */
293 cle = NEW(hashtable_classloader_entry);
295 #if defined(ENABLE_GC_CACAO)
296 /* register the classloader object with the GC */
298 gc_reference_register(&(cle->object), GC_REFTYPE_CLASSLOADER);
303 cle->object = LLNI_DIRECT(cl);
307 /*#define LOADER_DEBUG_CLASSLOADER*/
308 #ifdef LOADER_DEBUG_CLASSLOADER
309 printf("CLASSLOADER: adding new classloader entry %p for %p: ", cle, cl);
310 class_print(LLNI_vftbl_direct(cl)->class);
315 /* insert entry into hashtable */
317 cle->hashlink = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
318 hashtable_classloader->ptr[slot] = cle;
320 /* update number of entries */
322 hashtable_classloader->entries++;
325 hashtable_classloader->mutex->unlock();
327 #if defined(ENABLE_HANDLES)
335 /* loader_hashtable_classloader_find *******************************************
337 Find an entry in the classloader hashtable.
339 *******************************************************************************/
341 classloader_t *loader_hashtable_classloader_find(java_handle_t *cl)
343 hashtable_classloader_entry *cle;
352 /* key for entry is the hashcode of the classloader;
353 aligned to 16-byte boundaries */
355 key = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
356 slot = key & (hashtable_classloader->size - 1);
357 cle = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
359 /* search hashchain for existing entry */
362 if (cle->object == LLNI_DIRECT(cl))
368 #ifdef LOADER_DEBUG_CLASSLOADER
370 printf("CLASSLOADER: unable to find classloader entry for %p: ", cl);
371 class_print(LLNI_vftbl_direct(cl)->class);
379 #if defined(ENABLE_HANDLES)
387 /* loader_load_all_classes *****************************************************
389 Loads all classes specified in the BOOTCLASSPATH.
391 *******************************************************************************/
393 void loader_load_all_classes(void)
395 #if defined(ENABLE_ZLIB)
397 hashtable_zipfile_entry *htzfe;
401 for (List<list_classpath_entry*>::iterator it = list_classpath_entries->begin(); it != list_classpath_entries->end(); it++) {
402 list_classpath_entry* lce = *it;
404 #if defined(ENABLE_ZLIB)
405 if (lce->type == CLASSPATH_ARCHIVE) {
406 /* get the classes hashtable */
410 for (uint32_t slot = 0; slot < ht->size; slot++) {
411 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
413 for (; htzfe; htzfe = htzfe->hashlink) {
416 /* skip all entries in META-INF and .properties,
419 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
420 strstr(u->text, ".properties") ||
421 strstr(u->text, ".png"))
424 /* load class from bootstrap classloader */
426 if (!load_class_bootstrap(u)) {
427 fprintf(stderr, "Error loading: ");
428 utf_fprint_printable_ascii_classname(stderr, u);
429 fprintf(stderr, "\n");
432 /* print out exception and cause */
434 exceptions_print_current_exception();
442 #if defined(ENABLE_ZLIB)
449 /* loader_skip_attribute_body **************************************************
451 Skips an attribute the attribute_name_index has already been read.
454 u2 attribute_name_index;
456 u1 info[attribute_length];
459 *******************************************************************************/
461 bool loader_skip_attribute_body(classbuffer *cb)
465 if (!suck_check_classbuffer_size(cb, 4))
468 attribute_length = suck_u4(cb);
470 if (!suck_check_classbuffer_size(cb, attribute_length))
473 suck_skip_nbytes(cb, attribute_length);
479 /* load_constantpool ***********************************************************
481 Loads the constantpool of a class, the entries are transformed into
482 a simpler format by resolving references (a detailed overview of
483 the compact structures can be found in global.h).
485 *******************************************************************************/
487 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
490 /* The following structures are used to save information which cannot be
491 processed during the first pass. After the complete constantpool has
492 been traversed the references can be resolved.
493 (only in specific order) */
495 /* CONSTANT_Class entries */
496 typedef struct forward_class {
497 struct forward_class *next;
502 /* CONSTANT_String */
503 typedef struct forward_string {
504 struct forward_string *next;
509 /* CONSTANT_NameAndType */
510 typedef struct forward_nameandtype {
511 struct forward_nameandtype *next;
515 } forward_nameandtype;
517 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
518 typedef struct forward_fieldmethint {
519 struct forward_fieldmethint *next;
523 u2 nameandtype_index;
524 } forward_fieldmethint;
530 forward_class *forward_classes = NULL;
531 forward_string *forward_strings = NULL;
532 forward_nameandtype *forward_nameandtypes = NULL;
533 forward_fieldmethint *forward_fieldmethints = NULL;
537 forward_nameandtype *nfn;
538 forward_fieldmethint *nff;
546 /* number of entries in the constant_pool table plus one */
547 if (!suck_check_classbuffer_size(cb, 2))
550 cpcount = c->cpcount = suck_u2(cb);
552 /* allocate memory */
553 cptags = c->cptags = MNEW(u1, cpcount);
554 cpinfos = c->cpinfos = MNEW(void*, cpcount);
557 exceptions_throw_classformaterror(c, "Illegal constant pool size");
561 #if defined(ENABLE_STATISTICS)
563 count_const_pool_len += (sizeof(u1) + sizeof(void*)) * cpcount;
566 /* initialize constantpool */
567 for (idx = 0; idx < cpcount; idx++) {
568 cptags[idx] = CONSTANT_UNUSED;
573 /******* first pass *******/
574 /* entries which cannot be resolved now are written into
575 temporary structures and traversed again later */
578 while (idx < cpcount) {
581 /* get constant type */
582 if (!suck_check_classbuffer_size(cb, 1))
590 nfc = (forward_class*) DumpMemory::allocate(sizeof(forward_class));
592 nfc->next = forward_classes;
593 forward_classes = nfc;
595 nfc->thisindex = idx;
596 /* reference to CONSTANT_NameAndType */
597 if (!suck_check_classbuffer_size(cb, 2))
600 nfc->name_index = suck_u2(cb);
605 case CONSTANT_String:
607 nfs = (forward_string*) DumpMemory::allocate(sizeof(forward_string));
609 nfs->next = forward_strings;
610 forward_strings = nfs;
612 nfs->thisindex = idx;
614 /* reference to CONSTANT_Utf8_info with string characters */
615 if (!suck_check_classbuffer_size(cb, 2))
618 nfs->string_index = suck_u2(cb);
623 case CONSTANT_NameAndType:
625 nfn = (forward_nameandtype*) DumpMemory::allocate(sizeof(forward_nameandtype));
627 nfn->next = forward_nameandtypes;
628 forward_nameandtypes = nfn;
630 nfn->thisindex = idx;
632 if (!suck_check_classbuffer_size(cb, 2 + 2))
635 /* reference to CONSTANT_Utf8_info containing simple name */
636 nfn->name_index = suck_u2(cb);
638 /* reference to CONSTANT_Utf8_info containing field or method
640 nfn->sig_index = suck_u2(cb);
645 case CONSTANT_Fieldref:
646 case CONSTANT_Methodref:
647 case CONSTANT_InterfaceMethodref:
649 nff = (forward_fieldmethint*) DumpMemory::allocate(sizeof(forward_fieldmethint));
651 nff->next = forward_fieldmethints;
652 forward_fieldmethints = nff;
654 nff->thisindex = idx;
658 if (!suck_check_classbuffer_size(cb, 2 + 2))
661 /* class or interface type that contains the declaration of the
663 nff->class_index = suck_u2(cb);
665 /* name and descriptor of the field or method */
666 nff->nameandtype_index = suck_u2(cb);
671 case CONSTANT_Integer: {
672 constant_integer *ci = NEW(constant_integer);
674 #if defined(ENABLE_STATISTICS)
676 count_const_pool_len += sizeof(constant_integer);
679 if (!suck_check_classbuffer_size(cb, 4))
682 ci->value = suck_s4(cb);
683 cptags[idx] = CONSTANT_Integer;
690 case CONSTANT_Float: {
691 constant_float *cf = NEW(constant_float);
693 #if defined(ENABLE_STATISTICS)
695 count_const_pool_len += sizeof(constant_float);
698 if (!suck_check_classbuffer_size(cb, 4))
701 cf->value = suck_float(cb);
702 cptags[idx] = CONSTANT_Float;
709 case CONSTANT_Long: {
710 constant_long *cl = NEW(constant_long);
712 #if defined(ENABLE_STATISTICS)
714 count_const_pool_len += sizeof(constant_long);
717 if (!suck_check_classbuffer_size(cb, 8))
720 cl->value = suck_s8(cb);
721 cptags[idx] = CONSTANT_Long;
725 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
731 case CONSTANT_Double: {
732 constant_double *cd = NEW(constant_double);
734 #if defined(ENABLE_STATISTICS)
736 count_const_pool_len += sizeof(constant_double);
739 if (!suck_check_classbuffer_size(cb, 8))
742 cd->value = suck_double(cb);
743 cptags[idx] = CONSTANT_Double;
747 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
753 case CONSTANT_Utf8: {
756 /* number of bytes in the bytes array (not string-length) */
757 if (!suck_check_classbuffer_size(cb, 2))
760 length = suck_u2(cb);
761 cptags[idx] = CONSTANT_Utf8;
763 /* validate the string */
764 if (!suck_check_classbuffer_size(cb, length))
767 #ifdef ENABLE_VERIFIER
769 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
771 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
774 #endif /* ENABLE_VERIFIER */
775 /* insert utf-string into the utf-symboltable */
776 cpinfos[idx] = utf_new((char *) cb->pos, length);
778 /* skip bytes of the string (buffer size check above) */
779 suck_skip_nbytes(cb, length);
785 exceptions_throw_classformaterror(c, "Illegal constant pool type");
791 /* resolve entries in temporary structures */
793 while (forward_classes) {
794 utf *name = (utf*) class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
798 #ifdef ENABLE_VERIFIER
799 if (opt_verify && !is_valid_name_utf(name)) {
800 exceptions_throw_classformaterror(c, "Class reference with invalid name");
803 #endif /* ENABLE_VERIFIER */
805 /* add all class references to the descriptor_pool */
807 if (!descriptor_pool_add_class(descpool, name))
810 cptags[forward_classes->thisindex] = CONSTANT_Class;
812 /* the classref is created later */
813 cpinfos[forward_classes->thisindex] = name;
815 nfc = forward_classes;
816 forward_classes = forward_classes->next;
819 while (forward_strings) {
820 utf *text = (utf*) class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
825 /* resolve utf-string */
826 cptags[forward_strings->thisindex] = CONSTANT_String;
827 cpinfos[forward_strings->thisindex] = text;
829 nfs = forward_strings;
830 forward_strings = forward_strings->next;
833 while (forward_nameandtypes) {
834 constant_nameandtype *cn = NEW(constant_nameandtype);
836 #if defined(ENABLE_STATISTICS)
838 count_const_pool_len += sizeof(constant_nameandtype);
841 /* resolve simple name and descriptor */
842 cn->name = (utf*) class_getconstant(c,
843 forward_nameandtypes->name_index,
848 cn->descriptor = (utf*) class_getconstant(c,
849 forward_nameandtypes->sig_index,
854 #ifdef ENABLE_VERIFIER
857 if (!is_valid_name_utf(cn->name)) {
858 exceptions_throw_classformaterror(c,
859 "Illegal Field name \"%s\"",
865 /* disallow referencing <clinit> among others */
866 if (cn->name->text[0] == '<' && cn->name != utf_init) {
867 exceptions_throw_classformaterror(c, "Illegal reference to special method");
871 #endif /* ENABLE_VERIFIER */
873 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
874 cpinfos[forward_nameandtypes->thisindex] = cn;
876 nfn = forward_nameandtypes;
877 forward_nameandtypes = forward_nameandtypes->next;
880 while (forward_fieldmethints) {
881 constant_nameandtype *nat;
882 constant_FMIref *fmi = NEW(constant_FMIref);
884 #if defined(ENABLE_STATISTICS)
886 count_const_pool_len += sizeof(constant_FMIref);
888 /* resolve simple name and descriptor */
890 nat = (constant_nameandtype*) class_getconstant(c,
891 forward_fieldmethints->nameandtype_index,
892 CONSTANT_NameAndType);
897 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
899 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
902 /* the classref is created later */
904 fmi->p.index = forward_fieldmethints->class_index;
905 fmi->name = nat->name;
906 fmi->descriptor = nat->descriptor;
908 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
909 cpinfos[forward_fieldmethints->thisindex] = fmi;
911 nff = forward_fieldmethints;
912 forward_fieldmethints = forward_fieldmethints->next;
915 /* everything was ok */
921 /* loader_load_attribute_signature *********************************************
923 Signature_attribute {
924 u2 attribute_name_index;
929 *******************************************************************************/
931 #if defined(ENABLE_JAVASE)
932 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
942 /* check remaining bytecode */
944 if (!suck_check_classbuffer_size(cb, 4 + 2))
947 /* check attribute length */
949 attribute_length = suck_u4(cb);
951 if (attribute_length != 2) {
952 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
956 if (*signature != NULL) {
957 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
963 signature_index = suck_u2(cb);
965 *signature = (utf*) class_getconstant(c, signature_index, CONSTANT_Utf8);
967 if (*signature == NULL)
972 #endif /* defined(ENABLE_JAVASE) */
975 /* load_class_from_sysloader ***************************************************
977 Load the class with the given name using the system class loader
980 name.............the classname
984 NULL if an exception has been thrown
986 *******************************************************************************/
988 classinfo *load_class_from_sysloader(utf *name)
995 assert(class_java_lang_Object);
996 assert(class_java_lang_ClassLoader);
997 assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
999 m = class_resolveclassmethod(class_java_lang_ClassLoader,
1000 utf_getSystemClassLoader,
1001 utf_void__java_lang_ClassLoader,
1002 class_java_lang_Object,
1008 clo = vm_call_method(m, NULL);
1013 cl = loader_hashtable_classloader_add(clo);
1015 c = load_class_from_classloader(name, cl);
1021 /* load_class_from_classloader *************************************************
1023 Load the class with the given name using the given user-defined class loader.
1026 name.............the classname
1027 cl...............user-defined class loader
1030 the loaded class, or
1031 NULL if an exception has been thrown
1033 *******************************************************************************/
1035 classinfo *load_class_from_classloader(utf *name, classloader_t *cl)
1040 java_handle_t *string;
1041 #if defined(ENABLE_RT_TIMING)
1042 struct timespec time_start, time_lookup, time_prepare, time_java,
1046 RT_TIMING_GET_TIME(time_start);
1050 /* lookup if this class has already been loaded */
1052 c = classcache_lookup(cl, name);
1054 RT_TIMING_GET_TIME(time_lookup);
1055 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1060 /* if other class loader than bootstrap, call it */
1068 namelen = name->blength;
1070 /* handle array classes */
1071 if (text[0] == '[') {
1077 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1078 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1079 exceptions_throw_classnotfoundexception(name);
1083 u = utf_new(text + 2, namelen - 3);
1085 if (!(comp = load_class_from_classloader(u, cl)))
1088 /* create the array class */
1090 c = class_array_of(comp, false);
1092 tmpc = classcache_store(cl, c, true);
1095 /* exception, free the loaded class */
1096 c->state &= ~CLASS_LOADING;
1103 /* load the component class */
1105 u = utf_new(text + 1, namelen - 1);
1107 if (!(comp = load_class_from_classloader(u, cl)))
1110 /* create the array class */
1112 c = class_array_of(comp, false);
1114 tmpc = classcache_store(cl, c, true);
1117 /* exception, free the loaded class */
1118 c->state &= ~CLASS_LOADING;
1125 /* primitive array classes are loaded by the bootstrap loader */
1127 c = load_class_bootstrap(name);
1133 LLNI_class_get(cl, c);
1135 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1136 /* OpenJDK uses this internal function because it's
1139 lc = class_resolveclassmethod(c,
1140 utf_loadClassInternal,
1141 utf_java_lang_String__java_lang_Class,
1145 lc = class_resolveclassmethod(c,
1147 utf_java_lang_String__java_lang_Class,
1153 return false; /* exception */
1155 /* move return value into `o' and cast it afterwards to a classinfo* */
1157 string = javastring_new_slash_to_dot(name);
1159 RT_TIMING_GET_TIME(time_prepare);
1161 o = vm_call_method(lc, (java_handle_t *) cl, string);
1163 RT_TIMING_GET_TIME(time_java);
1165 c = LLNI_classinfo_unwrap(o);
1168 /* Store this class in the loaded class cache. If another
1169 class with the same (initloader,name) pair has been
1170 stored earlier it will be returned by classcache_store
1171 In this case classcache_store may not free the class
1172 because it has already been exposed to Java code which
1173 may have kept references to that class. */
1175 tmpc = classcache_store(cl, c, false);
1178 /* exception, free the loaded class */
1179 c->state &= ~CLASS_LOADING;
1186 RT_TIMING_GET_TIME(time_cache);
1188 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1189 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1190 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1192 /* SUN compatible -verbose:class output */
1194 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1196 utf_display_printable_ascii_classname(name);
1200 #if defined(ENABLE_JVMTI)
1201 /* fire Class Load JVMTI event */
1202 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1209 c = load_class_bootstrap(name);
1215 /* load_class_bootstrap ********************************************************
1217 Load the class with the given name using the bootstrap class loader.
1220 name.............the classname
1223 loaded classinfo, or
1224 NULL if an exception has been thrown
1227 load_class_bootstrap is synchronized. It can be treated as an
1230 *******************************************************************************/
1232 classinfo *load_class_bootstrap(utf *name)
1237 #if defined(ENABLE_RT_TIMING)
1238 struct timespec time_start, time_lookup, time_array, time_suck,
1239 time_load, time_cache;
1242 RT_TIMING_GET_TIME(time_start);
1248 /* lookup if this class has already been loaded */
1250 r = classcache_lookup(NULL, name);
1253 RT_TIMING_GET_TIME(time_lookup);
1254 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1259 RT_TIMING_GET_TIME(time_lookup);
1260 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1262 /* create the classinfo */
1264 c = class_create_classinfo(name);
1266 /* handle array classes */
1268 if (name->text[0] == '[') {
1269 c = load_newly_created_array(c, NULL);
1274 assert(c->state & CLASS_LOADED);
1276 RT_TIMING_GET_TIME(time_array);
1277 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1282 #if defined(ENABLE_STATISTICS)
1285 if (opt_getcompilingtime)
1286 compilingtime_stop();
1288 if (opt_getloadingtime)
1289 loadingtime_start();
1292 /* load classdata, throw exception on error */
1297 exceptions_throw_classnotfoundexception(name);
1301 RT_TIMING_GET_TIME(time_suck);
1303 /* load the class from the buffer */
1305 r = load_class_from_classbuffer(cb);
1307 RT_TIMING_GET_TIME(time_load);
1310 /* the class could not be loaded, free the classinfo struct */
1315 /* Store this class in the loaded class cache this step also
1316 checks the loading constraints. If the class has been
1317 loaded before, the earlier loaded class is returned. */
1319 classinfo *res = classcache_store(NULL, c, true);
1326 // Add the package name to the boot packages.
1327 Package::add(c->packagename);
1333 RT_TIMING_GET_TIME(time_cache);
1335 /* SUN compatible -verbose:class output */
1337 if (opt_verboseclass && r) {
1339 utf_display_printable_ascii_classname(name);
1340 printf(" from %s]\n", cb->path);
1347 #if defined(ENABLE_STATISTICS)
1350 if (opt_getloadingtime)
1353 if (opt_getcompilingtime)
1354 compilingtime_start();
1357 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1358 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1359 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1360 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1366 /* load_class_from_classbuffer_intern ******************************************
1368 Loads a class from a classbuffer into a given classinfo structure.
1369 Super-classes are also loaded at this point and some verfication
1373 This function is NOT synchronized!
1375 *******************************************************************************/
1377 static bool load_class_from_classbuffer_intern(classbuffer *cb)
1383 utf **interfacesnames;
1385 constant_classref *cr;
1389 descriptor_pool *descpool;
1390 #if defined(ENABLE_STATISTICS)
1394 #if defined(ENABLE_RT_TIMING)
1395 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1396 time_setup, time_fields, time_methods, time_classrefs,
1397 time_descs, time_setrefs, time_parsefds, time_parsemds,
1398 time_parsecpool, time_verify, time_attrs;
1401 // Create new dump memory area.
1404 RT_TIMING_GET_TIME(time_start);
1406 /* Get the classbuffer's class. */
1410 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1413 /* check signature */
1415 if (suck_u4(cb) != MAGIC) {
1416 exceptions_throw_classformaterror(c, "Bad magic number");
1425 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1426 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1430 RT_TIMING_GET_TIME(time_checks);
1432 /* create a new descriptor pool */
1434 descpool = descriptor_pool_new(c);
1436 RT_TIMING_GET_TIME(time_ndpool);
1438 /* load the constant pool */
1440 if (!load_constantpool(cb, descpool))
1443 RT_TIMING_GET_TIME(time_cpool);
1447 if (!suck_check_classbuffer_size(cb, 2))
1450 /* We OR the flags here, as we set already some flags in
1451 class_create_classinfo. */
1453 c->flags |= suck_u2(cb);
1455 /* check ACC flags consistency */
1457 if (c->flags & ACC_INTERFACE) {
1458 if (!(c->flags & ACC_ABSTRACT)) {
1459 /* We work around this because interfaces in JDK 1.1 are
1460 * not declared abstract. */
1462 c->flags |= ACC_ABSTRACT;
1465 if (c->flags & ACC_FINAL) {
1466 exceptions_throw_classformaterror(c,
1467 "Illegal class modifiers: 0x%X",
1472 if (c->flags & ACC_SUPER) {
1473 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1477 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1478 exceptions_throw_classformaterror(c,
1479 "Illegal class modifiers: 0x%X",
1484 if (!suck_check_classbuffer_size(cb, 2 + 2))
1489 index = suck_u2(cb);
1491 name = (utf *) class_getconstant(c, index, CONSTANT_Class);
1496 if (c->name == utf_not_named_yet) {
1497 /* we finally have a name for this class */
1499 class_set_packagename(c);
1501 else if (name != c->name) {
1502 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
1506 /* Retrieve superclass. */
1510 index = suck_u2(cb);
1515 /* This is only allowed for java.lang.Object. */
1517 if (c->name != utf_java_lang_Object) {
1518 exceptions_throw_classformaterror(c, "Bad superclass index");
1523 supername = (utf *) class_getconstant(c, index, CONSTANT_Class);
1525 if (supername == NULL)
1528 /* java.lang.Object may not have a super class. */
1530 if (c->name == utf_java_lang_Object) {
1531 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
1535 /* Detect circularity. */
1537 if (supername == c->name) {
1538 exceptions_throw_classcircularityerror(c);
1542 /* Interfaces must have java.lang.Object as super class. */
1544 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
1545 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
1550 /* Parse the super interfaces. */
1552 if (!suck_check_classbuffer_size(cb, 2))
1555 c->interfacescount = suck_u2(cb);
1557 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1560 c->interfaces = MNEW(classinfo*, c->interfacescount);
1562 /* Get the names of the super interfaces. */
1564 interfacesnames = (utf**) DumpMemory::allocate(sizeof(utf*) * c->interfacescount);
1566 for (int32_t i = 0; i < c->interfacescount; i++) {
1567 index = suck_u2(cb);
1569 u = (utf *) class_getconstant(c, index, CONSTANT_Class);
1574 interfacesnames[i] = u;
1577 RT_TIMING_GET_TIME(time_setup);
1581 if (!suck_check_classbuffer_size(cb, 2))
1584 c->fieldscount = suck_u2(cb);
1585 c->fields = MNEW(fieldinfo, c->fieldscount);
1587 MZERO(c->fields, fieldinfo, c->fieldscount);
1589 for (int32_t i = 0; i < c->fieldscount; i++) {
1590 if (!field_load(cb, &(c->fields[i]), descpool))
1594 RT_TIMING_GET_TIME(time_fields);
1596 /* Parse methods. */
1598 if (!suck_check_classbuffer_size(cb, 2))
1601 c->methodscount = suck_u2(cb);
1602 c->methods = MNEW(methodinfo, c->methodscount);
1604 MZERO(c->methods, methodinfo, c->methodscount);
1606 for (int32_t i = 0; i < c->methodscount; i++) {
1607 if (!method_load(cb, &(c->methods[i]), descpool))
1611 RT_TIMING_GET_TIME(time_methods);
1613 /* create the class reference table */
1616 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
1618 RT_TIMING_GET_TIME(time_classrefs);
1620 /* allocate space for the parsed descriptors */
1622 descriptor_pool_alloc_parsed_descriptors(descpool);
1623 c->parseddescs = (u1*) descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
1625 #if defined(ENABLE_STATISTICS)
1627 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
1628 count_classref_len += classrefsize;
1629 count_parsed_desc_len += descsize;
1633 RT_TIMING_GET_TIME(time_descs);
1635 /* put the classrefs in the constant pool */
1637 for (int32_t i = 0; i < c->cpcount; i++) {
1638 if (c->cptags[i] == CONSTANT_Class) {
1639 utf *name = (utf *) c->cpinfos[i];
1640 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
1644 /* Resolve the super class. */
1646 if (supername != NULL) {
1647 cr = descriptor_pool_lookup_classref(descpool, supername);
1652 /* XXX This should be done better. */
1653 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1656 resolve_handle_pending_exception(true);
1660 /* Interfaces are not allowed as super classes. */
1662 if (tc->flags & ACC_INTERFACE) {
1663 exceptions_throw_incompatibleclasschangeerror(c, "class %s has interface %s as super class");
1667 /* Don't allow extending final classes */
1669 if (tc->flags & ACC_FINAL) {
1670 exceptions_throw_verifyerror(NULL,
1671 "Cannot inherit from final class");
1675 /* Store the super class. */
1680 /* Resolve the super interfaces. */
1682 for (int32_t i = 0; i < c->interfacescount; i++) {
1683 u = interfacesnames[i];
1684 cr = descriptor_pool_lookup_classref(descpool, u);
1689 /* XXX This should be done better. */
1690 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1693 resolve_handle_pending_exception(true);
1697 /* Detect circularity. */
1700 exceptions_throw_classcircularityerror(c);
1704 if (!(tc->flags & ACC_INTERFACE)) {
1705 exceptions_throw_incompatibleclasschangeerror(tc,
1706 "Implementing class");
1710 /* Store the super interface. */
1712 c->interfaces[i] = tc;
1715 RT_TIMING_GET_TIME(time_setrefs);
1717 /* Parse the field descriptors. */
1719 for (int32_t i = 0; i < c->fieldscount; i++) {
1720 c->fields[i].parseddesc =
1721 descriptor_pool_parse_field_descriptor(descpool,
1722 c->fields[i].descriptor);
1723 if (!c->fields[i].parseddesc)
1727 RT_TIMING_GET_TIME(time_parsefds);
1729 /* parse method descriptors */
1731 for (int32_t i = 0; i < c->methodscount; i++) {
1732 methodinfo *m = &c->methods[i];
1734 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
1735 m->flags, class_get_self_classref(m->clazz));
1739 for (int32_t j = 0; j < m->rawexceptiontablelength; j++) {
1740 if (!m->rawexceptiontable[j].catchtype.any)
1743 if ((m->rawexceptiontable[j].catchtype.ref =
1744 descriptor_pool_lookup_classref(descpool,
1745 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
1749 for (int32_t j = 0; j < m->thrownexceptionscount; j++) {
1750 if (!m->thrownexceptions[j].any)
1753 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
1754 (utf *) m->thrownexceptions[j].any)) == NULL)
1759 RT_TIMING_GET_TIME(time_parsemds);
1761 /* parse the loaded descriptors */
1763 for (int32_t i = 0; i < c->cpcount; i++) {
1764 constant_FMIref *fmi;
1767 switch (c->cptags[i]) {
1768 case CONSTANT_Fieldref:
1769 fmi = (constant_FMIref *) c->cpinfos[i];
1770 fmi->parseddesc.fd =
1771 descriptor_pool_parse_field_descriptor(descpool,
1773 if (!fmi->parseddesc.fd)
1776 index = fmi->p.index;
1778 (constant_classref *) class_getconstant(c, index,
1780 if (!fmi->p.classref)
1783 case CONSTANT_Methodref:
1784 case CONSTANT_InterfaceMethodref:
1785 fmi = (constant_FMIref *) c->cpinfos[i];
1786 index = fmi->p.index;
1788 (constant_classref *) class_getconstant(c, index,
1790 if (!fmi->p.classref)
1792 fmi->parseddesc.md =
1793 descriptor_pool_parse_method_descriptor(descpool,
1797 if (!fmi->parseddesc.md)
1803 RT_TIMING_GET_TIME(time_parsecpool);
1805 #ifdef ENABLE_VERIFIER
1806 /* Check if all fields and methods can be uniquely
1807 * identified by (name,descriptor). */
1810 /* We use a hash table here to avoid making the
1811 * average case quadratic in # of methods, fields.
1813 static int shift = 0;
1815 u2 *next; /* for chaining colliding hash entries */
1821 /* Allocate hashtable */
1822 len = c->methodscount;
1823 if (len < c->fieldscount) len = c->fieldscount;
1825 hashtab = MNEW(u2,(hashlen + len));
1826 next = hashtab + hashlen;
1828 /* Determine bitshift (to get good hash values) */
1838 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
1840 for (int32_t i = 0; i < c->fieldscount; ++i) {
1841 fieldinfo *fi = c->fields + i;
1843 /* It's ok if we lose bits here */
1844 index = ((((size_t) fi->name) +
1845 ((size_t) fi->descriptor)) >> shift) % hashlen;
1847 if ((old = hashtab[index])) {
1851 if (c->fields[old].name == fi->name &&
1852 c->fields[old].descriptor == fi->descriptor) {
1853 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
1856 } while ((old = next[old]));
1858 hashtab[index] = i + 1;
1862 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
1864 for (int32_t i = 0; i < c->methodscount; ++i) {
1865 methodinfo *mi = c->methods + i;
1867 /* It's ok if we lose bits here */
1868 index = ((((size_t) mi->name) +
1869 ((size_t) mi->descriptor)) >> shift) % hashlen;
1871 if ((old = hashtab[index])) {
1875 if (c->methods[old].name == mi->name &&
1876 c->methods[old].descriptor == mi->descriptor) {
1877 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
1880 } while ((old = next[old]));
1882 hashtab[index] = i + 1;
1885 MFREE(hashtab, u2, (hashlen + len));
1887 #endif /* ENABLE_VERIFIER */
1889 RT_TIMING_GET_TIME(time_verify);
1891 #if defined(ENABLE_STATISTICS)
1893 size_classinfo += sizeof(classinfo*) * c->interfacescount;
1894 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
1895 size_methodinfo += sizeof(methodinfo) * c->methodscount;
1899 /* load attribute structures */
1901 if (!class_load_attributes(cb))
1904 /* Pre Java 1.5 version don't check this. This implementation is
1905 like Java 1.5 do it: for class file version 45.3 we don't check
1906 it, older versions are checked. */
1908 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
1909 /* check if all data has been read */
1910 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
1912 if (classdata_left > 0) {
1913 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
1918 RT_TIMING_GET_TIME(time_attrs);
1920 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
1921 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
1922 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
1923 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
1924 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
1925 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
1926 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
1927 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
1928 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
1929 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
1930 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
1931 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
1932 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
1933 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
1934 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
1940 /* load_class_from_classbuffer *************************************************
1942 Convenience wrapper for load_class_from_classbuffer.
1945 This function is NOT synchronized!
1947 *******************************************************************************/
1949 classinfo *load_class_from_classbuffer(classbuffer *cb)
1954 /* Get the classbuffer's class. */
1958 /* Check if the class is already loaded. */
1960 if (c->state & CLASS_LOADED)
1963 #if defined(ENABLE_STATISTICS)
1965 count_class_loads++;
1968 #if !defined(NDEBUG)
1970 log_message_class("Loading class: ", c);
1973 /* Class is currently loading. */
1975 c->state |= CLASS_LOADING;
1977 /* Parse the classbuffer. */
1979 result = load_class_from_classbuffer_intern(cb);
1981 /* An error occurred. */
1983 if (result == false) {
1984 /* Revert loading state. */
1986 c->state = (c->state & ~CLASS_LOADING);
1991 /* Revert loading state and set loaded. */
1993 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
1995 #if defined(ENABLE_JVMTI)
1996 /* fire Class Prepare JVMTI event */
1999 jvmti_ClassLoadPrepare(true, c);
2002 #if !defined(NDEBUG)
2004 log_message_class("Loading done class: ", c);
2011 /* load_newly_created_array ****************************************************
2013 Load a newly created array class.
2016 c....................the array class C has been loaded
2017 other classinfo......the array class was found in the class cache,
2019 NULL.................an exception has been thrown
2022 This is an internal function. Do not use it unless you know exactly
2025 Use one of the load_class_... functions for general array class loading.
2027 *******************************************************************************/
2029 classinfo *load_newly_created_array(classinfo *c, classloader_t *loader)
2031 classinfo *comp = NULL;
2033 methoddesc *clonedesc;
2034 constant_classref *classrefs;
2039 text = c->name->text;
2040 namelen = c->name->blength;
2042 /* Check array class name */
2044 if ((namelen < 2) || (text[0] != '[')) {
2045 exceptions_throw_classnotfoundexception(c->name);
2049 /* Check the element type */
2053 /* c is an array of arrays. We have to create the component class. */
2055 u = utf_new(text + 1, namelen - 1);
2057 comp = load_class_from_classloader(u, loader);
2062 assert(comp->state & CLASS_LOADED);
2064 /* the array's flags are that of the component class */
2065 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2066 c->classloader = comp->classloader;
2070 /* c is an array of objects. */
2072 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2073 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2074 exceptions_throw_classnotfoundexception(c->name);
2078 u = utf_new(text + 2, namelen - 3);
2080 if (!(comp = load_class_from_classloader(u, loader)))
2083 assert(comp->state & CLASS_LOADED);
2085 /* the array's flags are that of the component class */
2086 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2087 c->classloader = comp->classloader;
2091 /* c is an array of a primitive type */
2093 /* check for cases like `[II' and whether the character is a
2094 valid primitive type */
2096 if ((namelen > 2) || (Primitive::get_class_by_char(text[1]) == NULL)) {
2097 exceptions_throw_classnotfoundexception(c->name);
2101 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2102 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2103 c->classloader = NULL;
2106 assert(class_java_lang_Object);
2107 #if defined(ENABLE_JAVASE)
2108 assert(class_java_lang_Cloneable);
2109 assert(class_java_io_Serializable);
2112 /* Setup the array class. */
2114 c->super = class_java_lang_Object;
2116 #if defined(ENABLE_JAVASE)
2118 c->interfacescount = 2;
2119 c->interfaces = MNEW(classinfo*, 2);
2120 c->interfaces[0] = class_java_lang_Cloneable;
2121 c->interfaces[1] = class_java_io_Serializable;
2123 #elif defined(ENABLE_JAVAME_CLDC1_1)
2125 c->interfacescount = 0;
2126 c->interfaces = NULL;
2129 # error unknow Java configuration
2132 c->methodscount = 1;
2133 c->methods = MNEW(methodinfo, c->methodscount);
2135 MZERO(c->methods, methodinfo, c->methodscount);
2137 classrefs = MNEW(constant_classref, 2);
2139 CLASSREF_INIT(classrefs[0], c, c->name);
2140 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2142 /* create descriptor for clone method */
2143 /* we need one paramslot which is reserved for the 'this' parameter */
2144 clonedesc = NEW(methoddesc);
2145 clonedesc->returntype.type = TYPE_ADR;
2146 clonedesc->returntype.classref = classrefs + 1;
2147 clonedesc->returntype.arraydim = 0;
2148 /* initialize params to "empty", add real params below in
2149 descriptor_params_from_paramtypes */
2150 clonedesc->paramcount = 0;
2151 clonedesc->paramslots = 0;
2152 clonedesc->paramtypes[0].classref = classrefs + 0;
2153 clonedesc->params = NULL;
2155 /* create methodinfo */
2158 MSET(clone, 0, methodinfo, 1);
2160 /* ATTENTION: if you delete the ACC_NATIVE below, set
2161 clone->maxlocals=1 (interpreter related) */
2163 clone->mutex = new Mutex();
2164 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2165 clone->name = utf_clone;
2166 clone->descriptor = utf_void__java_lang_Object;
2167 clone->parseddesc = clonedesc;
2170 /* parse the descriptor to get the register allocation */
2172 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2175 clone->code = NativeStub::generate(clone, BUILTIN_clone);
2177 /* XXX: field: length? */
2179 /* array classes are not loaded from class files */
2181 c->state |= CLASS_LOADED;
2182 c->parseddescs = (u1 *) clonedesc;
2183 c->parseddescsize = sizeof(methodinfo);
2184 c->classrefs = classrefs;
2185 c->classrefcount = 1;
2187 /* insert class into the loaded class cache */
2188 /* XXX free classinfo if NULL returned? */
2190 return classcache_store(loader, c, true);
2194 /* loader_close ****************************************************************
2196 Frees all resources.
2198 *******************************************************************************/
2200 void loader_close(void)
2207 * These are local overrides for various environment variables in Emacs.
2208 * Please do not remove this and leave it at the end of the file, where
2209 * Emacs will automagically detect them.
2210 * ---------------------------------------------------------------------
2213 * indent-tabs-mode: t
2217 * vim:noexpandtab:sw=4:ts=4: