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 #if defined(WITH_CLASSPATH_SUN)
995 /* OpenJDK uses this internal function because it's
998 lc = class_resolveclassmethod(cl->vftbl->class,
999 utf_loadClassInternal,
1000 utf_java_lang_String__java_lang_Class,
1004 lc = class_resolveclassmethod(cl->vftbl->class,
1006 utf_java_lang_String__java_lang_Class,
1012 return false; /* exception */
1014 /* move return value into `o' and cast it afterwards to a classinfo* */
1016 string = javastring_new_slash_to_dot(name);
1018 RT_TIMING_GET_TIME(time_prepare);
1020 o = vm_call_method(lc, cl, string);
1022 RT_TIMING_GET_TIME(time_java);
1024 c = LLNI_classinfo_unwrap(o);
1027 /* Store this class in the loaded class cache. If another
1028 class with the same (initloader,name) pair has been
1029 stored earlier it will be returned by classcache_store
1030 In this case classcache_store may not free the class
1031 because it has already been exposed to Java code which
1032 may have kept references to that class. */
1034 tmpc = classcache_store(cl, c, false);
1037 /* exception, free the loaded class */
1038 c->state &= ~CLASS_LOADING;
1045 RT_TIMING_GET_TIME(time_cache);
1047 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1048 RT_TIMING_TIME_DIFF(time_prepare, time_java , RT_TIMING_LOAD_CL_JAVA);
1049 RT_TIMING_TIME_DIFF(time_java , time_cache , RT_TIMING_LOAD_CL_CACHE);
1051 /* SUN compatible -verbose:class output */
1053 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1055 utf_display_printable_ascii_classname(name);
1059 #if defined(ENABLE_JVMTI)
1060 /* fire Class Load JVMTI event */
1061 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1068 c = load_class_bootstrap(name);
1074 /* load_class_bootstrap ********************************************************
1076 Load the class with the given name using the bootstrap class loader.
1079 name.............the classname
1082 loaded classinfo, or
1083 NULL if an exception has been thrown
1086 load_class_bootstrap is synchronized. It can be treated as an
1089 *******************************************************************************/
1091 classinfo *load_class_bootstrap(utf *name)
1096 #if defined(ENABLE_RT_TIMING)
1097 struct timespec time_start, time_lookup, time_array, time_suck,
1098 time_load, time_cache;
1101 RT_TIMING_GET_TIME(time_start);
1107 /* lookup if this class has already been loaded */
1109 r = classcache_lookup(NULL, name);
1112 RT_TIMING_GET_TIME(time_lookup);
1113 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1118 RT_TIMING_GET_TIME(time_lookup);
1119 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1121 /* create the classinfo */
1123 c = class_create_classinfo(name);
1125 /* handle array classes */
1127 if (name->text[0] == '[') {
1128 c = load_newly_created_array(c, NULL);
1133 assert(c->state & CLASS_LOADED);
1135 RT_TIMING_GET_TIME(time_array);
1136 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1141 #if defined(ENABLE_STATISTICS)
1144 if (opt_getcompilingtime)
1145 compilingtime_stop();
1147 if (opt_getloadingtime)
1148 loadingtime_start();
1151 /* load classdata, throw exception on error */
1156 /* this normally means, the classpath was not set properly */
1158 if (name == utf_java_lang_Object)
1159 vm_abort("java/lang/NoClassDefFoundError: java/lang/Object");
1161 exceptions_throw_classnotfoundexception(name);
1166 RT_TIMING_GET_TIME(time_suck);
1168 /* load the class from the buffer */
1170 r = load_class_from_classbuffer(cb);
1172 RT_TIMING_GET_TIME(time_load);
1175 /* the class could not be loaded, free the classinfo struct */
1180 /* Store this class in the loaded class cache this step also
1181 checks the loading constraints. If the class has been loaded
1182 before, the earlier loaded class is returned. */
1184 classinfo *res = classcache_store(NULL, c, true);
1194 RT_TIMING_GET_TIME(time_cache);
1196 /* SUN compatible -verbose:class output */
1198 if (opt_verboseclass && r) {
1200 utf_display_printable_ascii_classname(name);
1201 printf(" from %s]\n", cb->path);
1208 #if defined(ENABLE_STATISTICS)
1211 if (opt_getloadingtime)
1214 if (opt_getcompilingtime)
1215 compilingtime_start();
1218 RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1219 RT_TIMING_TIME_DIFF(time_suck , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1220 RT_TIMING_TIME_DIFF(time_load , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1221 RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1227 /* load_class_from_classbuffer *************************************************
1229 Loads everything interesting about a class from the class file. The
1230 'classinfo' structure must have been allocated previously.
1232 The super class and the interfaces implemented by this class need
1233 not be loaded. The link is set later by the function 'class_link'.
1236 This function is NOT synchronized!
1238 *******************************************************************************/
1240 classinfo *load_class_from_classbuffer(classbuffer *cb)
1248 descriptor_pool *descpool;
1249 #if defined(ENABLE_STATISTICS)
1253 #if defined(ENABLE_RT_TIMING)
1254 struct timespec time_start, time_checks, time_ndpool, time_cpool,
1255 time_setup, time_fields, time_methods, time_classrefs,
1256 time_descs, time_setrefs, time_parsefds, time_parsemds,
1257 time_parsecpool, time_verify, time_attrs;
1260 RT_TIMING_GET_TIME(time_start);
1262 /* get the classbuffer's class */
1266 /* the class is already loaded */
1268 if (c->state & CLASS_LOADED)
1271 #if defined(ENABLE_STATISTICS)
1273 count_class_loads++;
1276 #if !defined(NDEBUG)
1277 /* output for debugging purposes */
1280 log_message_class("Loading class: ", c);
1283 /* mark start of dump memory area */
1285 dumpsize = dump_size();
1287 /* class is currently loading */
1289 c->state |= CLASS_LOADING;
1291 if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1292 goto return_exception;
1294 /* check signature */
1296 if (suck_u4(cb) != MAGIC) {
1297 exceptions_throw_classformaterror(c, "Bad magic number");
1299 goto return_exception;
1307 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1308 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1309 goto return_exception;
1312 RT_TIMING_GET_TIME(time_checks);
1314 /* create a new descriptor pool */
1316 descpool = descriptor_pool_new(c);
1318 RT_TIMING_GET_TIME(time_ndpool);
1320 /* load the constant pool */
1322 if (!load_constantpool(cb, descpool))
1323 goto return_exception;
1325 RT_TIMING_GET_TIME(time_cpool);
1329 if (!suck_check_classbuffer_size(cb, 2))
1330 goto return_exception;
1332 /* We OR the flags here, as we set already some flags in
1333 class_create_classinfo. */
1335 c->flags |= suck_u2(cb);
1337 /* check ACC flags consistency */
1339 if (c->flags & ACC_INTERFACE) {
1340 if (!(c->flags & ACC_ABSTRACT)) {
1341 /* We work around this because interfaces in JDK 1.1 are
1342 * not declared abstract. */
1344 c->flags |= ACC_ABSTRACT;
1347 if (c->flags & ACC_FINAL) {
1348 exceptions_throw_classformaterror(c,
1349 "Illegal class modifiers: 0x%X",
1351 goto return_exception;
1354 if (c->flags & ACC_SUPER) {
1355 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1359 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1360 exceptions_throw_classformaterror(c,
1361 "Illegal class modifiers: 0x%X",
1363 goto return_exception;
1366 if (!suck_check_classbuffer_size(cb, 2 + 2))
1367 goto return_exception;
1373 if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1374 goto return_exception;
1376 if (c->name == utf_not_named_yet) {
1377 /* we finally have a name for this class */
1379 class_set_packagename(c);
1381 else if (name != c->name) {
1382 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
1383 goto return_exception;
1386 /* retrieve superclass */
1388 c->super.any = NULL;
1390 if ((i = suck_u2(cb))) {
1391 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1392 goto return_exception;
1394 /* java.lang.Object may not have a super class. */
1396 if (c->name == utf_java_lang_Object) {
1397 exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
1398 goto return_exception;
1401 /* Interfaces must have java.lang.Object as super class. */
1403 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
1404 exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
1405 goto return_exception;
1411 /* This is only allowed for java.lang.Object. */
1413 if (c->name != utf_java_lang_Object) {
1414 exceptions_throw_classformaterror(c, "Bad superclass index");
1415 goto return_exception;
1419 /* retrieve interfaces */
1421 if (!suck_check_classbuffer_size(cb, 2))
1422 goto return_exception;
1424 c->interfacescount = suck_u2(cb);
1426 if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1427 goto return_exception;
1429 c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
1430 for (i = 0; i < c->interfacescount; i++) {
1431 /* the classrefs are created later */
1432 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1433 goto return_exception;
1436 RT_TIMING_GET_TIME(time_setup);
1440 if (!suck_check_classbuffer_size(cb, 2))
1441 goto return_exception;
1443 c->fieldscount = suck_u2(cb);
1444 c->fields = MNEW(fieldinfo, c->fieldscount);
1446 MZERO(c->fields, fieldinfo, c->fieldscount);
1448 for (i = 0; i < c->fieldscount; i++) {
1449 if (!field_load(cb, &(c->fields[i]), descpool))
1450 goto return_exception;
1453 RT_TIMING_GET_TIME(time_fields);
1457 if (!suck_check_classbuffer_size(cb, 2))
1458 goto return_exception;
1460 c->methodscount = suck_u2(cb);
1461 c->methods = MNEW(methodinfo, c->methodscount);
1463 MZERO(c->methods, methodinfo, c->methodscount);
1465 for (i = 0; i < c->methodscount; i++) {
1466 if (!method_load(cb, &(c->methods[i]), descpool))
1467 goto return_exception;
1470 RT_TIMING_GET_TIME(time_methods);
1472 /* create the class reference table */
1475 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
1477 RT_TIMING_GET_TIME(time_classrefs);
1479 /* allocate space for the parsed descriptors */
1481 descriptor_pool_alloc_parsed_descriptors(descpool);
1483 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
1485 #if defined(ENABLE_STATISTICS)
1487 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
1488 count_classref_len += classrefsize;
1489 count_parsed_desc_len += descsize;
1493 RT_TIMING_GET_TIME(time_descs);
1495 /* put the classrefs in the constant pool */
1496 for (i = 0; i < c->cpcount; i++) {
1497 if (c->cptags[i] == CONSTANT_Class) {
1498 utf *name = (utf *) c->cpinfos[i];
1499 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
1503 /* set the super class reference */
1506 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
1508 goto return_exception;
1511 /* set the super interfaces references */
1513 for (i = 0; i < c->interfacescount; i++) {
1514 c->interfaces[i].ref =
1515 descriptor_pool_lookup_classref(descpool,
1516 (utf *) c->interfaces[i].any);
1517 if (!c->interfaces[i].ref)
1518 goto return_exception;
1521 RT_TIMING_GET_TIME(time_setrefs);
1523 /* parse field descriptors */
1525 for (i = 0; i < c->fieldscount; i++) {
1526 c->fields[i].parseddesc =
1527 descriptor_pool_parse_field_descriptor(descpool,
1528 c->fields[i].descriptor);
1529 if (!c->fields[i].parseddesc)
1530 goto return_exception;
1533 RT_TIMING_GET_TIME(time_parsefds);
1535 /* parse method descriptors */
1537 for (i = 0; i < c->methodscount; i++) {
1538 methodinfo *m = &c->methods[i];
1540 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
1541 m->flags, class_get_self_classref(m->class));
1543 goto return_exception;
1545 for (j = 0; j < m->rawexceptiontablelength; j++) {
1546 if (!m->rawexceptiontable[j].catchtype.any)
1548 if ((m->rawexceptiontable[j].catchtype.ref =
1549 descriptor_pool_lookup_classref(descpool,
1550 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
1551 goto return_exception;
1554 for (j = 0; j < m->thrownexceptionscount; j++) {
1555 if (!m->thrownexceptions[j].any)
1557 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
1558 (utf *) m->thrownexceptions[j].any)) == NULL)
1559 goto return_exception;
1563 RT_TIMING_GET_TIME(time_parsemds);
1565 /* parse the loaded descriptors */
1567 for (i = 0; i < c->cpcount; i++) {
1568 constant_FMIref *fmi;
1571 switch (c->cptags[i]) {
1572 case CONSTANT_Fieldref:
1573 fmi = (constant_FMIref *) c->cpinfos[i];
1574 fmi->parseddesc.fd =
1575 descriptor_pool_parse_field_descriptor(descpool,
1577 if (!fmi->parseddesc.fd)
1578 goto return_exception;
1579 index = fmi->p.index;
1581 (constant_classref *) class_getconstant(c, index,
1583 if (!fmi->p.classref)
1584 goto return_exception;
1586 case CONSTANT_Methodref:
1587 case CONSTANT_InterfaceMethodref:
1588 fmi = (constant_FMIref *) c->cpinfos[i];
1589 index = fmi->p.index;
1591 (constant_classref *) class_getconstant(c, index,
1593 if (!fmi->p.classref)
1594 goto return_exception;
1595 fmi->parseddesc.md =
1596 descriptor_pool_parse_method_descriptor(descpool,
1600 if (!fmi->parseddesc.md)
1601 goto return_exception;
1606 RT_TIMING_GET_TIME(time_parsecpool);
1608 #ifdef ENABLE_VERIFIER
1609 /* Check if all fields and methods can be uniquely
1610 * identified by (name,descriptor). */
1613 /* We use a hash table here to avoid making the
1614 * average case quadratic in # of methods, fields.
1616 static int shift = 0;
1618 u2 *next; /* for chaining colliding hash entries */
1624 /* Allocate hashtable */
1625 len = c->methodscount;
1626 if (len < c->fieldscount) len = c->fieldscount;
1628 hashtab = MNEW(u2,(hashlen + len));
1629 next = hashtab + hashlen;
1631 /* Determine bitshift (to get good hash values) */
1641 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
1643 for (i = 0; i < c->fieldscount; ++i) {
1644 fieldinfo *fi = c->fields + i;
1646 /* It's ok if we lose bits here */
1647 index = ((((size_t) fi->name) +
1648 ((size_t) fi->descriptor)) >> shift) % hashlen;
1650 if ((old = hashtab[index])) {
1654 if (c->fields[old].name == fi->name &&
1655 c->fields[old].descriptor == fi->descriptor) {
1656 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
1657 goto return_exception;
1659 } while ((old = next[old]));
1661 hashtab[index] = i + 1;
1665 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
1667 for (i = 0; i < c->methodscount; ++i) {
1668 methodinfo *mi = c->methods + i;
1670 /* It's ok if we lose bits here */
1671 index = ((((size_t) mi->name) +
1672 ((size_t) mi->descriptor)) >> shift) % hashlen;
1676 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
1677 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
1681 if ((old = hashtab[index])) {
1685 if (c->methods[old].name == mi->name &&
1686 c->methods[old].descriptor == mi->descriptor) {
1687 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
1688 goto return_exception;
1690 } while ((old = next[old]));
1692 hashtab[index] = i + 1;
1695 MFREE(hashtab, u2, (hashlen + len));
1697 #endif /* ENABLE_VERIFIER */
1699 RT_TIMING_GET_TIME(time_verify);
1701 #if defined(ENABLE_STATISTICS)
1703 size_classinfo += sizeof(classinfo*) * c->interfacescount;
1704 size_fieldinfo += sizeof(fieldinfo) * c->fieldscount;
1705 size_methodinfo += sizeof(methodinfo) * c->methodscount;
1709 /* load attribute structures */
1711 if (!class_load_attributes(cb))
1712 goto return_exception;
1714 /* Pre Java 1.5 version don't check this. This implementation is like
1715 Java 1.5 do it: for class file version 45.3 we don't check it, older
1716 versions are checked.
1719 if (((ma == 45) && (mi > 3)) || (ma > 45)) {
1720 /* check if all data has been read */
1721 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
1723 if (classdata_left > 0) {
1724 exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
1725 goto return_exception;
1729 RT_TIMING_GET_TIME(time_attrs);
1731 /* release dump area */
1733 dump_release(dumpsize);
1735 /* revert loading state and class is loaded */
1737 c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
1739 #if defined(ENABLE_JVMTI)
1740 /* fire Class Prepare JVMTI event */
1743 jvmti_ClassLoadPrepare(true, c);
1746 #if !defined(NDEBUG)
1748 log_message_class("Loading done class: ", c);
1751 RT_TIMING_TIME_DIFF(time_start , time_checks , RT_TIMING_LOAD_CHECKS);
1752 RT_TIMING_TIME_DIFF(time_checks , time_ndpool , RT_TIMING_LOAD_NDPOOL);
1753 RT_TIMING_TIME_DIFF(time_ndpool , time_cpool , RT_TIMING_LOAD_CPOOL);
1754 RT_TIMING_TIME_DIFF(time_cpool , time_setup , RT_TIMING_LOAD_SETUP);
1755 RT_TIMING_TIME_DIFF(time_setup , time_fields , RT_TIMING_LOAD_FIELDS);
1756 RT_TIMING_TIME_DIFF(time_fields , time_methods , RT_TIMING_LOAD_METHODS);
1757 RT_TIMING_TIME_DIFF(time_methods , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
1758 RT_TIMING_TIME_DIFF(time_classrefs , time_descs , RT_TIMING_LOAD_DESCS);
1759 RT_TIMING_TIME_DIFF(time_descs , time_setrefs , RT_TIMING_LOAD_SETREFS);
1760 RT_TIMING_TIME_DIFF(time_setrefs , time_parsefds , RT_TIMING_LOAD_PARSEFDS);
1761 RT_TIMING_TIME_DIFF(time_parsefds , time_parsemds , RT_TIMING_LOAD_PARSEMDS);
1762 RT_TIMING_TIME_DIFF(time_parsemds , time_parsecpool, RT_TIMING_LOAD_PARSECP);
1763 RT_TIMING_TIME_DIFF(time_parsecpool, time_verify , RT_TIMING_LOAD_VERIFY);
1764 RT_TIMING_TIME_DIFF(time_verify , time_attrs , RT_TIMING_LOAD_ATTRS);
1765 RT_TIMING_TIME_DIFF(time_start , time_attrs , RT_TIMING_LOAD_TOTAL);
1770 /* release dump area */
1772 dump_release(dumpsize);
1774 /* an exception has been thrown */
1780 /* load_newly_created_array ****************************************************
1782 Load a newly created array class.
1785 c....................the array class C has been loaded
1786 other classinfo......the array class was found in the class cache,
1788 NULL.................an exception has been thrown
1791 This is an internal function. Do not use it unless you know exactly
1794 Use one of the load_class_... functions for general array class loading.
1796 *******************************************************************************/
1798 classinfo *load_newly_created_array(classinfo *c, classloader *loader)
1800 classinfo *comp = NULL;
1802 methoddesc *clonedesc;
1803 constant_classref *classrefs;
1808 text = c->name->text;
1809 namelen = c->name->blength;
1811 /* Check array class name */
1813 if ((namelen < 2) || (text[0] != '[')) {
1814 exceptions_throw_classnotfoundexception(c->name);
1818 /* Check the element type */
1822 /* c is an array of arrays. We have to create the component class. */
1824 u = utf_new(text + 1, namelen - 1);
1826 comp = load_class_from_classloader(u, loader);
1831 assert(comp->state & CLASS_LOADED);
1833 /* the array's flags are that of the component class */
1834 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
1835 c->classloader = comp->classloader;
1839 /* c is an array of objects. */
1841 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1842 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
1843 exceptions_throw_classnotfoundexception(c->name);
1847 u = utf_new(text + 2, namelen - 3);
1849 if (!(comp = load_class_from_classloader(u, loader)))
1852 assert(comp->state & CLASS_LOADED);
1854 /* the array's flags are that of the component class */
1855 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
1856 c->classloader = comp->classloader;
1860 /* c is an array of a primitive type */
1862 /* check for cases like `[II' and whether the character is a
1863 valid primitive type */
1865 if ((namelen > 2) || (primitive_class_get_by_char(text[1]) == NULL)) {
1866 exceptions_throw_classnotfoundexception(c->name);
1870 /* the accessibility of the array class is public (VM Spec 5.3.3) */
1871 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
1872 c->classloader = NULL;
1875 assert(class_java_lang_Object);
1876 #if defined(ENABLE_JAVASE)
1877 assert(class_java_lang_Cloneable);
1878 assert(class_java_io_Serializable);
1881 /* setup the array class */
1883 c->super.cls = class_java_lang_Object;
1885 #if defined(ENABLE_JAVASE)
1887 c->interfacescount = 2;
1888 c->interfaces = MNEW(classref_or_classinfo, 2);
1889 c->interfaces[0].cls = class_java_lang_Cloneable;
1890 c->interfaces[1].cls = class_java_io_Serializable;
1892 #elif defined(ENABLE_JAVAME_CLDC1_1)
1894 c->interfacescount = 0;
1895 c->interfaces = NULL;
1898 # error unknow Java configuration
1901 c->methodscount = 1;
1902 c->methods = MNEW(methodinfo, c->methodscount);
1903 MZERO(c->methods, methodinfo, c->methodscount);
1905 classrefs = MNEW(constant_classref, 2);
1906 CLASSREF_INIT(classrefs[0], c, c->name);
1907 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
1909 /* create descriptor for clone method */
1910 /* we need one paramslot which is reserved for the 'this' parameter */
1911 clonedesc = NEW(methoddesc);
1912 clonedesc->returntype.type = TYPE_ADR;
1913 clonedesc->returntype.classref = classrefs + 1;
1914 clonedesc->returntype.arraydim = 0;
1915 /* initialize params to "empty", add real params below in
1916 descriptor_params_from_paramtypes */
1917 clonedesc->paramcount = 0;
1918 clonedesc->paramslots = 0;
1919 clonedesc->paramtypes[0].classref = classrefs + 0;
1920 clonedesc->params = NULL;
1922 /* create methodinfo */
1925 MSET(clone, 0, methodinfo, 1);
1927 #if defined(ENABLE_THREADS)
1928 lock_init_object_lock(&clone->header);
1931 /* ATTENTION: if you delete the ACC_NATIVE below, set
1932 clone->maxlocals=1 (interpreter related) */
1934 clone->flags = ACC_PUBLIC | ACC_NATIVE;
1935 clone->name = utf_clone;
1936 clone->descriptor = utf_void__java_lang_Object;
1937 clone->parseddesc = clonedesc;
1940 /* parse the descriptor to get the register allocation */
1942 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
1945 clone->code = codegen_generate_stub_native(clone, BUILTIN_clone);
1947 /* XXX: field: length? */
1949 /* array classes are not loaded from class files */
1951 c->state |= CLASS_LOADED;
1952 c->parseddescs = (u1 *) clonedesc;
1953 c->parseddescsize = sizeof(methodinfo);
1954 c->classrefs = classrefs;
1955 c->classrefcount = 1;
1957 /* insert class into the loaded class cache */
1958 /* XXX free classinfo if NULL returned? */
1960 return classcache_store(loader, c, true);
1964 /* loader_close ****************************************************************
1966 Frees all resources.
1968 *******************************************************************************/
1970 void loader_close(void)
1977 * These are local overrides for various environment variables in Emacs.
1978 * Please do not remove this and leave it at the end of the file, where
1979 * Emacs will automagically detect them.
1980 * ---------------------------------------------------------------------
1983 * indent-tabs-mode: t
1987 * vim:noexpandtab:sw=4:ts=4: