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/logging.h"
44 #include "vm/builtin.h"
45 #include "vm/exceptions.h"
46 #include "vm/global.h"
47 #include "vm/primitive.h"
48 #include "vm/stringlocal.h"
51 #include "vm/jit_interface.h"
53 #if defined(ENABLE_JAVASE)
54 # include "vmcore/annotation.h"
55 # include "vmcore/stackmap.h"
58 #include "vmcore/classcache.h"
59 #include "vmcore/field.h"
60 #include "vmcore/linker.h"
61 #include "vmcore/loader.h"
62 #include "vmcore/method.h"
63 #include "vmcore/options.h"
64 #include "vmcore/rt-timing.h"
66 #if defined(ENABLE_STATISTICS)
67 # include "vmcore/statistics.h"
70 #include "vmcore/suck.h"
72 #if defined(ENABLE_ZLIB)
73 # include "vmcore/zip.h"
76 #if defined(ENABLE_JVMTI)
77 # include "native/jvmti/cacaodbg.h"
81 /* loader_preinit **************************************************************
83 Initializes the classpath list and loads classes required for the
86 *******************************************************************************/
88 void loader_preinit(void)
90 #if defined(ENABLE_THREADS)
91 list_classpath_entry *lce;
93 /* Initialize the monitor pointer for zip/jar file locking. */
95 for (lce = list_first(list_classpath_entries); lce != NULL;
96 lce = list_next(list_classpath_entries, lce)) {
97 if (lce->type == CLASSPATH_ARCHIVE)
98 LOCK_INIT_OBJECT_LOCK(lce);
102 /* Load the most basic class. */
104 if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
105 vm_abort("loader_preinit: loading java/lang/Object failed");
107 #if defined(ENABLE_JAVASE)
108 if (!(class_java_lang_Cloneable =
109 load_class_bootstrap(utf_java_lang_Cloneable)))
110 vm_abort("loader_preinit: loading java/lang/Cloneable failed");
112 if (!(class_java_io_Serializable =
113 load_class_bootstrap(utf_java_io_Serializable)))
114 vm_abort("loader_preinit: loading java/io/Serializable failed");
119 /* loader_init *****************************************************************
121 Loads all classes required in the VM.
123 *******************************************************************************/
125 void loader_init(void)
127 /* Load primitive-type wrapping classes. */
129 #if defined(ENABLE_JAVASE)
130 if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
131 vm_abort("loader_init: loading failed");
134 if (!(class_java_lang_Boolean =
135 load_class_bootstrap(utf_java_lang_Boolean)))
136 vm_abort("loader_init: loading failed");
138 if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
139 vm_abort("loader_init: loading failed");
141 if (!(class_java_lang_Character =
142 load_class_bootstrap(utf_java_lang_Character)))
143 vm_abort("loader_init: loading failed");
145 if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
146 vm_abort("loader_init: loading failed");
148 if (!(class_java_lang_Integer =
149 load_class_bootstrap(utf_java_lang_Integer)))
150 vm_abort("loader_init: loading failed");
152 if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
153 vm_abort("loader_init: loading failed");
155 if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
156 vm_abort("loader_init: loading failed");
158 if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
159 vm_abort("loader_init: loading failed");
161 /* Load important system classes. */
163 if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
164 vm_abort("loader_init: loading failed");
166 if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
167 vm_abort("loader_init: loading failed");
169 #if defined(ENABLE_JAVASE)
170 if (!(class_java_lang_ClassLoader =
171 load_class_bootstrap(utf_java_lang_ClassLoader)))
172 vm_abort("loader_init: loading failed");
174 if (!(class_java_lang_SecurityManager =
175 load_class_bootstrap(utf_java_lang_SecurityManager)))
176 vm_abort("loader_init: loading failed");
179 if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
180 vm_abort("loader_init: loading failed");
182 if (!(class_java_lang_Thread =
183 load_class_bootstrap(utf_new_char("java/lang/Thread"))))
184 vm_abort("loader_init: loading failed");
186 #if defined(ENABLE_JAVASE)
187 if (!(class_java_lang_ThreadGroup =
188 load_class_bootstrap(utf_java_lang_ThreadGroup)))
189 vm_abort("loader_init: loading failed");
192 #if defined(WITH_CLASSPATH_GNU)
193 if (!(class_java_lang_VMSystem =
194 load_class_bootstrap(utf_new_char("java/lang/VMSystem"))))
195 vm_abort("loader_init: loading failed");
197 if (!(class_java_lang_VMThread =
198 load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
199 vm_abort("loader_init: loading failed");
203 /* some classes which may be used more often */
205 #if defined(ENABLE_JAVASE)
206 if (!(class_java_lang_StackTraceElement =
207 load_class_bootstrap(utf_java_lang_StackTraceElement)))
208 vm_abort("loader_init: loading failed");
210 if (!(class_java_lang_reflect_Constructor =
211 load_class_bootstrap(utf_java_lang_reflect_Constructor)))
212 vm_abort("loader_init: loading failed");
214 if (!(class_java_lang_reflect_Field =
215 load_class_bootstrap(utf_java_lang_reflect_Field)))
216 vm_abort("loader_init: loading failed");
218 if (!(class_java_lang_reflect_Method =
219 load_class_bootstrap(utf_java_lang_reflect_Method)))
220 vm_abort("loader_init: loading failed");
222 if (!(class_java_security_PrivilegedAction =
223 load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
224 vm_abort("loader_init: loading failed");
226 if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
227 vm_abort("loader_init: loading failed");
229 # if defined(WITH_CLASSPATH_SUN)
230 if (!(class_sun_reflect_MagicAccessorImpl =
231 load_class_bootstrap(utf_new_char("sun/reflect/MagicAccessorImpl"))))
232 vm_abort("loader_init: loading failed");
235 if (!(arrayclass_java_lang_Object =
236 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
237 vm_abort("loader_init: loading failed");
239 # if defined(ENABLE_ANNOTATIONS)
240 /* needed by annotation support */
241 if (!(class_sun_reflect_ConstantPool =
242 load_class_bootstrap(utf_new_char("sun/reflect/ConstantPool"))))
243 vm_abort("loader_init: loading failed");
245 # if defined(WITH_CLASSPATH_GNU)
246 /* needed by GNU Classpaths annotation support */
247 if (!(class_sun_reflect_annotation_AnnotationParser =
248 load_class_bootstrap(utf_new_char("sun/reflect/annotation/AnnotationParser"))))
249 vm_abort("loader_init: loading failed");
256 /* loader_load_all_classes *****************************************************
258 Loads all classes specified in the BOOTCLASSPATH.
260 *******************************************************************************/
262 void loader_load_all_classes(void)
264 list_classpath_entry *lce;
265 #if defined(ENABLE_ZLIB)
268 hashtable_zipfile_entry *htzfe;
272 for (lce = list_first(list_classpath_entries); lce != NULL;
273 lce = list_next(list_classpath_entries, lce)) {
274 #if defined(ENABLE_ZLIB)
275 if (lce->type == CLASSPATH_ARCHIVE) {
276 /* get the classes hashtable */
280 for (slot = 0; slot < ht->size; slot++) {
281 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
283 for (; htzfe; htzfe = htzfe->hashlink) {
286 /* skip all entries in META-INF and .properties,
289 if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
290 strstr(u->text, ".properties") ||
291 strstr(u->text, ".png"))
294 /* load class from bootstrap classloader */
296 if (!load_class_bootstrap(u)) {
297 fprintf(stderr, "Error loading: ");
298 utf_fprint_printable_ascii_classname(stderr, u);
299 fprintf(stderr, "\n");
302 /* print out exception and cause */
304 exceptions_print_current_exception();
312 #if defined(ENABLE_ZLIB)
319 /* loader_skip_attribute_body **************************************************
321 Skips an attribute the attribute_name_index has already been read.
324 u2 attribute_name_index;
326 u1 info[attribute_length];
329 *******************************************************************************/
331 bool loader_skip_attribute_body(classbuffer *cb)
335 if (!suck_check_classbuffer_size(cb, 4))
338 attribute_length = suck_u4(cb);
340 if (!suck_check_classbuffer_size(cb, attribute_length))
343 suck_skip_nbytes(cb, attribute_length);
349 /* load_constantpool ***********************************************************
351 Loads the constantpool of a class, the entries are transformed into
352 a simpler format by resolving references (a detailed overview of
353 the compact structures can be found in global.h).
355 *******************************************************************************/
357 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
360 /* The following structures are used to save information which cannot be
361 processed during the first pass. After the complete constantpool has
362 been traversed the references can be resolved.
363 (only in specific order) */
365 /* CONSTANT_Class entries */
366 typedef struct forward_class {
367 struct forward_class *next;
372 /* CONSTANT_String */
373 typedef struct forward_string {
374 struct forward_string *next;
379 /* CONSTANT_NameAndType */
380 typedef struct forward_nameandtype {
381 struct forward_nameandtype *next;
385 } forward_nameandtype;
387 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
388 typedef struct forward_fieldmethint {
389 struct forward_fieldmethint *next;
393 u2 nameandtype_index;
394 } forward_fieldmethint;
400 forward_class *forward_classes = NULL;
401 forward_string *forward_strings = NULL;
402 forward_nameandtype *forward_nameandtypes = NULL;
403 forward_fieldmethint *forward_fieldmethints = NULL;
407 forward_nameandtype *nfn;
408 forward_fieldmethint *nff;
416 /* number of entries in the constant_pool table plus one */
417 if (!suck_check_classbuffer_size(cb, 2))
420 cpcount = c->cpcount = suck_u2(cb);
422 /* allocate memory */
423 cptags = c->cptags = MNEW(u1, cpcount);
424 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
427 exceptions_throw_classformaterror(c, "Illegal constant pool size");
431 #if defined(ENABLE_STATISTICS)
433 count_const_pool_len += (sizeof(u1) + sizeof(voidptr)) * cpcount;
436 /* initialize constantpool */
437 for (idx = 0; idx < cpcount; idx++) {
438 cptags[idx] = CONSTANT_UNUSED;
443 /******* first pass *******/
444 /* entries which cannot be resolved now are written into
445 temporary structures and traversed again later */
448 while (idx < cpcount) {
451 /* get constant type */
452 if (!suck_check_classbuffer_size(cb, 1))
459 nfc = DNEW(forward_class);
461 nfc->next = forward_classes;
462 forward_classes = nfc;
464 nfc->thisindex = idx;
465 /* reference to CONSTANT_NameAndType */
466 if (!suck_check_classbuffer_size(cb, 2))
469 nfc->name_index = suck_u2(cb);
474 case CONSTANT_String:
475 nfs = DNEW(forward_string);
477 nfs->next = forward_strings;
478 forward_strings = nfs;
480 nfs->thisindex = idx;
482 /* reference to CONSTANT_Utf8_info with string characters */
483 if (!suck_check_classbuffer_size(cb, 2))
486 nfs->string_index = suck_u2(cb);
491 case CONSTANT_NameAndType:
492 nfn = DNEW(forward_nameandtype);
494 nfn->next = forward_nameandtypes;
495 forward_nameandtypes = nfn;
497 nfn->thisindex = idx;
499 if (!suck_check_classbuffer_size(cb, 2 + 2))
502 /* reference to CONSTANT_Utf8_info containing simple name */
503 nfn->name_index = suck_u2(cb);
505 /* reference to CONSTANT_Utf8_info containing field or method
507 nfn->sig_index = suck_u2(cb);
512 case CONSTANT_Fieldref:
513 case CONSTANT_Methodref:
514 case CONSTANT_InterfaceMethodref:
515 nff = DNEW(forward_fieldmethint);
517 nff->next = forward_fieldmethints;
518 forward_fieldmethints = nff;
520 nff->thisindex = idx;
524 if (!suck_check_classbuffer_size(cb, 2 + 2))
527 /* class or interface type that contains the declaration of the
529 nff->class_index = suck_u2(cb);
531 /* name and descriptor of the field or method */
532 nff->nameandtype_index = suck_u2(cb);
537 case CONSTANT_Integer: {
538 constant_integer *ci = NEW(constant_integer);
540 #if defined(ENABLE_STATISTICS)
542 count_const_pool_len += sizeof(constant_integer);
545 if (!suck_check_classbuffer_size(cb, 4))
548 ci->value = suck_s4(cb);
549 cptags[idx] = CONSTANT_Integer;
556 case CONSTANT_Float: {
557 constant_float *cf = NEW(constant_float);
559 #if defined(ENABLE_STATISTICS)
561 count_const_pool_len += sizeof(constant_float);
564 if (!suck_check_classbuffer_size(cb, 4))
567 cf->value = suck_float(cb);
568 cptags[idx] = CONSTANT_Float;
575 case CONSTANT_Long: {
576 constant_long *cl = NEW(constant_long);
578 #if defined(ENABLE_STATISTICS)
580 count_const_pool_len += sizeof(constant_long);
583 if (!suck_check_classbuffer_size(cb, 8))
586 cl->value = suck_s8(cb);
587 cptags[idx] = CONSTANT_Long;
591 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
597 case CONSTANT_Double: {
598 constant_double *cd = NEW(constant_double);
600 #if defined(ENABLE_STATISTICS)
602 count_const_pool_len += sizeof(constant_double);
605 if (!suck_check_classbuffer_size(cb, 8))
608 cd->value = suck_double(cb);
609 cptags[idx] = CONSTANT_Double;
613 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
619 case CONSTANT_Utf8: {
622 /* number of bytes in the bytes array (not string-length) */
623 if (!suck_check_classbuffer_size(cb, 2))
626 length = suck_u2(cb);
627 cptags[idx] = CONSTANT_Utf8;
629 /* validate the string */
630 if (!suck_check_classbuffer_size(cb, length))
633 #ifdef ENABLE_VERIFIER
635 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length)))
637 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
640 #endif /* ENABLE_VERIFIER */
641 /* insert utf-string into the utf-symboltable */
642 cpinfos[idx] = utf_new((char *) cb->pos, length);
644 /* skip bytes of the string (buffer size check above) */
645 suck_skip_nbytes(cb, length);
651 exceptions_throw_classformaterror(c, "Illegal constant pool type");
657 /* resolve entries in temporary structures */
659 while (forward_classes) {
661 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
665 #ifdef ENABLE_VERIFIER
666 if (opt_verify && !is_valid_name_utf(name)) {
667 exceptions_throw_classformaterror(c, "Class reference with invalid name");
670 #endif /* ENABLE_VERIFIER */
672 /* add all class references to the descriptor_pool */
674 if (!descriptor_pool_add_class(descpool, name))
677 cptags[forward_classes->thisindex] = CONSTANT_Class;
679 /* the classref is created later */
680 cpinfos[forward_classes->thisindex] = name;
682 nfc = forward_classes;
683 forward_classes = forward_classes->next;
686 while (forward_strings) {
688 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
692 /* resolve utf-string */
693 cptags[forward_strings->thisindex] = CONSTANT_String;
694 cpinfos[forward_strings->thisindex] = text;
696 nfs = forward_strings;
697 forward_strings = forward_strings->next;
700 while (forward_nameandtypes) {
701 constant_nameandtype *cn = NEW(constant_nameandtype);
703 #if defined(ENABLE_STATISTICS)
705 count_const_pool_len += sizeof(constant_nameandtype);
708 /* resolve simple name and descriptor */
709 cn->name = class_getconstant(c,
710 forward_nameandtypes->name_index,
715 cn->descriptor = class_getconstant(c,
716 forward_nameandtypes->sig_index,
721 #ifdef ENABLE_VERIFIER
724 if (!is_valid_name_utf(cn->name)) {
725 exceptions_throw_classformaterror(c,
726 "Illegal Field name \"%s\"",
732 /* disallow referencing <clinit> among others */
733 if (cn->name->text[0] == '<' && cn->name != utf_init) {
734 exceptions_throw_classformaterror(c, "Illegal reference to special method");
738 #endif /* ENABLE_VERIFIER */
740 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
741 cpinfos[forward_nameandtypes->thisindex] = cn;
743 nfn = forward_nameandtypes;
744 forward_nameandtypes = forward_nameandtypes->next;
747 while (forward_fieldmethints) {
748 constant_nameandtype *nat;
749 constant_FMIref *fmi = NEW(constant_FMIref);
751 #if defined(ENABLE_STATISTICS)
753 count_const_pool_len += sizeof(constant_FMIref);
755 /* resolve simple name and descriptor */
757 nat = class_getconstant(c,
758 forward_fieldmethints->nameandtype_index,
759 CONSTANT_NameAndType);
763 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
765 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
768 /* the classref is created later */
770 fmi->p.index = forward_fieldmethints->class_index;
771 fmi->name = nat->name;
772 fmi->descriptor = nat->descriptor;
774 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
775 cpinfos[forward_fieldmethints->thisindex] = fmi;
777 nff = forward_fieldmethints;
778 forward_fieldmethints = forward_fieldmethints->next;
781 /* everything was ok */
787 /* loader_load_attribute_signature *********************************************
789 Signature_attribute {
790 u2 attribute_name_index;
795 *******************************************************************************/
797 #if defined(ENABLE_JAVASE)
798 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
808 /* check remaining bytecode */
810 if (!suck_check_classbuffer_size(cb, 4 + 2))
813 /* check attribute length */
815 attribute_length = suck_u4(cb);
817 if (attribute_length != 2) {
818 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
822 if (*signature != NULL) {
823 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
829 signature_index = suck_u2(cb);
831 if (!(*signature = class_getconstant(c, signature_index, CONSTANT_Utf8)))
836 #endif /* defined(ENABLE_JAVASE) */
839 /* load_class_from_sysloader ***************************************************
841 Load the class with the given name using the system class loader
844 name.............the classname
848 NULL if an exception has been thrown
850 *******************************************************************************/
852 classinfo *load_class_from_sysloader(utf *name)
858 assert(class_java_lang_Object);
859 assert(class_java_lang_ClassLoader);
860 assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
862 m = class_resolveclassmethod(class_java_lang_ClassLoader,
863 utf_getSystemClassLoader,
864 utf_void__java_lang_ClassLoader,
865 class_java_lang_Object,
871 cl = vm_call_method(m, NULL);
876 c = load_class_from_classloader(name, cl);
882 /* load_class_from_classloader *************************************************
884 Load the class with the given name using the given user-defined class loader.
887 name.............the classname
888 cl...............user-defined class loader
892 NULL if an exception has been thrown
894 *******************************************************************************/
896 classinfo *load_class_from_classloader(utf *name, classloader *cl)
901 java_handle_t *string;
902 #if defined(ENABLE_RT_TIMING)
903 struct timespec time_start, time_lookup, time_prepare, time_java,
907 RT_TIMING_GET_TIME(time_start);
911 /* lookup if this class has already been loaded */
913 c = classcache_lookup(cl, name);
915 RT_TIMING_GET_TIME(time_lookup);
916 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
921 /* if other class loader than bootstrap, call it */
929 namelen = name->blength;
931 /* handle array classes */
932 if (text[0] == '[') {
938 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
939 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
940 exceptions_throw_classnotfoundexception(name);
944 u = utf_new(text + 2, namelen - 3);
946 if (!(comp = load_class_from_classloader(u, cl)))
949 /* create the array class */
951 c = class_array_of(comp, false);
953 tmpc = classcache_store(cl, c, true);
956 /* exception, free the loaded class */
957 c->state &= ~CLASS_LOADING;
964 /* load the component class */
966 u = utf_new(text + 1, namelen - 1);
968 if (!(comp = load_class_from_classloader(u, cl)))
971 /* create the array class */
973 c = class_array_of(comp, false);
975 tmpc = classcache_store(cl, c, true);
978 /* exception, free the loaded class */
979 c->state &= ~CLASS_LOADING;
986 /* primitive array classes are loaded by the bootstrap loader */
988 c = load_class_bootstrap(name);
994 assert(class_java_lang_Object);
996 lc = class_resolveclassmethod(cl->vftbl->class,
998 utf_java_lang_String__java_lang_Class,
999 class_java_lang_Object,
1003 return false; /* exception */
1005 /* move return value into `o' and cast it afterwards to a classinfo* */
1007 string = javastring_new_slash_to_dot(name);
1009 RT_TIMING_GET_TIME(time_prepare);
1011 o = vm_call_method(lc, cl, string);
1013 RT_TIMING_GET_TIME(time_java);
1015 c = LLNI_classinfo_unwrap(o);
1018 /* Store this class in the loaded class cache. If another
1019 class with the same (initloader,name) pair has been
1020 stored earlier it will be returned by classcache_store
1021 In this case classcache_store may not free the class
1022 because it has already been exposed to Java code which
1023 may have kept references to that class. */
1025 tmpc = classcache_store(cl, c, false);
1028 /* exception, free the loaded class */
1029 c->state &= ~CLASS_LOADING;
1036 RT_TIMING_GET_TIME(time_cache);
1038 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1039 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1040 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1042 /* SUN compatible -verbose:class output */
1044 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1046 utf_display_printable_ascii_classname(name);
1050 #if defined(ENABLE_JVMTI)
1051 /* fire Class Load JVMTI event */
1052 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1059 c = load_class_bootstrap(name);
1065 /* load_class_bootstrap ********************************************************
1067 Load the class with the given name using the bootstrap class loader.
1070 name.............the classname
1073 loaded classinfo, or
1074 NULL if an exception has been thrown
1077 load_class_bootstrap is synchronized. It can be treated as an
1080 *******************************************************************************/
1082 classinfo *load_class_bootstrap(utf *name)
1087 #if defined(ENABLE_RT_TIMING)
1088 struct timespec time_start, time_lookup, time_array, time_suck,
1089 time_load, time_cache;
1092 RT_TIMING_GET_TIME(time_start);
1098 /* lookup if this class has already been loaded */
1100 r = classcache_lookup(NULL, name);
1103 RT_TIMING_GET_TIME(time_lookup);
1104 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1109 RT_TIMING_GET_TIME(time_lookup);
1110 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1112 /* create the classinfo */
1114 c = class_create_classinfo(name);
1116 /* handle array classes */
1118 if (name->text[0] == '[') {
1119 c = load_newly_created_array(c, NULL);
1124 assert(c->state & CLASS_LOADED);
1126 RT_TIMING_GET_TIME(time_array);
1127 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1132 #if defined(ENABLE_STATISTICS)
1135 if (opt_getcompilingtime)
1136 compilingtime_stop();
1138 if (opt_getloadingtime)
1139 loadingtime_start();
1142 /* load classdata, throw exception on error */
1147 /* this normally means, the classpath was not set properly */
1149 if (name == utf_java_lang_Object)
1150 vm_abort("java/lang/NoClassDefFoundError: java/lang/Object");
1152 exceptions_throw_classnotfoundexception(name);
1157 RT_TIMING_GET_TIME(time_suck);
1159 /* load the class from the buffer */
1161 r = load_class_from_classbuffer(cb);
1163 RT_TIMING_GET_TIME(time_load);
1166 /* the class could not be loaded, free the classinfo struct */
1171 /* Store this class in the loaded class cache this step also
1172 checks the loading constraints. If the class has been loaded
1173 before, the earlier loaded class is returned. */
1175 classinfo *res = classcache_store(NULL, c, true);
1185 RT_TIMING_GET_TIME(time_cache);
1187 /* SUN compatible -verbose:class output */
1189 if (opt_verboseclass && r) {
1191 utf_display_printable_ascii_classname(name);
1192 printf(" from %s]\n", cb->path);
1199 #if defined(ENABLE_STATISTICS)
1202 if (opt_getloadingtime)
1205 if (opt_getcompilingtime)
1206 compilingtime_start();
1209 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1210 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1211 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1212 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1218 /* load_class_from_classbuffer *************************************************
1220 Loads everything interesting about a class from the class file. The
1221 'classinfo' structure must have been allocated previously.
1223 The super class and the interfaces implemented by this class need
1224 not be loaded. The link is set later by the function 'class_link'.
1227 This function is NOT synchronized!
1229 *******************************************************************************/
1231 classinfo *load_class_from_classbuffer(classbuffer *cb)
1239 descriptor_pool *descpool;
1240 #if defined(ENABLE_STATISTICS)
1244 #if defined(ENABLE_RT_TIMING)
1245 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1246 time_setup, time_fields, time_methods, time_classrefs,
1247 time_descs, time_setrefs, time_parsefds, time_parsemds,
1248 time_parsecpool, time_verify, time_attrs;
1251 RT_TIMING_GET_TIME(time_start);
1253 /* get the classbuffer's class */
1257 /* the class is already loaded */
1259 if (c->state & CLASS_LOADED)
1262 #if defined(ENABLE_STATISTICS)
1264 count_class_loads++;
1267 #if !defined(NDEBUG)
1268 /* output for debugging purposes */
1271 log_message_class("Loading class: ", c);
1274 /* mark start of dump memory area */
1276 dumpsize = dump_size();
1278 /* class is currently loading */
1280 c->state |= CLASS_LOADING;
1282 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1283 goto return_exception;
1285 /* check signature */
1287 if (suck_u4(cb) != MAGIC) {
1288 exceptions_throw_classformaterror(c, "Bad magic number");
1290 goto return_exception;
1298 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1299 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1300 goto return_exception;
1303 RT_TIMING_GET_TIME(time_checks);
1305 /* create a new descriptor pool */
1307 descpool = descriptor_pool_new(c);
1309 RT_TIMING_GET_TIME(time_ndpool);
1311 /* load the constant pool */
1313 if (!load_constantpool(cb, descpool))
1314 goto return_exception;
1316 RT_TIMING_GET_TIME(time_cpool);
1320 if (!suck_check_classbuffer_size(cb, 2))
1321 goto return_exception;
1323 /* We OR the flags here, as we set already some flags in
1324 class_create_classinfo. */
1326 c->flags |= suck_u2(cb);
1328 /* check ACC flags consistency */
1330 if (c->flags & ACC_INTERFACE) {
1331 if (!(c->flags & ACC_ABSTRACT)) {
1332 /* We work around this because interfaces in JDK 1.1 are
1333 * not declared abstract. */
1335 c->flags |= ACC_ABSTRACT;
1338 if (c->flags & ACC_FINAL) {
1339 exceptions_throw_classformaterror(c,
1340 "Illegal class modifiers: 0x%X",
1342 goto return_exception;
1345 if (c->flags & ACC_SUPER) {
1346 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1350 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1351 exceptions_throw_classformaterror(c,
1352 "Illegal class modifiers: 0x%X",
1354 goto return_exception;
1357 if (!suck_check_classbuffer_size(cb, 2 + 2))
1358 goto return_exception;
1364 if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1365 goto return_exception;
1367 if (c->name == utf_not_named_yet) {
1368 /* we finally have a name for this class */
1370 class_set_packagename(c);
1372 else if (name != c->name) {
1373 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
1374 goto return_exception;
1377 /* retrieve superclass */
1379 c->super.any = NULL;
1381 if ((i = suck_u2(cb))) {
1382 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1383 goto return_exception;
1385 /* java.lang.Object may not have a super class. */
1387 if (c->name == utf_java_lang_Object) {
1388 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
1389 goto return_exception;
1392 /* Interfaces must have java.lang.Object as super class. */
1394 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
1395 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
1396 goto return_exception;
1402 /* This is only allowed for java.lang.Object. */
1404 if (c->name != utf_java_lang_Object) {
1405 exceptions_throw_classformaterror(c, "Bad superclass index");
1406 goto return_exception;
1410 /* retrieve interfaces */
1412 if (!suck_check_classbuffer_size(cb, 2))
1413 goto return_exception;
1415 c->interfacescount = suck_u2(cb);
1417 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1418 goto return_exception;
1420 c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
1421 for (i = 0; i < c->interfacescount; i++) {
1422 /* the classrefs are created later */
1423 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1424 goto return_exception;
1427 RT_TIMING_GET_TIME(time_setup);
1431 if (!suck_check_classbuffer_size(cb, 2))
1432 goto return_exception;
1434 c->fieldscount = suck_u2(cb);
1435 c->fields = MNEW(fieldinfo, c->fieldscount);
1437 MZERO(c->fields, fieldinfo, c->fieldscount);
1439 for (i = 0; i < c->fieldscount; i++) {
1440 if (!field_load(cb, &(c->fields[i]), descpool))
1441 goto return_exception;
1444 RT_TIMING_GET_TIME(time_fields);
1448 if (!suck_check_classbuffer_size(cb, 2))
1449 goto return_exception;
1451 c->methodscount = suck_u2(cb);
1452 c->methods = MNEW(methodinfo, c->methodscount);
1454 MZERO(c->methods, methodinfo, c->methodscount);
1456 for (i = 0; i < c->methodscount; i++) {
1457 if (!method_load(cb, &(c->methods[i]), descpool))
1458 goto return_exception;
1461 RT_TIMING_GET_TIME(time_methods);
1463 /* create the class reference table */
1466 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
1468 RT_TIMING_GET_TIME(time_classrefs);
1470 /* allocate space for the parsed descriptors */
1472 descriptor_pool_alloc_parsed_descriptors(descpool);
1474 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
1476 #if defined(ENABLE_STATISTICS)
1478 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
1479 count_classref_len += classrefsize;
1480 count_parsed_desc_len += descsize;
1484 RT_TIMING_GET_TIME(time_descs);
1486 /* put the classrefs in the constant pool */
1487 for (i = 0; i < c->cpcount; i++) {
1488 if (c->cptags[i] == CONSTANT_Class) {
1489 utf *name = (utf *) c->cpinfos[i];
1490 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
1494 /* set the super class reference */
1497 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
1499 goto return_exception;
1502 /* set the super interfaces references */
1504 for (i = 0; i < c->interfacescount; i++) {
1505 c->interfaces[i].ref =
1506 descriptor_pool_lookup_classref(descpool,
1507 (utf *) c->interfaces[i].any);
1508 if (!c->interfaces[i].ref)
1509 goto return_exception;
1512 RT_TIMING_GET_TIME(time_setrefs);
1514 /* parse field descriptors */
1516 for (i = 0; i < c->fieldscount; i++) {
1517 c->fields[i].parseddesc =
1518 descriptor_pool_parse_field_descriptor(descpool,
1519 c->fields[i].descriptor);
1520 if (!c->fields[i].parseddesc)
1521 goto return_exception;
1524 RT_TIMING_GET_TIME(time_parsefds);
1526 /* parse method descriptors */
1528 for (i = 0; i < c->methodscount; i++) {
1529 methodinfo *m = &c->methods[i];
1531 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
1532 m->flags, class_get_self_classref(m->class));
1534 goto return_exception;
1536 for (j = 0; j < m->rawexceptiontablelength; j++) {
1537 if (!m->rawexceptiontable[j].catchtype.any)
1539 if ((m->rawexceptiontable[j].catchtype.ref =
1540 descriptor_pool_lookup_classref(descpool,
1541 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
1542 goto return_exception;
1545 for (j = 0; j < m->thrownexceptionscount; j++) {
1546 if (!m->thrownexceptions[j].any)
1548 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
1549 (utf *) m->thrownexceptions[j].any)) == NULL)
1550 goto return_exception;
1554 RT_TIMING_GET_TIME(time_parsemds);
1556 /* parse the loaded descriptors */
1558 for (i = 0; i < c->cpcount; i++) {
1559 constant_FMIref *fmi;
1562 switch (c->cptags[i]) {
1563 case CONSTANT_Fieldref:
1564 fmi = (constant_FMIref *) c->cpinfos[i];
1565 fmi->parseddesc.fd =
1566 descriptor_pool_parse_field_descriptor(descpool,
1568 if (!fmi->parseddesc.fd)
1569 goto return_exception;
1570 index = fmi->p.index;
1572 (constant_classref *) class_getconstant(c, index,
1574 if (!fmi->p.classref)
1575 goto return_exception;
1577 case CONSTANT_Methodref:
1578 case CONSTANT_InterfaceMethodref:
1579 fmi = (constant_FMIref *) c->cpinfos[i];
1580 index = fmi->p.index;
1582 (constant_classref *) class_getconstant(c, index,
1584 if (!fmi->p.classref)
1585 goto return_exception;
1586 fmi->parseddesc.md =
1587 descriptor_pool_parse_method_descriptor(descpool,
1591 if (!fmi->parseddesc.md)
1592 goto return_exception;
1597 RT_TIMING_GET_TIME(time_parsecpool);
1599 #ifdef ENABLE_VERIFIER
1600 /* Check if all fields and methods can be uniquely
1601 * identified by (name,descriptor). */
1604 /* We use a hash table here to avoid making the
1605 * average case quadratic in # of methods, fields.
1607 static int shift = 0;
1609 u2 *next; /* for chaining colliding hash entries */
1615 /* Allocate hashtable */
1616 len = c->methodscount;
1617 if (len < c->fieldscount) len = c->fieldscount;
1619 hashtab = MNEW(u2,(hashlen + len));
1620 next = hashtab + hashlen;
1622 /* Determine bitshift (to get good hash values) */
1632 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
1634 for (i = 0; i < c->fieldscount; ++i) {
1635 fieldinfo *fi = c->fields + i;
1637 /* It's ok if we lose bits here */
1638 index = ((((size_t) fi->name) +
1639 ((size_t) fi->descriptor)) >> shift) % hashlen;
1641 if ((old = hashtab[index])) {
1645 if (c->fields[old].name == fi->name &&
1646 c->fields[old].descriptor == fi->descriptor) {
1647 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
1648 goto return_exception;
1650 } while ((old = next[old]));
1652 hashtab[index] = i + 1;
1656 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
1658 for (i = 0; i < c->methodscount; ++i) {
1659 methodinfo *mi = c->methods + i;
1661 /* It's ok if we lose bits here */
1662 index = ((((size_t) mi->name) +
1663 ((size_t) mi->descriptor)) >> shift) % hashlen;
1667 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
1668 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
1672 if ((old = hashtab[index])) {
1676 if (c->methods[old].name == mi->name &&
1677 c->methods[old].descriptor == mi->descriptor) {
1678 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
1679 goto return_exception;
1681 } while ((old = next[old]));
1683 hashtab[index] = i + 1;
1686 MFREE(hashtab, u2, (hashlen + len));
1688 #endif /* ENABLE_VERIFIER */
1690 RT_TIMING_GET_TIME(time_verify);
1692 #if defined(ENABLE_STATISTICS)
1694 size_classinfo += sizeof(classinfo*) * c->interfacescount;
1695 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
1696 size_methodinfo += sizeof(methodinfo) * c->methodscount;
1700 /* load attribute structures */
1702 if (!class_load_attributes(cb))
1703 goto return_exception;
1705 /* Pre Java 1.5 version don't check this. This implementation is like
1706 Java 1.5 do it: for class file version 45.3 we don't check it, older
1707 versions are checked.
1710 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
1711 /* check if all data has been read */
1712 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
1714 if (classdata_left > 0) {
1715 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
1716 goto return_exception;
1720 RT_TIMING_GET_TIME(time_attrs);
1722 /* release dump area */
1724 dump_release(dumpsize);
1726 /* revert loading state and class is loaded */
1728 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
1730 #if defined(ENABLE_JVMTI)
1731 /* fire Class Prepare JVMTI event */
1734 jvmti_ClassLoadPrepare(true, c);
1737 #if !defined(NDEBUG)
1739 log_message_class("Loading done class: ", c);
1742 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
1743 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
1744 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
1745 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
1746 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
1747 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
1748 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
1749 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
1750 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
1751 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
1752 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
1753 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
1754 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
1755 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
1756 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
1761 /* release dump area */
1763 dump_release(dumpsize);
1765 /* an exception has been thrown */
1771 /* load_newly_created_array ****************************************************
1773 Load a newly created array class.
1776 c....................the array class C has been loaded
1777 other classinfo......the array class was found in the class cache,
1779 NULL.................an exception has been thrown
1782 This is an internal function. Do not use it unless you know exactly
1785 Use one of the load_class_... functions for general array class loading.
1787 *******************************************************************************/
1789 classinfo *load_newly_created_array(classinfo *c, classloader *loader)
1791 classinfo *comp = NULL;
1793 methoddesc *clonedesc;
1794 constant_classref *classrefs;
1799 text = c->name->text;
1800 namelen = c->name->blength;
1802 /* Check array class name */
1804 if ((namelen < 2) || (text[0] != '[')) {
1805 exceptions_throw_classnotfoundexception(c->name);
1809 /* Check the element type */
1813 /* c is an array of arrays. We have to create the component class. */
1815 u = utf_new(text + 1, namelen - 1);
1817 comp = load_class_from_classloader(u, loader);
1822 assert(comp->state & CLASS_LOADED);
1824 /* the array's flags are that of the component class */
1825 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
1826 c->classloader = comp->classloader;
1830 /* c is an array of objects. */
1832 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1833 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
1834 exceptions_throw_classnotfoundexception(c->name);
1838 u = utf_new(text + 2, namelen - 3);
1840 if (!(comp = load_class_from_classloader(u, loader)))
1843 assert(comp->state & CLASS_LOADED);
1845 /* the array's flags are that of the component class */
1846 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
1847 c->classloader = comp->classloader;
1851 /* c is an array of a primitive type */
1853 /* check for cases like `[II' and whether the character is a
1854 valid primitive type */
1856 if ((namelen > 2) || (primitive_class_get_by_char(text[1]) == NULL)) {
1857 exceptions_throw_classnotfoundexception(c->name);
1861 /* the accessibility of the array class is public (VM Spec 5.3.3) */
1862 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
1863 c->classloader = NULL;
1866 assert(class_java_lang_Object);
1867 #if defined(ENABLE_JAVASE)
1868 assert(class_java_lang_Cloneable);
1869 assert(class_java_io_Serializable);
1872 /* setup the array class */
1874 c->super.cls = class_java_lang_Object;
1876 #if defined(ENABLE_JAVASE)
1878 c->interfacescount = 2;
1879 c->interfaces = MNEW(classref_or_classinfo, 2);
1880 c->interfaces[0].cls = class_java_lang_Cloneable;
1881 c->interfaces[1].cls = class_java_io_Serializable;
1883 #elif defined(ENABLE_JAVAME_CLDC1_1)
1885 c->interfacescount = 0;
1886 c->interfaces = NULL;
1889 # error unknow Java configuration
1892 c->methodscount = 1;
1893 c->methods = MNEW(methodinfo, c->methodscount);
1894 MZERO(c->methods, methodinfo, c->methodscount);
1896 classrefs = MNEW(constant_classref, 2);
1897 CLASSREF_INIT(classrefs[0], c, c->name);
1898 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
1900 /* create descriptor for clone method */
1901 /* we need one paramslot which is reserved for the 'this' parameter */
1902 clonedesc = NEW(methoddesc);
1903 clonedesc->returntype.type = TYPE_ADR;
1904 clonedesc->returntype.classref = classrefs + 1;
1905 clonedesc->returntype.arraydim = 0;
1906 /* initialize params to "empty", add real params below in
1907 descriptor_params_from_paramtypes */
1908 clonedesc->paramcount = 0;
1909 clonedesc->paramslots = 0;
1910 clonedesc->paramtypes[0].classref = classrefs + 0;
1911 clonedesc->params = NULL;
1913 /* create methodinfo */
1916 MSET(clone, 0, methodinfo, 1);
1918 #if defined(ENABLE_THREADS)
1919 lock_init_object_lock(&clone->header);
1922 /* ATTENTION: if you delete the ACC_NATIVE below, set
1923 clone->maxlocals=1 (interpreter related) */
1925 clone->flags = ACC_PUBLIC | ACC_NATIVE;
1926 clone->name = utf_clone;
1927 clone->descriptor = utf_void__java_lang_Object;
1928 clone->parseddesc = clonedesc;
1931 /* parse the descriptor to get the register allocation */
1933 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
1936 clone->code = codegen_generate_stub_native(clone, BUILTIN_clone);
1938 /* XXX: field: length? */
1940 /* array classes are not loaded from class files */
1942 c->state |= CLASS_LOADED;
1943 c->parseddescs = (u1 *) clonedesc;
1944 c->parseddescsize = sizeof(methodinfo);
1945 c->classrefs = classrefs;
1946 c->classrefcount = 1;
1948 /* insert class into the loaded class cache */
1949 /* XXX free classinfo if NULL returned? */
1951 return classcache_store(loader, c, true);
1955 /* loader_close ****************************************************************
1957 Frees all resources.
1959 *******************************************************************************/
1961 void loader_close(void)
1968 * These are local overrides for various environment variables in Emacs.
1969 * Please do not remove this and leave it at the end of the file, where
1970 * Emacs will automagically detect them.
1971 * ---------------------------------------------------------------------
1974 * indent-tabs-mode: t
1978 * vim:noexpandtab:sw=4:ts=4: