1 /* loader.c - class loader functions
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5 M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6 P. Tomsich, J. Wenninger
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 1553 2004-11-19 15:47:13Z carolyn $
44 #include "exceptions.h"
53 #include "statistics.h"
54 #include "toolbox/memory.h"
55 #include "toolbox/logging.h"
56 #include "threads/thread.h"
57 #include "threads/locks.h"
58 #include "nat/java_lang_Throwable.h"
68 /* global variables ***********************************************************/
70 static s4 interfaceindex; /* sequential numbering of interfaces */
74 /* utf-symbols for pointer comparison of frequently used strings */
76 static utf *utf_innerclasses; /* InnerClasses */
77 static utf *utf_constantvalue; /* ConstantValue */
78 static utf *utf_code; /* Code */
79 static utf *utf_exceptions; /* Exceptions */
80 static utf *utf_linenumbertable; /* LineNumberTable */
81 static utf *utf_sourcefile; /* SourceFile */
82 static utf *utf_finalize; /* finalize */
83 static utf *utf_fidesc; /* ()V changed */
84 static utf *utf_init; /* <init> */
85 static utf *utf_clinit; /* <clinit> */
86 static utf *utf_initsystemclass; /* initializeSystemClass */
87 static utf *utf_systemclass; /* java/lang/System */
88 static utf *utf_vmclassloader; /* java/lang/VMClassLoader */
89 static utf *utf_vmclass; /* java/lang/VMClassLoader */
90 static utf *utf_initialize;
91 static utf *utf_initializedesc;
92 static utf *utf_java_lang_Object; /* java/lang/Object */
94 utf *utf_fillInStackTrace_name;
95 utf *utf_fillInStackTrace_desc;
105 /* important system classes ***************************************************/
107 classinfo *class_java_lang_Object;
108 classinfo *class_java_lang_String;
109 classinfo *class_java_lang_Cloneable;
110 classinfo *class_java_io_Serializable;
112 /* Pseudo classes for the typechecker */
113 classinfo *pseudo_class_Arraystub = NULL;
114 classinfo *pseudo_class_Null = NULL;
115 classinfo *pseudo_class_New = NULL;
116 vftbl_t *pseudo_class_Arraystub_vftbl = NULL;
118 utf *array_packagename = NULL;
121 /********************************************************************
122 list of classpath entries (either filesystem directories or
124 ********************************************************************/
126 static classpath_info *classpath_entries = NULL;
129 /******************************************************************************
131 structure for primitive classes: contains the class for wrapping the
132 primitive type, the primitive class, the name of the class for wrapping,
133 the one character type signature and the name of the primitive class
135 ******************************************************************************/
137 /* CAUTION: Don't change the order of the types. This table is indexed
138 * by the ARRAYTYPE_ constants (expcept ARRAYTYPE_OBJECT).
140 primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = {
141 { NULL, NULL, "java/lang/Integer", 'I', "int" , "[I", NULL, NULL },
142 { NULL, NULL, "java/lang/Long", 'J', "long" , "[J", NULL, NULL },
143 { NULL, NULL, "java/lang/Float", 'F', "float" , "[F", NULL, NULL },
144 { NULL, NULL, "java/lang/Double", 'D', "double" , "[D", NULL, NULL },
145 { NULL, NULL, "java/lang/Byte", 'B', "byte" , "[B", NULL, NULL },
146 { NULL, NULL, "java/lang/Character", 'C', "char" , "[C", NULL, NULL },
147 { NULL, NULL, "java/lang/Short", 'S', "short" , "[S", NULL, NULL },
148 { NULL, NULL, "java/lang/Boolean", 'Z', "boolean" , "[Z", NULL, NULL },
149 { NULL, NULL, "java/lang/Void", 'V', "void" , NULL, NULL, NULL }
153 /************* functions for reading classdata *********************************
155 getting classdata in blocks of variable size
156 (8,16,32,64-bit integer or float)
158 *******************************************************************************/
160 /* check_classbuffer_size ******************************************************
162 assert that at least <len> bytes are left to read
163 <len> is limited to the range of non-negative s4 values
165 *******************************************************************************/
167 static inline bool check_classbuffer_size(classbuffer *cb, s4 len)
169 if (len < 0 || ((cb->data + cb->size) - cb->pos - 1) < len) {
171 new_classformaterror((cb)->class, "Truncated class file");
180 /* suck_nbytes *****************************************************************
182 transfer block of classfile data into a buffer
184 *******************************************************************************/
186 inline void suck_nbytes(u1 *buffer, classbuffer *cb, s4 len)
188 memcpy(buffer, cb->pos + 1, len);
193 /* skip_nbytes ****************************************************************
195 skip block of classfile data
197 *******************************************************************************/
199 inline void skip_nbytes(classbuffer *cb, s4 len)
205 inline u1 suck_u1(classbuffer *cb)
211 inline u2 suck_u2(classbuffer *cb)
215 return ((u2) a << 8) + (u2) b;
219 inline u4 suck_u4(classbuffer *cb)
225 return ((u4) a << 24) + ((u4) b << 16) + ((u4) c << 8) + (u4) d;
229 /* get u8 from classfile data */
230 static u8 suck_u8(classbuffer *cb)
236 return (hi << 32) + lo;
239 v.high = suck_u4(cb);
246 #define suck_s8(a) (s8) suck_u8((a))
247 #define suck_s2(a) (s2) suck_u2((a))
248 #define suck_s4(a) (s4) suck_u4((a))
249 #define suck_s1(a) (s1) suck_u1((a))
252 /* get float from classfile data */
253 static float suck_float(classbuffer *cb)
261 for (i = 0; i < 4; i++)
262 buffer[3 - i] = suck_u1(cb);
264 memcpy((u1*) (&f), buffer, 4);
266 suck_nbytes((u1*) (&f), cb, 4);
269 if (sizeof(float) != 4) {
270 *exceptionptr = new_exception_message(string_java_lang_InternalError,
271 "Incompatible float-format");
273 /* XXX should we exit in such a case? */
274 throw_exception_exit();
281 /* get double from classfile data */
282 static double suck_double(classbuffer *cb)
290 for (i = 0; i < 8; i++)
291 buffer[7 - i] = suck_u1(cb);
293 memcpy((u1*) (&d), buffer, 8);
295 suck_nbytes((u1*) (&d), cb, 8);
298 if (sizeof(double) != 8) {
299 *exceptionptr = new_exception_message(string_java_lang_InternalError,
300 "Incompatible double-format");
302 /* XXX should we exit in such a case? */
303 throw_exception_exit();
310 /************************** function suck_init *********************************
312 called once at startup, sets the searchpath for the classfiles
314 *******************************************************************************/
316 void suck_init(char *classpath)
324 classpath_info *lastcpi;
329 for (start = classpath; (*start) != '\0';) {
331 /* search for ':' delimiter to get the end of the current entry */
332 for (end = start; ((*end) != '\0') && ((*end) != ':'); end++);
336 filenamelen = end - start;
338 if (filenamelen > 3) {
339 if (strncasecmp(end - 3, "zip", 3) == 0 ||
340 strncasecmp(end - 3, "jar", 3) == 0) {
345 /* allocate memory for filename and fill it */
347 filename = MNEW(char, filenamelen + 2); /* 2 = "/\0" */
348 strncpy(filename, start, filenamelen);
349 filename[filenamelen + 1] = '\0';
353 #if defined(USE_ZLIB)
354 unzFile uf = unzOpen(filename);
357 cpi = (union classpath_info *) NEW(classpath_info);
358 cpi->archive.type = CLASSPATH_ARCHIVE;
359 cpi->archive.uf = uf;
360 cpi->archive.next = NULL;
363 throw_cacao_exception_exit(string_java_lang_InternalError,
364 "zip/jar files not supported");
368 cpi = (union classpath_info *) NEW(classpath_info);
369 cpi->filepath.type = CLASSPATH_PATH;
370 cpi->filepath.next = NULL;
372 if (filename[filenamelen - 1] != '/') {/*PERHAPS THIS SHOULD BE READ FROM A GLOBAL CONFIGURATION */
373 filename[filenamelen] = '/';
374 filename[filenamelen + 1] = '\0';
378 cpi->filepath.path = filename;
379 cpi->filepath.pathlen = filenamelen;
382 /* attach current classpath entry */
385 if (!classpath_entries) {
386 classpath_entries = cpi;
389 lastcpi->filepath.next = cpi;
396 /* goto next classpath entry, skip ':' delimiter */
408 void create_all_classes()
412 for (cpi = classpath_entries; cpi != 0; cpi = cpi->filepath.next) {
413 #if defined(USE_ZLIB)
414 if (cpi->filepath.type == CLASSPATH_ARCHIVE) {
418 s = (unz_s *) cpi->archive.uf;
419 ce = s->cacao_dir_list;
422 (void) class_new(ce->name);
428 #if defined(USE_ZLIB)
435 /************************** function suck_start ********************************
437 returns true if classbuffer is already loaded or a file for the
438 specified class has succussfully been read in. All directories of
439 the searchpath are used to find the classfile (<classname>.class).
440 Returns false if no classfile is found and writes an error message.
442 *******************************************************************************/
444 classbuffer *suck_start(classinfo *c)
459 utf_ptr = c->name->text;
461 while (utf_ptr < utf_end(c->name)) {
462 if (filenamelen >= CLASSPATH_MAXFILENAME) {
464 new_exception_message(string_java_lang_InternalError,
465 "Filename too long");
467 /* XXX should we exit in such a case? */
468 throw_exception_exit();
472 if ((ch <= ' ' || ch > 'z') && (ch != '/')) /* invalid character */
474 filename[filenamelen++] = ch;
478 /* initialize return value */
482 filenamelen = utf_strlen(c->name) + 7; /* 7 = ".class\0" */
483 filename = MNEW(char, filenamelen);
485 utf_sprint(filename, c->name);
486 strcat(filename, ".class");
488 /* walk through all classpath entries */
490 for (cpi = classpath_entries; cpi != NULL && cb == NULL; cpi = cpi->filepath.next) {
491 #if defined(USE_ZLIB)
492 if (cpi->filepath.type == CLASSPATH_ARCHIVE) {
493 if (cacao_locate(cpi->archive.uf, c->name) == UNZ_OK) {
494 unz_file_info file_info;
496 if (unzGetCurrentFileInfo(cpi->archive.uf, &file_info, filename,
497 sizeof(filename), NULL, 0, NULL, 0) == UNZ_OK) {
498 if (unzOpenCurrentFile(cpi->archive.uf) == UNZ_OK) {
499 cb = NEW(classbuffer);
501 cb->size = file_info.uncompressed_size;
502 cb->data = MNEW(u1, cb->size);
503 cb->pos = cb->data - 1;
505 len = unzReadCurrentFile(cpi->archive.uf, cb->data, cb->size);
507 if (len != cb->size) {
509 log_text("Error while unzipping");
513 log_text("Error while opening file in archive");
517 log_text("Error while retrieving fileinfo");
520 unzCloseCurrentFile(cpi->archive.uf);
523 #endif /* USE_ZLIB */
525 path = MNEW(char, cpi->filepath.pathlen + filenamelen + 1);
526 strcpy(path, cpi->filepath.path);
527 strcat(path, filename);
529 classfile = fopen(path, "r");
531 if (classfile) { /* file exists */
532 /* determine size of classfile */
533 err = stat(path, &buffer);
535 if (!err) { /* read classfile data */
536 cb = NEW(classbuffer);
538 cb->size = buffer.st_size;
539 cb->data = MNEW(u1, cb->size);
540 cb->pos = cb->data - 1;
542 /* read class data */
543 len = fread(cb->data, 1, cb->size, classfile);
545 if (len != buffer.st_size) {
547 /* if (ferror(classfile)) { */
553 MFREE(path, char, cpi->filepath.pathlen + filenamelen + 1);
554 #if defined(USE_ZLIB)
561 dolog("Warning: Can not open class file '%s'", filename);
564 MFREE(filename, char, filenamelen);
570 /************************** function suck_stop *********************************
572 frees memory for buffer with classfile data.
573 Caution: this function may only be called if buffer has been allocated
574 by suck_start with reading a file
576 *******************************************************************************/
578 void suck_stop(classbuffer *cb)
582 MFREE(cb->data, u1, cb->size);
583 FREE(cb, classbuffer);
587 /******************************************************************************/
588 /******************* Some support functions ***********************************/
589 /******************************************************************************/
591 void fprintflags (FILE *fp, u2 f)
593 if ( f & ACC_PUBLIC ) fprintf (fp," PUBLIC");
594 if ( f & ACC_PRIVATE ) fprintf (fp," PRIVATE");
595 if ( f & ACC_PROTECTED ) fprintf (fp," PROTECTED");
596 if ( f & ACC_STATIC ) fprintf (fp," STATIC");
597 if ( f & ACC_FINAL ) fprintf (fp," FINAL");
598 if ( f & ACC_SYNCHRONIZED ) fprintf (fp," SYNCHRONIZED");
599 if ( f & ACC_VOLATILE ) fprintf (fp," VOLATILE");
600 if ( f & ACC_TRANSIENT ) fprintf (fp," TRANSIENT");
601 if ( f & ACC_NATIVE ) fprintf (fp," NATIVE");
602 if ( f & ACC_INTERFACE ) fprintf (fp," INTERFACE");
603 if ( f & ACC_ABSTRACT ) fprintf (fp," ABSTRACT");
607 /********** internal function: printflags (only for debugging) ***************/
609 void printflags(u2 f)
611 if ( f & ACC_PUBLIC ) printf (" PUBLIC");
612 if ( f & ACC_PRIVATE ) printf (" PRIVATE");
613 if ( f & ACC_PROTECTED ) printf (" PROTECTED");
614 if ( f & ACC_STATIC ) printf (" STATIC");
615 if ( f & ACC_FINAL ) printf (" FINAL");
616 if ( f & ACC_SYNCHRONIZED ) printf (" SYNCHRONIZED");
617 if ( f & ACC_VOLATILE ) printf (" VOLATILE");
618 if ( f & ACC_TRANSIENT ) printf (" TRANSIENT");
619 if ( f & ACC_NATIVE ) printf (" NATIVE");
620 if ( f & ACC_INTERFACE ) printf (" INTERFACE");
621 if ( f & ACC_ABSTRACT ) printf (" ABSTRACT");
625 /********************** Function: skipattributebody ****************************
627 skips an attribute after the 16 bit reference to attribute_name has already
630 *******************************************************************************/
632 static bool skipattributebody(classbuffer *cb)
636 if (!check_classbuffer_size(cb, 4))
641 if (!check_classbuffer_size(cb, len))
644 skip_nbytes(cb, len);
650 /************************* Function: skipattributes ****************************
652 skips num attribute structures
654 *******************************************************************************/
656 static bool skipattributes(classbuffer *cb, u4 num)
661 for (i = 0; i < num; i++) {
662 if (!check_classbuffer_size(cb, 2 + 4))
668 if (!check_classbuffer_size(cb, len))
671 skip_nbytes(cb, len);
678 /******************** function:: class_getconstant *****************************
680 retrieves the value at position 'pos' of the constantpool of a class
681 if the type of the value is other than 'ctype' the system is stopped
683 *******************************************************************************/
685 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
687 /* check index and type of constantpool entry */
688 /* (pos == 0 is caught by type comparison) */
689 if (pos >= c->cpcount || c->cptags[pos] != ctype) {
690 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
694 return c->cpinfos[pos];
698 /******************** function: innerclass_getconstant ************************
700 like class_getconstant, but if cptags is ZERO null is returned
702 *******************************************************************************/
704 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
706 /* invalid position in constantpool */
707 if (pos >= c->cpcount) {
708 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
712 /* constantpool entry of type 0 */
716 /* check type of constantpool entry */
717 if (c->cptags[pos] != ctype) {
718 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
722 return c->cpinfos[pos];
726 /********************* Function: class_constanttype ****************************
728 Determines the type of a class entry in the ConstantPool
730 *******************************************************************************/
732 u4 class_constanttype(classinfo *c, u4 pos)
734 if (pos <= 0 || pos >= c->cpcount) {
735 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
739 return c->cptags[pos];
743 /************************ function: attribute_load ****************************
745 read attributes from classfile
747 *******************************************************************************/
749 static bool attribute_load(classbuffer *cb, classinfo *c, u4 num)
754 for (i = 0; i < num; i++) {
755 /* retrieve attribute name */
756 if (!check_classbuffer_size(cb, 2))
759 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
762 if (aname == utf_innerclasses) {
763 /* innerclasses attribute */
766 new_classformaterror(c, "Multiple InnerClasses attributes");
770 if (!check_classbuffer_size(cb, 4 + 2))
773 /* skip attribute length */
776 /* number of records */
777 c->innerclasscount = suck_u2(cb);
779 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
782 /* allocate memory for innerclass structure */
783 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
785 for (j = 0; j < c->innerclasscount; j++) {
786 /* The innerclass structure contains a class with an encoded
787 name, its defining scope, its simple name and a bitmask of
788 the access flags. If an inner class is not a member, its
789 outer_class is NULL, if a class is anonymous, its name is
792 innerclassinfo *info = c->innerclass + j;
795 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
797 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
799 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
800 info->flags = suck_u2(cb);
803 } else if (aname == utf_sourcefile) {
804 if (!check_classbuffer_size(cb, 4 + 2))
807 if (suck_u4(cb) != 2) {
809 new_classformaterror(c, "Wrong size for VALUE attribute");
815 new_classformaterror(c, "Multiple SourceFile attributes");
819 if (!(c->sourcefile = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
823 /* unknown attribute */
824 if (!skipattributebody(cb))
833 /******************* function: checkfielddescriptor ****************************
835 checks whether a field-descriptor is valid and aborts otherwise
836 all referenced classes are inserted into the list of unloaded classes
838 *******************************************************************************/
840 static void checkfielddescriptor (char *utf_ptr, char *end_pos)
842 class_from_descriptor(utf_ptr,end_pos,NULL,
844 | CLASSLOAD_NULLPRIMITIVE
846 | CLASSLOAD_CHECKEND);
848 /* XXX use the following if -noverify */
850 char *tstart; /* pointer to start of classname */
852 char *start = utf_ptr;
854 switch (*utf_ptr++) {
868 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
869 panic ("Ill formed descriptor");
873 panic ("Ill formed descriptor");
876 /* exceeding characters */
877 if (utf_ptr!=end_pos) panic ("descriptor has exceeding chars");
882 /******************* function checkmethoddescriptor ****************************
884 checks whether a method-descriptor is valid and aborts otherwise.
885 All referenced classes are inserted into the list of unloaded classes.
887 The number of arguments is returned. A long or double argument is counted
890 *******************************************************************************/
892 static int checkmethoddescriptor(classinfo *c, utf *descriptor)
894 char *utf_ptr; /* current position in utf text */
895 char *end_pos; /* points behind utf string */
896 s4 argcount = 0; /* number of arguments */
898 utf_ptr = descriptor->text;
899 end_pos = utf_end(descriptor);
901 /* method descriptor must start with parenthesis */
902 if (utf_ptr == end_pos || *utf_ptr++ != '(')
903 panic ("Missing '(' in method descriptor");
905 /* check arguments */
906 while (utf_ptr != end_pos && *utf_ptr != ')') {
907 /* We cannot count the this argument here because
908 * we don't know if the method is static. */
909 if (*utf_ptr == 'J' || *utf_ptr == 'D')
913 class_from_descriptor(utf_ptr,end_pos,&utf_ptr,
915 | CLASSLOAD_NULLPRIMITIVE
919 if (utf_ptr == end_pos)
920 panic("Missing ')' in method descriptor");
922 utf_ptr++; /* skip ')' */
924 class_from_descriptor(utf_ptr,
928 CLASSLOAD_NULLPRIMITIVE |
931 if (argcount > 255) {
933 new_classformaterror(c, "Too many arguments in signature");
940 /* XXX use the following if -noverify */
942 /* check arguments */
943 while ((c = *utf_ptr++) != ')') {
960 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
961 panic ("Ill formed method descriptor");
965 panic ("Ill formed methodtype-descriptor");
969 /* check returntype */
971 /* returntype void */
972 if ((utf_ptr+1) != end_pos) panic ("Method-descriptor has exceeding chars");
975 /* treat as field-descriptor */
976 checkfielddescriptor (utf_ptr,end_pos);
981 /***************** Function: print_arraydescriptor ****************************
983 Debugging helper for displaying an arraydescriptor
985 *******************************************************************************/
987 void print_arraydescriptor(FILE *file, arraydescriptor *desc)
990 fprintf(file, "<NULL>");
995 if (desc->componentvftbl) {
996 if (desc->componentvftbl->class)
997 utf_fprint(file, desc->componentvftbl->class->name);
999 fprintf(file, "<no classinfo>");
1005 if (desc->elementvftbl) {
1006 if (desc->elementvftbl->class)
1007 utf_fprint(file, desc->elementvftbl->class->name);
1009 fprintf(file, "<no classinfo>");
1013 fprintf(file, ",%d,%d,%d,%d}", desc->arraytype, desc->dimension,
1014 desc->dataoffset, desc->componentsize);
1018 /******************************************************************************/
1019 /************************** Functions for fields ****************************/
1020 /******************************************************************************/
1023 /* field_load ******************************************************************
1025 Load everything about a class field from the class file and fill a
1026 'fieldinfo' structure. For static fields, space in the data segment is
1029 *******************************************************************************/
1031 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
1033 static bool field_load(classbuffer *cb, classinfo *c, fieldinfo *f)
1037 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
1040 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1043 f->flags = suck_u2(cb);
1045 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1049 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1055 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<')
1056 panic("Field with invalid name");
1058 /* check flag consistency */
1059 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
1061 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
1062 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
1064 new_classformaterror(c,
1065 "Illegal field modifiers: 0x%X",
1070 if (c->flags & ACC_INTERFACE) {
1071 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
1072 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
1073 f->flags & ACC_TRANSIENT) {
1075 new_classformaterror(c,
1076 "Illegal field modifiers: 0x%X",
1082 /* check descriptor */
1083 checkfielddescriptor(f->descriptor->text, utf_end(f->descriptor));
1086 f->type = jtype = desc_to_type(f->descriptor); /* data type */
1087 f->offset = 0; /* offset from start of object */
1092 case TYPE_INT: f->value.i = 0; break;
1093 case TYPE_FLOAT: f->value.f = 0.0; break;
1094 case TYPE_DOUBLE: f->value.d = 0.0; break;
1095 case TYPE_ADDRESS: f->value.a = NULL; break;
1098 f->value.l = 0; break;
1100 f->value.l.low = 0; f->value.l.high = 0; break;
1104 /* read attributes */
1105 if (!check_classbuffer_size(cb, 2))
1108 attrnum = suck_u2(cb);
1109 for (i = 0; i < attrnum; i++) {
1110 if (!check_classbuffer_size(cb, 2))
1113 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1116 if (u == utf_constantvalue) {
1117 if (!check_classbuffer_size(cb, 4 + 2))
1120 /* check attribute length */
1121 if (suck_u4(cb) != 2) {
1123 new_classformaterror(c, "Wrong size for VALUE attribute");
1127 /* constant value attribute */
1128 if (pindex != field_load_NOVALUE) {
1130 new_classformaterror(c,
1131 "Multiple ConstantValue attributes");
1135 /* index of value in constantpool */
1136 pindex = suck_u2(cb);
1138 /* initialize field with value from constantpool */
1141 constant_integer *ci;
1143 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
1146 f->value.i = ci->value;
1153 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
1156 f->value.l = cl->value;
1163 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
1166 f->value.f = cf->value;
1171 constant_double *cd;
1173 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
1176 f->value.d = cd->value;
1181 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
1184 /* create javastring from compressed utf8-string */
1185 f->value.a = literalstring_new(u);
1189 log_text("Invalid Constant - Type");
1193 /* unknown attribute */
1194 if (!skipattributebody(cb))
1199 /* everything was ok */
1205 /********************** function: field_free **********************************/
1207 static void field_free(fieldinfo *f)
1213 /**************** Function: field_display (debugging only) ********************/
1215 void field_display(fieldinfo *f)
1218 printflags(f->flags);
1220 utf_display(f->name);
1222 utf_display(f->descriptor);
1223 printf(" offset: %ld\n", (long int) (f->offset));
1227 /******************************************************************************/
1228 /************************* Functions for methods ******************************/
1229 /******************************************************************************/
1232 /* method_load *****************************************************************
1234 Loads a method from the class file and fills an existing 'methodinfo'
1235 structure. For native methods, the function pointer field is set to the
1236 real function pointer, for JavaVM methods a pointer to the compiler is used
1239 *******************************************************************************/
1241 static bool method_load(classbuffer *cb, classinfo *c, methodinfo *m)
1249 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1250 initObjectLock(&m->header);
1255 count_all_methods++;
1258 m->thrownexceptionscount = 0;
1259 m->linenumbercount = 0;
1262 m->nativelyoverloaded = false;
1264 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1267 m->flags = suck_u2(cb);
1269 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1273 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1278 if (!is_valid_name_utf(m->name))
1279 panic("Method with invalid name");
1281 if (m->name->text[0] == '<'
1282 && m->name != utf_init && m->name != utf_clinit)
1283 panic("Method with invalid special name");
1286 argcount = checkmethoddescriptor(c, m->descriptor);
1288 if (!(m->flags & ACC_STATIC))
1289 argcount++; /* count the 'this' argument */
1292 if (argcount > 255) {
1294 new_classformaterror(c, "Too many arguments in signature");
1298 /* check flag consistency */
1299 if (m->name != utf_clinit) {
1300 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1302 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1304 new_classformaterror(c,
1305 "Illegal method modifiers: 0x%X",
1310 if (m->flags & ACC_ABSTRACT) {
1311 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1312 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1314 new_classformaterror(c,
1315 "Illegal method modifiers: 0x%X",
1321 if (c->flags & ACC_INTERFACE) {
1322 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1324 new_classformaterror(c,
1325 "Illegal method modifiers: 0x%X",
1331 if (m->name == utf_init) {
1332 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1333 ACC_NATIVE | ACC_ABSTRACT))
1334 panic("Instance initialization method has invalid flags set");
1340 m->basicblockcount = 0;
1341 m->basicblocks = NULL;
1342 m->basicblockindex = NULL;
1343 m->instructioncount = 0;
1344 m->instructions = NULL;
1347 m->exceptiontable = NULL;
1348 m->stubroutine = NULL;
1350 m->entrypoint = NULL;
1351 m->methodUsed = NOTUSED;
1354 m->subRedefsUsed = 0;
1358 if (!(m->flags & ACC_NATIVE)) {
1359 m->stubroutine = createcompilerstub(m);
1362 /*if (useinlining) {
1363 log_text("creating native stub:");
1366 functionptr f = native_findfunction(c->name, m->name, m->descriptor,
1367 (m->flags & ACC_STATIC) != 0);
1368 #ifdef STATIC_CLASSPATH
1372 m->stubroutine = createnativestub(f, m);
1376 if (!check_classbuffer_size(cb, 2))
1379 attrnum = suck_u2(cb);
1380 for (i = 0; i < attrnum; i++) {
1383 if (!check_classbuffer_size(cb, 2))
1386 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1389 if (aname == utf_code) {
1390 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1392 new_classformaterror(c,
1393 "Code attribute in native or abstract methods");
1400 new_classformaterror(c, "Multiple Code attributes");
1405 if (!check_classbuffer_size(cb, 4 + 2 + 2))
1409 m->maxstack = suck_u2(cb);
1410 m->maxlocals = suck_u2(cb);
1412 if (m->maxlocals < argcount) {
1414 new_classformaterror(c, "Arguments can't fit into locals");
1419 if (!check_classbuffer_size(cb, 4))
1422 m->jcodelength = suck_u4(cb);
1424 if (m->jcodelength == 0) {
1426 new_classformaterror(c, "Code of a method has length 0");
1431 if (m->jcodelength > 65535) {
1433 new_classformaterror(c,
1434 "Code of a method longer than 65535 bytes");
1439 if (!check_classbuffer_size(cb, m->jcodelength))
1442 m->jcode = MNEW(u1, m->jcodelength);
1443 suck_nbytes(m->jcode, cb, m->jcodelength);
1445 if (!check_classbuffer_size(cb, 2))
1448 m->exceptiontablelength = suck_u2(cb);
1449 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->exceptiontablelength))
1452 m->exceptiontable = MNEW(exceptiontable, m->exceptiontablelength);
1454 #if defined(STATISTICS)
1456 count_vmcode_len += m->jcodelength + 18;
1457 count_extable_len += 8 * m->exceptiontablelength;
1461 for (j = 0; j < m->exceptiontablelength; j++) {
1463 m->exceptiontable[j].startpc = suck_u2(cb);
1464 m->exceptiontable[j].endpc = suck_u2(cb);
1465 m->exceptiontable[j].handlerpc = suck_u2(cb);
1469 m->exceptiontable[j].catchtype = NULL;
1472 if (!(m->exceptiontable[j].catchtype =
1473 class_getconstant(c, idx, CONSTANT_Class)))
1478 if (!check_classbuffer_size(cb, 2))
1481 codeattrnum = suck_u2(cb);
1483 for (; codeattrnum > 0; codeattrnum--) {
1486 if (!check_classbuffer_size(cb, 2))
1489 if (!(caname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1492 if (caname == utf_linenumbertable) {
1495 if (!check_classbuffer_size(cb, 4 + 2))
1499 m->linenumbercount = suck_u2(cb);
1501 if (!check_classbuffer_size(cb,
1502 (2 + 2) * m->linenumbercount))
1505 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1507 for (lncid = 0; lncid < m->linenumbercount; lncid++) {
1508 m->linenumbers[lncid].start_pc = suck_u2(cb);
1509 m->linenumbers[lncid].line_number = suck_u2(cb);
1513 if (!skipattributes(cb, codeattrnum))
1519 if (!skipattributebody(cb))
1524 } else if (aname == utf_exceptions) {
1527 if (m->thrownexceptions) {
1529 new_classformaterror(c, "Multiple Exceptions attributes");
1533 if (!check_classbuffer_size(cb, 4 + 2))
1536 suck_u4(cb); /* length */
1537 m->thrownexceptionscount = suck_u2(cb);
1539 if (!check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1542 m->thrownexceptions = MNEW(classinfo*, m->thrownexceptionscount);
1544 for (j = 0; j < m->thrownexceptionscount; j++) {
1545 if (!((m->thrownexceptions)[j] =
1546 class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1551 if (!skipattributebody(cb))
1556 if (!m->jcode && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1557 *exceptionptr = new_classformaterror(c, "Missing Code attribute");
1562 /* everything was ok */
1563 /* utf_display(m->name);
1564 printf("\nexceptiontablelength:%ld\n",m->exceptiontablelength);*/
1570 /********************* Function: method_free ***********************************
1572 frees all memory that was allocated for this method
1574 *******************************************************************************/
1576 static void method_free(methodinfo *m)
1579 MFREE(m->jcode, u1, m->jcodelength);
1581 if (m->exceptiontable)
1582 MFREE(m->exceptiontable, exceptiontable, m->exceptiontablelength);
1585 CFREE(m->mcode, m->mcodelength);
1587 if (m->stubroutine) {
1588 if (m->flags & ACC_NATIVE) {
1589 removenativestub(m->stubroutine);
1592 removecompilerstub(m->stubroutine);
1598 /************** Function: method_display (debugging only) **************/
1600 void method_display(methodinfo *m)
1603 printflags(m->flags);
1605 utf_display(m->name);
1607 utf_display(m->descriptor);
1611 /************** Function: method_display_w_class (debugging only) **************/
1613 void method_display_w_class(methodinfo *m)
1615 printflags(m->class->flags);
1616 printf(" "); fflush(stdout);
1617 utf_display(m->class->name);
1618 printf(".");fflush(stdout);
1621 printflags(m->flags);
1622 printf(" "); fflush(stdout);
1623 utf_display(m->name);
1624 printf(" "); fflush(stdout);
1625 utf_display(m->descriptor);
1626 printf("\n"); fflush(stdout);
1629 /************** Function: method_display_flags_last (debugging only) **************/
1631 void method_display_flags_last(methodinfo *m)
1634 utf_display(m->name);
1636 utf_display(m->descriptor);
1638 printflags(m->flags);
1643 /******************** Function: method_canoverwrite ****************************
1645 Check if m and old are identical with respect to type and name. This means
1646 that old can be overwritten with m.
1648 *******************************************************************************/
1650 static bool method_canoverwrite(methodinfo *m, methodinfo *old)
1652 if (m->name != old->name) return false;
1653 if (m->descriptor != old->descriptor) return false;
1654 if (m->flags & ACC_STATIC) return false;
1659 /******************** function: class_loadcpool ********************************
1661 loads the constantpool of a class,
1662 the entries are transformed into a simpler format
1663 by resolving references
1664 (a detailed overview of the compact structures can be found in global.h)
1666 *******************************************************************************/
1668 static bool class_loadcpool(classbuffer *cb, classinfo *c)
1671 /* The following structures are used to save information which cannot be
1672 processed during the first pass. After the complete constantpool has
1673 been traversed the references can be resolved.
1674 (only in specific order) */
1676 /* CONSTANT_Class entries */
1677 typedef struct forward_class {
1678 struct forward_class *next;
1683 /* CONSTANT_String */
1684 typedef struct forward_string {
1685 struct forward_string *next;
1690 /* CONSTANT_NameAndType */
1691 typedef struct forward_nameandtype {
1692 struct forward_nameandtype *next;
1696 } forward_nameandtype;
1698 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
1699 typedef struct forward_fieldmethint {
1700 struct forward_fieldmethint *next;
1704 u2 nameandtype_index;
1705 } forward_fieldmethint;
1710 forward_class *forward_classes = NULL;
1711 forward_string *forward_strings = NULL;
1712 forward_nameandtype *forward_nameandtypes = NULL;
1713 forward_fieldmethint *forward_fieldmethints = NULL;
1716 forward_string *nfs;
1717 forward_nameandtype *nfn;
1718 forward_fieldmethint *nff;
1724 /* number of entries in the constant_pool table plus one */
1725 if (!check_classbuffer_size(cb, 2))
1728 cpcount = c->cpcount = suck_u2(cb);
1730 /* allocate memory */
1731 cptags = c->cptags = MNEW(u1, cpcount);
1732 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
1735 *exceptionptr = new_classformaterror(c, "Illegal constant pool size");
1739 #if defined(STATISTICS)
1741 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
1744 /* initialize constantpool */
1745 for (idx = 0; idx < cpcount; idx++) {
1746 cptags[idx] = CONSTANT_UNUSED;
1747 cpinfos[idx] = NULL;
1751 /******* first pass *******/
1752 /* entries which cannot be resolved now are written into
1753 temporary structures and traversed again later */
1756 while (idx < cpcount) {
1759 /* get constant type */
1760 if (!check_classbuffer_size(cb, 1))
1766 case CONSTANT_Class:
1767 nfc = NEW(forward_class);
1769 nfc->next = forward_classes;
1770 forward_classes = nfc;
1772 nfc->thisindex = idx;
1773 /* reference to CONSTANT_NameAndType */
1774 if (!check_classbuffer_size(cb, 2))
1777 nfc->name_index = suck_u2(cb);
1782 case CONSTANT_String:
1783 nfs = NEW(forward_string);
1785 nfs->next = forward_strings;
1786 forward_strings = nfs;
1788 nfs->thisindex = idx;
1790 /* reference to CONSTANT_Utf8_info with string characters */
1791 if (!check_classbuffer_size(cb, 2))
1794 nfs->string_index = suck_u2(cb);
1799 case CONSTANT_NameAndType:
1800 nfn = NEW(forward_nameandtype);
1802 nfn->next = forward_nameandtypes;
1803 forward_nameandtypes = nfn;
1805 nfn->thisindex = idx;
1807 if (!check_classbuffer_size(cb, 2 + 2))
1810 /* reference to CONSTANT_Utf8_info containing simple name */
1811 nfn->name_index = suck_u2(cb);
1813 /* reference to CONSTANT_Utf8_info containing field or method
1815 nfn->sig_index = suck_u2(cb);
1820 case CONSTANT_Fieldref:
1821 case CONSTANT_Methodref:
1822 case CONSTANT_InterfaceMethodref:
1823 nff = NEW(forward_fieldmethint);
1825 nff->next = forward_fieldmethints;
1826 forward_fieldmethints = nff;
1828 nff->thisindex = idx;
1832 if (!check_classbuffer_size(cb, 2 + 2))
1835 /* class or interface type that contains the declaration of the
1837 nff->class_index = suck_u2(cb);
1839 /* name and descriptor of the field or method */
1840 nff->nameandtype_index = suck_u2(cb);
1845 case CONSTANT_Integer: {
1846 constant_integer *ci = NEW(constant_integer);
1848 #if defined(STATISTICS)
1850 count_const_pool_len += sizeof(constant_integer);
1853 if (!check_classbuffer_size(cb, 4))
1856 ci->value = suck_s4(cb);
1857 cptags[idx] = CONSTANT_Integer;
1864 case CONSTANT_Float: {
1865 constant_float *cf = NEW(constant_float);
1867 #if defined(STATISTICS)
1869 count_const_pool_len += sizeof(constant_float);
1872 if (!check_classbuffer_size(cb, 4))
1875 cf->value = suck_float(cb);
1876 cptags[idx] = CONSTANT_Float;
1883 case CONSTANT_Long: {
1884 constant_long *cl = NEW(constant_long);
1886 #if defined(STATISTICS)
1888 count_const_pool_len += sizeof(constant_long);
1891 if (!check_classbuffer_size(cb, 8))
1894 cl->value = suck_s8(cb);
1895 cptags[idx] = CONSTANT_Long;
1898 if (idx > cpcount) {
1900 new_classformaterror(c, "Invalid constant pool entry");
1906 case CONSTANT_Double: {
1907 constant_double *cd = NEW(constant_double);
1909 #if defined(STATISTICS)
1911 count_const_pool_len += sizeof(constant_double);
1914 if (!check_classbuffer_size(cb, 8))
1917 cd->value = suck_double(cb);
1918 cptags[idx] = CONSTANT_Double;
1921 if (idx > cpcount) {
1923 new_classformaterror(c, "Invalid constant pool entry");
1929 case CONSTANT_Utf8: {
1932 /* number of bytes in the bytes array (not string-length) */
1933 if (!check_classbuffer_size(cb, 2))
1936 length = suck_u2(cb);
1937 cptags[idx] = CONSTANT_Utf8;
1939 /* validate the string */
1940 if (!check_classbuffer_size(cb, length))
1944 !is_valid_utf((char *) (cb->pos + 1),
1945 (char *) (cb->pos + 1 + length))) {
1946 dolog("Invalid UTF-8 string (constant pool index %d)",idx);
1947 panic("Invalid UTF-8 string");
1949 /* insert utf-string into the utf-symboltable */
1950 cpinfos[idx] = utf_new_intern((char *) (cb->pos + 1), length);
1952 /* skip bytes of the string (buffer size check above) */
1953 skip_nbytes(cb, length);
1960 new_classformaterror(c, "Illegal constant pool type");
1966 /* resolve entries in temporary structures */
1968 while (forward_classes) {
1970 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
1972 if (opt_verify && !is_valid_name_utf(name))
1973 panic("Class reference with invalid name");
1975 cptags[forward_classes->thisindex] = CONSTANT_Class;
1976 /* retrieve class from class-table */
1979 tc = class_new_intern(name);
1981 if (!class_load(tc))
1984 /* link the class later, because we cannot link the class currently
1986 list_addfirst(&unlinkedclasses, tc);
1988 cpinfos[forward_classes->thisindex] = tc;
1991 cpinfos[forward_classes->thisindex] = class_new(name);
1994 nfc = forward_classes;
1995 forward_classes = forward_classes->next;
1996 FREE(nfc, forward_class);
1999 while (forward_strings) {
2001 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
2003 /* resolve utf-string */
2004 cptags[forward_strings->thisindex] = CONSTANT_String;
2005 cpinfos[forward_strings->thisindex] = text;
2007 nfs = forward_strings;
2008 forward_strings = forward_strings->next;
2009 FREE(nfs, forward_string);
2012 while (forward_nameandtypes) {
2013 constant_nameandtype *cn = NEW(constant_nameandtype);
2015 #if defined(STATISTICS)
2017 count_const_pool_len += sizeof(constant_nameandtype);
2020 /* resolve simple name and descriptor */
2021 cn->name = class_getconstant(c,
2022 forward_nameandtypes->name_index,
2025 cn->descriptor = class_getconstant(c,
2026 forward_nameandtypes->sig_index,
2031 if (!is_valid_name_utf(cn->name))
2032 panic("NameAndType with invalid name");
2033 /* disallow referencing <clinit> among others */
2034 if (cn->name->text[0] == '<' && cn->name != utf_init)
2035 panic("NameAndType with invalid special name");
2038 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
2039 cpinfos[forward_nameandtypes->thisindex] = cn;
2041 nfn = forward_nameandtypes;
2042 forward_nameandtypes = forward_nameandtypes->next;
2043 FREE(nfn, forward_nameandtype);
2046 while (forward_fieldmethints) {
2047 constant_nameandtype *nat;
2048 constant_FMIref *fmi = NEW(constant_FMIref);
2050 #if defined(STATISTICS)
2052 count_const_pool_len += sizeof(constant_FMIref);
2054 /* resolve simple name and descriptor */
2055 nat = class_getconstant(c,
2056 forward_fieldmethints->nameandtype_index,
2057 CONSTANT_NameAndType);
2059 fmi->class = class_getconstant(c,
2060 forward_fieldmethints->class_index,
2062 fmi->name = nat->name;
2063 fmi->descriptor = nat->descriptor;
2065 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
2066 cpinfos[forward_fieldmethints->thisindex] = fmi;
2068 switch (forward_fieldmethints->tag) {
2069 case CONSTANT_Fieldref: /* check validity of descriptor */
2070 checkfielddescriptor(fmi->descriptor->text,
2071 utf_end(fmi->descriptor));
2073 case CONSTANT_InterfaceMethodref:
2074 case CONSTANT_Methodref: /* check validity of descriptor */
2075 checkmethoddescriptor(c, fmi->descriptor);
2079 nff = forward_fieldmethints;
2080 forward_fieldmethints = forward_fieldmethints->next;
2081 FREE(nff, forward_fieldmethint);
2084 /* everything was ok */
2090 /********************** Function: class_load ***********************************
2092 Loads everything interesting about a class from the class file. The
2093 'classinfo' structure must have been allocated previously.
2095 The super class and the interfaces implemented by this class need not be
2096 loaded. The link is set later by the function 'class_link'.
2098 The loaded class is removed from the list 'unloadedclasses' and added to
2099 the list 'unlinkedclasses'.
2101 *******************************************************************************/
2103 classinfo *class_load_intern(classbuffer *cb);
2105 classinfo *class_load(classinfo *c)
2110 /* enter a monitor on the class */
2112 builtin_monitorenter((java_objectheader *) c);
2114 /* maybe the class is already loaded */
2116 builtin_monitorexit((java_objectheader *) c);
2123 if (getcompilingtime)
2124 compilingtime_stop();
2127 loadingtime_start();
2129 /* load classdata, throw exception on error */
2131 if ((cb = suck_start(c)) == NULL) {
2132 /* this means, the classpath was not set properly */
2133 if (c->name == utf_java_lang_Object)
2134 throw_cacao_exception_exit(string_java_lang_NoClassDefFoundError,
2135 "java/lang/Object");
2138 new_exception_utfmessage(string_java_lang_NoClassDefFoundError,
2141 builtin_monitorexit((java_objectheader *) c);
2146 /* call the internal function */
2147 r = class_load_intern(cb);
2149 /* if return value is NULL, we had a problem and the class is not loaded */
2153 /* now free the allocated memory, otherwise we could ran into a DOS */
2165 if (getcompilingtime)
2166 compilingtime_start();
2168 /* leave the monitor */
2170 builtin_monitorexit((java_objectheader *) c);
2176 classinfo *class_load_intern(classbuffer *cb)
2182 char msg[MAXLOGTEXT]; /* maybe we get an exception */
2184 /* get the classbuffer's class */
2187 /* maybe the class is already loaded */
2191 #if defined(STATISTICS)
2193 count_class_loads++;
2196 /* output for debugging purposes */
2198 log_message_class("Loading class: ", c);
2200 /* class is somewhat loaded */
2203 if (!check_classbuffer_size(cb, 4 + 2 + 2))
2206 /* check signature */
2207 if (suck_u4(cb) != MAGIC) {
2208 *exceptionptr = new_classformaterror(c, "Bad magic number");
2217 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
2219 new_unsupportedclassversionerror(c,
2220 "Unsupported major.minor version %d.%d",
2226 /* load the constant pool */
2227 if (!class_loadcpool(cb, c))
2231 c->erroneous_state = 0;
2232 c->initializing_thread = 0;
2234 c->classUsed = NOTUSED; /* not used initially CO-RT */
2238 if (!check_classbuffer_size(cb, 2))
2241 c->flags = suck_u2(cb);
2242 /*if (!(c->flags & ACC_PUBLIC)) { log_text("CLASS NOT PUBLIC"); } JOWENN*/
2244 /* check ACC flags consistency */
2245 if (c->flags & ACC_INTERFACE) {
2246 if (!(c->flags & ACC_ABSTRACT)) {
2247 /* We work around this because interfaces in JDK 1.1 are
2248 * not declared abstract. */
2250 c->flags |= ACC_ABSTRACT;
2251 /* panic("Interface class not declared abstract"); */
2254 if (c->flags & ACC_FINAL) {
2256 new_classformaterror(c,
2257 "Illegal class modifiers: 0x%X", c->flags);
2262 if (c->flags & ACC_SUPER) {
2263 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
2267 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
2269 new_classformaterror(c, "Illegal class modifiers: 0x%X", c->flags);
2274 if (!check_classbuffer_size(cb, 2 + 2))
2279 if (!(tc = class_getconstant(c, i, CONSTANT_Class)))
2283 utf_sprint(msg, c->name);
2284 sprintf(msg + strlen(msg), " (wrong name: ");
2285 utf_sprint(msg + strlen(msg), tc->name);
2286 sprintf(msg + strlen(msg), ")");
2289 new_exception_message(string_java_lang_NoClassDefFoundError, msg);
2294 /* retrieve superclass */
2295 if ((i = suck_u2(cb))) {
2296 if (!(c->super = class_getconstant(c, i, CONSTANT_Class)))
2299 /* java.lang.Object may not have a super class. */
2300 if (c->name == utf_java_lang_Object) {
2302 new_exception_message(string_java_lang_ClassFormatError,
2303 "java.lang.Object with superclass");
2308 /* Interfaces must have java.lang.Object as super class. */
2309 if ((c->flags & ACC_INTERFACE) &&
2310 c->super->name != utf_java_lang_Object) {
2312 new_exception_message(string_java_lang_ClassFormatError,
2313 "Interfaces must have java.lang.Object as superclass");
2321 /* This is only allowed for java.lang.Object. */
2322 if (c->name != utf_java_lang_Object) {
2323 *exceptionptr = new_classformaterror(c, "Bad superclass index");
2329 /* retrieve interfaces */
2330 if (!check_classbuffer_size(cb, 2))
2333 c->interfacescount = suck_u2(cb);
2335 if (!check_classbuffer_size(cb, 2 * c->interfacescount))
2338 c->interfaces = MNEW(classinfo*, c->interfacescount);
2339 for (i = 0; i < c->interfacescount; i++) {
2340 if (!(c->interfaces[i] = class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2345 if (!check_classbuffer_size(cb, 2))
2348 c->fieldscount = suck_u2(cb);
2349 c->fields = GCNEW(fieldinfo, c->fieldscount);
2350 /* c->fields = MNEW(fieldinfo, c->fieldscount); */
2351 for (i = 0; i < c->fieldscount; i++) {
2352 if (!field_load(cb, c, &(c->fields[i])))
2357 if (!check_classbuffer_size(cb, 2))
2360 c->methodscount = suck_u2(cb);
2361 c->methods = GCNEW(methodinfo, c->methodscount);
2362 /* c->methods = MNEW(methodinfo, c->methodscount); */
2363 for (i = 0; i < c->methodscount; i++) {
2364 if (!method_load(cb, c, &(c->methods[i])))
2368 /* Check if all fields and methods can be uniquely
2369 * identified by (name,descriptor). */
2371 /* We use a hash table here to avoid making the
2372 * average case quadratic in # of methods, fields.
2374 static int shift = 0;
2376 u2 *next; /* for chaining colliding hash entries */
2382 /* Allocate hashtable */
2383 len = c->methodscount;
2384 if (len < c->fieldscount) len = c->fieldscount;
2386 hashtab = MNEW(u2,(hashlen + len));
2387 next = hashtab + hashlen;
2389 /* Determine bitshift (to get good hash values) */
2399 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2401 for (i = 0; i < c->fieldscount; ++i) {
2402 fieldinfo *fi = c->fields + i;
2404 /* It's ok if we lose bits here */
2405 index = ((((size_t) fi->name) +
2406 ((size_t) fi->descriptor)) >> shift) % hashlen;
2408 if ((old = hashtab[index])) {
2412 if (c->fields[old].name == fi->name &&
2413 c->fields[old].descriptor == fi->descriptor) {
2415 new_classformaterror(c,
2416 "Repetitive field name/signature");
2420 } while ((old = next[old]));
2422 hashtab[index] = i + 1;
2426 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2428 for (i = 0; i < c->methodscount; ++i) {
2429 methodinfo *mi = c->methods + i;
2431 /* It's ok if we lose bits here */
2432 index = ((((size_t) mi->name) +
2433 ((size_t) mi->descriptor)) >> shift) % hashlen;
2437 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2438 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2442 if ((old = hashtab[index])) {
2446 if (c->methods[old].name == mi->name &&
2447 c->methods[old].descriptor == mi->descriptor) {
2449 new_classformaterror(c,
2450 "Repetitive method name/signature");
2454 } while ((old = next[old]));
2456 hashtab[index] = i + 1;
2459 MFREE(hashtab, u2, (hashlen + len));
2462 #if defined(STATISTICS)
2464 count_class_infos += sizeof(classinfo*) * c->interfacescount;
2465 count_class_infos += sizeof(fieldinfo) * c->fieldscount;
2466 count_class_infos += sizeof(methodinfo) * c->methodscount;
2470 /* load attribute structures */
2471 if (!check_classbuffer_size(cb, 2))
2474 if (!attribute_load(cb, c, suck_u2(cb)))
2478 /* Pre java 1.5 version don't check this. This implementation is like
2479 java 1.5 do it: for class file version 45.3 we don't check it, older
2480 versions are checked.
2482 if ((ma == 45 && mi > 3) || ma > 45) {
2483 /* check if all data has been read */
2484 s4 classdata_left = ((cb->data + cb->size) - cb->pos - 1);
2486 if (classdata_left > 0) {
2488 new_classformaterror(c, "Extra bytes at the end of class file");
2495 log_message_class("Loading done class: ", c);
2502 /************** internal Function: class_highestinterface **********************
2504 Used by the function class_link to determine the amount of memory needed
2505 for the interface table.
2507 *******************************************************************************/
2509 static s4 class_highestinterface(classinfo *c)
2514 /* check for ACC_INTERFACE bit already done in class_link_intern */
2517 for (i = 0; i < c->interfacescount; i++) {
2518 s4 h2 = class_highestinterface(c->interfaces[i]);
2526 /* class_addinterface **********************************************************
2528 Is needed by class_link for adding a VTBL to a class. All interfaces
2529 implemented by ic are added as well.
2531 *******************************************************************************/
2533 static void class_addinterface(classinfo *c, classinfo *ic)
2537 vftbl_t *v = c->vftbl;
2539 if (i >= v->interfacetablelength)
2540 panic ("Inernal error: interfacetable overflow");
2542 if (v->interfacetable[-i])
2545 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
2546 v->interfacevftbllength[i] = 1;
2547 v->interfacetable[-i] = MNEW(methodptr, 1);
2548 v->interfacetable[-i][0] = NULL;
2551 v->interfacevftbllength[i] = ic->methodscount;
2552 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
2554 #if defined(STATISTICS)
2556 count_vftbl_len += sizeof(methodptr) *
2557 (ic->methodscount + (ic->methodscount == 0));
2560 for (j = 0; j < ic->methodscount; j++) {
2563 for (m = 0; m < sc->methodscount; m++) {
2564 methodinfo *mi = &(sc->methods[m]);
2565 if (method_canoverwrite(mi, &(ic->methods[j]))) {
2566 v->interfacetable[-i][j] = v->table[mi->vftblindex];
2577 for (j = 0; j < ic->interfacescount; j++)
2578 class_addinterface(c, ic->interfaces[j]);
2582 /******************* Function: class_new_array *********************************
2584 This function is called by class_new to setup an array class.
2586 *******************************************************************************/
2588 void class_new_array(classinfo *c)
2590 classinfo *comp = NULL;
2594 /* Check array class name */
2595 namelen = c->name->blength;
2596 if (namelen < 2 || c->name->text[0] != '[')
2597 panic("Invalid array class name");
2599 /* Check the component type */
2600 switch (c->name->text[1]) {
2602 /* c is an array of arrays. We have to create the component class. */
2604 comp = class_new_intern(utf_new_intern(c->name->text + 1,
2607 list_addfirst(&unlinkedclasses, comp);
2610 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2615 /* c is an array of objects. */
2616 if (namelen < 4 || c->name->text[namelen - 1] != ';')
2617 panic("Invalid array class name");
2620 comp = class_new_intern(utf_new_intern(c->name->text + 2,
2623 list_addfirst(&unlinkedclasses, comp);
2626 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2631 /* Setup the array class */
2632 c->super = class_java_lang_Object;
2633 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2635 c->interfacescount = 2;
2636 c->interfaces = MNEW(classinfo*, 2);
2641 tc = class_new_intern(utf_new_char("java/lang/Cloneable"));
2643 list_addfirst(&unlinkedclasses, tc);
2644 c->interfaces[0] = tc;
2646 tc = class_new_intern(utf_new_char("java/io/Serializable"));
2648 list_addfirst(&unlinkedclasses, tc);
2649 c->interfaces[1] = tc;
2652 c->interfaces[0] = class_new(utf_new_char("java/lang/Cloneable"));
2653 c->interfaces[1] = class_new(utf_new_char("java/io/Serializable"));
2656 c->methodscount = 1;
2657 c->methods = MNEW(methodinfo, c->methodscount);
2660 memset(clone, 0, sizeof(methodinfo));
2661 clone->flags = ACC_PUBLIC;
2662 clone->name = utf_new_char("clone");
2663 clone->descriptor = utf_new_char("()Ljava/lang/Object;");
2665 clone->stubroutine = createnativestub((functionptr) &builtin_clone_array, clone);
2666 clone->monoPoly = MONO;
2668 /* XXX: field: length? */
2670 /* array classes are not loaded from class files */
2675 /****************** Function: class_link_array *********************************
2677 This function is called by class_link to create the
2678 arraydescriptor for an array class.
2680 This function returns NULL if the array cannot be linked because
2681 the component type has not been linked yet.
2683 *******************************************************************************/
2685 static arraydescriptor *class_link_array(classinfo *c)
2687 classinfo *comp = NULL;
2688 s4 namelen = c->name->blength;
2689 arraydescriptor *desc;
2692 /* Check the component type */
2693 switch (c->name->text[1]) {
2695 /* c is an array of arrays. */
2696 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2698 panic("Could not find component array class.");
2702 /* c is an array of objects. */
2703 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2705 panic("Could not find component class.");
2709 /* If the component type has not been linked, link it now */
2710 if (comp && !comp->linked) {
2712 if (!class_load(comp))
2715 if (!class_link(comp))
2719 /* Allocate the arraydescriptor */
2720 desc = NEW(arraydescriptor);
2723 /* c is an array of references */
2724 desc->arraytype = ARRAYTYPE_OBJECT;
2725 desc->componentsize = sizeof(void*);
2726 desc->dataoffset = OFFSET(java_objectarray, data);
2728 compvftbl = comp->vftbl;
2730 panic("Component class has no vftbl");
2731 desc->componentvftbl = compvftbl;
2733 if (compvftbl->arraydesc) {
2734 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
2735 if (compvftbl->arraydesc->dimension >= 255)
2736 panic("Creating array of dimension >255");
2737 desc->dimension = compvftbl->arraydesc->dimension + 1;
2738 desc->elementtype = compvftbl->arraydesc->elementtype;
2741 desc->elementvftbl = compvftbl;
2742 desc->dimension = 1;
2743 desc->elementtype = ARRAYTYPE_OBJECT;
2747 /* c is an array of a primitive type */
2748 switch (c->name->text[1]) {
2750 desc->arraytype = ARRAYTYPE_BOOLEAN;
2751 desc->dataoffset = OFFSET(java_booleanarray,data);
2752 desc->componentsize = sizeof(u1);
2756 desc->arraytype = ARRAYTYPE_BYTE;
2757 desc->dataoffset = OFFSET(java_bytearray,data);
2758 desc->componentsize = sizeof(u1);
2762 desc->arraytype = ARRAYTYPE_CHAR;
2763 desc->dataoffset = OFFSET(java_chararray,data);
2764 desc->componentsize = sizeof(u2);
2768 desc->arraytype = ARRAYTYPE_DOUBLE;
2769 desc->dataoffset = OFFSET(java_doublearray,data);
2770 desc->componentsize = sizeof(double);
2774 desc->arraytype = ARRAYTYPE_FLOAT;
2775 desc->dataoffset = OFFSET(java_floatarray,data);
2776 desc->componentsize = sizeof(float);
2780 desc->arraytype = ARRAYTYPE_INT;
2781 desc->dataoffset = OFFSET(java_intarray,data);
2782 desc->componentsize = sizeof(s4);
2786 desc->arraytype = ARRAYTYPE_LONG;
2787 desc->dataoffset = OFFSET(java_longarray,data);
2788 desc->componentsize = sizeof(s8);
2792 desc->arraytype = ARRAYTYPE_SHORT;
2793 desc->dataoffset = OFFSET(java_shortarray,data);
2794 desc->componentsize = sizeof(s2);
2798 panic("Invalid array class name");
2801 desc->componentvftbl = NULL;
2802 desc->elementvftbl = NULL;
2803 desc->dimension = 1;
2804 desc->elementtype = desc->arraytype;
2811 /********************** Function: class_link ***********************************
2813 Tries to link a class. The function calculates the length in bytes that
2814 an instance of this class requires as well as the VTBL for methods and
2817 *******************************************************************************/
2819 static classinfo *class_link_intern(classinfo *c);
2821 classinfo *class_link(classinfo *c)
2825 /* enter a monitor on the class */
2827 builtin_monitorenter((java_objectheader *) c);
2829 /* maybe the class is already linked */
2831 builtin_monitorexit((java_objectheader *) c);
2838 if (getcompilingtime)
2839 compilingtime_stop();
2842 loadingtime_start();
2844 /* call the internal function */
2845 r = class_link_intern(c);
2847 /* if return value is NULL, we had a problem and the class is not linked */
2856 if (getcompilingtime)
2857 compilingtime_start();
2859 /* leave the monitor */
2861 builtin_monitorexit((java_objectheader *) c);
2867 static classinfo *class_link_intern(classinfo *c)
2869 s4 supervftbllength; /* vftbllegnth of super class */
2870 s4 vftbllength; /* vftbllength of current class */
2871 s4 interfacetablelength; /* interface table length */
2872 classinfo *super; /* super class */
2873 classinfo *tc; /* temporary class variable */
2874 vftbl_t *v; /* vftbl of current class */
2875 s4 i; /* interface/method/field counter */
2876 arraydescriptor *arraydesc; /* descriptor for array classes */
2878 /* maybe the class is already linked */
2882 /* maybe the class is not loaded */
2888 log_message_class("Linking class: ", c);
2890 /* ok, this class is somewhat linked */
2895 /* check interfaces */
2897 for (i = 0; i < c->interfacescount; i++) {
2898 tc = c->interfaces[i];
2900 /* detect circularity */
2903 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2909 if (!class_load(tc))
2912 if (!(tc->flags & ACC_INTERFACE)) {
2914 new_exception_message(string_java_lang_IncompatibleClassChangeError,
2915 "Implementing class");
2920 if (!class_link(tc))
2924 /* check super class */
2928 if (super == NULL) { /* class java.lang.Object */
2930 c->classUsed = USED; /* Object class is always used CO-RT*/
2932 c->instancesize = sizeof(java_objectheader);
2934 vftbllength = supervftbllength = 0;
2936 c->finalizer = NULL;
2939 /* detect circularity */
2942 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2948 if (!class_load(super))
2951 if (super->flags & ACC_INTERFACE) {
2952 /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
2953 panic("Interface specified as super class");
2956 /* Don't allow extending final classes */
2957 if (super->flags & ACC_FINAL) {
2959 new_exception_message(string_java_lang_VerifyError,
2960 "Cannot inherit from final class");
2965 if (!class_link(super))
2968 /* handle array classes */
2969 if (c->name->text[0] == '[')
2970 if (!(arraydesc = class_link_array(c)))
2973 if (c->flags & ACC_INTERFACE)
2974 c->index = interfaceindex++;
2976 c->index = super->index + 1;
2978 c->instancesize = super->instancesize;
2980 vftbllength = supervftbllength = super->vftbl->vftbllength;
2982 c->finalizer = super->finalizer;
2985 /* compute vftbl length */
2987 for (i = 0; i < c->methodscount; i++) {
2988 methodinfo *m = &(c->methods[i]);
2990 if (!(m->flags & ACC_STATIC)) { /* is instance method */
2995 for (j = 0; j < tc->methodscount; j++) {
2996 if (method_canoverwrite(m, &(tc->methods[j]))) {
2997 if (tc->methods[j].flags & ACC_PRIVATE)
2998 goto notfoundvftblindex;
3000 if (tc->methods[j].flags & ACC_FINAL) {
3001 /* class a overrides final method . */
3003 new_exception(string_java_lang_VerifyError);
3006 m->vftblindex = tc->methods[j].vftblindex;
3007 goto foundvftblindex;
3013 m->vftblindex = (vftbllength++);
3019 #if defined(STATISTICS)
3022 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
3025 /* compute interfacetable length */
3027 interfacetablelength = 0;
3030 for (i = 0; i < tc->interfacescount; i++) {
3031 s4 h = class_highestinterface(tc->interfaces[i]) + 1;
3032 if (h > interfacetablelength)
3033 interfacetablelength = h;
3038 /* allocate virtual function table */
3040 v = (vftbl_t*) mem_alloc(sizeof(vftbl_t) + sizeof(methodptr) *
3041 (vftbllength - 1) + sizeof(methodptr*) *
3042 (interfacetablelength - (interfacetablelength > 0)));
3043 v = (vftbl_t*) (((methodptr*) v) + (interfacetablelength - 1) *
3044 (interfacetablelength > 1));
3045 c->header.vftbl = c->vftbl = v;
3047 v->vftbllength = vftbllength;
3048 v->interfacetablelength = interfacetablelength;
3049 v->arraydesc = arraydesc;
3051 /* store interface index in vftbl */
3052 if (c->flags & ACC_INTERFACE)
3053 v->baseval = -(c->index);
3055 /* copy virtual function table of super class */
3057 for (i = 0; i < supervftbllength; i++)
3058 v->table[i] = super->vftbl->table[i];
3060 /* add method stubs into virtual function table */
3062 for (i = 0; i < c->methodscount; i++) {
3063 methodinfo *m = &(c->methods[i]);
3064 if (!(m->flags & ACC_STATIC)) {
3065 v->table[m->vftblindex] = m->stubroutine;
3069 /* compute instance size and offset of each field */
3071 for (i = 0; i < c->fieldscount; i++) {
3073 fieldinfo *f = &(c->fields[i]);
3075 if (!(f->flags & ACC_STATIC)) {
3076 dsize = desc_typesize(f->descriptor);
3077 c->instancesize = ALIGN(c->instancesize, dsize);
3078 f->offset = c->instancesize;
3079 c->instancesize += dsize;
3083 /* initialize interfacetable and interfacevftbllength */
3085 v->interfacevftbllength = MNEW(s4, interfacetablelength);
3087 #if defined(STATISTICS)
3089 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
3092 for (i = 0; i < interfacetablelength; i++) {
3093 v->interfacevftbllength[i] = 0;
3094 v->interfacetable[-i] = NULL;
3097 /* add interfaces */
3099 for (tc = c; tc != NULL; tc = tc->super) {
3100 for (i = 0; i < tc->interfacescount; i++) {
3101 class_addinterface(c, tc->interfaces[i]);
3105 /* add finalizer method (not for java.lang.Object) */
3110 fi = class_findmethod(c, utf_finalize, utf_fidesc);
3113 if (!(fi->flags & ACC_STATIC)) {
3121 loader_compute_subclasses(c);
3124 log_message_class("Linking done class: ", c);
3126 /* just return c to show that we didn't had a problem */
3132 /******************* Function: class_freepool **********************************
3134 Frees all resources used by this classes Constant Pool.
3136 *******************************************************************************/
3138 static void class_freecpool(classinfo *c)
3144 if (c->cptags && c->cpinfos) {
3145 for (idx = 0; idx < c->cpcount; idx++) {
3146 tag = c->cptags[idx];
3147 info = c->cpinfos[idx];
3151 case CONSTANT_Fieldref:
3152 case CONSTANT_Methodref:
3153 case CONSTANT_InterfaceMethodref:
3154 FREE(info, constant_FMIref);
3156 case CONSTANT_Integer:
3157 FREE(info, constant_integer);
3159 case CONSTANT_Float:
3160 FREE(info, constant_float);
3163 FREE(info, constant_long);
3165 case CONSTANT_Double:
3166 FREE(info, constant_double);
3168 case CONSTANT_NameAndType:
3169 FREE(info, constant_nameandtype);
3177 MFREE(c->cptags, u1, c->cpcount);
3180 MFREE(c->cpinfos, voidptr, c->cpcount);
3184 /*********************** Function: class_free **********************************
3186 Frees all resources used by the class.
3188 *******************************************************************************/
3190 void class_free(classinfo *c)
3198 MFREE(c->interfaces, classinfo*, c->interfacescount);
3201 for (i = 0; i < c->fieldscount; i++)
3202 field_free(&(c->fields[i]));
3203 /* MFREE(c->fields, fieldinfo, c->fieldscount); */
3207 for (i = 0; i < c->methodscount; i++)
3208 method_free(&(c->methods[i]));
3209 /* MFREE(c->methods, methodinfo, c->methodscount); */
3212 if ((v = c->vftbl) != NULL) {
3214 mem_free(v->arraydesc,sizeof(arraydescriptor));
3216 for (i = 0; i < v->interfacetablelength; i++) {
3217 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
3219 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
3221 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
3222 sizeof(methodptr*) * (v->interfacetablelength -
3223 (v->interfacetablelength > 0));
3224 v = (vftbl_t*) (((methodptr*) v) - (v->interfacetablelength - 1) *
3225 (v->interfacetablelength > 1));
3230 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
3232 /* if (c->classvftbl)
3233 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
3239 /************************* Function: class_findfield ***************************
3241 Searches a 'classinfo' structure for a field having the given name and
3244 *******************************************************************************/
3246 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
3250 for (i = 0; i < c->fieldscount; i++) {
3251 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
3252 return &(c->fields[i]);
3255 panic("Can not find field given in CONSTANT_Fieldref");
3257 /* keep compiler happy */
3262 /****************** Function: class_resolvefield_int ***************************
3264 This is an internally used helper function. Do not use this directly.
3266 Tries to resolve a field having the given name and type.
3267 If the field cannot be resolved, NULL is returned.
3269 *******************************************************************************/
3271 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
3276 /* search for field in class c */
3277 for (i = 0; i < c->fieldscount; i++) {
3278 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
3279 return &(c->fields[i]);
3283 /* try superinterfaces recursively */
3284 for (i = 0; i < c->interfacescount; ++i) {
3285 fi = class_resolvefield_int(c->interfaces[i], name, desc);
3290 /* try superclass */
3292 return class_resolvefield_int(c->super, name, desc);
3299 /********************* Function: class_resolvefield ***************************
3301 Resolves a reference from REFERER to a field with NAME and DESC in class C.
3303 If the field cannot be resolved the return value is NULL. If EXCEPT is
3304 true *exceptionptr is set, too.
3306 *******************************************************************************/
3308 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
3309 classinfo *referer, bool except)
3313 /* XXX resolve class c */
3314 /* XXX check access from REFERER to C */
3316 fi = class_resolvefield_int(c, name, desc);
3321 new_exception_utfmessage(string_java_lang_NoSuchFieldError,
3327 /* XXX check access rights */
3333 /************************* Function: class_findmethod **************************
3335 Searches a 'classinfo' structure for a method having the given name and
3336 type and returns the index in the class info structure.
3337 If type is NULL, it is ignored.
3339 *******************************************************************************/
3341 s4 class_findmethodIndex(classinfo *c, utf *name, utf *desc)
3345 for (i = 0; i < c->methodscount; i++) {
3347 /* utf_display_classname(c->name);printf("."); */
3348 /* utf_display(c->methods[i].name);printf("."); */
3349 /* utf_display(c->methods[i].descriptor); */
3352 if ((c->methods[i].name == name) && ((desc == NULL) ||
3353 (c->methods[i].descriptor == desc))) {
3362 /************************* Function: class_findmethod **************************
3364 Searches a 'classinfo' structure for a method having the given name and
3366 If type is NULL, it is ignored.
3368 *******************************************************************************/
3370 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
3372 s4 idx = class_findmethodIndex(c, name, desc);
3377 return &(c->methods[idx]);
3381 /*********************** Function: class_fetchmethod **************************
3383 like class_findmethod, but aborts with an error if the method is not found
3385 *******************************************************************************/
3387 methodinfo *class_fetchmethod(classinfo *c, utf *name, utf *desc)
3391 mi = class_findmethod(c, name, desc);
3394 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3395 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3396 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3397 panic("Method not found");
3404 /*********************** Function: class_findmethod_w**************************
3406 like class_findmethod, but logs a warning if the method is not found
3408 *******************************************************************************/
3410 methodinfo *class_findmethod_w(classinfo *c, utf *name, utf *desc, char *from)
3413 mi = class_findmethod(c, name, desc);
3416 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3417 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3418 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3420 if ( c->flags & ACC_PUBLIC ) log_plain(" PUBLIC ");
3421 if ( c->flags & ACC_PRIVATE ) log_plain(" PRIVATE ");
3422 if ( c->flags & ACC_PROTECTED ) log_plain(" PROTECTED ");
3423 if ( c->flags & ACC_STATIC ) log_plain(" STATIC ");
3424 if ( c->flags & ACC_FINAL ) log_plain(" FINAL ");
3425 if ( c->flags & ACC_SYNCHRONIZED ) log_plain(" SYNCHRONIZED ");
3426 if ( c->flags & ACC_VOLATILE ) log_plain(" VOLATILE ");
3427 if ( c->flags & ACC_TRANSIENT ) log_plain(" TRANSIENT ");
3428 if ( c->flags & ACC_NATIVE ) log_plain(" NATIVE ");
3429 if ( c->flags & ACC_INTERFACE ) log_plain(" INTERFACE ");
3430 if ( c->flags & ACC_ABSTRACT ) log_plain(" ABSTRACT ");
3433 log_plain(" : WARNING: Method not found");log_nl( );
3440 /************************* Function: class_findmethod_approx ******************
3442 like class_findmethod but ignores the return value when comparing the
3445 *******************************************************************************/
3447 methodinfo *class_findmethod_approx(classinfo *c, utf *name, utf *desc)
3451 for (i = 0; i < c->methodscount; i++) {
3452 if (c->methods[i].name == name) {
3453 utf *meth_descr = c->methods[i].descriptor;
3457 return &(c->methods[i]);
3459 if (desc->blength <= meth_descr->blength) {
3460 /* current position in utf text */
3461 char *desc_utf_ptr = desc->text;
3462 char *meth_utf_ptr = meth_descr->text;
3463 /* points behind utf strings */
3464 char *desc_end = utf_end(desc);
3465 char *meth_end = utf_end(meth_descr);
3468 /* compare argument types */
3469 while (desc_utf_ptr < desc_end && meth_utf_ptr < meth_end) {
3471 if ((ch = *desc_utf_ptr++) != (*meth_utf_ptr++))
3472 break; /* no match */
3475 return &(c->methods[i]); /* all parameter types equal */
3485 /***************** Function: class_resolvemethod_approx ***********************
3487 Searches a class and every super class for a method (without paying
3488 attention to the return value)
3490 *******************************************************************************/
3492 methodinfo *class_resolvemethod_approx(classinfo *c, utf *name, utf *desc)
3495 /* search for method (ignore returntype) */
3496 methodinfo *m = class_findmethod_approx(c, name, desc);
3499 /* search superclass */
3507 /************************* Function: class_resolvemethod ***********************
3509 Searches a class and every super class for a method.
3511 *******************************************************************************/
3513 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
3515 /*log_text("Trying to resolve a method");
3516 utf_display(c->name);
3518 utf_display(desc);*/
3521 /*log_text("Looking in:");
3522 utf_display(c->name);*/
3523 methodinfo *m = class_findmethod(c, name, desc);
3525 /* search superclass */
3528 /*log_text("method not found:");*/
3534 /****************** Function: class_resolveinterfacemethod_int ****************
3536 Internally used helper function. Do not use this directly.
3538 *******************************************************************************/
3541 methodinfo *class_resolveinterfacemethod_int(classinfo *c, utf *name, utf *desc)
3546 mi = class_findmethod(c,name,desc);
3550 /* try the superinterfaces */
3551 for (i=0; i<c->interfacescount; ++i) {
3552 mi = class_resolveinterfacemethod_int(c->interfaces[i],name,desc);
3560 /******************** Function: class_resolveinterfacemethod ******************
3562 Resolves a reference from REFERER to a method with NAME and DESC in
3565 If the method cannot be resolved the return value is NULL. If EXCEPT is
3566 true *exceptionptr is set, too.
3568 *******************************************************************************/
3570 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
3571 classinfo *referer, bool except)
3575 /* XXX resolve class c */
3576 /* XXX check access from REFERER to C */
3578 if (!(c->flags & ACC_INTERFACE)) {
3581 new_exception(string_java_lang_IncompatibleClassChangeError);
3586 mi = class_resolveinterfacemethod_int(c, name, desc);
3591 /* try class java.lang.Object */
3592 mi = class_findmethod(class_java_lang_Object, name, desc);
3599 new_exception_utfmessage(string_java_lang_NoSuchMethodError, name);
3605 /********************* Function: class_resolveclassmethod *********************
3607 Resolves a reference from REFERER to a method with NAME and DESC in
3610 If the method cannot be resolved the return value is NULL. If EXCEPT is
3611 true *exceptionptr is set, too.
3613 *******************************************************************************/
3615 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
3616 classinfo *referer, bool except)
3621 char msg[MAXLOGTEXT];
3623 /* XXX resolve class c */
3624 /* XXX check access from REFERER to C */
3626 /* if (c->flags & ACC_INTERFACE) { */
3628 /* *exceptionptr = */
3629 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
3633 /* try class c and its superclasses */
3636 mi = class_findmethod(cls, name, desc);
3639 } while ((cls = cls->super) != NULL); /* try the superclass */
3641 /* try the superinterfaces */
3642 for (i = 0; i < c->interfacescount; ++i) {
3643 mi = class_resolveinterfacemethod_int(c->interfaces[i], name, desc);
3649 utf_sprint(msg, c->name);
3650 sprintf(msg + strlen(msg), ".");
3651 utf_sprint(msg + strlen(msg), name);
3652 utf_sprint(msg + strlen(msg), desc);
3655 new_exception_message(string_java_lang_NoSuchMethodError, msg);
3661 if ((mi->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
3663 *exceptionptr = new_exception(string_java_lang_AbstractMethodError);
3668 /* XXX check access rights */
3674 /************************* Function: class_issubclass **************************
3676 Checks if sub is a descendant of super.
3678 *******************************************************************************/
3680 bool class_issubclass(classinfo *sub, classinfo *super)
3683 if (!sub) return false;
3684 if (sub == super) return true;
3690 /****************** Initialization function for classes ******************
3692 In Java, every class can have a static initialization function. This
3693 function has to be called BEFORE calling other methods or accessing static
3696 *******************************************************************************/
3698 static classinfo *class_init_intern(classinfo *c);
3700 classinfo *class_init(classinfo *c)
3704 if (!makeinitializations)
3707 /* enter a monitor on the class */
3709 builtin_monitorenter((java_objectheader *) c);
3711 /* maybe the class is already initalized or the current thread, which can
3712 pass the monitor, is currently initalizing this class */
3714 if (c->initialized || c->initializing) {
3715 builtin_monitorexit((java_objectheader *) c);
3720 /* this initalizing run begins NOW */
3721 c->initializing = true;
3723 /* call the internal function */
3724 r = class_init_intern(c);
3726 /* if return value is not NULL everything was ok and the class is
3729 c->initialized = true;
3731 /* this initalizing run is done */
3732 c->initializing = false;
3734 /* leave the monitor */
3736 builtin_monitorexit((java_objectheader *) c);
3742 /* this function MUST NOT be called directly, because of thread <clinit>
3745 static classinfo *class_init_intern(classinfo *c)
3749 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3753 /* maybe the class is not already loaded */
3758 /* maybe the class is not already linked */
3763 #if defined(STATISTICS)
3765 count_class_inits++;
3768 /* initialize super class */
3771 if (!c->super->initialized) {
3773 char logtext[MAXLOGTEXT];
3774 sprintf(logtext, "Initialize super class ");
3775 utf_sprint_classname(logtext + strlen(logtext), c->super->name);
3776 sprintf(logtext + strlen(logtext), " from ");
3777 utf_sprint_classname(logtext + strlen(logtext), c->name);
3781 if (!class_init(c->super))
3786 /* initialize interface classes */
3788 for (i = 0; i < c->interfacescount; i++) {
3789 if (!c->interfaces[i]->initialized) {
3791 char logtext[MAXLOGTEXT];
3792 sprintf(logtext, "Initialize interface class ");
3793 utf_sprint_classname(logtext + strlen(logtext), c->interfaces[i]->name);
3794 sprintf(logtext + strlen(logtext), " from ");
3795 utf_sprint_classname(logtext + strlen(logtext), c->name);
3799 if (!class_init(c->interfaces[i]))
3804 m = class_findmethod(c, utf_clinit, utf_fidesc);
3808 char logtext[MAXLOGTEXT];
3809 sprintf(logtext, "Class ");
3810 utf_sprint_classname(logtext + strlen(logtext), c->name);
3811 sprintf(logtext + strlen(logtext), " has no static class initializer");
3818 /* Sun's and IBM's JVM don't care about the static flag */
3819 /* if (!(m->flags & ACC_STATIC)) { */
3820 /* panic("Class initializer is not static!"); */
3823 log_message_class("Starting static class initializer for class: ", c);
3825 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3830 /* now call the initializer */
3831 asm_calljavafunction(m, NULL, NULL, NULL, NULL);
3833 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3834 assert(blockInts == 0);
3838 /* we have an exception or error */
3839 if (*exceptionptr) {
3840 /* class is NOT initialized */
3841 c->initialized = false;
3843 /* is this an exception, than wrap it */
3844 if (builtin_instanceof(*exceptionptr, class_java_lang_Exception)) {
3845 java_objectheader *xptr;
3846 java_objectheader *cause;
3849 cause = *exceptionptr;
3851 /* clear exception, because we are calling jit code again */
3852 *exceptionptr = NULL;
3854 /* wrap the exception */
3856 new_exception_throwable(string_java_lang_ExceptionInInitializerError,
3857 (java_lang_Throwable *) cause);
3859 /* XXX should we exit here? */
3863 /* set new exception */
3864 *exceptionptr = xptr;
3871 log_message_class("Finished static class initializer for class: ", c);
3877 /********* Function: find_class_method_constant *********/
3879 int find_class_method_constant (classinfo *c, utf * c1, utf* m1, utf* d1)
3884 for (i=0; i<c->cpcount; i++) {
3886 e = c -> cpinfos [i];
3889 switch (c -> cptags [i]) {
3890 case CONSTANT_Methodref:
3892 constant_FMIref *fmi = e;
3893 if ( (fmi->class->name == c1)
3894 && (fmi->name == m1)
3895 && (fmi->descriptor == d1)) {
3902 case CONSTANT_InterfaceMethodref:
3904 constant_FMIref *fmi = e;
3905 if ( (fmi->class->name == c1)
3906 && (fmi->name == m1)
3907 && (fmi->descriptor == d1)) {
3921 void class_showconstanti(classinfo *c, int ii)
3927 printf ("#%d: ", (int) i);
3929 switch (c->cptags [i]) {
3930 case CONSTANT_Class:
3931 printf("Classreference -> ");
3932 utf_display(((classinfo*)e)->name);
3935 case CONSTANT_Fieldref:
3936 printf("Fieldref -> "); goto displayFMIi;
3937 case CONSTANT_Methodref:
3938 printf("Methodref -> "); goto displayFMIi;
3939 case CONSTANT_InterfaceMethodref:
3940 printf("InterfaceMethod -> "); goto displayFMIi;
3943 constant_FMIref *fmi = e;
3944 utf_display(fmi->class->name);
3946 utf_display(fmi->name);
3948 utf_display(fmi->descriptor);
3952 case CONSTANT_String:
3953 printf("String -> ");
3956 case CONSTANT_Integer:
3957 printf("Integer -> %d", (int) (((constant_integer*)e)->value));
3959 case CONSTANT_Float:
3960 printf("Float -> %f", ((constant_float*)e)->value);
3962 case CONSTANT_Double:
3963 printf("Double -> %f", ((constant_double*)e)->value);
3967 u8 v = ((constant_long*)e)->value;
3969 printf("Long -> %ld", (long int) v);
3971 printf("Long -> HI: %ld, LO: %ld\n",
3972 (long int) v.high, (long int) v.low);
3976 case CONSTANT_NameAndType:
3978 constant_nameandtype *cnt = e;
3979 printf("NameAndType: ");
3980 utf_display(cnt->name);
3982 utf_display(cnt->descriptor);
3990 panic("Invalid type of ConstantPool-Entry");
3997 void class_showconstantpool (classinfo *c)
4002 printf ("---- dump of constant pool ----\n");
4004 for (i=0; i<c->cpcount; i++) {
4005 printf ("#%d: ", (int) i);
4007 e = c -> cpinfos [i];
4010 switch (c -> cptags [i]) {
4011 case CONSTANT_Class:
4012 printf ("Classreference -> ");
4013 utf_display ( ((classinfo*)e) -> name );
4016 case CONSTANT_Fieldref:
4017 printf ("Fieldref -> "); goto displayFMI;
4018 case CONSTANT_Methodref:
4019 printf ("Methodref -> "); goto displayFMI;
4020 case CONSTANT_InterfaceMethodref:
4021 printf ("InterfaceMethod -> "); goto displayFMI;
4024 constant_FMIref *fmi = e;
4025 utf_display ( fmi->class->name );
4027 utf_display ( fmi->name);
4029 utf_display ( fmi->descriptor );
4033 case CONSTANT_String:
4034 printf ("String -> ");
4037 case CONSTANT_Integer:
4038 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
4040 case CONSTANT_Float:
4041 printf ("Float -> %f", ((constant_float*)e) -> value);
4043 case CONSTANT_Double:
4044 printf ("Double -> %f", ((constant_double*)e) -> value);
4048 u8 v = ((constant_long*)e) -> value;
4050 printf ("Long -> %ld", (long int) v);
4052 printf ("Long -> HI: %ld, LO: %ld\n",
4053 (long int) v.high, (long int) v.low);
4057 case CONSTANT_NameAndType:
4059 constant_nameandtype *cnt = e;
4060 printf ("NameAndType: ");
4061 utf_display (cnt->name);
4063 utf_display (cnt->descriptor);
4067 printf ("Utf8 -> ");
4071 panic ("Invalid type of ConstantPool-Entry");
4081 /********** Function: class_showmethods (debugging only) *************/
4083 void class_showmethods (classinfo *c)
4087 printf ("--------- Fields and Methods ----------------\n");
4088 printf ("Flags: "); printflags (c->flags); printf ("\n");
4090 printf ("This: "); utf_display (c->name); printf ("\n");
4092 printf ("Super: "); utf_display (c->super->name); printf ("\n");
4094 printf ("Index: %d\n", c->index);
4096 printf ("interfaces:\n");
4097 for (i=0; i < c-> interfacescount; i++) {
4099 utf_display (c -> interfaces[i] -> name);
4100 printf (" (%d)\n", c->interfaces[i] -> index);
4103 printf ("fields:\n");
4104 for (i=0; i < c -> fieldscount; i++) {
4105 field_display (&(c -> fields[i]));
4108 printf ("methods:\n");
4109 for (i=0; i < c -> methodscount; i++) {
4110 methodinfo *m = &(c->methods[i]);
4111 if ( !(m->flags & ACC_STATIC))
4112 printf ("vftblindex: %d ", m->vftblindex);
4114 method_display ( m );
4118 printf ("Virtual function table:\n");
4119 for (i=0; i<c->vftbl->vftbllength; i++) {
4120 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]) );
4126 /******************************************************************************/
4127 /******************* General functions for the class loader *******************/
4128 /******************************************************************************/
4130 /**************** function: create_primitive_classes ***************************
4132 create classes representing primitive types
4134 *******************************************************************************/
4136 static bool create_primitive_classes()
4140 for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
4141 /* create primitive class */
4143 class_new_intern(utf_new_char(primitivetype_table[i].name));
4144 c->classUsed = NOTUSED; /* not used initially CO-RT */
4147 /* prevent loader from loading primitive class */
4152 primitivetype_table[i].class_primitive = c;
4154 /* create class for wrapping the primitive type */
4155 c = class_new_intern(utf_new_char(primitivetype_table[i].wrapname));
4156 primitivetype_table[i].class_wrap = c;
4157 primitivetype_table[i].class_wrap->classUsed = NOTUSED; /* not used initially CO-RT */
4158 primitivetype_table[i].class_wrap->impldBy = NULL;
4160 /* create the primitive array class */
4161 if (primitivetype_table[i].arrayname) {
4162 c = class_new_intern(utf_new_char(primitivetype_table[i].arrayname));
4163 primitivetype_table[i].arrayclass = c;
4168 primitivetype_table[i].arrayvftbl = c->vftbl;
4176 /**************** function: class_primitive_from_sig ***************************
4178 return the primitive class indicated by the given signature character
4180 If the descriptor does not indicate a valid primitive type the
4181 return value is NULL.
4183 ********************************************************************************/
4185 classinfo *class_primitive_from_sig(char sig)
4188 case 'I': return primitivetype_table[PRIMITIVETYPE_INT].class_primitive;
4189 case 'J': return primitivetype_table[PRIMITIVETYPE_LONG].class_primitive;
4190 case 'F': return primitivetype_table[PRIMITIVETYPE_FLOAT].class_primitive;
4191 case 'D': return primitivetype_table[PRIMITIVETYPE_DOUBLE].class_primitive;
4192 case 'B': return primitivetype_table[PRIMITIVETYPE_BYTE].class_primitive;
4193 case 'C': return primitivetype_table[PRIMITIVETYPE_CHAR].class_primitive;
4194 case 'S': return primitivetype_table[PRIMITIVETYPE_SHORT].class_primitive;
4195 case 'Z': return primitivetype_table[PRIMITIVETYPE_BOOLEAN].class_primitive;
4196 case 'V': return primitivetype_table[PRIMITIVETYPE_VOID].class_primitive;
4201 /****************** function: class_from_descriptor ****************************
4203 return the class indicated by the given descriptor
4205 utf_ptr....first character of descriptor
4206 end_ptr....first character after the end of the string
4207 next.......if non-NULL, *next is set to the first character after
4208 the descriptor. (Undefined if an error occurs.)
4210 mode.......a combination (binary or) of the following flags:
4212 (Flags marked with * are the default settings.)
4214 What to do if a reference type descriptor is parsed successfully:
4216 CLASSLOAD_SKIP...skip it and return something != NULL
4217 * CLASSLOAD_NEW....get classinfo * via class_new
4218 CLASSLOAD_LOAD...get classinfo * via loader_load
4220 How to handle primitive types:
4222 * CLASSLOAD_PRIMITIVE.......return primitive class (eg. "int")
4223 CLASSLOAD_NULLPRIMITIVE...return NULL for primitive types
4225 How to handle "V" descriptors:
4227 * CLASSLOAD_VOID.....handle it like other primitive types
4228 CLASSLOAD_NOVOID...treat it as an error
4230 How to deal with extra characters after the end of the
4233 * CLASSLOAD_NOCHECKEND...ignore (useful for parameter lists)
4234 CLASSLOAD_CHECKEND.....treat them as an error
4236 How to deal with errors:
4238 * CLASSLOAD_PANIC....abort execution with an error message
4239 CLASSLOAD_NOPANIC..return NULL on error
4241 *******************************************************************************/
4243 classinfo *class_from_descriptor(char *utf_ptr, char *end_ptr,
4244 char **next, int mode)
4246 char *start = utf_ptr;
4250 SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr, end_ptr, error);
4252 if (mode & CLASSLOAD_CHECKEND)
4253 error |= (utf_ptr != end_ptr);
4256 if (next) *next = utf_ptr;
4260 if (mode & CLASSLOAD_NOVOID)
4271 return (mode & CLASSLOAD_NULLPRIMITIVE)
4273 : class_primitive_from_sig(*start);
4280 if (mode & CLASSLOAD_SKIP) return class_java_lang_Object;
4281 name = utf_new(start, utf_ptr - start);
4285 tc = class_new_intern(name);
4287 list_addfirst(&unlinkedclasses, tc);
4292 return (mode & CLASSLOAD_LOAD)
4293 ? class_load(class_new(name)) : class_new(name); /* XXX handle errors */
4298 /* An error occurred */
4299 if (mode & CLASSLOAD_NOPANIC)
4302 log_plain("Invalid descriptor at beginning of '");
4303 log_plain_utf(utf_new(start, end_ptr - start));
4307 panic("Invalid descriptor");
4309 /* keep compiler happy */
4314 /******************* function: type_from_descriptor ****************************
4316 return the basic type indicated by the given descriptor
4318 This function parses a descriptor and returns its basic type as
4319 TYPE_INT, TYPE_LONG, TYPE_FLOAT, TYPE_DOUBLE, TYPE_ADDRESS or TYPE_VOID.
4321 cls...if non-NULL the referenced variable is set to the classinfo *
4322 returned by class_from_descriptor.
4324 For documentation of the arguments utf_ptr, end_ptr, next and mode
4325 see class_from_descriptor. The only difference is that
4326 type_from_descriptor always uses CLASSLOAD_PANIC.
4328 ********************************************************************************/
4330 int type_from_descriptor(classinfo **cls, char *utf_ptr, char *end_ptr,
4331 char **next, int mode)
4334 if (!cls) cls = &mycls;
4335 *cls = class_from_descriptor(utf_ptr, end_ptr, next, mode & (~CLASSLOAD_NOPANIC));
4352 return TYPE_ADDRESS;
4356 /*************** function: create_pseudo_classes *******************************
4358 create pseudo classes used by the typechecker
4360 ********************************************************************************/
4362 static void create_pseudo_classes()
4364 /* pseudo class for Arraystubs (extends java.lang.Object) */
4366 pseudo_class_Arraystub = class_new_intern(utf_new_char("$ARRAYSTUB$"));
4367 pseudo_class_Arraystub->loaded = true;
4368 pseudo_class_Arraystub->super = class_java_lang_Object;
4369 pseudo_class_Arraystub->interfacescount = 2;
4370 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
4371 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
4372 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
4374 class_link(pseudo_class_Arraystub);
4376 pseudo_class_Arraystub_vftbl = pseudo_class_Arraystub->vftbl;
4378 /* pseudo class representing the null type */
4380 pseudo_class_Null = class_new_intern(utf_new_char("$NULL$"));
4381 pseudo_class_Null->loaded = true;
4382 pseudo_class_Null->super = class_java_lang_Object;
4383 class_link(pseudo_class_Null);
4385 /* pseudo class representing new uninitialized objects */
4387 pseudo_class_New = class_new_intern(utf_new_char("$NEW$"));
4388 pseudo_class_New->loaded = true;
4389 pseudo_class_New->linked = true;
4390 pseudo_class_New->super = class_java_lang_Object;
4391 /* class_link(pseudo_class_New); */
4395 /********************** Function: loader_init **********************************
4397 Initializes all lists and loads all classes required for the system or the
4400 *******************************************************************************/
4402 void loader_init(u1 *stackbottom)
4406 /* create utf-symbols for pointer comparison of frequently used strings */
4407 utf_innerclasses = utf_new_char("InnerClasses");
4408 utf_constantvalue = utf_new_char("ConstantValue");
4409 utf_code = utf_new_char("Code");
4410 utf_exceptions = utf_new_char("Exceptions");
4411 utf_linenumbertable = utf_new_char("LineNumberTable");
4412 utf_sourcefile = utf_new_char("SourceFile");
4413 utf_finalize = utf_new_char("finalize");
4414 utf_fidesc = utf_new_char("()V");
4415 utf_init = utf_new_char("<init>");
4416 utf_clinit = utf_new_char("<clinit>");
4417 utf_initsystemclass = utf_new_char("initializeSystemClass");
4418 utf_systemclass = utf_new_char("java/lang/System");
4419 utf_vmclassloader = utf_new_char("java/lang/VMClassLoader");
4420 utf_initialize = utf_new_char("initialize");
4421 utf_initializedesc = utf_new_char("(I)V");
4422 utf_vmclass = utf_new_char("java/lang/VMClass");
4423 utf_java_lang_Object= utf_new_char("java/lang/Object");
4424 array_packagename = utf_new_char("<the array package>");
4425 utf_fillInStackTrace_name = utf_new_char("fillInStackTrace");
4426 utf_fillInStackTrace_desc = utf_new_char("()Ljava/lang/Throwable;");
4428 /* create some important classes */
4429 /* These classes have to be created now because the classinfo
4430 * pointers are used in the loading code.
4432 class_java_lang_Object = class_new_intern(utf_java_lang_Object);
4433 class_load(class_java_lang_Object);
4434 class_link(class_java_lang_Object);
4436 class_java_lang_String = class_new(utf_new_char("java/lang/String"));
4437 class_load(class_java_lang_String);
4438 class_link(class_java_lang_String);
4440 class_java_lang_Cloneable = class_new(utf_new_char("java/lang/Cloneable"));
4441 class_load(class_java_lang_Cloneable);
4442 class_link(class_java_lang_Cloneable);
4444 class_java_io_Serializable =
4445 class_new(utf_new_char("java/io/Serializable"));
4446 class_load(class_java_io_Serializable);
4447 class_link(class_java_io_Serializable);
4449 /* create classes representing primitive types */
4450 create_primitive_classes();
4452 /* create classes used by the typechecker */
4453 create_pseudo_classes();
4455 /* correct vftbl-entries (retarded loading of class java/lang/String) */
4456 stringtable_update();
4458 #if defined(USE_THREADS)
4459 if (stackbottom != 0)
4465 /* loader_compute_subclasses ***************************************************
4469 *******************************************************************************/
4471 static void loader_compute_class_values(classinfo *c);
4473 void loader_compute_subclasses(classinfo *c)
4475 #if defined(USE_THREADS)
4476 #if defined(NATIVE_THREADS)
4483 if (!(c->flags & ACC_INTERFACE)) {
4488 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
4489 c->nextsub = c->super->sub;
4495 /* this is the java.lang.Object special case */
4497 if (!class_java_lang_Object) {
4498 loader_compute_class_values(c);
4501 loader_compute_class_values(class_java_lang_Object);
4504 #if defined(USE_THREADS)
4505 #if defined(NATIVE_THREADS)
4514 /* loader_compute_class_values *************************************************
4518 *******************************************************************************/
4520 static void loader_compute_class_values(classinfo *c)
4524 c->vftbl->baseval = ++classvalue;
4528 loader_compute_class_values(subs);
4529 subs = subs->nextsub;
4532 c->vftbl->diffval = classvalue - c->vftbl->baseval;
4536 /******************** Function: loader_close ***********************************
4540 *******************************************************************************/
4547 for (slot = 0; slot < class_hash.size; slot++) {
4548 c = class_hash.ptr[slot];
4559 * These are local overrides for various environment variables in Emacs.
4560 * Please do not remove this and leave it at the end of the file, where
4561 * Emacs will automagically detect them.
4562 * ---------------------------------------------------------------------
4565 * indent-tabs-mode: t