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 8374 2007-08-21 10:20:33Z michi $
38 #include "mm/memory.h"
40 #include "native/llni.h"
42 #include "threads/lock-common.h"
44 #include "toolbox/hashtable.h"
45 #include "toolbox/logging.h"
47 #include "vm/builtin.h"
48 #include "vm/exceptions.h"
49 #include "vm/global.h"
50 #include "vm/primitive.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_init *****************************************************************
91 Initializes all lists and loads all classes required for the system
94 *******************************************************************************/
96 bool loader_init(void)
98 #if defined(ENABLE_THREADS)
99 list_classpath_entry *lce;
101 /* Initialize the monitor pointer for zip/jar file locking. */
103 for (lce = list_first(list_classpath_entries); lce != NULL;
104 lce = list_next(list_classpath_entries, lce))
105 if (lce->type == CLASSPATH_ARCHIVE)
106 LOCK_INIT_OBJECT_LOCK(lce);
109 /* initialize classloader hashtable, 10 entries should be enough */
111 hashtable_classloader = NEW(hashtable);
112 hashtable_create(hashtable_classloader, 10);
114 /* load some important classes */
116 if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
119 if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
122 #if defined(ENABLE_JAVASE)
123 if (!(class_java_lang_Cloneable =
124 load_class_bootstrap(utf_java_lang_Cloneable)))
127 if (!(class_java_io_Serializable =
128 load_class_bootstrap(utf_java_io_Serializable)))
132 /* load classes for wrapping primitive types */
134 #if defined(ENABLE_JAVASE)
135 if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
139 if (!(class_java_lang_Boolean =
140 load_class_bootstrap(utf_java_lang_Boolean)))
143 if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
146 if (!(class_java_lang_Character =
147 load_class_bootstrap(utf_java_lang_Character)))
150 if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
153 if (!(class_java_lang_Integer =
154 load_class_bootstrap(utf_java_lang_Integer)))
157 if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
160 if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
163 if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
167 /* load some other important classes */
169 if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
172 #if defined(ENABLE_JAVASE)
173 if (!(class_java_lang_ClassLoader =
174 load_class_bootstrap(utf_java_lang_ClassLoader)))
177 if (!(class_java_lang_SecurityManager =
178 load_class_bootstrap(utf_java_lang_SecurityManager)))
182 if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
185 if (!(class_java_lang_Thread =
186 load_class_bootstrap(utf_new_char("java/lang/Thread"))))
189 #if defined(ENABLE_JAVASE)
190 if (!(class_java_lang_ThreadGroup =
191 load_class_bootstrap(utf_java_lang_ThreadGroup)))
195 #if defined(WITH_CLASSPATH_GNU)
196 if (!(class_java_lang_VMSystem =
197 load_class_bootstrap(utf_new_char("java/lang/VMSystem"))))
201 if (!(class_java_lang_VMThread =
202 load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
207 /* some classes which may be used more often */
209 #if defined(ENABLE_JAVASE)
210 if (!(class_java_lang_StackTraceElement =
211 load_class_bootstrap(utf_java_lang_StackTraceElement)))
214 if (!(class_java_lang_reflect_Constructor =
215 load_class_bootstrap(utf_java_lang_reflect_Constructor)))
218 if (!(class_java_lang_reflect_Field =
219 load_class_bootstrap(utf_java_lang_reflect_Field)))
222 if (!(class_java_lang_reflect_Method =
223 load_class_bootstrap(utf_java_lang_reflect_Method)))
226 if (!(class_java_security_PrivilegedAction =
227 load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
230 if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
233 # if defined(WITH_CLASSPATH_SUN)
234 if (!(class_sun_reflect_MagicAccessorImpl =
235 load_class_bootstrap(utf_new_char("sun/reflect/MagicAccessorImpl"))))
239 if (!(arrayclass_java_lang_Object =
240 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
243 #if defined(ENABLE_ANNOTATIONS)
244 /* needed by annotation support */
245 if (!(class_sun_reflect_ConstantPool =
246 load_class_bootstrap(utf_sun_reflect_ConstantPool)))
249 #if defined(WITH_CLASSPATH_GNU)
250 /* needed by GNU Classpaths annotation support */
251 if (!(class_sun_reflect_annotation_AnnotationParser =
252 load_class_bootstrap(utf_sun_reflect_annotation_AnnotationParser)))
263 /* loader_hashtable_classloader_add ********************************************
265 Adds an entry to the classloader hashtable.
267 REMEMBER: Also use this to register native loaders!
269 *******************************************************************************/
271 classloader *loader_hashtable_classloader_add(java_handle_t *cl)
273 hashtable_classloader_entry *cle;
280 LOCK_MONITOR_ENTER(hashtable_classloader->header);
284 /* key for entry is the hashcode of the classloader;
285 aligned to 16-byte boundaries */
287 #if defined(ENABLE_GC_CACAO)
288 key = heap_get_hashcode(LLNI_DIRECT(cl)) >> 4;
290 key = ((u4) (ptrint) cl) >> 4;
293 slot = key & (hashtable_classloader->size - 1);
294 cle = hashtable_classloader->ptr[slot];
296 /* search hashchain for existing entry */
299 if (cle->object == LLNI_DIRECT(cl))
307 /* if no classloader was found, we create a new entry here */
310 cle = NEW(hashtable_classloader_entry);
312 #if defined(ENABLE_GC_CACAO)
313 /* register the classloader object with the GC */
315 gc_reference_register(&(cle->object), GC_REFTYPE_CLASSLOADER);
320 cle->object = LLNI_DIRECT(cl);
324 /* insert entry into hashtable */
326 cle->hashlink = hashtable_classloader->ptr[slot];
327 hashtable_classloader->ptr[slot] = cle;
329 /* update number of entries */
331 hashtable_classloader->entries++;
335 LOCK_MONITOR_EXIT(hashtable_classloader->header);
341 /* loader_hashtable_classloader_find *******************************************
343 Find an entry in the classloader hashtable.
345 *******************************************************************************/
347 classloader *loader_hashtable_classloader_find(java_handle_t *cl)
349 hashtable_classloader_entry *cle;
358 /* key for entry is the hashcode of the classloader;
359 aligned to 16-byte boundaries */
361 #if defined(ENABLE_GC_CACAO)
362 key = heap_get_hashcode(LLNI_DIRECT(cl)) >> 4;
364 key = ((u4) (ptrint) cl) >> 4;
367 slot = key & (hashtable_classloader->size - 1);
368 cle = hashtable_classloader->ptr[slot];
370 /* search hashchain for existing entry */
373 if (cle->object == LLNI_DIRECT(cl))
385 /* loader_load_all_classes *****************************************************
387 Loads all classes specified in the BOOTCLASSPATH.
389 *******************************************************************************/
391 void loader_load_all_classes(void)
393 list_classpath_entry *lce;
394 #if defined(ENABLE_ZLIB)
397 hashtable_zipfile_entry *htzfe;
401 for (lce = list_first(list_classpath_entries); lce != NULL;
402 lce = list_next(list_classpath_entries, lce)) {
403 #if defined(ENABLE_ZLIB)
404 if (lce->type == CLASSPATH_ARCHIVE) {
405 /* get the classes hashtable */
409 for (slot = 0; slot < ht->size; slot++) {
410 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
412 for (; htzfe; htzfe = htzfe->hashlink) {
415 /* skip all entries in META-INF and .properties,
418 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
419 strstr(u->text, ".properties") ||
420 strstr(u->text, ".png"))
423 /* load class from bootstrap classloader */
425 if (!load_class_bootstrap(u)) {
426 fprintf(stderr, "Error loading: ");
427 utf_fprint_printable_ascii_classname(stderr, u);
428 fprintf(stderr, "\n");
431 /* print out exception and cause */
433 exceptions_print_current_exception();
441 #if defined(ENABLE_ZLIB)
448 /* loader_skip_attribute_body **************************************************
450 Skips an attribute the attribute_name_index has already been read.
453 u2 attribute_name_index;
455 u1 info[attribute_length];
458 *******************************************************************************/
460 bool loader_skip_attribute_body(classbuffer *cb)
464 if (!suck_check_classbuffer_size(cb, 4))
467 attribute_length = suck_u4(cb);
469 if (!suck_check_classbuffer_size(cb, attribute_length))
472 suck_skip_nbytes(cb, attribute_length);
478 /* load_constantpool ***********************************************************
480 Loads the constantpool of a class, the entries are transformed into
481 a simpler format by resolving references (a detailed overview of
482 the compact structures can be found in global.h).
484 *******************************************************************************/
486 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
489 /* The following structures are used to save information which cannot be
490 processed during the first pass. After the complete constantpool has
491 been traversed the references can be resolved.
492 (only in specific order) */
494 /* CONSTANT_Class entries */
495 typedef struct forward_class {
496 struct forward_class *next;
501 /* CONSTANT_String */
502 typedef struct forward_string {
503 struct forward_string *next;
508 /* CONSTANT_NameAndType */
509 typedef struct forward_nameandtype {
510 struct forward_nameandtype *next;
514 } forward_nameandtype;
516 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
517 typedef struct forward_fieldmethint {
518 struct forward_fieldmethint *next;
522 u2 nameandtype_index;
523 } forward_fieldmethint;
529 forward_class *forward_classes = NULL;
530 forward_string *forward_strings = NULL;
531 forward_nameandtype *forward_nameandtypes = NULL;
532 forward_fieldmethint *forward_fieldmethints = NULL;
536 forward_nameandtype *nfn;
537 forward_fieldmethint *nff;
545 /* number of entries in the constant_pool table plus one */
546 if (!suck_check_classbuffer_size(cb, 2))
549 cpcount = c->cpcount = suck_u2(cb);
551 /* allocate memory */
552 cptags = c->cptags = MNEW(u1, cpcount);
553 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
556 exceptions_throw_classformaterror(c, "Illegal constant pool size");
560 #if defined(ENABLE_STATISTICS)
562 count_const_pool_len += (sizeof(u1) + sizeof(voidptr)) * cpcount;
565 /* initialize constantpool */
566 for (idx = 0; idx < cpcount; idx++) {
567 cptags[idx] = CONSTANT_UNUSED;
572 /******* first pass *******/
573 /* entries which cannot be resolved now are written into
574 temporary structures and traversed again later */
577 while (idx < cpcount) {
580 /* get constant type */
581 if (!suck_check_classbuffer_size(cb, 1))
588 nfc = DNEW(forward_class);
590 nfc->next = forward_classes;
591 forward_classes = nfc;
593 nfc->thisindex = idx;
594 /* reference to CONSTANT_NameAndType */
595 if (!suck_check_classbuffer_size(cb, 2))
598 nfc->name_index = suck_u2(cb);
603 case CONSTANT_String:
604 nfs = DNEW(forward_string);
606 nfs->next = forward_strings;
607 forward_strings = nfs;
609 nfs->thisindex = idx;
611 /* reference to CONSTANT_Utf8_info with string characters */
612 if (!suck_check_classbuffer_size(cb, 2))
615 nfs->string_index = suck_u2(cb);
620 case CONSTANT_NameAndType:
621 nfn = DNEW(forward_nameandtype);
623 nfn->next = forward_nameandtypes;
624 forward_nameandtypes = nfn;
626 nfn->thisindex = idx;
628 if (!suck_check_classbuffer_size(cb, 2 + 2))
631 /* reference to CONSTANT_Utf8_info containing simple name */
632 nfn->name_index = suck_u2(cb);
634 /* reference to CONSTANT_Utf8_info containing field or method
636 nfn->sig_index = suck_u2(cb);
641 case CONSTANT_Fieldref:
642 case CONSTANT_Methodref:
643 case CONSTANT_InterfaceMethodref:
644 nff = DNEW(forward_fieldmethint);
646 nff->next = forward_fieldmethints;
647 forward_fieldmethints = nff;
649 nff->thisindex = idx;
653 if (!suck_check_classbuffer_size(cb, 2 + 2))
656 /* class or interface type that contains the declaration of the
658 nff->class_index = suck_u2(cb);
660 /* name and descriptor of the field or method */
661 nff->nameandtype_index = suck_u2(cb);
666 case CONSTANT_Integer: {
667 constant_integer *ci = NEW(constant_integer);
669 #if defined(ENABLE_STATISTICS)
671 count_const_pool_len += sizeof(constant_integer);
674 if (!suck_check_classbuffer_size(cb, 4))
677 ci->value = suck_s4(cb);
678 cptags[idx] = CONSTANT_Integer;
685 case CONSTANT_Float: {
686 constant_float *cf = NEW(constant_float);
688 #if defined(ENABLE_STATISTICS)
690 count_const_pool_len += sizeof(constant_float);
693 if (!suck_check_classbuffer_size(cb, 4))
696 cf->value = suck_float(cb);
697 cptags[idx] = CONSTANT_Float;
704 case CONSTANT_Long: {
705 constant_long *cl = NEW(constant_long);
707 #if defined(ENABLE_STATISTICS)
709 count_const_pool_len += sizeof(constant_long);
712 if (!suck_check_classbuffer_size(cb, 8))
715 cl->value = suck_s8(cb);
716 cptags[idx] = CONSTANT_Long;
720 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
726 case CONSTANT_Double: {
727 constant_double *cd = NEW(constant_double);
729 #if defined(ENABLE_STATISTICS)
731 count_const_pool_len += sizeof(constant_double);
734 if (!suck_check_classbuffer_size(cb, 8))
737 cd->value = suck_double(cb);
738 cptags[idx] = CONSTANT_Double;
742 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
748 case CONSTANT_Utf8: {
751 /* number of bytes in the bytes array (not string-length) */
752 if (!suck_check_classbuffer_size(cb, 2))
755 length = suck_u2(cb);
756 cptags[idx] = CONSTANT_Utf8;
758 /* validate the string */
759 if (!suck_check_classbuffer_size(cb, length))
762 #ifdef ENABLE_VERIFIER
764 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
766 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
769 #endif /* ENABLE_VERIFIER */
770 /* insert utf-string into the utf-symboltable */
771 cpinfos[idx] = utf_new((char *) cb->pos, length);
773 /* skip bytes of the string (buffer size check above) */
774 suck_skip_nbytes(cb, length);
780 exceptions_throw_classformaterror(c, "Illegal constant pool type");
786 /* resolve entries in temporary structures */
788 while (forward_classes) {
790 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
794 #ifdef ENABLE_VERIFIER
795 if (opt_verify && !is_valid_name_utf(name)) {
796 exceptions_throw_classformaterror(c, "Class reference with invalid name");
799 #endif /* ENABLE_VERIFIER */
801 /* add all class references to the descriptor_pool */
803 if (!descriptor_pool_add_class(descpool, name))
806 cptags[forward_classes->thisindex] = CONSTANT_Class;
808 /* the classref is created later */
809 cpinfos[forward_classes->thisindex] = name;
811 nfc = forward_classes;
812 forward_classes = forward_classes->next;
815 while (forward_strings) {
817 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
821 /* resolve utf-string */
822 cptags[forward_strings->thisindex] = CONSTANT_String;
823 cpinfos[forward_strings->thisindex] = text;
825 nfs = forward_strings;
826 forward_strings = forward_strings->next;
829 while (forward_nameandtypes) {
830 constant_nameandtype *cn = NEW(constant_nameandtype);
832 #if defined(ENABLE_STATISTICS)
834 count_const_pool_len += sizeof(constant_nameandtype);
837 /* resolve simple name and descriptor */
838 cn->name = class_getconstant(c,
839 forward_nameandtypes->name_index,
844 cn->descriptor = class_getconstant(c,
845 forward_nameandtypes->sig_index,
850 #ifdef ENABLE_VERIFIER
853 if (!is_valid_name_utf(cn->name)) {
854 exceptions_throw_classformaterror(c,
855 "Illegal Field name \"%s\"",
861 /* disallow referencing <clinit> among others */
862 if (cn->name->text[0] == '<' && cn->name != utf_init) {
863 exceptions_throw_classformaterror(c, "Illegal reference to special method");
867 #endif /* ENABLE_VERIFIER */
869 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
870 cpinfos[forward_nameandtypes->thisindex] = cn;
872 nfn = forward_nameandtypes;
873 forward_nameandtypes = forward_nameandtypes->next;
876 while (forward_fieldmethints) {
877 constant_nameandtype *nat;
878 constant_FMIref *fmi = NEW(constant_FMIref);
880 #if defined(ENABLE_STATISTICS)
882 count_const_pool_len += sizeof(constant_FMIref);
884 /* resolve simple name and descriptor */
886 nat = class_getconstant(c,
887 forward_fieldmethints->nameandtype_index,
888 CONSTANT_NameAndType);
892 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
894 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
897 /* the classref is created later */
899 fmi->p.index = forward_fieldmethints->class_index;
900 fmi->name = nat->name;
901 fmi->descriptor = nat->descriptor;
903 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
904 cpinfos[forward_fieldmethints->thisindex] = fmi;
906 nff = forward_fieldmethints;
907 forward_fieldmethints = forward_fieldmethints->next;
910 /* everything was ok */
916 /* loader_load_attribute_signature *********************************************
918 Signature_attribute {
919 u2 attribute_name_index;
924 *******************************************************************************/
926 #if defined(ENABLE_JAVASE)
927 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
937 /* check remaining bytecode */
939 if (!suck_check_classbuffer_size(cb, 4 + 2))
942 /* check attribute length */
944 attribute_length = suck_u4(cb);
946 if (attribute_length != 2) {
947 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
951 if (*signature != NULL) {
952 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
958 signature_index = suck_u2(cb);
960 if (!(*signature = class_getconstant(c, signature_index, CONSTANT_Utf8)))
965 #endif /* defined(ENABLE_JAVASE) */
968 /* load_class_from_sysloader ***************************************************
970 Load the class with the given name using the system class loader
973 name.............the classname
977 NULL if an exception has been thrown
979 *******************************************************************************/
981 classinfo *load_class_from_sysloader(utf *name)
988 assert(class_java_lang_Object);
989 assert(class_java_lang_ClassLoader);
990 assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
992 m = class_resolveclassmethod(class_java_lang_ClassLoader,
993 utf_getSystemClassLoader,
994 utf_void__java_lang_ClassLoader,
995 class_java_lang_Object,
1001 clo = vm_call_method(m, NULL);
1006 cl = loader_hashtable_classloader_add(clo);
1008 c = load_class_from_classloader(name, cl);
1014 /* load_class_from_classloader *************************************************
1016 Load the class with the given name using the given user-defined class loader.
1019 name.............the classname
1020 cl...............user-defined class loader
1023 the loaded class, or
1024 NULL if an exception has been thrown
1026 *******************************************************************************/
1028 classinfo *load_class_from_classloader(utf *name, classloader *cl)
1033 java_handle_t *string;
1034 #if defined(ENABLE_RT_TIMING)
1035 struct timespec time_start, time_lookup, time_prepare, time_java,
1039 RT_TIMING_GET_TIME(time_start);
1043 /* lookup if this class has already been loaded */
1045 c = classcache_lookup(cl, name);
1047 RT_TIMING_GET_TIME(time_lookup);
1048 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1053 /* if other class loader than bootstrap, call it */
1061 namelen = name->blength;
1063 /* handle array classes */
1064 if (text[0] == '[') {
1070 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1071 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1072 exceptions_throw_classnotfoundexception(name);
1076 u = utf_new(text + 2, namelen - 3);
1078 if (!(comp = load_class_from_classloader(u, cl)))
1081 /* create the array class */
1083 c = class_array_of(comp, false);
1085 tmpc = classcache_store(cl, c, true);
1088 /* exception, free the loaded class */
1089 c->state &= ~CLASS_LOADING;
1096 /* load the component class */
1098 u = utf_new(text + 1, namelen - 1);
1100 if (!(comp = load_class_from_classloader(u, cl)))
1103 /* create the array class */
1105 c = class_array_of(comp, false);
1107 tmpc = classcache_store(cl, c, true);
1110 /* exception, free the loaded class */
1111 c->state &= ~CLASS_LOADING;
1118 /* primitive array classes are loaded by the bootstrap loader */
1120 c = load_class_bootstrap(name);
1126 assert(class_java_lang_Object);
1128 lc = class_resolveclassmethod(cl->object->vftbl->class,
1130 utf_java_lang_String__java_lang_Class,
1131 class_java_lang_Object,
1135 return false; /* exception */
1137 /* move return value into `o' and cast it afterwards to a classinfo* */
1139 string = javastring_new_slash_to_dot(name);
1141 RT_TIMING_GET_TIME(time_prepare);
1143 #if defined(ENABLE_HANDLES)
1144 o = vm_call_method(lc, (java_handle_t *) cl, string);
1146 o = vm_call_method(lc, cl->object, string);
1149 RT_TIMING_GET_TIME(time_java);
1151 c = LLNI_classinfo_unwrap(o);
1154 /* Store this class in the loaded class cache. If another
1155 class with the same (initloader,name) pair has been
1156 stored earlier it will be returned by classcache_store
1157 In this case classcache_store may not free the class
1158 because it has already been exposed to Java code which
1159 may have kept references to that class. */
1161 tmpc = classcache_store(cl, c, false);
1164 /* exception, free the loaded class */
1165 c->state &= ~CLASS_LOADING;
1172 RT_TIMING_GET_TIME(time_cache);
1174 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1175 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1176 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1178 /* SUN compatible -verbose:class output */
1180 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1182 utf_display_printable_ascii_classname(name);
1186 #if defined(ENABLE_JVMTI)
1187 /* fire Class Load JVMTI event */
1188 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1195 c = load_class_bootstrap(name);
1201 /* load_class_bootstrap ********************************************************
1203 Load the class with the given name using the bootstrap class loader.
1206 name.............the classname
1209 loaded classinfo, or
1210 NULL if an exception has been thrown
1213 load_class_bootstrap is synchronized. It can be treated as an
1216 *******************************************************************************/
1218 classinfo *load_class_bootstrap(utf *name)
1223 #if defined(ENABLE_RT_TIMING)
1224 struct timespec time_start, time_lookup, time_array, time_suck,
1225 time_load, time_cache;
1228 RT_TIMING_GET_TIME(time_start);
1234 /* lookup if this class has already been loaded */
1236 r = classcache_lookup(NULL, name);
1239 RT_TIMING_GET_TIME(time_lookup);
1240 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1245 RT_TIMING_GET_TIME(time_lookup);
1246 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1248 /* create the classinfo */
1250 c = class_create_classinfo(name);
1252 /* handle array classes */
1254 if (name->text[0] == '[') {
1255 c = load_newly_created_array(c, NULL);
1260 assert(c->state & CLASS_LOADED);
1262 RT_TIMING_GET_TIME(time_array);
1263 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1268 #if defined(ENABLE_STATISTICS)
1271 if (opt_getcompilingtime)
1272 compilingtime_stop();
1274 if (opt_getloadingtime)
1275 loadingtime_start();
1278 /* load classdata, throw exception on error */
1283 /* this normally means, the classpath was not set properly */
1285 if (name == utf_java_lang_Object)
1286 vm_abort("java/lang/NoClassDefFoundError: java/lang/Object");
1288 exceptions_throw_classnotfoundexception(name);
1293 RT_TIMING_GET_TIME(time_suck);
1295 /* load the class from the buffer */
1297 r = load_class_from_classbuffer(cb);
1299 RT_TIMING_GET_TIME(time_load);
1302 /* the class could not be loaded, free the classinfo struct */
1307 /* Store this class in the loaded class cache this step also
1308 checks the loading constraints. If the class has been loaded
1309 before, the earlier loaded class is returned. */
1311 classinfo *res = classcache_store(NULL, c, true);
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 *************************************************
1356 Loads everything interesting about a class from the class file. The
1357 'classinfo' structure must have been allocated previously.
1359 The super class and the interfaces implemented by this class need
1360 not be loaded. The link is set later by the function 'class_link'.
1363 This function is NOT synchronized!
1365 *******************************************************************************/
1367 classinfo *load_class_from_classbuffer(classbuffer *cb)
1375 descriptor_pool *descpool;
1376 #if defined(ENABLE_STATISTICS)
1380 #if defined(ENABLE_RT_TIMING)
1381 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1382 time_setup, time_fields, time_methods, time_classrefs,
1383 time_descs, time_setrefs, time_parsefds, time_parsemds,
1384 time_parsecpool, time_verify, time_attrs;
1387 RT_TIMING_GET_TIME(time_start);
1389 /* get the classbuffer's class */
1393 /* the class is already loaded */
1395 if (c->state & CLASS_LOADED)
1398 #if defined(ENABLE_STATISTICS)
1400 count_class_loads++;
1403 #if !defined(NDEBUG)
1404 /* output for debugging purposes */
1407 log_message_class("Loading class: ", c);
1410 /* mark start of dump memory area */
1412 dumpsize = dump_size();
1414 /* class is currently loading */
1416 c->state |= CLASS_LOADING;
1418 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1419 goto return_exception;
1421 /* check signature */
1423 if (suck_u4(cb) != MAGIC) {
1424 exceptions_throw_classformaterror(c, "Bad magic number");
1426 goto return_exception;
1434 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1435 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1436 goto return_exception;
1439 RT_TIMING_GET_TIME(time_checks);
1441 /* create a new descriptor pool */
1443 descpool = descriptor_pool_new(c);
1445 RT_TIMING_GET_TIME(time_ndpool);
1447 /* load the constant pool */
1449 if (!load_constantpool(cb, descpool))
1450 goto return_exception;
1452 RT_TIMING_GET_TIME(time_cpool);
1456 if (!suck_check_classbuffer_size(cb, 2))
1457 goto return_exception;
1459 /* We OR the flags here, as we set already some flags in
1460 class_create_classinfo. */
1462 c->flags |= suck_u2(cb);
1464 /* check ACC flags consistency */
1466 if (c->flags & ACC_INTERFACE) {
1467 if (!(c->flags & ACC_ABSTRACT)) {
1468 /* We work around this because interfaces in JDK 1.1 are
1469 * not declared abstract. */
1471 c->flags |= ACC_ABSTRACT;
1474 if (c->flags & ACC_FINAL) {
1475 exceptions_throw_classformaterror(c,
1476 "Illegal class modifiers: 0x%X",
1478 goto return_exception;
1481 if (c->flags & ACC_SUPER) {
1482 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1486 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1487 exceptions_throw_classformaterror(c,
1488 "Illegal class modifiers: 0x%X",
1490 goto return_exception;
1493 if (!suck_check_classbuffer_size(cb, 2 + 2))
1494 goto return_exception;
1500 if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1501 goto return_exception;
1503 if (c->name == utf_not_named_yet) {
1504 /* we finally have a name for this class */
1506 class_set_packagename(c);
1508 else if (name != c->name) {
1509 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
1510 goto return_exception;
1513 /* retrieve superclass */
1515 c->super.any = NULL;
1517 if ((i = suck_u2(cb))) {
1518 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1519 goto return_exception;
1521 /* java.lang.Object may not have a super class. */
1523 if (c->name == utf_java_lang_Object) {
1524 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
1525 goto return_exception;
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");
1532 goto return_exception;
1538 /* This is only allowed for java.lang.Object. */
1540 if (c->name != utf_java_lang_Object) {
1541 exceptions_throw_classformaterror(c, "Bad superclass index");
1542 goto return_exception;
1546 /* retrieve interfaces */
1548 if (!suck_check_classbuffer_size(cb, 2))
1549 goto return_exception;
1551 c->interfacescount = suck_u2(cb);
1553 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1554 goto return_exception;
1556 c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
1557 for (i = 0; i < c->interfacescount; i++) {
1558 /* the classrefs are created later */
1559 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1560 goto return_exception;
1563 RT_TIMING_GET_TIME(time_setup);
1567 if (!suck_check_classbuffer_size(cb, 2))
1568 goto return_exception;
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))
1577 goto return_exception;
1580 RT_TIMING_GET_TIME(time_fields);
1584 if (!suck_check_classbuffer_size(cb, 2))
1585 goto return_exception;
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))
1594 goto return_exception;
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 */
1623 for (i = 0; i < c->cpcount; i++) {
1624 if (c->cptags[i] == CONSTANT_Class) {
1625 utf *name = (utf *) c->cpinfos[i];
1626 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
1630 /* set the super class reference */
1633 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
1635 goto return_exception;
1638 /* set the super interfaces references */
1640 for (i = 0; i < c->interfacescount; i++) {
1641 c->interfaces[i].ref =
1642 descriptor_pool_lookup_classref(descpool,
1643 (utf *) c->interfaces[i].any);
1644 if (!c->interfaces[i].ref)
1645 goto return_exception;
1648 RT_TIMING_GET_TIME(time_setrefs);
1650 /* parse field descriptors */
1652 for (i = 0; i < c->fieldscount; i++) {
1653 c->fields[i].parseddesc =
1654 descriptor_pool_parse_field_descriptor(descpool,
1655 c->fields[i].descriptor);
1656 if (!c->fields[i].parseddesc)
1657 goto return_exception;
1660 RT_TIMING_GET_TIME(time_parsefds);
1662 /* parse method descriptors */
1664 for (i = 0; i < c->methodscount; i++) {
1665 methodinfo *m = &c->methods[i];
1667 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
1668 m->flags, class_get_self_classref(m->class));
1670 goto return_exception;
1672 for (j = 0; j < m->rawexceptiontablelength; j++) {
1673 if (!m->rawexceptiontable[j].catchtype.any)
1675 if ((m->rawexceptiontable[j].catchtype.ref =
1676 descriptor_pool_lookup_classref(descpool,
1677 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
1678 goto return_exception;
1681 for (j = 0; j < m->thrownexceptionscount; j++) {
1682 if (!m->thrownexceptions[j].any)
1684 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
1685 (utf *) m->thrownexceptions[j].any)) == NULL)
1686 goto return_exception;
1690 RT_TIMING_GET_TIME(time_parsemds);
1692 /* parse the loaded descriptors */
1694 for (i = 0; i < c->cpcount; i++) {
1695 constant_FMIref *fmi;
1698 switch (c->cptags[i]) {
1699 case CONSTANT_Fieldref:
1700 fmi = (constant_FMIref *) c->cpinfos[i];
1701 fmi->parseddesc.fd =
1702 descriptor_pool_parse_field_descriptor(descpool,
1704 if (!fmi->parseddesc.fd)
1705 goto return_exception;
1706 index = fmi->p.index;
1708 (constant_classref *) class_getconstant(c, index,
1710 if (!fmi->p.classref)
1711 goto return_exception;
1713 case CONSTANT_Methodref:
1714 case CONSTANT_InterfaceMethodref:
1715 fmi = (constant_FMIref *) c->cpinfos[i];
1716 index = fmi->p.index;
1718 (constant_classref *) class_getconstant(c, index,
1720 if (!fmi->p.classref)
1721 goto return_exception;
1722 fmi->parseddesc.md =
1723 descriptor_pool_parse_method_descriptor(descpool,
1727 if (!fmi->parseddesc.md)
1728 goto return_exception;
1733 RT_TIMING_GET_TIME(time_parsecpool);
1735 #ifdef ENABLE_VERIFIER
1736 /* Check if all fields and methods can be uniquely
1737 * identified by (name,descriptor). */
1740 /* We use a hash table here to avoid making the
1741 * average case quadratic in # of methods, fields.
1743 static int shift = 0;
1745 u2 *next; /* for chaining colliding hash entries */
1751 /* Allocate hashtable */
1752 len = c->methodscount;
1753 if (len < c->fieldscount) len = c->fieldscount;
1755 hashtab = MNEW(u2,(hashlen + len));
1756 next = hashtab + hashlen;
1758 /* Determine bitshift (to get good hash values) */
1768 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
1770 for (i = 0; i < c->fieldscount; ++i) {
1771 fieldinfo *fi = c->fields + i;
1773 /* It's ok if we lose bits here */
1774 index = ((((size_t) fi->name) +
1775 ((size_t) fi->descriptor)) >> shift) % hashlen;
1777 if ((old = hashtab[index])) {
1781 if (c->fields[old].name == fi->name &&
1782 c->fields[old].descriptor == fi->descriptor) {
1783 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
1784 goto return_exception;
1786 } while ((old = next[old]));
1788 hashtab[index] = i + 1;
1792 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
1794 for (i = 0; i < c->methodscount; ++i) {
1795 methodinfo *mi = c->methods + i;
1797 /* It's ok if we lose bits here */
1798 index = ((((size_t) mi->name) +
1799 ((size_t) mi->descriptor)) >> shift) % hashlen;
1803 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
1804 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
1808 if ((old = hashtab[index])) {
1812 if (c->methods[old].name == mi->name &&
1813 c->methods[old].descriptor == mi->descriptor) {
1814 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
1815 goto return_exception;
1817 } while ((old = next[old]));
1819 hashtab[index] = i + 1;
1822 MFREE(hashtab, u2, (hashlen + len));
1824 #endif /* ENABLE_VERIFIER */
1826 RT_TIMING_GET_TIME(time_verify);
1828 #if defined(ENABLE_STATISTICS)
1830 size_classinfo += sizeof(classinfo*) * c->interfacescount;
1831 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
1832 size_methodinfo += sizeof(methodinfo) * c->methodscount;
1836 /* load attribute structures */
1838 if (!class_load_attributes(cb))
1839 goto return_exception;
1841 /* Pre Java 1.5 version don't check this. This implementation is like
1842 Java 1.5 do it: for class file version 45.3 we don't check it, older
1843 versions are checked.
1846 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
1847 /* check if all data has been read */
1848 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
1850 if (classdata_left > 0) {
1851 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
1852 goto return_exception;
1856 RT_TIMING_GET_TIME(time_attrs);
1858 /* release dump area */
1860 dump_release(dumpsize);
1862 /* revert loading state and class is loaded */
1864 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
1866 #if defined(ENABLE_JVMTI)
1867 /* fire Class Prepare JVMTI event */
1870 jvmti_ClassLoadPrepare(true, c);
1873 #if !defined(NDEBUG)
1875 log_message_class("Loading done class: ", c);
1878 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
1879 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
1880 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
1881 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
1882 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
1883 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
1884 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
1885 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
1886 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
1887 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
1888 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
1889 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
1890 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
1891 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
1892 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
1897 /* release dump area */
1899 dump_release(dumpsize);
1901 /* an exception has been thrown */
1907 /* load_newly_created_array ****************************************************
1909 Load a newly created array class.
1912 c....................the array class C has been loaded
1913 other classinfo......the array class was found in the class cache,
1915 NULL.................an exception has been thrown
1918 This is an internal function. Do not use it unless you know exactly
1921 Use one of the load_class_... functions for general array class loading.
1923 *******************************************************************************/
1925 classinfo *load_newly_created_array(classinfo *c, classloader *loader)
1927 classinfo *comp = NULL;
1929 methoddesc *clonedesc;
1930 constant_classref *classrefs;
1935 text = c->name->text;
1936 namelen = c->name->blength;
1938 /* Check array class name */
1940 if ((namelen < 2) || (text[0] != '[')) {
1941 exceptions_throw_classnotfoundexception(c->name);
1945 /* Check the element type */
1949 /* c is an array of arrays. We have to create the component class. */
1951 u = utf_new(text + 1, namelen - 1);
1953 comp = load_class_from_classloader(u, loader);
1958 assert(comp->state & CLASS_LOADED);
1960 /* the array's flags are that of the component class */
1961 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
1962 c->classloader = comp->classloader;
1966 /* c is an array of objects. */
1968 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1969 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
1970 exceptions_throw_classnotfoundexception(c->name);
1974 u = utf_new(text + 2, namelen - 3);
1976 if (!(comp = load_class_from_classloader(u, loader)))
1979 assert(comp->state & CLASS_LOADED);
1981 /* the array's flags are that of the component class */
1982 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
1983 c->classloader = comp->classloader;
1987 /* c is an array of a primitive type */
1989 /* check for cases like `[II' and whether the character is a
1990 valid primitive type */
1992 if ((namelen > 2) || (primitive_class_get_by_char(text[1]) == NULL)) {
1993 exceptions_throw_classnotfoundexception(c->name);
1997 /* the accessibility of the array class is public (VM Spec 5.3.3) */
1998 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
1999 c->classloader = NULL;
2002 assert(class_java_lang_Object);
2003 #if defined(ENABLE_JAVASE)
2004 assert(class_java_lang_Cloneable);
2005 assert(class_java_io_Serializable);
2008 /* setup the array class */
2010 c->super.cls = class_java_lang_Object;
2012 #if defined(ENABLE_JAVASE)
2014 c->interfacescount = 2;
2015 c->interfaces = MNEW(classref_or_classinfo, 2);
2016 c->interfaces[0].cls = class_java_lang_Cloneable;
2017 c->interfaces[1].cls = class_java_io_Serializable;
2019 #elif defined(ENABLE_JAVAME_CLDC1_1)
2021 c->interfacescount = 0;
2022 c->interfaces = NULL;
2025 # error unknow Java configuration
2028 c->methodscount = 1;
2029 c->methods = MNEW(methodinfo, c->methodscount);
2030 MZERO(c->methods, methodinfo, c->methodscount);
2032 classrefs = MNEW(constant_classref, 2);
2033 CLASSREF_INIT(classrefs[0], c, c->name);
2034 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2036 /* create descriptor for clone method */
2037 /* we need one paramslot which is reserved for the 'this' parameter */
2038 clonedesc = NEW(methoddesc);
2039 clonedesc->returntype.type = TYPE_ADR;
2040 clonedesc->returntype.classref = classrefs + 1;
2041 clonedesc->returntype.arraydim = 0;
2042 /* initialize params to "empty", add real params below in
2043 descriptor_params_from_paramtypes */
2044 clonedesc->paramcount = 0;
2045 clonedesc->paramslots = 0;
2046 clonedesc->paramtypes[0].classref = classrefs + 0;
2047 clonedesc->params = NULL;
2049 /* create methodinfo */
2052 MSET(clone, 0, methodinfo, 1);
2054 #if defined(ENABLE_THREADS)
2055 lock_init_object_lock(&clone->header);
2058 /* ATTENTION: if you delete the ACC_NATIVE below, set
2059 clone->maxlocals=1 (interpreter related) */
2061 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2062 clone->name = utf_clone;
2063 clone->descriptor = utf_void__java_lang_Object;
2064 clone->parseddesc = clonedesc;
2067 /* parse the descriptor to get the register allocation */
2069 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2072 clone->code = codegen_generate_stub_native(clone, BUILTIN_clone);
2074 /* XXX: field: length? */
2076 /* array classes are not loaded from class files */
2078 c->state |= CLASS_LOADED;
2079 c->parseddescs = (u1 *) clonedesc;
2080 c->parseddescsize = sizeof(methodinfo);
2081 c->classrefs = classrefs;
2082 c->classrefcount = 1;
2084 /* insert class into the loaded class cache */
2085 /* XXX free classinfo if NULL returned? */
2087 return classcache_store(loader, c, true);
2091 /* loader_close ****************************************************************
2093 Frees all resources.
2095 *******************************************************************************/
2097 void loader_close(void)
2104 * These are local overrides for various environment variables in Emacs.
2105 * Please do not remove this and leave it at the end of the file, where
2106 * Emacs will automagically detect them.
2107 * ---------------------------------------------------------------------
2110 * indent-tabs-mode: t
2114 * vim:noexpandtab:sw=4:ts=4: