1 /* src/vmcore/loader.c - class loader functions
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
36 #include "mm/memory.h"
38 #include "native/llni.h"
40 #include "threads/lock-common.h"
42 #include "toolbox/hashtable.h"
43 #include "toolbox/logging.h"
45 #include "vm/builtin.h"
46 #include "vm/exceptions.h"
47 #include "vm/global.h"
48 #include "vm/package.h"
49 #include "vm/primitive.h"
50 #include "vm/resolve.h"
51 #include "vm/stringlocal.h"
54 #include "vm/jit_interface.h"
56 #if defined(ENABLE_JAVASE)
57 # include "vmcore/annotation.h"
58 # include "vmcore/stackmap.h"
61 #include "vmcore/classcache.h"
62 #include "vmcore/field.h"
63 #include "vmcore/linker.h"
64 #include "vmcore/loader.h"
65 #include "vmcore/method.h"
66 #include "vmcore/options.h"
67 #include "vmcore/rt-timing.h"
69 #if defined(ENABLE_STATISTICS)
70 # include "vmcore/statistics.h"
73 #include "vmcore/suck.h"
75 #if defined(ENABLE_ZLIB)
76 # include "vmcore/zip.h"
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;
104 /* Initialize the monitor pointer for zip/jar file locking. */
106 for (lce = list_first(list_classpath_entries); lce != NULL;
107 lce = list_next(list_classpath_entries, lce)) {
108 if (lce->type == CLASSPATH_ARCHIVE)
109 LOCK_INIT_OBJECT_LOCK(lce);
113 /* initialize classloader hashtable, 10 entries should be enough */
115 hashtable_classloader = NEW(hashtable);
116 hashtable_create(hashtable_classloader, 10);
118 /* Load the most basic classes. */
120 assert(vm_initializing == true);
122 class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object);
124 #if defined(ENABLE_JAVASE)
125 class_java_lang_Cloneable = load_class_bootstrap(utf_java_lang_Cloneable);
126 class_java_io_Serializable = load_class_bootstrap(utf_java_io_Serializable);
131 /* loader_init *****************************************************************
133 Loads all classes required in the VM.
135 NOTE: Exceptions thrown during VM initialization are caught in the
136 exception functions themselves.
138 *******************************************************************************/
140 void loader_init(void)
142 /* Load primitive-type wrapping classes. */
144 assert(vm_initializing == true);
146 #if defined(ENABLE_JAVASE)
147 class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void);
150 class_java_lang_Boolean = load_class_bootstrap(utf_java_lang_Boolean);
151 class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte);
152 class_java_lang_Character = load_class_bootstrap(utf_java_lang_Character);
153 class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short);
154 class_java_lang_Integer = load_class_bootstrap(utf_java_lang_Integer);
155 class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long);
156 class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float);
157 class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double);
159 /* Load important system classes. */
161 class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class);
162 class_java_lang_String = load_class_bootstrap(utf_java_lang_String);
164 #if defined(ENABLE_JAVASE)
165 class_java_lang_ClassLoader =
166 load_class_bootstrap(utf_java_lang_ClassLoader);
168 class_java_lang_SecurityManager =
169 load_class_bootstrap(utf_java_lang_SecurityManager);
172 class_java_lang_System =
173 load_class_bootstrap(utf_new_char("java/lang/System"));
175 class_java_lang_Thread =
176 load_class_bootstrap(utf_new_char("java/lang/Thread"));
178 #if defined(ENABLE_JAVASE)
179 class_java_lang_ThreadGroup =
180 load_class_bootstrap(utf_java_lang_ThreadGroup);
183 class_java_lang_Throwable = load_class_bootstrap(utf_java_lang_Throwable);
185 #if defined(WITH_CLASSPATH_GNU)
186 class_java_lang_VMSystem =
187 load_class_bootstrap(utf_new_char("java/lang/VMSystem"));
189 class_java_lang_VMThread =
190 load_class_bootstrap(utf_new_char("java/lang/VMThread"));
192 class_java_lang_VMThrowable =
193 load_class_bootstrap(utf_new_char("java/lang/VMThrowable"));
196 /* Some classes which may be used often. */
198 #if defined(ENABLE_JAVASE)
199 class_java_lang_StackTraceElement =
200 load_class_bootstrap(utf_java_lang_StackTraceElement);
202 class_java_lang_reflect_Constructor =
203 load_class_bootstrap(utf_java_lang_reflect_Constructor);
205 class_java_lang_reflect_Field =
206 load_class_bootstrap(utf_java_lang_reflect_Field);
208 class_java_lang_reflect_Method =
209 load_class_bootstrap(utf_java_lang_reflect_Method);
211 class_java_security_PrivilegedAction =
212 load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"));
214 class_java_util_HashMap =
215 load_class_bootstrap(utf_new_char("java/util/HashMap"));
217 class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector);
219 # if defined(WITH_CLASSPATH_SUN)
220 class_sun_reflect_MagicAccessorImpl =
221 load_class_bootstrap(utf_new_char("sun/reflect/MagicAccessorImpl"));
224 arrayclass_java_lang_Object =
225 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"));
227 # if defined(ENABLE_ANNOTATIONS)
228 /* needed by annotation support */
229 class_sun_reflect_ConstantPool =
230 load_class_bootstrap(utf_new_char("sun/reflect/ConstantPool"));
232 # if defined(WITH_CLASSPATH_GNU)
233 /* needed by GNU Classpaths annotation support */
234 class_sun_reflect_annotation_AnnotationParser =
235 load_class_bootstrap(utf_new_char("sun/reflect/annotation/AnnotationParser"));
242 /* loader_hashtable_classloader_add ********************************************
244 Adds an entry to the classloader hashtable.
246 REMEMBER: Also use this to register native loaders!
248 *******************************************************************************/
250 classloader *loader_hashtable_classloader_add(java_handle_t *cl)
252 hashtable_classloader_entry *cle;
259 LOCK_MONITOR_ENTER(hashtable_classloader->header);
263 /* key for entry is the hashcode of the classloader;
264 aligned to 16-byte boundaries */
266 key = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
267 slot = key & (hashtable_classloader->size - 1);
268 cle = hashtable_classloader->ptr[slot];
270 /* search hashchain for existing entry */
273 if (cle->object == LLNI_DIRECT(cl))
281 /* if no classloader was found, we create a new entry here */
284 cle = NEW(hashtable_classloader_entry);
286 #if defined(ENABLE_GC_CACAO)
287 /* register the classloader object with the GC */
289 gc_reference_register(&(cle->object), GC_REFTYPE_CLASSLOADER);
294 cle->object = LLNI_DIRECT(cl);
298 /*#define LOADER_DEBUG_CLASSLOADER*/
299 #ifdef LOADER_DEBUG_CLASSLOADER
300 printf("CLASSLOADER: adding new classloader entry %p for %p: ", cle, cl);
301 class_print(LLNI_vftbl_direct(cl)->class);
306 /* insert entry into hashtable */
308 cle->hashlink = hashtable_classloader->ptr[slot];
309 hashtable_classloader->ptr[slot] = cle;
311 /* update number of entries */
313 hashtable_classloader->entries++;
317 LOCK_MONITOR_EXIT(hashtable_classloader->header);
319 #if defined(ENABLE_HANDLES)
327 /* loader_hashtable_classloader_find *******************************************
329 Find an entry in the classloader hashtable.
331 *******************************************************************************/
333 classloader *loader_hashtable_classloader_find(java_handle_t *cl)
335 hashtable_classloader_entry *cle;
344 /* key for entry is the hashcode of the classloader;
345 aligned to 16-byte boundaries */
347 key = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
348 slot = key & (hashtable_classloader->size - 1);
349 cle = hashtable_classloader->ptr[slot];
351 /* search hashchain for existing entry */
354 if (cle->object == LLNI_DIRECT(cl))
360 #ifdef LOADER_DEBUG_CLASSLOADER
362 printf("CLASSLOADER: unable to find classloader entry for %p: ", cl);
363 class_print(LLNI_vftbl_direct(cl)->class);
371 #if defined(ENABLE_HANDLES)
379 /* loader_load_all_classes *****************************************************
381 Loads all classes specified in the BOOTCLASSPATH.
383 *******************************************************************************/
385 void loader_load_all_classes(void)
387 list_classpath_entry *lce;
388 #if defined(ENABLE_ZLIB)
391 hashtable_zipfile_entry *htzfe;
395 for (lce = list_first(list_classpath_entries); lce != NULL;
396 lce = list_next(list_classpath_entries, lce)) {
397 #if defined(ENABLE_ZLIB)
398 if (lce->type == CLASSPATH_ARCHIVE) {
399 /* get the classes hashtable */
403 for (slot = 0; slot < ht->size; slot++) {
404 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
406 for (; htzfe; htzfe = htzfe->hashlink) {
409 /* skip all entries in META-INF and .properties,
412 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
413 strstr(u->text, ".properties") ||
414 strstr(u->text, ".png"))
417 /* load class from bootstrap classloader */
419 if (!load_class_bootstrap(u)) {
420 fprintf(stderr, "Error loading: ");
421 utf_fprint_printable_ascii_classname(stderr, u);
422 fprintf(stderr, "\n");
425 /* print out exception and cause */
427 exceptions_print_current_exception();
435 #if defined(ENABLE_ZLIB)
442 /* loader_skip_attribute_body **************************************************
444 Skips an attribute the attribute_name_index has already been read.
447 u2 attribute_name_index;
449 u1 info[attribute_length];
452 *******************************************************************************/
454 bool loader_skip_attribute_body(classbuffer *cb)
458 if (!suck_check_classbuffer_size(cb, 4))
461 attribute_length = suck_u4(cb);
463 if (!suck_check_classbuffer_size(cb, attribute_length))
466 suck_skip_nbytes(cb, attribute_length);
472 /* load_constantpool ***********************************************************
474 Loads the constantpool of a class, the entries are transformed into
475 a simpler format by resolving references (a detailed overview of
476 the compact structures can be found in global.h).
478 *******************************************************************************/
480 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
483 /* The following structures are used to save information which cannot be
484 processed during the first pass. After the complete constantpool has
485 been traversed the references can be resolved.
486 (only in specific order) */
488 /* CONSTANT_Class entries */
489 typedef struct forward_class {
490 struct forward_class *next;
495 /* CONSTANT_String */
496 typedef struct forward_string {
497 struct forward_string *next;
502 /* CONSTANT_NameAndType */
503 typedef struct forward_nameandtype {
504 struct forward_nameandtype *next;
508 } forward_nameandtype;
510 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
511 typedef struct forward_fieldmethint {
512 struct forward_fieldmethint *next;
516 u2 nameandtype_index;
517 } forward_fieldmethint;
523 forward_class *forward_classes = NULL;
524 forward_string *forward_strings = NULL;
525 forward_nameandtype *forward_nameandtypes = NULL;
526 forward_fieldmethint *forward_fieldmethints = NULL;
530 forward_nameandtype *nfn;
531 forward_fieldmethint *nff;
539 /* number of entries in the constant_pool table plus one */
540 if (!suck_check_classbuffer_size(cb, 2))
543 cpcount = c->cpcount = suck_u2(cb);
545 /* allocate memory */
546 cptags = c->cptags = MNEW(u1, cpcount);
547 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
550 exceptions_throw_classformaterror(c, "Illegal constant pool size");
554 #if defined(ENABLE_STATISTICS)
556 count_const_pool_len += (sizeof(u1) + sizeof(voidptr)) * cpcount;
559 /* initialize constantpool */
560 for (idx = 0; idx < cpcount; idx++) {
561 cptags[idx] = CONSTANT_UNUSED;
566 /******* first pass *******/
567 /* entries which cannot be resolved now are written into
568 temporary structures and traversed again later */
571 while (idx < cpcount) {
574 /* get constant type */
575 if (!suck_check_classbuffer_size(cb, 1))
582 nfc = DNEW(forward_class);
584 nfc->next = forward_classes;
585 forward_classes = nfc;
587 nfc->thisindex = idx;
588 /* reference to CONSTANT_NameAndType */
589 if (!suck_check_classbuffer_size(cb, 2))
592 nfc->name_index = suck_u2(cb);
597 case CONSTANT_String:
598 nfs = DNEW(forward_string);
600 nfs->next = forward_strings;
601 forward_strings = nfs;
603 nfs->thisindex = idx;
605 /* reference to CONSTANT_Utf8_info with string characters */
606 if (!suck_check_classbuffer_size(cb, 2))
609 nfs->string_index = suck_u2(cb);
614 case CONSTANT_NameAndType:
615 nfn = DNEW(forward_nameandtype);
617 nfn->next = forward_nameandtypes;
618 forward_nameandtypes = nfn;
620 nfn->thisindex = idx;
622 if (!suck_check_classbuffer_size(cb, 2 + 2))
625 /* reference to CONSTANT_Utf8_info containing simple name */
626 nfn->name_index = suck_u2(cb);
628 /* reference to CONSTANT_Utf8_info containing field or method
630 nfn->sig_index = suck_u2(cb);
635 case CONSTANT_Fieldref:
636 case CONSTANT_Methodref:
637 case CONSTANT_InterfaceMethodref:
638 nff = DNEW(forward_fieldmethint);
640 nff->next = forward_fieldmethints;
641 forward_fieldmethints = nff;
643 nff->thisindex = idx;
647 if (!suck_check_classbuffer_size(cb, 2 + 2))
650 /* class or interface type that contains the declaration of the
652 nff->class_index = suck_u2(cb);
654 /* name and descriptor of the field or method */
655 nff->nameandtype_index = suck_u2(cb);
660 case CONSTANT_Integer: {
661 constant_integer *ci = NEW(constant_integer);
663 #if defined(ENABLE_STATISTICS)
665 count_const_pool_len += sizeof(constant_integer);
668 if (!suck_check_classbuffer_size(cb, 4))
671 ci->value = suck_s4(cb);
672 cptags[idx] = CONSTANT_Integer;
679 case CONSTANT_Float: {
680 constant_float *cf = NEW(constant_float);
682 #if defined(ENABLE_STATISTICS)
684 count_const_pool_len += sizeof(constant_float);
687 if (!suck_check_classbuffer_size(cb, 4))
690 cf->value = suck_float(cb);
691 cptags[idx] = CONSTANT_Float;
698 case CONSTANT_Long: {
699 constant_long *cl = NEW(constant_long);
701 #if defined(ENABLE_STATISTICS)
703 count_const_pool_len += sizeof(constant_long);
706 if (!suck_check_classbuffer_size(cb, 8))
709 cl->value = suck_s8(cb);
710 cptags[idx] = CONSTANT_Long;
714 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
720 case CONSTANT_Double: {
721 constant_double *cd = NEW(constant_double);
723 #if defined(ENABLE_STATISTICS)
725 count_const_pool_len += sizeof(constant_double);
728 if (!suck_check_classbuffer_size(cb, 8))
731 cd->value = suck_double(cb);
732 cptags[idx] = CONSTANT_Double;
736 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
742 case CONSTANT_Utf8: {
745 /* number of bytes in the bytes array (not string-length) */
746 if (!suck_check_classbuffer_size(cb, 2))
749 length = suck_u2(cb);
750 cptags[idx] = CONSTANT_Utf8;
752 /* validate the string */
753 if (!suck_check_classbuffer_size(cb, length))
756 #ifdef ENABLE_VERIFIER
758 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
760 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
763 #endif /* ENABLE_VERIFIER */
764 /* insert utf-string into the utf-symboltable */
765 cpinfos[idx] = utf_new((char *) cb->pos, length);
767 /* skip bytes of the string (buffer size check above) */
768 suck_skip_nbytes(cb, length);
774 exceptions_throw_classformaterror(c, "Illegal constant pool type");
780 /* resolve entries in temporary structures */
782 while (forward_classes) {
784 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
788 #ifdef ENABLE_VERIFIER
789 if (opt_verify && !is_valid_name_utf(name)) {
790 exceptions_throw_classformaterror(c, "Class reference with invalid name");
793 #endif /* ENABLE_VERIFIER */
795 /* add all class references to the descriptor_pool */
797 if (!descriptor_pool_add_class(descpool, name))
800 cptags[forward_classes->thisindex] = CONSTANT_Class;
802 /* the classref is created later */
803 cpinfos[forward_classes->thisindex] = name;
805 nfc = forward_classes;
806 forward_classes = forward_classes->next;
809 while (forward_strings) {
811 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
815 /* resolve utf-string */
816 cptags[forward_strings->thisindex] = CONSTANT_String;
817 cpinfos[forward_strings->thisindex] = text;
819 nfs = forward_strings;
820 forward_strings = forward_strings->next;
823 while (forward_nameandtypes) {
824 constant_nameandtype *cn = NEW(constant_nameandtype);
826 #if defined(ENABLE_STATISTICS)
828 count_const_pool_len += sizeof(constant_nameandtype);
831 /* resolve simple name and descriptor */
832 cn->name = class_getconstant(c,
833 forward_nameandtypes->name_index,
838 cn->descriptor = class_getconstant(c,
839 forward_nameandtypes->sig_index,
844 #ifdef ENABLE_VERIFIER
847 if (!is_valid_name_utf(cn->name)) {
848 exceptions_throw_classformaterror(c,
849 "Illegal Field name \"%s\"",
855 /* disallow referencing <clinit> among others */
856 if (cn->name->text[0] == '<' && cn->name != utf_init) {
857 exceptions_throw_classformaterror(c, "Illegal reference to special method");
861 #endif /* ENABLE_VERIFIER */
863 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
864 cpinfos[forward_nameandtypes->thisindex] = cn;
866 nfn = forward_nameandtypes;
867 forward_nameandtypes = forward_nameandtypes->next;
870 while (forward_fieldmethints) {
871 constant_nameandtype *nat;
872 constant_FMIref *fmi = NEW(constant_FMIref);
874 #if defined(ENABLE_STATISTICS)
876 count_const_pool_len += sizeof(constant_FMIref);
878 /* resolve simple name and descriptor */
880 nat = class_getconstant(c,
881 forward_fieldmethints->nameandtype_index,
882 CONSTANT_NameAndType);
886 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
888 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
891 /* the classref is created later */
893 fmi->p.index = forward_fieldmethints->class_index;
894 fmi->name = nat->name;
895 fmi->descriptor = nat->descriptor;
897 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
898 cpinfos[forward_fieldmethints->thisindex] = fmi;
900 nff = forward_fieldmethints;
901 forward_fieldmethints = forward_fieldmethints->next;
904 /* everything was ok */
910 /* loader_load_attribute_signature *********************************************
912 Signature_attribute {
913 u2 attribute_name_index;
918 *******************************************************************************/
920 #if defined(ENABLE_JAVASE)
921 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
931 /* check remaining bytecode */
933 if (!suck_check_classbuffer_size(cb, 4 + 2))
936 /* check attribute length */
938 attribute_length = suck_u4(cb);
940 if (attribute_length != 2) {
941 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
945 if (*signature != NULL) {
946 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
952 signature_index = suck_u2(cb);
954 if (!(*signature = class_getconstant(c, signature_index, CONSTANT_Utf8)))
959 #endif /* defined(ENABLE_JAVASE) */
962 /* load_class_from_sysloader ***************************************************
964 Load the class with the given name using the system class loader
967 name.............the classname
971 NULL if an exception has been thrown
973 *******************************************************************************/
975 classinfo *load_class_from_sysloader(utf *name)
982 assert(class_java_lang_Object);
983 assert(class_java_lang_ClassLoader);
984 assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
986 m = class_resolveclassmethod(class_java_lang_ClassLoader,
987 utf_getSystemClassLoader,
988 utf_void__java_lang_ClassLoader,
989 class_java_lang_Object,
995 clo = vm_call_method(m, NULL);
1000 cl = loader_hashtable_classloader_add(clo);
1002 c = load_class_from_classloader(name, cl);
1008 /* load_class_from_classloader *************************************************
1010 Load the class with the given name using the given user-defined class loader.
1013 name.............the classname
1014 cl...............user-defined class loader
1017 the loaded class, or
1018 NULL if an exception has been thrown
1020 *******************************************************************************/
1022 classinfo *load_class_from_classloader(utf *name, classloader *cl)
1027 java_handle_t *string;
1028 #if defined(ENABLE_RT_TIMING)
1029 struct timespec time_start, time_lookup, time_prepare, time_java,
1033 RT_TIMING_GET_TIME(time_start);
1037 /* lookup if this class has already been loaded */
1039 c = classcache_lookup(cl, name);
1041 RT_TIMING_GET_TIME(time_lookup);
1042 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1047 /* if other class loader than bootstrap, call it */
1055 namelen = name->blength;
1057 /* handle array classes */
1058 if (text[0] == '[') {
1064 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1065 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1066 exceptions_throw_classnotfoundexception(name);
1070 u = utf_new(text + 2, namelen - 3);
1072 if (!(comp = load_class_from_classloader(u, cl)))
1075 /* create the array class */
1077 c = class_array_of(comp, false);
1079 tmpc = classcache_store(cl, c, true);
1082 /* exception, free the loaded class */
1083 c->state &= ~CLASS_LOADING;
1090 /* load the component class */
1092 u = utf_new(text + 1, namelen - 1);
1094 if (!(comp = load_class_from_classloader(u, cl)))
1097 /* create the array class */
1099 c = class_array_of(comp, false);
1101 tmpc = classcache_store(cl, c, true);
1104 /* exception, free the loaded class */
1105 c->state &= ~CLASS_LOADING;
1112 /* primitive array classes are loaded by the bootstrap loader */
1114 c = load_class_bootstrap(name);
1120 LLNI_class_get(cl, c);
1122 #if defined(WITH_CLASSPATH_SUN)
1123 /* OpenJDK uses this internal function because it's
1126 lc = class_resolveclassmethod(c,
1127 utf_loadClassInternal,
1128 utf_java_lang_String__java_lang_Class,
1132 lc = class_resolveclassmethod(c,
1134 utf_java_lang_String__java_lang_Class,
1140 return false; /* exception */
1142 /* move return value into `o' and cast it afterwards to a classinfo* */
1144 string = javastring_new_slash_to_dot(name);
1146 RT_TIMING_GET_TIME(time_prepare);
1148 o = vm_call_method(lc, (java_handle_t *) cl, string);
1150 RT_TIMING_GET_TIME(time_java);
1152 c = LLNI_classinfo_unwrap(o);
1155 /* Store this class in the loaded class cache. If another
1156 class with the same (initloader,name) pair has been
1157 stored earlier it will be returned by classcache_store
1158 In this case classcache_store may not free the class
1159 because it has already been exposed to Java code which
1160 may have kept references to that class. */
1162 tmpc = classcache_store(cl, c, false);
1165 /* exception, free the loaded class */
1166 c->state &= ~CLASS_LOADING;
1173 RT_TIMING_GET_TIME(time_cache);
1175 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1176 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1177 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1179 /* SUN compatible -verbose:class output */
1181 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1183 utf_display_printable_ascii_classname(name);
1187 #if defined(ENABLE_JVMTI)
1188 /* fire Class Load JVMTI event */
1189 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1196 c = load_class_bootstrap(name);
1202 /* load_class_bootstrap ********************************************************
1204 Load the class with the given name using the bootstrap class loader.
1207 name.............the classname
1210 loaded classinfo, or
1211 NULL if an exception has been thrown
1214 load_class_bootstrap is synchronized. It can be treated as an
1217 *******************************************************************************/
1219 classinfo *load_class_bootstrap(utf *name)
1224 #if defined(ENABLE_RT_TIMING)
1225 struct timespec time_start, time_lookup, time_array, time_suck,
1226 time_load, time_cache;
1229 RT_TIMING_GET_TIME(time_start);
1235 /* lookup if this class has already been loaded */
1237 r = classcache_lookup(NULL, name);
1240 RT_TIMING_GET_TIME(time_lookup);
1241 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1246 RT_TIMING_GET_TIME(time_lookup);
1247 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1249 /* create the classinfo */
1251 c = class_create_classinfo(name);
1253 /* handle array classes */
1255 if (name->text[0] == '[') {
1256 c = load_newly_created_array(c, NULL);
1261 assert(c->state & CLASS_LOADED);
1263 RT_TIMING_GET_TIME(time_array);
1264 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1269 #if defined(ENABLE_STATISTICS)
1272 if (opt_getcompilingtime)
1273 compilingtime_stop();
1275 if (opt_getloadingtime)
1276 loadingtime_start();
1279 /* load classdata, throw exception on error */
1284 exceptions_throw_classnotfoundexception(name);
1288 RT_TIMING_GET_TIME(time_suck);
1290 /* load the class from the buffer */
1292 r = load_class_from_classbuffer(cb);
1294 RT_TIMING_GET_TIME(time_load);
1297 /* the class could not be loaded, free the classinfo struct */
1302 /* Store this class in the loaded class cache this step also
1303 checks the loading constraints. If the class has been
1304 loaded before, the earlier loaded class is returned. */
1306 classinfo *res = classcache_store(NULL, c, true);
1313 /* Add the package name to the boot packages. */
1315 package_add(c->packagename);
1321 RT_TIMING_GET_TIME(time_cache);
1323 /* SUN compatible -verbose:class output */
1325 if (opt_verboseclass && r) {
1327 utf_display_printable_ascii_classname(name);
1328 printf(" from %s]\n", cb->path);
1335 #if defined(ENABLE_STATISTICS)
1338 if (opt_getloadingtime)
1341 if (opt_getcompilingtime)
1342 compilingtime_start();
1345 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1346 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1347 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1348 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1354 /* load_class_from_classbuffer_intern ******************************************
1356 Loads a class from a classbuffer into a given classinfo structure.
1357 Super-classes are also loaded at this point and some verfication
1361 This function is NOT synchronized!
1363 *******************************************************************************/
1365 static bool load_class_from_classbuffer_intern(classbuffer *cb)
1371 utf **interfacesnames;
1373 constant_classref *cr;
1378 descriptor_pool *descpool;
1379 #if defined(ENABLE_STATISTICS)
1383 #if defined(ENABLE_RT_TIMING)
1384 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1385 time_setup, time_fields, time_methods, time_classrefs,
1386 time_descs, time_setrefs, time_parsefds, time_parsemds,
1387 time_parsecpool, time_verify, time_attrs;
1390 RT_TIMING_GET_TIME(time_start);
1392 /* Get the classbuffer's class. */
1396 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1399 /* check signature */
1401 if (suck_u4(cb) != MAGIC) {
1402 exceptions_throw_classformaterror(c, "Bad magic number");
1411 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1412 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1416 RT_TIMING_GET_TIME(time_checks);
1418 /* create a new descriptor pool */
1420 descpool = descriptor_pool_new(c);
1422 RT_TIMING_GET_TIME(time_ndpool);
1424 /* load the constant pool */
1426 if (!load_constantpool(cb, descpool))
1429 RT_TIMING_GET_TIME(time_cpool);
1433 if (!suck_check_classbuffer_size(cb, 2))
1436 /* We OR the flags here, as we set already some flags in
1437 class_create_classinfo. */
1439 c->flags |= suck_u2(cb);
1441 /* check ACC flags consistency */
1443 if (c->flags & ACC_INTERFACE) {
1444 if (!(c->flags & ACC_ABSTRACT)) {
1445 /* We work around this because interfaces in JDK 1.1 are
1446 * not declared abstract. */
1448 c->flags |= ACC_ABSTRACT;
1451 if (c->flags & ACC_FINAL) {
1452 exceptions_throw_classformaterror(c,
1453 "Illegal class modifiers: 0x%X",
1458 if (c->flags & ACC_SUPER) {
1459 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1463 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1464 exceptions_throw_classformaterror(c,
1465 "Illegal class modifiers: 0x%X",
1470 if (!suck_check_classbuffer_size(cb, 2 + 2))
1475 index = suck_u2(cb);
1477 name = (utf *) class_getconstant(c, index, CONSTANT_Class);
1482 if (c->name == utf_not_named_yet) {
1483 /* we finally have a name for this class */
1485 class_set_packagename(c);
1487 else if (name != c->name) {
1488 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
1492 /* Retrieve superclass. */
1496 index = suck_u2(cb);
1501 /* This is only allowed for java.lang.Object. */
1503 if (c->name != utf_java_lang_Object) {
1504 exceptions_throw_classformaterror(c, "Bad superclass index");
1509 supername = (utf *) class_getconstant(c, index, CONSTANT_Class);
1511 if (supername == NULL)
1514 /* java.lang.Object may not have a super class. */
1516 if (c->name == utf_java_lang_Object) {
1517 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
1521 /* Detect circularity. */
1523 if (supername == c->name) {
1524 exceptions_throw_classcircularityerror(c);
1528 /* Interfaces must have java.lang.Object as super class. */
1530 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
1531 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
1536 /* Parse the super interfaces. */
1538 if (!suck_check_classbuffer_size(cb, 2))
1541 c->interfacescount = suck_u2(cb);
1543 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1546 c->interfaces = MNEW(classinfo*, c->interfacescount);
1548 /* Get the names of the super interfaces. */
1550 interfacesnames = DMNEW(utf*, c->interfacescount);
1552 for (i = 0; i < c->interfacescount; i++) {
1553 index = suck_u2(cb);
1555 u = (utf *) class_getconstant(c, index, CONSTANT_Class);
1560 interfacesnames[i] = u;
1563 RT_TIMING_GET_TIME(time_setup);
1567 if (!suck_check_classbuffer_size(cb, 2))
1570 c->fieldscount = suck_u2(cb);
1571 c->fields = MNEW(fieldinfo, c->fieldscount);
1573 MZERO(c->fields, fieldinfo, c->fieldscount);
1575 for (i = 0; i < c->fieldscount; i++) {
1576 if (!field_load(cb, &(c->fields[i]), descpool))
1580 RT_TIMING_GET_TIME(time_fields);
1582 /* Parse methods. */
1584 if (!suck_check_classbuffer_size(cb, 2))
1587 c->methodscount = suck_u2(cb);
1588 c->methods = MNEW(methodinfo, c->methodscount);
1590 MZERO(c->methods, methodinfo, c->methodscount);
1592 for (i = 0; i < c->methodscount; i++) {
1593 if (!method_load(cb, &(c->methods[i]), descpool))
1597 RT_TIMING_GET_TIME(time_methods);
1599 /* create the class reference table */
1602 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
1604 RT_TIMING_GET_TIME(time_classrefs);
1606 /* allocate space for the parsed descriptors */
1608 descriptor_pool_alloc_parsed_descriptors(descpool);
1610 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
1612 #if defined(ENABLE_STATISTICS)
1614 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
1615 count_classref_len += classrefsize;
1616 count_parsed_desc_len += descsize;
1620 RT_TIMING_GET_TIME(time_descs);
1622 /* put the classrefs in the constant pool */
1624 for (i = 0; i < c->cpcount; i++) {
1625 if (c->cptags[i] == CONSTANT_Class) {
1626 utf *name = (utf *) c->cpinfos[i];
1627 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
1631 /* Resolve the super class. */
1633 if (supername != NULL) {
1634 cr = descriptor_pool_lookup_classref(descpool, supername);
1639 /* XXX This should be done better. */
1640 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1645 /* Interfaces are not allowed as super classes. */
1647 if (tc->flags & ACC_INTERFACE) {
1648 exceptions_throw_incompatibleclasschangeerror(c, "class %s has interface %s as super class");
1652 /* Don't allow extending final classes */
1654 if (tc->flags & ACC_FINAL) {
1655 exceptions_throw_verifyerror(NULL,
1656 "Cannot inherit from final class");
1660 /* Store the super class. */
1665 /* Resolve the super interfaces. */
1667 for (i = 0; i < c->interfacescount; i++) {
1668 u = interfacesnames[i];
1669 cr = descriptor_pool_lookup_classref(descpool, u);
1674 /* XXX This should be done better. */
1675 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1680 /* Detect circularity. */
1683 exceptions_throw_classcircularityerror(c);
1687 if (!(tc->flags & ACC_INTERFACE)) {
1688 exceptions_throw_incompatibleclasschangeerror(tc,
1689 "Implementing class");
1693 /* Store the super interface. */
1695 c->interfaces[i] = tc;
1698 RT_TIMING_GET_TIME(time_setrefs);
1700 /* Parse the field descriptors. */
1702 for (i = 0; i < c->fieldscount; i++) {
1703 c->fields[i].parseddesc =
1704 descriptor_pool_parse_field_descriptor(descpool,
1705 c->fields[i].descriptor);
1706 if (!c->fields[i].parseddesc)
1710 RT_TIMING_GET_TIME(time_parsefds);
1712 /* parse method descriptors */
1714 for (i = 0; i < c->methodscount; i++) {
1715 methodinfo *m = &c->methods[i];
1717 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
1718 m->flags, class_get_self_classref(m->class));
1722 for (j = 0; j < m->rawexceptiontablelength; j++) {
1723 if (!m->rawexceptiontable[j].catchtype.any)
1726 if ((m->rawexceptiontable[j].catchtype.ref =
1727 descriptor_pool_lookup_classref(descpool,
1728 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
1732 for (j = 0; j < m->thrownexceptionscount; j++) {
1733 if (!m->thrownexceptions[j].any)
1736 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
1737 (utf *) m->thrownexceptions[j].any)) == NULL)
1742 RT_TIMING_GET_TIME(time_parsemds);
1744 /* parse the loaded descriptors */
1746 for (i = 0; i < c->cpcount; i++) {
1747 constant_FMIref *fmi;
1750 switch (c->cptags[i]) {
1751 case CONSTANT_Fieldref:
1752 fmi = (constant_FMIref *) c->cpinfos[i];
1753 fmi->parseddesc.fd =
1754 descriptor_pool_parse_field_descriptor(descpool,
1756 if (!fmi->parseddesc.fd)
1759 index = fmi->p.index;
1761 (constant_classref *) class_getconstant(c, index,
1763 if (!fmi->p.classref)
1766 case CONSTANT_Methodref:
1767 case CONSTANT_InterfaceMethodref:
1768 fmi = (constant_FMIref *) c->cpinfos[i];
1769 index = fmi->p.index;
1771 (constant_classref *) class_getconstant(c, index,
1773 if (!fmi->p.classref)
1775 fmi->parseddesc.md =
1776 descriptor_pool_parse_method_descriptor(descpool,
1780 if (!fmi->parseddesc.md)
1786 RT_TIMING_GET_TIME(time_parsecpool);
1788 #ifdef ENABLE_VERIFIER
1789 /* Check if all fields and methods can be uniquely
1790 * identified by (name,descriptor). */
1793 /* We use a hash table here to avoid making the
1794 * average case quadratic in # of methods, fields.
1796 static int shift = 0;
1798 u2 *next; /* for chaining colliding hash entries */
1804 /* Allocate hashtable */
1805 len = c->methodscount;
1806 if (len < c->fieldscount) len = c->fieldscount;
1808 hashtab = MNEW(u2,(hashlen + len));
1809 next = hashtab + hashlen;
1811 /* Determine bitshift (to get good hash values) */
1821 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
1823 for (i = 0; i < c->fieldscount; ++i) {
1824 fieldinfo *fi = c->fields + i;
1826 /* It's ok if we lose bits here */
1827 index = ((((size_t) fi->name) +
1828 ((size_t) fi->descriptor)) >> shift) % hashlen;
1830 if ((old = hashtab[index])) {
1834 if (c->fields[old].name == fi->name &&
1835 c->fields[old].descriptor == fi->descriptor) {
1836 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
1839 } while ((old = next[old]));
1841 hashtab[index] = i + 1;
1845 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
1847 for (i = 0; i < c->methodscount; ++i) {
1848 methodinfo *mi = c->methods + i;
1850 /* It's ok if we lose bits here */
1851 index = ((((size_t) mi->name) +
1852 ((size_t) mi->descriptor)) >> shift) % hashlen;
1854 if ((old = hashtab[index])) {
1858 if (c->methods[old].name == mi->name &&
1859 c->methods[old].descriptor == mi->descriptor) {
1860 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
1863 } while ((old = next[old]));
1865 hashtab[index] = i + 1;
1868 MFREE(hashtab, u2, (hashlen + len));
1870 #endif /* ENABLE_VERIFIER */
1872 RT_TIMING_GET_TIME(time_verify);
1874 #if defined(ENABLE_STATISTICS)
1876 size_classinfo += sizeof(classinfo*) * c->interfacescount;
1877 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
1878 size_methodinfo += sizeof(methodinfo) * c->methodscount;
1882 /* load attribute structures */
1884 if (!class_load_attributes(cb))
1887 /* Pre Java 1.5 version don't check this. This implementation is
1888 like Java 1.5 do it: for class file version 45.3 we don't check
1889 it, older versions are checked. */
1891 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
1892 /* check if all data has been read */
1893 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
1895 if (classdata_left > 0) {
1896 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
1901 RT_TIMING_GET_TIME(time_attrs);
1903 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
1904 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
1905 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
1906 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
1907 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
1908 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
1909 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
1910 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
1911 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
1912 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
1913 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
1914 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
1915 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
1916 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
1917 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
1923 /* load_class_from_classbuffer *************************************************
1925 Convenience wrapper for load_class_from_classbuffer.
1928 This function is NOT synchronized!
1930 *******************************************************************************/
1932 classinfo *load_class_from_classbuffer(classbuffer *cb)
1938 /* Get the classbuffer's class. */
1942 /* Check if the class is already loaded. */
1944 if (c->state & CLASS_LOADED)
1947 #if defined(ENABLE_STATISTICS)
1949 count_class_loads++;
1952 #if !defined(NDEBUG)
1954 log_message_class("Loading class: ", c);
1957 /* Mark start of dump memory area. */
1959 dumpsize = dump_size();
1961 /* Class is currently loading. */
1963 c->state |= CLASS_LOADING;
1965 /* Parse the classbuffer. */
1967 result = load_class_from_classbuffer_intern(cb);
1969 /* Release dump area. */
1971 dump_release(dumpsize);
1973 /* An error occurred. */
1975 if (result == false) {
1976 /* Revert loading state. */
1978 c->state = (c->state & ~CLASS_LOADING);
1983 /* Revert loading state and set loaded. */
1985 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
1987 #if defined(ENABLE_JVMTI)
1988 /* fire Class Prepare JVMTI event */
1991 jvmti_ClassLoadPrepare(true, c);
1994 #if !defined(NDEBUG)
1996 log_message_class("Loading done class: ", c);
2003 /* load_newly_created_array ****************************************************
2005 Load a newly created array class.
2008 c....................the array class C has been loaded
2009 other classinfo......the array class was found in the class cache,
2011 NULL.................an exception has been thrown
2014 This is an internal function. Do not use it unless you know exactly
2017 Use one of the load_class_... functions for general array class loading.
2019 *******************************************************************************/
2021 classinfo *load_newly_created_array(classinfo *c, classloader *loader)
2023 classinfo *comp = NULL;
2025 methoddesc *clonedesc;
2026 constant_classref *classrefs;
2031 text = c->name->text;
2032 namelen = c->name->blength;
2034 /* Check array class name */
2036 if ((namelen < 2) || (text[0] != '[')) {
2037 exceptions_throw_classnotfoundexception(c->name);
2041 /* Check the element type */
2045 /* c is an array of arrays. We have to create the component class. */
2047 u = utf_new(text + 1, namelen - 1);
2049 comp = load_class_from_classloader(u, loader);
2054 assert(comp->state & CLASS_LOADED);
2056 /* the array's flags are that of the component class */
2057 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2058 c->classloader = comp->classloader;
2062 /* c is an array of objects. */
2064 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2065 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2066 exceptions_throw_classnotfoundexception(c->name);
2070 u = utf_new(text + 2, namelen - 3);
2072 if (!(comp = load_class_from_classloader(u, loader)))
2075 assert(comp->state & CLASS_LOADED);
2077 /* the array's flags are that of the component class */
2078 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2079 c->classloader = comp->classloader;
2083 /* c is an array of a primitive type */
2085 /* check for cases like `[II' and whether the character is a
2086 valid primitive type */
2088 if ((namelen > 2) || (primitive_class_get_by_char(text[1]) == NULL)) {
2089 exceptions_throw_classnotfoundexception(c->name);
2093 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2094 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2095 c->classloader = NULL;
2098 assert(class_java_lang_Object);
2099 #if defined(ENABLE_JAVASE)
2100 assert(class_java_lang_Cloneable);
2101 assert(class_java_io_Serializable);
2104 /* Setup the array class. */
2106 c->super = class_java_lang_Object;
2108 #if defined(ENABLE_JAVASE)
2110 c->interfacescount = 2;
2111 c->interfaces = MNEW(classinfo*, 2);
2112 c->interfaces[0] = class_java_lang_Cloneable;
2113 c->interfaces[1] = class_java_io_Serializable;
2115 #elif defined(ENABLE_JAVAME_CLDC1_1)
2117 c->interfacescount = 0;
2118 c->interfaces = NULL;
2121 # error unknow Java configuration
2124 c->methodscount = 1;
2125 c->methods = MNEW(methodinfo, c->methodscount);
2127 MZERO(c->methods, methodinfo, c->methodscount);
2129 classrefs = MNEW(constant_classref, 2);
2131 CLASSREF_INIT(classrefs[0], c, c->name);
2132 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2134 /* create descriptor for clone method */
2135 /* we need one paramslot which is reserved for the 'this' parameter */
2136 clonedesc = NEW(methoddesc);
2137 clonedesc->returntype.type = TYPE_ADR;
2138 clonedesc->returntype.classref = classrefs + 1;
2139 clonedesc->returntype.arraydim = 0;
2140 /* initialize params to "empty", add real params below in
2141 descriptor_params_from_paramtypes */
2142 clonedesc->paramcount = 0;
2143 clonedesc->paramslots = 0;
2144 clonedesc->paramtypes[0].classref = classrefs + 0;
2145 clonedesc->params = NULL;
2147 /* create methodinfo */
2150 MSET(clone, 0, methodinfo, 1);
2152 #if defined(ENABLE_THREADS)
2153 lock_init_object_lock(&clone->header);
2156 /* ATTENTION: if you delete the ACC_NATIVE below, set
2157 clone->maxlocals=1 (interpreter related) */
2159 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2160 clone->name = utf_clone;
2161 clone->descriptor = utf_void__java_lang_Object;
2162 clone->parseddesc = clonedesc;
2165 /* parse the descriptor to get the register allocation */
2167 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2170 clone->code = codegen_generate_stub_native(clone, BUILTIN_clone);
2172 /* XXX: field: length? */
2174 /* array classes are not loaded from class files */
2176 c->state |= CLASS_LOADED;
2177 c->parseddescs = (u1 *) clonedesc;
2178 c->parseddescsize = sizeof(methodinfo);
2179 c->classrefs = classrefs;
2180 c->classrefcount = 1;
2182 /* insert class into the loaded class cache */
2183 /* XXX free classinfo if NULL returned? */
2185 return classcache_store(loader, c, true);
2189 /* loader_close ****************************************************************
2191 Frees all resources.
2193 *******************************************************************************/
2195 void loader_close(void)
2202 * These are local overrides for various environment variables in Emacs.
2203 * Please do not remove this and leave it at the end of the file, where
2204 * Emacs will automagically detect them.
2205 * ---------------------------------------------------------------------
2208 * indent-tabs-mode: t
2212 * vim:noexpandtab:sw=4:ts=4: