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
25 $Id: loader.c 8299 2007-08-13 08:41:18Z michi $
38 #include "mm/memory.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_init *****************************************************************
89 Initializes all lists and loads all classes required for the system
92 *******************************************************************************/
94 bool loader_init(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);
107 /* initialize classloader hashtable, 10 entries should be enough */
109 hashtable_classloader = NEW(hashtable);
110 hashtable_create(hashtable_classloader, 10);
112 /* load some important classes */
114 if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
117 if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
120 #if defined(ENABLE_JAVASE)
121 if (!(class_java_lang_Cloneable =
122 load_class_bootstrap(utf_java_lang_Cloneable)))
125 if (!(class_java_io_Serializable =
126 load_class_bootstrap(utf_java_io_Serializable)))
130 /* load classes for wrapping primitive types */
132 #if defined(ENABLE_JAVASE)
133 if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
137 if (!(class_java_lang_Boolean =
138 load_class_bootstrap(utf_java_lang_Boolean)))
141 if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
144 if (!(class_java_lang_Character =
145 load_class_bootstrap(utf_java_lang_Character)))
148 if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
151 if (!(class_java_lang_Integer =
152 load_class_bootstrap(utf_java_lang_Integer)))
155 if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
158 if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
161 if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
165 /* load some other important classes */
167 if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
170 #if defined(ENABLE_JAVASE)
171 if (!(class_java_lang_ClassLoader =
172 load_class_bootstrap(utf_java_lang_ClassLoader)))
175 if (!(class_java_lang_SecurityManager =
176 load_class_bootstrap(utf_java_lang_SecurityManager)))
180 if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
183 if (!(class_java_lang_Thread =
184 load_class_bootstrap(utf_new_char("java/lang/Thread"))))
187 #if defined(ENABLE_JAVASE)
188 if (!(class_java_lang_ThreadGroup =
189 load_class_bootstrap(utf_java_lang_ThreadGroup)))
193 #if defined(WITH_CLASSPATH_GNU)
194 if (!(class_java_lang_VMSystem =
195 load_class_bootstrap(utf_new_char("java/lang/VMSystem"))))
199 if (!(class_java_lang_VMThread =
200 load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
205 /* some classes which may be used more often */
207 #if defined(ENABLE_JAVASE)
208 if (!(class_java_lang_StackTraceElement =
209 load_class_bootstrap(utf_java_lang_StackTraceElement)))
212 if (!(class_java_lang_reflect_Constructor =
213 load_class_bootstrap(utf_java_lang_reflect_Constructor)))
216 if (!(class_java_lang_reflect_Field =
217 load_class_bootstrap(utf_java_lang_reflect_Field)))
220 if (!(class_java_lang_reflect_Method =
221 load_class_bootstrap(utf_java_lang_reflect_Method)))
224 if (!(class_java_security_PrivilegedAction =
225 load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
228 if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
231 # if defined(WITH_CLASSPATH_SUN)
232 if (!(class_sun_reflect_MagicAccessorImpl =
233 load_class_bootstrap(utf_new_char("sun/reflect/MagicAccessorImpl"))))
237 if (!(arrayclass_java_lang_Object =
238 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
241 #if defined(ENABLE_ANNOTATIONS)
242 /* needed by annotation support */
243 if (!(class_sun_reflect_ConstantPool =
244 load_class_bootstrap(utf_sun_reflect_ConstantPool)))
247 #if defined(WITH_CLASSPATH_GNU)
248 /* needed by GNU Classpaths annotation support */
249 if (!(class_sun_reflect_annotation_AnnotationParser =
250 load_class_bootstrap(utf_sun_reflect_annotation_AnnotationParser)))
261 /* loader_hashtable_classloader_add ********************************************
263 Adds an entry to the classloader hashtable.
265 REMEMBER: Also use this to register native loaders!
267 *******************************************************************************/
269 classloader *loader_hashtable_classloader_add(java_objectheader *cl)
271 hashtable_classloader_entry *cle;
278 LOCK_MONITOR_ENTER(hashtable_classloader->header);
280 /* key for entry is the hashcode of the classloader;
281 aligned to 16-byte boundaries */
283 #if defined(ENABLE_GC_CACAO)
284 key = heap_get_hashcode(cl) >> 4;
286 key = ((u4) (ptrint) cl) >> 4;
289 slot = key & (hashtable_classloader->size - 1);
290 cle = hashtable_classloader->ptr[slot];
292 /* search hashchain for existing entry */
293 /* XXX no GC collection is allowed here, make this a critical section */
296 if (cle->object == cl)
302 /* if no classloader was found, we create a new entry here */
305 cle = NEW(hashtable_classloader_entry);
307 #if defined(ENABLE_GC_CACAO)
308 /* register the classloader object with the GC */
310 gc_reference_register(&(cle->object));
315 /* insert entry into hashtable */
317 cle->hashlink = hashtable_classloader->ptr[slot];
318 hashtable_classloader->ptr[slot] = cle;
320 /* update number of entries */
322 hashtable_classloader->entries++;
326 LOCK_MONITOR_EXIT(hashtable_classloader->header);
332 /* loader_hashtable_classloader_find *******************************************
334 Find an entry in the classloader hashtable.
336 *******************************************************************************/
338 classloader *loader_hashtable_classloader_find(java_objectheader *cl)
340 hashtable_classloader_entry *cle;
347 /* key for entry is the hashcode of the classloader;
348 aligned to 16-byte boundaries */
350 #if defined(ENABLE_GC_CACAO)
351 key = heap_get_hashcode(cl) >> 4;
353 key = ((u4) (ptrint) cl) >> 4;
356 slot = key & (hashtable_classloader->size - 1);
357 cle = hashtable_classloader->ptr[slot];
359 /* search hashchain for existing entry */
360 /* XXX no GC collection is allowed here, make this a critical section */
363 if (cle->object == cl)
373 /* loader_load_all_classes *****************************************************
375 Loads all classes specified in the BOOTCLASSPATH.
377 *******************************************************************************/
379 void loader_load_all_classes(void)
381 list_classpath_entry *lce;
382 #if defined(ENABLE_ZLIB)
385 hashtable_zipfile_entry *htzfe;
389 for (lce = list_first(list_classpath_entries); lce != NULL;
390 lce = list_next(list_classpath_entries, lce)) {
391 #if defined(ENABLE_ZLIB)
392 if (lce->type == CLASSPATH_ARCHIVE) {
393 /* get the classes hashtable */
397 for (slot = 0; slot < ht->size; slot++) {
398 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
400 for (; htzfe; htzfe = htzfe->hashlink) {
403 /* skip all entries in META-INF and .properties,
406 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
407 strstr(u->text, ".properties") ||
408 strstr(u->text, ".png"))
411 /* load class from bootstrap classloader */
413 if (!load_class_bootstrap(u)) {
414 fprintf(stderr, "Error loading: ");
415 utf_fprint_printable_ascii_classname(stderr, u);
416 fprintf(stderr, "\n");
419 /* print out exception and cause */
421 exceptions_print_current_exception();
429 #if defined(ENABLE_ZLIB)
436 /* loader_skip_attribute_body **************************************************
438 Skips an attribute the attribute_name_index has already been read.
441 u2 attribute_name_index;
443 u1 info[attribute_length];
446 *******************************************************************************/
448 bool loader_skip_attribute_body(classbuffer *cb)
452 if (!suck_check_classbuffer_size(cb, 4))
455 attribute_length = suck_u4(cb);
457 if (!suck_check_classbuffer_size(cb, attribute_length))
460 suck_skip_nbytes(cb, attribute_length);
466 /* load_constantpool ***********************************************************
468 Loads the constantpool of a class, the entries are transformed into
469 a simpler format by resolving references (a detailed overview of
470 the compact structures can be found in global.h).
472 *******************************************************************************/
474 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
477 /* The following structures are used to save information which cannot be
478 processed during the first pass. After the complete constantpool has
479 been traversed the references can be resolved.
480 (only in specific order) */
482 /* CONSTANT_Class entries */
483 typedef struct forward_class {
484 struct forward_class *next;
489 /* CONSTANT_String */
490 typedef struct forward_string {
491 struct forward_string *next;
496 /* CONSTANT_NameAndType */
497 typedef struct forward_nameandtype {
498 struct forward_nameandtype *next;
502 } forward_nameandtype;
504 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
505 typedef struct forward_fieldmethint {
506 struct forward_fieldmethint *next;
510 u2 nameandtype_index;
511 } forward_fieldmethint;
517 forward_class *forward_classes = NULL;
518 forward_string *forward_strings = NULL;
519 forward_nameandtype *forward_nameandtypes = NULL;
520 forward_fieldmethint *forward_fieldmethints = NULL;
524 forward_nameandtype *nfn;
525 forward_fieldmethint *nff;
533 /* number of entries in the constant_pool table plus one */
534 if (!suck_check_classbuffer_size(cb, 2))
537 cpcount = c->cpcount = suck_u2(cb);
539 /* allocate memory */
540 cptags = c->cptags = MNEW(u1, cpcount);
541 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
544 exceptions_throw_classformaterror(c, "Illegal constant pool size");
548 #if defined(ENABLE_STATISTICS)
550 count_const_pool_len += (sizeof(u1) + sizeof(voidptr)) * cpcount;
553 /* initialize constantpool */
554 for (idx = 0; idx < cpcount; idx++) {
555 cptags[idx] = CONSTANT_UNUSED;
560 /******* first pass *******/
561 /* entries which cannot be resolved now are written into
562 temporary structures and traversed again later */
565 while (idx < cpcount) {
568 /* get constant type */
569 if (!suck_check_classbuffer_size(cb, 1))
576 nfc = DNEW(forward_class);
578 nfc->next = forward_classes;
579 forward_classes = nfc;
581 nfc->thisindex = idx;
582 /* reference to CONSTANT_NameAndType */
583 if (!suck_check_classbuffer_size(cb, 2))
586 nfc->name_index = suck_u2(cb);
591 case CONSTANT_String:
592 nfs = DNEW(forward_string);
594 nfs->next = forward_strings;
595 forward_strings = nfs;
597 nfs->thisindex = idx;
599 /* reference to CONSTANT_Utf8_info with string characters */
600 if (!suck_check_classbuffer_size(cb, 2))
603 nfs->string_index = suck_u2(cb);
608 case CONSTANT_NameAndType:
609 nfn = DNEW(forward_nameandtype);
611 nfn->next = forward_nameandtypes;
612 forward_nameandtypes = nfn;
614 nfn->thisindex = idx;
616 if (!suck_check_classbuffer_size(cb, 2 + 2))
619 /* reference to CONSTANT_Utf8_info containing simple name */
620 nfn->name_index = suck_u2(cb);
622 /* reference to CONSTANT_Utf8_info containing field or method
624 nfn->sig_index = suck_u2(cb);
629 case CONSTANT_Fieldref:
630 case CONSTANT_Methodref:
631 case CONSTANT_InterfaceMethodref:
632 nff = DNEW(forward_fieldmethint);
634 nff->next = forward_fieldmethints;
635 forward_fieldmethints = nff;
637 nff->thisindex = idx;
641 if (!suck_check_classbuffer_size(cb, 2 + 2))
644 /* class or interface type that contains the declaration of the
646 nff->class_index = suck_u2(cb);
648 /* name and descriptor of the field or method */
649 nff->nameandtype_index = suck_u2(cb);
654 case CONSTANT_Integer: {
655 constant_integer *ci = NEW(constant_integer);
657 #if defined(ENABLE_STATISTICS)
659 count_const_pool_len += sizeof(constant_integer);
662 if (!suck_check_classbuffer_size(cb, 4))
665 ci->value = suck_s4(cb);
666 cptags[idx] = CONSTANT_Integer;
673 case CONSTANT_Float: {
674 constant_float *cf = NEW(constant_float);
676 #if defined(ENABLE_STATISTICS)
678 count_const_pool_len += sizeof(constant_float);
681 if (!suck_check_classbuffer_size(cb, 4))
684 cf->value = suck_float(cb);
685 cptags[idx] = CONSTANT_Float;
692 case CONSTANT_Long: {
693 constant_long *cl = NEW(constant_long);
695 #if defined(ENABLE_STATISTICS)
697 count_const_pool_len += sizeof(constant_long);
700 if (!suck_check_classbuffer_size(cb, 8))
703 cl->value = suck_s8(cb);
704 cptags[idx] = CONSTANT_Long;
708 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
714 case CONSTANT_Double: {
715 constant_double *cd = NEW(constant_double);
717 #if defined(ENABLE_STATISTICS)
719 count_const_pool_len += sizeof(constant_double);
722 if (!suck_check_classbuffer_size(cb, 8))
725 cd->value = suck_double(cb);
726 cptags[idx] = CONSTANT_Double;
730 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
736 case CONSTANT_Utf8: {
739 /* number of bytes in the bytes array (not string-length) */
740 if (!suck_check_classbuffer_size(cb, 2))
743 length = suck_u2(cb);
744 cptags[idx] = CONSTANT_Utf8;
746 /* validate the string */
747 if (!suck_check_classbuffer_size(cb, length))
750 #ifdef ENABLE_VERIFIER
752 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
754 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
757 #endif /* ENABLE_VERIFIER */
758 /* insert utf-string into the utf-symboltable */
759 cpinfos[idx] = utf_new((char *) cb->pos, length);
761 /* skip bytes of the string (buffer size check above) */
762 suck_skip_nbytes(cb, length);
768 exceptions_throw_classformaterror(c, "Illegal constant pool type");
774 /* resolve entries in temporary structures */
776 while (forward_classes) {
778 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
782 #ifdef ENABLE_VERIFIER
783 if (opt_verify && !is_valid_name_utf(name)) {
784 exceptions_throw_classformaterror(c, "Class reference with invalid name");
787 #endif /* ENABLE_VERIFIER */
789 /* add all class references to the descriptor_pool */
791 if (!descriptor_pool_add_class(descpool, name))
794 cptags[forward_classes->thisindex] = CONSTANT_Class;
796 /* the classref is created later */
797 cpinfos[forward_classes->thisindex] = name;
799 nfc = forward_classes;
800 forward_classes = forward_classes->next;
803 while (forward_strings) {
805 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
809 /* resolve utf-string */
810 cptags[forward_strings->thisindex] = CONSTANT_String;
811 cpinfos[forward_strings->thisindex] = text;
813 nfs = forward_strings;
814 forward_strings = forward_strings->next;
817 while (forward_nameandtypes) {
818 constant_nameandtype *cn = NEW(constant_nameandtype);
820 #if defined(ENABLE_STATISTICS)
822 count_const_pool_len += sizeof(constant_nameandtype);
825 /* resolve simple name and descriptor */
826 cn->name = class_getconstant(c,
827 forward_nameandtypes->name_index,
832 cn->descriptor = class_getconstant(c,
833 forward_nameandtypes->sig_index,
838 #ifdef ENABLE_VERIFIER
841 if (!is_valid_name_utf(cn->name)) {
842 exceptions_throw_classformaterror(c,
843 "Illegal Field name \"%s\"",
849 /* disallow referencing <clinit> among others */
850 if (cn->name->text[0] == '<' && cn->name != utf_init) {
851 exceptions_throw_classformaterror(c, "Illegal reference to special method");
855 #endif /* ENABLE_VERIFIER */
857 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
858 cpinfos[forward_nameandtypes->thisindex] = cn;
860 nfn = forward_nameandtypes;
861 forward_nameandtypes = forward_nameandtypes->next;
864 while (forward_fieldmethints) {
865 constant_nameandtype *nat;
866 constant_FMIref *fmi = NEW(constant_FMIref);
868 #if defined(ENABLE_STATISTICS)
870 count_const_pool_len += sizeof(constant_FMIref);
872 /* resolve simple name and descriptor */
874 nat = class_getconstant(c,
875 forward_fieldmethints->nameandtype_index,
876 CONSTANT_NameAndType);
880 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
882 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
885 /* the classref is created later */
887 fmi->p.index = forward_fieldmethints->class_index;
888 fmi->name = nat->name;
889 fmi->descriptor = nat->descriptor;
891 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
892 cpinfos[forward_fieldmethints->thisindex] = fmi;
894 nff = forward_fieldmethints;
895 forward_fieldmethints = forward_fieldmethints->next;
898 /* everything was ok */
904 /* loader_load_attribute_signature *********************************************
906 Signature_attribute {
907 u2 attribute_name_index;
912 *******************************************************************************/
914 #if defined(ENABLE_JAVASE)
915 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
925 /* check remaining bytecode */
927 if (!suck_check_classbuffer_size(cb, 4 + 2))
930 /* check attribute length */
932 attribute_length = suck_u4(cb);
934 if (attribute_length != 2) {
935 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
939 if (*signature != NULL) {
940 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
946 signature_index = suck_u2(cb);
948 if (!(*signature = class_getconstant(c, signature_index, CONSTANT_Utf8)))
953 #endif /* defined(ENABLE_JAVASE) */
956 /* load_class_from_sysloader ***************************************************
958 Load the class with the given name using the system class loader
961 name.............the classname
965 NULL if an exception has been thrown
967 *******************************************************************************/
969 classinfo *load_class_from_sysloader(utf *name)
976 assert(class_java_lang_Object);
977 assert(class_java_lang_ClassLoader);
978 assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
980 m = class_resolveclassmethod(class_java_lang_ClassLoader,
981 utf_getSystemClassLoader,
982 utf_void__java_lang_ClassLoader,
983 class_java_lang_Object,
989 clo = vm_call_method(m, NULL);
994 cl = loader_hashtable_classloader_add(clo);
996 c = load_class_from_classloader(name, cl);
1002 /* load_class_from_classloader *************************************************
1004 Load the class with the given name using the given user-defined class loader.
1007 name.............the classname
1008 cl...............user-defined class loader
1011 the loaded class, or
1012 NULL if an exception has been thrown
1014 *******************************************************************************/
1016 classinfo *load_class_from_classloader(utf *name, classloader *cl)
1021 java_handle_t *string;
1022 #if defined(ENABLE_RT_TIMING)
1023 struct timespec time_start, time_lookup, time_prepare, time_java,
1027 RT_TIMING_GET_TIME(time_start);
1031 /* lookup if this class has already been loaded */
1033 c = classcache_lookup(cl, name);
1035 RT_TIMING_GET_TIME(time_lookup);
1036 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1041 /* if other class loader than bootstrap, call it */
1049 namelen = name->blength;
1051 /* handle array classes */
1052 if (text[0] == '[') {
1058 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1059 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1060 exceptions_throw_classnotfoundexception(name);
1064 u = utf_new(text + 2, namelen - 3);
1066 if (!(comp = load_class_from_classloader(u, cl)))
1069 /* create the array class */
1071 c = class_array_of(comp, false);
1073 tmpc = classcache_store(cl, c, true);
1076 /* exception, free the loaded class */
1077 c->state &= ~CLASS_LOADING;
1084 /* load the component class */
1086 u = utf_new(text + 1, namelen - 1);
1088 if (!(comp = load_class_from_classloader(u, cl)))
1091 /* create the array class */
1093 c = class_array_of(comp, false);
1095 tmpc = classcache_store(cl, c, true);
1098 /* exception, free the loaded class */
1099 c->state &= ~CLASS_LOADING;
1106 /* primitive array classes are loaded by the bootstrap loader */
1108 c = load_class_bootstrap(name);
1114 assert(class_java_lang_Object);
1116 lc = class_resolveclassmethod(cl->object->vftbl->class,
1118 utf_java_lang_String__java_lang_Class,
1119 class_java_lang_Object,
1123 return false; /* exception */
1125 /* move return value into `o' and cast it afterwards to a classinfo* */
1127 string = javastring_new_slash_to_dot(name);
1129 RT_TIMING_GET_TIME(time_prepare);
1131 o = vm_call_method(lc, cl->object, string);
1133 RT_TIMING_GET_TIME(time_java);
1135 c = (classinfo *) o;
1138 /* Store this class in the loaded class cache. If another
1139 class with the same (initloader,name) pair has been
1140 stored earlier it will be returned by classcache_store
1141 In this case classcache_store may not free the class
1142 because it has already been exposed to Java code which
1143 may have kept references to that class. */
1145 tmpc = classcache_store(cl, c, false);
1148 /* exception, free the loaded class */
1149 c->state &= ~CLASS_LOADING;
1156 RT_TIMING_GET_TIME(time_cache);
1158 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1159 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1160 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1162 /* SUN compatible -verbose:class output */
1164 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1166 utf_display_printable_ascii_classname(name);
1170 #if defined(ENABLE_JVMTI)
1171 /* fire Class Load JVMTI event */
1172 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1179 c = load_class_bootstrap(name);
1185 /* load_class_bootstrap ********************************************************
1187 Load the class with the given name using the bootstrap class loader.
1190 name.............the classname
1193 loaded classinfo, or
1194 NULL if an exception has been thrown
1197 load_class_bootstrap is synchronized. It can be treated as an
1200 *******************************************************************************/
1202 classinfo *load_class_bootstrap(utf *name)
1207 #if defined(ENABLE_RT_TIMING)
1208 struct timespec time_start, time_lookup, time_array, time_suck,
1209 time_load, time_cache;
1212 RT_TIMING_GET_TIME(time_start);
1218 /* lookup if this class has already been loaded */
1220 r = classcache_lookup(NULL, name);
1223 RT_TIMING_GET_TIME(time_lookup);
1224 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1229 RT_TIMING_GET_TIME(time_lookup);
1230 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1232 /* create the classinfo */
1234 c = class_create_classinfo(name);
1236 /* handle array classes */
1238 if (name->text[0] == '[') {
1239 c = load_newly_created_array(c, NULL);
1244 assert(c->state & CLASS_LOADED);
1246 RT_TIMING_GET_TIME(time_array);
1247 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1252 #if defined(ENABLE_STATISTICS)
1255 if (opt_getcompilingtime)
1256 compilingtime_stop();
1258 if (opt_getloadingtime)
1259 loadingtime_start();
1262 /* load classdata, throw exception on error */
1267 /* this normally means, the classpath was not set properly */
1269 if (name == utf_java_lang_Object)
1270 vm_abort("java/lang/NoClassDefFoundError: java/lang/Object");
1272 exceptions_throw_classnotfoundexception(name);
1277 RT_TIMING_GET_TIME(time_suck);
1279 /* load the class from the buffer */
1281 r = load_class_from_classbuffer(cb);
1283 RT_TIMING_GET_TIME(time_load);
1286 /* the class could not be loaded, free the classinfo struct */
1291 /* Store this class in the loaded class cache this step also
1292 checks the loading constraints. If the class has been loaded
1293 before, the earlier loaded class is returned. */
1295 classinfo *res = classcache_store(NULL, c, true);
1305 RT_TIMING_GET_TIME(time_cache);
1307 /* SUN compatible -verbose:class output */
1309 if (opt_verboseclass && r) {
1311 utf_display_printable_ascii_classname(name);
1312 printf(" from %s]\n", cb->path);
1319 #if defined(ENABLE_STATISTICS)
1322 if (opt_getloadingtime)
1325 if (opt_getcompilingtime)
1326 compilingtime_start();
1329 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1330 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1331 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1332 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1338 /* load_class_from_classbuffer *************************************************
1340 Loads everything interesting about a class from the class file. The
1341 'classinfo' structure must have been allocated previously.
1343 The super class and the interfaces implemented by this class need
1344 not be loaded. The link is set later by the function 'class_link'.
1347 This function is NOT synchronized!
1349 *******************************************************************************/
1351 classinfo *load_class_from_classbuffer(classbuffer *cb)
1359 descriptor_pool *descpool;
1360 #if defined(ENABLE_STATISTICS)
1364 #if defined(ENABLE_RT_TIMING)
1365 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1366 time_setup, time_fields, time_methods, time_classrefs,
1367 time_descs, time_setrefs, time_parsefds, time_parsemds,
1368 time_parsecpool, time_verify, time_attrs;
1371 RT_TIMING_GET_TIME(time_start);
1373 /* get the classbuffer's class */
1377 /* the class is already loaded */
1379 if (c->state & CLASS_LOADED)
1382 #if defined(ENABLE_STATISTICS)
1384 count_class_loads++;
1387 #if !defined(NDEBUG)
1388 /* output for debugging purposes */
1391 log_message_class("Loading class: ", c);
1394 /* mark start of dump memory area */
1396 dumpsize = dump_size();
1398 /* class is currently loading */
1400 c->state |= CLASS_LOADING;
1402 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1403 goto return_exception;
1405 /* check signature */
1407 if (suck_u4(cb) != MAGIC) {
1408 exceptions_throw_classformaterror(c, "Bad magic number");
1410 goto return_exception;
1418 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1419 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1420 goto return_exception;
1423 RT_TIMING_GET_TIME(time_checks);
1425 /* create a new descriptor pool */
1427 descpool = descriptor_pool_new(c);
1429 RT_TIMING_GET_TIME(time_ndpool);
1431 /* load the constant pool */
1433 if (!load_constantpool(cb, descpool))
1434 goto return_exception;
1436 RT_TIMING_GET_TIME(time_cpool);
1440 if (!suck_check_classbuffer_size(cb, 2))
1441 goto return_exception;
1443 /* We OR the flags here, as we set already some flags in
1444 class_create_classinfo. */
1446 c->flags |= suck_u2(cb);
1448 /* check ACC flags consistency */
1450 if (c->flags & ACC_INTERFACE) {
1451 if (!(c->flags & ACC_ABSTRACT)) {
1452 /* We work around this because interfaces in JDK 1.1 are
1453 * not declared abstract. */
1455 c->flags |= ACC_ABSTRACT;
1458 if (c->flags & ACC_FINAL) {
1459 exceptions_throw_classformaterror(c,
1460 "Illegal class modifiers: 0x%X",
1462 goto return_exception;
1465 if (c->flags & ACC_SUPER) {
1466 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1470 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1471 exceptions_throw_classformaterror(c,
1472 "Illegal class modifiers: 0x%X",
1474 goto return_exception;
1477 if (!suck_check_classbuffer_size(cb, 2 + 2))
1478 goto return_exception;
1484 if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1485 goto return_exception;
1487 if (c->name == utf_not_named_yet) {
1488 /* we finally have a name for this class */
1490 class_set_packagename(c);
1492 else if (name != c->name) {
1493 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
1494 goto return_exception;
1497 /* retrieve superclass */
1499 c->super.any = NULL;
1501 if ((i = suck_u2(cb))) {
1502 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1503 goto return_exception;
1505 /* java.lang.Object may not have a super class. */
1507 if (c->name == utf_java_lang_Object) {
1508 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
1509 goto return_exception;
1512 /* Interfaces must have java.lang.Object as super class. */
1514 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
1515 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
1516 goto return_exception;
1522 /* This is only allowed for java.lang.Object. */
1524 if (c->name != utf_java_lang_Object) {
1525 exceptions_throw_classformaterror(c, "Bad superclass index");
1526 goto return_exception;
1530 /* retrieve interfaces */
1532 if (!suck_check_classbuffer_size(cb, 2))
1533 goto return_exception;
1535 c->interfacescount = suck_u2(cb);
1537 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1538 goto return_exception;
1540 c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
1541 for (i = 0; i < c->interfacescount; i++) {
1542 /* the classrefs are created later */
1543 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1544 goto return_exception;
1547 RT_TIMING_GET_TIME(time_setup);
1551 if (!suck_check_classbuffer_size(cb, 2))
1552 goto return_exception;
1554 c->fieldscount = suck_u2(cb);
1555 c->fields = MNEW(fieldinfo, c->fieldscount);
1557 MZERO(c->fields, fieldinfo, c->fieldscount);
1559 for (i = 0; i < c->fieldscount; i++) {
1560 if (!field_load(cb, &(c->fields[i]), descpool))
1561 goto return_exception;
1564 RT_TIMING_GET_TIME(time_fields);
1568 if (!suck_check_classbuffer_size(cb, 2))
1569 goto return_exception;
1571 c->methodscount = suck_u2(cb);
1572 c->methods = MNEW(methodinfo, c->methodscount);
1574 MZERO(c->methods, methodinfo, c->methodscount);
1576 for (i = 0; i < c->methodscount; i++) {
1577 if (!method_load(cb, &(c->methods[i]), descpool))
1578 goto return_exception;
1581 RT_TIMING_GET_TIME(time_methods);
1583 /* create the class reference table */
1586 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
1588 RT_TIMING_GET_TIME(time_classrefs);
1590 /* allocate space for the parsed descriptors */
1592 descriptor_pool_alloc_parsed_descriptors(descpool);
1594 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
1596 #if defined(ENABLE_STATISTICS)
1598 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
1599 count_classref_len += classrefsize;
1600 count_parsed_desc_len += descsize;
1604 RT_TIMING_GET_TIME(time_descs);
1606 /* put the classrefs in the constant pool */
1607 for (i = 0; i < c->cpcount; i++) {
1608 if (c->cptags[i] == CONSTANT_Class) {
1609 utf *name = (utf *) c->cpinfos[i];
1610 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
1614 /* set the super class reference */
1617 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
1619 goto return_exception;
1622 /* set the super interfaces references */
1624 for (i = 0; i < c->interfacescount; i++) {
1625 c->interfaces[i].ref =
1626 descriptor_pool_lookup_classref(descpool,
1627 (utf *) c->interfaces[i].any);
1628 if (!c->interfaces[i].ref)
1629 goto return_exception;
1632 RT_TIMING_GET_TIME(time_setrefs);
1634 /* parse field descriptors */
1636 for (i = 0; i < c->fieldscount; i++) {
1637 c->fields[i].parseddesc =
1638 descriptor_pool_parse_field_descriptor(descpool,
1639 c->fields[i].descriptor);
1640 if (!c->fields[i].parseddesc)
1641 goto return_exception;
1644 RT_TIMING_GET_TIME(time_parsefds);
1646 /* parse method descriptors */
1648 for (i = 0; i < c->methodscount; i++) {
1649 methodinfo *m = &c->methods[i];
1651 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
1652 m->flags, class_get_self_classref(m->class));
1654 goto return_exception;
1656 for (j = 0; j < m->rawexceptiontablelength; j++) {
1657 if (!m->rawexceptiontable[j].catchtype.any)
1659 if ((m->rawexceptiontable[j].catchtype.ref =
1660 descriptor_pool_lookup_classref(descpool,
1661 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
1662 goto return_exception;
1665 for (j = 0; j < m->thrownexceptionscount; j++) {
1666 if (!m->thrownexceptions[j].any)
1668 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
1669 (utf *) m->thrownexceptions[j].any)) == NULL)
1670 goto return_exception;
1674 RT_TIMING_GET_TIME(time_parsemds);
1676 /* parse the loaded descriptors */
1678 for (i = 0; i < c->cpcount; i++) {
1679 constant_FMIref *fmi;
1682 switch (c->cptags[i]) {
1683 case CONSTANT_Fieldref:
1684 fmi = (constant_FMIref *) c->cpinfos[i];
1685 fmi->parseddesc.fd =
1686 descriptor_pool_parse_field_descriptor(descpool,
1688 if (!fmi->parseddesc.fd)
1689 goto return_exception;
1690 index = fmi->p.index;
1692 (constant_classref *) class_getconstant(c, index,
1694 if (!fmi->p.classref)
1695 goto return_exception;
1697 case CONSTANT_Methodref:
1698 case CONSTANT_InterfaceMethodref:
1699 fmi = (constant_FMIref *) c->cpinfos[i];
1700 index = fmi->p.index;
1702 (constant_classref *) class_getconstant(c, index,
1704 if (!fmi->p.classref)
1705 goto return_exception;
1706 fmi->parseddesc.md =
1707 descriptor_pool_parse_method_descriptor(descpool,
1711 if (!fmi->parseddesc.md)
1712 goto return_exception;
1717 RT_TIMING_GET_TIME(time_parsecpool);
1719 #ifdef ENABLE_VERIFIER
1720 /* Check if all fields and methods can be uniquely
1721 * identified by (name,descriptor). */
1724 /* We use a hash table here to avoid making the
1725 * average case quadratic in # of methods, fields.
1727 static int shift = 0;
1729 u2 *next; /* for chaining colliding hash entries */
1735 /* Allocate hashtable */
1736 len = c->methodscount;
1737 if (len < c->fieldscount) len = c->fieldscount;
1739 hashtab = MNEW(u2,(hashlen + len));
1740 next = hashtab + hashlen;
1742 /* Determine bitshift (to get good hash values) */
1752 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
1754 for (i = 0; i < c->fieldscount; ++i) {
1755 fieldinfo *fi = c->fields + i;
1757 /* It's ok if we lose bits here */
1758 index = ((((size_t) fi->name) +
1759 ((size_t) fi->descriptor)) >> shift) % hashlen;
1761 if ((old = hashtab[index])) {
1765 if (c->fields[old].name == fi->name &&
1766 c->fields[old].descriptor == fi->descriptor) {
1767 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
1768 goto return_exception;
1770 } while ((old = next[old]));
1772 hashtab[index] = i + 1;
1776 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
1778 for (i = 0; i < c->methodscount; ++i) {
1779 methodinfo *mi = c->methods + i;
1781 /* It's ok if we lose bits here */
1782 index = ((((size_t) mi->name) +
1783 ((size_t) mi->descriptor)) >> shift) % hashlen;
1787 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
1788 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
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");
1799 goto return_exception;
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))
1823 goto return_exception;
1825 /* Pre Java 1.5 version don't check this. This implementation is like
1826 Java 1.5 do it: for class file version 45.3 we don't check it, older
1827 versions are checked.
1830 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
1831 /* check if all data has been read */
1832 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
1834 if (classdata_left > 0) {
1835 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
1836 goto return_exception;
1840 RT_TIMING_GET_TIME(time_attrs);
1842 /* release dump area */
1844 dump_release(dumpsize);
1846 /* revert loading state and class is loaded */
1848 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
1850 #if defined(ENABLE_JVMTI)
1851 /* fire Class Prepare JVMTI event */
1854 jvmti_ClassLoadPrepare(true, c);
1857 #if !defined(NDEBUG)
1859 log_message_class("Loading done class: ", c);
1862 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
1863 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
1864 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
1865 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
1866 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
1867 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
1868 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
1869 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
1870 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
1871 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
1872 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
1873 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
1874 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
1875 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
1876 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
1881 /* release dump area */
1883 dump_release(dumpsize);
1885 /* an exception has been thrown */
1891 /* load_newly_created_array ****************************************************
1893 Load a newly created array class.
1896 c....................the array class C has been loaded
1897 other classinfo......the array class was found in the class cache,
1899 NULL.................an exception has been thrown
1902 This is an internal function. Do not use it unless you know exactly
1905 Use one of the load_class_... functions for general array class loading.
1907 *******************************************************************************/
1909 classinfo *load_newly_created_array(classinfo *c, classloader *loader)
1911 classinfo *comp = NULL;
1913 methoddesc *clonedesc;
1914 constant_classref *classrefs;
1919 text = c->name->text;
1920 namelen = c->name->blength;
1922 /* Check array class name */
1924 if ((namelen < 2) || (text[0] != '[')) {
1925 exceptions_throw_classnotfoundexception(c->name);
1929 /* Check the element type */
1933 /* c is an array of arrays. We have to create the component class. */
1935 u = utf_new(text + 1, namelen - 1);
1937 comp = load_class_from_classloader(u, loader);
1942 assert(comp->state & CLASS_LOADED);
1944 /* the array's flags are that of the component class */
1945 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
1946 c->classloader = comp->classloader;
1950 /* c is an array of objects. */
1952 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1953 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
1954 exceptions_throw_classnotfoundexception(c->name);
1958 u = utf_new(text + 2, namelen - 3);
1960 if (!(comp = load_class_from_classloader(u, loader)))
1963 assert(comp->state & CLASS_LOADED);
1965 /* the array's flags are that of the component class */
1966 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
1967 c->classloader = comp->classloader;
1971 /* c is an array of a primitive type */
1973 /* check for cases like `[II' and whether the character is a
1974 valid primitive type */
1976 if ((namelen > 2) || (primitive_class_get_by_char(text[1]) == NULL)) {
1977 exceptions_throw_classnotfoundexception(c->name);
1981 /* the accessibility of the array class is public (VM Spec 5.3.3) */
1982 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
1983 c->classloader = NULL;
1986 assert(class_java_lang_Object);
1987 #if defined(ENABLE_JAVASE)
1988 assert(class_java_lang_Cloneable);
1989 assert(class_java_io_Serializable);
1992 /* setup the array class */
1994 c->super.cls = class_java_lang_Object;
1996 #if defined(ENABLE_JAVASE)
1998 c->interfacescount = 2;
1999 c->interfaces = MNEW(classref_or_classinfo, 2);
2000 c->interfaces[0].cls = class_java_lang_Cloneable;
2001 c->interfaces[1].cls = class_java_io_Serializable;
2003 #elif defined(ENABLE_JAVAME_CLDC1_1)
2005 c->interfacescount = 0;
2006 c->interfaces = NULL;
2009 # error unknow Java configuration
2012 c->methodscount = 1;
2013 c->methods = MNEW(methodinfo, c->methodscount);
2014 MZERO(c->methods, methodinfo, c->methodscount);
2016 classrefs = MNEW(constant_classref, 2);
2017 CLASSREF_INIT(classrefs[0], c, c->name);
2018 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2020 /* create descriptor for clone method */
2021 /* we need one paramslot which is reserved for the 'this' parameter */
2022 clonedesc = NEW(methoddesc);
2023 clonedesc->returntype.type = TYPE_ADR;
2024 clonedesc->returntype.classref = classrefs + 1;
2025 clonedesc->returntype.arraydim = 0;
2026 /* initialize params to "empty", add real params below in
2027 descriptor_params_from_paramtypes */
2028 clonedesc->paramcount = 0;
2029 clonedesc->paramslots = 0;
2030 clonedesc->paramtypes[0].classref = classrefs + 0;
2031 clonedesc->params = NULL;
2033 /* create methodinfo */
2036 MSET(clone, 0, methodinfo, 1);
2038 #if defined(ENABLE_THREADS)
2039 lock_init_object_lock(&clone->header);
2042 /* ATTENTION: if you delete the ACC_NATIVE below, set
2043 clone->maxlocals=1 (interpreter related) */
2045 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2046 clone->name = utf_clone;
2047 clone->descriptor = utf_void__java_lang_Object;
2048 clone->parseddesc = clonedesc;
2051 /* parse the descriptor to get the register allocation */
2053 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2056 clone->code = codegen_generate_stub_native(clone, BUILTIN_clone);
2058 /* XXX: field: length? */
2060 /* array classes are not loaded from class files */
2062 c->state |= CLASS_LOADED;
2063 c->parseddescs = (u1 *) clonedesc;
2064 c->parseddescsize = sizeof(methodinfo);
2065 c->classrefs = classrefs;
2066 c->classrefcount = 1;
2068 /* insert class into the loaded class cache */
2069 /* XXX free classinfo if NULL returned? */
2071 return classcache_store(loader, c, true);
2075 /* loader_close ****************************************************************
2077 Frees all resources.
2079 *******************************************************************************/
2081 void loader_close(void)
2088 * These are local overrides for various environment variables in Emacs.
2089 * Please do not remove this and leave it at the end of the file, where
2090 * Emacs will automagically detect them.
2091 * ---------------------------------------------------------------------
2094 * indent-tabs-mode: t
2098 * vim:noexpandtab:sw=4:ts=4: