1 /* src/vm/loader.c - class loader functions
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 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., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Reinhard Grafl
29 Changes: Andreas Krall
35 $Id: loader.c 3501 2005-10-26 20:27:15Z twisti $
45 #include "mm/memory.h"
46 #include "native/native.h"
47 #include "native/include/java_lang_Throwable.h"
49 #if defined(USE_THREADS)
50 # if defined(NATIVE_THREADS)
51 # include "threads/native/threads.h"
53 # include "threads/green/threads.h"
54 # include "threads/green/locks.h"
58 #include "toolbox/logging.h"
59 #include "toolbox/util.h"
60 #include "vm/exceptions.h"
61 #include "vm/builtin.h"
62 #include "vm/global.h"
63 #include "vm/linker.h"
64 #include "vm/loader.h"
65 #include "vm/options.h"
66 #include "vm/statistics.h"
67 #include "vm/stringlocal.h"
68 #include "vm/tables.h"
69 #include "vm/classcache.h"
72 # include "vm/unzip.h"
75 #include "vm/jit/asmpart.h"
76 #include "vm/jit/codegen.inc.h"
78 /******************************************************************************/
80 /******************************************************************************/
82 /*#define LOADER_VERBOSE*/
89 #define LOADER_ASSERT(cond) assert(cond)
91 #define LOADER_ASSERT(cond)
99 static int loader_recursion = 0;
100 #define LOADER_INDENT(str) do { int i; for(i=0;i<loader_recursion*4;++i) {str[i]=' ';} str[i]=0;} while (0)
101 #define LOADER_INC() loader_recursion++
102 #define LOADER_DEC() loader_recursion--
109 /********************************************************************
110 list of classpath entries (either filesystem directories or
112 ********************************************************************/
114 classpath_info *classpath_entries = NULL;
117 /* loader_init *****************************************************************
119 Initializes all lists and loads all classes required for the system
122 *******************************************************************************/
124 bool loader_init(u1 *stackbottom)
126 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
129 /* Initialize the monitor pointer for zip/jar file locking. */
131 for (cpi = classpath_entries; cpi != NULL; cpi = cpi->next) {
132 if (cpi->type == CLASSPATH_ARCHIVE)
133 initObjectLock(&cpi->header);
137 /* load some important classes */
139 if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
142 if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
145 if (!(class_java_lang_Cloneable =
146 load_class_bootstrap(utf_java_lang_Cloneable)))
149 if (!(class_java_io_Serializable =
150 load_class_bootstrap(utf_java_io_Serializable)))
154 /* load classes for wrapping primitive types */
156 if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
159 if (!(class_java_lang_Boolean =
160 load_class_bootstrap(utf_java_lang_Boolean)))
163 if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
166 if (!(class_java_lang_Character =
167 load_class_bootstrap(utf_java_lang_Character)))
170 if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
173 if (!(class_java_lang_Integer =
174 load_class_bootstrap(utf_java_lang_Integer)))
177 if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
180 if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
183 if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
187 /* load some other important classes */
189 if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
192 if (!(class_java_lang_ClassLoader =
193 load_class_bootstrap(utf_java_lang_ClassLoader)))
196 if (!(class_java_lang_SecurityManager =
197 load_class_bootstrap(utf_java_lang_SecurityManager)))
200 if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
203 if (!(class_java_lang_Thread =
204 load_class_bootstrap(utf_new_char("java/lang/Thread"))))
207 if (!(class_java_lang_ThreadGroup =
208 load_class_bootstrap(utf_java_lang_ThreadGroup)))
211 if (!(class_java_lang_VMThread =
212 load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
216 /* some classes which may be used more often */
218 if (!(class_java_lang_StackTraceElement =
219 load_class_bootstrap(utf_java_lang_StackTraceElement)))
222 if (!(class_java_lang_reflect_Constructor =
223 load_class_bootstrap(utf_java_lang_reflect_Constructor)))
226 if (!(class_java_lang_reflect_Field =
227 load_class_bootstrap(utf_java_lang_reflect_Field)))
230 if (!(class_java_lang_reflect_Method =
231 load_class_bootstrap(utf_java_lang_reflect_Method)))
234 if (!(class_java_security_PrivilegedAction =
235 load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
238 if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
241 if (!(arrayclass_java_lang_Object =
242 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
245 #if defined(USE_THREADS)
246 if (stackbottom != 0)
254 /************* functions for reading classdata *********************************
256 getting classdata in blocks of variable size
257 (8,16,32,64-bit integer or float)
259 *******************************************************************************/
261 /* check_classbuffer_size ******************************************************
263 assert that at least <len> bytes are left to read
264 <len> is limited to the range of non-negative s4 values
266 *******************************************************************************/
268 inline bool check_classbuffer_size(classbuffer *cb, s4 len)
270 if (len < 0 || ((cb->data + cb->size) - cb->pos - 1) < len) {
272 new_classformaterror((cb)->class, "Truncated class file");
281 /* suck_nbytes *****************************************************************
283 transfer block of classfile data into a buffer
285 *******************************************************************************/
287 inline void suck_nbytes(u1 *buffer, classbuffer *cb, s4 len)
289 memcpy(buffer, cb->pos + 1, len);
294 /* skip_nbytes ****************************************************************
296 skip block of classfile data
298 *******************************************************************************/
300 inline void skip_nbytes(classbuffer *cb, s4 len)
306 inline u1 suck_u1(classbuffer *cb)
312 inline u2 suck_u2(classbuffer *cb)
316 return ((u2) a << 8) + (u2) b;
320 inline u4 suck_u4(classbuffer *cb)
326 return ((u4) a << 24) + ((u4) b << 16) + ((u4) c << 8) + (u4) d;
330 /* get u8 from classfile data */
331 static u8 suck_u8(classbuffer *cb)
337 return (hi << 32) + lo;
340 v.high = suck_u4(cb);
347 /* get float from classfile data */
348 static float suck_float(classbuffer *cb)
356 for (i = 0; i < 4; i++)
357 buffer[3 - i] = suck_u1(cb);
359 memcpy((u1*) (&f), buffer, 4);
361 suck_nbytes((u1*) (&f), cb, 4);
364 if (sizeof(float) != 4) {
365 *exceptionptr = new_internalerror("Incompatible float-format");
367 /* XXX should we exit in such a case? */
368 throw_exception_exit();
375 /* get double from classfile data */
376 static double suck_double(classbuffer *cb)
384 #if defined(__ARM__) && defined(__ARMEL__) && !defined(__VFP_FP__)
386 * On little endian ARM processors when using FPA, word order
387 * of doubles is still big endian. So take that into account
388 * here. When using VFP, word order of doubles follows byte
389 * order. (michi 2005/07/24)
391 for (i = 0; i < 4; i++)
392 buffer[3 - i] = suck_u1(cb);
393 for (i = 0; i < 4; i++)
394 buffer[7 - i] = suck_u1(cb);
396 for (i = 0; i < 8; i++)
397 buffer[7 - i] = suck_u1(cb);
398 #endif /* defined(__ARM__) && ... */
400 memcpy((u1*) (&d), buffer, 8);
402 suck_nbytes((u1*) (&d), cb, 8);
405 if (sizeof(double) != 8) {
406 *exceptionptr = new_internalerror("Incompatible double-format");
408 /* XXX should we exit in such a case? */
409 throw_exception_exit();
416 /************************** function suck_init *********************************
418 called once at startup, sets the searchpath for the classfiles
420 *******************************************************************************/
422 void suck_init(char *classpath)
430 classpath_info *lastcpi;
434 /* search for last classpath entry (only if there already some) */
436 if ((lastcpi = classpath_entries)) {
437 while (lastcpi->next)
438 lastcpi = lastcpi->next;
441 for (start = classpath; (*start) != '\0';) {
443 /* search for ':' delimiter to get the end of the current entry */
444 for (end = start; ((*end) != '\0') && ((*end) != ':'); end++);
448 filenamelen = end - start;
450 if (filenamelen > 3) {
451 if (strncasecmp(end - 3, "zip", 3) == 0 ||
452 strncasecmp(end - 3, "jar", 3) == 0) {
457 /* save classpath entries as absolute pathnames */
462 if (*start != '/') { /* XXX fix me for win32 */
464 cwdlen = strlen(cwd) + strlen("/");
467 /* allocate memory for filename and fill it */
469 filename = MNEW(char, filenamelen + cwdlen + strlen("/") +
473 strcpy(filename, cwd);
474 strcat(filename, "/");
475 strncat(filename, start, filenamelen);
477 /* add cwd length to file length */
478 filenamelen += cwdlen;
481 strncpy(filename, start, filenamelen);
482 filename[filenamelen] = '\0';
488 #if defined(USE_ZLIB)
489 unzFile uf = unzOpen(filename);
492 cpi = NEW(classpath_info);
493 cpi->type = CLASSPATH_ARCHIVE;
496 cpi->path = filename;
497 cpi->pathlen = filenamelen;
499 /* SUN compatible -verbose:class output */
501 if (opt_verboseclass)
502 printf("[Opened %s]\n", filename);
506 throw_cacao_exception_exit(string_java_lang_InternalError,
507 "zip/jar files not supported");
511 cpi = NEW(classpath_info);
512 cpi->type = CLASSPATH_PATH;
515 if (filename[filenamelen - 1] != '/') {/*PERHAPS THIS SHOULD BE READ FROM A GLOBAL CONFIGURATION */
516 filename[filenamelen] = '/';
517 filename[filenamelen + 1] = '\0';
521 cpi->path = filename;
522 cpi->pathlen = filenamelen;
525 /* attach current classpath entry */
528 if (!classpath_entries)
529 classpath_entries = cpi;
537 /* goto next classpath entry, skip ':' delimiter */
549 /* loader_load_all_classes *****************************************************
551 Loads all classes specified in the BOOTCLASSPATH.
553 *******************************************************************************/
555 void loader_load_all_classes(void)
560 for (cpi = classpath_entries; cpi != 0; cpi = cpi->next) {
561 #if defined(USE_ZLIB)
562 if (cpi->type == CLASSPATH_ARCHIVE) {
566 s = (unz_s *) cpi->uf;
567 ce = s->cacao_dir_list;
570 /* skip all entries in META-INF and .properties, .png files */
572 if (strncmp(ce->name->text, "META-INF", strlen("META-INF")) &&
573 !strstr(ce->name->text, ".properties") &&
574 !strstr(ce->name->text, ".png"))
575 c = load_class_bootstrap(ce->name);
582 #if defined(USE_ZLIB)
589 /* suck_start ******************************************************************
591 Returns true if classbuffer is already loaded or a file for the
592 specified class has succussfully been read in. All directories of
593 the searchpath are used to find the classfile (<classname>.class).
594 Returns false if no classfile is found and writes an error message.
596 *******************************************************************************/
598 classbuffer *suck_start(classinfo *c)
610 /* initialize return value */
615 filenamelen = utf_strlen(c->name) + strlen(".class") + strlen("0");
616 filename = MNEW(char, filenamelen);
618 utf_sprint(filename, c->name);
619 strcat(filename, ".class");
621 /* walk through all classpath entries */
623 for (cpi = classpath_entries; cpi != NULL && cb == NULL; cpi = cpi->next) {
624 #if defined(USE_ZLIB)
625 if (cpi->type == CLASSPATH_ARCHIVE) {
627 #if defined(USE_THREADS)
628 /* enter a monitor on zip/jar archives */
630 builtin_monitorenter((java_objectheader *) cpi);
633 if (cacao_locate(cpi->uf, c->name) == UNZ_OK) {
634 unz_file_info file_info;
636 if (unzGetCurrentFileInfo(cpi->uf, &file_info, filename,
637 sizeof(filename), NULL, 0, NULL, 0) == UNZ_OK) {
638 if (unzOpenCurrentFile(cpi->uf) == UNZ_OK) {
639 cb = NEW(classbuffer);
641 cb->size = file_info.uncompressed_size;
642 cb->data = MNEW(u1, cb->size);
643 cb->pos = cb->data - 1;
644 cb->path = cpi->path;
646 len = unzReadCurrentFile(cpi->uf, cb->data, cb->size);
648 if (len != cb->size) {
650 log_text("Error while unzipping");
657 log_text("Error while opening file in archive");
661 log_text("Error while retrieving fileinfo");
664 unzCloseCurrentFile(cpi->uf);
666 #if defined(USE_THREADS)
667 /* leave the monitor */
669 builtin_monitorexit((java_objectheader *) cpi);
673 #endif /* defined(USE_ZLIB) */
675 path = MNEW(char, cpi->pathlen + filenamelen);
676 strcpy(path, cpi->path);
677 strcat(path, filename);
679 classfile = fopen(path, "r");
681 if (classfile) { /* file exists */
682 if (!stat(path, &buffer)) { /* read classfile data */
683 cb = NEW(classbuffer);
685 cb->size = buffer.st_size;
686 cb->data = MNEW(u1, cb->size);
687 cb->pos = cb->data - 1;
688 cb->path = cpi->path;
690 /* read class data */
691 len = fread(cb->data, 1, cb->size, classfile);
693 if (len != buffer.st_size) {
695 /* if (ferror(classfile)) { */
704 MFREE(path, char, cpi->pathlen + filenamelen);
705 #if defined(USE_ZLIB)
712 dolog("Warning: Can not open class file '%s'", filename);
714 if (strcmp(filename, "org/mortbay/util/MultiException.class") == 0) {
722 MFREE(filename, char, filenamelen);
728 /************************** function suck_stop *********************************
730 frees memory for buffer with classfile data.
731 Caution: this function may only be called if buffer has been allocated
732 by suck_start with reading a file
734 *******************************************************************************/
736 void suck_stop(classbuffer *cb)
740 MFREE(cb->data, u1, cb->size);
741 FREE(cb, classbuffer);
745 /******************************************************************************/
746 /******************* Some support functions ***********************************/
747 /******************************************************************************/
749 void fprintflags (FILE *fp, u2 f)
751 if ( f & ACC_PUBLIC ) fprintf (fp," PUBLIC");
752 if ( f & ACC_PRIVATE ) fprintf (fp," PRIVATE");
753 if ( f & ACC_PROTECTED ) fprintf (fp," PROTECTED");
754 if ( f & ACC_STATIC ) fprintf (fp," STATIC");
755 if ( f & ACC_FINAL ) fprintf (fp," FINAL");
756 if ( f & ACC_SYNCHRONIZED ) fprintf (fp," SYNCHRONIZED");
757 if ( f & ACC_VOLATILE ) fprintf (fp," VOLATILE");
758 if ( f & ACC_TRANSIENT ) fprintf (fp," TRANSIENT");
759 if ( f & ACC_NATIVE ) fprintf (fp," NATIVE");
760 if ( f & ACC_INTERFACE ) fprintf (fp," INTERFACE");
761 if ( f & ACC_ABSTRACT ) fprintf (fp," ABSTRACT");
765 /********** internal function: printflags (only for debugging) ***************/
767 void printflags(u2 f)
769 fprintflags(stdout,f);
773 /********************** Function: skipattributebody ****************************
775 skips an attribute after the 16 bit reference to attribute_name has already
778 *******************************************************************************/
780 static bool skipattributebody(classbuffer *cb)
784 if (!check_classbuffer_size(cb, 4))
789 if (!check_classbuffer_size(cb, len))
792 skip_nbytes(cb, len);
798 /************************* Function: skipattributes ****************************
800 skips num attribute structures
802 *******************************************************************************/
804 static bool skipattributes(classbuffer *cb, u4 num)
809 for (i = 0; i < num; i++) {
810 if (!check_classbuffer_size(cb, 2 + 4))
816 if (!check_classbuffer_size(cb, len))
819 skip_nbytes(cb, len);
826 /* load_constantpool ***********************************************************
828 Loads the constantpool of a class, the entries are transformed into
829 a simpler format by resolving references (a detailed overview of
830 the compact structures can be found in global.h).
832 *******************************************************************************/
834 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
837 /* The following structures are used to save information which cannot be
838 processed during the first pass. After the complete constantpool has
839 been traversed the references can be resolved.
840 (only in specific order) */
842 /* CONSTANT_Class entries */
843 typedef struct forward_class {
844 struct forward_class *next;
849 /* CONSTANT_String */
850 typedef struct forward_string {
851 struct forward_string *next;
856 /* CONSTANT_NameAndType */
857 typedef struct forward_nameandtype {
858 struct forward_nameandtype *next;
862 } forward_nameandtype;
864 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
865 typedef struct forward_fieldmethint {
866 struct forward_fieldmethint *next;
870 u2 nameandtype_index;
871 } forward_fieldmethint;
877 forward_class *forward_classes = NULL;
878 forward_string *forward_strings = NULL;
879 forward_nameandtype *forward_nameandtypes = NULL;
880 forward_fieldmethint *forward_fieldmethints = NULL;
884 forward_nameandtype *nfn;
885 forward_fieldmethint *nff;
893 /* number of entries in the constant_pool table plus one */
894 if (!check_classbuffer_size(cb, 2))
897 cpcount = c->cpcount = suck_u2(cb);
899 /* allocate memory */
900 cptags = c->cptags = MNEW(u1, cpcount);
901 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
904 *exceptionptr = new_classformaterror(c, "Illegal constant pool size");
908 #if defined(STATISTICS)
910 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
913 /* initialize constantpool */
914 for (idx = 0; idx < cpcount; idx++) {
915 cptags[idx] = CONSTANT_UNUSED;
920 /******* first pass *******/
921 /* entries which cannot be resolved now are written into
922 temporary structures and traversed again later */
925 while (idx < cpcount) {
928 /* get constant type */
929 if (!check_classbuffer_size(cb, 1))
936 nfc = DNEW(forward_class);
938 nfc->next = forward_classes;
939 forward_classes = nfc;
941 nfc->thisindex = idx;
942 /* reference to CONSTANT_NameAndType */
943 if (!check_classbuffer_size(cb, 2))
946 nfc->name_index = suck_u2(cb);
951 case CONSTANT_String:
952 nfs = DNEW(forward_string);
954 nfs->next = forward_strings;
955 forward_strings = nfs;
957 nfs->thisindex = idx;
959 /* reference to CONSTANT_Utf8_info with string characters */
960 if (!check_classbuffer_size(cb, 2))
963 nfs->string_index = suck_u2(cb);
968 case CONSTANT_NameAndType:
969 nfn = DNEW(forward_nameandtype);
971 nfn->next = forward_nameandtypes;
972 forward_nameandtypes = nfn;
974 nfn->thisindex = idx;
976 if (!check_classbuffer_size(cb, 2 + 2))
979 /* reference to CONSTANT_Utf8_info containing simple name */
980 nfn->name_index = suck_u2(cb);
982 /* reference to CONSTANT_Utf8_info containing field or method
984 nfn->sig_index = suck_u2(cb);
989 case CONSTANT_Fieldref:
990 case CONSTANT_Methodref:
991 case CONSTANT_InterfaceMethodref:
992 nff = DNEW(forward_fieldmethint);
994 nff->next = forward_fieldmethints;
995 forward_fieldmethints = nff;
997 nff->thisindex = idx;
1001 if (!check_classbuffer_size(cb, 2 + 2))
1004 /* class or interface type that contains the declaration of the
1006 nff->class_index = suck_u2(cb);
1008 /* name and descriptor of the field or method */
1009 nff->nameandtype_index = suck_u2(cb);
1014 case CONSTANT_Integer: {
1015 constant_integer *ci = NEW(constant_integer);
1017 #if defined(STATISTICS)
1019 count_const_pool_len += sizeof(constant_integer);
1022 if (!check_classbuffer_size(cb, 4))
1025 ci->value = suck_s4(cb);
1026 cptags[idx] = CONSTANT_Integer;
1033 case CONSTANT_Float: {
1034 constant_float *cf = NEW(constant_float);
1036 #if defined(STATISTICS)
1038 count_const_pool_len += sizeof(constant_float);
1041 if (!check_classbuffer_size(cb, 4))
1044 cf->value = suck_float(cb);
1045 cptags[idx] = CONSTANT_Float;
1052 case CONSTANT_Long: {
1053 constant_long *cl = NEW(constant_long);
1055 #if defined(STATISTICS)
1057 count_const_pool_len += sizeof(constant_long);
1060 if (!check_classbuffer_size(cb, 8))
1063 cl->value = suck_s8(cb);
1064 cptags[idx] = CONSTANT_Long;
1067 if (idx > cpcount) {
1069 new_classformaterror(c, "Invalid constant pool entry");
1075 case CONSTANT_Double: {
1076 constant_double *cd = NEW(constant_double);
1078 #if defined(STATISTICS)
1080 count_const_pool_len += sizeof(constant_double);
1083 if (!check_classbuffer_size(cb, 8))
1086 cd->value = suck_double(cb);
1087 cptags[idx] = CONSTANT_Double;
1090 if (idx > cpcount) {
1092 new_classformaterror(c, "Invalid constant pool entry");
1098 case CONSTANT_Utf8: {
1101 /* number of bytes in the bytes array (not string-length) */
1102 if (!check_classbuffer_size(cb, 2))
1105 length = suck_u2(cb);
1106 cptags[idx] = CONSTANT_Utf8;
1108 /* validate the string */
1109 if (!check_classbuffer_size(cb, length))
1113 !is_valid_utf((char *) (cb->pos + 1),
1114 (char *) (cb->pos + 1 + length))) {
1115 *exceptionptr = new_classformaterror(c,"Invalid UTF-8 string");
1118 /* insert utf-string into the utf-symboltable */
1119 cpinfos[idx] = utf_new_intern((char *) (cb->pos + 1), length);
1121 /* skip bytes of the string (buffer size check above) */
1122 skip_nbytes(cb, length);
1129 new_classformaterror(c, "Illegal constant pool type");
1135 /* resolve entries in temporary structures */
1137 while (forward_classes) {
1139 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
1143 if (opt_verify && !is_valid_name_utf(name)) {
1145 new_classformaterror(c, "Class reference with invalid name");
1149 /* add all class references to the descriptor_pool */
1151 if (!descriptor_pool_add_class(descpool, name))
1154 cptags[forward_classes->thisindex] = CONSTANT_Class;
1159 if (!(tc = load_class_bootstrap(name)))
1162 /* link the class later, because we cannot link the class currently
1164 list_addfirst(&unlinkedclasses, tc);
1167 /* the classref is created later */
1168 cpinfos[forward_classes->thisindex] = name;
1170 nfc = forward_classes;
1171 forward_classes = forward_classes->next;
1174 while (forward_strings) {
1176 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
1180 /* resolve utf-string */
1181 cptags[forward_strings->thisindex] = CONSTANT_String;
1182 cpinfos[forward_strings->thisindex] = text;
1184 nfs = forward_strings;
1185 forward_strings = forward_strings->next;
1188 while (forward_nameandtypes) {
1189 constant_nameandtype *cn = NEW(constant_nameandtype);
1191 #if defined(STATISTICS)
1193 count_const_pool_len += sizeof(constant_nameandtype);
1196 /* resolve simple name and descriptor */
1197 cn->name = class_getconstant(c,
1198 forward_nameandtypes->name_index,
1203 cn->descriptor = class_getconstant(c,
1204 forward_nameandtypes->sig_index,
1206 if (!cn->descriptor)
1211 if (!is_valid_name_utf(cn->name)) {
1213 new_classformaterror(c,
1214 "Illegal Field name \"%s\"",
1220 /* disallow referencing <clinit> among others */
1221 if (cn->name->text[0] == '<' && cn->name != utf_init) {
1223 new_classformaterror(c,"Illegal reference to special method");
1228 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
1229 cpinfos[forward_nameandtypes->thisindex] = cn;
1231 nfn = forward_nameandtypes;
1232 forward_nameandtypes = forward_nameandtypes->next;
1235 while (forward_fieldmethints) {
1236 constant_nameandtype *nat;
1237 constant_FMIref *fmi = NEW(constant_FMIref);
1239 #if defined(STATISTICS)
1241 count_const_pool_len += sizeof(constant_FMIref);
1243 /* resolve simple name and descriptor */
1245 nat = class_getconstant(c,
1246 forward_fieldmethints->nameandtype_index,
1247 CONSTANT_NameAndType);
1251 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
1253 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
1256 /* the classref is created later */
1258 fmi->classref = (constant_classref *) (size_t) forward_fieldmethints->class_index;
1259 fmi->name = nat->name;
1260 fmi->descriptor = nat->descriptor;
1262 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
1263 cpinfos[forward_fieldmethints->thisindex] = fmi;
1265 nff = forward_fieldmethints;
1266 forward_fieldmethints = forward_fieldmethints->next;
1269 /* everything was ok */
1275 /* load_field ******************************************************************
1277 Load everything about a class field from the class file and fill a
1278 'fieldinfo' structure. For static fields, space in the data segment
1281 *******************************************************************************/
1283 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
1285 static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
1290 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
1295 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1298 f->flags = suck_u2(cb);
1300 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1305 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1309 f->parseddesc = NULL;
1311 if (!descriptor_pool_add(descpool, u, NULL))
1314 /* descriptor_pool_add accepts method descriptors, so we have to check */
1315 /* against them here before the call of desc_to_type below. */
1316 if (u->text[0] == '(') {
1317 *exceptionptr = new_classformaterror(c,"Method descriptor used for field");
1323 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<') {
1324 *exceptionptr = new_classformaterror(c,
1325 "Illegal Field name \"%s\"",
1330 /* check flag consistency */
1331 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
1333 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
1334 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
1336 new_classformaterror(c,
1337 "Illegal field modifiers: 0x%X",
1342 if (c->flags & ACC_INTERFACE) {
1343 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
1344 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
1345 f->flags & ACC_TRANSIENT) {
1347 new_classformaterror(c,
1348 "Illegal field modifiers: 0x%X",
1355 f->type = jtype = desc_to_type(f->descriptor); /* data type */
1356 f->offset = 0; /* offset from start of object */
1361 case TYPE_INT: f->value.i = 0; break;
1362 case TYPE_FLOAT: f->value.f = 0.0; break;
1363 case TYPE_DOUBLE: f->value.d = 0.0; break;
1364 case TYPE_ADDRESS: f->value.a = NULL; break;
1367 f->value.l = 0; break;
1369 f->value.l.low = 0; f->value.l.high = 0; break;
1373 /* read attributes */
1374 if (!check_classbuffer_size(cb, 2))
1377 attrnum = suck_u2(cb);
1378 for (i = 0; i < attrnum; i++) {
1379 if (!check_classbuffer_size(cb, 2))
1382 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1385 if (u == utf_ConstantValue) {
1386 if (!check_classbuffer_size(cb, 4 + 2))
1389 /* check attribute length */
1390 if (suck_u4(cb) != 2) {
1392 new_classformaterror(c, "Wrong size for VALUE attribute");
1396 /* constant value attribute */
1397 if (pindex != field_load_NOVALUE) {
1399 new_classformaterror(c,
1400 "Multiple ConstantValue attributes");
1404 /* index of value in constantpool */
1405 pindex = suck_u2(cb);
1407 /* initialize field with value from constantpool */
1410 constant_integer *ci;
1412 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
1415 f->value.i = ci->value;
1422 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
1425 f->value.l = cl->value;
1432 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
1435 f->value.f = cf->value;
1440 constant_double *cd;
1442 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
1445 f->value.d = cd->value;
1450 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
1453 /* create javastring from compressed utf8-string */
1454 f->value.a = literalstring_new(u);
1458 log_text("Invalid Constant - Type");
1462 /* unknown attribute */
1463 if (!skipattributebody(cb))
1468 /* everything was ok */
1474 /* load_method *****************************************************************
1476 Loads a method from the class file and fills an existing
1477 'methodinfo' structure. For native methods, the function pointer
1478 field is set to the real function pointer, for JavaVM methods a
1479 pointer to the compiler is used preliminarily.
1481 *******************************************************************************/
1483 static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpool)
1494 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1495 initObjectLock(&m->header);
1500 count_all_methods++;
1503 m->thrownexceptionscount = 0;
1504 m->linenumbercount = 0;
1507 m->nativelyoverloaded = false;
1509 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1512 m->flags = suck_u2(cb);
1514 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1519 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1523 m->parseddesc = NULL;
1525 if (!descriptor_pool_add(descpool, u, &argcount))
1529 if (!is_valid_name_utf(m->name)) {
1530 *exceptionptr = new_classformaterror(c,"Method with invalid name");
1534 if (m->name->text[0] == '<' &&
1535 m->name != utf_init && m->name != utf_clinit) {
1536 *exceptionptr = new_classformaterror(c,"Method with invalid special name");
1541 if (!(m->flags & ACC_STATIC))
1542 argcount++; /* count the 'this' argument */
1545 if (argcount > 255) {
1547 new_classformaterror(c, "Too many arguments in signature");
1551 /* check flag consistency */
1552 if (m->name != utf_clinit) {
1553 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1555 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1557 new_classformaterror(c,
1558 "Illegal method modifiers: 0x%X",
1563 if (m->flags & ACC_ABSTRACT) {
1564 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1565 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1567 new_classformaterror(c,
1568 "Illegal method modifiers: 0x%X",
1574 if (c->flags & ACC_INTERFACE) {
1575 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1577 new_classformaterror(c,
1578 "Illegal method modifiers: 0x%X",
1584 if (m->name == utf_init) {
1585 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1586 ACC_NATIVE | ACC_ABSTRACT)) {
1587 *exceptionptr = new_classformaterror(c,
1588 "Instance initialization method has invalid flags set");
1596 m->basicblockcount = 0;
1597 m->basicblocks = NULL;
1598 m->basicblockindex = NULL;
1599 m->instructioncount = 0;
1600 m->instructions = NULL;
1603 m->exceptiontable = NULL;
1604 m->stubroutine = NULL;
1606 m->entrypoint = NULL;
1607 m->methodUsed = NOTUSED;
1610 m->subRedefsUsed = 0;
1614 if (!check_classbuffer_size(cb, 2))
1617 attrnum = suck_u2(cb);
1618 for (i = 0; i < attrnum; i++) {
1621 if (!check_classbuffer_size(cb, 2))
1624 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1627 if (aname == utf_Code) {
1628 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1630 new_classformaterror(c,
1631 "Code attribute in native or abstract methods");
1638 new_classformaterror(c, "Multiple Code attributes");
1643 if (!check_classbuffer_size(cb, 4 + 2 + 2))
1647 m->maxstack = suck_u2(cb);
1648 m->maxlocals = suck_u2(cb);
1650 if (m->maxlocals < argcount) {
1652 new_classformaterror(c, "Arguments can't fit into locals");
1657 if (!check_classbuffer_size(cb, 4))
1660 m->jcodelength = suck_u4(cb);
1662 if (m->jcodelength == 0) {
1664 new_classformaterror(c, "Code of a method has length 0");
1669 if (m->jcodelength > 65535) {
1671 new_classformaterror(c,
1672 "Code of a method longer than 65535 bytes");
1677 if (!check_classbuffer_size(cb, m->jcodelength))
1680 m->jcode = MNEW(u1, m->jcodelength);
1681 suck_nbytes(m->jcode, cb, m->jcodelength);
1683 if (!check_classbuffer_size(cb, 2))
1686 m->exceptiontablelength = suck_u2(cb);
1687 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->exceptiontablelength))
1690 m->exceptiontable = MNEW(exceptiontable, m->exceptiontablelength);
1692 #if defined(STATISTICS)
1694 count_vmcode_len += m->jcodelength + 18;
1695 count_extable_len += 8 * m->exceptiontablelength;
1699 for (j = 0; j < m->exceptiontablelength; j++) {
1701 m->exceptiontable[j].startpc = suck_u2(cb);
1702 m->exceptiontable[j].endpc = suck_u2(cb);
1703 m->exceptiontable[j].handlerpc = suck_u2(cb);
1707 m->exceptiontable[j].catchtype.any = NULL;
1710 /* the classref is created later */
1711 if (!(m->exceptiontable[j].catchtype.any =
1712 (utf*)class_getconstant(c, idx, CONSTANT_Class)))
1717 if (!check_classbuffer_size(cb, 2))
1720 codeattrnum = suck_u2(cb);
1722 for (; codeattrnum > 0; codeattrnum--) {
1725 if (!check_classbuffer_size(cb, 2))
1728 if (!(caname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1731 if (caname == utf_LineNumberTable) {
1734 if (!check_classbuffer_size(cb, 4 + 2))
1738 m->linenumbercount = suck_u2(cb);
1740 if (!check_classbuffer_size(cb,
1741 (2 + 2) * m->linenumbercount))
1744 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1746 for (lncid = 0; lncid < m->linenumbercount; lncid++) {
1747 m->linenumbers[lncid].start_pc = suck_u2(cb);
1748 m->linenumbers[lncid].line_number = suck_u2(cb);
1752 if (!skipattributes(cb, codeattrnum))
1758 if (!skipattributebody(cb))
1763 } else if (aname == utf_Exceptions) {
1766 if (m->thrownexceptions) {
1768 new_classformaterror(c, "Multiple Exceptions attributes");
1772 if (!check_classbuffer_size(cb, 4 + 2))
1775 suck_u4(cb); /* length */
1776 m->thrownexceptionscount = suck_u2(cb);
1778 if (!check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1781 m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
1783 for (j = 0; j < m->thrownexceptionscount; j++) {
1784 /* the classref is created later */
1785 if (!((m->thrownexceptions)[j].any =
1786 (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1791 if (!skipattributebody(cb))
1796 if (!m->jcode && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1797 *exceptionptr = new_classformaterror(c, "Missing Code attribute");
1802 /* everything was ok */
1808 /* load_attribute **************************************************************
1810 Read attributes from classfile.
1812 *******************************************************************************/
1814 static bool load_attributes(classbuffer *cb, u4 num)
1822 for (i = 0; i < num; i++) {
1823 /* retrieve attribute name */
1824 if (!check_classbuffer_size(cb, 2))
1827 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1830 if (aname == utf_InnerClasses) {
1831 /* innerclasses attribute */
1832 if (c->innerclass) {
1834 new_classformaterror(c, "Multiple InnerClasses attributes");
1838 if (!check_classbuffer_size(cb, 4 + 2))
1841 /* skip attribute length */
1844 /* number of records */
1845 c->innerclasscount = suck_u2(cb);
1847 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
1850 /* allocate memory for innerclass structure */
1851 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
1853 for (j = 0; j < c->innerclasscount; j++) {
1854 /* The innerclass structure contains a class with an encoded
1855 name, its defining scope, its simple name and a bitmask of
1856 the access flags. If an inner class is not a member, its
1857 outer_class is NULL, if a class is anonymous, its name is
1860 innerclassinfo *info = c->innerclass + j;
1862 info->inner_class.ref =
1863 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
1864 info->outer_class.ref =
1865 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
1867 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1868 info->flags = suck_u2(cb);
1871 } else if (aname == utf_SourceFile) {
1872 if (!check_classbuffer_size(cb, 4 + 2))
1875 if (suck_u4(cb) != 2) {
1877 new_classformaterror(c, "Wrong size for VALUE attribute");
1881 if (c->sourcefile) {
1883 new_classformaterror(c, "Multiple SourceFile attributes");
1887 if (!(c->sourcefile = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1891 /* unknown attribute */
1892 if (!skipattributebody(cb))
1901 /* load_class_from_sysloader ***************************************************
1903 Load the class with the given name using the system class loader
1906 name.............the classname
1909 the loaded class, or
1910 NULL if an exception has been thrown
1912 *******************************************************************************/
1914 classinfo *load_class_from_sysloader(utf *name)
1917 java_objectheader *cl;
1920 #ifdef LOADER_VERBOSE
1921 char logtext[MAXLOGTEXT];
1922 LOADER_INDENT(logtext);
1923 sprintf(logtext+strlen(logtext),"load_class_from_sysloader(");
1924 utf_sprint(logtext+strlen(logtext),name);strcat(logtext,")");
1928 LOADER_ASSERT(class_java_lang_Object);
1929 LOADER_ASSERT(class_java_lang_ClassLoader);
1930 LOADER_ASSERT(class_java_lang_ClassLoader->linked);
1932 m = class_resolveclassmethod(class_java_lang_ClassLoader,
1933 utf_getSystemClassLoader,
1934 utf_void__java_lang_ClassLoader,
1935 class_java_lang_Object,
1941 cl = (java_objectheader *) asm_calljavafunction(m, NULL, NULL, NULL, NULL);
1946 r = load_class_from_classloader(name, cl);
1952 /* load_class_from_classloader *************************************************
1954 Load the class with the given name using the given user-defined class loader.
1957 name.............the classname
1958 cl...............user-defined class loader
1961 the loaded class, or
1962 NULL if an exception has been thrown
1964 *******************************************************************************/
1966 classinfo *load_class_from_classloader(utf *name, java_objectheader *cl)
1970 #ifdef LOADER_VERBOSE
1971 char logtext[MAXLOGTEXT];
1972 LOADER_INDENT(logtext);
1973 strcat(logtext,"load_class_from_classloader(");
1974 utf_sprint(logtext+strlen(logtext),name);sprintf(logtext+strlen(logtext),",%p,",(void*)cl);
1975 if (!cl) strcat(logtext,"<bootstrap>");
1976 else if (cl->vftbl && cl->vftbl->class) utf_sprint(logtext+strlen(logtext),cl->vftbl->class->name);
1977 else strcat(logtext,"<unknown class>");
1978 strcat(logtext,")");
1982 LOADER_ASSERT(name);
1984 /* lookup if this class has already been loaded */
1986 r = classcache_lookup(cl, name);
1988 #ifdef LOADER_VERBOSE
1990 dolog(" cached -> %p",(void*)r);
1996 /* if other class loader than bootstrap, call it */
2004 namelen = name->blength;
2006 /* handle array classes */
2007 if (text[0] == '[') {
2013 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2014 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
2015 *exceptionptr = new_noclassdeffounderror(name);
2019 u = utf_new(text + 2, namelen - 3);
2021 if (!(comp = load_class_from_classloader(u, cl)))
2024 /* create the array class */
2025 return class_array_of(comp, false);
2028 /* load the component class */
2030 u = utf_new(text + 1, namelen - 1);
2032 if (!(comp = load_class_from_classloader(u, cl)))
2035 /* create the array class */
2036 return class_array_of(comp, false);
2039 /* primitive array classes are loaded by the bootstrap loader */
2040 return load_class_bootstrap(name);
2044 LOADER_ASSERT(class_java_lang_Object);
2046 lc = class_resolveclassmethod(cl->vftbl->class,
2048 utf_java_lang_String__java_lang_Class,
2049 class_java_lang_Object,
2053 return false; /* exception */
2056 r = (classinfo *) asm_calljavafunction(lc,
2058 javastring_new_slash_to_dot(name),
2063 /* Store this class in the loaded class cache. If another
2064 class with the same (initloader,name) pair has been
2065 stored earlier it will be returned by classcache_store
2066 In this case classcache_store may not free the class
2067 because it has already been exposed to Java code which
2068 may have kept references to that class. */
2070 classinfo *c = classcache_store(cl,r,false);
2073 /* exception, free the loaded class */
2081 /* loadClass has thrown an exception */
2082 /* we must convert ClassNotFoundException into NoClassDefFoundException */
2083 /* XXX maybe we should have a flag that avoids this conversion */
2084 /* for calling load_class_from_classloader from Class.forName */
2085 /* Currently we do a double conversion in these cases */
2086 classnotfoundexception_to_noclassdeffounderror();
2089 /* SUN compatible -verbose:class output */
2091 if (opt_verboseclass && (r != NULL) && (r->classloader == cl)) {
2093 utf_display_classname(name);
2101 r = load_class_bootstrap(name);
2108 /* load_class_bootstrap ********************************************************
2110 Load the class with the given name using the bootstrap class loader.
2113 name.............the classname
2116 loaded classinfo, or
2117 NULL if an exception has been thrown
2120 load_class_bootstrap is synchronized. It can be treated as an
2123 *******************************************************************************/
2125 classinfo *load_class_bootstrap(utf *name)
2130 #ifdef LOADER_VERBOSE
2131 char logtext[MAXLOGTEXT];
2136 LOADER_ASSERT(name);
2139 /* lookup if this class has already been loaded */
2141 if ((r = classcache_lookup(NULL, name)))
2144 #ifdef LOADER_VERBOSE
2145 LOADER_INDENT(logtext);
2146 strcat(logtext,"load_class_bootstrap(");
2147 utf_sprint(logtext+strlen(logtext),name);strcat(logtext,")");
2151 /* create the classinfo */
2153 c = class_create_classinfo(name);
2155 /* handle array classes */
2157 if (name->text[0] == '[') {
2158 c = load_newly_created_array(c, NULL);
2160 goto return_exception;
2161 LOADER_ASSERT(c->loaded);
2166 #if defined(STATISTICS)
2169 if (getcompilingtime)
2170 compilingtime_stop();
2173 loadingtime_start();
2176 /* load classdata, throw exception on error */
2178 if ((cb = suck_start(c)) == NULL) {
2179 /* this normally means, the classpath was not set properly */
2181 if (name == utf_java_lang_Object)
2182 throw_cacao_exception_exit(string_java_lang_NoClassDefFoundError,
2183 "java/lang/Object");
2186 new_exception_utfmessage(string_java_lang_NoClassDefFoundError,
2188 goto return_exception;
2191 /* load the class from the buffer */
2193 r = load_class_from_classbuffer(cb);
2196 /* the class could not be loaded, free the classinfo struct */
2201 /* Store this class in the loaded class cache this step also
2202 checks the loading constraints. If the class has been loaded
2203 before, the earlier loaded class is returned. */
2205 classinfo *res = classcache_store(NULL, c, true);
2215 /* SUN compatible -verbose:class output */
2217 if (opt_verboseclass && r) {
2219 utf_display_classname(name);
2220 printf(" from %s]\n", cb->path);
2227 #if defined(STATISTICS)
2233 if (getcompilingtime)
2234 compilingtime_start();
2238 goto return_exception;
2252 /* load_class_from_classbuffer *************************************************
2254 Loads everything interesting about a class from the class file. The
2255 'classinfo' structure must have been allocated previously.
2257 The super class and the interfaces implemented by this class need
2258 not be loaded. The link is set later by the function 'class_link'.
2260 The loaded class is removed from the list 'unloadedclasses' and
2261 added to the list 'unlinkedclasses'.
2264 This function is NOT synchronized!
2266 *******************************************************************************/
2268 classinfo *load_class_from_classbuffer(classbuffer *cb)
2276 descriptor_pool *descpool;
2277 #if defined(STATISTICS)
2281 #ifdef LOADER_VERBOSE
2282 char logtext[MAXLOGTEXT];
2285 /* get the classbuffer's class */
2289 /* maybe the class is already loaded */
2294 #ifdef LOADER_VERBOSE
2295 LOADER_INDENT(logtext);
2296 strcat(logtext,"load_class_from_classbuffer(");
2297 utf_sprint(logtext+strlen(logtext),c->name);strcat(logtext,")");
2302 #if defined(STATISTICS)
2304 count_class_loads++;
2307 /* output for debugging purposes */
2310 log_message_class("Loading class: ", c);
2312 /* mark start of dump memory area */
2314 dumpsize = dump_size();
2316 /* class is somewhat loaded */
2320 if (!check_classbuffer_size(cb, 4 + 2 + 2))
2321 goto return_exception;
2323 /* check signature */
2325 if (suck_u4(cb) != MAGIC) {
2326 *exceptionptr = new_classformaterror(c, "Bad magic number");
2328 goto return_exception;
2336 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
2338 new_unsupportedclassversionerror(c,
2339 "Unsupported major.minor version %d.%d",
2342 goto return_exception;
2345 /* create a new descriptor pool */
2347 descpool = descriptor_pool_new(c);
2349 /* load the constant pool */
2351 if (!load_constantpool(cb, descpool))
2352 goto return_exception;
2355 c->erroneous_state = 0;
2356 c->initializing_thread = 0;
2358 c->classUsed = NOTUSED; /* not used initially CO-RT */
2363 if (!check_classbuffer_size(cb, 2))
2364 goto return_exception;
2366 c->flags = suck_u2(cb);
2368 /* check ACC flags consistency */
2370 if (c->flags & ACC_INTERFACE) {
2371 if (!(c->flags & ACC_ABSTRACT)) {
2372 /* We work around this because interfaces in JDK 1.1 are
2373 * not declared abstract. */
2375 c->flags |= ACC_ABSTRACT;
2378 if (c->flags & ACC_FINAL) {
2380 new_classformaterror(c,
2381 "Illegal class modifiers: 0x%X", c->flags);
2383 goto return_exception;
2386 if (c->flags & ACC_SUPER) {
2387 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
2391 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
2393 new_classformaterror(c, "Illegal class modifiers: 0x%X", c->flags);
2395 goto return_exception;
2398 if (!check_classbuffer_size(cb, 2 + 2))
2399 goto return_exception;
2404 if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
2405 goto return_exception;
2407 if (c->name == utf_not_named_yet) {
2408 /* we finally have a name for this class */
2410 class_set_packagename(c);
2412 } else if (name != c->name) {
2416 msglen = utf_strlen(c->name) + strlen(" (wrong name: ") +
2417 utf_strlen(name) + strlen(")") + strlen("0");
2419 msg = MNEW(char, msglen);
2421 utf_sprint(msg, c->name);
2422 strcat(msg, " (wrong name: ");
2423 utf_strcat(msg, name);
2427 new_exception_message(string_java_lang_NoClassDefFoundError, msg);
2429 MFREE(msg, char, msglen);
2431 goto return_exception;
2434 /* retrieve superclass */
2436 c->super.any = NULL;
2437 if ((i = suck_u2(cb))) {
2438 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
2439 goto return_exception;
2441 /* java.lang.Object may not have a super class. */
2443 if (c->name == utf_java_lang_Object) {
2445 new_exception_message(string_java_lang_ClassFormatError,
2446 "java.lang.Object with superclass");
2448 goto return_exception;
2451 /* Interfaces must have java.lang.Object as super class. */
2453 if ((c->flags & ACC_INTERFACE) &&
2454 supername != utf_java_lang_Object) {
2456 new_exception_message(string_java_lang_ClassFormatError,
2457 "Interfaces must have java.lang.Object as superclass");
2459 goto return_exception;
2465 /* This is only allowed for java.lang.Object. */
2467 if (c->name != utf_java_lang_Object) {
2468 *exceptionptr = new_classformaterror(c, "Bad superclass index");
2470 goto return_exception;
2474 /* retrieve interfaces */
2476 if (!check_classbuffer_size(cb, 2))
2477 goto return_exception;
2479 c->interfacescount = suck_u2(cb);
2481 if (!check_classbuffer_size(cb, 2 * c->interfacescount))
2482 goto return_exception;
2484 c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
2485 for (i = 0; i < c->interfacescount; i++) {
2486 /* the classrefs are created later */
2487 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2488 goto return_exception;
2492 if (!check_classbuffer_size(cb, 2))
2493 goto return_exception;
2495 c->fieldscount = suck_u2(cb);
2496 c->fields = GCNEW_UNCOLLECTABLE(fieldinfo, c->fieldscount);
2497 /* c->fields = MNEW(fieldinfo, c->fieldscount); */
2498 for (i = 0; i < c->fieldscount; i++) {
2499 if (!load_field(cb, &(c->fields[i]),descpool))
2500 goto return_exception;
2504 if (!check_classbuffer_size(cb, 2))
2505 goto return_exception;
2507 c->methodscount = suck_u2(cb);
2508 /* c->methods = GCNEW(methodinfo, c->methodscount); */
2509 c->methods = MNEW(methodinfo, c->methodscount);
2510 for (i = 0; i < c->methodscount; i++) {
2511 if (!load_method(cb, &(c->methods[i]),descpool))
2512 goto return_exception;
2515 /* create the class reference table */
2518 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
2520 /* allocate space for the parsed descriptors */
2522 descriptor_pool_alloc_parsed_descriptors(descpool);
2524 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
2526 #if defined(STATISTICS)
2528 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
2529 count_classref_len += classrefsize;
2530 count_parsed_desc_len += descsize;
2534 /* put the classrefs in the constant pool */
2535 for (i = 0; i < c->cpcount; i++) {
2536 if (c->cptags[i] == CONSTANT_Class) {
2537 utf *name = (utf *) c->cpinfos[i];
2538 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
2542 /* set the super class reference */
2545 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
2547 goto return_exception;
2550 /* set the super interfaces references */
2552 for (i = 0; i < c->interfacescount; i++) {
2553 c->interfaces[i].ref =
2554 descriptor_pool_lookup_classref(descpool,
2555 (utf *) c->interfaces[i].any);
2556 if (!c->interfaces[i].ref)
2557 goto return_exception;
2560 /* parse field descriptors */
2562 for (i = 0; i < c->fieldscount; i++) {
2563 c->fields[i].parseddesc =
2564 descriptor_pool_parse_field_descriptor(descpool,
2565 c->fields[i].descriptor);
2566 if (!c->fields[i].parseddesc)
2567 goto return_exception;
2570 /* parse method descriptors */
2572 for (i = 0; i < c->methodscount; i++) {
2573 methodinfo *m = &c->methods[i];
2575 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
2576 m->flags, class_get_self_classref(m->class));
2578 goto return_exception;
2580 for (j = 0; j < m->exceptiontablelength; j++) {
2581 if (!m->exceptiontable[j].catchtype.any)
2583 if ((m->exceptiontable[j].catchtype.ref =
2584 descriptor_pool_lookup_classref(descpool,
2585 (utf *) m->exceptiontable[j].catchtype.any)) == NULL)
2586 goto return_exception;
2589 for (j = 0; j < m->thrownexceptionscount; j++) {
2590 if (!m->thrownexceptions[j].any)
2592 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
2593 (utf *) m->thrownexceptions[j].any)) == NULL)
2594 goto return_exception;
2598 /* parse the loaded descriptors */
2600 for (i = 0; i < c->cpcount; i++) {
2601 constant_FMIref *fmi;
2604 switch (c->cptags[i]) {
2605 case CONSTANT_Fieldref:
2606 fmi = (constant_FMIref *) c->cpinfos[i];
2607 fmi->parseddesc.fd =
2608 descriptor_pool_parse_field_descriptor(descpool,
2610 if (!fmi->parseddesc.fd)
2611 goto return_exception;
2612 index = (int) (size_t) fmi->classref;
2614 (constant_classref *) class_getconstant(c, index,
2617 goto return_exception;
2619 case CONSTANT_Methodref:
2620 case CONSTANT_InterfaceMethodref:
2621 fmi = (constant_FMIref *) c->cpinfos[i];
2622 index = (int) (size_t) fmi->classref;
2624 (constant_classref *) class_getconstant(c, index,
2627 goto return_exception;
2628 fmi->parseddesc.md =
2629 descriptor_pool_parse_method_descriptor(descpool,
2633 if (!fmi->parseddesc.md)
2634 goto return_exception;
2639 /* Check if all fields and methods can be uniquely
2640 * identified by (name,descriptor). */
2643 /* We use a hash table here to avoid making the
2644 * average case quadratic in # of methods, fields.
2646 static int shift = 0;
2648 u2 *next; /* for chaining colliding hash entries */
2654 /* Allocate hashtable */
2655 len = c->methodscount;
2656 if (len < c->fieldscount) len = c->fieldscount;
2658 hashtab = MNEW(u2,(hashlen + len));
2659 next = hashtab + hashlen;
2661 /* Determine bitshift (to get good hash values) */
2671 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2673 for (i = 0; i < c->fieldscount; ++i) {
2674 fieldinfo *fi = c->fields + i;
2676 /* It's ok if we lose bits here */
2677 index = ((((size_t) fi->name) +
2678 ((size_t) fi->descriptor)) >> shift) % hashlen;
2680 if ((old = hashtab[index])) {
2684 if (c->fields[old].name == fi->name &&
2685 c->fields[old].descriptor == fi->descriptor) {
2687 new_classformaterror(c,
2688 "Repetitive field name/signature");
2690 goto return_exception;
2692 } while ((old = next[old]));
2694 hashtab[index] = i + 1;
2698 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2700 for (i = 0; i < c->methodscount; ++i) {
2701 methodinfo *mi = c->methods + i;
2703 /* It's ok if we lose bits here */
2704 index = ((((size_t) mi->name) +
2705 ((size_t) mi->descriptor)) >> shift) % hashlen;
2709 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2710 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2714 if ((old = hashtab[index])) {
2718 if (c->methods[old].name == mi->name &&
2719 c->methods[old].descriptor == mi->descriptor) {
2721 new_classformaterror(c,
2722 "Repetitive method name/signature");
2724 goto return_exception;
2726 } while ((old = next[old]));
2728 hashtab[index] = i + 1;
2731 MFREE(hashtab, u2, (hashlen + len));
2734 #if defined(STATISTICS)
2736 count_class_infos += sizeof(classinfo*) * c->interfacescount;
2737 count_class_infos += sizeof(fieldinfo) * c->fieldscount;
2738 count_class_infos += sizeof(methodinfo) * c->methodscount;
2742 /* load attribute structures */
2744 if (!check_classbuffer_size(cb, 2))
2745 goto return_exception;
2747 if (!load_attributes(cb, suck_u2(cb)))
2748 goto return_exception;
2751 /* Pre java 1.5 version don't check this. This implementation is like
2752 java 1.5 do it: for class file version 45.3 we don't check it, older
2753 versions are checked.
2755 if ((ma == 45 && mi > 3) || ma > 45) {
2756 /* check if all data has been read */
2757 s4 classdata_left = ((cb->data + cb->size) - cb->pos - 1);
2759 if (classdata_left > 0) {
2761 new_classformaterror(c, "Extra bytes at the end of class file");
2762 goto return_exception;
2767 /* release dump area */
2769 dump_release(dumpsize);
2772 log_message_class("Loading done class: ", c);
2778 /* release dump area */
2780 dump_release(dumpsize);
2782 /* an exception has been thrown */
2789 /* load_newly_created_array ****************************************************
2791 Load a newly created array class.
2794 c....................the array class C has been loaded
2795 other classinfo......the array class was found in the class cache,
2797 NULL.................an exception has been thrown
2800 This is an internal function. Do not use it unless you know exactly
2803 Use one of the load_class_... functions for general array class loading.
2805 *******************************************************************************/
2807 classinfo *load_newly_created_array(classinfo *c, java_objectheader *loader)
2809 classinfo *comp = NULL;
2811 methoddesc *clonedesc;
2812 constant_classref *classrefs;
2817 #ifdef LOADER_VERBOSE
2818 char logtext[MAXLOGTEXT];
2819 LOADER_INDENT(logtext);
2820 strcat(logtext,"load_newly_created_array(");utf_sprint_classname(logtext+strlen(logtext),c->name);
2821 sprintf(logtext+strlen(logtext),") loader=%p",loader);
2825 text = c->name->text;
2826 namelen = c->name->blength;
2828 /* Check array class name */
2830 if (namelen < 2 || text[0] != '[') {
2831 *exceptionptr = new_noclassdeffounderror(c->name);
2835 /* Check the element type */
2839 /* c is an array of arrays. We have to create the component class. */
2841 u = utf_new_intern(text + 1, namelen - 1);
2843 if (!(comp = load_class_from_classloader(u, loader))) {
2848 LOADER_ASSERT(comp->loaded);
2853 /* the array's flags are that of the component class */
2854 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2855 c->classloader = comp->classloader;
2859 /* c is an array of objects. */
2861 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2862 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
2863 *exceptionptr = new_noclassdeffounderror(c->name);
2867 u = utf_new_intern(text + 2, namelen - 3);
2870 if (!(comp = load_class_from_classloader(u, loader))) {
2875 LOADER_ASSERT(comp->loaded);
2880 /* the array's flags are that of the component class */
2881 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2882 c->classloader = comp->classloader;
2886 /* c is an array of a primitive type */
2888 /* check for cases like `[II' */
2890 *exceptionptr = new_noclassdeffounderror(c->name);
2894 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2895 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2896 c->classloader = NULL;
2899 LOADER_ASSERT(class_java_lang_Object);
2900 LOADER_ASSERT(class_java_lang_Cloneable);
2901 LOADER_ASSERT(class_java_io_Serializable);
2903 /* setup the array class */
2905 c->super.cls = class_java_lang_Object;
2907 c->interfacescount = 2;
2908 c->interfaces = MNEW(classref_or_classinfo, 2);
2913 tc = class_java_lang_Cloneable;
2914 LOADER_ASSERT(tc->loaded);
2915 list_addfirst(&unlinkedclasses, tc);
2916 c->interfaces[0].cls = tc;
2918 tc = class_java_io_Serializable;
2919 LOADER_ASSERT(tc->loaded);
2920 list_addfirst(&unlinkedclasses, tc);
2921 c->interfaces[1].cls = tc;
2924 c->interfaces[0].cls = class_java_lang_Cloneable;
2925 c->interfaces[1].cls = class_java_io_Serializable;
2928 c->methodscount = 1;
2929 c->methods = MNEW(methodinfo, c->methodscount);
2931 classrefs = MNEW(constant_classref, 2);
2932 CLASSREF_INIT(classrefs[0], c, c->name);
2933 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2935 /* create descriptor for clone method */
2936 /* we need one paramslot which is reserved for the 'this' parameter */
2937 clonedesc = NEW(methoddesc);
2938 clonedesc->returntype.type = TYPE_ADDRESS;
2939 clonedesc->returntype.classref = classrefs + 1;
2940 clonedesc->returntype.arraydim = 0;
2941 /* initialize params to "empty", add real params below in
2942 descriptor_params_from_paramtypes */
2943 clonedesc->paramcount = 0;
2944 clonedesc->paramslots = 0;
2945 clonedesc->paramtypes[0].classref = classrefs + 0;
2947 /* create methodinfo */
2950 MSET(clone, 0, methodinfo, 1);
2952 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
2953 initObjectLock(&clone->header);
2956 /* if you delete the ACC_NATIVE below, set clone->maxlocals=1 (interpreter
2958 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2959 clone->name = utf_clone;
2960 clone->descriptor = utf_void__java_lang_Object;
2961 clone->parseddesc = clonedesc;
2963 clone->monoPoly = MONO;
2965 /* parse the descriptor to get the register allocation */
2967 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2971 codegen_createnativestub((functionptr) &builtin_clone_array, clone);
2973 /* XXX: field: length? */
2975 /* array classes are not loaded from class files */
2978 c->parseddescs = (u1 *) clonedesc;
2979 c->parseddescsize = sizeof(methodinfo);
2980 c->classrefs = classrefs;
2981 c->classrefcount = 1;
2983 /* insert class into the loaded class cache */
2984 /* XXX free classinfo if NULL returned? */
2986 return classcache_store(loader,c,true);
2990 /* loader_close ****************************************************************
2992 Frees all resources.
2994 *******************************************************************************/
2996 void loader_close(void)
3003 * These are local overrides for various environment variables in Emacs.
3004 * Please do not remove this and leave it at the end of the file, where
3005 * Emacs will automagically detect them.
3006 * ---------------------------------------------------------------------
3009 * indent-tabs-mode: t