1 /* 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 1936 2005-02-10 11:04:10Z 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 "vm/exceptions.h"
60 #include "vm/builtin.h"
61 #include "vm/global.h"
62 #include "vm/loader.h"
63 #include "vm/options.h"
64 #include "vm/statistics.h"
65 #include "vm/stringlocal.h"
66 #include "vm/tables.h"
69 # include "vm/unzip.h"
72 #include "vm/jit/asmpart.h"
73 #include "vm/jit/jit.h"
80 /* global variables ***********************************************************/
82 static s4 interfaceindex; /* sequential numbering of interfaces */
86 vftbl_t *pseudo_class_Arraystub_vftbl = NULL;
89 /********************************************************************
90 list of classpath entries (either filesystem directories or
92 ********************************************************************/
94 static classpath_info *classpath_entries = NULL;
97 /******************************************************************************
99 structure for primitive classes: contains the class for wrapping the
100 primitive type, the primitive class, the name of the class for wrapping,
101 the one character type signature and the name of the primitive class
103 ******************************************************************************/
105 /* CAUTION: Don't change the order of the types. This table is indexed
106 * by the ARRAYTYPE_ constants (expcept ARRAYTYPE_OBJECT).
108 primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = {
109 { NULL, NULL, "java/lang/Integer", 'I', "int" , "[I", NULL, NULL },
110 { NULL, NULL, "java/lang/Long", 'J', "long" , "[J", NULL, NULL },
111 { NULL, NULL, "java/lang/Float", 'F', "float" , "[F", NULL, NULL },
112 { NULL, NULL, "java/lang/Double", 'D', "double" , "[D", NULL, NULL },
113 { NULL, NULL, "java/lang/Byte", 'B', "byte" , "[B", NULL, NULL },
114 { NULL, NULL, "java/lang/Character", 'C', "char" , "[C", NULL, NULL },
115 { NULL, NULL, "java/lang/Short", 'S', "short" , "[S", NULL, NULL },
116 { NULL, NULL, "java/lang/Boolean", 'Z', "boolean" , "[Z", NULL, NULL },
117 { NULL, NULL, "java/lang/Void", 'V', "void" , NULL, NULL, NULL }
121 /************* functions for reading classdata *********************************
123 getting classdata in blocks of variable size
124 (8,16,32,64-bit integer or float)
126 *******************************************************************************/
128 /* check_classbuffer_size ******************************************************
130 assert that at least <len> bytes are left to read
131 <len> is limited to the range of non-negative s4 values
133 *******************************************************************************/
135 static inline bool check_classbuffer_size(classbuffer *cb, s4 len)
137 if (len < 0 || ((cb->data + cb->size) - cb->pos - 1) < len) {
139 new_classformaterror((cb)->class, "Truncated class file");
148 /* suck_nbytes *****************************************************************
150 transfer block of classfile data into a buffer
152 *******************************************************************************/
154 inline void suck_nbytes(u1 *buffer, classbuffer *cb, s4 len)
156 memcpy(buffer, cb->pos + 1, len);
161 /* skip_nbytes ****************************************************************
163 skip block of classfile data
165 *******************************************************************************/
167 inline void skip_nbytes(classbuffer *cb, s4 len)
173 inline u1 suck_u1(classbuffer *cb)
179 inline u2 suck_u2(classbuffer *cb)
183 return ((u2) a << 8) + (u2) b;
187 inline u4 suck_u4(classbuffer *cb)
193 return ((u4) a << 24) + ((u4) b << 16) + ((u4) c << 8) + (u4) d;
197 /* get u8 from classfile data */
198 static u8 suck_u8(classbuffer *cb)
204 return (hi << 32) + lo;
207 v.high = suck_u4(cb);
214 #define suck_s8(a) (s8) suck_u8((a))
215 #define suck_s2(a) (s2) suck_u2((a))
216 #define suck_s4(a) (s4) suck_u4((a))
217 #define suck_s1(a) (s1) suck_u1((a))
220 /* get float from classfile data */
221 static float suck_float(classbuffer *cb)
229 for (i = 0; i < 4; i++)
230 buffer[3 - i] = suck_u1(cb);
232 memcpy((u1*) (&f), buffer, 4);
234 suck_nbytes((u1*) (&f), cb, 4);
237 if (sizeof(float) != 4) {
238 *exceptionptr = new_exception_message(string_java_lang_InternalError,
239 "Incompatible float-format");
241 /* XXX should we exit in such a case? */
242 throw_exception_exit();
249 /* get double from classfile data */
250 static double suck_double(classbuffer *cb)
258 for (i = 0; i < 8; i++)
259 buffer[7 - i] = suck_u1(cb);
261 memcpy((u1*) (&d), buffer, 8);
263 suck_nbytes((u1*) (&d), cb, 8);
266 if (sizeof(double) != 8) {
267 *exceptionptr = new_exception_message(string_java_lang_InternalError,
268 "Incompatible double-format");
270 /* XXX should we exit in such a case? */
271 throw_exception_exit();
278 /************************** function suck_init *********************************
280 called once at startup, sets the searchpath for the classfiles
282 *******************************************************************************/
284 void suck_init(char *classpath)
292 classpath_info *lastcpi;
294 /* search for last classpath entry (only if there already some) */
296 if ((lastcpi = classpath_entries)) {
297 while (lastcpi->next)
298 lastcpi = lastcpi->next;
301 for (start = classpath; (*start) != '\0';) {
303 /* search for ':' delimiter to get the end of the current entry */
304 for (end = start; ((*end) != '\0') && ((*end) != ':'); end++);
308 filenamelen = end - start;
310 if (filenamelen > 3) {
311 if (strncasecmp(end - 3, "zip", 3) == 0 ||
312 strncasecmp(end - 3, "jar", 3) == 0) {
317 /* allocate memory for filename and fill it */
319 filename = MNEW(char, filenamelen + 2); /* 2 = "/\0" */
320 strncpy(filename, start, filenamelen);
321 filename[filenamelen + 1] = '\0';
325 #if defined(USE_ZLIB)
326 unzFile uf = unzOpen(filename);
329 cpi = NEW(classpath_info);
330 cpi->type = CLASSPATH_ARCHIVE;
333 cpi->pd = NULL; /* ProtectionDomain not set yet */
334 cpi->path = filename;
338 throw_cacao_exception_exit(string_java_lang_InternalError,
339 "zip/jar files not supported");
343 cpi = NEW(classpath_info);
344 cpi->type = CLASSPATH_PATH;
346 cpi->pd = NULL; /* ProtectionDomain not set yet */
348 if (filename[filenamelen - 1] != '/') {/*PERHAPS THIS SHOULD BE READ FROM A GLOBAL CONFIGURATION */
349 filename[filenamelen] = '/';
350 filename[filenamelen + 1] = '\0';
354 cpi->path = filename;
355 cpi->pathlen = filenamelen;
358 /* attach current classpath entry */
361 if (!classpath_entries)
362 classpath_entries = cpi;
370 /* goto next classpath entry, skip ':' delimiter */
382 void create_all_classes()
386 for (cpi = classpath_entries; cpi != 0; cpi = cpi->next) {
387 #if defined(USE_ZLIB)
388 if (cpi->type == CLASSPATH_ARCHIVE) {
392 s = (unz_s *) cpi->uf;
393 ce = s->cacao_dir_list;
396 (void) class_new(ce->name);
402 #if defined(USE_ZLIB)
409 /************************** function suck_start ********************************
411 returns true if classbuffer is already loaded or a file for the
412 specified class has succussfully been read in. All directories of
413 the searchpath are used to find the classfile (<classname>.class).
414 Returns false if no classfile is found and writes an error message.
416 *******************************************************************************/
418 classbuffer *suck_start(classinfo *c)
432 /* initialize return value */
437 filenamelen = utf_strlen(c->name) + 7; /* 7 = ".class\0" */
438 filename = MNEW(char, filenamelen);
440 utf_sprint(filename, c->name);
441 strcat(filename, ".class");
443 /* walk through all classpath entries */
445 for (cpi = classpath_entries; cpi != NULL && cb == NULL; cpi = cpi->next) {
446 #if defined(USE_ZLIB)
447 if (cpi->type == CLASSPATH_ARCHIVE) {
449 #if defined(USE_THREADS)
450 /* enter a monitor on zip/jar archives */
452 builtin_monitorenter((java_objectheader *) cpi);
455 if (cacao_locate(cpi->uf, c->name) == UNZ_OK) {
456 unz_file_info file_info;
458 if (unzGetCurrentFileInfo(cpi->uf, &file_info, filename,
459 sizeof(filename), NULL, 0, NULL, 0) == UNZ_OK) {
460 if (unzOpenCurrentFile(cpi->uf) == UNZ_OK) {
461 cb = NEW(classbuffer);
463 cb->size = file_info.uncompressed_size;
464 cb->data = MNEW(u1, cb->size);
465 cb->pos = cb->data - 1;
466 /* We need this later in use_class_as_object to set a */
467 /* correct ProtectionDomain and CodeSource. */
468 c->pd = (struct java_security_ProtectionDomain *) cpi;
470 len = unzReadCurrentFile(cpi->uf, cb->data, cb->size);
472 if (len != cb->size) {
474 log_text("Error while unzipping");
481 log_text("Error while opening file in archive");
485 log_text("Error while retrieving fileinfo");
488 unzCloseCurrentFile(cpi->uf);
490 #if defined(USE_THREADS)
491 /* leave the monitor */
493 builtin_monitorexit((java_objectheader *) cpi);
497 #endif /* USE_ZLIB */
499 path = MNEW(char, cpi->pathlen + filenamelen + 1);
500 strcpy(path, cpi->path);
501 strcat(path, filename);
503 classfile = fopen(path, "r");
505 if (classfile) { /* file exists */
506 if (!stat(path, &buffer)) { /* read classfile data */
507 cb = NEW(classbuffer);
509 cb->size = buffer.st_size;
510 cb->data = MNEW(u1, cb->size);
511 cb->pos = cb->data - 1;
512 /* We need this later in use_class_as_object to set a */
513 /* correct ProtectionDomain and CodeSource. */
514 c->pd = (struct java_security_ProtectionDomain *) cpi;
516 /* read class data */
517 len = fread(cb->data, 1, cb->size, classfile);
519 if (len != buffer.st_size) {
521 /* if (ferror(classfile)) { */
530 MFREE(path, char, cpi->pathlen + filenamelen + 1);
531 #if defined(USE_ZLIB)
538 dolog("Warning: Can not open class file '%s'", filename);
541 MFREE(filename, char, filenamelen);
547 /************************** function suck_stop *********************************
549 frees memory for buffer with classfile data.
550 Caution: this function may only be called if buffer has been allocated
551 by suck_start with reading a file
553 *******************************************************************************/
555 void suck_stop(classbuffer *cb)
559 MFREE(cb->data, u1, cb->size);
560 FREE(cb, classbuffer);
564 /******************************************************************************/
565 /******************* Some support functions ***********************************/
566 /******************************************************************************/
568 void fprintflags (FILE *fp, u2 f)
570 if ( f & ACC_PUBLIC ) fprintf (fp," PUBLIC");
571 if ( f & ACC_PRIVATE ) fprintf (fp," PRIVATE");
572 if ( f & ACC_PROTECTED ) fprintf (fp," PROTECTED");
573 if ( f & ACC_STATIC ) fprintf (fp," STATIC");
574 if ( f & ACC_FINAL ) fprintf (fp," FINAL");
575 if ( f & ACC_SYNCHRONIZED ) fprintf (fp," SYNCHRONIZED");
576 if ( f & ACC_VOLATILE ) fprintf (fp," VOLATILE");
577 if ( f & ACC_TRANSIENT ) fprintf (fp," TRANSIENT");
578 if ( f & ACC_NATIVE ) fprintf (fp," NATIVE");
579 if ( f & ACC_INTERFACE ) fprintf (fp," INTERFACE");
580 if ( f & ACC_ABSTRACT ) fprintf (fp," ABSTRACT");
584 /********** internal function: printflags (only for debugging) ***************/
586 void printflags(u2 f)
588 if ( f & ACC_PUBLIC ) printf (" PUBLIC");
589 if ( f & ACC_PRIVATE ) printf (" PRIVATE");
590 if ( f & ACC_PROTECTED ) printf (" PROTECTED");
591 if ( f & ACC_STATIC ) printf (" STATIC");
592 if ( f & ACC_FINAL ) printf (" FINAL");
593 if ( f & ACC_SYNCHRONIZED ) printf (" SYNCHRONIZED");
594 if ( f & ACC_VOLATILE ) printf (" VOLATILE");
595 if ( f & ACC_TRANSIENT ) printf (" TRANSIENT");
596 if ( f & ACC_NATIVE ) printf (" NATIVE");
597 if ( f & ACC_INTERFACE ) printf (" INTERFACE");
598 if ( f & ACC_ABSTRACT ) printf (" ABSTRACT");
602 /********************** Function: skipattributebody ****************************
604 skips an attribute after the 16 bit reference to attribute_name has already
607 *******************************************************************************/
609 static bool skipattributebody(classbuffer *cb)
613 if (!check_classbuffer_size(cb, 4))
618 if (!check_classbuffer_size(cb, len))
621 skip_nbytes(cb, len);
627 /************************* Function: skipattributes ****************************
629 skips num attribute structures
631 *******************************************************************************/
633 static bool skipattributes(classbuffer *cb, u4 num)
638 for (i = 0; i < num; i++) {
639 if (!check_classbuffer_size(cb, 2 + 4))
645 if (!check_classbuffer_size(cb, len))
648 skip_nbytes(cb, len);
655 /******************** function:: class_getconstant *****************************
657 retrieves the value at position 'pos' of the constantpool of a class
658 if the type of the value is other than 'ctype' the system is stopped
660 *******************************************************************************/
662 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
664 /* check index and type of constantpool entry */
665 /* (pos == 0 is caught by type comparison) */
666 if (pos >= c->cpcount || c->cptags[pos] != ctype) {
667 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
671 return c->cpinfos[pos];
675 /******************** function: innerclass_getconstant ************************
677 like class_getconstant, but if cptags is ZERO null is returned
679 *******************************************************************************/
681 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
683 /* invalid position in constantpool */
684 if (pos >= c->cpcount) {
685 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
689 /* constantpool entry of type 0 */
693 /* check type of constantpool entry */
694 if (c->cptags[pos] != ctype) {
695 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
699 return c->cpinfos[pos];
703 /********************* Function: class_constanttype ****************************
705 Determines the type of a class entry in the ConstantPool
707 *******************************************************************************/
709 u4 class_constanttype(classinfo *c, u4 pos)
711 if (pos <= 0 || pos >= c->cpcount) {
712 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
716 return c->cptags[pos];
720 /************************ function: attribute_load ****************************
722 read attributes from classfile
724 *******************************************************************************/
726 static bool attribute_load(classbuffer *cb, classinfo *c, u4 num)
731 for (i = 0; i < num; i++) {
732 /* retrieve attribute name */
733 if (!check_classbuffer_size(cb, 2))
736 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
739 if (aname == utf_InnerClasses) {
740 /* innerclasses attribute */
743 new_classformaterror(c, "Multiple InnerClasses attributes");
747 if (!check_classbuffer_size(cb, 4 + 2))
750 /* skip attribute length */
753 /* number of records */
754 c->innerclasscount = suck_u2(cb);
756 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
759 /* allocate memory for innerclass structure */
760 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
762 for (j = 0; j < c->innerclasscount; j++) {
763 /* The innerclass structure contains a class with an encoded
764 name, its defining scope, its simple name and a bitmask of
765 the access flags. If an inner class is not a member, its
766 outer_class is NULL, if a class is anonymous, its name is
769 innerclassinfo *info = c->innerclass + j;
772 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
774 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
776 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
777 info->flags = suck_u2(cb);
780 } else if (aname == utf_SourceFile) {
781 if (!check_classbuffer_size(cb, 4 + 2))
784 if (suck_u4(cb) != 2) {
786 new_classformaterror(c, "Wrong size for VALUE attribute");
792 new_classformaterror(c, "Multiple SourceFile attributes");
796 if (!(c->sourcefile = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
800 /* unknown attribute */
801 if (!skipattributebody(cb))
810 /******************* function: checkfielddescriptor ****************************
812 checks whether a field-descriptor is valid and aborts otherwise
813 all referenced classes are inserted into the list of unloaded classes
815 *******************************************************************************/
817 static void checkfielddescriptor (char *utf_ptr, char *end_pos)
819 class_from_descriptor(utf_ptr,end_pos,NULL,
821 | CLASSLOAD_NULLPRIMITIVE
823 | CLASSLOAD_CHECKEND);
825 /* XXX use the following if -noverify */
827 char *tstart; /* pointer to start of classname */
829 char *start = utf_ptr;
831 switch (*utf_ptr++) {
845 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
846 panic ("Ill formed descriptor");
850 panic ("Ill formed descriptor");
853 /* exceeding characters */
854 if (utf_ptr!=end_pos) panic ("descriptor has exceeding chars");
859 /******************* function checkmethoddescriptor ****************************
861 checks whether a method-descriptor is valid and aborts otherwise.
862 All referenced classes are inserted into the list of unloaded classes.
864 The number of arguments is returned. A long or double argument is counted
867 *******************************************************************************/
869 static int checkmethoddescriptor(classinfo *c, utf *descriptor)
871 char *utf_ptr; /* current position in utf text */
872 char *end_pos; /* points behind utf string */
873 s4 argcount = 0; /* number of arguments */
875 utf_ptr = descriptor->text;
876 end_pos = utf_end(descriptor);
878 /* method descriptor must start with parenthesis */
879 if (utf_ptr == end_pos || *utf_ptr++ != '(')
880 panic ("Missing '(' in method descriptor");
882 /* check arguments */
883 while (utf_ptr != end_pos && *utf_ptr != ')') {
884 /* We cannot count the this argument here because
885 * we don't know if the method is static. */
886 if (*utf_ptr == 'J' || *utf_ptr == 'D')
890 class_from_descriptor(utf_ptr,end_pos,&utf_ptr,
892 | CLASSLOAD_NULLPRIMITIVE
896 if (utf_ptr == end_pos)
897 panic("Missing ')' in method descriptor");
899 utf_ptr++; /* skip ')' */
901 class_from_descriptor(utf_ptr,
905 CLASSLOAD_NULLPRIMITIVE |
908 if (argcount > 255) {
910 new_classformaterror(c, "Too many arguments in signature");
917 /* XXX use the following if -noverify */
919 /* check arguments */
920 while ((c = *utf_ptr++) != ')') {
937 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
938 panic ("Ill formed method descriptor");
942 panic ("Ill formed methodtype-descriptor");
946 /* check returntype */
948 /* returntype void */
949 if ((utf_ptr+1) != end_pos) panic ("Method-descriptor has exceeding chars");
952 /* treat as field-descriptor */
953 checkfielddescriptor (utf_ptr,end_pos);
958 /***************** Function: print_arraydescriptor ****************************
960 Debugging helper for displaying an arraydescriptor
962 *******************************************************************************/
964 void print_arraydescriptor(FILE *file, arraydescriptor *desc)
967 fprintf(file, "<NULL>");
972 if (desc->componentvftbl) {
973 if (desc->componentvftbl->class)
974 utf_fprint(file, desc->componentvftbl->class->name);
976 fprintf(file, "<no classinfo>");
982 if (desc->elementvftbl) {
983 if (desc->elementvftbl->class)
984 utf_fprint(file, desc->elementvftbl->class->name);
986 fprintf(file, "<no classinfo>");
990 fprintf(file, ",%d,%d,%d,%d}", desc->arraytype, desc->dimension,
991 desc->dataoffset, desc->componentsize);
995 /******************************************************************************/
996 /************************** Functions for fields ****************************/
997 /******************************************************************************/
1000 /* field_load ******************************************************************
1002 Load everything about a class field from the class file and fill a
1003 'fieldinfo' structure. For static fields, space in the data segment is
1006 *******************************************************************************/
1008 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
1010 static bool field_load(classbuffer *cb, classinfo *c, fieldinfo *f)
1014 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
1017 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1020 f->flags = suck_u2(cb);
1022 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1026 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1032 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<')
1033 panic("Field with invalid name");
1035 /* check flag consistency */
1036 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
1038 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
1039 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
1041 new_classformaterror(c,
1042 "Illegal field modifiers: 0x%X",
1047 if (c->flags & ACC_INTERFACE) {
1048 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
1049 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
1050 f->flags & ACC_TRANSIENT) {
1052 new_classformaterror(c,
1053 "Illegal field modifiers: 0x%X",
1059 /* check descriptor */
1060 checkfielddescriptor(f->descriptor->text, utf_end(f->descriptor));
1063 f->type = jtype = desc_to_type(f->descriptor); /* data type */
1064 f->offset = 0; /* offset from start of object */
1069 case TYPE_INT: f->value.i = 0; break;
1070 case TYPE_FLOAT: f->value.f = 0.0; break;
1071 case TYPE_DOUBLE: f->value.d = 0.0; break;
1072 case TYPE_ADDRESS: f->value.a = NULL; break;
1075 f->value.l = 0; break;
1077 f->value.l.low = 0; f->value.l.high = 0; break;
1081 /* read attributes */
1082 if (!check_classbuffer_size(cb, 2))
1085 attrnum = suck_u2(cb);
1086 for (i = 0; i < attrnum; i++) {
1087 if (!check_classbuffer_size(cb, 2))
1090 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1093 if (u == utf_ConstantValue) {
1094 if (!check_classbuffer_size(cb, 4 + 2))
1097 /* check attribute length */
1098 if (suck_u4(cb) != 2) {
1100 new_classformaterror(c, "Wrong size for VALUE attribute");
1104 /* constant value attribute */
1105 if (pindex != field_load_NOVALUE) {
1107 new_classformaterror(c,
1108 "Multiple ConstantValue attributes");
1112 /* index of value in constantpool */
1113 pindex = suck_u2(cb);
1115 /* initialize field with value from constantpool */
1118 constant_integer *ci;
1120 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
1123 f->value.i = ci->value;
1130 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
1133 f->value.l = cl->value;
1140 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
1143 f->value.f = cf->value;
1148 constant_double *cd;
1150 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
1153 f->value.d = cd->value;
1158 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
1161 /* create javastring from compressed utf8-string */
1162 f->value.a = literalstring_new(u);
1166 log_text("Invalid Constant - Type");
1170 /* unknown attribute */
1171 if (!skipattributebody(cb))
1176 /* everything was ok */
1182 /********************** function: field_free **********************************/
1184 static void field_free(fieldinfo *f)
1190 /**************** Function: field_display (debugging only) ********************/
1192 void field_display(fieldinfo *f)
1195 printflags(f->flags);
1197 utf_display(f->name);
1199 utf_display(f->descriptor);
1200 printf(" offset: %ld\n", (long int) (f->offset));
1204 /******************************************************************************/
1205 /************************* Functions for methods ******************************/
1206 /******************************************************************************/
1209 /* method_load *****************************************************************
1211 Loads a method from the class file and fills an existing 'methodinfo'
1212 structure. For native methods, the function pointer field is set to the
1213 real function pointer, for JavaVM methods a pointer to the compiler is used
1216 *******************************************************************************/
1218 static bool method_load(classbuffer *cb, classinfo *c, methodinfo *m)
1226 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1227 initObjectLock(&m->header);
1232 count_all_methods++;
1235 m->thrownexceptionscount = 0;
1236 m->linenumbercount = 0;
1239 m->nativelyoverloaded = false;
1241 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1244 m->flags = suck_u2(cb);
1246 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1250 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1255 if (!is_valid_name_utf(m->name))
1256 panic("Method with invalid name");
1258 if (m->name->text[0] == '<'
1259 && m->name != utf_init && m->name != utf_clinit)
1260 panic("Method with invalid special name");
1263 argcount = checkmethoddescriptor(c, m->descriptor);
1265 if (!(m->flags & ACC_STATIC))
1266 argcount++; /* count the 'this' argument */
1269 if (argcount > 255) {
1271 new_classformaterror(c, "Too many arguments in signature");
1275 /* check flag consistency */
1276 if (m->name != utf_clinit) {
1277 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1279 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1281 new_classformaterror(c,
1282 "Illegal method modifiers: 0x%X",
1287 if (m->flags & ACC_ABSTRACT) {
1288 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1289 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1291 new_classformaterror(c,
1292 "Illegal method modifiers: 0x%X",
1298 if (c->flags & ACC_INTERFACE) {
1299 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1301 new_classformaterror(c,
1302 "Illegal method modifiers: 0x%X",
1308 if (m->name == utf_init) {
1309 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1310 ACC_NATIVE | ACC_ABSTRACT))
1311 panic("Instance initialization method has invalid flags set");
1317 m->basicblockcount = 0;
1318 m->basicblocks = NULL;
1319 m->basicblockindex = NULL;
1320 m->instructioncount = 0;
1321 m->instructions = NULL;
1324 m->exceptiontable = NULL;
1325 m->stubroutine = NULL;
1327 m->entrypoint = NULL;
1328 m->methodUsed = NOTUSED;
1331 m->subRedefsUsed = 0;
1335 if (!(m->flags & ACC_NATIVE)) {
1336 m->stubroutine = createcompilerstub(m);
1339 /*if (useinlining) {
1340 log_text("creating native stub:");
1343 functionptr f = native_findfunction(c->name, m->name, m->descriptor,
1344 (m->flags & ACC_STATIC) != 0);
1345 #ifdef STATIC_CLASSPATH
1349 m->stubroutine = createnativestub(f, m);
1353 if (!check_classbuffer_size(cb, 2))
1356 attrnum = suck_u2(cb);
1357 for (i = 0; i < attrnum; i++) {
1360 if (!check_classbuffer_size(cb, 2))
1363 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1366 if (aname == utf_Code) {
1367 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1369 new_classformaterror(c,
1370 "Code attribute in native or abstract methods");
1377 new_classformaterror(c, "Multiple Code attributes");
1382 if (!check_classbuffer_size(cb, 4 + 2 + 2))
1386 m->maxstack = suck_u2(cb);
1387 m->maxlocals = suck_u2(cb);
1389 if (m->maxlocals < argcount) {
1391 new_classformaterror(c, "Arguments can't fit into locals");
1396 if (!check_classbuffer_size(cb, 4))
1399 m->jcodelength = suck_u4(cb);
1401 if (m->jcodelength == 0) {
1403 new_classformaterror(c, "Code of a method has length 0");
1408 if (m->jcodelength > 65535) {
1410 new_classformaterror(c,
1411 "Code of a method longer than 65535 bytes");
1416 if (!check_classbuffer_size(cb, m->jcodelength))
1419 m->jcode = MNEW(u1, m->jcodelength);
1420 suck_nbytes(m->jcode, cb, m->jcodelength);
1422 if (!check_classbuffer_size(cb, 2))
1425 m->exceptiontablelength = suck_u2(cb);
1426 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->exceptiontablelength))
1429 m->exceptiontable = MNEW(exceptiontable, m->exceptiontablelength);
1431 #if defined(STATISTICS)
1433 count_vmcode_len += m->jcodelength + 18;
1434 count_extable_len += 8 * m->exceptiontablelength;
1438 for (j = 0; j < m->exceptiontablelength; j++) {
1440 m->exceptiontable[j].startpc = suck_u2(cb);
1441 m->exceptiontable[j].endpc = suck_u2(cb);
1442 m->exceptiontable[j].handlerpc = suck_u2(cb);
1446 m->exceptiontable[j].catchtype = NULL;
1449 if (!(m->exceptiontable[j].catchtype =
1450 class_getconstant(c, idx, CONSTANT_Class)))
1455 if (!check_classbuffer_size(cb, 2))
1458 codeattrnum = suck_u2(cb);
1460 for (; codeattrnum > 0; codeattrnum--) {
1463 if (!check_classbuffer_size(cb, 2))
1466 if (!(caname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1469 if (caname == utf_LineNumberTable) {
1472 if (!check_classbuffer_size(cb, 4 + 2))
1476 m->linenumbercount = suck_u2(cb);
1478 if (!check_classbuffer_size(cb,
1479 (2 + 2) * m->linenumbercount))
1482 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1484 for (lncid = 0; lncid < m->linenumbercount; lncid++) {
1485 m->linenumbers[lncid].start_pc = suck_u2(cb);
1486 m->linenumbers[lncid].line_number = suck_u2(cb);
1490 if (!skipattributes(cb, codeattrnum))
1496 if (!skipattributebody(cb))
1501 } else if (aname == utf_Exceptions) {
1504 if (m->thrownexceptions) {
1506 new_classformaterror(c, "Multiple Exceptions attributes");
1510 if (!check_classbuffer_size(cb, 4 + 2))
1513 suck_u4(cb); /* length */
1514 m->thrownexceptionscount = suck_u2(cb);
1516 if (!check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1519 m->thrownexceptions = MNEW(classinfo*, m->thrownexceptionscount);
1521 for (j = 0; j < m->thrownexceptionscount; j++) {
1522 if (!((m->thrownexceptions)[j] =
1523 class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1528 if (!skipattributebody(cb))
1533 if (!m->jcode && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1534 *exceptionptr = new_classformaterror(c, "Missing Code attribute");
1539 /* everything was ok */
1545 /********************* Function: method_free ***********************************
1547 frees all memory that was allocated for this method
1549 *******************************************************************************/
1551 static void method_free(methodinfo *m)
1554 MFREE(m->jcode, u1, m->jcodelength);
1556 if (m->exceptiontable)
1557 MFREE(m->exceptiontable, exceptiontable, m->exceptiontablelength);
1560 CFREE(m->mcode, m->mcodelength);
1562 if (m->stubroutine) {
1563 if (m->flags & ACC_NATIVE) {
1564 removenativestub(m->stubroutine);
1567 removecompilerstub(m->stubroutine);
1573 /************** Function: method_display (debugging only) **************/
1575 void method_display(methodinfo *m)
1578 printflags(m->flags);
1580 utf_display(m->name);
1582 utf_display(m->descriptor);
1586 /************** Function: method_display_w_class (debugging only) **************/
1588 void method_display_w_class(methodinfo *m)
1590 printflags(m->class->flags);
1591 printf(" "); fflush(stdout);
1592 utf_display(m->class->name);
1593 printf(".");fflush(stdout);
1596 printflags(m->flags);
1597 printf(" "); fflush(stdout);
1598 utf_display(m->name);
1599 printf(" "); fflush(stdout);
1600 utf_display(m->descriptor);
1601 printf("\n"); fflush(stdout);
1604 /************** Function: method_display_flags_last (debugging only) **************/
1606 void method_display_flags_last(methodinfo *m)
1609 utf_display(m->name);
1611 utf_display(m->descriptor);
1613 printflags(m->flags);
1618 /******************** Function: method_canoverwrite ****************************
1620 Check if m and old are identical with respect to type and name. This means
1621 that old can be overwritten with m.
1623 *******************************************************************************/
1625 static bool method_canoverwrite(methodinfo *m, methodinfo *old)
1627 if (m->name != old->name) return false;
1628 if (m->descriptor != old->descriptor) return false;
1629 if (m->flags & ACC_STATIC) return false;
1634 /******************** function: class_loadcpool ********************************
1636 loads the constantpool of a class,
1637 the entries are transformed into a simpler format
1638 by resolving references
1639 (a detailed overview of the compact structures can be found in global.h)
1641 *******************************************************************************/
1643 static bool class_loadcpool(classbuffer *cb, classinfo *c)
1646 /* The following structures are used to save information which cannot be
1647 processed during the first pass. After the complete constantpool has
1648 been traversed the references can be resolved.
1649 (only in specific order) */
1651 /* CONSTANT_Class entries */
1652 typedef struct forward_class {
1653 struct forward_class *next;
1658 /* CONSTANT_String */
1659 typedef struct forward_string {
1660 struct forward_string *next;
1665 /* CONSTANT_NameAndType */
1666 typedef struct forward_nameandtype {
1667 struct forward_nameandtype *next;
1671 } forward_nameandtype;
1673 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
1674 typedef struct forward_fieldmethint {
1675 struct forward_fieldmethint *next;
1679 u2 nameandtype_index;
1680 } forward_fieldmethint;
1685 forward_class *forward_classes = NULL;
1686 forward_string *forward_strings = NULL;
1687 forward_nameandtype *forward_nameandtypes = NULL;
1688 forward_fieldmethint *forward_fieldmethints = NULL;
1691 forward_string *nfs;
1692 forward_nameandtype *nfn;
1693 forward_fieldmethint *nff;
1699 /* number of entries in the constant_pool table plus one */
1700 if (!check_classbuffer_size(cb, 2))
1703 cpcount = c->cpcount = suck_u2(cb);
1705 /* allocate memory */
1706 cptags = c->cptags = MNEW(u1, cpcount);
1707 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
1710 *exceptionptr = new_classformaterror(c, "Illegal constant pool size");
1714 #if defined(STATISTICS)
1716 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
1719 /* initialize constantpool */
1720 for (idx = 0; idx < cpcount; idx++) {
1721 cptags[idx] = CONSTANT_UNUSED;
1722 cpinfos[idx] = NULL;
1726 /******* first pass *******/
1727 /* entries which cannot be resolved now are written into
1728 temporary structures and traversed again later */
1731 while (idx < cpcount) {
1734 /* get constant type */
1735 if (!check_classbuffer_size(cb, 1))
1741 case CONSTANT_Class:
1742 nfc = NEW(forward_class);
1744 nfc->next = forward_classes;
1745 forward_classes = nfc;
1747 nfc->thisindex = idx;
1748 /* reference to CONSTANT_NameAndType */
1749 if (!check_classbuffer_size(cb, 2))
1752 nfc->name_index = suck_u2(cb);
1757 case CONSTANT_String:
1758 nfs = NEW(forward_string);
1760 nfs->next = forward_strings;
1761 forward_strings = nfs;
1763 nfs->thisindex = idx;
1765 /* reference to CONSTANT_Utf8_info with string characters */
1766 if (!check_classbuffer_size(cb, 2))
1769 nfs->string_index = suck_u2(cb);
1774 case CONSTANT_NameAndType:
1775 nfn = NEW(forward_nameandtype);
1777 nfn->next = forward_nameandtypes;
1778 forward_nameandtypes = nfn;
1780 nfn->thisindex = idx;
1782 if (!check_classbuffer_size(cb, 2 + 2))
1785 /* reference to CONSTANT_Utf8_info containing simple name */
1786 nfn->name_index = suck_u2(cb);
1788 /* reference to CONSTANT_Utf8_info containing field or method
1790 nfn->sig_index = suck_u2(cb);
1795 case CONSTANT_Fieldref:
1796 case CONSTANT_Methodref:
1797 case CONSTANT_InterfaceMethodref:
1798 nff = NEW(forward_fieldmethint);
1800 nff->next = forward_fieldmethints;
1801 forward_fieldmethints = nff;
1803 nff->thisindex = idx;
1807 if (!check_classbuffer_size(cb, 2 + 2))
1810 /* class or interface type that contains the declaration of the
1812 nff->class_index = suck_u2(cb);
1814 /* name and descriptor of the field or method */
1815 nff->nameandtype_index = suck_u2(cb);
1820 case CONSTANT_Integer: {
1821 constant_integer *ci = NEW(constant_integer);
1823 #if defined(STATISTICS)
1825 count_const_pool_len += sizeof(constant_integer);
1828 if (!check_classbuffer_size(cb, 4))
1831 ci->value = suck_s4(cb);
1832 cptags[idx] = CONSTANT_Integer;
1839 case CONSTANT_Float: {
1840 constant_float *cf = NEW(constant_float);
1842 #if defined(STATISTICS)
1844 count_const_pool_len += sizeof(constant_float);
1847 if (!check_classbuffer_size(cb, 4))
1850 cf->value = suck_float(cb);
1851 cptags[idx] = CONSTANT_Float;
1858 case CONSTANT_Long: {
1859 constant_long *cl = NEW(constant_long);
1861 #if defined(STATISTICS)
1863 count_const_pool_len += sizeof(constant_long);
1866 if (!check_classbuffer_size(cb, 8))
1869 cl->value = suck_s8(cb);
1870 cptags[idx] = CONSTANT_Long;
1873 if (idx > cpcount) {
1875 new_classformaterror(c, "Invalid constant pool entry");
1881 case CONSTANT_Double: {
1882 constant_double *cd = NEW(constant_double);
1884 #if defined(STATISTICS)
1886 count_const_pool_len += sizeof(constant_double);
1889 if (!check_classbuffer_size(cb, 8))
1892 cd->value = suck_double(cb);
1893 cptags[idx] = CONSTANT_Double;
1896 if (idx > cpcount) {
1898 new_classformaterror(c, "Invalid constant pool entry");
1904 case CONSTANT_Utf8: {
1907 /* number of bytes in the bytes array (not string-length) */
1908 if (!check_classbuffer_size(cb, 2))
1911 length = suck_u2(cb);
1912 cptags[idx] = CONSTANT_Utf8;
1914 /* validate the string */
1915 if (!check_classbuffer_size(cb, length))
1919 !is_valid_utf((char *) (cb->pos + 1),
1920 (char *) (cb->pos + 1 + length))) {
1921 dolog("Invalid UTF-8 string (constant pool index %d)",idx);
1922 panic("Invalid UTF-8 string");
1924 /* insert utf-string into the utf-symboltable */
1925 cpinfos[idx] = utf_new_intern((char *) (cb->pos + 1), length);
1927 /* skip bytes of the string (buffer size check above) */
1928 skip_nbytes(cb, length);
1935 new_classformaterror(c, "Illegal constant pool type");
1941 /* resolve entries in temporary structures */
1943 while (forward_classes) {
1945 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
1947 if (opt_verify && !is_valid_name_utf(name))
1948 panic("Class reference with invalid name");
1950 cptags[forward_classes->thisindex] = CONSTANT_Class;
1951 /* retrieve class from class-table */
1954 tc = class_new_intern(name);
1956 if (!class_load(tc))
1959 /* link the class later, because we cannot link the class currently
1961 list_addfirst(&unlinkedclasses, tc);
1963 cpinfos[forward_classes->thisindex] = tc;
1966 cpinfos[forward_classes->thisindex] = class_new(name);
1969 nfc = forward_classes;
1970 forward_classes = forward_classes->next;
1971 FREE(nfc, forward_class);
1974 while (forward_strings) {
1976 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
1978 /* resolve utf-string */
1979 cptags[forward_strings->thisindex] = CONSTANT_String;
1980 cpinfos[forward_strings->thisindex] = text;
1982 nfs = forward_strings;
1983 forward_strings = forward_strings->next;
1984 FREE(nfs, forward_string);
1987 while (forward_nameandtypes) {
1988 constant_nameandtype *cn = NEW(constant_nameandtype);
1990 #if defined(STATISTICS)
1992 count_const_pool_len += sizeof(constant_nameandtype);
1995 /* resolve simple name and descriptor */
1996 cn->name = class_getconstant(c,
1997 forward_nameandtypes->name_index,
2000 cn->descriptor = class_getconstant(c,
2001 forward_nameandtypes->sig_index,
2006 if (!is_valid_name_utf(cn->name)) {
2008 new_exception_utfmessage(string_java_lang_InternalError,
2013 /* disallow referencing <clinit> among others */
2014 if (cn->name->text[0] == '<' && cn->name != utf_init) {
2016 new_exception_utfmessage(string_java_lang_InternalError,
2022 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
2023 cpinfos[forward_nameandtypes->thisindex] = cn;
2025 nfn = forward_nameandtypes;
2026 forward_nameandtypes = forward_nameandtypes->next;
2027 FREE(nfn, forward_nameandtype);
2030 while (forward_fieldmethints) {
2031 constant_nameandtype *nat;
2032 constant_FMIref *fmi = NEW(constant_FMIref);
2034 #if defined(STATISTICS)
2036 count_const_pool_len += sizeof(constant_FMIref);
2038 /* resolve simple name and descriptor */
2039 nat = class_getconstant(c,
2040 forward_fieldmethints->nameandtype_index,
2041 CONSTANT_NameAndType);
2043 fmi->class = class_getconstant(c,
2044 forward_fieldmethints->class_index,
2046 fmi->name = nat->name;
2047 fmi->descriptor = nat->descriptor;
2049 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
2050 cpinfos[forward_fieldmethints->thisindex] = fmi;
2052 switch (forward_fieldmethints->tag) {
2053 case CONSTANT_Fieldref: /* check validity of descriptor */
2054 checkfielddescriptor(fmi->descriptor->text,
2055 utf_end(fmi->descriptor));
2057 case CONSTANT_InterfaceMethodref:
2058 case CONSTANT_Methodref: /* check validity of descriptor */
2059 checkmethoddescriptor(c, fmi->descriptor);
2063 nff = forward_fieldmethints;
2064 forward_fieldmethints = forward_fieldmethints->next;
2065 FREE(nff, forward_fieldmethint);
2068 /* everything was ok */
2074 /********************** Function: class_load ***********************************
2076 Loads everything interesting about a class from the class file. The
2077 'classinfo' structure must have been allocated previously.
2079 The super class and the interfaces implemented by this class need not be
2080 loaded. The link is set later by the function 'class_link'.
2082 The loaded class is removed from the list 'unloadedclasses' and added to
2083 the list 'unlinkedclasses'.
2085 *******************************************************************************/
2087 classinfo *class_load_intern(classbuffer *cb);
2089 classinfo *class_load(classinfo *c)
2094 #if defined(USE_THREADS)
2095 /* enter a monitor on the class */
2097 builtin_monitorenter((java_objectheader *) c);
2100 /* maybe the class is already loaded */
2102 #if defined(USE_THREADS)
2103 builtin_monitorexit((java_objectheader *) c);
2111 if (getcompilingtime)
2112 compilingtime_stop();
2115 loadingtime_start();
2117 /* load classdata, throw exception on error */
2119 if ((cb = suck_start(c)) == NULL) {
2120 /* this means, the classpath was not set properly */
2121 if (c->name == utf_java_lang_Object)
2122 throw_cacao_exception_exit(string_java_lang_NoClassDefFoundError,
2123 "java/lang/Object");
2126 new_exception_utfmessage(string_java_lang_NoClassDefFoundError,
2129 #if defined(USE_THREADS)
2130 builtin_monitorexit((java_objectheader *) c);
2136 /* call the internal function */
2137 r = class_load_intern(cb);
2139 /* if return value is NULL, we had a problem and the class is not loaded */
2143 /* now free the allocated memory, otherwise we could ran into a DOS */
2155 if (getcompilingtime)
2156 compilingtime_start();
2158 #if defined(USE_THREADS)
2159 /* leave the monitor */
2161 builtin_monitorexit((java_objectheader *) c);
2168 classinfo *class_load_intern(classbuffer *cb)
2174 char msg[MAXLOGTEXT]; /* maybe we get an exception */
2176 /* get the classbuffer's class */
2179 /* maybe the class is already loaded */
2183 #if defined(STATISTICS)
2185 count_class_loads++;
2188 /* output for debugging purposes */
2190 log_message_class("Loading class: ", c);
2192 /* class is somewhat loaded */
2195 if (!check_classbuffer_size(cb, 4 + 2 + 2))
2198 /* check signature */
2199 if (suck_u4(cb) != MAGIC) {
2200 *exceptionptr = new_classformaterror(c, "Bad magic number");
2209 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
2211 new_unsupportedclassversionerror(c,
2212 "Unsupported major.minor version %d.%d",
2218 /* load the constant pool */
2219 if (!class_loadcpool(cb, c))
2223 c->erroneous_state = 0;
2224 c->initializing_thread = 0;
2226 c->classUsed = NOTUSED; /* not used initially CO-RT */
2230 if (!check_classbuffer_size(cb, 2))
2233 c->flags = suck_u2(cb);
2234 /*if (!(c->flags & ACC_PUBLIC)) { log_text("CLASS NOT PUBLIC"); } JOWENN*/
2236 /* check ACC flags consistency */
2237 if (c->flags & ACC_INTERFACE) {
2238 if (!(c->flags & ACC_ABSTRACT)) {
2239 /* We work around this because interfaces in JDK 1.1 are
2240 * not declared abstract. */
2242 c->flags |= ACC_ABSTRACT;
2243 /* panic("Interface class not declared abstract"); */
2246 if (c->flags & ACC_FINAL) {
2248 new_classformaterror(c,
2249 "Illegal class modifiers: 0x%X", c->flags);
2254 if (c->flags & ACC_SUPER) {
2255 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
2259 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
2261 new_classformaterror(c, "Illegal class modifiers: 0x%X", c->flags);
2266 if (!check_classbuffer_size(cb, 2 + 2))
2271 if (!(tc = class_getconstant(c, i, CONSTANT_Class)))
2275 utf_sprint(msg, c->name);
2276 sprintf(msg + strlen(msg), " (wrong name: ");
2277 utf_sprint(msg + strlen(msg), tc->name);
2278 sprintf(msg + strlen(msg), ")");
2281 new_exception_message(string_java_lang_NoClassDefFoundError, msg);
2286 /* retrieve superclass */
2287 if ((i = suck_u2(cb))) {
2288 if (!(c->super = class_getconstant(c, i, CONSTANT_Class)))
2291 /* java.lang.Object may not have a super class. */
2292 if (c->name == utf_java_lang_Object) {
2294 new_exception_message(string_java_lang_ClassFormatError,
2295 "java.lang.Object with superclass");
2300 /* Interfaces must have java.lang.Object as super class. */
2301 if ((c->flags & ACC_INTERFACE) &&
2302 c->super->name != utf_java_lang_Object) {
2304 new_exception_message(string_java_lang_ClassFormatError,
2305 "Interfaces must have java.lang.Object as superclass");
2313 /* This is only allowed for java.lang.Object. */
2314 if (c->name != utf_java_lang_Object) {
2315 *exceptionptr = new_classformaterror(c, "Bad superclass index");
2321 /* retrieve interfaces */
2322 if (!check_classbuffer_size(cb, 2))
2325 c->interfacescount = suck_u2(cb);
2327 if (!check_classbuffer_size(cb, 2 * c->interfacescount))
2330 c->interfaces = MNEW(classinfo*, c->interfacescount);
2331 for (i = 0; i < c->interfacescount; i++) {
2332 if (!(c->interfaces[i] = class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2337 if (!check_classbuffer_size(cb, 2))
2340 c->fieldscount = suck_u2(cb);
2341 c->fields = GCNEW(fieldinfo, c->fieldscount);
2342 /* c->fields = MNEW(fieldinfo, c->fieldscount); */
2343 for (i = 0; i < c->fieldscount; i++) {
2344 if (!field_load(cb, c, &(c->fields[i])))
2349 if (!check_classbuffer_size(cb, 2))
2352 c->methodscount = suck_u2(cb);
2353 c->methods = GCNEW(methodinfo, c->methodscount);
2354 /* c->methods = MNEW(methodinfo, c->methodscount); */
2355 for (i = 0; i < c->methodscount; i++) {
2356 if (!method_load(cb, c, &(c->methods[i])))
2360 /* Check if all fields and methods can be uniquely
2361 * identified by (name,descriptor). */
2363 /* We use a hash table here to avoid making the
2364 * average case quadratic in # of methods, fields.
2366 static int shift = 0;
2368 u2 *next; /* for chaining colliding hash entries */
2374 /* Allocate hashtable */
2375 len = c->methodscount;
2376 if (len < c->fieldscount) len = c->fieldscount;
2378 hashtab = MNEW(u2,(hashlen + len));
2379 next = hashtab + hashlen;
2381 /* Determine bitshift (to get good hash values) */
2391 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2393 for (i = 0; i < c->fieldscount; ++i) {
2394 fieldinfo *fi = c->fields + i;
2396 /* It's ok if we lose bits here */
2397 index = ((((size_t) fi->name) +
2398 ((size_t) fi->descriptor)) >> shift) % hashlen;
2400 if ((old = hashtab[index])) {
2404 if (c->fields[old].name == fi->name &&
2405 c->fields[old].descriptor == fi->descriptor) {
2407 new_classformaterror(c,
2408 "Repetitive field name/signature");
2412 } while ((old = next[old]));
2414 hashtab[index] = i + 1;
2418 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2420 for (i = 0; i < c->methodscount; ++i) {
2421 methodinfo *mi = c->methods + i;
2423 /* It's ok if we lose bits here */
2424 index = ((((size_t) mi->name) +
2425 ((size_t) mi->descriptor)) >> shift) % hashlen;
2429 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2430 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2434 if ((old = hashtab[index])) {
2438 if (c->methods[old].name == mi->name &&
2439 c->methods[old].descriptor == mi->descriptor) {
2441 new_classformaterror(c,
2442 "Repetitive method name/signature");
2446 } while ((old = next[old]));
2448 hashtab[index] = i + 1;
2451 MFREE(hashtab, u2, (hashlen + len));
2454 #if defined(STATISTICS)
2456 count_class_infos += sizeof(classinfo*) * c->interfacescount;
2457 count_class_infos += sizeof(fieldinfo) * c->fieldscount;
2458 count_class_infos += sizeof(methodinfo) * c->methodscount;
2462 /* load attribute structures */
2463 if (!check_classbuffer_size(cb, 2))
2466 if (!attribute_load(cb, c, suck_u2(cb)))
2470 /* Pre java 1.5 version don't check this. This implementation is like
2471 java 1.5 do it: for class file version 45.3 we don't check it, older
2472 versions are checked.
2474 if ((ma == 45 && mi > 3) || ma > 45) {
2475 /* check if all data has been read */
2476 s4 classdata_left = ((cb->data + cb->size) - cb->pos - 1);
2478 if (classdata_left > 0) {
2480 new_classformaterror(c, "Extra bytes at the end of class file");
2487 log_message_class("Loading done class: ", c);
2494 /************** internal Function: class_highestinterface **********************
2496 Used by the function class_link to determine the amount of memory needed
2497 for the interface table.
2499 *******************************************************************************/
2501 static s4 class_highestinterface(classinfo *c)
2506 /* check for ACC_INTERFACE bit already done in class_link_intern */
2509 for (i = 0; i < c->interfacescount; i++) {
2510 s4 h2 = class_highestinterface(c->interfaces[i]);
2518 /* class_addinterface **********************************************************
2520 Is needed by class_link for adding a VTBL to a class. All interfaces
2521 implemented by ic are added as well.
2523 *******************************************************************************/
2525 static void class_addinterface(classinfo *c, classinfo *ic)
2529 vftbl_t *v = c->vftbl;
2531 if (i >= v->interfacetablelength)
2532 panic ("Inernal error: interfacetable overflow");
2534 if (v->interfacetable[-i])
2537 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
2538 v->interfacevftbllength[i] = 1;
2539 v->interfacetable[-i] = MNEW(methodptr, 1);
2540 v->interfacetable[-i][0] = NULL;
2543 v->interfacevftbllength[i] = ic->methodscount;
2544 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
2546 #if defined(STATISTICS)
2548 count_vftbl_len += sizeof(methodptr) *
2549 (ic->methodscount + (ic->methodscount == 0));
2552 for (j = 0; j < ic->methodscount; j++) {
2555 for (m = 0; m < sc->methodscount; m++) {
2556 methodinfo *mi = &(sc->methods[m]);
2557 if (method_canoverwrite(mi, &(ic->methods[j]))) {
2558 v->interfacetable[-i][j] = v->table[mi->vftblindex];
2569 for (j = 0; j < ic->interfacescount; j++)
2570 class_addinterface(c, ic->interfaces[j]);
2574 /******************* Function: class_new_array *********************************
2576 This function is called by class_new to setup an array class.
2578 *******************************************************************************/
2580 void class_new_array(classinfo *c)
2582 classinfo *comp = NULL;
2586 /* Check array class name */
2587 namelen = c->name->blength;
2588 if (namelen < 2 || c->name->text[0] != '[')
2589 panic("Invalid array class name");
2591 /* Check the component type */
2592 switch (c->name->text[1]) {
2594 /* c is an array of arrays. We have to create the component class. */
2596 comp = class_new_intern(utf_new_intern(c->name->text + 1,
2599 list_addfirst(&unlinkedclasses, comp);
2602 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2607 /* c is an array of objects. */
2608 if (namelen < 4 || c->name->text[namelen - 1] != ';')
2609 panic("Invalid array class name");
2612 comp = class_new_intern(utf_new_intern(c->name->text + 2,
2615 list_addfirst(&unlinkedclasses, comp);
2618 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2623 /* Setup the array class */
2624 c->super = class_java_lang_Object;
2625 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2627 c->interfacescount = 2;
2628 c->interfaces = MNEW(classinfo*, 2);
2633 tc = class_new_intern(utf_new_char("java/lang/Cloneable"));
2635 list_addfirst(&unlinkedclasses, tc);
2636 c->interfaces[0] = tc;
2638 tc = class_new_intern(utf_new_char("java/io/Serializable"));
2640 list_addfirst(&unlinkedclasses, tc);
2641 c->interfaces[1] = tc;
2644 c->interfaces[0] = class_new(utf_new_char("java/lang/Cloneable"));
2645 c->interfaces[1] = class_new(utf_new_char("java/io/Serializable"));
2648 c->methodscount = 1;
2649 c->methods = MNEW(methodinfo, c->methodscount);
2652 memset(clone, 0, sizeof(methodinfo));
2653 clone->flags = ACC_PUBLIC;
2654 clone->name = utf_new_char("clone");
2655 clone->descriptor = utf_new_char("()Ljava/lang/Object;");
2657 clone->stubroutine = createnativestub((functionptr) &builtin_clone_array, clone);
2658 clone->monoPoly = MONO;
2660 /* XXX: field: length? */
2662 /* array classes are not loaded from class files */
2667 /****************** Function: class_link_array *********************************
2669 This function is called by class_link to create the
2670 arraydescriptor for an array class.
2672 This function returns NULL if the array cannot be linked because
2673 the component type has not been linked yet.
2675 *******************************************************************************/
2677 static arraydescriptor *class_link_array(classinfo *c)
2679 classinfo *comp = NULL;
2680 s4 namelen = c->name->blength;
2681 arraydescriptor *desc;
2684 /* Check the component type */
2685 switch (c->name->text[1]) {
2687 /* c is an array of arrays. */
2688 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2690 panic("Could not find component array class.");
2694 /* c is an array of objects. */
2695 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2697 panic("Could not find component class.");
2701 /* If the component type has not been linked, link it now */
2702 if (comp && !comp->linked) {
2704 if (!class_load(comp))
2707 if (!class_link(comp))
2711 /* Allocate the arraydescriptor */
2712 desc = NEW(arraydescriptor);
2715 /* c is an array of references */
2716 desc->arraytype = ARRAYTYPE_OBJECT;
2717 desc->componentsize = sizeof(void*);
2718 desc->dataoffset = OFFSET(java_objectarray, data);
2720 compvftbl = comp->vftbl;
2722 panic("Component class has no vftbl");
2723 desc->componentvftbl = compvftbl;
2725 if (compvftbl->arraydesc) {
2726 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
2727 if (compvftbl->arraydesc->dimension >= 255)
2728 panic("Creating array of dimension >255");
2729 desc->dimension = compvftbl->arraydesc->dimension + 1;
2730 desc->elementtype = compvftbl->arraydesc->elementtype;
2733 desc->elementvftbl = compvftbl;
2734 desc->dimension = 1;
2735 desc->elementtype = ARRAYTYPE_OBJECT;
2739 /* c is an array of a primitive type */
2740 switch (c->name->text[1]) {
2742 desc->arraytype = ARRAYTYPE_BOOLEAN;
2743 desc->dataoffset = OFFSET(java_booleanarray,data);
2744 desc->componentsize = sizeof(u1);
2748 desc->arraytype = ARRAYTYPE_BYTE;
2749 desc->dataoffset = OFFSET(java_bytearray,data);
2750 desc->componentsize = sizeof(u1);
2754 desc->arraytype = ARRAYTYPE_CHAR;
2755 desc->dataoffset = OFFSET(java_chararray,data);
2756 desc->componentsize = sizeof(u2);
2760 desc->arraytype = ARRAYTYPE_DOUBLE;
2761 desc->dataoffset = OFFSET(java_doublearray,data);
2762 desc->componentsize = sizeof(double);
2766 desc->arraytype = ARRAYTYPE_FLOAT;
2767 desc->dataoffset = OFFSET(java_floatarray,data);
2768 desc->componentsize = sizeof(float);
2772 desc->arraytype = ARRAYTYPE_INT;
2773 desc->dataoffset = OFFSET(java_intarray,data);
2774 desc->componentsize = sizeof(s4);
2778 desc->arraytype = ARRAYTYPE_LONG;
2779 desc->dataoffset = OFFSET(java_longarray,data);
2780 desc->componentsize = sizeof(s8);
2784 desc->arraytype = ARRAYTYPE_SHORT;
2785 desc->dataoffset = OFFSET(java_shortarray,data);
2786 desc->componentsize = sizeof(s2);
2790 panic("Invalid array class name");
2793 desc->componentvftbl = NULL;
2794 desc->elementvftbl = NULL;
2795 desc->dimension = 1;
2796 desc->elementtype = desc->arraytype;
2803 /********************** Function: class_link ***********************************
2805 Tries to link a class. The function calculates the length in bytes that
2806 an instance of this class requires as well as the VTBL for methods and
2809 *******************************************************************************/
2811 static classinfo *class_link_intern(classinfo *c);
2813 classinfo *class_link(classinfo *c)
2817 #if defined(USE_THREADS)
2818 /* enter a monitor on the class */
2820 builtin_monitorenter((java_objectheader *) c);
2823 /* maybe the class is already linked */
2825 #if defined(USE_THREADS)
2826 builtin_monitorexit((java_objectheader *) c);
2834 if (getcompilingtime)
2835 compilingtime_stop();
2838 loadingtime_start();
2840 /* call the internal function */
2841 r = class_link_intern(c);
2843 /* if return value is NULL, we had a problem and the class is not linked */
2852 if (getcompilingtime)
2853 compilingtime_start();
2855 #if defined(USE_THREADS)
2856 /* leave the monitor */
2858 builtin_monitorexit((java_objectheader *) c);
2865 static classinfo *class_link_intern(classinfo *c)
2867 s4 supervftbllength; /* vftbllegnth of super class */
2868 s4 vftbllength; /* vftbllength of current class */
2869 s4 interfacetablelength; /* interface table length */
2870 classinfo *super; /* super class */
2871 classinfo *tc; /* temporary class variable */
2872 vftbl_t *v; /* vftbl of current class */
2873 s4 i; /* interface/method/field counter */
2874 arraydescriptor *arraydesc; /* descriptor for array classes */
2876 /* maybe the class is already linked */
2880 /* maybe the class is not loaded */
2886 log_message_class("Linking class: ", c);
2888 /* ok, this class is somewhat linked */
2893 /* check interfaces */
2895 for (i = 0; i < c->interfacescount; i++) {
2896 tc = c->interfaces[i];
2898 /* detect circularity */
2901 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2907 if (!class_load(tc))
2910 if (!(tc->flags & ACC_INTERFACE)) {
2912 new_exception_message(string_java_lang_IncompatibleClassChangeError,
2913 "Implementing class");
2918 if (!class_link(tc))
2922 /* check super class */
2926 if (super == NULL) { /* class java.lang.Object */
2928 c->classUsed = USED; /* Object class is always used CO-RT*/
2930 c->instancesize = sizeof(java_objectheader);
2932 vftbllength = supervftbllength = 0;
2934 c->finalizer = NULL;
2937 /* detect circularity */
2940 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2946 if (!class_load(super))
2949 if (super->flags & ACC_INTERFACE) {
2950 /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
2951 panic("Interface specified as super class");
2954 /* Don't allow extending final classes */
2955 if (super->flags & ACC_FINAL) {
2957 new_exception_message(string_java_lang_VerifyError,
2958 "Cannot inherit from final class");
2963 if (!class_link(super))
2966 /* handle array classes */
2967 if (c->name->text[0] == '[')
2968 if (!(arraydesc = class_link_array(c)))
2971 if (c->flags & ACC_INTERFACE)
2972 c->index = interfaceindex++;
2974 c->index = super->index + 1;
2976 c->instancesize = super->instancesize;
2978 vftbllength = supervftbllength = super->vftbl->vftbllength;
2980 c->finalizer = super->finalizer;
2983 /* compute vftbl length */
2985 for (i = 0; i < c->methodscount; i++) {
2986 methodinfo *m = &(c->methods[i]);
2988 if (!(m->flags & ACC_STATIC)) { /* is instance method */
2993 for (j = 0; j < tc->methodscount; j++) {
2994 if (method_canoverwrite(m, &(tc->methods[j]))) {
2995 if (tc->methods[j].flags & ACC_PRIVATE)
2996 goto notfoundvftblindex;
2998 if (tc->methods[j].flags & ACC_FINAL) {
2999 /* class a overrides final method . */
3001 new_exception(string_java_lang_VerifyError);
3004 m->vftblindex = tc->methods[j].vftblindex;
3005 goto foundvftblindex;
3011 m->vftblindex = (vftbllength++);
3017 #if defined(STATISTICS)
3020 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
3023 /* compute interfacetable length */
3025 interfacetablelength = 0;
3028 for (i = 0; i < tc->interfacescount; i++) {
3029 s4 h = class_highestinterface(tc->interfaces[i]) + 1;
3030 if (h > interfacetablelength)
3031 interfacetablelength = h;
3036 /* allocate virtual function table */
3038 v = (vftbl_t*) mem_alloc(sizeof(vftbl_t) + sizeof(methodptr) *
3039 (vftbllength - 1) + sizeof(methodptr*) *
3040 (interfacetablelength - (interfacetablelength > 0)));
3041 v = (vftbl_t*) (((methodptr*) v) + (interfacetablelength - 1) *
3042 (interfacetablelength > 1));
3043 c->header.vftbl = c->vftbl = v;
3045 v->vftbllength = vftbllength;
3046 v->interfacetablelength = interfacetablelength;
3047 v->arraydesc = arraydesc;
3049 /* store interface index in vftbl */
3050 if (c->flags & ACC_INTERFACE)
3051 v->baseval = -(c->index);
3053 /* copy virtual function table of super class */
3055 for (i = 0; i < supervftbllength; i++)
3056 v->table[i] = super->vftbl->table[i];
3058 /* add method stubs into virtual function table */
3060 for (i = 0; i < c->methodscount; i++) {
3061 methodinfo *m = &(c->methods[i]);
3062 if (!(m->flags & ACC_STATIC)) {
3063 v->table[m->vftblindex] = m->stubroutine;
3067 /* compute instance size and offset of each field */
3069 for (i = 0; i < c->fieldscount; i++) {
3071 fieldinfo *f = &(c->fields[i]);
3073 if (!(f->flags & ACC_STATIC)) {
3074 dsize = desc_typesize(f->descriptor);
3075 c->instancesize = ALIGN(c->instancesize, dsize);
3076 f->offset = c->instancesize;
3077 c->instancesize += dsize;
3081 /* initialize interfacetable and interfacevftbllength */
3083 v->interfacevftbllength = MNEW(s4, interfacetablelength);
3085 #if defined(STATISTICS)
3087 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
3090 for (i = 0; i < interfacetablelength; i++) {
3091 v->interfacevftbllength[i] = 0;
3092 v->interfacetable[-i] = NULL;
3095 /* add interfaces */
3097 for (tc = c; tc != NULL; tc = tc->super)
3098 for (i = 0; i < tc->interfacescount; i++)
3099 class_addinterface(c, tc->interfaces[i]);
3101 /* add finalizer method (not for java.lang.Object) */
3106 fi = class_findmethod(c, utf_finalize, utf_void__void);
3109 if (!(fi->flags & ACC_STATIC))
3115 loader_compute_subclasses(c);
3118 log_message_class("Linking done class: ", c);
3120 /* just return c to show that we didn't had a problem */
3126 /******************* Function: class_freepool **********************************
3128 Frees all resources used by this classes Constant Pool.
3130 *******************************************************************************/
3132 static void class_freecpool(classinfo *c)
3138 if (c->cptags && c->cpinfos) {
3139 for (idx = 0; idx < c->cpcount; idx++) {
3140 tag = c->cptags[idx];
3141 info = c->cpinfos[idx];
3145 case CONSTANT_Fieldref:
3146 case CONSTANT_Methodref:
3147 case CONSTANT_InterfaceMethodref:
3148 FREE(info, constant_FMIref);
3150 case CONSTANT_Integer:
3151 FREE(info, constant_integer);
3153 case CONSTANT_Float:
3154 FREE(info, constant_float);
3157 FREE(info, constant_long);
3159 case CONSTANT_Double:
3160 FREE(info, constant_double);
3162 case CONSTANT_NameAndType:
3163 FREE(info, constant_nameandtype);
3171 MFREE(c->cptags, u1, c->cpcount);
3174 MFREE(c->cpinfos, voidptr, c->cpcount);
3178 /*********************** Function: class_free **********************************
3180 Frees all resources used by the class.
3182 *******************************************************************************/
3184 void class_free(classinfo *c)
3192 MFREE(c->interfaces, classinfo*, c->interfacescount);
3195 for (i = 0; i < c->fieldscount; i++)
3196 field_free(&(c->fields[i]));
3197 /* MFREE(c->fields, fieldinfo, c->fieldscount); */
3201 for (i = 0; i < c->methodscount; i++)
3202 method_free(&(c->methods[i]));
3203 /* MFREE(c->methods, methodinfo, c->methodscount); */
3206 if ((v = c->vftbl) != NULL) {
3208 mem_free(v->arraydesc,sizeof(arraydescriptor));
3210 for (i = 0; i < v->interfacetablelength; i++) {
3211 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
3213 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
3215 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
3216 sizeof(methodptr*) * (v->interfacetablelength -
3217 (v->interfacetablelength > 0));
3218 v = (vftbl_t*) (((methodptr*) v) - (v->interfacetablelength - 1) *
3219 (v->interfacetablelength > 1));
3224 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
3226 /* if (c->classvftbl)
3227 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
3233 /************************* Function: class_findfield ***************************
3235 Searches a 'classinfo' structure for a field having the given name and
3238 *******************************************************************************/
3240 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
3244 for (i = 0; i < c->fieldscount; i++) {
3245 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
3246 return &(c->fields[i]);
3249 panic("Can not find field given in CONSTANT_Fieldref");
3251 /* keep compiler happy */
3256 /****************** Function: class_resolvefield_int ***************************
3258 This is an internally used helper function. Do not use this directly.
3260 Tries to resolve a field having the given name and type.
3261 If the field cannot be resolved, NULL is returned.
3263 *******************************************************************************/
3265 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
3270 /* search for field in class c */
3271 for (i = 0; i < c->fieldscount; i++) {
3272 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
3273 return &(c->fields[i]);
3277 /* try superinterfaces recursively */
3278 for (i = 0; i < c->interfacescount; ++i) {
3279 fi = class_resolvefield_int(c->interfaces[i], name, desc);
3284 /* try superclass */
3286 return class_resolvefield_int(c->super, name, desc);
3293 /********************* Function: class_resolvefield ***************************
3295 Resolves a reference from REFERER to a field with NAME and DESC in class C.
3297 If the field cannot be resolved the return value is NULL. If EXCEPT is
3298 true *exceptionptr is set, too.
3300 *******************************************************************************/
3302 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
3303 classinfo *referer, bool except)
3307 /* XXX resolve class c */
3308 /* XXX check access from REFERER to C */
3310 fi = class_resolvefield_int(c, name, desc);
3315 new_exception_utfmessage(string_java_lang_NoSuchFieldError,
3321 /* XXX check access rights */
3327 /************************* Function: class_findmethod **************************
3329 Searches a 'classinfo' structure for a method having the given name and
3330 type and returns the index in the class info structure.
3331 If type is NULL, it is ignored.
3333 *******************************************************************************/
3335 s4 class_findmethodIndex(classinfo *c, utf *name, utf *desc)
3339 for (i = 0; i < c->methodscount; i++) {
3341 /* utf_display_classname(c->name);printf("."); */
3342 /* utf_display(c->methods[i].name);printf("."); */
3343 /* utf_display(c->methods[i].descriptor); */
3346 if ((c->methods[i].name == name) && ((desc == NULL) ||
3347 (c->methods[i].descriptor == desc))) {
3356 /************************* Function: class_findmethod **************************
3358 Searches a 'classinfo' structure for a method having the given name and
3360 If type is NULL, it is ignored.
3362 *******************************************************************************/
3364 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
3366 s4 idx = class_findmethodIndex(c, name, desc);
3371 return &(c->methods[idx]);
3375 /*********************** Function: class_fetchmethod **************************
3377 like class_findmethod, but aborts with an error if the method is not found
3379 *******************************************************************************/
3381 methodinfo *class_fetchmethod(classinfo *c, utf *name, utf *desc)
3385 mi = class_findmethod(c, name, desc);
3388 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3389 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3390 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3391 panic("Method not found");
3398 /*********************** Function: class_findmethod_w**************************
3400 like class_findmethod, but logs a warning if the method is not found
3402 *******************************************************************************/
3404 methodinfo *class_findmethod_w(classinfo *c, utf *name, utf *desc, char *from)
3407 mi = class_findmethod(c, name, desc);
3410 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3411 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3412 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3414 if ( c->flags & ACC_PUBLIC ) log_plain(" PUBLIC ");
3415 if ( c->flags & ACC_PRIVATE ) log_plain(" PRIVATE ");
3416 if ( c->flags & ACC_PROTECTED ) log_plain(" PROTECTED ");
3417 if ( c->flags & ACC_STATIC ) log_plain(" STATIC ");
3418 if ( c->flags & ACC_FINAL ) log_plain(" FINAL ");
3419 if ( c->flags & ACC_SYNCHRONIZED ) log_plain(" SYNCHRONIZED ");
3420 if ( c->flags & ACC_VOLATILE ) log_plain(" VOLATILE ");
3421 if ( c->flags & ACC_TRANSIENT ) log_plain(" TRANSIENT ");
3422 if ( c->flags & ACC_NATIVE ) log_plain(" NATIVE ");
3423 if ( c->flags & ACC_INTERFACE ) log_plain(" INTERFACE ");
3424 if ( c->flags & ACC_ABSTRACT ) log_plain(" ABSTRACT ");
3427 log_plain(" : WARNING: Method not found");log_nl( );
3434 /************************* Function: class_findmethod_approx ******************
3436 like class_findmethod but ignores the return value when comparing the
3439 *******************************************************************************/
3441 methodinfo *class_findmethod_approx(classinfo *c, utf *name, utf *desc)
3445 for (i = 0; i < c->methodscount; i++) {
3446 if (c->methods[i].name == name) {
3447 utf *meth_descr = c->methods[i].descriptor;
3451 return &(c->methods[i]);
3453 if (desc->blength <= meth_descr->blength) {
3454 /* current position in utf text */
3455 char *desc_utf_ptr = desc->text;
3456 char *meth_utf_ptr = meth_descr->text;
3457 /* points behind utf strings */
3458 char *desc_end = utf_end(desc);
3459 char *meth_end = utf_end(meth_descr);
3462 /* compare argument types */
3463 while (desc_utf_ptr < desc_end && meth_utf_ptr < meth_end) {
3465 if ((ch = *desc_utf_ptr++) != (*meth_utf_ptr++))
3466 break; /* no match */
3469 return &(c->methods[i]); /* all parameter types equal */
3479 /***************** Function: class_resolvemethod_approx ***********************
3481 Searches a class and every super class for a method (without paying
3482 attention to the return value)
3484 *******************************************************************************/
3486 methodinfo *class_resolvemethod_approx(classinfo *c, utf *name, utf *desc)
3489 /* search for method (ignore returntype) */
3490 methodinfo *m = class_findmethod_approx(c, name, desc);
3493 /* search superclass */
3501 /************************* Function: class_resolvemethod ***********************
3503 Searches a class and every super class for a method.
3505 *******************************************************************************/
3507 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
3509 /*log_text("Trying to resolve a method");
3510 utf_display(c->name);
3512 utf_display(desc);*/
3515 /*log_text("Looking in:");
3516 utf_display(c->name);*/
3517 methodinfo *m = class_findmethod(c, name, desc);
3519 /* search superclass */
3522 /*log_text("method not found:");*/
3528 /****************** Function: class_resolveinterfacemethod_int ****************
3530 Internally used helper function. Do not use this directly.
3532 *******************************************************************************/
3535 methodinfo *class_resolveinterfacemethod_int(classinfo *c, utf *name, utf *desc)
3540 mi = class_findmethod(c,name,desc);
3544 /* try the superinterfaces */
3545 for (i=0; i<c->interfacescount; ++i) {
3546 mi = class_resolveinterfacemethod_int(c->interfaces[i],name,desc);
3554 /******************** Function: class_resolveinterfacemethod ******************
3556 Resolves a reference from REFERER to a method with NAME and DESC in
3559 If the method cannot be resolved the return value is NULL. If EXCEPT is
3560 true *exceptionptr is set, too.
3562 *******************************************************************************/
3564 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
3565 classinfo *referer, bool except)
3569 /* XXX resolve class c */
3570 /* XXX check access from REFERER to C */
3572 if (!(c->flags & ACC_INTERFACE)) {
3575 new_exception(string_java_lang_IncompatibleClassChangeError);
3580 mi = class_resolveinterfacemethod_int(c, name, desc);
3585 /* try class java.lang.Object */
3586 mi = class_findmethod(class_java_lang_Object, name, desc);
3593 new_exception_utfmessage(string_java_lang_NoSuchMethodError, name);
3599 /********************* Function: class_resolveclassmethod *********************
3601 Resolves a reference from REFERER to a method with NAME and DESC in
3604 If the method cannot be resolved the return value is NULL. If EXCEPT is
3605 true *exceptionptr is set, too.
3607 *******************************************************************************/
3609 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
3610 classinfo *referer, bool except)
3615 char msg[MAXLOGTEXT];
3617 /* XXX resolve class c */
3618 /* XXX check access from REFERER to C */
3620 /* if (c->flags & ACC_INTERFACE) { */
3622 /* *exceptionptr = */
3623 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
3627 /* try class c and its superclasses */
3630 mi = class_findmethod(cls, name, desc);
3633 } while ((cls = cls->super) != NULL); /* try the superclass */
3635 /* try the superinterfaces */
3636 for (i = 0; i < c->interfacescount; ++i) {
3637 mi = class_resolveinterfacemethod_int(c->interfaces[i], name, desc);
3643 utf_sprint(msg, c->name);
3644 sprintf(msg + strlen(msg), ".");
3645 utf_sprint(msg + strlen(msg), name);
3646 utf_sprint(msg + strlen(msg), desc);
3649 new_exception_message(string_java_lang_NoSuchMethodError, msg);
3655 if ((mi->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
3657 *exceptionptr = new_exception(string_java_lang_AbstractMethodError);
3662 /* XXX check access rights */
3668 /************************* Function: class_issubclass **************************
3670 Checks if sub is a descendant of super.
3672 *******************************************************************************/
3674 bool class_issubclass(classinfo *sub, classinfo *super)
3677 if (!sub) return false;
3678 if (sub == super) return true;
3684 /****************** Initialization function for classes ******************
3686 In Java, every class can have a static initialization function. This
3687 function has to be called BEFORE calling other methods or accessing static
3690 *******************************************************************************/
3692 static classinfo *class_init_intern(classinfo *c);
3694 classinfo *class_init(classinfo *c)
3698 if (!makeinitializations)
3701 #if defined(USE_THREADS)
3702 /* enter a monitor on the class */
3704 builtin_monitorenter((java_objectheader *) c);
3707 /* maybe the class is already initalized or the current thread, which can
3708 pass the monitor, is currently initalizing this class */
3710 /* JOWENN: In future we need an additinal flag: initializationfailed,
3711 since further access to the class should cause a NoClassDefFound,
3712 if the static initializer failed once
3715 if (c->initialized || c->initializing) {
3716 #if defined(USE_THREADS)
3717 builtin_monitorexit((java_objectheader *) c);
3723 /* this initalizing run begins NOW */
3724 c->initializing = true;
3726 /* call the internal function */
3727 r = class_init_intern(c);
3729 /* if return value is not NULL everything was ok and the class is
3732 c->initialized = true;
3734 /* this initalizing run is done */
3735 c->initializing = false;
3737 #if defined(USE_THREADS)
3738 /* leave the monitor */
3740 builtin_monitorexit((java_objectheader *) c);
3747 /* this function MUST NOT be called directly, because of thread <clinit>
3750 static classinfo *class_init_intern(classinfo *c)
3754 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3758 /* maybe the class is not already loaded */
3763 /* maybe the class is not already linked */
3768 #if defined(STATISTICS)
3770 count_class_inits++;
3773 /* initialize super class */
3776 if (!c->super->initialized) {
3778 char logtext[MAXLOGTEXT];
3779 sprintf(logtext, "Initialize super class ");
3780 utf_sprint_classname(logtext + strlen(logtext), c->super->name);
3781 sprintf(logtext + strlen(logtext), " from ");
3782 utf_sprint_classname(logtext + strlen(logtext), c->name);
3786 if (!class_init(c->super))
3791 /* initialize interface classes */
3793 for (i = 0; i < c->interfacescount; i++) {
3794 if (!c->interfaces[i]->initialized) {
3796 char logtext[MAXLOGTEXT];
3797 sprintf(logtext, "Initialize interface class ");
3798 utf_sprint_classname(logtext + strlen(logtext), c->interfaces[i]->name);
3799 sprintf(logtext + strlen(logtext), " from ");
3800 utf_sprint_classname(logtext + strlen(logtext), c->name);
3804 if (!class_init(c->interfaces[i]))
3809 m = class_findmethod(c, utf_clinit, utf_void__void);
3813 char logtext[MAXLOGTEXT];
3814 sprintf(logtext, "Class ");
3815 utf_sprint_classname(logtext + strlen(logtext), c->name);
3816 sprintf(logtext + strlen(logtext), " has no static class initializer");
3823 /* Sun's and IBM's JVM don't care about the static flag */
3824 /* if (!(m->flags & ACC_STATIC)) { */
3825 /* panic("Class initializer is not static!"); */
3828 log_message_class("Starting static class initializer for class: ", c);
3830 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3835 /* now call the initializer */
3836 asm_calljavafunction(m, NULL, NULL, NULL, NULL);
3838 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3839 assert(blockInts == 0);
3843 /* we have an exception or error */
3844 if (*exceptionptr) {
3845 /* class is NOT initialized */
3846 c->initialized = false;
3848 /* is this an exception, than wrap it */
3849 if (builtin_instanceof(*exceptionptr, class_java_lang_Exception)) {
3850 java_objectheader *xptr;
3851 java_objectheader *cause;
3854 cause = *exceptionptr;
3856 /* clear exception, because we are calling jit code again */
3857 *exceptionptr = NULL;
3859 /* wrap the exception */
3861 new_exception_throwable(string_java_lang_ExceptionInInitializerError,
3862 (java_lang_Throwable *) cause);
3864 /* XXX should we exit here? */
3868 /* set new exception */
3869 *exceptionptr = xptr;
3876 log_message_class("Finished static class initializer for class: ", c);
3882 /********* Function: find_class_method_constant *********/
3884 int find_class_method_constant (classinfo *c, utf * c1, utf* m1, utf* d1)
3889 for (i=0; i<c->cpcount; i++) {
3891 e = c -> cpinfos [i];
3894 switch (c -> cptags [i]) {
3895 case CONSTANT_Methodref:
3897 constant_FMIref *fmi = e;
3898 if ( (fmi->class->name == c1)
3899 && (fmi->name == m1)
3900 && (fmi->descriptor == d1)) {
3907 case CONSTANT_InterfaceMethodref:
3909 constant_FMIref *fmi = e;
3910 if ( (fmi->class->name == c1)
3911 && (fmi->name == m1)
3912 && (fmi->descriptor == d1)) {
3926 void class_showconstanti(classinfo *c, int ii)
3932 printf ("#%d: ", (int) i);
3934 switch (c->cptags [i]) {
3935 case CONSTANT_Class:
3936 printf("Classreference -> ");
3937 utf_display(((classinfo*)e)->name);
3940 case CONSTANT_Fieldref:
3941 printf("Fieldref -> "); goto displayFMIi;
3942 case CONSTANT_Methodref:
3943 printf("Methodref -> "); goto displayFMIi;
3944 case CONSTANT_InterfaceMethodref:
3945 printf("InterfaceMethod -> "); goto displayFMIi;
3948 constant_FMIref *fmi = e;
3949 utf_display(fmi->class->name);
3951 utf_display(fmi->name);
3953 utf_display(fmi->descriptor);
3957 case CONSTANT_String:
3958 printf("String -> ");
3961 case CONSTANT_Integer:
3962 printf("Integer -> %d", (int) (((constant_integer*)e)->value));
3964 case CONSTANT_Float:
3965 printf("Float -> %f", ((constant_float*)e)->value);
3967 case CONSTANT_Double:
3968 printf("Double -> %f", ((constant_double*)e)->value);
3972 u8 v = ((constant_long*)e)->value;
3974 printf("Long -> %ld", (long int) v);
3976 printf("Long -> HI: %ld, LO: %ld\n",
3977 (long int) v.high, (long int) v.low);
3981 case CONSTANT_NameAndType:
3983 constant_nameandtype *cnt = e;
3984 printf("NameAndType: ");
3985 utf_display(cnt->name);
3987 utf_display(cnt->descriptor);
3995 panic("Invalid type of ConstantPool-Entry");
4002 void class_showconstantpool (classinfo *c)
4007 printf ("---- dump of constant pool ----\n");
4009 for (i=0; i<c->cpcount; i++) {
4010 printf ("#%d: ", (int) i);
4012 e = c -> cpinfos [i];
4015 switch (c -> cptags [i]) {
4016 case CONSTANT_Class:
4017 printf ("Classreference -> ");
4018 utf_display ( ((classinfo*)e) -> name );
4021 case CONSTANT_Fieldref:
4022 printf ("Fieldref -> "); goto displayFMI;
4023 case CONSTANT_Methodref:
4024 printf ("Methodref -> "); goto displayFMI;
4025 case CONSTANT_InterfaceMethodref:
4026 printf ("InterfaceMethod -> "); goto displayFMI;
4029 constant_FMIref *fmi = e;
4030 utf_display ( fmi->class->name );
4032 utf_display ( fmi->name);
4034 utf_display ( fmi->descriptor );
4038 case CONSTANT_String:
4039 printf ("String -> ");
4042 case CONSTANT_Integer:
4043 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
4045 case CONSTANT_Float:
4046 printf ("Float -> %f", ((constant_float*)e) -> value);
4048 case CONSTANT_Double:
4049 printf ("Double -> %f", ((constant_double*)e) -> value);
4053 u8 v = ((constant_long*)e) -> value;
4055 printf ("Long -> %ld", (long int) v);
4057 printf ("Long -> HI: %ld, LO: %ld\n",
4058 (long int) v.high, (long int) v.low);
4062 case CONSTANT_NameAndType:
4064 constant_nameandtype *cnt = e;
4065 printf ("NameAndType: ");
4066 utf_display (cnt->name);
4068 utf_display (cnt->descriptor);
4072 printf ("Utf8 -> ");
4076 panic ("Invalid type of ConstantPool-Entry");
4086 /********** Function: class_showmethods (debugging only) *************/
4088 void class_showmethods (classinfo *c)
4092 printf ("--------- Fields and Methods ----------------\n");
4093 printf ("Flags: "); printflags (c->flags); printf ("\n");
4095 printf ("This: "); utf_display (c->name); printf ("\n");
4097 printf ("Super: "); utf_display (c->super->name); printf ("\n");
4099 printf ("Index: %d\n", c->index);
4101 printf ("interfaces:\n");
4102 for (i=0; i < c-> interfacescount; i++) {
4104 utf_display (c -> interfaces[i] -> name);
4105 printf (" (%d)\n", c->interfaces[i] -> index);
4108 printf ("fields:\n");
4109 for (i=0; i < c -> fieldscount; i++) {
4110 field_display (&(c -> fields[i]));
4113 printf ("methods:\n");
4114 for (i=0; i < c -> methodscount; i++) {
4115 methodinfo *m = &(c->methods[i]);
4116 if ( !(m->flags & ACC_STATIC))
4117 printf ("vftblindex: %d ", m->vftblindex);
4119 method_display ( m );
4123 printf ("Virtual function table:\n");
4124 for (i=0; i<c->vftbl->vftbllength; i++) {
4125 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]) );
4131 /******************************************************************************/
4132 /******************* General functions for the class loader *******************/
4133 /******************************************************************************/
4135 /**************** function: create_primitive_classes ***************************
4137 create classes representing primitive types
4139 *******************************************************************************/
4141 static bool create_primitive_classes()
4145 for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
4146 /* create primitive class */
4148 class_new_intern(utf_new_char(primitivetype_table[i].name));
4149 c->classUsed = NOTUSED; /* not used initially CO-RT */
4152 /* prevent loader from loading primitive class */
4157 primitivetype_table[i].class_primitive = c;
4159 /* create class for wrapping the primitive type */
4160 c = class_new_intern(utf_new_char(primitivetype_table[i].wrapname));
4161 primitivetype_table[i].class_wrap = c;
4162 primitivetype_table[i].class_wrap->classUsed = NOTUSED; /* not used initially CO-RT */
4163 primitivetype_table[i].class_wrap->impldBy = NULL;
4165 /* create the primitive array class */
4166 if (primitivetype_table[i].arrayname) {
4167 c = class_new_intern(utf_new_char(primitivetype_table[i].arrayname));
4168 primitivetype_table[i].arrayclass = c;
4173 primitivetype_table[i].arrayvftbl = c->vftbl;
4181 /**************** function: class_primitive_from_sig ***************************
4183 return the primitive class indicated by the given signature character
4185 If the descriptor does not indicate a valid primitive type the
4186 return value is NULL.
4188 ********************************************************************************/
4190 classinfo *class_primitive_from_sig(char sig)
4193 case 'I': return primitivetype_table[PRIMITIVETYPE_INT].class_primitive;
4194 case 'J': return primitivetype_table[PRIMITIVETYPE_LONG].class_primitive;
4195 case 'F': return primitivetype_table[PRIMITIVETYPE_FLOAT].class_primitive;
4196 case 'D': return primitivetype_table[PRIMITIVETYPE_DOUBLE].class_primitive;
4197 case 'B': return primitivetype_table[PRIMITIVETYPE_BYTE].class_primitive;
4198 case 'C': return primitivetype_table[PRIMITIVETYPE_CHAR].class_primitive;
4199 case 'S': return primitivetype_table[PRIMITIVETYPE_SHORT].class_primitive;
4200 case 'Z': return primitivetype_table[PRIMITIVETYPE_BOOLEAN].class_primitive;
4201 case 'V': return primitivetype_table[PRIMITIVETYPE_VOID].class_primitive;
4206 /****************** function: class_from_descriptor ****************************
4208 return the class indicated by the given descriptor
4210 utf_ptr....first character of descriptor
4211 end_ptr....first character after the end of the string
4212 next.......if non-NULL, *next is set to the first character after
4213 the descriptor. (Undefined if an error occurs.)
4215 mode.......a combination (binary or) of the following flags:
4217 (Flags marked with * are the default settings.)
4219 What to do if a reference type descriptor is parsed successfully:
4221 CLASSLOAD_SKIP...skip it and return something != NULL
4222 * CLASSLOAD_NEW....get classinfo * via class_new
4223 CLASSLOAD_LOAD...get classinfo * via loader_load
4225 How to handle primitive types:
4227 * CLASSLOAD_PRIMITIVE.......return primitive class (eg. "int")
4228 CLASSLOAD_NULLPRIMITIVE...return NULL for primitive types
4230 How to handle "V" descriptors:
4232 * CLASSLOAD_VOID.....handle it like other primitive types
4233 CLASSLOAD_NOVOID...treat it as an error
4235 How to deal with extra characters after the end of the
4238 * CLASSLOAD_NOCHECKEND...ignore (useful for parameter lists)
4239 CLASSLOAD_CHECKEND.....treat them as an error
4241 How to deal with errors:
4243 * CLASSLOAD_PANIC....abort execution with an error message
4244 CLASSLOAD_NOPANIC..return NULL on error
4246 *******************************************************************************/
4248 classinfo *class_from_descriptor(char *utf_ptr, char *end_ptr,
4249 char **next, int mode)
4251 char *start = utf_ptr;
4255 SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr, end_ptr, error);
4257 if (mode & CLASSLOAD_CHECKEND)
4258 error |= (utf_ptr != end_ptr);
4261 if (next) *next = utf_ptr;
4265 if (mode & CLASSLOAD_NOVOID)
4276 return (mode & CLASSLOAD_NULLPRIMITIVE)
4278 : class_primitive_from_sig(*start);
4285 if (mode & CLASSLOAD_SKIP) return class_java_lang_Object;
4286 name = utf_new(start, utf_ptr - start);
4290 tc = class_new_intern(name);
4292 list_addfirst(&unlinkedclasses, tc);
4297 return (mode & CLASSLOAD_LOAD)
4298 ? class_load(class_new(name)) : class_new(name); /* XXX handle errors */
4303 /* An error occurred */
4304 if (mode & CLASSLOAD_NOPANIC)
4307 log_plain("Invalid descriptor at beginning of '");
4308 log_plain_utf(utf_new(start, end_ptr - start));
4312 panic("Invalid descriptor");
4314 /* keep compiler happy */
4319 /******************* function: type_from_descriptor ****************************
4321 return the basic type indicated by the given descriptor
4323 This function parses a descriptor and returns its basic type as
4324 TYPE_INT, TYPE_LONG, TYPE_FLOAT, TYPE_DOUBLE, TYPE_ADDRESS or TYPE_VOID.
4326 cls...if non-NULL the referenced variable is set to the classinfo *
4327 returned by class_from_descriptor.
4329 For documentation of the arguments utf_ptr, end_ptr, next and mode
4330 see class_from_descriptor. The only difference is that
4331 type_from_descriptor always uses CLASSLOAD_PANIC.
4333 ********************************************************************************/
4335 int type_from_descriptor(classinfo **cls, char *utf_ptr, char *end_ptr,
4336 char **next, int mode)
4339 if (!cls) cls = &mycls;
4340 *cls = class_from_descriptor(utf_ptr, end_ptr, next, mode & (~CLASSLOAD_NOPANIC));
4357 return TYPE_ADDRESS;
4361 /*************** function: create_pseudo_classes *******************************
4363 create pseudo classes used by the typechecker
4365 ********************************************************************************/
4367 static void create_pseudo_classes()
4369 /* pseudo class for Arraystubs (extends java.lang.Object) */
4371 pseudo_class_Arraystub->loaded = true;
4372 pseudo_class_Arraystub->super = class_java_lang_Object;
4373 pseudo_class_Arraystub->interfacescount = 2;
4374 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
4375 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
4376 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
4378 class_link(pseudo_class_Arraystub);
4380 pseudo_class_Arraystub_vftbl = pseudo_class_Arraystub->vftbl;
4382 /* pseudo class representing the null type */
4384 pseudo_class_Null->loaded = true;
4385 pseudo_class_Null->super = class_java_lang_Object;
4386 class_link(pseudo_class_Null);
4388 /* pseudo class representing new uninitialized objects */
4390 pseudo_class_New->loaded = true;
4391 pseudo_class_New->linked = true;
4392 pseudo_class_New->super = class_java_lang_Object;
4396 /********************** Function: loader_init **********************************
4398 Initializes all lists and loads all classes required for the system or the
4401 *******************************************************************************/
4403 bool loader_init(u1 *stackbottom)
4405 classpath_info *cpi;
4407 /* reset interface index */
4411 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4412 /* Initialize the monitor pointer for zip/jar file locking. */
4414 for (cpi = classpath_entries; cpi != NULL; cpi = cpi->next) {
4415 if (cpi->type == CLASSPATH_ARCHIVE)
4416 initObjectLock(&cpi->header);
4420 /* Create some important classes. These classes have to be created now */
4421 /* because the classinfo pointers are used in the loading code. */
4423 if (!class_load(class_java_lang_Object) ||
4424 !class_link(class_java_lang_Object))
4427 if (!class_load(class_java_lang_String) ||
4428 !class_link(class_java_lang_String))
4431 if (!class_load(class_java_lang_Cloneable) ||
4432 !class_link(class_java_lang_Cloneable))
4435 if (!class_load(class_java_io_Serializable) ||
4436 !class_link(class_java_io_Serializable))
4439 /* create classes representing primitive types */
4440 create_primitive_classes();
4442 /* create classes used by the typechecker */
4443 create_pseudo_classes();
4445 /* correct vftbl-entries (retarded loading of class java/lang/String) */
4446 stringtable_update();
4448 #if defined(USE_THREADS)
4449 if (stackbottom != 0)
4457 /* loader_compute_subclasses ***************************************************
4461 *******************************************************************************/
4463 static void loader_compute_class_values(classinfo *c);
4465 void loader_compute_subclasses(classinfo *c)
4467 #if defined(USE_THREADS)
4468 #if defined(NATIVE_THREADS)
4475 if (!(c->flags & ACC_INTERFACE)) {
4480 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
4481 c->nextsub = c->super->sub;
4487 /* this is the java.lang.Object special case */
4489 if (!class_java_lang_Object) {
4490 loader_compute_class_values(c);
4493 loader_compute_class_values(class_java_lang_Object);
4496 #if defined(USE_THREADS)
4497 #if defined(NATIVE_THREADS)
4506 /* loader_compute_class_values *************************************************
4510 *******************************************************************************/
4512 static void loader_compute_class_values(classinfo *c)
4516 c->vftbl->baseval = ++classvalue;
4520 loader_compute_class_values(subs);
4521 subs = subs->nextsub;
4524 c->vftbl->diffval = classvalue - c->vftbl->baseval;
4528 /******************** Function: loader_close ***********************************
4532 *******************************************************************************/
4539 for (slot = 0; slot < class_hash.size; slot++) {
4540 c = class_hash.ptr[slot];
4551 * These are local overrides for various environment variables in Emacs.
4552 * Please do not remove this and leave it at the end of the file, where
4553 * Emacs will automagically detect them.
4554 * ---------------------------------------------------------------------
4557 * indent-tabs-mode: t