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/primitive.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/linker.h"
62 #include "vmcore/loader.h"
63 #include "vmcore/method.h"
64 #include "vmcore/options.h"
65 #include "vmcore/rt-timing.h"
67 #if defined(ENABLE_STATISTICS)
68 # include "vmcore/statistics.h"
71 #include "vmcore/suck.h"
73 #if defined(ENABLE_ZLIB)
74 # include "vmcore/zip.h"
77 #if defined(ENABLE_JVMTI)
78 # include "native/jvmti/cacaodbg.h"
82 /* global variables ***********************************************************/
84 static hashtable *hashtable_classloader;
87 /* loader_preinit **************************************************************
89 Initializes the classpath list and loads classes required for the
92 *******************************************************************************/
94 void loader_preinit(void)
96 #if defined(ENABLE_THREADS)
97 list_classpath_entry *lce;
99 /* Initialize the monitor pointer for zip/jar file locking. */
101 for (lce = list_first(list_classpath_entries); lce != NULL;
102 lce = list_next(list_classpath_entries, lce)) {
103 if (lce->type == CLASSPATH_ARCHIVE)
104 LOCK_INIT_OBJECT_LOCK(lce);
108 /* initialize classloader hashtable, 10 entries should be enough */
110 hashtable_classloader = NEW(hashtable);
111 hashtable_create(hashtable_classloader, 10);
113 /* Load the most basic class. */
115 if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
116 vm_abort("loader_preinit: loading java/lang/Object failed");
118 #if defined(ENABLE_JAVASE)
119 if (!(class_java_lang_Cloneable =
120 load_class_bootstrap(utf_java_lang_Cloneable)))
121 vm_abort("loader_preinit: loading java/lang/Cloneable failed");
123 if (!(class_java_io_Serializable =
124 load_class_bootstrap(utf_java_io_Serializable)))
125 vm_abort("loader_preinit: loading java/io/Serializable failed");
130 /* loader_init *****************************************************************
132 Loads all classes required in the VM.
134 *******************************************************************************/
136 void loader_init(void)
138 /* Load primitive-type wrapping classes. */
140 #if defined(ENABLE_JAVASE)
141 if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
142 vm_abort("loader_init: loading failed");
145 if (!(class_java_lang_Boolean =
146 load_class_bootstrap(utf_java_lang_Boolean)))
147 vm_abort("loader_init: loading failed");
149 if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
150 vm_abort("loader_init: loading failed");
152 if (!(class_java_lang_Character =
153 load_class_bootstrap(utf_java_lang_Character)))
154 vm_abort("loader_init: loading failed");
156 if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
157 vm_abort("loader_init: loading failed");
159 if (!(class_java_lang_Integer =
160 load_class_bootstrap(utf_java_lang_Integer)))
161 vm_abort("loader_init: loading failed");
163 if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
164 vm_abort("loader_init: loading failed");
166 if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
167 vm_abort("loader_init: loading failed");
169 if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
170 vm_abort("loader_init: loading failed");
172 /* Load important system classes. */
174 if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
175 vm_abort("loader_init: loading failed");
177 if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
178 vm_abort("loader_init: loading failed");
180 #if defined(ENABLE_JAVASE)
181 if (!(class_java_lang_ClassLoader =
182 load_class_bootstrap(utf_java_lang_ClassLoader)))
183 vm_abort("loader_init: loading failed");
185 if (!(class_java_lang_SecurityManager =
186 load_class_bootstrap(utf_java_lang_SecurityManager)))
187 vm_abort("loader_init: loading failed");
190 if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
191 vm_abort("loader_init: loading failed");
193 if (!(class_java_lang_Thread =
194 load_class_bootstrap(utf_new_char("java/lang/Thread"))))
195 vm_abort("loader_init: loading failed");
197 #if defined(ENABLE_JAVASE)
198 if (!(class_java_lang_ThreadGroup =
199 load_class_bootstrap(utf_java_lang_ThreadGroup)))
200 vm_abort("loader_init: loading failed");
203 #if defined(WITH_CLASSPATH_GNU)
204 if (!(class_java_lang_VMSystem =
205 load_class_bootstrap(utf_new_char("java/lang/VMSystem"))))
206 vm_abort("loader_init: loading failed");
208 if (!(class_java_lang_VMThread =
209 load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
210 vm_abort("loader_init: loading failed");
214 /* some classes which may be used more often */
216 #if defined(ENABLE_JAVASE)
217 if (!(class_java_lang_StackTraceElement =
218 load_class_bootstrap(utf_java_lang_StackTraceElement)))
219 vm_abort("loader_init: loading failed");
221 if (!(class_java_lang_reflect_Constructor =
222 load_class_bootstrap(utf_java_lang_reflect_Constructor)))
223 vm_abort("loader_init: loading failed");
225 if (!(class_java_lang_reflect_Field =
226 load_class_bootstrap(utf_java_lang_reflect_Field)))
227 vm_abort("loader_init: loading failed");
229 if (!(class_java_lang_reflect_Method =
230 load_class_bootstrap(utf_java_lang_reflect_Method)))
231 vm_abort("loader_init: loading failed");
233 if (!(class_java_security_PrivilegedAction =
234 load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
235 vm_abort("loader_init: loading failed");
237 if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
238 vm_abort("loader_init: loading failed");
240 # if defined(WITH_CLASSPATH_SUN)
241 if (!(class_sun_reflect_MagicAccessorImpl =
242 load_class_bootstrap(utf_new_char("sun/reflect/MagicAccessorImpl"))))
243 vm_abort("loader_init: loading failed");
246 if (!(arrayclass_java_lang_Object =
247 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
250 # if defined(ENABLE_ANNOTATIONS)
251 /* needed by annotation support */
252 if (!(class_sun_reflect_ConstantPool =
253 load_class_bootstrap(utf_new_char("sun/reflect/ConstantPool"))))
254 vm_abort("loader_init: loading failed");
256 # if defined(WITH_CLASSPATH_GNU)
257 /* needed by GNU Classpaths annotation support */
258 if (!(class_sun_reflect_annotation_AnnotationParser =
259 load_class_bootstrap(utf_new_char("sun/reflect/annotation/AnnotationParser"))))
260 vm_abort("loader_init: loading failed");
270 /* loader_hashtable_classloader_add ********************************************
272 Adds an entry to the classloader hashtable.
274 REMEMBER: Also use this to register native loaders!
276 *******************************************************************************/
278 classloader *loader_hashtable_classloader_add(java_handle_t *cl)
280 hashtable_classloader_entry *cle;
287 LOCK_MONITOR_ENTER(hashtable_classloader->header);
291 /* key for entry is the hashcode of the classloader;
292 aligned to 16-byte boundaries */
294 #if defined(ENABLE_GC_CACAO)
295 key = heap_get_hashcode(LLNI_DIRECT(cl)) >> 4;
297 key = ((u4) (ptrint) cl) >> 4;
300 slot = key & (hashtable_classloader->size - 1);
301 cle = hashtable_classloader->ptr[slot];
303 /* search hashchain for existing entry */
306 if (cle->object == LLNI_DIRECT(cl))
314 /* if no classloader was found, we create a new entry here */
317 cle = NEW(hashtable_classloader_entry);
319 #if defined(ENABLE_GC_CACAO)
320 /* register the classloader object with the GC */
322 gc_reference_register(&(cle->object), GC_REFTYPE_CLASSLOADER);
327 cle->object = LLNI_DIRECT(cl);
331 /* insert entry into hashtable */
333 cle->hashlink = hashtable_classloader->ptr[slot];
334 hashtable_classloader->ptr[slot] = cle;
336 /* update number of entries */
338 hashtable_classloader->entries++;
342 LOCK_MONITOR_EXIT(hashtable_classloader->header);
348 /* loader_hashtable_classloader_find *******************************************
350 Find an entry in the classloader hashtable.
352 *******************************************************************************/
354 classloader *loader_hashtable_classloader_find(java_handle_t *cl)
356 hashtable_classloader_entry *cle;
365 /* key for entry is the hashcode of the classloader;
366 aligned to 16-byte boundaries */
368 #if defined(ENABLE_GC_CACAO)
369 key = heap_get_hashcode(LLNI_DIRECT(cl)) >> 4;
371 key = ((u4) (ptrint) cl) >> 4;
374 slot = key & (hashtable_classloader->size - 1);
375 cle = hashtable_classloader->ptr[slot];
377 /* search hashchain for existing entry */
380 if (cle->object == LLNI_DIRECT(cl))
392 /* loader_load_all_classes *****************************************************
394 Loads all classes specified in the BOOTCLASSPATH.
396 *******************************************************************************/
398 void loader_load_all_classes(void)
400 list_classpath_entry *lce;
401 #if defined(ENABLE_ZLIB)
404 hashtable_zipfile_entry *htzfe;
408 for (lce = list_first(list_classpath_entries); lce != NULL;
409 lce = list_next(list_classpath_entries, lce)) {
410 #if defined(ENABLE_ZLIB)
411 if (lce->type == CLASSPATH_ARCHIVE) {
412 /* get the classes hashtable */
416 for (slot = 0; slot < ht->size; slot++) {
417 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
419 for (; htzfe; htzfe = htzfe->hashlink) {
422 /* skip all entries in META-INF and .properties,
425 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
426 strstr(u->text, ".properties") ||
427 strstr(u->text, ".png"))
430 /* load class from bootstrap classloader */
432 if (!load_class_bootstrap(u)) {
433 fprintf(stderr, "Error loading: ");
434 utf_fprint_printable_ascii_classname(stderr, u);
435 fprintf(stderr, "\n");
438 /* print out exception and cause */
440 exceptions_print_current_exception();
448 #if defined(ENABLE_ZLIB)
455 /* loader_skip_attribute_body **************************************************
457 Skips an attribute the attribute_name_index has already been read.
460 u2 attribute_name_index;
462 u1 info[attribute_length];
465 *******************************************************************************/
467 bool loader_skip_attribute_body(classbuffer *cb)
471 if (!suck_check_classbuffer_size(cb, 4))
474 attribute_length = suck_u4(cb);
476 if (!suck_check_classbuffer_size(cb, attribute_length))
479 suck_skip_nbytes(cb, attribute_length);
485 /* load_constantpool ***********************************************************
487 Loads the constantpool of a class, the entries are transformed into
488 a simpler format by resolving references (a detailed overview of
489 the compact structures can be found in global.h).
491 *******************************************************************************/
493 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
496 /* The following structures are used to save information which cannot be
497 processed during the first pass. After the complete constantpool has
498 been traversed the references can be resolved.
499 (only in specific order) */
501 /* CONSTANT_Class entries */
502 typedef struct forward_class {
503 struct forward_class *next;
508 /* CONSTANT_String */
509 typedef struct forward_string {
510 struct forward_string *next;
515 /* CONSTANT_NameAndType */
516 typedef struct forward_nameandtype {
517 struct forward_nameandtype *next;
521 } forward_nameandtype;
523 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
524 typedef struct forward_fieldmethint {
525 struct forward_fieldmethint *next;
529 u2 nameandtype_index;
530 } forward_fieldmethint;
536 forward_class *forward_classes = NULL;
537 forward_string *forward_strings = NULL;
538 forward_nameandtype *forward_nameandtypes = NULL;
539 forward_fieldmethint *forward_fieldmethints = NULL;
543 forward_nameandtype *nfn;
544 forward_fieldmethint *nff;
552 /* number of entries in the constant_pool table plus one */
553 if (!suck_check_classbuffer_size(cb, 2))
556 cpcount = c->cpcount = suck_u2(cb);
558 /* allocate memory */
559 cptags = c->cptags = MNEW(u1, cpcount);
560 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
563 exceptions_throw_classformaterror(c, "Illegal constant pool size");
567 #if defined(ENABLE_STATISTICS)
569 count_const_pool_len += (sizeof(u1) + sizeof(voidptr)) * cpcount;
572 /* initialize constantpool */
573 for (idx = 0; idx < cpcount; idx++) {
574 cptags[idx] = CONSTANT_UNUSED;
579 /******* first pass *******/
580 /* entries which cannot be resolved now are written into
581 temporary structures and traversed again later */
584 while (idx < cpcount) {
587 /* get constant type */
588 if (!suck_check_classbuffer_size(cb, 1))
595 nfc = DNEW(forward_class);
597 nfc->next = forward_classes;
598 forward_classes = nfc;
600 nfc->thisindex = idx;
601 /* reference to CONSTANT_NameAndType */
602 if (!suck_check_classbuffer_size(cb, 2))
605 nfc->name_index = suck_u2(cb);
610 case CONSTANT_String:
611 nfs = DNEW(forward_string);
613 nfs->next = forward_strings;
614 forward_strings = nfs;
616 nfs->thisindex = idx;
618 /* reference to CONSTANT_Utf8_info with string characters */
619 if (!suck_check_classbuffer_size(cb, 2))
622 nfs->string_index = suck_u2(cb);
627 case CONSTANT_NameAndType:
628 nfn = DNEW(forward_nameandtype);
630 nfn->next = forward_nameandtypes;
631 forward_nameandtypes = nfn;
633 nfn->thisindex = idx;
635 if (!suck_check_classbuffer_size(cb, 2 + 2))
638 /* reference to CONSTANT_Utf8_info containing simple name */
639 nfn->name_index = suck_u2(cb);
641 /* reference to CONSTANT_Utf8_info containing field or method
643 nfn->sig_index = suck_u2(cb);
648 case CONSTANT_Fieldref:
649 case CONSTANT_Methodref:
650 case CONSTANT_InterfaceMethodref:
651 nff = DNEW(forward_fieldmethint);
653 nff->next = forward_fieldmethints;
654 forward_fieldmethints = nff;
656 nff->thisindex = idx;
660 if (!suck_check_classbuffer_size(cb, 2 + 2))
663 /* class or interface type that contains the declaration of the
665 nff->class_index = suck_u2(cb);
667 /* name and descriptor of the field or method */
668 nff->nameandtype_index = suck_u2(cb);
673 case CONSTANT_Integer: {
674 constant_integer *ci = NEW(constant_integer);
676 #if defined(ENABLE_STATISTICS)
678 count_const_pool_len += sizeof(constant_integer);
681 if (!suck_check_classbuffer_size(cb, 4))
684 ci->value = suck_s4(cb);
685 cptags[idx] = CONSTANT_Integer;
692 case CONSTANT_Float: {
693 constant_float *cf = NEW(constant_float);
695 #if defined(ENABLE_STATISTICS)
697 count_const_pool_len += sizeof(constant_float);
700 if (!suck_check_classbuffer_size(cb, 4))
703 cf->value = suck_float(cb);
704 cptags[idx] = CONSTANT_Float;
711 case CONSTANT_Long: {
712 constant_long *cl = NEW(constant_long);
714 #if defined(ENABLE_STATISTICS)
716 count_const_pool_len += sizeof(constant_long);
719 if (!suck_check_classbuffer_size(cb, 8))
722 cl->value = suck_s8(cb);
723 cptags[idx] = CONSTANT_Long;
727 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
733 case CONSTANT_Double: {
734 constant_double *cd = NEW(constant_double);
736 #if defined(ENABLE_STATISTICS)
738 count_const_pool_len += sizeof(constant_double);
741 if (!suck_check_classbuffer_size(cb, 8))
744 cd->value = suck_double(cb);
745 cptags[idx] = CONSTANT_Double;
749 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
755 case CONSTANT_Utf8: {
758 /* number of bytes in the bytes array (not string-length) */
759 if (!suck_check_classbuffer_size(cb, 2))
762 length = suck_u2(cb);
763 cptags[idx] = CONSTANT_Utf8;
765 /* validate the string */
766 if (!suck_check_classbuffer_size(cb, length))
769 #ifdef ENABLE_VERIFIER
771 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
773 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
776 #endif /* ENABLE_VERIFIER */
777 /* insert utf-string into the utf-symboltable */
778 cpinfos[idx] = utf_new((char *) cb->pos, length);
780 /* skip bytes of the string (buffer size check above) */
781 suck_skip_nbytes(cb, length);
787 exceptions_throw_classformaterror(c, "Illegal constant pool type");
793 /* resolve entries in temporary structures */
795 while (forward_classes) {
797 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
801 #ifdef ENABLE_VERIFIER
802 if (opt_verify && !is_valid_name_utf(name)) {
803 exceptions_throw_classformaterror(c, "Class reference with invalid name");
806 #endif /* ENABLE_VERIFIER */
808 /* add all class references to the descriptor_pool */
810 if (!descriptor_pool_add_class(descpool, name))
813 cptags[forward_classes->thisindex] = CONSTANT_Class;
815 /* the classref is created later */
816 cpinfos[forward_classes->thisindex] = name;
818 nfc = forward_classes;
819 forward_classes = forward_classes->next;
822 while (forward_strings) {
824 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
828 /* resolve utf-string */
829 cptags[forward_strings->thisindex] = CONSTANT_String;
830 cpinfos[forward_strings->thisindex] = text;
832 nfs = forward_strings;
833 forward_strings = forward_strings->next;
836 while (forward_nameandtypes) {
837 constant_nameandtype *cn = NEW(constant_nameandtype);
839 #if defined(ENABLE_STATISTICS)
841 count_const_pool_len += sizeof(constant_nameandtype);
844 /* resolve simple name and descriptor */
845 cn->name = class_getconstant(c,
846 forward_nameandtypes->name_index,
851 cn->descriptor = class_getconstant(c,
852 forward_nameandtypes->sig_index,
857 #ifdef ENABLE_VERIFIER
860 if (!is_valid_name_utf(cn->name)) {
861 exceptions_throw_classformaterror(c,
862 "Illegal Field name \"%s\"",
868 /* disallow referencing <clinit> among others */
869 if (cn->name->text[0] == '<' && cn->name != utf_init) {
870 exceptions_throw_classformaterror(c, "Illegal reference to special method");
874 #endif /* ENABLE_VERIFIER */
876 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
877 cpinfos[forward_nameandtypes->thisindex] = cn;
879 nfn = forward_nameandtypes;
880 forward_nameandtypes = forward_nameandtypes->next;
883 while (forward_fieldmethints) {
884 constant_nameandtype *nat;
885 constant_FMIref *fmi = NEW(constant_FMIref);
887 #if defined(ENABLE_STATISTICS)
889 count_const_pool_len += sizeof(constant_FMIref);
891 /* resolve simple name and descriptor */
893 nat = class_getconstant(c,
894 forward_fieldmethints->nameandtype_index,
895 CONSTANT_NameAndType);
899 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
901 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
904 /* the classref is created later */
906 fmi->p.index = forward_fieldmethints->class_index;
907 fmi->name = nat->name;
908 fmi->descriptor = nat->descriptor;
910 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
911 cpinfos[forward_fieldmethints->thisindex] = fmi;
913 nff = forward_fieldmethints;
914 forward_fieldmethints = forward_fieldmethints->next;
917 /* everything was ok */
923 /* loader_load_attribute_signature *********************************************
925 Signature_attribute {
926 u2 attribute_name_index;
931 *******************************************************************************/
933 #if defined(ENABLE_JAVASE)
934 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
944 /* check remaining bytecode */
946 if (!suck_check_classbuffer_size(cb, 4 + 2))
949 /* check attribute length */
951 attribute_length = suck_u4(cb);
953 if (attribute_length != 2) {
954 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
958 if (*signature != NULL) {
959 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
965 signature_index = suck_u2(cb);
967 if (!(*signature = class_getconstant(c, signature_index, CONSTANT_Utf8)))
972 #endif /* defined(ENABLE_JAVASE) */
975 /* load_class_from_sysloader ***************************************************
977 Load the class with the given name using the system class loader
980 name.............the classname
984 NULL if an exception has been thrown
986 *******************************************************************************/
988 classinfo *load_class_from_sysloader(utf *name)
995 assert(class_java_lang_Object);
996 assert(class_java_lang_ClassLoader);
997 assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
999 m = class_resolveclassmethod(class_java_lang_ClassLoader,
1000 utf_getSystemClassLoader,
1001 utf_void__java_lang_ClassLoader,
1002 class_java_lang_Object,
1008 clo = vm_call_method(m, NULL);
1013 cl = loader_hashtable_classloader_add(clo);
1015 c = load_class_from_classloader(name, cl);
1021 /* load_class_from_classloader *************************************************
1023 Load the class with the given name using the given user-defined class loader.
1026 name.............the classname
1027 cl...............user-defined class loader
1030 the loaded class, or
1031 NULL if an exception has been thrown
1033 *******************************************************************************/
1035 classinfo *load_class_from_classloader(utf *name, classloader *cl)
1040 java_handle_t *string;
1041 #if defined(ENABLE_RT_TIMING)
1042 struct timespec time_start, time_lookup, time_prepare, time_java,
1046 RT_TIMING_GET_TIME(time_start);
1050 /* lookup if this class has already been loaded */
1052 c = classcache_lookup(cl, name);
1054 RT_TIMING_GET_TIME(time_lookup);
1055 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1060 /* if other class loader than bootstrap, call it */
1068 namelen = name->blength;
1070 /* handle array classes */
1071 if (text[0] == '[') {
1077 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1078 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1079 exceptions_throw_classnotfoundexception(name);
1083 u = utf_new(text + 2, namelen - 3);
1085 if (!(comp = load_class_from_classloader(u, cl)))
1088 /* create the array class */
1090 c = class_array_of(comp, false);
1092 tmpc = classcache_store(cl, c, true);
1095 /* exception, free the loaded class */
1096 c->state &= ~CLASS_LOADING;
1103 /* load the component class */
1105 u = utf_new(text + 1, namelen - 1);
1107 if (!(comp = load_class_from_classloader(u, cl)))
1110 /* create the array class */
1112 c = class_array_of(comp, false);
1114 tmpc = classcache_store(cl, c, true);
1117 /* exception, free the loaded class */
1118 c->state &= ~CLASS_LOADING;
1125 /* primitive array classes are loaded by the bootstrap loader */
1127 c = load_class_bootstrap(name);
1133 #if defined(WITH_CLASSPATH_SUN)
1134 /* OpenJDK uses this internal function because it's
1137 lc = class_resolveclassmethod(cl->object->vftbl->class,
1138 utf_loadClassInternal,
1139 utf_java_lang_String__java_lang_Class,
1143 lc = class_resolveclassmethod(cl->vftbl->class,
1145 utf_java_lang_String__java_lang_Class,
1151 return false; /* exception */
1153 /* move return value into `o' and cast it afterwards to a classinfo* */
1155 string = javastring_new_slash_to_dot(name);
1157 RT_TIMING_GET_TIME(time_prepare);
1159 #if defined(ENABLE_HANDLES)
1160 o = vm_call_method(lc, (java_handle_t *) cl, string);
1162 o = vm_call_method(lc, cl->object, string);
1165 RT_TIMING_GET_TIME(time_java);
1167 c = LLNI_classinfo_unwrap(o);
1170 /* Store this class in the loaded class cache. If another
1171 class with the same (initloader,name) pair has been
1172 stored earlier it will be returned by classcache_store
1173 In this case classcache_store may not free the class
1174 because it has already been exposed to Java code which
1175 may have kept references to that class. */
1177 tmpc = classcache_store(cl, c, false);
1180 /* exception, free the loaded class */
1181 c->state &= ~CLASS_LOADING;
1188 RT_TIMING_GET_TIME(time_cache);
1190 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1191 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1192 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1194 /* SUN compatible -verbose:class output */
1196 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1198 utf_display_printable_ascii_classname(name);
1202 #if defined(ENABLE_JVMTI)
1203 /* fire Class Load JVMTI event */
1204 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1211 c = load_class_bootstrap(name);
1217 /* load_class_bootstrap ********************************************************
1219 Load the class with the given name using the bootstrap class loader.
1222 name.............the classname
1225 loaded classinfo, or
1226 NULL if an exception has been thrown
1229 load_class_bootstrap is synchronized. It can be treated as an
1232 *******************************************************************************/
1234 classinfo *load_class_bootstrap(utf *name)
1239 #if defined(ENABLE_RT_TIMING)
1240 struct timespec time_start, time_lookup, time_array, time_suck,
1241 time_load, time_cache;
1244 RT_TIMING_GET_TIME(time_start);
1250 /* lookup if this class has already been loaded */
1252 r = classcache_lookup(NULL, name);
1255 RT_TIMING_GET_TIME(time_lookup);
1256 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1261 RT_TIMING_GET_TIME(time_lookup);
1262 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1264 /* create the classinfo */
1266 c = class_create_classinfo(name);
1268 /* handle array classes */
1270 if (name->text[0] == '[') {
1271 c = load_newly_created_array(c, NULL);
1276 assert(c->state & CLASS_LOADED);
1278 RT_TIMING_GET_TIME(time_array);
1279 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1284 #if defined(ENABLE_STATISTICS)
1287 if (opt_getcompilingtime)
1288 compilingtime_stop();
1290 if (opt_getloadingtime)
1291 loadingtime_start();
1294 /* load classdata, throw exception on error */
1299 /* this normally means, the classpath was not set properly */
1301 if (name == utf_java_lang_Object)
1302 vm_abort("java/lang/NoClassDefFoundError: java/lang/Object");
1304 exceptions_throw_classnotfoundexception(name);
1309 RT_TIMING_GET_TIME(time_suck);
1311 /* load the class from the buffer */
1313 r = load_class_from_classbuffer(cb);
1315 RT_TIMING_GET_TIME(time_load);
1318 /* the class could not be loaded, free the classinfo struct */
1323 /* Store this class in the loaded class cache this step also
1324 checks the loading constraints. If the class has been loaded
1325 before, the earlier loaded class is returned. */
1327 classinfo *res = classcache_store(NULL, c, true);
1337 RT_TIMING_GET_TIME(time_cache);
1339 /* SUN compatible -verbose:class output */
1341 if (opt_verboseclass && r) {
1343 utf_display_printable_ascii_classname(name);
1344 printf(" from %s]\n", cb->path);
1351 #if defined(ENABLE_STATISTICS)
1354 if (opt_getloadingtime)
1357 if (opt_getcompilingtime)
1358 compilingtime_start();
1361 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1362 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1363 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1364 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1370 /* load_class_from_classbuffer_intern ******************************************
1372 Loads a class from a classbuffer into a given classinfo structure.
1373 Super-classes are also loaded at this point and some verfication
1377 This function is NOT synchronized!
1379 *******************************************************************************/
1381 static bool load_class_from_classbuffer_intern(classbuffer *cb)
1388 descriptor_pool *descpool;
1389 #if defined(ENABLE_STATISTICS)
1393 #if defined(ENABLE_RT_TIMING)
1394 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1395 time_setup, time_fields, time_methods, time_classrefs,
1396 time_descs, time_setrefs, time_parsefds, time_parsemds,
1397 time_parsecpool, time_verify, time_attrs;
1400 RT_TIMING_GET_TIME(time_start);
1402 /* Get the classbuffer's class. */
1406 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1409 /* check signature */
1411 if (suck_u4(cb) != MAGIC) {
1412 exceptions_throw_classformaterror(c, "Bad magic number");
1421 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1422 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1426 RT_TIMING_GET_TIME(time_checks);
1428 /* create a new descriptor pool */
1430 descpool = descriptor_pool_new(c);
1432 RT_TIMING_GET_TIME(time_ndpool);
1434 /* load the constant pool */
1436 if (!load_constantpool(cb, descpool))
1439 RT_TIMING_GET_TIME(time_cpool);
1443 if (!suck_check_classbuffer_size(cb, 2))
1446 /* We OR the flags here, as we set already some flags in
1447 class_create_classinfo. */
1449 c->flags |= suck_u2(cb);
1451 /* check ACC flags consistency */
1453 if (c->flags & ACC_INTERFACE) {
1454 if (!(c->flags & ACC_ABSTRACT)) {
1455 /* We work around this because interfaces in JDK 1.1 are
1456 * not declared abstract. */
1458 c->flags |= ACC_ABSTRACT;
1461 if (c->flags & ACC_FINAL) {
1462 exceptions_throw_classformaterror(c,
1463 "Illegal class modifiers: 0x%X",
1468 if (c->flags & ACC_SUPER) {
1469 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1473 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1474 exceptions_throw_classformaterror(c,
1475 "Illegal class modifiers: 0x%X",
1480 if (!suck_check_classbuffer_size(cb, 2 + 2))
1487 if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1490 if (c->name == utf_not_named_yet) {
1491 /* we finally have a name for this class */
1493 class_set_packagename(c);
1495 else if (name != c->name) {
1496 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
1500 /* retrieve superclass */
1502 c->super.any = NULL;
1504 if ((i = suck_u2(cb))) {
1505 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1508 /* java.lang.Object may not have a super class. */
1510 if (c->name == utf_java_lang_Object) {
1511 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
1515 /* Interfaces must have java.lang.Object as super class. */
1517 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
1518 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
1525 /* This is only allowed for java.lang.Object. */
1527 if (c->name != utf_java_lang_Object) {
1528 exceptions_throw_classformaterror(c, "Bad superclass index");
1533 /* retrieve interfaces */
1535 if (!suck_check_classbuffer_size(cb, 2))
1538 c->interfacescount = suck_u2(cb);
1540 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1543 c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
1545 for (i = 0; i < c->interfacescount; i++) {
1546 /* the classrefs are created later */
1547 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1551 RT_TIMING_GET_TIME(time_setup);
1555 if (!suck_check_classbuffer_size(cb, 2))
1558 c->fieldscount = suck_u2(cb);
1559 c->fields = MNEW(fieldinfo, c->fieldscount);
1561 MZERO(c->fields, fieldinfo, c->fieldscount);
1563 for (i = 0; i < c->fieldscount; i++) {
1564 if (!field_load(cb, &(c->fields[i]), descpool))
1568 RT_TIMING_GET_TIME(time_fields);
1572 if (!suck_check_classbuffer_size(cb, 2))
1575 c->methodscount = suck_u2(cb);
1576 c->methods = MNEW(methodinfo, c->methodscount);
1578 MZERO(c->methods, methodinfo, c->methodscount);
1580 for (i = 0; i < c->methodscount; i++) {
1581 if (!method_load(cb, &(c->methods[i]), descpool))
1585 RT_TIMING_GET_TIME(time_methods);
1587 /* create the class reference table */
1590 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
1592 RT_TIMING_GET_TIME(time_classrefs);
1594 /* allocate space for the parsed descriptors */
1596 descriptor_pool_alloc_parsed_descriptors(descpool);
1598 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
1600 #if defined(ENABLE_STATISTICS)
1602 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
1603 count_classref_len += classrefsize;
1604 count_parsed_desc_len += descsize;
1608 RT_TIMING_GET_TIME(time_descs);
1610 /* put the classrefs in the constant pool */
1611 for (i = 0; i < c->cpcount; i++) {
1612 if (c->cptags[i] == CONSTANT_Class) {
1613 utf *name = (utf *) c->cpinfos[i];
1614 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
1618 /* set the super class reference */
1621 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
1626 /* set the super interfaces references */
1628 for (i = 0; i < c->interfacescount; i++) {
1629 c->interfaces[i].ref =
1630 descriptor_pool_lookup_classref(descpool,
1631 (utf *) c->interfaces[i].any);
1632 if (!c->interfaces[i].ref)
1636 RT_TIMING_GET_TIME(time_setrefs);
1638 /* parse field descriptors */
1640 for (i = 0; i < c->fieldscount; i++) {
1641 c->fields[i].parseddesc =
1642 descriptor_pool_parse_field_descriptor(descpool,
1643 c->fields[i].descriptor);
1644 if (!c->fields[i].parseddesc)
1648 RT_TIMING_GET_TIME(time_parsefds);
1650 /* parse method descriptors */
1652 for (i = 0; i < c->methodscount; i++) {
1653 methodinfo *m = &c->methods[i];
1655 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
1656 m->flags, class_get_self_classref(m->class));
1660 for (j = 0; j < m->rawexceptiontablelength; j++) {
1661 if (!m->rawexceptiontable[j].catchtype.any)
1664 if ((m->rawexceptiontable[j].catchtype.ref =
1665 descriptor_pool_lookup_classref(descpool,
1666 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
1670 for (j = 0; j < m->thrownexceptionscount; j++) {
1671 if (!m->thrownexceptions[j].any)
1674 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
1675 (utf *) m->thrownexceptions[j].any)) == NULL)
1680 RT_TIMING_GET_TIME(time_parsemds);
1682 /* parse the loaded descriptors */
1684 for (i = 0; i < c->cpcount; i++) {
1685 constant_FMIref *fmi;
1688 switch (c->cptags[i]) {
1689 case CONSTANT_Fieldref:
1690 fmi = (constant_FMIref *) c->cpinfos[i];
1691 fmi->parseddesc.fd =
1692 descriptor_pool_parse_field_descriptor(descpool,
1694 if (!fmi->parseddesc.fd)
1697 index = fmi->p.index;
1699 (constant_classref *) class_getconstant(c, index,
1701 if (!fmi->p.classref)
1704 case CONSTANT_Methodref:
1705 case CONSTANT_InterfaceMethodref:
1706 fmi = (constant_FMIref *) c->cpinfos[i];
1707 index = fmi->p.index;
1709 (constant_classref *) class_getconstant(c, index,
1711 if (!fmi->p.classref)
1713 fmi->parseddesc.md =
1714 descriptor_pool_parse_method_descriptor(descpool,
1718 if (!fmi->parseddesc.md)
1724 RT_TIMING_GET_TIME(time_parsecpool);
1726 #ifdef ENABLE_VERIFIER
1727 /* Check if all fields and methods can be uniquely
1728 * identified by (name,descriptor). */
1731 /* We use a hash table here to avoid making the
1732 * average case quadratic in # of methods, fields.
1734 static int shift = 0;
1736 u2 *next; /* for chaining colliding hash entries */
1742 /* Allocate hashtable */
1743 len = c->methodscount;
1744 if (len < c->fieldscount) len = c->fieldscount;
1746 hashtab = MNEW(u2,(hashlen + len));
1747 next = hashtab + hashlen;
1749 /* Determine bitshift (to get good hash values) */
1759 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
1761 for (i = 0; i < c->fieldscount; ++i) {
1762 fieldinfo *fi = c->fields + i;
1764 /* It's ok if we lose bits here */
1765 index = ((((size_t) fi->name) +
1766 ((size_t) fi->descriptor)) >> shift) % hashlen;
1768 if ((old = hashtab[index])) {
1772 if (c->fields[old].name == fi->name &&
1773 c->fields[old].descriptor == fi->descriptor) {
1774 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
1777 } while ((old = next[old]));
1779 hashtab[index] = i + 1;
1783 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
1785 for (i = 0; i < c->methodscount; ++i) {
1786 methodinfo *mi = c->methods + i;
1788 /* It's ok if we lose bits here */
1789 index = ((((size_t) mi->name) +
1790 ((size_t) mi->descriptor)) >> shift) % hashlen;
1792 if ((old = hashtab[index])) {
1796 if (c->methods[old].name == mi->name &&
1797 c->methods[old].descriptor == mi->descriptor) {
1798 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
1801 } while ((old = next[old]));
1803 hashtab[index] = i + 1;
1806 MFREE(hashtab, u2, (hashlen + len));
1808 #endif /* ENABLE_VERIFIER */
1810 RT_TIMING_GET_TIME(time_verify);
1812 #if defined(ENABLE_STATISTICS)
1814 size_classinfo += sizeof(classinfo*) * c->interfacescount;
1815 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
1816 size_methodinfo += sizeof(methodinfo) * c->methodscount;
1820 /* load attribute structures */
1822 if (!class_load_attributes(cb))
1825 /* Pre Java 1.5 version don't check this. This implementation is
1826 like Java 1.5 do it: for class file version 45.3 we don't check
1827 it, older versions are checked. */
1829 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
1830 /* check if all data has been read */
1831 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
1833 if (classdata_left > 0) {
1834 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
1839 RT_TIMING_GET_TIME(time_attrs);
1841 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
1842 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
1843 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
1844 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
1845 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
1846 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
1847 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
1848 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
1849 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
1850 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
1851 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
1852 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
1853 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
1854 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
1855 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
1861 /* load_class_from_classbuffer *************************************************
1863 Convenience wrapper for load_class_from_classbuffer.
1866 This function is NOT synchronized!
1868 *******************************************************************************/
1870 classinfo *load_class_from_classbuffer(classbuffer *cb)
1876 /* Get the classbuffer's class. */
1880 /* Check if the class is already loaded. */
1882 if (c->state & CLASS_LOADED)
1885 #if defined(ENABLE_STATISTICS)
1887 count_class_loads++;
1890 #if !defined(NDEBUG)
1892 log_message_class("Loading class: ", c);
1895 /* Mark start of dump memory area. */
1897 dumpsize = dump_size();
1899 /* Class is currently loading. */
1901 c->state |= CLASS_LOADING;
1903 /* Parse the classbuffer. */
1905 result = load_class_from_classbuffer_intern(cb);
1907 /* Release dump area. */
1909 dump_release(dumpsize);
1911 /* An error occurred. */
1913 if (result == false) {
1914 /* Revert loading state. */
1916 c->state = (c->state & ~CLASS_LOADING);
1921 /* Revert loading state and set loaded. */
1923 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
1925 #if defined(ENABLE_JVMTI)
1926 /* fire Class Prepare JVMTI event */
1929 jvmti_ClassLoadPrepare(true, c);
1932 #if !defined(NDEBUG)
1934 log_message_class("Loading done class: ", c);
1941 /* load_newly_created_array ****************************************************
1943 Load a newly created array class.
1946 c....................the array class C has been loaded
1947 other classinfo......the array class was found in the class cache,
1949 NULL.................an exception has been thrown
1952 This is an internal function. Do not use it unless you know exactly
1955 Use one of the load_class_... functions for general array class loading.
1957 *******************************************************************************/
1959 classinfo *load_newly_created_array(classinfo *c, classloader *loader)
1961 classinfo *comp = NULL;
1963 methoddesc *clonedesc;
1964 constant_classref *classrefs;
1969 text = c->name->text;
1970 namelen = c->name->blength;
1972 /* Check array class name */
1974 if ((namelen < 2) || (text[0] != '[')) {
1975 exceptions_throw_classnotfoundexception(c->name);
1979 /* Check the element type */
1983 /* c is an array of arrays. We have to create the component class. */
1985 u = utf_new(text + 1, namelen - 1);
1987 comp = load_class_from_classloader(u, loader);
1992 assert(comp->state & CLASS_LOADED);
1994 /* the array's flags are that of the component class */
1995 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
1996 c->classloader = comp->classloader;
2000 /* c is an array of objects. */
2002 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2003 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2004 exceptions_throw_classnotfoundexception(c->name);
2008 u = utf_new(text + 2, namelen - 3);
2010 if (!(comp = load_class_from_classloader(u, loader)))
2013 assert(comp->state & CLASS_LOADED);
2015 /* the array's flags are that of the component class */
2016 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2017 c->classloader = comp->classloader;
2021 /* c is an array of a primitive type */
2023 /* check for cases like `[II' and whether the character is a
2024 valid primitive type */
2026 if ((namelen > 2) || (primitive_class_get_by_char(text[1]) == NULL)) {
2027 exceptions_throw_classnotfoundexception(c->name);
2031 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2032 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2033 c->classloader = NULL;
2036 assert(class_java_lang_Object);
2037 #if defined(ENABLE_JAVASE)
2038 assert(class_java_lang_Cloneable);
2039 assert(class_java_io_Serializable);
2042 /* setup the array class */
2044 c->super.cls = class_java_lang_Object;
2046 #if defined(ENABLE_JAVASE)
2048 c->interfacescount = 2;
2049 c->interfaces = MNEW(classref_or_classinfo, 2);
2050 c->interfaces[0].cls = class_java_lang_Cloneable;
2051 c->interfaces[1].cls = class_java_io_Serializable;
2053 #elif defined(ENABLE_JAVAME_CLDC1_1)
2055 c->interfacescount = 0;
2056 c->interfaces = NULL;
2059 # error unknow Java configuration
2062 c->methodscount = 1;
2063 c->methods = MNEW(methodinfo, c->methodscount);
2064 MZERO(c->methods, methodinfo, c->methodscount);
2066 classrefs = MNEW(constant_classref, 2);
2067 CLASSREF_INIT(classrefs[0], c, c->name);
2068 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2070 /* create descriptor for clone method */
2071 /* we need one paramslot which is reserved for the 'this' parameter */
2072 clonedesc = NEW(methoddesc);
2073 clonedesc->returntype.type = TYPE_ADR;
2074 clonedesc->returntype.classref = classrefs + 1;
2075 clonedesc->returntype.arraydim = 0;
2076 /* initialize params to "empty", add real params below in
2077 descriptor_params_from_paramtypes */
2078 clonedesc->paramcount = 0;
2079 clonedesc->paramslots = 0;
2080 clonedesc->paramtypes[0].classref = classrefs + 0;
2081 clonedesc->params = NULL;
2083 /* create methodinfo */
2086 MSET(clone, 0, methodinfo, 1);
2088 #if defined(ENABLE_THREADS)
2089 lock_init_object_lock(&clone->header);
2092 /* ATTENTION: if you delete the ACC_NATIVE below, set
2093 clone->maxlocals=1 (interpreter related) */
2095 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2096 clone->name = utf_clone;
2097 clone->descriptor = utf_void__java_lang_Object;
2098 clone->parseddesc = clonedesc;
2101 /* parse the descriptor to get the register allocation */
2103 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2106 clone->code = codegen_generate_stub_native(clone, BUILTIN_clone);
2108 /* XXX: field: length? */
2110 /* array classes are not loaded from class files */
2112 c->state |= CLASS_LOADED;
2113 c->parseddescs = (u1 *) clonedesc;
2114 c->parseddescsize = sizeof(methodinfo);
2115 c->classrefs = classrefs;
2116 c->classrefcount = 1;
2118 /* insert class into the loaded class cache */
2119 /* XXX free classinfo if NULL returned? */
2121 return classcache_store(loader, c, true);
2125 /* loader_close ****************************************************************
2127 Frees all resources.
2129 *******************************************************************************/
2131 void loader_close(void)
2138 * These are local overrides for various environment variables in Emacs.
2139 * Please do not remove this and leave it at the end of the file, where
2140 * Emacs will automagically detect them.
2141 * ---------------------------------------------------------------------
2144 * indent-tabs-mode: t
2148 * vim:noexpandtab:sw=4:ts=4: