1 /* src/vmcore/loader.c - 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/memory.h"
36 #include "native/llni.h"
38 #include "threads/lock-common.h"
40 #include "toolbox/hashtable.h"
41 #include "toolbox/logging.h"
43 #include "vm/builtin.h"
44 #include "vm/exceptions.h"
45 #include "vm/global.h"
46 #include "vm/package.hpp"
47 #include "vm/primitive.hpp"
48 #include "vm/resolve.h"
49 #include "vm/stringlocal.h"
52 #include "vm/jit_interface.h"
54 #if defined(ENABLE_JAVASE)
55 # include "vmcore/annotation.h"
56 # include "vmcore/stackmap.h"
59 #include "vmcore/classcache.h"
60 #include "vmcore/field.h"
61 #include "vmcore/globals.hpp"
62 #include "vmcore/linker.h"
63 #include "vmcore/loader.h"
64 #include "vmcore/method.h"
65 #include "vmcore/options.h"
66 #include "vmcore/rt-timing.h"
68 #if defined(ENABLE_STATISTICS)
69 # include "vmcore/statistics.h"
72 #include "vmcore/suck.h"
74 #if defined(ENABLE_ZLIB)
75 # include "vmcore/zip.h"
78 #if defined(ENABLE_JVMTI)
79 # include "native/jvmti/cacaodbg.h"
83 /* global variables ***********************************************************/
85 static hashtable *hashtable_classloader;
88 /* loader_preinit **************************************************************
90 Initializes the classpath list and loads classes required for the
93 NOTE: Exceptions thrown during VM initialization are caught in the
94 exception functions themselves.
96 *******************************************************************************/
98 void loader_preinit(void)
100 #if defined(ENABLE_THREADS)
101 list_classpath_entry *lce;
104 TRACESUBSYSTEMINITIALIZATION("loader_preinit");
106 #if defined(ENABLE_THREADS)
107 /* Initialize the monitor pointer for zip/jar file locking. */
109 for (lce = list_first(list_classpath_entries); lce != NULL;
110 lce = list_next(list_classpath_entries, lce)) {
111 if (lce->type == CLASSPATH_ARCHIVE)
112 LOCK_INIT_OBJECT_LOCK(lce);
116 /* initialize classloader hashtable, 10 entries should be enough */
118 hashtable_classloader = NEW(hashtable);
119 hashtable_create(hashtable_classloader, 10);
121 /* Load the most basic classes. */
123 assert(VM_is_initializing() == true);
125 class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object);
127 #if defined(ENABLE_JAVASE)
128 class_java_lang_Cloneable = load_class_bootstrap(utf_java_lang_Cloneable);
129 class_java_io_Serializable = load_class_bootstrap(utf_java_io_Serializable);
134 /* loader_init *****************************************************************
136 Loads all classes required in the VM.
138 NOTE: Exceptions thrown during VM initialization are caught in the
139 exception functions themselves.
141 *******************************************************************************/
143 void loader_init(void)
145 TRACESUBSYSTEMINITIALIZATION("loader_init");
147 /* Load primitive-type wrapping classes. */
149 assert(VM_is_initializing() == true);
151 #if defined(ENABLE_JAVASE)
152 class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void);
155 class_java_lang_Boolean = load_class_bootstrap(utf_java_lang_Boolean);
156 class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte);
157 class_java_lang_Character = load_class_bootstrap(utf_java_lang_Character);
158 class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short);
159 class_java_lang_Integer = load_class_bootstrap(utf_java_lang_Integer);
160 class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long);
161 class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float);
162 class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double);
164 /* Load important system classes. */
166 class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class);
167 class_java_lang_String = load_class_bootstrap(utf_java_lang_String);
169 #if defined(ENABLE_JAVASE)
170 class_java_lang_ClassLoader =
171 load_class_bootstrap(utf_java_lang_ClassLoader);
173 class_java_lang_SecurityManager =
174 load_class_bootstrap(utf_java_lang_SecurityManager);
177 class_java_lang_System =
178 load_class_bootstrap(utf_new_char("java/lang/System"));
180 class_java_lang_Thread =
181 load_class_bootstrap(utf_new_char("java/lang/Thread"));
183 #if defined(ENABLE_JAVASE)
184 class_java_lang_ThreadGroup =
185 load_class_bootstrap(utf_java_lang_ThreadGroup);
188 class_java_lang_Throwable = load_class_bootstrap(utf_java_lang_Throwable);
190 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
191 class_java_lang_VMSystem =
192 load_class_bootstrap(utf_new_char("java/lang/VMSystem"));
194 class_java_lang_VMThread =
195 load_class_bootstrap(utf_new_char("java/lang/VMThread"));
197 class_java_lang_VMThrowable =
198 load_class_bootstrap(utf_new_char("java/lang/VMThrowable"));
201 /* Important system exceptions. */
203 class_java_lang_Exception = load_class_bootstrap(utf_java_lang_Exception);
205 class_java_lang_ClassNotFoundException =
206 load_class_bootstrap(utf_java_lang_ClassNotFoundException);
208 class_java_lang_RuntimeException =
209 load_class_bootstrap(utf_java_lang_RuntimeException);
211 /* Some classes which may be used often. */
213 #if defined(ENABLE_JAVASE)
214 class_java_lang_StackTraceElement = load_class_bootstrap(utf_java_lang_StackTraceElement);
216 class_java_lang_reflect_Constructor = load_class_bootstrap(utf_java_lang_reflect_Constructor);
217 class_java_lang_reflect_Field = load_class_bootstrap(utf_java_lang_reflect_Field);
218 class_java_lang_reflect_Method = load_class_bootstrap(utf_java_lang_reflect_Method);
220 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
221 class_java_lang_reflect_VMConstructor = load_class_bootstrap(utf_java_lang_reflect_VMConstructor);
222 class_java_lang_reflect_VMField = load_class_bootstrap(utf_java_lang_reflect_VMField);
223 class_java_lang_reflect_VMMethod = load_class_bootstrap(utf_java_lang_reflect_VMMethod);
226 class_java_security_PrivilegedAction = load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"));
228 class_java_util_HashMap = load_class_bootstrap(utf_new_char("java/util/HashMap"));
229 class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector);
231 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
232 class_sun_reflect_MagicAccessorImpl =
233 load_class_bootstrap(utf_new_char("sun/reflect/MagicAccessorImpl"));
236 arrayclass_java_lang_Object =
237 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"));
239 # if defined(ENABLE_ANNOTATIONS)
240 /* needed by annotation support */
241 class_sun_reflect_ConstantPool =
242 load_class_bootstrap(utf_new_char("sun/reflect/ConstantPool"));
244 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
245 /* needed by GNU Classpaths annotation support */
246 class_sun_reflect_annotation_AnnotationParser =
247 load_class_bootstrap(utf_new_char("sun/reflect/annotation/AnnotationParser"));
254 /* loader_hashtable_classloader_add ********************************************
256 Adds an entry to the classloader hashtable.
258 REMEMBER: Also use this to register native loaders!
260 *******************************************************************************/
262 classloader_t *loader_hashtable_classloader_add(java_handle_t *cl)
264 hashtable_classloader_entry *cle;
271 LOCK_MONITOR_ENTER(hashtable_classloader->header);
275 /* key for entry is the hashcode of the classloader;
276 aligned to 16-byte boundaries */
278 key = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
279 slot = key & (hashtable_classloader->size - 1);
280 cle = hashtable_classloader->ptr[slot];
282 /* search hashchain for existing entry */
285 if (cle->object == LLNI_DIRECT(cl))
293 /* if no classloader was found, we create a new entry here */
296 cle = NEW(hashtable_classloader_entry);
298 #if defined(ENABLE_GC_CACAO)
299 /* register the classloader object with the GC */
301 gc_reference_register(&(cle->object), GC_REFTYPE_CLASSLOADER);
306 cle->object = LLNI_DIRECT(cl);
310 /*#define LOADER_DEBUG_CLASSLOADER*/
311 #ifdef LOADER_DEBUG_CLASSLOADER
312 printf("CLASSLOADER: adding new classloader entry %p for %p: ", cle, cl);
313 class_print(LLNI_vftbl_direct(cl)->class);
318 /* insert entry into hashtable */
320 cle->hashlink = hashtable_classloader->ptr[slot];
321 hashtable_classloader->ptr[slot] = cle;
323 /* update number of entries */
325 hashtable_classloader->entries++;
329 LOCK_MONITOR_EXIT(hashtable_classloader->header);
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->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)
403 hashtable_zipfile_entry *htzfe;
407 for (lce = list_first(list_classpath_entries); lce != NULL;
408 lce = list_next(list_classpath_entries, lce)) {
409 #if defined(ENABLE_ZLIB)
410 if (lce->type == CLASSPATH_ARCHIVE) {
411 /* get the classes hashtable */
415 for (slot = 0; slot < ht->size; slot++) {
416 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
418 for (; htzfe; htzfe = htzfe->hashlink) {
421 /* skip all entries in META-INF and .properties,
424 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
425 strstr(u->text, ".properties") ||
426 strstr(u->text, ".png"))
429 /* load class from bootstrap classloader */
431 if (!load_class_bootstrap(u)) {
432 fprintf(stderr, "Error loading: ");
433 utf_fprint_printable_ascii_classname(stderr, u);
434 fprintf(stderr, "\n");
437 /* print out exception and cause */
439 exceptions_print_current_exception();
447 #if defined(ENABLE_ZLIB)
454 /* loader_skip_attribute_body **************************************************
456 Skips an attribute the attribute_name_index has already been read.
459 u2 attribute_name_index;
461 u1 info[attribute_length];
464 *******************************************************************************/
466 bool loader_skip_attribute_body(classbuffer *cb)
470 if (!suck_check_classbuffer_size(cb, 4))
473 attribute_length = suck_u4(cb);
475 if (!suck_check_classbuffer_size(cb, attribute_length))
478 suck_skip_nbytes(cb, attribute_length);
484 /* load_constantpool ***********************************************************
486 Loads the constantpool of a class, the entries are transformed into
487 a simpler format by resolving references (a detailed overview of
488 the compact structures can be found in global.h).
490 *******************************************************************************/
492 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
495 /* The following structures are used to save information which cannot be
496 processed during the first pass. After the complete constantpool has
497 been traversed the references can be resolved.
498 (only in specific order) */
500 /* CONSTANT_Class entries */
501 typedef struct forward_class {
502 struct forward_class *next;
507 /* CONSTANT_String */
508 typedef struct forward_string {
509 struct forward_string *next;
514 /* CONSTANT_NameAndType */
515 typedef struct forward_nameandtype {
516 struct forward_nameandtype *next;
520 } forward_nameandtype;
522 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
523 typedef struct forward_fieldmethint {
524 struct forward_fieldmethint *next;
528 u2 nameandtype_index;
529 } forward_fieldmethint;
535 forward_class *forward_classes = NULL;
536 forward_string *forward_strings = NULL;
537 forward_nameandtype *forward_nameandtypes = NULL;
538 forward_fieldmethint *forward_fieldmethints = NULL;
542 forward_nameandtype *nfn;
543 forward_fieldmethint *nff;
551 /* number of entries in the constant_pool table plus one */
552 if (!suck_check_classbuffer_size(cb, 2))
555 cpcount = c->cpcount = suck_u2(cb);
557 /* allocate memory */
558 cptags = c->cptags = MNEW(u1, cpcount);
559 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
562 exceptions_throw_classformaterror(c, "Illegal constant pool size");
566 #if defined(ENABLE_STATISTICS)
568 count_const_pool_len += (sizeof(u1) + sizeof(voidptr)) * cpcount;
571 /* initialize constantpool */
572 for (idx = 0; idx < cpcount; idx++) {
573 cptags[idx] = CONSTANT_UNUSED;
578 /******* first pass *******/
579 /* entries which cannot be resolved now are written into
580 temporary structures and traversed again later */
583 while (idx < cpcount) {
586 /* get constant type */
587 if (!suck_check_classbuffer_size(cb, 1))
594 nfc = DNEW(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:
610 nfs = DNEW(forward_string);
612 nfs->next = forward_strings;
613 forward_strings = nfs;
615 nfs->thisindex = idx;
617 /* reference to CONSTANT_Utf8_info with string characters */
618 if (!suck_check_classbuffer_size(cb, 2))
621 nfs->string_index = suck_u2(cb);
626 case CONSTANT_NameAndType:
627 nfn = DNEW(forward_nameandtype);
629 nfn->next = forward_nameandtypes;
630 forward_nameandtypes = nfn;
632 nfn->thisindex = idx;
634 if (!suck_check_classbuffer_size(cb, 2 + 2))
637 /* reference to CONSTANT_Utf8_info containing simple name */
638 nfn->name_index = suck_u2(cb);
640 /* reference to CONSTANT_Utf8_info containing field or method
642 nfn->sig_index = suck_u2(cb);
647 case CONSTANT_Fieldref:
648 case CONSTANT_Methodref:
649 case CONSTANT_InterfaceMethodref:
650 nff = DNEW(forward_fieldmethint);
652 nff->next = forward_fieldmethints;
653 forward_fieldmethints = nff;
655 nff->thisindex = idx;
659 if (!suck_check_classbuffer_size(cb, 2 + 2))
662 /* class or interface type that contains the declaration of the
664 nff->class_index = suck_u2(cb);
666 /* name and descriptor of the field or method */
667 nff->nameandtype_index = suck_u2(cb);
672 case CONSTANT_Integer: {
673 constant_integer *ci = NEW(constant_integer);
675 #if defined(ENABLE_STATISTICS)
677 count_const_pool_len += sizeof(constant_integer);
680 if (!suck_check_classbuffer_size(cb, 4))
683 ci->value = suck_s4(cb);
684 cptags[idx] = CONSTANT_Integer;
691 case CONSTANT_Float: {
692 constant_float *cf = NEW(constant_float);
694 #if defined(ENABLE_STATISTICS)
696 count_const_pool_len += sizeof(constant_float);
699 if (!suck_check_classbuffer_size(cb, 4))
702 cf->value = suck_float(cb);
703 cptags[idx] = CONSTANT_Float;
710 case CONSTANT_Long: {
711 constant_long *cl = NEW(constant_long);
713 #if defined(ENABLE_STATISTICS)
715 count_const_pool_len += sizeof(constant_long);
718 if (!suck_check_classbuffer_size(cb, 8))
721 cl->value = suck_s8(cb);
722 cptags[idx] = CONSTANT_Long;
726 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
732 case CONSTANT_Double: {
733 constant_double *cd = NEW(constant_double);
735 #if defined(ENABLE_STATISTICS)
737 count_const_pool_len += sizeof(constant_double);
740 if (!suck_check_classbuffer_size(cb, 8))
743 cd->value = suck_double(cb);
744 cptags[idx] = CONSTANT_Double;
748 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
754 case CONSTANT_Utf8: {
757 /* number of bytes in the bytes array (not string-length) */
758 if (!suck_check_classbuffer_size(cb, 2))
761 length = suck_u2(cb);
762 cptags[idx] = CONSTANT_Utf8;
764 /* validate the string */
765 if (!suck_check_classbuffer_size(cb, length))
768 #ifdef ENABLE_VERIFIER
770 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
772 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
775 #endif /* ENABLE_VERIFIER */
776 /* insert utf-string into the utf-symboltable */
777 cpinfos[idx] = utf_new((char *) cb->pos, length);
779 /* skip bytes of the string (buffer size check above) */
780 suck_skip_nbytes(cb, length);
786 exceptions_throw_classformaterror(c, "Illegal constant pool type");
792 /* resolve entries in temporary structures */
794 while (forward_classes) {
796 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
800 #ifdef ENABLE_VERIFIER
801 if (opt_verify && !is_valid_name_utf(name)) {
802 exceptions_throw_classformaterror(c, "Class reference with invalid name");
805 #endif /* ENABLE_VERIFIER */
807 /* add all class references to the descriptor_pool */
809 if (!descriptor_pool_add_class(descpool, name))
812 cptags[forward_classes->thisindex] = CONSTANT_Class;
814 /* the classref is created later */
815 cpinfos[forward_classes->thisindex] = name;
817 nfc = forward_classes;
818 forward_classes = forward_classes->next;
821 while (forward_strings) {
823 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
827 /* resolve utf-string */
828 cptags[forward_strings->thisindex] = CONSTANT_String;
829 cpinfos[forward_strings->thisindex] = text;
831 nfs = forward_strings;
832 forward_strings = forward_strings->next;
835 while (forward_nameandtypes) {
836 constant_nameandtype *cn = NEW(constant_nameandtype);
838 #if defined(ENABLE_STATISTICS)
840 count_const_pool_len += sizeof(constant_nameandtype);
843 /* resolve simple name and descriptor */
844 cn->name = class_getconstant(c,
845 forward_nameandtypes->name_index,
850 cn->descriptor = class_getconstant(c,
851 forward_nameandtypes->sig_index,
856 #ifdef ENABLE_VERIFIER
859 if (!is_valid_name_utf(cn->name)) {
860 exceptions_throw_classformaterror(c,
861 "Illegal Field name \"%s\"",
867 /* disallow referencing <clinit> among others */
868 if (cn->name->text[0] == '<' && cn->name != utf_init) {
869 exceptions_throw_classformaterror(c, "Illegal reference to special method");
873 #endif /* ENABLE_VERIFIER */
875 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
876 cpinfos[forward_nameandtypes->thisindex] = cn;
878 nfn = forward_nameandtypes;
879 forward_nameandtypes = forward_nameandtypes->next;
882 while (forward_fieldmethints) {
883 constant_nameandtype *nat;
884 constant_FMIref *fmi = NEW(constant_FMIref);
886 #if defined(ENABLE_STATISTICS)
888 count_const_pool_len += sizeof(constant_FMIref);
890 /* resolve simple name and descriptor */
892 nat = class_getconstant(c,
893 forward_fieldmethints->nameandtype_index,
894 CONSTANT_NameAndType);
898 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
900 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
903 /* the classref is created later */
905 fmi->p.index = forward_fieldmethints->class_index;
906 fmi->name = nat->name;
907 fmi->descriptor = nat->descriptor;
909 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
910 cpinfos[forward_fieldmethints->thisindex] = fmi;
912 nff = forward_fieldmethints;
913 forward_fieldmethints = forward_fieldmethints->next;
916 /* everything was ok */
922 /* loader_load_attribute_signature *********************************************
924 Signature_attribute {
925 u2 attribute_name_index;
930 *******************************************************************************/
932 #if defined(ENABLE_JAVASE)
933 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
943 /* check remaining bytecode */
945 if (!suck_check_classbuffer_size(cb, 4 + 2))
948 /* check attribute length */
950 attribute_length = suck_u4(cb);
952 if (attribute_length != 2) {
953 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
957 if (*signature != NULL) {
958 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
964 signature_index = suck_u2(cb);
966 if (!(*signature = class_getconstant(c, signature_index, CONSTANT_Utf8)))
971 #endif /* defined(ENABLE_JAVASE) */
974 /* load_class_from_sysloader ***************************************************
976 Load the class with the given name using the system class loader
979 name.............the classname
983 NULL if an exception has been thrown
985 *******************************************************************************/
987 classinfo *load_class_from_sysloader(utf *name)
994 assert(class_java_lang_Object);
995 assert(class_java_lang_ClassLoader);
996 assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
998 m = class_resolveclassmethod(class_java_lang_ClassLoader,
999 utf_getSystemClassLoader,
1000 utf_void__java_lang_ClassLoader,
1001 class_java_lang_Object,
1007 clo = vm_call_method(m, NULL);
1012 cl = loader_hashtable_classloader_add(clo);
1014 c = load_class_from_classloader(name, cl);
1020 /* load_class_from_classloader *************************************************
1022 Load the class with the given name using the given user-defined class loader.
1025 name.............the classname
1026 cl...............user-defined class loader
1029 the loaded class, or
1030 NULL if an exception has been thrown
1032 *******************************************************************************/
1034 classinfo *load_class_from_classloader(utf *name, classloader_t *cl)
1039 java_handle_t *string;
1040 #if defined(ENABLE_RT_TIMING)
1041 struct timespec time_start, time_lookup, time_prepare, time_java,
1045 RT_TIMING_GET_TIME(time_start);
1049 /* lookup if this class has already been loaded */
1051 c = classcache_lookup(cl, name);
1053 RT_TIMING_GET_TIME(time_lookup);
1054 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1059 /* if other class loader than bootstrap, call it */
1067 namelen = name->blength;
1069 /* handle array classes */
1070 if (text[0] == '[') {
1076 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1077 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1078 exceptions_throw_classnotfoundexception(name);
1082 u = utf_new(text + 2, namelen - 3);
1084 if (!(comp = load_class_from_classloader(u, cl)))
1087 /* create the array class */
1089 c = class_array_of(comp, false);
1091 tmpc = classcache_store(cl, c, true);
1094 /* exception, free the loaded class */
1095 c->state &= ~CLASS_LOADING;
1102 /* load the component class */
1104 u = utf_new(text + 1, namelen - 1);
1106 if (!(comp = load_class_from_classloader(u, cl)))
1109 /* create the array class */
1111 c = class_array_of(comp, false);
1113 tmpc = classcache_store(cl, c, true);
1116 /* exception, free the loaded class */
1117 c->state &= ~CLASS_LOADING;
1124 /* primitive array classes are loaded by the bootstrap loader */
1126 c = load_class_bootstrap(name);
1132 LLNI_class_get(cl, c);
1134 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1135 /* OpenJDK uses this internal function because it's
1138 lc = class_resolveclassmethod(c,
1139 utf_loadClassInternal,
1140 utf_java_lang_String__java_lang_Class,
1144 lc = class_resolveclassmethod(c,
1146 utf_java_lang_String__java_lang_Class,
1152 return false; /* exception */
1154 /* move return value into `o' and cast it afterwards to a classinfo* */
1156 string = javastring_new_slash_to_dot(name);
1158 RT_TIMING_GET_TIME(time_prepare);
1160 o = vm_call_method(lc, (java_handle_t *) cl, string);
1162 RT_TIMING_GET_TIME(time_java);
1164 c = LLNI_classinfo_unwrap(o);
1167 /* Store this class in the loaded class cache. If another
1168 class with the same (initloader,name) pair has been
1169 stored earlier it will be returned by classcache_store
1170 In this case classcache_store may not free the class
1171 because it has already been exposed to Java code which
1172 may have kept references to that class. */
1174 tmpc = classcache_store(cl, c, false);
1177 /* exception, free the loaded class */
1178 c->state &= ~CLASS_LOADING;
1185 RT_TIMING_GET_TIME(time_cache);
1187 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1188 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1189 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1191 /* SUN compatible -verbose:class output */
1193 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1195 utf_display_printable_ascii_classname(name);
1199 #if defined(ENABLE_JVMTI)
1200 /* fire Class Load JVMTI event */
1201 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1208 c = load_class_bootstrap(name);
1214 /* load_class_bootstrap ********************************************************
1216 Load the class with the given name using the bootstrap class loader.
1219 name.............the classname
1222 loaded classinfo, or
1223 NULL if an exception has been thrown
1226 load_class_bootstrap is synchronized. It can be treated as an
1229 *******************************************************************************/
1231 classinfo *load_class_bootstrap(utf *name)
1236 #if defined(ENABLE_RT_TIMING)
1237 struct timespec time_start, time_lookup, time_array, time_suck,
1238 time_load, time_cache;
1241 RT_TIMING_GET_TIME(time_start);
1247 /* lookup if this class has already been loaded */
1249 r = classcache_lookup(NULL, name);
1252 RT_TIMING_GET_TIME(time_lookup);
1253 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1258 RT_TIMING_GET_TIME(time_lookup);
1259 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1261 /* create the classinfo */
1263 c = class_create_classinfo(name);
1265 /* handle array classes */
1267 if (name->text[0] == '[') {
1268 c = load_newly_created_array(c, NULL);
1273 assert(c->state & CLASS_LOADED);
1275 RT_TIMING_GET_TIME(time_array);
1276 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1281 #if defined(ENABLE_STATISTICS)
1284 if (opt_getcompilingtime)
1285 compilingtime_stop();
1287 if (opt_getloadingtime)
1288 loadingtime_start();
1291 /* load classdata, throw exception on error */
1296 exceptions_throw_classnotfoundexception(name);
1300 RT_TIMING_GET_TIME(time_suck);
1302 /* load the class from the buffer */
1304 r = load_class_from_classbuffer(cb);
1306 RT_TIMING_GET_TIME(time_load);
1309 /* the class could not be loaded, free the classinfo struct */
1314 /* Store this class in the loaded class cache this step also
1315 checks the loading constraints. If the class has been
1316 loaded before, the earlier loaded class is returned. */
1318 classinfo *res = classcache_store(NULL, c, true);
1325 /* 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;
1390 descriptor_pool *descpool;
1391 #if defined(ENABLE_STATISTICS)
1395 #if defined(ENABLE_RT_TIMING)
1396 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1397 time_setup, time_fields, time_methods, time_classrefs,
1398 time_descs, time_setrefs, time_parsefds, time_parsemds,
1399 time_parsecpool, time_verify, time_attrs;
1402 RT_TIMING_GET_TIME(time_start);
1404 /* Get the classbuffer's class. */
1408 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1411 /* check signature */
1413 if (suck_u4(cb) != MAGIC) {
1414 exceptions_throw_classformaterror(c, "Bad magic number");
1423 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1424 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1428 RT_TIMING_GET_TIME(time_checks);
1430 /* create a new descriptor pool */
1432 descpool = descriptor_pool_new(c);
1434 RT_TIMING_GET_TIME(time_ndpool);
1436 /* load the constant pool */
1438 if (!load_constantpool(cb, descpool))
1441 RT_TIMING_GET_TIME(time_cpool);
1445 if (!suck_check_classbuffer_size(cb, 2))
1448 /* We OR the flags here, as we set already some flags in
1449 class_create_classinfo. */
1451 c->flags |= suck_u2(cb);
1453 /* check ACC flags consistency */
1455 if (c->flags & ACC_INTERFACE) {
1456 if (!(c->flags & ACC_ABSTRACT)) {
1457 /* We work around this because interfaces in JDK 1.1 are
1458 * not declared abstract. */
1460 c->flags |= ACC_ABSTRACT;
1463 if (c->flags & ACC_FINAL) {
1464 exceptions_throw_classformaterror(c,
1465 "Illegal class modifiers: 0x%X",
1470 if (c->flags & ACC_SUPER) {
1471 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1475 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1476 exceptions_throw_classformaterror(c,
1477 "Illegal class modifiers: 0x%X",
1482 if (!suck_check_classbuffer_size(cb, 2 + 2))
1487 index = suck_u2(cb);
1489 name = (utf *) class_getconstant(c, index, CONSTANT_Class);
1494 if (c->name == utf_not_named_yet) {
1495 /* we finally have a name for this class */
1497 class_set_packagename(c);
1499 else if (name != c->name) {
1500 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
1504 /* Retrieve superclass. */
1508 index = suck_u2(cb);
1513 /* This is only allowed for java.lang.Object. */
1515 if (c->name != utf_java_lang_Object) {
1516 exceptions_throw_classformaterror(c, "Bad superclass index");
1521 supername = (utf *) class_getconstant(c, index, CONSTANT_Class);
1523 if (supername == NULL)
1526 /* java.lang.Object may not have a super class. */
1528 if (c->name == utf_java_lang_Object) {
1529 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
1533 /* Detect circularity. */
1535 if (supername == c->name) {
1536 exceptions_throw_classcircularityerror(c);
1540 /* Interfaces must have java.lang.Object as super class. */
1542 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
1543 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
1548 /* Parse the super interfaces. */
1550 if (!suck_check_classbuffer_size(cb, 2))
1553 c->interfacescount = suck_u2(cb);
1555 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1558 c->interfaces = MNEW(classinfo*, c->interfacescount);
1560 /* Get the names of the super interfaces. */
1562 interfacesnames = DMNEW(utf*, c->interfacescount);
1564 for (i = 0; i < c->interfacescount; i++) {
1565 index = suck_u2(cb);
1567 u = (utf *) class_getconstant(c, index, CONSTANT_Class);
1572 interfacesnames[i] = u;
1575 RT_TIMING_GET_TIME(time_setup);
1579 if (!suck_check_classbuffer_size(cb, 2))
1582 c->fieldscount = suck_u2(cb);
1583 c->fields = MNEW(fieldinfo, c->fieldscount);
1585 MZERO(c->fields, fieldinfo, c->fieldscount);
1587 for (i = 0; i < c->fieldscount; i++) {
1588 if (!field_load(cb, &(c->fields[i]), descpool))
1592 RT_TIMING_GET_TIME(time_fields);
1594 /* Parse methods. */
1596 if (!suck_check_classbuffer_size(cb, 2))
1599 c->methodscount = suck_u2(cb);
1600 c->methods = MNEW(methodinfo, c->methodscount);
1602 MZERO(c->methods, methodinfo, c->methodscount);
1604 for (i = 0; i < c->methodscount; i++) {
1605 if (!method_load(cb, &(c->methods[i]), descpool))
1609 RT_TIMING_GET_TIME(time_methods);
1611 /* create the class reference table */
1614 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
1616 RT_TIMING_GET_TIME(time_classrefs);
1618 /* allocate space for the parsed descriptors */
1620 descriptor_pool_alloc_parsed_descriptors(descpool);
1622 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
1624 #if defined(ENABLE_STATISTICS)
1626 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
1627 count_classref_len += classrefsize;
1628 count_parsed_desc_len += descsize;
1632 RT_TIMING_GET_TIME(time_descs);
1634 /* put the classrefs in the constant pool */
1636 for (i = 0; i < c->cpcount; i++) {
1637 if (c->cptags[i] == CONSTANT_Class) {
1638 utf *name = (utf *) c->cpinfos[i];
1639 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
1643 /* Resolve the super class. */
1645 if (supername != NULL) {
1646 cr = descriptor_pool_lookup_classref(descpool, supername);
1651 /* XXX This should be done better. */
1652 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1655 resolve_handle_pending_exception(true);
1659 /* Interfaces are not allowed as super classes. */
1661 if (tc->flags & ACC_INTERFACE) {
1662 exceptions_throw_incompatibleclasschangeerror(c, "class %s has interface %s as super class");
1666 /* Don't allow extending final classes */
1668 if (tc->flags & ACC_FINAL) {
1669 exceptions_throw_verifyerror(NULL,
1670 "Cannot inherit from final class");
1674 /* Store the super class. */
1679 /* Resolve the super interfaces. */
1681 for (i = 0; i < c->interfacescount; i++) {
1682 u = interfacesnames[i];
1683 cr = descriptor_pool_lookup_classref(descpool, u);
1688 /* XXX This should be done better. */
1689 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1692 resolve_handle_pending_exception(true);
1696 /* Detect circularity. */
1699 exceptions_throw_classcircularityerror(c);
1703 if (!(tc->flags & ACC_INTERFACE)) {
1704 exceptions_throw_incompatibleclasschangeerror(tc,
1705 "Implementing class");
1709 /* Store the super interface. */
1711 c->interfaces[i] = tc;
1714 RT_TIMING_GET_TIME(time_setrefs);
1716 /* Parse the field descriptors. */
1718 for (i = 0; i < c->fieldscount; i++) {
1719 c->fields[i].parseddesc =
1720 descriptor_pool_parse_field_descriptor(descpool,
1721 c->fields[i].descriptor);
1722 if (!c->fields[i].parseddesc)
1726 RT_TIMING_GET_TIME(time_parsefds);
1728 /* parse method descriptors */
1730 for (i = 0; i < c->methodscount; i++) {
1731 methodinfo *m = &c->methods[i];
1733 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
1734 m->flags, class_get_self_classref(m->clazz));
1738 for (j = 0; j < m->rawexceptiontablelength; j++) {
1739 if (!m->rawexceptiontable[j].catchtype.any)
1742 if ((m->rawexceptiontable[j].catchtype.ref =
1743 descriptor_pool_lookup_classref(descpool,
1744 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
1748 for (j = 0; j < m->thrownexceptionscount; j++) {
1749 if (!m->thrownexceptions[j].any)
1752 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
1753 (utf *) m->thrownexceptions[j].any)) == NULL)
1758 RT_TIMING_GET_TIME(time_parsemds);
1760 /* parse the loaded descriptors */
1762 for (i = 0; i < c->cpcount; i++) {
1763 constant_FMIref *fmi;
1766 switch (c->cptags[i]) {
1767 case CONSTANT_Fieldref:
1768 fmi = (constant_FMIref *) c->cpinfos[i];
1769 fmi->parseddesc.fd =
1770 descriptor_pool_parse_field_descriptor(descpool,
1772 if (!fmi->parseddesc.fd)
1775 index = fmi->p.index;
1777 (constant_classref *) class_getconstant(c, index,
1779 if (!fmi->p.classref)
1782 case CONSTANT_Methodref:
1783 case CONSTANT_InterfaceMethodref:
1784 fmi = (constant_FMIref *) c->cpinfos[i];
1785 index = fmi->p.index;
1787 (constant_classref *) class_getconstant(c, index,
1789 if (!fmi->p.classref)
1791 fmi->parseddesc.md =
1792 descriptor_pool_parse_method_descriptor(descpool,
1796 if (!fmi->parseddesc.md)
1802 RT_TIMING_GET_TIME(time_parsecpool);
1804 #ifdef ENABLE_VERIFIER
1805 /* Check if all fields and methods can be uniquely
1806 * identified by (name,descriptor). */
1809 /* We use a hash table here to avoid making the
1810 * average case quadratic in # of methods, fields.
1812 static int shift = 0;
1814 u2 *next; /* for chaining colliding hash entries */
1820 /* Allocate hashtable */
1821 len = c->methodscount;
1822 if (len < c->fieldscount) len = c->fieldscount;
1824 hashtab = MNEW(u2,(hashlen + len));
1825 next = hashtab + hashlen;
1827 /* Determine bitshift (to get good hash values) */
1837 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
1839 for (i = 0; i < c->fieldscount; ++i) {
1840 fieldinfo *fi = c->fields + i;
1842 /* It's ok if we lose bits here */
1843 index = ((((size_t) fi->name) +
1844 ((size_t) fi->descriptor)) >> shift) % hashlen;
1846 if ((old = hashtab[index])) {
1850 if (c->fields[old].name == fi->name &&
1851 c->fields[old].descriptor == fi->descriptor) {
1852 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
1855 } while ((old = next[old]));
1857 hashtab[index] = i + 1;
1861 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
1863 for (i = 0; i < c->methodscount; ++i) {
1864 methodinfo *mi = c->methods + i;
1866 /* It's ok if we lose bits here */
1867 index = ((((size_t) mi->name) +
1868 ((size_t) mi->descriptor)) >> shift) % hashlen;
1870 if ((old = hashtab[index])) {
1874 if (c->methods[old].name == mi->name &&
1875 c->methods[old].descriptor == mi->descriptor) {
1876 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
1879 } while ((old = next[old]));
1881 hashtab[index] = i + 1;
1884 MFREE(hashtab, u2, (hashlen + len));
1886 #endif /* ENABLE_VERIFIER */
1888 RT_TIMING_GET_TIME(time_verify);
1890 #if defined(ENABLE_STATISTICS)
1892 size_classinfo += sizeof(classinfo*) * c->interfacescount;
1893 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
1894 size_methodinfo += sizeof(methodinfo) * c->methodscount;
1898 /* load attribute structures */
1900 if (!class_load_attributes(cb))
1903 /* Pre Java 1.5 version don't check this. This implementation is
1904 like Java 1.5 do it: for class file version 45.3 we don't check
1905 it, older versions are checked. */
1907 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
1908 /* check if all data has been read */
1909 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
1911 if (classdata_left > 0) {
1912 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
1917 RT_TIMING_GET_TIME(time_attrs);
1919 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
1920 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
1921 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
1922 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
1923 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
1924 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
1925 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
1926 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
1927 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
1928 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
1929 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
1930 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
1931 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
1932 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
1933 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
1939 /* load_class_from_classbuffer *************************************************
1941 Convenience wrapper for load_class_from_classbuffer.
1944 This function is NOT synchronized!
1946 *******************************************************************************/
1948 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 /* Mark start of dump memory area. */
1977 /* Class is currently loading. */
1979 c->state |= CLASS_LOADING;
1981 /* Parse the classbuffer. */
1983 result = load_class_from_classbuffer_intern(cb);
1985 /* Release dump area. */
1989 /* An error occurred. */
1991 if (result == false) {
1992 /* Revert loading state. */
1994 c->state = (c->state & ~CLASS_LOADING);
1999 /* Revert loading state and set loaded. */
2001 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2003 #if defined(ENABLE_JVMTI)
2004 /* fire Class Prepare JVMTI event */
2007 jvmti_ClassLoadPrepare(true, c);
2010 #if !defined(NDEBUG)
2012 log_message_class("Loading done class: ", c);
2019 /* load_newly_created_array ****************************************************
2021 Load a newly created array class.
2024 c....................the array class C has been loaded
2025 other classinfo......the array class was found in the class cache,
2027 NULL.................an exception has been thrown
2030 This is an internal function. Do not use it unless you know exactly
2033 Use one of the load_class_... functions for general array class loading.
2035 *******************************************************************************/
2037 classinfo *load_newly_created_array(classinfo *c, classloader_t *loader)
2039 classinfo *comp = NULL;
2041 methoddesc *clonedesc;
2042 constant_classref *classrefs;
2047 text = c->name->text;
2048 namelen = c->name->blength;
2050 /* Check array class name */
2052 if ((namelen < 2) || (text[0] != '[')) {
2053 exceptions_throw_classnotfoundexception(c->name);
2057 /* Check the element type */
2061 /* c is an array of arrays. We have to create the component class. */
2063 u = utf_new(text + 1, namelen - 1);
2065 comp = load_class_from_classloader(u, loader);
2070 assert(comp->state & CLASS_LOADED);
2072 /* the array's flags are that of the component class */
2073 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2074 c->classloader = comp->classloader;
2078 /* c is an array of objects. */
2080 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2081 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2082 exceptions_throw_classnotfoundexception(c->name);
2086 u = utf_new(text + 2, namelen - 3);
2088 if (!(comp = load_class_from_classloader(u, loader)))
2091 assert(comp->state & CLASS_LOADED);
2093 /* the array's flags are that of the component class */
2094 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2095 c->classloader = comp->classloader;
2099 /* c is an array of a primitive type */
2101 /* check for cases like `[II' and whether the character is a
2102 valid primitive type */
2104 if ((namelen > 2) || (Primitive_get_class_by_char(text[1]) == NULL)) {
2105 exceptions_throw_classnotfoundexception(c->name);
2109 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2110 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2111 c->classloader = NULL;
2114 assert(class_java_lang_Object);
2115 #if defined(ENABLE_JAVASE)
2116 assert(class_java_lang_Cloneable);
2117 assert(class_java_io_Serializable);
2120 /* Setup the array class. */
2122 c->super = class_java_lang_Object;
2124 #if defined(ENABLE_JAVASE)
2126 c->interfacescount = 2;
2127 c->interfaces = MNEW(classinfo*, 2);
2128 c->interfaces[0] = class_java_lang_Cloneable;
2129 c->interfaces[1] = class_java_io_Serializable;
2131 #elif defined(ENABLE_JAVAME_CLDC1_1)
2133 c->interfacescount = 0;
2134 c->interfaces = NULL;
2137 # error unknow Java configuration
2140 c->methodscount = 1;
2141 c->methods = MNEW(methodinfo, c->methodscount);
2143 MZERO(c->methods, methodinfo, c->methodscount);
2145 classrefs = MNEW(constant_classref, 2);
2147 CLASSREF_INIT(classrefs[0], c, c->name);
2148 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2150 /* create descriptor for clone method */
2151 /* we need one paramslot which is reserved for the 'this' parameter */
2152 clonedesc = NEW(methoddesc);
2153 clonedesc->returntype.type = TYPE_ADR;
2154 clonedesc->returntype.classref = classrefs + 1;
2155 clonedesc->returntype.arraydim = 0;
2156 /* initialize params to "empty", add real params below in
2157 descriptor_params_from_paramtypes */
2158 clonedesc->paramcount = 0;
2159 clonedesc->paramslots = 0;
2160 clonedesc->paramtypes[0].classref = classrefs + 0;
2161 clonedesc->params = NULL;
2163 /* create methodinfo */
2166 MSET(clone, 0, methodinfo, 1);
2168 #if defined(ENABLE_THREADS)
2169 lock_init_object_lock(&clone->header);
2172 /* ATTENTION: if you delete the ACC_NATIVE below, set
2173 clone->maxlocals=1 (interpreter related) */
2175 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2176 clone->name = utf_clone;
2177 clone->descriptor = utf_void__java_lang_Object;
2178 clone->parseddesc = clonedesc;
2181 /* parse the descriptor to get the register allocation */
2183 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2186 clone->code = codegen_generate_stub_native(clone, BUILTIN_clone);
2188 /* XXX: field: length? */
2190 /* array classes are not loaded from class files */
2192 c->state |= CLASS_LOADED;
2193 c->parseddescs = (u1 *) clonedesc;
2194 c->parseddescsize = sizeof(methodinfo);
2195 c->classrefs = classrefs;
2196 c->classrefcount = 1;
2198 /* insert class into the loaded class cache */
2199 /* XXX free classinfo if NULL returned? */
2201 return classcache_store(loader, c, true);
2205 /* loader_close ****************************************************************
2207 Frees all resources.
2209 *******************************************************************************/
2211 void loader_close(void)
2218 * These are local overrides for various environment variables in Emacs.
2219 * Please do not remove this and leave it at the end of the file, where
2220 * Emacs will automagically detect them.
2221 * ---------------------------------------------------------------------
2224 * indent-tabs-mode: t
2228 * vim:noexpandtab:sw=4:ts=4: