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 3806 2005-11-26 21:45:09Z 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 /******************************************************************************/
87 #define LOADER_ASSERT(cond) assert(cond)
89 #define LOADER_ASSERT(cond)
93 /********************************************************************
94 list of classpath entries (either filesystem directories or
96 ********************************************************************/
98 classpath_info *classpath_entries = NULL;
101 /* loader_init *****************************************************************
103 Initializes all lists and loads all classes required for the system
106 *******************************************************************************/
108 bool loader_init(u1 *stackbottom)
110 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
113 /* Initialize the monitor pointer for zip/jar file locking. */
115 for (cpi = classpath_entries; cpi != NULL; cpi = cpi->next) {
116 if (cpi->type == CLASSPATH_ARCHIVE)
117 initObjectLock(&cpi->header);
121 /* load some important classes */
123 if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
126 if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
129 if (!(class_java_lang_Cloneable =
130 load_class_bootstrap(utf_java_lang_Cloneable)))
133 if (!(class_java_io_Serializable =
134 load_class_bootstrap(utf_java_io_Serializable)))
138 /* load classes for wrapping primitive types */
140 if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
143 if (!(class_java_lang_Boolean =
144 load_class_bootstrap(utf_java_lang_Boolean)))
147 if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
150 if (!(class_java_lang_Character =
151 load_class_bootstrap(utf_java_lang_Character)))
154 if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
157 if (!(class_java_lang_Integer =
158 load_class_bootstrap(utf_java_lang_Integer)))
161 if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
164 if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
167 if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
171 /* load some other important classes */
173 if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
176 if (!(class_java_lang_ClassLoader =
177 load_class_bootstrap(utf_java_lang_ClassLoader)))
180 if (!(class_java_lang_SecurityManager =
181 load_class_bootstrap(utf_java_lang_SecurityManager)))
184 if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
187 if (!(class_java_lang_Thread =
188 load_class_bootstrap(utf_new_char("java/lang/Thread"))))
191 if (!(class_java_lang_ThreadGroup =
192 load_class_bootstrap(utf_java_lang_ThreadGroup)))
195 if (!(class_java_lang_VMThread =
196 load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
200 /* some classes which may be used more often */
202 if (!(class_java_lang_StackTraceElement =
203 load_class_bootstrap(utf_java_lang_StackTraceElement)))
206 if (!(class_java_lang_reflect_Constructor =
207 load_class_bootstrap(utf_java_lang_reflect_Constructor)))
210 if (!(class_java_lang_reflect_Field =
211 load_class_bootstrap(utf_java_lang_reflect_Field)))
214 if (!(class_java_lang_reflect_Method =
215 load_class_bootstrap(utf_java_lang_reflect_Method)))
218 if (!(class_java_security_PrivilegedAction =
219 load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
222 if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
225 if (!(arrayclass_java_lang_Object =
226 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
229 #if defined(USE_THREADS)
230 if (stackbottom != 0)
238 /************* functions for reading classdata *********************************
240 getting classdata in blocks of variable size
241 (8,16,32,64-bit integer or float)
243 *******************************************************************************/
245 /* check_classbuffer_size ******************************************************
247 assert that at least <len> bytes are left to read
248 <len> is limited to the range of non-negative s4 values
250 *******************************************************************************/
252 inline bool check_classbuffer_size(classbuffer *cb, s4 len)
254 if (len < 0 || ((cb->data + cb->size) - cb->pos - 1) < len) {
256 new_classformaterror((cb)->class, "Truncated class file");
265 /* suck_nbytes *****************************************************************
267 transfer block of classfile data into a buffer
269 *******************************************************************************/
271 inline void suck_nbytes(u1 *buffer, classbuffer *cb, s4 len)
273 memcpy(buffer, cb->pos + 1, len);
278 /* skip_nbytes ****************************************************************
280 skip block of classfile data
282 *******************************************************************************/
284 inline void skip_nbytes(classbuffer *cb, s4 len)
290 inline u1 suck_u1(classbuffer *cb)
296 inline u2 suck_u2(classbuffer *cb)
300 return ((u2) a << 8) + (u2) b;
304 inline u4 suck_u4(classbuffer *cb)
310 return ((u4) a << 24) + ((u4) b << 16) + ((u4) c << 8) + (u4) d;
314 /* get u8 from classfile data */
315 static u8 suck_u8(classbuffer *cb)
321 return (hi << 32) + lo;
324 v.high = suck_u4(cb);
331 /* get float from classfile data */
332 static float suck_float(classbuffer *cb)
340 for (i = 0; i < 4; i++)
341 buffer[3 - i] = suck_u1(cb);
343 memcpy((u1*) (&f), buffer, 4);
345 suck_nbytes((u1*) (&f), cb, 4);
348 if (sizeof(float) != 4) {
349 *exceptionptr = new_internalerror("Incompatible float-format");
351 /* XXX should we exit in such a case? */
352 throw_exception_exit();
359 /* get double from classfile data */
360 static double suck_double(classbuffer *cb)
368 #if defined(__ARM__) && defined(__ARMEL__) && !defined(__VFP_FP__)
370 * On little endian ARM processors when using FPA, word order
371 * of doubles is still big endian. So take that into account
372 * here. When using VFP, word order of doubles follows byte
373 * order. (michi 2005/07/24)
375 for (i = 0; i < 4; i++)
376 buffer[3 - i] = suck_u1(cb);
377 for (i = 0; i < 4; i++)
378 buffer[7 - i] = suck_u1(cb);
380 for (i = 0; i < 8; i++)
381 buffer[7 - i] = suck_u1(cb);
382 #endif /* defined(__ARM__) && ... */
384 memcpy((u1*) (&d), buffer, 8);
386 suck_nbytes((u1*) (&d), cb, 8);
389 if (sizeof(double) != 8) {
390 *exceptionptr = new_internalerror("Incompatible double-format");
392 /* XXX should we exit in such a case? */
393 throw_exception_exit();
400 /************************** function suck_init *********************************
402 called once at startup, sets the searchpath for the classfiles
404 *******************************************************************************/
406 void suck_init(char *classpath)
414 classpath_info *lastcpi;
418 /* search for last classpath entry (only if there already some) */
420 if ((lastcpi = classpath_entries)) {
421 while (lastcpi->next)
422 lastcpi = lastcpi->next;
425 for (start = classpath; (*start) != '\0';) {
427 /* search for ':' delimiter to get the end of the current entry */
428 for (end = start; ((*end) != '\0') && ((*end) != ':'); end++);
432 filenamelen = end - start;
434 if (filenamelen > 3) {
435 if (strncasecmp(end - 3, "zip", 3) == 0 ||
436 strncasecmp(end - 3, "jar", 3) == 0) {
441 /* save classpath entries as absolute pathnames */
446 if (*start != '/') { /* XXX fix me for win32 */
448 cwdlen = strlen(cwd) + strlen("/");
451 /* allocate memory for filename and fill it */
453 filename = MNEW(char, filenamelen + cwdlen + strlen("/") +
457 strcpy(filename, cwd);
458 strcat(filename, "/");
459 strncat(filename, start, filenamelen);
461 /* add cwd length to file length */
462 filenamelen += cwdlen;
465 strncpy(filename, start, filenamelen);
466 filename[filenamelen] = '\0';
472 #if defined(USE_ZLIB)
473 unzFile uf = unzOpen(filename);
476 cpi = NEW(classpath_info);
477 cpi->type = CLASSPATH_ARCHIVE;
480 cpi->path = filename;
481 cpi->pathlen = filenamelen;
483 /* SUN compatible -verbose:class output */
485 if (opt_verboseclass)
486 printf("[Opened %s]\n", filename);
490 throw_cacao_exception_exit(string_java_lang_InternalError,
491 "zip/jar files not supported");
495 cpi = NEW(classpath_info);
496 cpi->type = CLASSPATH_PATH;
499 if (filename[filenamelen - 1] != '/') {/*PERHAPS THIS SHOULD BE READ FROM A GLOBAL CONFIGURATION */
500 filename[filenamelen] = '/';
501 filename[filenamelen + 1] = '\0';
505 cpi->path = filename;
506 cpi->pathlen = filenamelen;
509 /* attach current classpath entry */
512 if (!classpath_entries)
513 classpath_entries = cpi;
521 /* goto next classpath entry, skip ':' delimiter */
533 /* loader_load_all_classes *****************************************************
535 Loads all classes specified in the BOOTCLASSPATH.
537 *******************************************************************************/
539 void loader_load_all_classes(void)
544 for (cpi = classpath_entries; cpi != 0; cpi = cpi->next) {
545 #if defined(USE_ZLIB)
546 if (cpi->type == CLASSPATH_ARCHIVE) {
550 s = (unz_s *) cpi->uf;
551 ce = s->cacao_dir_list;
554 /* skip all entries in META-INF and .properties, .png files */
556 if (strncmp(ce->name->text, "META-INF", strlen("META-INF")) &&
557 !strstr(ce->name->text, ".properties") &&
558 !strstr(ce->name->text, ".png"))
559 c = load_class_bootstrap(ce->name);
566 #if defined(USE_ZLIB)
573 /* suck_start ******************************************************************
575 Returns true if classbuffer is already loaded or a file for the
576 specified class has succussfully been read in. All directories of
577 the searchpath are used to find the classfile (<classname>.class).
578 Returns false if no classfile is found and writes an error message.
580 *******************************************************************************/
582 classbuffer *suck_start(classinfo *c)
594 /* initialize return value */
599 filenamelen = utf_strlen(c->name) + strlen(".class") + strlen("0");
600 filename = MNEW(char, filenamelen);
602 utf_sprint(filename, c->name);
603 strcat(filename, ".class");
605 /* walk through all classpath entries */
607 for (cpi = classpath_entries; cpi != NULL && cb == NULL; cpi = cpi->next) {
608 #if defined(USE_ZLIB)
609 if (cpi->type == CLASSPATH_ARCHIVE) {
611 #if defined(USE_THREADS)
612 /* enter a monitor on zip/jar archives */
614 builtin_monitorenter((java_objectheader *) cpi);
617 if (cacao_locate(cpi->uf, c->name) == UNZ_OK) {
618 unz_file_info file_info;
620 if (unzGetCurrentFileInfo(cpi->uf, &file_info, filename,
621 sizeof(filename), NULL, 0, NULL, 0) == UNZ_OK) {
622 if (unzOpenCurrentFile(cpi->uf) == UNZ_OK) {
623 cb = NEW(classbuffer);
625 cb->size = file_info.uncompressed_size;
626 cb->data = MNEW(u1, cb->size);
627 cb->pos = cb->data - 1;
628 cb->path = cpi->path;
630 len = unzReadCurrentFile(cpi->uf, cb->data, cb->size);
632 if (len != cb->size) {
634 log_text("Error while unzipping");
641 log_text("Error while opening file in archive");
645 log_text("Error while retrieving fileinfo");
648 unzCloseCurrentFile(cpi->uf);
650 #if defined(USE_THREADS)
651 /* leave the monitor */
653 builtin_monitorexit((java_objectheader *) cpi);
657 #endif /* defined(USE_ZLIB) */
659 path = MNEW(char, cpi->pathlen + filenamelen);
660 strcpy(path, cpi->path);
661 strcat(path, filename);
663 classfile = fopen(path, "r");
665 if (classfile) { /* file exists */
666 if (!stat(path, &buffer)) { /* read classfile data */
667 cb = NEW(classbuffer);
669 cb->size = buffer.st_size;
670 cb->data = MNEW(u1, cb->size);
671 cb->pos = cb->data - 1;
672 cb->path = cpi->path;
674 /* read class data */
675 len = fread(cb->data, 1, cb->size, classfile);
677 if (len != buffer.st_size) {
679 /* if (ferror(classfile)) { */
688 MFREE(path, char, cpi->pathlen + filenamelen);
689 #if defined(USE_ZLIB)
696 dolog("Warning: Can not open class file '%s'", filename);
698 if (strcmp(filename, "org/mortbay/util/MultiException.class") == 0) {
706 MFREE(filename, char, filenamelen);
712 /************************** function suck_stop *********************************
714 frees memory for buffer with classfile data.
715 Caution: this function may only be called if buffer has been allocated
716 by suck_start with reading a file
718 *******************************************************************************/
720 void suck_stop(classbuffer *cb)
724 MFREE(cb->data, u1, cb->size);
725 FREE(cb, classbuffer);
729 /******************************************************************************/
730 /******************* Some support functions ***********************************/
731 /******************************************************************************/
733 void fprintflags (FILE *fp, u2 f)
735 if ( f & ACC_PUBLIC ) fprintf (fp," PUBLIC");
736 if ( f & ACC_PRIVATE ) fprintf (fp," PRIVATE");
737 if ( f & ACC_PROTECTED ) fprintf (fp," PROTECTED");
738 if ( f & ACC_STATIC ) fprintf (fp," STATIC");
739 if ( f & ACC_FINAL ) fprintf (fp," FINAL");
740 if ( f & ACC_SYNCHRONIZED ) fprintf (fp," SYNCHRONIZED");
741 if ( f & ACC_VOLATILE ) fprintf (fp," VOLATILE");
742 if ( f & ACC_TRANSIENT ) fprintf (fp," TRANSIENT");
743 if ( f & ACC_NATIVE ) fprintf (fp," NATIVE");
744 if ( f & ACC_INTERFACE ) fprintf (fp," INTERFACE");
745 if ( f & ACC_ABSTRACT ) fprintf (fp," ABSTRACT");
749 /********** internal function: printflags (only for debugging) ***************/
751 void printflags(u2 f)
753 fprintflags(stdout,f);
757 /********************** Function: skipattributebody ****************************
759 skips an attribute after the 16 bit reference to attribute_name has already
762 *******************************************************************************/
764 static bool skipattributebody(classbuffer *cb)
768 if (!check_classbuffer_size(cb, 4))
773 if (!check_classbuffer_size(cb, len))
776 skip_nbytes(cb, len);
782 /************************* Function: skipattributes ****************************
784 skips num attribute structures
786 *******************************************************************************/
788 static bool skipattributes(classbuffer *cb, u4 num)
793 for (i = 0; i < num; i++) {
794 if (!check_classbuffer_size(cb, 2 + 4))
800 if (!check_classbuffer_size(cb, len))
803 skip_nbytes(cb, len);
810 /* load_constantpool ***********************************************************
812 Loads the constantpool of a class, the entries are transformed into
813 a simpler format by resolving references (a detailed overview of
814 the compact structures can be found in global.h).
816 *******************************************************************************/
818 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
821 /* The following structures are used to save information which cannot be
822 processed during the first pass. After the complete constantpool has
823 been traversed the references can be resolved.
824 (only in specific order) */
826 /* CONSTANT_Class entries */
827 typedef struct forward_class {
828 struct forward_class *next;
833 /* CONSTANT_String */
834 typedef struct forward_string {
835 struct forward_string *next;
840 /* CONSTANT_NameAndType */
841 typedef struct forward_nameandtype {
842 struct forward_nameandtype *next;
846 } forward_nameandtype;
848 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
849 typedef struct forward_fieldmethint {
850 struct forward_fieldmethint *next;
854 u2 nameandtype_index;
855 } forward_fieldmethint;
861 forward_class *forward_classes = NULL;
862 forward_string *forward_strings = NULL;
863 forward_nameandtype *forward_nameandtypes = NULL;
864 forward_fieldmethint *forward_fieldmethints = NULL;
868 forward_nameandtype *nfn;
869 forward_fieldmethint *nff;
877 /* number of entries in the constant_pool table plus one */
878 if (!check_classbuffer_size(cb, 2))
881 cpcount = c->cpcount = suck_u2(cb);
883 /* allocate memory */
884 cptags = c->cptags = MNEW(u1, cpcount);
885 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
888 *exceptionptr = new_classformaterror(c, "Illegal constant pool size");
892 #if defined(STATISTICS)
894 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
897 /* initialize constantpool */
898 for (idx = 0; idx < cpcount; idx++) {
899 cptags[idx] = CONSTANT_UNUSED;
904 /******* first pass *******/
905 /* entries which cannot be resolved now are written into
906 temporary structures and traversed again later */
909 while (idx < cpcount) {
912 /* get constant type */
913 if (!check_classbuffer_size(cb, 1))
920 nfc = DNEW(forward_class);
922 nfc->next = forward_classes;
923 forward_classes = nfc;
925 nfc->thisindex = idx;
926 /* reference to CONSTANT_NameAndType */
927 if (!check_classbuffer_size(cb, 2))
930 nfc->name_index = suck_u2(cb);
935 case CONSTANT_String:
936 nfs = DNEW(forward_string);
938 nfs->next = forward_strings;
939 forward_strings = nfs;
941 nfs->thisindex = idx;
943 /* reference to CONSTANT_Utf8_info with string characters */
944 if (!check_classbuffer_size(cb, 2))
947 nfs->string_index = suck_u2(cb);
952 case CONSTANT_NameAndType:
953 nfn = DNEW(forward_nameandtype);
955 nfn->next = forward_nameandtypes;
956 forward_nameandtypes = nfn;
958 nfn->thisindex = idx;
960 if (!check_classbuffer_size(cb, 2 + 2))
963 /* reference to CONSTANT_Utf8_info containing simple name */
964 nfn->name_index = suck_u2(cb);
966 /* reference to CONSTANT_Utf8_info containing field or method
968 nfn->sig_index = suck_u2(cb);
973 case CONSTANT_Fieldref:
974 case CONSTANT_Methodref:
975 case CONSTANT_InterfaceMethodref:
976 nff = DNEW(forward_fieldmethint);
978 nff->next = forward_fieldmethints;
979 forward_fieldmethints = nff;
981 nff->thisindex = idx;
985 if (!check_classbuffer_size(cb, 2 + 2))
988 /* class or interface type that contains the declaration of the
990 nff->class_index = suck_u2(cb);
992 /* name and descriptor of the field or method */
993 nff->nameandtype_index = suck_u2(cb);
998 case CONSTANT_Integer: {
999 constant_integer *ci = NEW(constant_integer);
1001 #if defined(STATISTICS)
1003 count_const_pool_len += sizeof(constant_integer);
1006 if (!check_classbuffer_size(cb, 4))
1009 ci->value = suck_s4(cb);
1010 cptags[idx] = CONSTANT_Integer;
1017 case CONSTANT_Float: {
1018 constant_float *cf = NEW(constant_float);
1020 #if defined(STATISTICS)
1022 count_const_pool_len += sizeof(constant_float);
1025 if (!check_classbuffer_size(cb, 4))
1028 cf->value = suck_float(cb);
1029 cptags[idx] = CONSTANT_Float;
1036 case CONSTANT_Long: {
1037 constant_long *cl = NEW(constant_long);
1039 #if defined(STATISTICS)
1041 count_const_pool_len += sizeof(constant_long);
1044 if (!check_classbuffer_size(cb, 8))
1047 cl->value = suck_s8(cb);
1048 cptags[idx] = CONSTANT_Long;
1051 if (idx > cpcount) {
1053 new_classformaterror(c, "Invalid constant pool entry");
1059 case CONSTANT_Double: {
1060 constant_double *cd = NEW(constant_double);
1062 #if defined(STATISTICS)
1064 count_const_pool_len += sizeof(constant_double);
1067 if (!check_classbuffer_size(cb, 8))
1070 cd->value = suck_double(cb);
1071 cptags[idx] = CONSTANT_Double;
1074 if (idx > cpcount) {
1076 new_classformaterror(c, "Invalid constant pool entry");
1082 case CONSTANT_Utf8: {
1085 /* number of bytes in the bytes array (not string-length) */
1086 if (!check_classbuffer_size(cb, 2))
1089 length = suck_u2(cb);
1090 cptags[idx] = CONSTANT_Utf8;
1092 /* validate the string */
1093 if (!check_classbuffer_size(cb, length))
1097 !is_valid_utf((char *) (cb->pos + 1),
1098 (char *) (cb->pos + 1 + length))) {
1099 *exceptionptr = new_classformaterror(c,"Invalid UTF-8 string");
1102 /* insert utf-string into the utf-symboltable */
1103 cpinfos[idx] = utf_new((char *) (cb->pos + 1), length);
1105 /* skip bytes of the string (buffer size check above) */
1106 skip_nbytes(cb, length);
1113 new_classformaterror(c, "Illegal constant pool type");
1119 /* resolve entries in temporary structures */
1121 while (forward_classes) {
1123 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
1127 if (opt_verify && !is_valid_name_utf(name)) {
1129 new_classformaterror(c, "Class reference with invalid name");
1133 /* add all class references to the descriptor_pool */
1135 if (!descriptor_pool_add_class(descpool, name))
1138 cptags[forward_classes->thisindex] = CONSTANT_Class;
1143 if (!(tc = load_class_bootstrap(name)))
1146 /* link the class later, because we cannot link the class currently
1148 list_addfirst(&unlinkedclasses, tc);
1151 /* the classref is created later */
1152 cpinfos[forward_classes->thisindex] = name;
1154 nfc = forward_classes;
1155 forward_classes = forward_classes->next;
1158 while (forward_strings) {
1160 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
1164 /* resolve utf-string */
1165 cptags[forward_strings->thisindex] = CONSTANT_String;
1166 cpinfos[forward_strings->thisindex] = text;
1168 nfs = forward_strings;
1169 forward_strings = forward_strings->next;
1172 while (forward_nameandtypes) {
1173 constant_nameandtype *cn = NEW(constant_nameandtype);
1175 #if defined(STATISTICS)
1177 count_const_pool_len += sizeof(constant_nameandtype);
1180 /* resolve simple name and descriptor */
1181 cn->name = class_getconstant(c,
1182 forward_nameandtypes->name_index,
1187 cn->descriptor = class_getconstant(c,
1188 forward_nameandtypes->sig_index,
1190 if (!cn->descriptor)
1195 if (!is_valid_name_utf(cn->name)) {
1197 new_classformaterror(c,
1198 "Illegal Field name \"%s\"",
1204 /* disallow referencing <clinit> among others */
1205 if (cn->name->text[0] == '<' && cn->name != utf_init) {
1207 new_classformaterror(c,"Illegal reference to special method");
1212 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
1213 cpinfos[forward_nameandtypes->thisindex] = cn;
1215 nfn = forward_nameandtypes;
1216 forward_nameandtypes = forward_nameandtypes->next;
1219 while (forward_fieldmethints) {
1220 constant_nameandtype *nat;
1221 constant_FMIref *fmi = NEW(constant_FMIref);
1223 #if defined(STATISTICS)
1225 count_const_pool_len += sizeof(constant_FMIref);
1227 /* resolve simple name and descriptor */
1229 nat = class_getconstant(c,
1230 forward_fieldmethints->nameandtype_index,
1231 CONSTANT_NameAndType);
1235 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
1237 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
1240 /* the classref is created later */
1242 fmi->classref = (constant_classref *) (size_t) forward_fieldmethints->class_index;
1243 fmi->name = nat->name;
1244 fmi->descriptor = nat->descriptor;
1246 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
1247 cpinfos[forward_fieldmethints->thisindex] = fmi;
1249 nff = forward_fieldmethints;
1250 forward_fieldmethints = forward_fieldmethints->next;
1253 /* everything was ok */
1259 /* load_field ******************************************************************
1261 Load everything about a class field from the class file and fill a
1262 'fieldinfo' structure. For static fields, space in the data segment
1265 *******************************************************************************/
1267 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
1269 static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
1274 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
1279 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1282 f->flags = suck_u2(cb);
1284 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1289 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1293 f->parseddesc = NULL;
1295 if (!descriptor_pool_add(descpool, u, NULL))
1298 /* descriptor_pool_add accepts method descriptors, so we have to check */
1299 /* against them here before the call of desc_to_type below. */
1300 if (u->text[0] == '(') {
1301 *exceptionptr = new_classformaterror(c,"Method descriptor used for field");
1307 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<') {
1308 *exceptionptr = new_classformaterror(c,
1309 "Illegal Field name \"%s\"",
1314 /* check flag consistency */
1315 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
1317 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
1318 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
1320 new_classformaterror(c,
1321 "Illegal field modifiers: 0x%X",
1326 if (c->flags & ACC_INTERFACE) {
1327 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
1328 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
1329 f->flags & ACC_TRANSIENT) {
1331 new_classformaterror(c,
1332 "Illegal field modifiers: 0x%X",
1339 f->type = jtype = desc_to_type(f->descriptor); /* data type */
1340 f->offset = 0; /* offset from start of object */
1345 case TYPE_INT: f->value.i = 0; break;
1346 case TYPE_FLOAT: f->value.f = 0.0; break;
1347 case TYPE_DOUBLE: f->value.d = 0.0; break;
1348 case TYPE_ADDRESS: f->value.a = NULL; break;
1351 f->value.l = 0; break;
1353 f->value.l.low = 0; f->value.l.high = 0; break;
1357 /* read attributes */
1358 if (!check_classbuffer_size(cb, 2))
1361 attrnum = suck_u2(cb);
1362 for (i = 0; i < attrnum; i++) {
1363 if (!check_classbuffer_size(cb, 2))
1366 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1369 if (u == utf_ConstantValue) {
1370 if (!check_classbuffer_size(cb, 4 + 2))
1373 /* check attribute length */
1374 if (suck_u4(cb) != 2) {
1376 new_classformaterror(c, "Wrong size for VALUE attribute");
1380 /* constant value attribute */
1381 if (pindex != field_load_NOVALUE) {
1383 new_classformaterror(c,
1384 "Multiple ConstantValue attributes");
1388 /* index of value in constantpool */
1389 pindex = suck_u2(cb);
1391 /* initialize field with value from constantpool */
1394 constant_integer *ci;
1396 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
1399 f->value.i = ci->value;
1406 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
1409 f->value.l = cl->value;
1416 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
1419 f->value.f = cf->value;
1424 constant_double *cd;
1426 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
1429 f->value.d = cd->value;
1434 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
1437 /* create javastring from compressed utf8-string */
1438 f->value.a = literalstring_new(u);
1442 log_text("Invalid Constant - Type");
1446 /* unknown attribute */
1447 if (!skipattributebody(cb))
1452 /* everything was ok */
1458 /* load_method *****************************************************************
1460 Loads a method from the class file and fills an existing
1461 'methodinfo' structure. For native methods, the function pointer
1462 field is set to the real function pointer, for JavaVM methods a
1463 pointer to the compiler is used preliminarily.
1465 *******************************************************************************/
1467 static bool load_method(classbuffer *cb, methodinfo *m, descriptor_pool *descpool)
1478 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1479 initObjectLock(&m->header);
1484 count_all_methods++;
1487 m->thrownexceptionscount = 0;
1488 m->linenumbercount = 0;
1491 m->nativelyoverloaded = false;
1493 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1496 m->flags = suck_u2(cb);
1498 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1503 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1507 m->parseddesc = NULL;
1509 if (!descriptor_pool_add(descpool, u, &argcount))
1513 if (!is_valid_name_utf(m->name)) {
1514 *exceptionptr = new_classformaterror(c,"Method with invalid name");
1518 if (m->name->text[0] == '<' &&
1519 m->name != utf_init && m->name != utf_clinit) {
1520 *exceptionptr = new_classformaterror(c,"Method with invalid special name");
1525 if (!(m->flags & ACC_STATIC))
1526 argcount++; /* count the 'this' argument */
1529 if (argcount > 255) {
1531 new_classformaterror(c, "Too many arguments in signature");
1535 /* check flag consistency */
1536 if (m->name != utf_clinit) {
1537 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1539 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1541 new_classformaterror(c,
1542 "Illegal method modifiers: 0x%X",
1547 if (m->flags & ACC_ABSTRACT) {
1548 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1549 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1551 new_classformaterror(c,
1552 "Illegal method modifiers: 0x%X",
1558 if (c->flags & ACC_INTERFACE) {
1559 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1561 new_classformaterror(c,
1562 "Illegal method modifiers: 0x%X",
1568 if (m->name == utf_init) {
1569 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1570 ACC_NATIVE | ACC_ABSTRACT)) {
1571 *exceptionptr = new_classformaterror(c,
1572 "Instance initialization method has invalid flags set");
1580 m->basicblockcount = 0;
1581 m->basicblocks = NULL;
1582 m->basicblockindex = NULL;
1583 m->instructioncount = 0;
1584 m->instructions = NULL;
1587 m->exceptiontable = NULL;
1588 m->stubroutine = NULL;
1590 m->entrypoint = NULL;
1591 m->methodUsed = NOTUSED;
1594 m->subRedefsUsed = 0;
1598 if (!check_classbuffer_size(cb, 2))
1601 attrnum = suck_u2(cb);
1602 for (i = 0; i < attrnum; i++) {
1605 if (!check_classbuffer_size(cb, 2))
1608 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1611 if (aname == utf_Code) {
1612 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1614 new_classformaterror(c,
1615 "Code attribute in native or abstract methods");
1622 new_classformaterror(c, "Multiple Code attributes");
1627 if (!check_classbuffer_size(cb, 4 + 2 + 2))
1631 m->maxstack = suck_u2(cb);
1632 m->maxlocals = suck_u2(cb);
1634 if (m->maxlocals < argcount) {
1636 new_classformaterror(c, "Arguments can't fit into locals");
1641 if (!check_classbuffer_size(cb, 4))
1644 m->jcodelength = suck_u4(cb);
1646 if (m->jcodelength == 0) {
1648 new_classformaterror(c, "Code of a method has length 0");
1653 if (m->jcodelength > 65535) {
1655 new_classformaterror(c,
1656 "Code of a method longer than 65535 bytes");
1661 if (!check_classbuffer_size(cb, m->jcodelength))
1664 m->jcode = MNEW(u1, m->jcodelength);
1665 suck_nbytes(m->jcode, cb, m->jcodelength);
1667 if (!check_classbuffer_size(cb, 2))
1670 m->exceptiontablelength = suck_u2(cb);
1671 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->exceptiontablelength))
1674 m->exceptiontable = MNEW(exceptiontable, m->exceptiontablelength);
1676 #if defined(STATISTICS)
1678 count_vmcode_len += m->jcodelength + 18;
1679 count_extable_len +=
1680 m->exceptiontablelength * sizeof(exceptiontable);
1684 for (j = 0; j < m->exceptiontablelength; j++) {
1686 m->exceptiontable[j].startpc = suck_u2(cb);
1687 m->exceptiontable[j].endpc = suck_u2(cb);
1688 m->exceptiontable[j].handlerpc = suck_u2(cb);
1692 m->exceptiontable[j].catchtype.any = NULL;
1695 /* the classref is created later */
1696 if (!(m->exceptiontable[j].catchtype.any =
1697 (utf*)class_getconstant(c, idx, CONSTANT_Class)))
1702 if (!check_classbuffer_size(cb, 2))
1705 codeattrnum = suck_u2(cb);
1707 for (; codeattrnum > 0; codeattrnum--) {
1710 if (!check_classbuffer_size(cb, 2))
1713 if (!(caname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1716 if (caname == utf_LineNumberTable) {
1719 if (!check_classbuffer_size(cb, 4 + 2))
1723 m->linenumbercount = suck_u2(cb);
1725 if (!check_classbuffer_size(cb,
1726 (2 + 2) * m->linenumbercount))
1729 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1731 for (lncid = 0; lncid < m->linenumbercount; lncid++) {
1732 m->linenumbers[lncid].start_pc = suck_u2(cb);
1733 m->linenumbers[lncid].line_number = suck_u2(cb);
1737 if (!skipattributes(cb, codeattrnum))
1743 if (!skipattributebody(cb))
1748 } else if (aname == utf_Exceptions) {
1751 if (m->thrownexceptions) {
1753 new_classformaterror(c, "Multiple Exceptions attributes");
1757 if (!check_classbuffer_size(cb, 4 + 2))
1760 suck_u4(cb); /* length */
1761 m->thrownexceptionscount = suck_u2(cb);
1763 if (!check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1766 m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
1768 for (j = 0; j < m->thrownexceptionscount; j++) {
1769 /* the classref is created later */
1770 if (!((m->thrownexceptions)[j].any =
1771 (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1776 if (!skipattributebody(cb))
1781 if (!m->jcode && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1782 *exceptionptr = new_classformaterror(c, "Missing Code attribute");
1787 /* everything was ok */
1793 /* load_attribute **************************************************************
1795 Read attributes from classfile.
1797 *******************************************************************************/
1799 static bool load_attributes(classbuffer *cb, u4 num)
1807 for (i = 0; i < num; i++) {
1808 /* retrieve attribute name */
1809 if (!check_classbuffer_size(cb, 2))
1812 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1815 if (aname == utf_InnerClasses) {
1816 /* innerclasses attribute */
1817 if (c->innerclass) {
1819 new_classformaterror(c, "Multiple InnerClasses attributes");
1823 if (!check_classbuffer_size(cb, 4 + 2))
1826 /* skip attribute length */
1829 /* number of records */
1830 c->innerclasscount = suck_u2(cb);
1832 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
1835 /* allocate memory for innerclass structure */
1836 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
1838 for (j = 0; j < c->innerclasscount; j++) {
1839 /* The innerclass structure contains a class with an encoded
1840 name, its defining scope, its simple name and a bitmask of
1841 the access flags. If an inner class is not a member, its
1842 outer_class is NULL, if a class is anonymous, its name is
1845 innerclassinfo *info = c->innerclass + j;
1847 info->inner_class.ref =
1848 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
1849 info->outer_class.ref =
1850 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
1852 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1853 info->flags = suck_u2(cb);
1856 } else if (aname == utf_SourceFile) {
1857 if (!check_classbuffer_size(cb, 4 + 2))
1860 if (suck_u4(cb) != 2) {
1862 new_classformaterror(c, "Wrong size for VALUE attribute");
1866 if (c->sourcefile) {
1868 new_classformaterror(c, "Multiple SourceFile attributes");
1872 if (!(c->sourcefile = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1876 /* unknown attribute */
1877 if (!skipattributebody(cb))
1886 /* load_class_from_sysloader ***************************************************
1888 Load the class with the given name using the system class loader
1891 name.............the classname
1894 the loaded class, or
1895 NULL if an exception has been thrown
1897 *******************************************************************************/
1899 classinfo *load_class_from_sysloader(utf *name)
1902 java_objectheader *cl;
1905 LOADER_ASSERT(class_java_lang_Object);
1906 LOADER_ASSERT(class_java_lang_ClassLoader);
1907 LOADER_ASSERT(class_java_lang_ClassLoader->linked);
1909 m = class_resolveclassmethod(class_java_lang_ClassLoader,
1910 utf_getSystemClassLoader,
1911 utf_void__java_lang_ClassLoader,
1912 class_java_lang_Object,
1918 cl = (java_objectheader *) asm_calljavafunction(m, NULL, NULL, NULL, NULL);
1923 c = load_class_from_classloader(name, cl);
1929 /* load_class_from_classloader *************************************************
1931 Load the class with the given name using the given user-defined class loader.
1934 name.............the classname
1935 cl...............user-defined class loader
1938 the loaded class, or
1939 NULL if an exception has been thrown
1941 *******************************************************************************/
1943 classinfo *load_class_from_classloader(utf *name, java_objectheader *cl)
1948 LOADER_ASSERT(name);
1950 /* lookup if this class has already been loaded */
1952 c = classcache_lookup(cl, name);
1957 /* if other class loader than bootstrap, call it */
1965 namelen = name->blength;
1967 /* handle array classes */
1968 if (text[0] == '[') {
1974 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1975 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1976 *exceptionptr = new_noclassdeffounderror(name);
1980 u = utf_new(text + 2, namelen - 3);
1982 if (!(comp = load_class_from_classloader(u, cl)))
1985 /* create the array class */
1987 c = class_array_of(comp, false);
1989 tmpc = classcache_store(cl, c, true);
1992 /* exception, free the loaded class */
2000 /* load the component class */
2002 u = utf_new(text + 1, namelen - 1);
2004 if (!(comp = load_class_from_classloader(u, cl)))
2007 /* create the array class */
2009 c = class_array_of(comp, false);
2011 tmpc = classcache_store(cl, c, true);
2014 /* exception, free the loaded class */
2022 /* primitive array classes are loaded by the bootstrap loader */
2024 c = load_class_bootstrap(name);
2030 LOADER_ASSERT(class_java_lang_Object);
2032 lc = class_resolveclassmethod(cl->vftbl->class,
2034 utf_java_lang_String__java_lang_Class,
2035 class_java_lang_Object,
2039 return false; /* exception */
2041 c = (classinfo *) asm_calljavafunction(lc,
2043 javastring_new_slash_to_dot(name),
2047 /* Store this class in the loaded class cache. If another
2048 class with the same (initloader,name) pair has been
2049 stored earlier it will be returned by classcache_store
2050 In this case classcache_store may not free the class
2051 because it has already been exposed to Java code which
2052 may have kept references to that class. */
2054 tmpc = classcache_store(cl, c, false);
2057 /* exception, free the loaded class */
2065 /* loadClass has thrown an exception */
2066 /* we must convert ClassNotFoundException into NoClassDefFoundException */
2067 /* XXX maybe we should have a flag that avoids this conversion */
2068 /* for calling load_class_from_classloader from Class.forName */
2069 /* Currently we do a double conversion in these cases */
2070 classnotfoundexception_to_noclassdeffounderror();
2073 /* SUN compatible -verbose:class output */
2075 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
2077 utf_display_classname(name);
2084 c = load_class_bootstrap(name);
2090 /* load_class_bootstrap ********************************************************
2092 Load the class with the given name using the bootstrap class loader.
2095 name.............the classname
2098 loaded classinfo, or
2099 NULL if an exception has been thrown
2102 load_class_bootstrap is synchronized. It can be treated as an
2105 *******************************************************************************/
2107 classinfo *load_class_bootstrap(utf *name)
2115 LOADER_ASSERT(name);
2117 /* lookup if this class has already been loaded */
2119 if ((r = classcache_lookup(NULL, name)))
2122 /* create the classinfo */
2124 c = class_create_classinfo(name);
2126 /* handle array classes */
2128 if (name->text[0] == '[') {
2129 c = load_newly_created_array(c, NULL);
2132 LOADER_ASSERT(c->loaded);
2136 #if defined(STATISTICS)
2139 if (getcompilingtime)
2140 compilingtime_stop();
2143 loadingtime_start();
2146 /* load classdata, throw exception on error */
2148 if ((cb = suck_start(c)) == NULL) {
2149 /* this normally means, the classpath was not set properly */
2151 if (name == utf_java_lang_Object)
2152 throw_cacao_exception_exit(string_java_lang_NoClassDefFoundError,
2153 "java/lang/Object");
2156 new_exception_utfmessage(string_java_lang_NoClassDefFoundError,
2162 /* load the class from the buffer */
2164 r = load_class_from_classbuffer(cb);
2167 /* the class could not be loaded, free the classinfo struct */
2172 /* Store this class in the loaded class cache this step also
2173 checks the loading constraints. If the class has been loaded
2174 before, the earlier loaded class is returned. */
2176 classinfo *res = classcache_store(NULL, c, true);
2186 /* SUN compatible -verbose:class output */
2188 if (opt_verboseclass && r) {
2190 utf_display_classname(name);
2191 printf(" from %s]\n", cb->path);
2198 #if defined(STATISTICS)
2204 if (getcompilingtime)
2205 compilingtime_start();
2212 /* load_class_from_classbuffer *************************************************
2214 Loads everything interesting about a class from the class file. The
2215 'classinfo' structure must have been allocated previously.
2217 The super class and the interfaces implemented by this class need
2218 not be loaded. The link is set later by the function 'class_link'.
2220 The loaded class is removed from the list 'unloadedclasses' and
2221 added to the list 'unlinkedclasses'.
2224 This function is NOT synchronized!
2226 *******************************************************************************/
2228 classinfo *load_class_from_classbuffer(classbuffer *cb)
2236 descriptor_pool *descpool;
2237 #if defined(STATISTICS)
2242 /* get the classbuffer's class */
2246 /* maybe the class is already loaded */
2251 #if defined(STATISTICS)
2253 count_class_loads++;
2256 /* output for debugging purposes */
2259 log_message_class("Loading class: ", c);
2261 /* mark start of dump memory area */
2263 dumpsize = dump_size();
2265 /* class is somewhat loaded */
2269 if (!check_classbuffer_size(cb, 4 + 2 + 2))
2270 goto return_exception;
2272 /* check signature */
2274 if (suck_u4(cb) != MAGIC) {
2275 *exceptionptr = new_classformaterror(c, "Bad magic number");
2277 goto return_exception;
2285 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
2287 new_unsupportedclassversionerror(c,
2288 "Unsupported major.minor version %d.%d",
2291 goto return_exception;
2294 /* create a new descriptor pool */
2296 descpool = descriptor_pool_new(c);
2298 /* load the constant pool */
2300 if (!load_constantpool(cb, descpool))
2301 goto return_exception;
2304 c->erroneous_state = 0;
2305 c->initializing_thread = 0;
2307 c->classUsed = NOTUSED; /* not used initially CO-RT */
2312 if (!check_classbuffer_size(cb, 2))
2313 goto return_exception;
2315 c->flags = suck_u2(cb);
2317 /* check ACC flags consistency */
2319 if (c->flags & ACC_INTERFACE) {
2320 if (!(c->flags & ACC_ABSTRACT)) {
2321 /* We work around this because interfaces in JDK 1.1 are
2322 * not declared abstract. */
2324 c->flags |= ACC_ABSTRACT;
2327 if (c->flags & ACC_FINAL) {
2329 new_classformaterror(c,
2330 "Illegal class modifiers: 0x%X", c->flags);
2332 goto return_exception;
2335 if (c->flags & ACC_SUPER) {
2336 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
2340 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
2342 new_classformaterror(c, "Illegal class modifiers: 0x%X", c->flags);
2344 goto return_exception;
2347 if (!check_classbuffer_size(cb, 2 + 2))
2348 goto return_exception;
2353 if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
2354 goto return_exception;
2356 if (c->name == utf_not_named_yet) {
2357 /* we finally have a name for this class */
2359 class_set_packagename(c);
2361 } else if (name != c->name) {
2365 msglen = utf_strlen(c->name) + strlen(" (wrong name: ") +
2366 utf_strlen(name) + strlen(")") + strlen("0");
2368 msg = MNEW(char, msglen);
2370 utf_sprint(msg, c->name);
2371 strcat(msg, " (wrong name: ");
2372 utf_strcat(msg, name);
2376 new_exception_message(string_java_lang_NoClassDefFoundError, msg);
2378 MFREE(msg, char, msglen);
2380 goto return_exception;
2383 /* retrieve superclass */
2385 c->super.any = NULL;
2386 if ((i = suck_u2(cb))) {
2387 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
2388 goto return_exception;
2390 /* java.lang.Object may not have a super class. */
2392 if (c->name == utf_java_lang_Object) {
2394 new_exception_message(string_java_lang_ClassFormatError,
2395 "java.lang.Object with superclass");
2397 goto return_exception;
2400 /* Interfaces must have java.lang.Object as super class. */
2402 if ((c->flags & ACC_INTERFACE) &&
2403 supername != utf_java_lang_Object) {
2405 new_exception_message(string_java_lang_ClassFormatError,
2406 "Interfaces must have java.lang.Object as superclass");
2408 goto return_exception;
2414 /* This is only allowed for java.lang.Object. */
2416 if (c->name != utf_java_lang_Object) {
2417 *exceptionptr = new_classformaterror(c, "Bad superclass index");
2419 goto return_exception;
2423 /* retrieve interfaces */
2425 if (!check_classbuffer_size(cb, 2))
2426 goto return_exception;
2428 c->interfacescount = suck_u2(cb);
2430 if (!check_classbuffer_size(cb, 2 * c->interfacescount))
2431 goto return_exception;
2433 c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
2434 for (i = 0; i < c->interfacescount; i++) {
2435 /* the classrefs are created later */
2436 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2437 goto return_exception;
2441 if (!check_classbuffer_size(cb, 2))
2442 goto return_exception;
2444 c->fieldscount = suck_u2(cb);
2445 c->fields = GCNEW_UNCOLLECTABLE(fieldinfo, c->fieldscount);
2446 /* c->fields = MNEW(fieldinfo, c->fieldscount); */
2447 for (i = 0; i < c->fieldscount; i++) {
2448 if (!load_field(cb, &(c->fields[i]),descpool))
2449 goto return_exception;
2453 if (!check_classbuffer_size(cb, 2))
2454 goto return_exception;
2456 c->methodscount = suck_u2(cb);
2457 /* c->methods = GCNEW(methodinfo, c->methodscount); */
2458 c->methods = MNEW(methodinfo, c->methodscount);
2459 for (i = 0; i < c->methodscount; i++) {
2460 if (!load_method(cb, &(c->methods[i]),descpool))
2461 goto return_exception;
2464 /* create the class reference table */
2467 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
2469 /* allocate space for the parsed descriptors */
2471 descriptor_pool_alloc_parsed_descriptors(descpool);
2473 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
2475 #if defined(STATISTICS)
2477 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
2478 count_classref_len += classrefsize;
2479 count_parsed_desc_len += descsize;
2483 /* put the classrefs in the constant pool */
2484 for (i = 0; i < c->cpcount; i++) {
2485 if (c->cptags[i] == CONSTANT_Class) {
2486 utf *name = (utf *) c->cpinfos[i];
2487 c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
2491 /* set the super class reference */
2494 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
2496 goto return_exception;
2499 /* set the super interfaces references */
2501 for (i = 0; i < c->interfacescount; i++) {
2502 c->interfaces[i].ref =
2503 descriptor_pool_lookup_classref(descpool,
2504 (utf *) c->interfaces[i].any);
2505 if (!c->interfaces[i].ref)
2506 goto return_exception;
2509 /* parse field descriptors */
2511 for (i = 0; i < c->fieldscount; i++) {
2512 c->fields[i].parseddesc =
2513 descriptor_pool_parse_field_descriptor(descpool,
2514 c->fields[i].descriptor);
2515 if (!c->fields[i].parseddesc)
2516 goto return_exception;
2519 /* parse method descriptors */
2521 for (i = 0; i < c->methodscount; i++) {
2522 methodinfo *m = &c->methods[i];
2524 descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
2525 m->flags, class_get_self_classref(m->class));
2527 goto return_exception;
2529 for (j = 0; j < m->exceptiontablelength; j++) {
2530 if (!m->exceptiontable[j].catchtype.any)
2532 if ((m->exceptiontable[j].catchtype.ref =
2533 descriptor_pool_lookup_classref(descpool,
2534 (utf *) m->exceptiontable[j].catchtype.any)) == NULL)
2535 goto return_exception;
2538 for (j = 0; j < m->thrownexceptionscount; j++) {
2539 if (!m->thrownexceptions[j].any)
2541 if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
2542 (utf *) m->thrownexceptions[j].any)) == NULL)
2543 goto return_exception;
2547 /* parse the loaded descriptors */
2549 for (i = 0; i < c->cpcount; i++) {
2550 constant_FMIref *fmi;
2553 switch (c->cptags[i]) {
2554 case CONSTANT_Fieldref:
2555 fmi = (constant_FMIref *) c->cpinfos[i];
2556 fmi->parseddesc.fd =
2557 descriptor_pool_parse_field_descriptor(descpool,
2559 if (!fmi->parseddesc.fd)
2560 goto return_exception;
2561 index = (int) (size_t) fmi->classref;
2563 (constant_classref *) class_getconstant(c, index,
2566 goto return_exception;
2568 case CONSTANT_Methodref:
2569 case CONSTANT_InterfaceMethodref:
2570 fmi = (constant_FMIref *) c->cpinfos[i];
2571 index = (int) (size_t) fmi->classref;
2573 (constant_classref *) class_getconstant(c, index,
2576 goto return_exception;
2577 fmi->parseddesc.md =
2578 descriptor_pool_parse_method_descriptor(descpool,
2582 if (!fmi->parseddesc.md)
2583 goto return_exception;
2588 /* Check if all fields and methods can be uniquely
2589 * identified by (name,descriptor). */
2592 /* We use a hash table here to avoid making the
2593 * average case quadratic in # of methods, fields.
2595 static int shift = 0;
2597 u2 *next; /* for chaining colliding hash entries */
2603 /* Allocate hashtable */
2604 len = c->methodscount;
2605 if (len < c->fieldscount) len = c->fieldscount;
2607 hashtab = MNEW(u2,(hashlen + len));
2608 next = hashtab + hashlen;
2610 /* Determine bitshift (to get good hash values) */
2620 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2622 for (i = 0; i < c->fieldscount; ++i) {
2623 fieldinfo *fi = c->fields + i;
2625 /* It's ok if we lose bits here */
2626 index = ((((size_t) fi->name) +
2627 ((size_t) fi->descriptor)) >> shift) % hashlen;
2629 if ((old = hashtab[index])) {
2633 if (c->fields[old].name == fi->name &&
2634 c->fields[old].descriptor == fi->descriptor) {
2636 new_classformaterror(c,
2637 "Repetitive field name/signature");
2639 goto return_exception;
2641 } while ((old = next[old]));
2643 hashtab[index] = i + 1;
2647 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2649 for (i = 0; i < c->methodscount; ++i) {
2650 methodinfo *mi = c->methods + i;
2652 /* It's ok if we lose bits here */
2653 index = ((((size_t) mi->name) +
2654 ((size_t) mi->descriptor)) >> shift) % hashlen;
2658 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2659 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2663 if ((old = hashtab[index])) {
2667 if (c->methods[old].name == mi->name &&
2668 c->methods[old].descriptor == mi->descriptor) {
2670 new_classformaterror(c,
2671 "Repetitive method name/signature");
2673 goto return_exception;
2675 } while ((old = next[old]));
2677 hashtab[index] = i + 1;
2680 MFREE(hashtab, u2, (hashlen + len));
2683 #if defined(STATISTICS)
2685 count_class_infos += sizeof(classinfo*) * c->interfacescount;
2686 count_class_infos += sizeof(fieldinfo) * c->fieldscount;
2687 count_class_infos += sizeof(methodinfo) * c->methodscount;
2691 /* load attribute structures */
2693 if (!check_classbuffer_size(cb, 2))
2694 goto return_exception;
2696 if (!load_attributes(cb, suck_u2(cb)))
2697 goto return_exception;
2700 /* Pre java 1.5 version don't check this. This implementation is like
2701 java 1.5 do it: for class file version 45.3 we don't check it, older
2702 versions are checked.
2704 if ((ma == 45 && mi > 3) || ma > 45) {
2705 /* check if all data has been read */
2706 s4 classdata_left = ((cb->data + cb->size) - cb->pos - 1);
2708 if (classdata_left > 0) {
2710 new_classformaterror(c, "Extra bytes at the end of class file");
2711 goto return_exception;
2716 /* release dump area */
2718 dump_release(dumpsize);
2721 log_message_class("Loading done class: ", c);
2726 /* release dump area */
2728 dump_release(dumpsize);
2730 /* an exception has been thrown */
2736 /* load_newly_created_array ****************************************************
2738 Load a newly created array class.
2741 c....................the array class C has been loaded
2742 other classinfo......the array class was found in the class cache,
2744 NULL.................an exception has been thrown
2747 This is an internal function. Do not use it unless you know exactly
2750 Use one of the load_class_... functions for general array class loading.
2752 *******************************************************************************/
2754 classinfo *load_newly_created_array(classinfo *c, java_objectheader *loader)
2756 classinfo *comp = NULL;
2758 methoddesc *clonedesc;
2759 constant_classref *classrefs;
2764 text = c->name->text;
2765 namelen = c->name->blength;
2767 /* Check array class name */
2769 if (namelen < 2 || text[0] != '[') {
2770 *exceptionptr = new_noclassdeffounderror(c->name);
2774 /* Check the element type */
2778 /* c is an array of arrays. We have to create the component class. */
2780 u = utf_new(text + 1, namelen - 1);
2781 if (!(comp = load_class_from_classloader(u, loader)))
2784 LOADER_ASSERT(comp->loaded);
2790 /* the array's flags are that of the component class */
2791 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2792 c->classloader = comp->classloader;
2796 /* c is an array of objects. */
2798 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2799 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
2800 *exceptionptr = new_noclassdeffounderror(c->name);
2804 u = utf_new(text + 2, namelen - 3);
2806 if (!(comp = load_class_from_classloader(u, loader)))
2809 LOADER_ASSERT(comp->loaded);
2815 /* the array's flags are that of the component class */
2816 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2817 c->classloader = comp->classloader;
2821 /* c is an array of a primitive type */
2823 /* check for cases like `[II' */
2825 *exceptionptr = new_noclassdeffounderror(c->name);
2829 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2830 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2831 c->classloader = NULL;
2834 LOADER_ASSERT(class_java_lang_Object);
2835 LOADER_ASSERT(class_java_lang_Cloneable);
2836 LOADER_ASSERT(class_java_io_Serializable);
2838 /* setup the array class */
2840 c->super.cls = class_java_lang_Object;
2842 c->interfacescount = 2;
2843 c->interfaces = MNEW(classref_or_classinfo, 2);
2848 tc = class_java_lang_Cloneable;
2849 LOADER_ASSERT(tc->loaded);
2850 list_addfirst(&unlinkedclasses, tc);
2851 c->interfaces[0].cls = tc;
2853 tc = class_java_io_Serializable;
2854 LOADER_ASSERT(tc->loaded);
2855 list_addfirst(&unlinkedclasses, tc);
2856 c->interfaces[1].cls = tc;
2859 c->interfaces[0].cls = class_java_lang_Cloneable;
2860 c->interfaces[1].cls = class_java_io_Serializable;
2863 c->methodscount = 1;
2864 c->methods = MNEW(methodinfo, c->methodscount);
2866 classrefs = MNEW(constant_classref, 2);
2867 CLASSREF_INIT(classrefs[0], c, c->name);
2868 CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2870 /* create descriptor for clone method */
2871 /* we need one paramslot which is reserved for the 'this' parameter */
2872 clonedesc = NEW(methoddesc);
2873 clonedesc->returntype.type = TYPE_ADDRESS;
2874 clonedesc->returntype.classref = classrefs + 1;
2875 clonedesc->returntype.arraydim = 0;
2876 /* initialize params to "empty", add real params below in
2877 descriptor_params_from_paramtypes */
2878 clonedesc->paramcount = 0;
2879 clonedesc->paramslots = 0;
2880 clonedesc->paramtypes[0].classref = classrefs + 0;
2882 /* create methodinfo */
2885 MSET(clone, 0, methodinfo, 1);
2887 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
2888 initObjectLock(&clone->header);
2891 /* if you delete the ACC_NATIVE below, set clone->maxlocals=1 (interpreter
2893 clone->flags = ACC_PUBLIC | ACC_NATIVE;
2894 clone->name = utf_clone;
2895 clone->descriptor = utf_void__java_lang_Object;
2896 clone->parseddesc = clonedesc;
2898 clone->monoPoly = MONO;
2900 /* parse the descriptor to get the register allocation */
2902 if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2906 codegen_createnativestub((functionptr) &builtin_clone_array, clone);
2908 /* XXX: field: length? */
2910 /* array classes are not loaded from class files */
2913 c->parseddescs = (u1 *) clonedesc;
2914 c->parseddescsize = sizeof(methodinfo);
2915 c->classrefs = classrefs;
2916 c->classrefcount = 1;
2918 /* insert class into the loaded class cache */
2919 /* XXX free classinfo if NULL returned? */
2921 return classcache_store(loader, c, true);
2925 /* loader_close ****************************************************************
2927 Frees all resources.
2929 *******************************************************************************/
2931 void loader_close(void)
2938 * These are local overrides for various environment variables in Emacs.
2939 * Please do not remove this and leave it at the end of the file, where
2940 * Emacs will automagically detect them.
2941 * ---------------------------------------------------------------------
2944 * indent-tabs-mode: t