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/lock-common.h"
40 #include "threads/mutex.hpp"
42 #include "toolbox/hashtable.h"
43 #include "toolbox/logging.h"
45 #include "vm/jit/builtin.hpp"
46 #include "vm/classcache.h"
47 #include "vm/exceptions.hpp"
49 #include "vm/global.h"
50 #include "vm/globals.hpp"
51 #include "vm/linker.h"
52 #include "vm/loader.hpp"
53 #include "vm/method.h"
54 #include "vm/options.h"
55 #include "vm/package.hpp"
56 #include "vm/primitive.hpp"
57 #include "vm/resolve.h"
58 #include "vm/rt-timing.h"
59 #include "vm/string.hpp"
64 #if defined(ENABLE_JAVASE)
65 # include "vm/annotation.h"
66 # include "vm/stackmap.h"
69 #if defined(ENABLE_STATISTICS)
70 # include "vm/statistics.h"
73 #if defined(ENABLE_ZLIB)
77 #include "vm/jit/stubs.hpp"
79 #if defined(ENABLE_JVMTI)
80 # include "native/jvmti/cacaodbg.h"
84 /* global variables ***********************************************************/
86 static hashtable *hashtable_classloader;
89 /* loader_preinit **************************************************************
91 Initializes the classpath list and loads classes required for the
94 NOTE: Exceptions thrown during VM initialization are caught in the
95 exception functions themselves.
97 *******************************************************************************/
99 void loader_preinit(void)
101 #if defined(ENABLE_THREADS)
102 list_classpath_entry *lce;
105 TRACESUBSYSTEMINITIALIZATION("loader_preinit");
107 #if defined(ENABLE_THREADS)
108 /* Initialize the monitor pointer for zip/jar file locking. */
110 for (lce = (list_classpath_entry*) list_first(list_classpath_entries); lce != NULL;
111 lce = (list_classpath_entry*) list_next(list_classpath_entries, lce)) {
112 if (lce->type == CLASSPATH_ARCHIVE)
113 LOCK_INIT_OBJECT_LOCK(lce);
117 /* initialize classloader hashtable, 10 entries should be enough */
119 hashtable_classloader = NEW(hashtable);
120 hashtable_create(hashtable_classloader, 10);
122 /* Load the most basic classes. */
124 assert(VM::get_current()->is_initializing() == true);
126 class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object);
128 #if defined(ENABLE_JAVASE)
129 class_java_lang_Cloneable = load_class_bootstrap(utf_java_lang_Cloneable);
130 class_java_io_Serializable = load_class_bootstrap(utf_java_io_Serializable);
135 /* loader_init *****************************************************************
137 Loads all classes required in the VM.
139 NOTE: Exceptions thrown during VM initialization are caught in the
140 exception functions themselves.
142 *******************************************************************************/
144 void loader_init(void)
146 TRACESUBSYSTEMINITIALIZATION("loader_init");
148 /* Load primitive-type wrapping classes. */
150 assert(VM::get_current()->is_initializing() == true);
152 #if defined(ENABLE_JAVASE)
153 class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void);
156 class_java_lang_Boolean = load_class_bootstrap(utf_java_lang_Boolean);
157 class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte);
158 class_java_lang_Character = load_class_bootstrap(utf_java_lang_Character);
159 class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short);
160 class_java_lang_Integer = load_class_bootstrap(utf_java_lang_Integer);
161 class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long);
162 class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float);
163 class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double);
165 /* Load important system classes. */
167 class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class);
168 class_java_lang_String = load_class_bootstrap(utf_java_lang_String);
170 #if defined(ENABLE_JAVASE)
171 class_java_lang_ClassLoader =
172 load_class_bootstrap(utf_java_lang_ClassLoader);
174 class_java_lang_SecurityManager =
175 load_class_bootstrap(utf_java_lang_SecurityManager);
178 class_java_lang_System =
179 load_class_bootstrap(utf_new_char("java/lang/System"));
181 class_java_lang_Thread =
182 load_class_bootstrap(utf_new_char("java/lang/Thread"));
184 #if defined(ENABLE_JAVASE)
185 class_java_lang_ThreadGroup =
186 load_class_bootstrap(utf_java_lang_ThreadGroup);
189 class_java_lang_Throwable = load_class_bootstrap(utf_java_lang_Throwable);
191 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
192 class_java_lang_VMSystem =
193 load_class_bootstrap(utf_new_char("java/lang/VMSystem"));
195 class_java_lang_VMThread =
196 load_class_bootstrap(utf_new_char("java/lang/VMThread"));
198 class_java_lang_VMThrowable =
199 load_class_bootstrap(utf_new_char("java/lang/VMThrowable"));
202 /* Important system exceptions. */
204 class_java_lang_Exception = load_class_bootstrap(utf_java_lang_Exception);
206 class_java_lang_ClassNotFoundException =
207 load_class_bootstrap(utf_java_lang_ClassNotFoundException);
209 class_java_lang_RuntimeException =
210 load_class_bootstrap(utf_java_lang_RuntimeException);
212 /* Some classes which may be used often. */
214 #if defined(ENABLE_JAVASE)
215 class_java_lang_StackTraceElement = load_class_bootstrap(utf_java_lang_StackTraceElement);
217 class_java_lang_reflect_Constructor = load_class_bootstrap(utf_java_lang_reflect_Constructor);
218 class_java_lang_reflect_Field = load_class_bootstrap(utf_java_lang_reflect_Field);
219 class_java_lang_reflect_Method = load_class_bootstrap(utf_java_lang_reflect_Method);
221 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
222 class_java_lang_reflect_VMConstructor = load_class_bootstrap(utf_java_lang_reflect_VMConstructor);
223 class_java_lang_reflect_VMField = load_class_bootstrap(utf_java_lang_reflect_VMField);
224 class_java_lang_reflect_VMMethod = load_class_bootstrap(utf_java_lang_reflect_VMMethod);
227 class_java_security_PrivilegedAction = load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"));
229 class_java_util_HashMap = load_class_bootstrap(utf_new_char("java/util/HashMap"));
230 class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector);
232 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
233 class_sun_misc_Signal = load_class_bootstrap(utf_new_char("sun/misc/Signal"));
234 class_sun_reflect_MagicAccessorImpl = load_class_bootstrap(utf_new_char("sun/reflect/MagicAccessorImpl"));
237 arrayclass_java_lang_Object =
238 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"));
240 # if defined(ENABLE_ANNOTATIONS)
241 /* needed by annotation support */
242 class_sun_reflect_ConstantPool =
243 load_class_bootstrap(utf_new_char("sun/reflect/ConstantPool"));
245 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
246 /* needed by GNU Classpaths annotation support */
247 class_sun_reflect_annotation_AnnotationParser =
248 load_class_bootstrap(utf_new_char("sun/reflect/annotation/AnnotationParser"));
255 /* loader_hashtable_classloader_add ********************************************
257 Adds an entry to the classloader hashtable.
259 REMEMBER: Also use this to register native loaders!
261 *******************************************************************************/
263 classloader_t *loader_hashtable_classloader_add(java_handle_t *cl)
265 hashtable_classloader_entry *cle;
272 hashtable_classloader->mutex->lock();
276 /* key for entry is the hashcode of the classloader;
277 aligned to 16-byte boundaries */
279 key = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
280 slot = key & (hashtable_classloader->size - 1);
281 cle = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
283 /* search hashchain for existing entry */
286 if (cle->object == LLNI_DIRECT(cl))
294 /* if no classloader was found, we create a new entry here */
297 cle = NEW(hashtable_classloader_entry);
299 #if defined(ENABLE_GC_CACAO)
300 /* register the classloader object with the GC */
302 gc_reference_register(&(cle->object), GC_REFTYPE_CLASSLOADER);
307 cle->object = LLNI_DIRECT(cl);
311 /*#define LOADER_DEBUG_CLASSLOADER*/
312 #ifdef LOADER_DEBUG_CLASSLOADER
313 printf("CLASSLOADER: adding new classloader entry %p for %p: ", cle, cl);
314 class_print(LLNI_vftbl_direct(cl)->class);
319 /* insert entry into hashtable */
321 cle->hashlink = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
322 hashtable_classloader->ptr[slot] = cle;
324 /* update number of entries */
326 hashtable_classloader->entries++;
329 hashtable_classloader->mutex->unlock();
331 #if defined(ENABLE_HANDLES)
339 /* loader_hashtable_classloader_find *******************************************
341 Find an entry in the classloader hashtable.
343 *******************************************************************************/
345 classloader_t *loader_hashtable_classloader_find(java_handle_t *cl)
347 hashtable_classloader_entry *cle;
356 /* key for entry is the hashcode of the classloader;
357 aligned to 16-byte boundaries */
359 key = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
360 slot = key & (hashtable_classloader->size - 1);
361 cle = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
363 /* search hashchain for existing entry */
366 if (cle->object == LLNI_DIRECT(cl))
372 #ifdef LOADER_DEBUG_CLASSLOADER
374 printf("CLASSLOADER: unable to find classloader entry for %p: ", cl);
375 class_print(LLNI_vftbl_direct(cl)->class);
383 #if defined(ENABLE_HANDLES)
391 /* loader_load_all_classes *****************************************************
393 Loads all classes specified in the BOOTCLASSPATH.
395 *******************************************************************************/
397 void loader_load_all_classes(void)
399 list_classpath_entry *lce;
400 #if defined(ENABLE_ZLIB)
402 hashtable_zipfile_entry *htzfe;
406 for (lce = (list_classpath_entry*) list_first(list_classpath_entries); lce != NULL;
407 lce = (list_classpath_entry*) list_next(list_classpath_entries, lce)) {
408 #if defined(ENABLE_ZLIB)
409 if (lce->type == CLASSPATH_ARCHIVE) {
410 /* get the classes hashtable */
414 for (uint32_t slot = 0; slot < ht->size; slot++) {
415 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
417 for (; htzfe; htzfe = htzfe->hashlink) {
420 /* skip all entries in META-INF and .properties,
423 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
424 strstr(u->text, ".properties") ||
425 strstr(u->text, ".png"))
428 /* load class from bootstrap classloader */
430 if (!load_class_bootstrap(u)) {
431 fprintf(stderr, "Error loading: ");
432 utf_fprint_printable_ascii_classname(stderr, u);
433 fprintf(stderr, "\n");
436 /* print out exception and cause */
438 exceptions_print_current_exception();
446 #if defined(ENABLE_ZLIB)
453 /* loader_skip_attribute_body **************************************************
455 Skips an attribute the attribute_name_index has already been read.
458 u2 attribute_name_index;
460 u1 info[attribute_length];
463 *******************************************************************************/
465 bool loader_skip_attribute_body(classbuffer *cb)
469 if (!suck_check_classbuffer_size(cb, 4))
472 attribute_length = suck_u4(cb);
474 if (!suck_check_classbuffer_size(cb, attribute_length))
477 suck_skip_nbytes(cb, attribute_length);
483 /* load_constantpool ***********************************************************
485 Loads the constantpool of a class, the entries are transformed into
486 a simpler format by resolving references (a detailed overview of
487 the compact structures can be found in global.h).
489 *******************************************************************************/
491 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
494 /* The following structures are used to save information which cannot be
495 processed during the first pass. After the complete constantpool has
496 been traversed the references can be resolved.
497 (only in specific order) */
499 /* CONSTANT_Class entries */
500 typedef struct forward_class {
501 struct forward_class *next;
506 /* CONSTANT_String */
507 typedef struct forward_string {
508 struct forward_string *next;
513 /* CONSTANT_NameAndType */
514 typedef struct forward_nameandtype {
515 struct forward_nameandtype *next;
519 } forward_nameandtype;
521 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
522 typedef struct forward_fieldmethint {
523 struct forward_fieldmethint *next;
527 u2 nameandtype_index;
528 } forward_fieldmethint;
534 forward_class *forward_classes = NULL;
535 forward_string *forward_strings = NULL;
536 forward_nameandtype *forward_nameandtypes = NULL;
537 forward_fieldmethint *forward_fieldmethints = NULL;
541 forward_nameandtype *nfn;
542 forward_fieldmethint *nff;
550 /* number of entries in the constant_pool table plus one */
551 if (!suck_check_classbuffer_size(cb, 2))
554 cpcount = c->cpcount = suck_u2(cb);
556 /* allocate memory */
557 cptags = c->cptags = MNEW(u1, cpcount);
558 cpinfos = c->cpinfos = MNEW(void*, cpcount);
561 exceptions_throw_classformaterror(c, "Illegal constant pool size");
565 #if defined(ENABLE_STATISTICS)
567 count_const_pool_len += (sizeof(u1) + sizeof(void*)) * cpcount;
570 /* initialize constantpool */
571 for (idx = 0; idx < cpcount; idx++) {
572 cptags[idx] = CONSTANT_UNUSED;
577 /******* first pass *******/
578 /* entries which cannot be resolved now are written into
579 temporary structures and traversed again later */
582 while (idx < cpcount) {
585 /* get constant type */
586 if (!suck_check_classbuffer_size(cb, 1))
594 nfc = (forward_class*) DumpMemory::allocate(sizeof(forward_class));
596 nfc->next = forward_classes;
597 forward_classes = nfc;
599 nfc->thisindex = idx;
600 /* reference to CONSTANT_NameAndType */
601 if (!suck_check_classbuffer_size(cb, 2))
604 nfc->name_index = suck_u2(cb);
609 case CONSTANT_String:
611 nfs = (forward_string*) DumpMemory::allocate(sizeof(forward_string));
613 nfs->next = forward_strings;
614 forward_strings = nfs;
616 nfs->thisindex = idx;
618 /* reference to CONSTANT_Utf8_info with string characters */
619 if (!suck_check_classbuffer_size(cb, 2))
622 nfs->string_index = suck_u2(cb);
627 case CONSTANT_NameAndType:
629 nfn = (forward_nameandtype*) DumpMemory::allocate(sizeof(forward_nameandtype));
631 nfn->next = forward_nameandtypes;
632 forward_nameandtypes = nfn;
634 nfn->thisindex = idx;
636 if (!suck_check_classbuffer_size(cb, 2 + 2))
639 /* reference to CONSTANT_Utf8_info containing simple name */
640 nfn->name_index = suck_u2(cb);
642 /* reference to CONSTANT_Utf8_info containing field or method
644 nfn->sig_index = suck_u2(cb);
649 case CONSTANT_Fieldref:
650 case CONSTANT_Methodref:
651 case CONSTANT_InterfaceMethodref:
653 nff = (forward_fieldmethint*) DumpMemory::allocate(sizeof(forward_fieldmethint));
655 nff->next = forward_fieldmethints;
656 forward_fieldmethints = nff;
658 nff->thisindex = idx;
662 if (!suck_check_classbuffer_size(cb, 2 + 2))
665 /* class or interface type that contains the declaration of the
667 nff->class_index = suck_u2(cb);
669 /* name and descriptor of the field or method */
670 nff->nameandtype_index = suck_u2(cb);
675 case CONSTANT_Integer: {
676 constant_integer *ci = NEW(constant_integer);
678 #if defined(ENABLE_STATISTICS)
680 count_const_pool_len += sizeof(constant_integer);
683 if (!suck_check_classbuffer_size(cb, 4))
686 ci->value = suck_s4(cb);
687 cptags[idx] = CONSTANT_Integer;
694 case CONSTANT_Float: {
695 constant_float *cf = NEW(constant_float);
697 #if defined(ENABLE_STATISTICS)
699 count_const_pool_len += sizeof(constant_float);
702 if (!suck_check_classbuffer_size(cb, 4))
705 cf->value = suck_float(cb);
706 cptags[idx] = CONSTANT_Float;
713 case CONSTANT_Long: {
714 constant_long *cl = NEW(constant_long);
716 #if defined(ENABLE_STATISTICS)
718 count_const_pool_len += sizeof(constant_long);
721 if (!suck_check_classbuffer_size(cb, 8))
724 cl->value = suck_s8(cb);
725 cptags[idx] = CONSTANT_Long;
729 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
735 case CONSTANT_Double: {
736 constant_double *cd = NEW(constant_double);
738 #if defined(ENABLE_STATISTICS)
740 count_const_pool_len += sizeof(constant_double);
743 if (!suck_check_classbuffer_size(cb, 8))
746 cd->value = suck_double(cb);
747 cptags[idx] = CONSTANT_Double;
751 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
757 case CONSTANT_Utf8: {
760 /* number of bytes in the bytes array (not string-length) */
761 if (!suck_check_classbuffer_size(cb, 2))
764 length = suck_u2(cb);
765 cptags[idx] = CONSTANT_Utf8;
767 /* validate the string */
768 if (!suck_check_classbuffer_size(cb, length))
771 #ifdef ENABLE_VERIFIER
773 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
775 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
778 #endif /* ENABLE_VERIFIER */
779 /* insert utf-string into the utf-symboltable */
780 cpinfos[idx] = utf_new((char *) cb->pos, length);
782 /* skip bytes of the string (buffer size check above) */
783 suck_skip_nbytes(cb, length);
789 exceptions_throw_classformaterror(c, "Illegal constant pool type");
795 /* resolve entries in temporary structures */
797 while (forward_classes) {
798 utf *name = (utf*) class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
802 #ifdef ENABLE_VERIFIER
803 if (opt_verify && !is_valid_name_utf(name)) {
804 exceptions_throw_classformaterror(c, "Class reference with invalid name");
807 #endif /* ENABLE_VERIFIER */
809 /* add all class references to the descriptor_pool */
811 if (!descriptor_pool_add_class(descpool, name))
814 cptags[forward_classes->thisindex] = CONSTANT_Class;
816 /* the classref is created later */
817 cpinfos[forward_classes->thisindex] = name;
819 nfc = forward_classes;
820 forward_classes = forward_classes->next;
823 while (forward_strings) {
824 utf *text = (utf*) class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
829 /* resolve utf-string */
830 cptags[forward_strings->thisindex] = CONSTANT_String;
831 cpinfos[forward_strings->thisindex] = text;
833 nfs = forward_strings;
834 forward_strings = forward_strings->next;
837 while (forward_nameandtypes) {
838 constant_nameandtype *cn = NEW(constant_nameandtype);
840 #if defined(ENABLE_STATISTICS)
842 count_const_pool_len += sizeof(constant_nameandtype);
845 /* resolve simple name and descriptor */
846 cn->name = (utf*) class_getconstant(c,
847 forward_nameandtypes->name_index,
852 cn->descriptor = (utf*) class_getconstant(c,
853 forward_nameandtypes->sig_index,
858 #ifdef ENABLE_VERIFIER
861 if (!is_valid_name_utf(cn->name)) {
862 exceptions_throw_classformaterror(c,
863 "Illegal Field name \"%s\"",
869 /* disallow referencing <clinit> among others */
870 if (cn->name->text[0] == '<' && cn->name != utf_init) {
871 exceptions_throw_classformaterror(c, "Illegal reference to special method");
875 #endif /* ENABLE_VERIFIER */
877 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
878 cpinfos[forward_nameandtypes->thisindex] = cn;
880 nfn = forward_nameandtypes;
881 forward_nameandtypes = forward_nameandtypes->next;
884 while (forward_fieldmethints) {
885 constant_nameandtype *nat;
886 constant_FMIref *fmi = NEW(constant_FMIref);
888 #if defined(ENABLE_STATISTICS)
890 count_const_pool_len += sizeof(constant_FMIref);
892 /* resolve simple name and descriptor */
894 nat = (constant_nameandtype*) class_getconstant(c,
895 forward_fieldmethints->nameandtype_index,
896 CONSTANT_NameAndType);
901 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
903 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
906 /* the classref is created later */
908 fmi->p.index = forward_fieldmethints->class_index;
909 fmi->name = nat->name;
910 fmi->descriptor = nat->descriptor;
912 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
913 cpinfos[forward_fieldmethints->thisindex] = fmi;
915 nff = forward_fieldmethints;
916 forward_fieldmethints = forward_fieldmethints->next;
919 /* everything was ok */
925 /* loader_load_attribute_signature *********************************************
927 Signature_attribute {
928 u2 attribute_name_index;
933 *******************************************************************************/
935 #if defined(ENABLE_JAVASE)
936 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
946 /* check remaining bytecode */
948 if (!suck_check_classbuffer_size(cb, 4 + 2))
951 /* check attribute length */
953 attribute_length = suck_u4(cb);
955 if (attribute_length != 2) {
956 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
960 if (*signature != NULL) {
961 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
967 signature_index = suck_u2(cb);
969 *signature = (utf*) class_getconstant(c, signature_index, CONSTANT_Utf8);
971 if (*signature == NULL)
976 #endif /* defined(ENABLE_JAVASE) */
979 /* load_class_from_sysloader ***************************************************
981 Load the class with the given name using the system class loader
984 name.............the classname
988 NULL if an exception has been thrown
990 *******************************************************************************/
992 classinfo *load_class_from_sysloader(utf *name)
999 assert(class_java_lang_Object);
1000 assert(class_java_lang_ClassLoader);
1001 assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
1003 m = class_resolveclassmethod(class_java_lang_ClassLoader,
1004 utf_getSystemClassLoader,
1005 utf_void__java_lang_ClassLoader,
1006 class_java_lang_Object,
1012 clo = vm_call_method(m, NULL);
1017 cl = loader_hashtable_classloader_add(clo);
1019 c = load_class_from_classloader(name, cl);
1025 /* load_class_from_classloader *************************************************
1027 Load the class with the given name using the given user-defined class loader.
1030 name.............the classname
1031 cl...............user-defined class loader
1034 the loaded class, or
1035 NULL if an exception has been thrown
1037 *******************************************************************************/
1039 classinfo *load_class_from_classloader(utf *name, classloader_t *cl)
1044 java_handle_t *string;
1045 #if defined(ENABLE_RT_TIMING)
1046 struct timespec time_start, time_lookup, time_prepare, time_java,
1050 RT_TIMING_GET_TIME(time_start);
1054 /* lookup if this class has already been loaded */
1056 c = classcache_lookup(cl, name);
1058 RT_TIMING_GET_TIME(time_lookup);
1059 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1064 /* if other class loader than bootstrap, call it */
1072 namelen = name->blength;
1074 /* handle array classes */
1075 if (text[0] == '[') {
1081 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1082 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1083 exceptions_throw_classnotfoundexception(name);
1087 u = utf_new(text + 2, namelen - 3);
1089 if (!(comp = load_class_from_classloader(u, cl)))
1092 /* create the array class */
1094 c = class_array_of(comp, false);
1096 tmpc = classcache_store(cl, c, true);
1099 /* exception, free the loaded class */
1100 c->state &= ~CLASS_LOADING;
1107 /* load the component class */
1109 u = utf_new(text + 1, namelen - 1);
1111 if (!(comp = load_class_from_classloader(u, cl)))
1114 /* create the array class */
1116 c = class_array_of(comp, false);
1118 tmpc = classcache_store(cl, c, true);
1121 /* exception, free the loaded class */
1122 c->state &= ~CLASS_LOADING;
1129 /* primitive array classes are loaded by the bootstrap loader */
1131 c = load_class_bootstrap(name);
1137 LLNI_class_get(cl, c);
1139 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1140 /* OpenJDK uses this internal function because it's
1143 lc = class_resolveclassmethod(c,
1144 utf_loadClassInternal,
1145 utf_java_lang_String__java_lang_Class,
1149 lc = class_resolveclassmethod(c,
1151 utf_java_lang_String__java_lang_Class,
1157 return false; /* exception */
1159 /* move return value into `o' and cast it afterwards to a classinfo* */
1161 string = javastring_new_slash_to_dot(name);
1163 RT_TIMING_GET_TIME(time_prepare);
1165 o = vm_call_method(lc, (java_handle_t *) cl, string);
1167 RT_TIMING_GET_TIME(time_java);
1169 c = LLNI_classinfo_unwrap(o);
1172 /* Store this class in the loaded class cache. If another
1173 class with the same (initloader,name) pair has been
1174 stored earlier it will be returned by classcache_store
1175 In this case classcache_store may not free the class
1176 because it has already been exposed to Java code which
1177 may have kept references to that class. */
1179 tmpc = classcache_store(cl, c, false);
1182 /* exception, free the loaded class */
1183 c->state &= ~CLASS_LOADING;
1190 RT_TIMING_GET_TIME(time_cache);
1192 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1193 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1194 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1196 /* SUN compatible -verbose:class output */
1198 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1200 utf_display_printable_ascii_classname(name);
1204 #if defined(ENABLE_JVMTI)
1205 /* fire Class Load JVMTI event */
1206 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1213 c = load_class_bootstrap(name);
1219 /* load_class_bootstrap ********************************************************
1221 Load the class with the given name using the bootstrap class loader.
1224 name.............the classname
1227 loaded classinfo, or
1228 NULL if an exception has been thrown
1231 load_class_bootstrap is synchronized. It can be treated as an
1234 *******************************************************************************/
1236 classinfo *load_class_bootstrap(utf *name)
1241 #if defined(ENABLE_RT_TIMING)
1242 struct timespec time_start, time_lookup, time_array, time_suck,
1243 time_load, time_cache;
1246 RT_TIMING_GET_TIME(time_start);
1252 /* lookup if this class has already been loaded */
1254 r = classcache_lookup(NULL, name);
1257 RT_TIMING_GET_TIME(time_lookup);
1258 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1263 RT_TIMING_GET_TIME(time_lookup);
1264 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1266 /* create the classinfo */
1268 c = class_create_classinfo(name);
1270 /* handle array classes */
1272 if (name->text[0] == '[') {
1273 c = load_newly_created_array(c, NULL);
1278 assert(c->state & CLASS_LOADED);
1280 RT_TIMING_GET_TIME(time_array);
1281 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1286 #if defined(ENABLE_STATISTICS)
1289 if (opt_getcompilingtime)
1290 compilingtime_stop();
1292 if (opt_getloadingtime)
1293 loadingtime_start();
1296 /* load classdata, throw exception on error */
1301 exceptions_throw_classnotfoundexception(name);
1305 RT_TIMING_GET_TIME(time_suck);
1307 /* load the class from the buffer */
1309 r = load_class_from_classbuffer(cb);
1311 RT_TIMING_GET_TIME(time_load);
1314 /* the class could not be loaded, free the classinfo struct */
1319 /* Store this class in the loaded class cache this step also
1320 checks the loading constraints. If the class has been
1321 loaded before, the earlier loaded class is returned. */
1323 classinfo *res = classcache_store(NULL, c, true);
1330 // Add the package name to the boot packages.
1331 Package::add(c->packagename);
1337 RT_TIMING_GET_TIME(time_cache);
1339 /* SUN compatible -verbose:class output */
1341 if (opt_verboseclass && r) {
1343 utf_display_printable_ascii_classname(name);
1344 printf(" from %s]\n", cb->path);
1351 #if defined(ENABLE_STATISTICS)
1354 if (opt_getloadingtime)
1357 if (opt_getcompilingtime)
1358 compilingtime_start();
1361 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1362 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1363 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1364 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1370 /* load_class_from_classbuffer_intern ******************************************
1372 Loads a class from a classbuffer into a given classinfo structure.
1373 Super-classes are also loaded at this point and some verfication
1377 This function is NOT synchronized!
1379 *******************************************************************************/
1381 static bool load_class_from_classbuffer_intern(classbuffer *cb)
1387 utf **interfacesnames;
1389 constant_classref *cr;
1393 descriptor_pool *descpool;
1394 #if defined(ENABLE_STATISTICS)
1398 #if defined(ENABLE_RT_TIMING)
1399 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1400 time_setup, time_fields, time_methods, time_classrefs,
1401 time_descs, time_setrefs, time_parsefds, time_parsemds,
1402 time_parsecpool, time_verify, time_attrs;
1405 // Create new dump memory area.
1408 RT_TIMING_GET_TIME(time_start);
1410 /* Get the classbuffer's class. */
1414 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1417 /* check signature */
1419 if (suck_u4(cb) != MAGIC) {
1420 exceptions_throw_classformaterror(c, "Bad magic number");
1429 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1430 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1434 RT_TIMING_GET_TIME(time_checks);
1436 /* create a new descriptor pool */
1438 descpool = descriptor_pool_new(c);
1440 RT_TIMING_GET_TIME(time_ndpool);
1442 /* load the constant pool */
1444 if (!load_constantpool(cb, descpool))
1447 RT_TIMING_GET_TIME(time_cpool);
1451 if (!suck_check_classbuffer_size(cb, 2))
1454 /* We OR the flags here, as we set already some flags in
1455 class_create_classinfo. */
1457 c->flags |= suck_u2(cb);
1459 /* check ACC flags consistency */
1461 if (c->flags & ACC_INTERFACE) {
1462 if (!(c->flags & ACC_ABSTRACT)) {
1463 /* We work around this because interfaces in JDK 1.1 are
1464 * not declared abstract. */
1466 c->flags |= ACC_ABSTRACT;
1469 if (c->flags & ACC_FINAL) {
1470 exceptions_throw_classformaterror(c,
1471 "Illegal class modifiers: 0x%X",
1476 if (c->flags & ACC_SUPER) {
1477 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1481 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1482 exceptions_throw_classformaterror(c,
1483 "Illegal class modifiers: 0x%X",
1488 if (!suck_check_classbuffer_size(cb, 2 + 2))
1493 index = suck_u2(cb);
1495 name = (utf *) class_getconstant(c, index, CONSTANT_Class);
1500 if (c->name == utf_not_named_yet) {
1501 /* we finally have a name for this class */
1503 class_set_packagename(c);
1505 else if (name != c->name) {
1506 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
1510 /* Retrieve superclass. */
1514 index = suck_u2(cb);
1519 /* This is only allowed for java.lang.Object. */
1521 if (c->name != utf_java_lang_Object) {
1522 exceptions_throw_classformaterror(c, "Bad superclass index");
1527 supername = (utf *) class_getconstant(c, index, CONSTANT_Class);
1529 if (supername == NULL)
1532 /* java.lang.Object may not have a super class. */
1534 if (c->name == utf_java_lang_Object) {
1535 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
1539 /* Detect circularity. */
1541 if (supername == c->name) {
1542 exceptions_throw_classcircularityerror(c);
1546 /* Interfaces must have java.lang.Object as super class. */
1548 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
1549 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
1554 /* Parse the super interfaces. */
1556 if (!suck_check_classbuffer_size(cb, 2))
1559 c->interfacescount = suck_u2(cb);
1561 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1564 c->interfaces = MNEW(classinfo*, c->interfacescount);
1566 /* Get the names of the super interfaces. */
1568 interfacesnames = (utf**) DumpMemory::allocate(sizeof(utf*) * c->interfacescount);
1570 for (int32_t i = 0; i < c->interfacescount; i++) {
1571 index = suck_u2(cb);
1573 u = (utf *) class_getconstant(c, index, CONSTANT_Class);
1578 interfacesnames[i] = u;
1581 RT_TIMING_GET_TIME(time_setup);
1585 if (!suck_check_classbuffer_size(cb, 2))
1588 c->fieldscount = suck_u2(cb);
1589 c->fields = MNEW(fieldinfo, c->fieldscount);
1591 MZERO(c->fields, fieldinfo, c->fieldscount);
1593 for (int32_t i = 0; i < c->fieldscount; i++) {
1594 if (!field_load(cb, &(c->fields[i]), descpool))
1598 RT_TIMING_GET_TIME(time_fields);
1600 /* Parse methods. */
1602 if (!suck_check_classbuffer_size(cb, 2))
1605 c->methodscount = suck_u2(cb);
1606 c->methods = MNEW(methodinfo, c->methodscount);
1608 MZERO(c->methods, methodinfo, c->methodscount);
1610 for (int32_t i = 0; i < c->methodscount; i++) {
1611 if (!method_load(cb, &(c->methods[i]), descpool))
1615 RT_TIMING_GET_TIME(time_methods);
1617 /* create the class reference table */
1620 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
1622 RT_TIMING_GET_TIME(time_classrefs);
1624 /* allocate space for the parsed descriptors */
1626 descriptor_pool_alloc_parsed_descriptors(descpool);
1627 c->parseddescs = (u1*) descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
1629 #if defined(ENABLE_STATISTICS)
1631 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
1632 count_classref_len += classrefsize;
1633 count_parsed_desc_len += descsize;
1637 RT_TIMING_GET_TIME(time_descs);
1639 /* put the classrefs in the constant pool */
1641 for (int32_t i = 0; i < c->cpcount; i++) {
1642 if (c->cptags[i] == CONSTANT_Class) {
1643 utf *name = (utf *) c->cpinfos[i];
1644 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
1648 /* Resolve the super class. */
1650 if (supername != NULL) {
1651 cr = descriptor_pool_lookup_classref(descpool, supername);
1656 /* XXX This should be done better. */
1657 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1660 resolve_handle_pending_exception(true);
1664 /* Interfaces are not allowed as super classes. */
1666 if (tc->flags & ACC_INTERFACE) {
1667 exceptions_throw_incompatibleclasschangeerror(c, "class %s has interface %s as super class");
1671 /* Don't allow extending final classes */
1673 if (tc->flags & ACC_FINAL) {
1674 exceptions_throw_verifyerror(NULL,
1675 "Cannot inherit from final class");
1679 /* Store the super class. */
1684 /* Resolve the super interfaces. */
1686 for (int32_t i = 0; i < c->interfacescount; i++) {
1687 u = interfacesnames[i];
1688 cr = descriptor_pool_lookup_classref(descpool, u);
1693 /* XXX This should be done better. */
1694 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1697 resolve_handle_pending_exception(true);
1701 /* Detect circularity. */
1704 exceptions_throw_classcircularityerror(c);
1708 if (!(tc->flags & ACC_INTERFACE)) {
1709 exceptions_throw_incompatibleclasschangeerror(tc,
1710 "Implementing class");
1714 /* Store the super interface. */
1716 c->interfaces[i] = tc;
1719 RT_TIMING_GET_TIME(time_setrefs);
1721 /* Parse the field descriptors. */
1723 for (int32_t i = 0; i < c->fieldscount; i++) {
1724 c->fields[i].parseddesc =
1725 descriptor_pool_parse_field_descriptor(descpool,
1726 c->fields[i].descriptor);
1727 if (!c->fields[i].parseddesc)
1731 RT_TIMING_GET_TIME(time_parsefds);
1733 /* parse method descriptors */
1735 for (int32_t i = 0; i < c->methodscount; i++) {
1736 methodinfo *m = &c->methods[i];
1738 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
1739 m->flags, class_get_self_classref(m->clazz));
1743 for (int32_t j = 0; j < m->rawexceptiontablelength; j++) {
1744 if (!m->rawexceptiontable[j].catchtype.any)
1747 if ((m->rawexceptiontable[j].catchtype.ref =
1748 descriptor_pool_lookup_classref(descpool,
1749 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
1753 for (int32_t j = 0; j < m->thrownexceptionscount; j++) {
1754 if (!m->thrownexceptions[j].any)
1757 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
1758 (utf *) m->thrownexceptions[j].any)) == NULL)
1763 RT_TIMING_GET_TIME(time_parsemds);
1765 /* parse the loaded descriptors */
1767 for (int32_t i = 0; i < c->cpcount; i++) {
1768 constant_FMIref *fmi;
1771 switch (c->cptags[i]) {
1772 case CONSTANT_Fieldref:
1773 fmi = (constant_FMIref *) c->cpinfos[i];
1774 fmi->parseddesc.fd =
1775 descriptor_pool_parse_field_descriptor(descpool,
1777 if (!fmi->parseddesc.fd)
1780 index = fmi->p.index;
1782 (constant_classref *) class_getconstant(c, index,
1784 if (!fmi->p.classref)
1787 case CONSTANT_Methodref:
1788 case CONSTANT_InterfaceMethodref:
1789 fmi = (constant_FMIref *) c->cpinfos[i];
1790 index = fmi->p.index;
1792 (constant_classref *) class_getconstant(c, index,
1794 if (!fmi->p.classref)
1796 fmi->parseddesc.md =
1797 descriptor_pool_parse_method_descriptor(descpool,
1801 if (!fmi->parseddesc.md)
1807 RT_TIMING_GET_TIME(time_parsecpool);
1809 #ifdef ENABLE_VERIFIER
1810 /* Check if all fields and methods can be uniquely
1811 * identified by (name,descriptor). */
1814 /* We use a hash table here to avoid making the
1815 * average case quadratic in # of methods, fields.
1817 static int shift = 0;
1819 u2 *next; /* for chaining colliding hash entries */
1825 /* Allocate hashtable */
1826 len = c->methodscount;
1827 if (len < c->fieldscount) len = c->fieldscount;
1829 hashtab = MNEW(u2,(hashlen + len));
1830 next = hashtab + hashlen;
1832 /* Determine bitshift (to get good hash values) */
1842 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
1844 for (int32_t i = 0; i < c->fieldscount; ++i) {
1845 fieldinfo *fi = c->fields + i;
1847 /* It's ok if we lose bits here */
1848 index = ((((size_t) fi->name) +
1849 ((size_t) fi->descriptor)) >> shift) % hashlen;
1851 if ((old = hashtab[index])) {
1855 if (c->fields[old].name == fi->name &&
1856 c->fields[old].descriptor == fi->descriptor) {
1857 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
1860 } while ((old = next[old]));
1862 hashtab[index] = i + 1;
1866 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
1868 for (int32_t i = 0; i < c->methodscount; ++i) {
1869 methodinfo *mi = c->methods + i;
1871 /* It's ok if we lose bits here */
1872 index = ((((size_t) mi->name) +
1873 ((size_t) mi->descriptor)) >> shift) % hashlen;
1875 if ((old = hashtab[index])) {
1879 if (c->methods[old].name == mi->name &&
1880 c->methods[old].descriptor == mi->descriptor) {
1881 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
1884 } while ((old = next[old]));
1886 hashtab[index] = i + 1;
1889 MFREE(hashtab, u2, (hashlen + len));
1891 #endif /* ENABLE_VERIFIER */
1893 RT_TIMING_GET_TIME(time_verify);
1895 #if defined(ENABLE_STATISTICS)
1897 size_classinfo += sizeof(classinfo*) * c->interfacescount;
1898 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
1899 size_methodinfo += sizeof(methodinfo) * c->methodscount;
1903 /* load attribute structures */
1905 if (!class_load_attributes(cb))
1908 /* Pre Java 1.5 version don't check this. This implementation is
1909 like Java 1.5 do it: for class file version 45.3 we don't check
1910 it, older versions are checked. */
1912 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
1913 /* check if all data has been read */
1914 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
1916 if (classdata_left > 0) {
1917 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
1922 RT_TIMING_GET_TIME(time_attrs);
1924 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
1925 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
1926 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
1927 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
1928 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
1929 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
1930 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
1931 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
1932 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
1933 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
1934 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
1935 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
1936 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
1937 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
1938 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
1944 /* load_class_from_classbuffer *************************************************
1946 Convenience wrapper for load_class_from_classbuffer.
1949 This function is NOT synchronized!
1951 *******************************************************************************/
1953 classinfo *load_class_from_classbuffer(classbuffer *cb)
1958 /* Get the classbuffer's class. */
1962 /* Check if the class is already loaded. */
1964 if (c->state & CLASS_LOADED)
1967 #if defined(ENABLE_STATISTICS)
1969 count_class_loads++;
1972 #if !defined(NDEBUG)
1974 log_message_class("Loading class: ", c);
1977 /* Class is currently loading. */
1979 c->state |= CLASS_LOADING;
1981 /* Parse the classbuffer. */
1983 result = load_class_from_classbuffer_intern(cb);
1985 /* An error occurred. */
1987 if (result == false) {
1988 /* Revert loading state. */
1990 c->state = (c->state & ~CLASS_LOADING);
1995 /* Revert loading state and set loaded. */
1997 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
1999 #if defined(ENABLE_JVMTI)
2000 /* fire Class Prepare JVMTI event */
2003 jvmti_ClassLoadPrepare(true, c);
2006 #if !defined(NDEBUG)
2008 log_message_class("Loading done class: ", c);
2015 /* load_newly_created_array ****************************************************
2017 Load a newly created array class.
2020 c....................the array class C has been loaded
2021 other classinfo......the array class was found in the class cache,
2023 NULL.................an exception has been thrown
2026 This is an internal function. Do not use it unless you know exactly
2029 Use one of the load_class_... functions for general array class loading.
2031 *******************************************************************************/
2033 classinfo *load_newly_created_array(classinfo *c, classloader_t *loader)
2035 classinfo *comp = NULL;
2037 methoddesc *clonedesc;
2038 constant_classref *classrefs;
2043 text = c->name->text;
2044 namelen = c->name->blength;
2046 /* Check array class name */
2048 if ((namelen < 2) || (text[0] != '[')) {
2049 exceptions_throw_classnotfoundexception(c->name);
2053 /* Check the element type */
2057 /* c is an array of arrays. We have to create the component class. */
2059 u = utf_new(text + 1, namelen - 1);
2061 comp = load_class_from_classloader(u, loader);
2066 assert(comp->state & CLASS_LOADED);
2068 /* the array's flags are that of the component class */
2069 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2070 c->classloader = comp->classloader;
2074 /* c is an array of objects. */
2076 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2077 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2078 exceptions_throw_classnotfoundexception(c->name);
2082 u = utf_new(text + 2, namelen - 3);
2084 if (!(comp = load_class_from_classloader(u, loader)))
2087 assert(comp->state & CLASS_LOADED);
2089 /* the array's flags are that of the component class */
2090 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2091 c->classloader = comp->classloader;
2095 /* c is an array of a primitive type */
2097 /* check for cases like `[II' and whether the character is a
2098 valid primitive type */
2100 if ((namelen > 2) || (Primitive::get_class_by_char(text[1]) == NULL)) {
2101 exceptions_throw_classnotfoundexception(c->name);
2105 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2106 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2107 c->classloader = NULL;
2110 assert(class_java_lang_Object);
2111 #if defined(ENABLE_JAVASE)
2112 assert(class_java_lang_Cloneable);
2113 assert(class_java_io_Serializable);
2116 /* Setup the array class. */
2118 c->super = class_java_lang_Object;
2120 #if defined(ENABLE_JAVASE)
2122 c->interfacescount = 2;
2123 c->interfaces = MNEW(classinfo*, 2);
2124 c->interfaces[0] = class_java_lang_Cloneable;
2125 c->interfaces[1] = class_java_io_Serializable;
2127 #elif defined(ENABLE_JAVAME_CLDC1_1)
2129 c->interfacescount = 0;
2130 c->interfaces = NULL;
2133 # error unknow Java configuration
2136 c->methodscount = 1;
2137 c->methods = MNEW(methodinfo, c->methodscount);
2139 MZERO(c->methods, methodinfo, c->methodscount);
2141 classrefs = MNEW(constant_classref, 2);
2143 CLASSREF_INIT(classrefs[0], c, c->name);
2144 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2146 /* create descriptor for clone method */
2147 /* we need one paramslot which is reserved for the 'this' parameter */
2148 clonedesc = NEW(methoddesc);
2149 clonedesc->returntype.type = TYPE_ADR;
2150 clonedesc->returntype.classref = classrefs + 1;
2151 clonedesc->returntype.arraydim = 0;
2152 /* initialize params to "empty", add real params below in
2153 descriptor_params_from_paramtypes */
2154 clonedesc->paramcount = 0;
2155 clonedesc->paramslots = 0;
2156 clonedesc->paramtypes[0].classref = classrefs + 0;
2157 clonedesc->params = NULL;
2159 /* create methodinfo */
2162 MSET(clone, 0, methodinfo, 1);
2164 /* ATTENTION: if you delete the ACC_NATIVE below, set
2165 clone->maxlocals=1 (interpreter related) */
2167 clone->mutex = new Mutex();
2168 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2169 clone->name = utf_clone;
2170 clone->descriptor = utf_void__java_lang_Object;
2171 clone->parseddesc = clonedesc;
2174 /* parse the descriptor to get the register allocation */
2176 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2179 clone->code = NativeStub::generate(clone, BUILTIN_clone);
2181 /* XXX: field: length? */
2183 /* array classes are not loaded from class files */
2185 c->state |= CLASS_LOADED;
2186 c->parseddescs = (u1 *) clonedesc;
2187 c->parseddescsize = sizeof(methodinfo);
2188 c->classrefs = classrefs;
2189 c->classrefcount = 1;
2191 /* insert class into the loaded class cache */
2192 /* XXX free classinfo if NULL returned? */
2194 return classcache_store(loader, c, true);
2198 /* loader_close ****************************************************************
2200 Frees all resources.
2202 *******************************************************************************/
2204 void loader_close(void)
2211 * These are local overrides for various environment variables in Emacs.
2212 * Please do not remove this and leave it at the end of the file, where
2213 * Emacs will automagically detect them.
2214 * ---------------------------------------------------------------------
2217 * indent-tabs-mode: t
2221 * vim:noexpandtab:sw=4:ts=4: