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 1443 2004-11-05 13:53:13Z twisti $
44 #include "exceptions.h"
54 #include "statistics.h"
55 #include "toolbox/memory.h"
56 #include "toolbox/logging.h"
57 #include "threads/thread.h"
58 #include "threads/locks.h"
59 #include "nat/java_lang_Throwable.h"
69 /* global variables ***********************************************************/
71 static s4 interfaceindex; /* sequential numbering of interfaces */
75 /* utf-symbols for pointer comparison of frequently used strings */
77 static utf *utf_innerclasses; /* InnerClasses */
78 static utf *utf_constantvalue; /* ConstantValue */
79 static utf *utf_code; /* Code */
80 static utf *utf_exceptions; /* Exceptions */
81 static utf *utf_linenumbertable; /* LineNumberTable */
82 static utf *utf_sourcefile; /* SourceFile */
83 static utf *utf_finalize; /* finalize */
84 static utf *utf_fidesc; /* ()V changed */
85 static utf *utf_init; /* <init> */
86 static utf *utf_clinit; /* <clinit> */
87 static utf *utf_initsystemclass; /* initializeSystemClass */
88 static utf *utf_systemclass; /* java/lang/System */
89 static utf *utf_vmclassloader; /* java/lang/VMClassLoader */
90 static utf *utf_vmclass; /* java/lang/VMClassLoader */
91 static utf *utf_initialize;
92 static utf *utf_initializedesc;
93 static utf *utf_java_lang_Object; /* java/lang/Object */
95 utf *utf_fillInStackTrace_name;
96 utf *utf_fillInStackTrace_desc;
106 /* important system classes ***************************************************/
108 classinfo *class_java_lang_Object;
109 classinfo *class_java_lang_String;
110 classinfo *class_java_lang_Cloneable;
111 classinfo *class_java_io_Serializable;
113 /* Pseudo classes for the typechecker */
114 classinfo *pseudo_class_Arraystub = NULL;
115 classinfo *pseudo_class_Null = NULL;
116 classinfo *pseudo_class_New = NULL;
117 vftbl_t *pseudo_class_Arraystub_vftbl = NULL;
119 utf *array_packagename = NULL;
122 /********************************************************************
123 list of classpath entries (either filesystem directories or
125 ********************************************************************/
126 static classpath_info *classpath_entries=0;
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)
323 union classpath_info *tmp;
324 union classpath_info *insertAfter=0;
329 if (classpath_entries)
330 panic("suck_init should be called only once");
332 for (start = classpath; (*start) != '\0';) {
333 for (end = start; ((*end) != '\0') && ((*end) != ':'); end++);
337 filenamelen = end - start;
339 if (filenamelen > 3) {
340 if (strncasecmp(end - 3, "zip", 3) == 0 ||
341 strncasecmp(end - 3, "jar", 3) == 0) {
346 if (filenamelen >= (CLASSPATH_MAXFILENAME - 1))
347 panic("path length >= MAXFILENAME in suck_init");
350 filename = MNEW(char, CLASSPATH_MAXFILENAME);
352 strncpy(filename, start, filenamelen);
353 filename[filenamelen + 1] = '\0';
357 #if defined(USE_ZLIB)
358 unzFile uf = unzOpen(filename);
361 tmp = (union classpath_info *) NEW(classpath_info);
362 tmp->archive.type = CLASSPATH_ARCHIVE;
363 tmp->archive.uf = uf;
364 tmp->archive.next = NULL;
368 throw_cacao_exception_exit(string_java_lang_InternalError,
369 "zip/jar files not supported");
373 tmp = (union classpath_info *) NEW(classpath_info);
374 tmp->filepath.type = CLASSPATH_PATH;
375 tmp->filepath.next = 0;
377 if (filename[filenamelen - 1] != '/') {/*PERHAPS THIS SHOULD BE READ FROM A GLOBAL CONFIGURATION */
378 filename[filenamelen] = '/';
379 filename[filenamelen + 1] = '\0';
383 tmp->filepath.filename = filename;
384 tmp->filepath.pathlen = filenamelen;
390 insertAfter->filepath.next = tmp;
393 classpath_entries = tmp;
405 MFREE(filename, char, CLASSPATH_MAXFILENAME);
412 void create_all_classes()
416 for (cpi = classpath_entries; cpi != 0; cpi = cpi->filepath.next) {
417 #if defined(USE_ZLIB)
418 if (cpi->filepath.type == CLASSPATH_ARCHIVE) {
422 s = (unz_s *) cpi->archive.uf;
423 ce = s->cacao_dir_list;
426 (void) class_new(ce->name);
432 #if defined(USE_ZLIB)
439 /************************** function suck_start ********************************
441 returns true if classbuffer is already loaded or a file for the
442 specified class has succussfully been read in. All directories of
443 the searchpath are used to find the classfile (<classname>.class).
444 Returns false if no classfile is found and writes an error message.
446 *******************************************************************************/
448 classbuffer *suck_start(classinfo *c)
450 classpath_info *currPos;
453 char filename[CLASSPATH_MAXFILENAME+10]; /* room for '.class' */
460 utf_ptr = c->name->text;
462 while (utf_ptr < utf_end(c->name)) {
463 if (filenamelen >= CLASSPATH_MAXFILENAME) {
465 new_exception_message(string_java_lang_InternalError,
466 "Filename too long");
468 /* XXX should we exit in such a case? */
469 throw_exception_exit();
473 if ((ch <= ' ' || ch > 'z') && (ch != '/')) /* invalid character */
475 filename[filenamelen++] = ch;
478 strcpy(filename + filenamelen, ".class");
481 for (currPos = classpath_entries; currPos != 0; currPos = currPos->filepath.next) {
482 #if defined(USE_ZLIB)
483 if (currPos->filepath.type == CLASSPATH_ARCHIVE) {
484 if (cacao_locate(currPos->archive.uf, c->name) == UNZ_OK) {
485 unz_file_info file_info;
486 /*log_text("Class found in zip file");*/
487 if (unzGetCurrentFileInfo(currPos->archive.uf, &file_info, filename,
488 sizeof(filename), NULL, 0, NULL, 0) == UNZ_OK) {
489 if (unzOpenCurrentFile(currPos->archive.uf) == UNZ_OK) {
490 cb = NEW(classbuffer);
492 cb->size = file_info.uncompressed_size;
493 cb->data = MNEW(u1, cb->size);
494 cb->pos = cb->data - 1;
495 /*printf("classfile size: %d\n",file_info.uncompressed_size);*/
496 if (unzReadCurrentFile(currPos->archive.uf, cb->data, cb->size) == cb->size) {
497 unzCloseCurrentFile(currPos->archive.uf);
501 MFREE(cb->data, u1, cb->size);
502 FREE(cb, classbuffer);
503 log_text("Error while unzipping");
505 } else log_text("Error while opening file in archive");
506 } else log_text("Error while retrieving fileinfo");
508 unzCloseCurrentFile(currPos->archive.uf);
512 if ((currPos->filepath.pathlen + filenamelen) >= CLASSPATH_MAXFILENAME) continue;
513 strcpy(currPos->filepath.filename + currPos->filepath.pathlen, filename);
514 classfile = fopen(currPos->filepath.filename, "r");
515 if (classfile) { /* file exists */
517 /* determine size of classfile */
519 /* dolog("File: %s",filename); */
520 err = stat(currPos->filepath.filename, &buffer);
522 if (!err) { /* read classfile data */
523 cb = NEW(classbuffer);
525 cb->size = buffer.st_size;
526 cb->data = MNEW(u1, cb->size);
527 cb->pos = cb->data - 1;
528 fread(cb->data, 1, cb->size, classfile);
534 #if defined(USE_ZLIB)
540 dolog("Warning: Can not open class file '%s'", filename);
547 /************************** function suck_stop *********************************
549 frees memory for buffer with classfile data.
550 Caution: this function may only be called if buffer has been allocated
551 by suck_start with reading a file
553 *******************************************************************************/
555 void suck_stop(classbuffer *cb)
559 MFREE(cb->data, u1, cb->size);
560 FREE(cb, classbuffer);
564 /******************************************************************************/
565 /******************* Some support functions ***********************************/
566 /******************************************************************************/
568 void fprintflags (FILE *fp, u2 f)
570 if ( f & ACC_PUBLIC ) fprintf (fp," PUBLIC");
571 if ( f & ACC_PRIVATE ) fprintf (fp," PRIVATE");
572 if ( f & ACC_PROTECTED ) fprintf (fp," PROTECTED");
573 if ( f & ACC_STATIC ) fprintf (fp," STATIC");
574 if ( f & ACC_FINAL ) fprintf (fp," FINAL");
575 if ( f & ACC_SYNCHRONIZED ) fprintf (fp," SYNCHRONIZED");
576 if ( f & ACC_VOLATILE ) fprintf (fp," VOLATILE");
577 if ( f & ACC_TRANSIENT ) fprintf (fp," TRANSIENT");
578 if ( f & ACC_NATIVE ) fprintf (fp," NATIVE");
579 if ( f & ACC_INTERFACE ) fprintf (fp," INTERFACE");
580 if ( f & ACC_ABSTRACT ) fprintf (fp," ABSTRACT");
584 /********** internal function: printflags (only for debugging) ***************/
586 void printflags(u2 f)
588 if ( f & ACC_PUBLIC ) printf (" PUBLIC");
589 if ( f & ACC_PRIVATE ) printf (" PRIVATE");
590 if ( f & ACC_PROTECTED ) printf (" PROTECTED");
591 if ( f & ACC_STATIC ) printf (" STATIC");
592 if ( f & ACC_FINAL ) printf (" FINAL");
593 if ( f & ACC_SYNCHRONIZED ) printf (" SYNCHRONIZED");
594 if ( f & ACC_VOLATILE ) printf (" VOLATILE");
595 if ( f & ACC_TRANSIENT ) printf (" TRANSIENT");
596 if ( f & ACC_NATIVE ) printf (" NATIVE");
597 if ( f & ACC_INTERFACE ) printf (" INTERFACE");
598 if ( f & ACC_ABSTRACT ) printf (" ABSTRACT");
602 /********************** Function: skipattributebody ****************************
604 skips an attribute after the 16 bit reference to attribute_name has already
607 *******************************************************************************/
609 static bool skipattributebody(classbuffer *cb)
613 if (!check_classbuffer_size(cb, 4))
618 if (!check_classbuffer_size(cb, len))
621 skip_nbytes(cb, len);
627 /************************* Function: skipattributes ****************************
629 skips num attribute structures
631 *******************************************************************************/
633 static bool skipattributes(classbuffer *cb, u4 num)
638 for (i = 0; i < num; i++) {
639 if (!check_classbuffer_size(cb, 2 + 4))
645 if (!check_classbuffer_size(cb, len))
648 skip_nbytes(cb, len);
655 /******************** function:: class_getconstant *****************************
657 retrieves the value at position 'pos' of the constantpool of a class
658 if the type of the value is other than 'ctype' the system is stopped
660 *******************************************************************************/
662 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
664 /* check index and type of constantpool entry */
665 /* (pos == 0 is caught by type comparison) */
666 if (pos >= c->cpcount || c->cptags[pos] != ctype) {
667 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
671 return c->cpinfos[pos];
675 /******************** function: innerclass_getconstant ************************
677 like class_getconstant, but if cptags is ZERO null is returned
679 *******************************************************************************/
681 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
683 /* invalid position in constantpool */
684 if (pos >= c->cpcount) {
685 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
689 /* constantpool entry of type 0 */
693 /* check type of constantpool entry */
694 if (c->cptags[pos] != ctype) {
695 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
699 return c->cpinfos[pos];
703 /********************* Function: class_constanttype ****************************
705 Determines the type of a class entry in the ConstantPool
707 *******************************************************************************/
709 u4 class_constanttype(classinfo *c, u4 pos)
711 if (pos <= 0 || pos >= c->cpcount) {
712 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
716 return c->cptags[pos];
720 /************************ function: attribute_load ****************************
722 read attributes from classfile
724 *******************************************************************************/
726 static bool attribute_load(classbuffer *cb, classinfo *c, u4 num)
731 for (i = 0; i < num; i++) {
732 /* retrieve attribute name */
733 if (!check_classbuffer_size(cb, 2))
736 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
739 if (aname == utf_innerclasses) {
740 /* innerclasses attribute */
743 new_classformaterror(c, "Multiple InnerClasses attributes");
747 if (!check_classbuffer_size(cb, 4 + 2))
750 /* skip attribute length */
753 /* number of records */
754 c->innerclasscount = suck_u2(cb);
756 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
759 /* allocate memory for innerclass structure */
760 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
762 for (j = 0; j < c->innerclasscount; j++) {
763 /* The innerclass structure contains a class with an encoded
764 name, its defining scope, its simple name and a bitmask of
765 the access flags. If an inner class is not a member, its
766 outer_class is NULL, if a class is anonymous, its name is
769 innerclassinfo *info = c->innerclass + j;
772 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
774 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
776 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
777 info->flags = suck_u2(cb);
780 } else if (aname == utf_sourcefile) {
781 if (!check_classbuffer_size(cb, 4 + 2))
784 if (suck_u4(cb) != 2) {
786 new_classformaterror(c, "Wrong size for VALUE attribute");
792 new_classformaterror(c, "Multiple SourceFile attributes");
796 if (!(c->sourcefile = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
800 /* unknown attribute */
801 if (!skipattributebody(cb))
810 /******************* function: checkfielddescriptor ****************************
812 checks whether a field-descriptor is valid and aborts otherwise
813 all referenced classes are inserted into the list of unloaded classes
815 *******************************************************************************/
817 static void checkfielddescriptor (char *utf_ptr, char *end_pos)
819 class_from_descriptor(utf_ptr,end_pos,NULL,
821 | CLASSLOAD_NULLPRIMITIVE
823 | CLASSLOAD_CHECKEND);
825 /* XXX use the following if -noverify */
827 char *tstart; /* pointer to start of classname */
829 char *start = utf_ptr;
831 switch (*utf_ptr++) {
845 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
846 panic ("Ill formed descriptor");
850 panic ("Ill formed descriptor");
853 /* exceeding characters */
854 if (utf_ptr!=end_pos) panic ("descriptor has exceeding chars");
859 /******************* function checkmethoddescriptor ****************************
861 checks whether a method-descriptor is valid and aborts otherwise.
862 All referenced classes are inserted into the list of unloaded classes.
864 The number of arguments is returned. A long or double argument is counted
867 *******************************************************************************/
869 static int checkmethoddescriptor(classinfo *c, utf *descriptor)
871 char *utf_ptr; /* current position in utf text */
872 char *end_pos; /* points behind utf string */
873 s4 argcount = 0; /* number of arguments */
875 utf_ptr = descriptor->text;
876 end_pos = utf_end(descriptor);
878 /* method descriptor must start with parenthesis */
879 if (utf_ptr == end_pos || *utf_ptr++ != '(')
880 panic ("Missing '(' in method descriptor");
882 /* check arguments */
883 while (utf_ptr != end_pos && *utf_ptr != ')') {
884 /* We cannot count the this argument here because
885 * we don't know if the method is static. */
886 if (*utf_ptr == 'J' || *utf_ptr == 'D')
890 class_from_descriptor(utf_ptr,end_pos,&utf_ptr,
892 | CLASSLOAD_NULLPRIMITIVE
896 if (utf_ptr == end_pos)
897 panic("Missing ')' in method descriptor");
899 utf_ptr++; /* skip ')' */
901 class_from_descriptor(utf_ptr,
905 CLASSLOAD_NULLPRIMITIVE |
908 if (argcount > 255) {
910 new_classformaterror(c, "Too many arguments in signature");
917 /* XXX use the following if -noverify */
919 /* check arguments */
920 while ((c = *utf_ptr++) != ')') {
937 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
938 panic ("Ill formed method descriptor");
942 panic ("Ill formed methodtype-descriptor");
946 /* check returntype */
948 /* returntype void */
949 if ((utf_ptr+1) != end_pos) panic ("Method-descriptor has exceeding chars");
952 /* treat as field-descriptor */
953 checkfielddescriptor (utf_ptr,end_pos);
958 /***************** Function: print_arraydescriptor ****************************
960 Debugging helper for displaying an arraydescriptor
962 *******************************************************************************/
964 void print_arraydescriptor(FILE *file, arraydescriptor *desc)
967 fprintf(file, "<NULL>");
972 if (desc->componentvftbl) {
973 if (desc->componentvftbl->class)
974 utf_fprint(file, desc->componentvftbl->class->name);
976 fprintf(file, "<no classinfo>");
982 if (desc->elementvftbl) {
983 if (desc->elementvftbl->class)
984 utf_fprint(file, desc->elementvftbl->class->name);
986 fprintf(file, "<no classinfo>");
990 fprintf(file, ",%d,%d,%d,%d}", desc->arraytype, desc->dimension,
991 desc->dataoffset, desc->componentsize);
995 /******************************************************************************/
996 /************************** Functions for fields ****************************/
997 /******************************************************************************/
1000 /* field_load ******************************************************************
1002 Load everything about a class field from the class file and fill a
1003 'fieldinfo' structure. For static fields, space in the data segment is
1006 *******************************************************************************/
1008 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
1010 static bool field_load(classbuffer *cb, classinfo *c, fieldinfo *f)
1014 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
1017 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1020 f->flags = suck_u2(cb);
1022 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1026 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1032 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<')
1033 panic("Field with invalid name");
1035 /* check flag consistency */
1036 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
1038 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
1039 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
1041 new_classformaterror(c,
1042 "Illegal field modifiers: 0x%X",
1047 if (c->flags & ACC_INTERFACE) {
1048 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
1049 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
1050 f->flags & ACC_TRANSIENT) {
1052 new_classformaterror(c,
1053 "Illegal field modifiers: 0x%X",
1059 /* check descriptor */
1060 checkfielddescriptor(f->descriptor->text, utf_end(f->descriptor));
1063 f->type = jtype = desc_to_type(f->descriptor); /* data type */
1064 f->offset = 0; /* offset from start of object */
1069 case TYPE_INT: f->value.i = 0; break;
1070 case TYPE_FLOAT: f->value.f = 0.0; break;
1071 case TYPE_DOUBLE: f->value.d = 0.0; break;
1072 case TYPE_ADDRESS: f->value.a = NULL; break;
1075 f->value.l = 0; break;
1077 f->value.l.low = 0; f->value.l.high = 0; break;
1081 /* read attributes */
1082 if (!check_classbuffer_size(cb, 2))
1085 attrnum = suck_u2(cb);
1086 for (i = 0; i < attrnum; i++) {
1087 if (!check_classbuffer_size(cb, 2))
1090 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1093 if (u == utf_constantvalue) {
1094 if (!check_classbuffer_size(cb, 4 + 2))
1097 /* check attribute length */
1098 if (suck_u4(cb) != 2) {
1100 new_classformaterror(c, "Wrong size for VALUE attribute");
1104 /* constant value attribute */
1105 if (pindex != field_load_NOVALUE) {
1107 new_classformaterror(c,
1108 "Multiple ConstantValue attributes");
1112 /* index of value in constantpool */
1113 pindex = suck_u2(cb);
1115 /* initialize field with value from constantpool */
1118 constant_integer *ci;
1120 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
1123 f->value.i = ci->value;
1130 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
1133 f->value.l = cl->value;
1140 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
1143 f->value.f = cf->value;
1148 constant_double *cd;
1150 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
1153 f->value.d = cd->value;
1158 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
1161 /* create javastring from compressed utf8-string */
1162 f->value.a = literalstring_new(u);
1166 log_text("Invalid Constant - Type");
1170 /* unknown attribute */
1171 if (!skipattributebody(cb))
1176 /* everything was ok */
1182 /********************** function: field_free **********************************/
1184 static void field_free(fieldinfo *f)
1190 /**************** Function: field_display (debugging only) ********************/
1192 void field_display(fieldinfo *f)
1195 printflags(f->flags);
1197 utf_display(f->name);
1199 utf_display(f->descriptor);
1200 printf(" offset: %ld\n", (long int) (f->offset));
1204 /******************************************************************************/
1205 /************************* Functions for methods ******************************/
1206 /******************************************************************************/
1209 /* method_load *****************************************************************
1211 Loads a method from the class file and fills an existing 'methodinfo'
1212 structure. For native methods, the function pointer field is set to the
1213 real function pointer, for JavaVM methods a pointer to the compiler is used
1216 *******************************************************************************/
1218 static bool method_load(classbuffer *cb, classinfo *c, methodinfo *m)
1226 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1227 initObjectLock(&m->header);
1232 count_all_methods++;
1235 m->thrownexceptionscount = 0;
1236 m->linenumbercount = 0;
1239 m->nativelyoverloaded = false;
1241 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1244 m->flags = suck_u2(cb);
1246 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1250 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1255 if (!is_valid_name_utf(m->name))
1256 panic("Method with invalid name");
1258 if (m->name->text[0] == '<'
1259 && m->name != utf_init && m->name != utf_clinit)
1260 panic("Method with invalid special name");
1263 argcount = checkmethoddescriptor(c, m->descriptor);
1265 if (!(m->flags & ACC_STATIC))
1266 argcount++; /* count the 'this' argument */
1269 if (argcount > 255) {
1271 new_classformaterror(c, "Too many arguments in signature");
1275 /* check flag consistency */
1276 if (m->name != utf_clinit) {
1277 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1279 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1281 new_classformaterror(c,
1282 "Illegal method modifiers: 0x%X",
1287 if (m->flags & ACC_ABSTRACT) {
1288 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1289 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1291 new_classformaterror(c,
1292 "Illegal method modifiers: 0x%X",
1298 if (c->flags & ACC_INTERFACE) {
1299 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1301 new_classformaterror(c,
1302 "Illegal method modifiers: 0x%X",
1308 if (m->name == utf_init) {
1309 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1310 ACC_NATIVE | ACC_ABSTRACT))
1311 panic("Instance initialization method has invalid flags set");
1317 m->basicblockcount = 0;
1318 m->basicblocks = NULL;
1319 m->basicblockindex = NULL;
1320 m->instructioncount = 0;
1321 m->instructions = NULL;
1324 m->exceptiontable = NULL;
1325 m->stubroutine = NULL;
1327 m->entrypoint = NULL;
1328 m->methodUsed = NOTUSED;
1331 m->subRedefsUsed = 0;
1335 if (!(m->flags & ACC_NATIVE)) {
1336 m->stubroutine = createcompilerstub(m);
1339 /*if (useinlining) {
1340 log_text("creating native stub:");
1343 functionptr f = native_findfunction(c->name, m->name, m->descriptor,
1344 (m->flags & ACC_STATIC) != 0);
1345 #ifdef STATIC_CLASSPATH
1349 m->stubroutine = createnativestub(f, m);
1353 if (!check_classbuffer_size(cb, 2))
1356 attrnum = suck_u2(cb);
1357 for (i = 0; i < attrnum; i++) {
1360 if (!check_classbuffer_size(cb, 2))
1363 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1366 if (aname == utf_code) {
1367 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1369 new_classformaterror(c,
1370 "Code attribute in native or abstract methods");
1377 new_classformaterror(c, "Multiple Code attributes");
1382 if (!check_classbuffer_size(cb, 4 + 2 + 2))
1386 m->maxstack = suck_u2(cb);
1387 m->maxlocals = suck_u2(cb);
1389 if (m->maxlocals < argcount) {
1391 new_classformaterror(c, "Arguments can't fit into locals");
1396 if (!check_classbuffer_size(cb, 4))
1399 m->jcodelength = suck_u4(cb);
1401 if (m->jcodelength == 0) {
1403 new_classformaterror(c, "Code of a method has length 0");
1408 if (m->jcodelength > 65535) {
1410 new_classformaterror(c,
1411 "Code of a method longer than 65535 bytes");
1416 if (!check_classbuffer_size(cb, m->jcodelength))
1419 m->jcode = MNEW(u1, m->jcodelength);
1420 suck_nbytes(m->jcode, cb, m->jcodelength);
1422 if (!check_classbuffer_size(cb, 2))
1425 m->exceptiontablelength = suck_u2(cb);
1426 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->exceptiontablelength))
1429 m->exceptiontable = MNEW(exceptiontable, m->exceptiontablelength);
1431 #if defined(STATISTICS)
1433 count_vmcode_len += m->jcodelength + 18;
1434 count_extable_len += 8 * m->exceptiontablelength;
1438 for (j = 0; j < m->exceptiontablelength; j++) {
1440 m->exceptiontable[j].startpc = suck_u2(cb);
1441 m->exceptiontable[j].endpc = suck_u2(cb);
1442 m->exceptiontable[j].handlerpc = suck_u2(cb);
1446 m->exceptiontable[j].catchtype = NULL;
1449 if (!(m->exceptiontable[j].catchtype =
1450 class_getconstant(c, idx, CONSTANT_Class)))
1455 if (!check_classbuffer_size(cb, 2))
1458 codeattrnum = suck_u2(cb);
1460 for (; codeattrnum > 0; codeattrnum--) {
1463 if (!check_classbuffer_size(cb, 2))
1466 if (!(caname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1469 if (caname == utf_linenumbertable) {
1472 if (!check_classbuffer_size(cb, 4 + 2))
1476 m->linenumbercount = suck_u2(cb);
1478 if (!check_classbuffer_size(cb,
1479 (2 + 2) * m->linenumbercount))
1482 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1484 for (lncid = 0; lncid < m->linenumbercount; lncid++) {
1485 m->linenumbers[lncid].start_pc = suck_u2(cb);
1486 m->linenumbers[lncid].line_number = suck_u2(cb);
1490 if (!skipattributes(cb, codeattrnum))
1496 if (!skipattributebody(cb))
1501 } else if (aname == utf_exceptions) {
1504 if (m->thrownexceptions) {
1506 new_classformaterror(c, "Multiple Exceptions attributes");
1510 if (!check_classbuffer_size(cb, 4 + 2))
1513 suck_u4(cb); /* length */
1514 m->thrownexceptionscount = suck_u2(cb);
1516 if (!check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1519 m->thrownexceptions = MNEW(classinfo*, m->thrownexceptionscount);
1521 for (j = 0; j < m->thrownexceptionscount; j++) {
1522 if (!((m->thrownexceptions)[j] =
1523 class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1528 if (!skipattributebody(cb))
1533 if (!m->jcode && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1534 *exceptionptr = new_classformaterror(c, "Missing Code attribute");
1539 /* everything was ok */
1540 /* utf_display(m->name);
1541 printf("\nexceptiontablelength:%ld\n",m->exceptiontablelength);*/
1547 /********************* Function: method_free ***********************************
1549 frees all memory that was allocated for this method
1551 *******************************************************************************/
1553 static void method_free(methodinfo *m)
1556 MFREE(m->jcode, u1, m->jcodelength);
1558 if (m->exceptiontable)
1559 MFREE(m->exceptiontable, exceptiontable, m->exceptiontablelength);
1562 CFREE(m->mcode, m->mcodelength);
1564 if (m->stubroutine) {
1565 if (m->flags & ACC_NATIVE) {
1566 removenativestub(m->stubroutine);
1569 removecompilerstub(m->stubroutine);
1575 /************** Function: method_display (debugging only) **************/
1577 void method_display(methodinfo *m)
1580 printflags(m->flags);
1582 utf_display(m->name);
1584 utf_display(m->descriptor);
1588 /************** Function: method_display_flags_last (debugging only) **************/
1590 void method_display_flags_last(methodinfo *m)
1593 utf_display(m->name);
1595 utf_display(m->descriptor);
1597 printflags(m->flags);
1602 /******************** Function: method_canoverwrite ****************************
1604 Check if m and old are identical with respect to type and name. This means
1605 that old can be overwritten with m.
1607 *******************************************************************************/
1609 static bool method_canoverwrite(methodinfo *m, methodinfo *old)
1611 if (m->name != old->name) return false;
1612 if (m->descriptor != old->descriptor) return false;
1613 if (m->flags & ACC_STATIC) return false;
1618 /******************** function: class_loadcpool ********************************
1620 loads the constantpool of a class,
1621 the entries are transformed into a simpler format
1622 by resolving references
1623 (a detailed overview of the compact structures can be found in global.h)
1625 *******************************************************************************/
1627 static bool class_loadcpool(classbuffer *cb, classinfo *c)
1630 /* The following structures are used to save information which cannot be
1631 processed during the first pass. After the complete constantpool has
1632 been traversed the references can be resolved.
1633 (only in specific order) */
1635 /* CONSTANT_Class entries */
1636 typedef struct forward_class {
1637 struct forward_class *next;
1642 /* CONSTANT_String */
1643 typedef struct forward_string {
1644 struct forward_string *next;
1649 /* CONSTANT_NameAndType */
1650 typedef struct forward_nameandtype {
1651 struct forward_nameandtype *next;
1655 } forward_nameandtype;
1657 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
1658 typedef struct forward_fieldmethint {
1659 struct forward_fieldmethint *next;
1663 u2 nameandtype_index;
1664 } forward_fieldmethint;
1669 forward_class *forward_classes = NULL;
1670 forward_string *forward_strings = NULL;
1671 forward_nameandtype *forward_nameandtypes = NULL;
1672 forward_fieldmethint *forward_fieldmethints = NULL;
1675 forward_string *nfs;
1676 forward_nameandtype *nfn;
1677 forward_fieldmethint *nff;
1683 /* number of entries in the constant_pool table plus one */
1684 if (!check_classbuffer_size(cb, 2))
1687 cpcount = c->cpcount = suck_u2(cb);
1689 /* allocate memory */
1690 cptags = c->cptags = MNEW(u1, cpcount);
1691 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
1694 *exceptionptr = new_classformaterror(c, "Illegal constant pool size");
1698 #if defined(STATISTICS)
1700 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
1703 /* initialize constantpool */
1704 for (idx = 0; idx < cpcount; idx++) {
1705 cptags[idx] = CONSTANT_UNUSED;
1706 cpinfos[idx] = NULL;
1710 /******* first pass *******/
1711 /* entries which cannot be resolved now are written into
1712 temporary structures and traversed again later */
1715 while (idx < cpcount) {
1718 /* get constant type */
1719 if (!check_classbuffer_size(cb, 1))
1725 case CONSTANT_Class:
1726 nfc = NEW(forward_class);
1728 nfc->next = forward_classes;
1729 forward_classes = nfc;
1731 nfc->thisindex = idx;
1732 /* reference to CONSTANT_NameAndType */
1733 if (!check_classbuffer_size(cb, 2))
1736 nfc->name_index = suck_u2(cb);
1741 case CONSTANT_String:
1742 nfs = NEW(forward_string);
1744 nfs->next = forward_strings;
1745 forward_strings = nfs;
1747 nfs->thisindex = idx;
1749 /* reference to CONSTANT_Utf8_info with string characters */
1750 if (!check_classbuffer_size(cb, 2))
1753 nfs->string_index = suck_u2(cb);
1758 case CONSTANT_NameAndType:
1759 nfn = NEW(forward_nameandtype);
1761 nfn->next = forward_nameandtypes;
1762 forward_nameandtypes = nfn;
1764 nfn->thisindex = idx;
1766 if (!check_classbuffer_size(cb, 2 + 2))
1769 /* reference to CONSTANT_Utf8_info containing simple name */
1770 nfn->name_index = suck_u2(cb);
1772 /* reference to CONSTANT_Utf8_info containing field or method
1774 nfn->sig_index = suck_u2(cb);
1779 case CONSTANT_Fieldref:
1780 case CONSTANT_Methodref:
1781 case CONSTANT_InterfaceMethodref:
1782 nff = NEW(forward_fieldmethint);
1784 nff->next = forward_fieldmethints;
1785 forward_fieldmethints = nff;
1787 nff->thisindex = idx;
1791 if (!check_classbuffer_size(cb, 2 + 2))
1794 /* class or interface type that contains the declaration of the
1796 nff->class_index = suck_u2(cb);
1798 /* name and descriptor of the field or method */
1799 nff->nameandtype_index = suck_u2(cb);
1804 case CONSTANT_Integer: {
1805 constant_integer *ci = NEW(constant_integer);
1807 #if defined(STATISTICS)
1809 count_const_pool_len += sizeof(constant_integer);
1812 if (!check_classbuffer_size(cb, 4))
1815 ci->value = suck_s4(cb);
1816 cptags[idx] = CONSTANT_Integer;
1823 case CONSTANT_Float: {
1824 constant_float *cf = NEW(constant_float);
1826 #if defined(STATISTICS)
1828 count_const_pool_len += sizeof(constant_float);
1831 if (!check_classbuffer_size(cb, 4))
1834 cf->value = suck_float(cb);
1835 cptags[idx] = CONSTANT_Float;
1842 case CONSTANT_Long: {
1843 constant_long *cl = NEW(constant_long);
1845 #if defined(STATISTICS)
1847 count_const_pool_len += sizeof(constant_long);
1850 if (!check_classbuffer_size(cb, 8))
1853 cl->value = suck_s8(cb);
1854 cptags[idx] = CONSTANT_Long;
1857 if (idx > cpcount) {
1859 new_classformaterror(c, "Invalid constant pool entry");
1865 case CONSTANT_Double: {
1866 constant_double *cd = NEW(constant_double);
1868 #if defined(STATISTICS)
1870 count_const_pool_len += sizeof(constant_double);
1873 if (!check_classbuffer_size(cb, 8))
1876 cd->value = suck_double(cb);
1877 cptags[idx] = CONSTANT_Double;
1880 if (idx > cpcount) {
1882 new_classformaterror(c, "Invalid constant pool entry");
1888 case CONSTANT_Utf8: {
1891 /* number of bytes in the bytes array (not string-length) */
1892 if (!check_classbuffer_size(cb, 2))
1895 length = suck_u2(cb);
1896 cptags[idx] = CONSTANT_Utf8;
1898 /* validate the string */
1899 if (!check_classbuffer_size(cb, length))
1903 !is_valid_utf(cb->pos + 1, cb->pos + 1 + length)) {
1904 dolog("Invalid UTF-8 string (constant pool index %d)",idx);
1905 panic("Invalid UTF-8 string");
1907 /* insert utf-string into the utf-symboltable */
1908 cpinfos[idx] = utf_new_intern(cb->pos + 1, length);
1910 /* skip bytes of the string (buffer size check above) */
1911 skip_nbytes(cb, length);
1918 new_classformaterror(c, "Illegal constant pool type");
1924 /* resolve entries in temporary structures */
1926 while (forward_classes) {
1928 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
1930 if (opt_verify && !is_valid_name_utf(name))
1931 panic("Class reference with invalid name");
1933 cptags[forward_classes->thisindex] = CONSTANT_Class;
1934 /* retrieve class from class-table */
1937 tc = class_new_intern(name);
1939 if (!class_load(tc))
1942 /* link the class later, because we cannot link the class currently
1944 list_addfirst(&unlinkedclasses, tc);
1946 cpinfos[forward_classes->thisindex] = tc;
1949 cpinfos[forward_classes->thisindex] = class_new(name);
1952 nfc = forward_classes;
1953 forward_classes = forward_classes->next;
1954 FREE(nfc, forward_class);
1957 while (forward_strings) {
1959 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
1961 /* resolve utf-string */
1962 cptags[forward_strings->thisindex] = CONSTANT_String;
1963 cpinfos[forward_strings->thisindex] = text;
1965 nfs = forward_strings;
1966 forward_strings = forward_strings->next;
1967 FREE(nfs, forward_string);
1970 while (forward_nameandtypes) {
1971 constant_nameandtype *cn = NEW(constant_nameandtype);
1973 #if defined(STATISTICS)
1975 count_const_pool_len += sizeof(constant_nameandtype);
1978 /* resolve simple name and descriptor */
1979 cn->name = class_getconstant(c,
1980 forward_nameandtypes->name_index,
1983 cn->descriptor = class_getconstant(c,
1984 forward_nameandtypes->sig_index,
1989 if (!is_valid_name_utf(cn->name))
1990 panic("NameAndType with invalid name");
1991 /* disallow referencing <clinit> among others */
1992 if (cn->name->text[0] == '<' && cn->name != utf_init)
1993 panic("NameAndType with invalid special name");
1996 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
1997 cpinfos[forward_nameandtypes->thisindex] = cn;
1999 nfn = forward_nameandtypes;
2000 forward_nameandtypes = forward_nameandtypes->next;
2001 FREE(nfn, forward_nameandtype);
2004 while (forward_fieldmethints) {
2005 constant_nameandtype *nat;
2006 constant_FMIref *fmi = NEW(constant_FMIref);
2008 #if defined(STATISTICS)
2010 count_const_pool_len += sizeof(constant_FMIref);
2012 /* resolve simple name and descriptor */
2013 nat = class_getconstant(c,
2014 forward_fieldmethints->nameandtype_index,
2015 CONSTANT_NameAndType);
2017 fmi->class = class_getconstant(c,
2018 forward_fieldmethints->class_index,
2020 fmi->name = nat->name;
2021 fmi->descriptor = nat->descriptor;
2023 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
2024 cpinfos[forward_fieldmethints->thisindex] = fmi;
2026 switch (forward_fieldmethints->tag) {
2027 case CONSTANT_Fieldref: /* check validity of descriptor */
2028 checkfielddescriptor(fmi->descriptor->text,
2029 utf_end(fmi->descriptor));
2031 case CONSTANT_InterfaceMethodref:
2032 case CONSTANT_Methodref: /* check validity of descriptor */
2033 checkmethoddescriptor(c, fmi->descriptor);
2037 nff = forward_fieldmethints;
2038 forward_fieldmethints = forward_fieldmethints->next;
2039 FREE(nff, forward_fieldmethint);
2042 /* everything was ok */
2048 /********************** Function: class_load ***********************************
2050 Loads everything interesting about a class from the class file. The
2051 'classinfo' structure must have been allocated previously.
2053 The super class and the interfaces implemented by this class need not be
2054 loaded. The link is set later by the function 'class_link'.
2056 The loaded class is removed from the list 'unloadedclasses' and added to
2057 the list 'unlinkedclasses'.
2059 *******************************************************************************/
2061 classinfo *class_load_intern(classbuffer *cb);
2063 classinfo *class_load(classinfo *c)
2068 /* enter a monitor on the class */
2070 builtin_monitorenter((java_objectheader *) c);
2072 /* maybe the class is already loaded */
2074 builtin_monitorexit((java_objectheader *) c);
2081 if (getcompilingtime)
2082 compilingtime_stop();
2085 loadingtime_start();
2087 /* load classdata, throw exception on error */
2089 if ((cb = suck_start(c)) == NULL) {
2090 /* this means, the classpath was not set properly */
2091 if (c->name == utf_java_lang_Object)
2092 throw_cacao_exception_exit(string_java_lang_NoClassDefFoundError,
2093 "java/lang/Object");
2096 new_exception_utfmessage(string_java_lang_NoClassDefFoundError,
2099 builtin_monitorexit((java_objectheader *) c);
2104 /* call the internal function */
2105 r = class_load_intern(cb);
2107 /* if return value is NULL, we had a problem and the class is not loaded */
2111 /* now free the allocated memory, otherwise we could ran into a DOS */
2123 if (getcompilingtime)
2124 compilingtime_start();
2126 /* leave the monitor */
2128 builtin_monitorexit((java_objectheader *) c);
2134 classinfo *class_load_intern(classbuffer *cb)
2140 char msg[MAXLOGTEXT]; /* maybe we get an exception */
2142 /* get the classbuffer's class */
2145 /* maybe the class is already loaded */
2149 #if defined(STATISTICS)
2151 count_class_loads++;
2154 /* output for debugging purposes */
2156 log_message_class("Loading class: ", c);
2158 /* class is somewhat loaded */
2161 if (!check_classbuffer_size(cb, 4 + 2 + 2))
2164 /* check signature */
2165 if (suck_u4(cb) != MAGIC) {
2166 *exceptionptr = new_classformaterror(c, "Bad magic number");
2175 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
2177 new_unsupportedclassversionerror(c,
2178 "Unsupported major.minor version %d.%d",
2184 /* load the constant pool */
2185 if (!class_loadcpool(cb, c))
2189 c->erroneous_state = 0;
2190 c->initializing_thread = 0;
2192 c->classUsed = NOTUSED; /* not used initially CO-RT */
2196 if (!check_classbuffer_size(cb, 2))
2199 c->flags = suck_u2(cb);
2200 /*if (!(c->flags & ACC_PUBLIC)) { log_text("CLASS NOT PUBLIC"); } JOWENN*/
2202 /* check ACC flags consistency */
2203 if (c->flags & ACC_INTERFACE) {
2204 if (!(c->flags & ACC_ABSTRACT)) {
2205 /* We work around this because interfaces in JDK 1.1 are
2206 * not declared abstract. */
2208 c->flags |= ACC_ABSTRACT;
2209 /* panic("Interface class not declared abstract"); */
2212 if (c->flags & ACC_FINAL) {
2214 new_classformaterror(c,
2215 "Illegal class modifiers: 0x%X", c->flags);
2220 if (c->flags & ACC_SUPER) {
2221 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
2225 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
2227 new_classformaterror(c, "Illegal class modifiers: 0x%X", c->flags);
2232 if (!check_classbuffer_size(cb, 2 + 2))
2237 if (!(tc = class_getconstant(c, i, CONSTANT_Class)))
2241 utf_sprint(msg, c->name);
2242 sprintf(msg + strlen(msg), " (wrong name: ");
2243 utf_sprint(msg + strlen(msg), tc->name);
2244 sprintf(msg + strlen(msg), ")");
2247 new_exception_message(string_java_lang_NoClassDefFoundError, msg);
2252 /* retrieve superclass */
2253 if ((i = suck_u2(cb))) {
2254 if (!(c->super = class_getconstant(c, i, CONSTANT_Class)))
2257 /* java.lang.Object may not have a super class. */
2258 if (c->name == utf_java_lang_Object) {
2260 new_exception_message(string_java_lang_ClassFormatError,
2261 "java.lang.Object with superclass");
2266 /* Interfaces must have java.lang.Object as super class. */
2267 if ((c->flags & ACC_INTERFACE) &&
2268 c->super->name != utf_java_lang_Object) {
2270 new_exception_message(string_java_lang_ClassFormatError,
2271 "Interfaces must have java.lang.Object as superclass");
2279 /* This is only allowed for java.lang.Object. */
2280 if (c->name != utf_java_lang_Object) {
2281 *exceptionptr = new_classformaterror(c, "Bad superclass index");
2287 /* retrieve interfaces */
2288 if (!check_classbuffer_size(cb, 2))
2291 c->interfacescount = suck_u2(cb);
2293 if (!check_classbuffer_size(cb, 2 * c->interfacescount))
2296 c->interfaces = MNEW(classinfo*, c->interfacescount);
2297 for (i = 0; i < c->interfacescount; i++) {
2298 if (!(c->interfaces[i] = class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2303 if (!check_classbuffer_size(cb, 2))
2306 c->fieldscount = suck_u2(cb);
2307 c->fields = GCNEW(fieldinfo, c->fieldscount);
2308 /* c->fields = MNEW(fieldinfo, c->fieldscount); */
2309 for (i = 0; i < c->fieldscount; i++) {
2310 if (!field_load(cb, c, &(c->fields[i])))
2315 if (!check_classbuffer_size(cb, 2))
2318 c->methodscount = suck_u2(cb);
2319 c->methods = GCNEW(methodinfo, c->methodscount);
2320 /* c->methods = MNEW(methodinfo, c->methodscount); */
2321 for (i = 0; i < c->methodscount; i++) {
2322 if (!method_load(cb, c, &(c->methods[i])))
2326 /* Check if all fields and methods can be uniquely
2327 * identified by (name,descriptor). */
2329 /* We use a hash table here to avoid making the
2330 * average case quadratic in # of methods, fields.
2332 static int shift = 0;
2334 u2 *next; /* for chaining colliding hash entries */
2340 /* Allocate hashtable */
2341 len = c->methodscount;
2342 if (len < c->fieldscount) len = c->fieldscount;
2344 hashtab = MNEW(u2,(hashlen + len));
2345 next = hashtab + hashlen;
2347 /* Determine bitshift (to get good hash values) */
2357 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2359 for (i = 0; i < c->fieldscount; ++i) {
2360 fieldinfo *fi = c->fields + i;
2362 /* It's ok if we lose bits here */
2363 index = ((((size_t) fi->name) +
2364 ((size_t) fi->descriptor)) >> shift) % hashlen;
2366 if ((old = hashtab[index])) {
2370 if (c->fields[old].name == fi->name &&
2371 c->fields[old].descriptor == fi->descriptor) {
2373 new_classformaterror(c,
2374 "Repetitive field name/signature");
2378 } while ((old = next[old]));
2380 hashtab[index] = i + 1;
2384 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2386 for (i = 0; i < c->methodscount; ++i) {
2387 methodinfo *mi = c->methods + i;
2389 /* It's ok if we lose bits here */
2390 index = ((((size_t) mi->name) +
2391 ((size_t) mi->descriptor)) >> shift) % hashlen;
2395 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2396 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2400 if ((old = hashtab[index])) {
2404 if (c->methods[old].name == mi->name &&
2405 c->methods[old].descriptor == mi->descriptor) {
2407 new_classformaterror(c,
2408 "Repetitive method name/signature");
2412 } while ((old = next[old]));
2414 hashtab[index] = i + 1;
2417 MFREE(hashtab, u2, (hashlen + len));
2420 #if defined(STATISTICS)
2422 count_class_infos += sizeof(classinfo*) * c->interfacescount;
2423 count_class_infos += sizeof(fieldinfo) * c->fieldscount;
2424 count_class_infos += sizeof(methodinfo) * c->methodscount;
2428 /* load attribute structures */
2429 if (!check_classbuffer_size(cb, 2))
2432 if (!attribute_load(cb, c, suck_u2(cb)))
2436 /* Pre java 1.5 version don't check this. This implementation is like
2437 java 1.5 do it: for class file version 45.3 we don't check it, older
2438 versions are checked.
2440 if ((ma == 45 && mi > 3) || ma > 45) {
2441 /* check if all data has been read */
2442 s4 classdata_left = ((cb->data + cb->size) - cb->pos - 1);
2444 if (classdata_left > 0) {
2446 new_classformaterror(c, "Extra bytes at the end of class file");
2453 log_message_class("Loading done class: ", c);
2460 /************** internal Function: class_highestinterface **********************
2462 Used by the function class_link to determine the amount of memory needed
2463 for the interface table.
2465 *******************************************************************************/
2467 static s4 class_highestinterface(classinfo *c)
2472 /* check for ACC_INTERFACE bit already done in class_link_intern */
2475 for (i = 0; i < c->interfacescount; i++) {
2476 s4 h2 = class_highestinterface(c->interfaces[i]);
2484 /* class_addinterface **********************************************************
2486 Is needed by class_link for adding a VTBL to a class. All interfaces
2487 implemented by ic are added as well.
2489 *******************************************************************************/
2491 static void class_addinterface(classinfo *c, classinfo *ic)
2495 vftbl_t *v = c->vftbl;
2497 if (i >= v->interfacetablelength)
2498 panic ("Inernal error: interfacetable overflow");
2500 if (v->interfacetable[-i])
2503 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
2504 v->interfacevftbllength[i] = 1;
2505 v->interfacetable[-i] = MNEW(methodptr, 1);
2506 v->interfacetable[-i][0] = NULL;
2509 v->interfacevftbllength[i] = ic->methodscount;
2510 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
2512 #if defined(STATISTICS)
2514 count_vftbl_len += sizeof(methodptr) *
2515 (ic->methodscount + (ic->methodscount == 0));
2518 for (j = 0; j < ic->methodscount; j++) {
2521 for (m = 0; m < sc->methodscount; m++) {
2522 methodinfo *mi = &(sc->methods[m]);
2523 if (method_canoverwrite(mi, &(ic->methods[j]))) {
2524 v->interfacetable[-i][j] = v->table[mi->vftblindex];
2535 for (j = 0; j < ic->interfacescount; j++)
2536 class_addinterface(c, ic->interfaces[j]);
2540 /******************* Function: class_new_array *********************************
2542 This function is called by class_new to setup an array class.
2544 *******************************************************************************/
2546 void class_new_array(classinfo *c)
2548 classinfo *comp = NULL;
2552 /* Check array class name */
2553 namelen = c->name->blength;
2554 if (namelen < 2 || c->name->text[0] != '[')
2555 panic("Invalid array class name");
2557 /* Check the component type */
2558 switch (c->name->text[1]) {
2560 /* c is an array of arrays. We have to create the component class. */
2562 comp = class_new_intern(utf_new_intern(c->name->text + 1,
2565 list_addfirst(&unlinkedclasses, comp);
2568 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2573 /* c is an array of objects. */
2574 if (namelen < 4 || c->name->text[namelen - 1] != ';')
2575 panic("Invalid array class name");
2578 comp = class_new_intern(utf_new_intern(c->name->text + 2,
2581 list_addfirst(&unlinkedclasses, comp);
2584 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2589 /* Setup the array class */
2590 c->super = class_java_lang_Object;
2591 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2593 c->interfacescount = 2;
2594 c->interfaces = MNEW(classinfo*, 2);
2599 tc = class_new_intern(utf_new_char("java/lang/Cloneable"));
2601 list_addfirst(&unlinkedclasses, tc);
2602 c->interfaces[0] = tc;
2604 tc = class_new_intern(utf_new_char("java/io/Serializable"));
2606 list_addfirst(&unlinkedclasses, tc);
2607 c->interfaces[1] = tc;
2610 c->interfaces[0] = class_new(utf_new_char("java/lang/Cloneable"));
2611 c->interfaces[1] = class_new(utf_new_char("java/io/Serializable"));
2614 c->methodscount = 1;
2615 c->methods = MNEW(methodinfo, c->methodscount);
2618 memset(clone, 0, sizeof(methodinfo));
2619 clone->flags = ACC_PUBLIC;
2620 clone->name = utf_new_char("clone");
2621 clone->descriptor = utf_new_char("()Ljava/lang/Object;");
2623 clone->stubroutine = createnativestub((functionptr) &builtin_clone_array, clone);
2624 clone->monoPoly = MONO;
2626 /* XXX: field: length? */
2628 /* array classes are not loaded from class files */
2633 /****************** Function: class_link_array *********************************
2635 This function is called by class_link to create the
2636 arraydescriptor for an array class.
2638 This function returns NULL if the array cannot be linked because
2639 the component type has not been linked yet.
2641 *******************************************************************************/
2643 static arraydescriptor *class_link_array(classinfo *c)
2645 classinfo *comp = NULL;
2646 s4 namelen = c->name->blength;
2647 arraydescriptor *desc;
2650 /* Check the component type */
2651 switch (c->name->text[1]) {
2653 /* c is an array of arrays. */
2654 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2656 panic("Could not find component array class.");
2660 /* c is an array of objects. */
2661 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2663 panic("Could not find component class.");
2667 /* If the component type has not been linked, link it now */
2668 if (comp && !comp->linked) {
2670 if (!class_load(comp))
2673 if (!class_link(comp))
2677 /* Allocate the arraydescriptor */
2678 desc = NEW(arraydescriptor);
2681 /* c is an array of references */
2682 desc->arraytype = ARRAYTYPE_OBJECT;
2683 desc->componentsize = sizeof(void*);
2684 desc->dataoffset = OFFSET(java_objectarray, data);
2686 compvftbl = comp->vftbl;
2688 panic("Component class has no vftbl");
2689 desc->componentvftbl = compvftbl;
2691 if (compvftbl->arraydesc) {
2692 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
2693 if (compvftbl->arraydesc->dimension >= 255)
2694 panic("Creating array of dimension >255");
2695 desc->dimension = compvftbl->arraydesc->dimension + 1;
2696 desc->elementtype = compvftbl->arraydesc->elementtype;
2699 desc->elementvftbl = compvftbl;
2700 desc->dimension = 1;
2701 desc->elementtype = ARRAYTYPE_OBJECT;
2705 /* c is an array of a primitive type */
2706 switch (c->name->text[1]) {
2708 desc->arraytype = ARRAYTYPE_BOOLEAN;
2709 desc->dataoffset = OFFSET(java_booleanarray,data);
2710 desc->componentsize = sizeof(u1);
2714 desc->arraytype = ARRAYTYPE_BYTE;
2715 desc->dataoffset = OFFSET(java_bytearray,data);
2716 desc->componentsize = sizeof(u1);
2720 desc->arraytype = ARRAYTYPE_CHAR;
2721 desc->dataoffset = OFFSET(java_chararray,data);
2722 desc->componentsize = sizeof(u2);
2726 desc->arraytype = ARRAYTYPE_DOUBLE;
2727 desc->dataoffset = OFFSET(java_doublearray,data);
2728 desc->componentsize = sizeof(double);
2732 desc->arraytype = ARRAYTYPE_FLOAT;
2733 desc->dataoffset = OFFSET(java_floatarray,data);
2734 desc->componentsize = sizeof(float);
2738 desc->arraytype = ARRAYTYPE_INT;
2739 desc->dataoffset = OFFSET(java_intarray,data);
2740 desc->componentsize = sizeof(s4);
2744 desc->arraytype = ARRAYTYPE_LONG;
2745 desc->dataoffset = OFFSET(java_longarray,data);
2746 desc->componentsize = sizeof(s8);
2750 desc->arraytype = ARRAYTYPE_SHORT;
2751 desc->dataoffset = OFFSET(java_shortarray,data);
2752 desc->componentsize = sizeof(s2);
2756 panic("Invalid array class name");
2759 desc->componentvftbl = NULL;
2760 desc->elementvftbl = NULL;
2761 desc->dimension = 1;
2762 desc->elementtype = desc->arraytype;
2769 /********************** Function: class_link ***********************************
2771 Tries to link a class. The function calculates the length in bytes that
2772 an instance of this class requires as well as the VTBL for methods and
2775 *******************************************************************************/
2777 static classinfo *class_link_intern(classinfo *c);
2779 classinfo *class_link(classinfo *c)
2783 /* enter a monitor on the class */
2785 builtin_monitorenter((java_objectheader *) c);
2787 /* maybe the class is already linked */
2789 builtin_monitorexit((java_objectheader *) c);
2796 if (getcompilingtime)
2797 compilingtime_stop();
2800 loadingtime_start();
2802 /* call the internal function */
2803 r = class_link_intern(c);
2805 /* if return value is NULL, we had a problem and the class is not linked */
2814 if (getcompilingtime)
2815 compilingtime_start();
2817 /* leave the monitor */
2819 builtin_monitorexit((java_objectheader *) c);
2825 static classinfo *class_link_intern(classinfo *c)
2827 s4 supervftbllength; /* vftbllegnth of super class */
2828 s4 vftbllength; /* vftbllength of current class */
2829 s4 interfacetablelength; /* interface table length */
2830 classinfo *super; /* super class */
2831 classinfo *tc; /* temporary class variable */
2832 vftbl_t *v; /* vftbl of current class */
2833 s4 i; /* interface/method/field counter */
2834 arraydescriptor *arraydesc; /* descriptor for array classes */
2836 /* maybe the class is already linked */
2840 /* maybe the class is not loaded */
2846 log_message_class("Linking class: ", c);
2848 /* ok, this class is somewhat linked */
2853 /* check interfaces */
2855 for (i = 0; i < c->interfacescount; i++) {
2856 tc = c->interfaces[i];
2858 /* detect circularity */
2861 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2867 if (!class_load(tc))
2870 if (!(tc->flags & ACC_INTERFACE)) {
2872 new_exception_message(string_java_lang_IncompatibleClassChangeError,
2873 "Implementing class");
2878 if (!class_link(tc))
2882 /* check super class */
2886 if (super == NULL) { /* class java.lang.Object */
2888 c->classUsed = USED; /* Object class is always used CO-RT*/
2890 c->instancesize = sizeof(java_objectheader);
2892 vftbllength = supervftbllength = 0;
2894 c->finalizer = NULL;
2897 /* detect circularity */
2900 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2906 if (!class_load(super))
2909 if (super->flags & ACC_INTERFACE) {
2910 // java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class
2911 panic("Interface specified as super class");
2914 /* Don't allow extending final classes */
2915 if (super->flags & ACC_FINAL) {
2917 new_exception_message(string_java_lang_VerifyError,
2918 "Cannot inherit from final class");
2923 if (!class_link(super))
2926 /* handle array classes */
2927 if (c->name->text[0] == '[')
2928 if (!(arraydesc = class_link_array(c)))
2931 if (c->flags & ACC_INTERFACE)
2932 c->index = interfaceindex++;
2934 c->index = super->index + 1;
2936 c->instancesize = super->instancesize;
2938 vftbllength = supervftbllength = super->vftbl->vftbllength;
2940 c->finalizer = super->finalizer;
2943 /* compute vftbl length */
2945 for (i = 0; i < c->methodscount; i++) {
2946 methodinfo *m = &(c->methods[i]);
2948 if (!(m->flags & ACC_STATIC)) { /* is instance method */
2953 for (j = 0; j < tc->methodscount; j++) {
2954 if (method_canoverwrite(m, &(tc->methods[j]))) {
2955 if (tc->methods[j].flags & ACC_PRIVATE)
2956 goto notfoundvftblindex;
2958 if (tc->methods[j].flags & ACC_FINAL) {
2959 // class a overrides final method .
2961 new_exception(string_java_lang_VerifyError);
2964 m->vftblindex = tc->methods[j].vftblindex;
2965 goto foundvftblindex;
2971 m->vftblindex = (vftbllength++);
2977 #if defined(STATISTICS)
2980 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
2983 /* compute interfacetable length */
2985 interfacetablelength = 0;
2988 for (i = 0; i < tc->interfacescount; i++) {
2989 s4 h = class_highestinterface(tc->interfaces[i]) + 1;
2990 if (h > interfacetablelength)
2991 interfacetablelength = h;
2996 /* allocate virtual function table */
2998 v = (vftbl_t*) mem_alloc(sizeof(vftbl_t) + sizeof(methodptr) *
2999 (vftbllength - 1) + sizeof(methodptr*) *
3000 (interfacetablelength - (interfacetablelength > 0)));
3001 v = (vftbl_t*) (((methodptr*) v) + (interfacetablelength - 1) *
3002 (interfacetablelength > 1));
3003 c->header.vftbl = c->vftbl = v;
3005 v->vftbllength = vftbllength;
3006 v->interfacetablelength = interfacetablelength;
3007 v->arraydesc = arraydesc;
3009 /* store interface index in vftbl */
3010 if (c->flags & ACC_INTERFACE)
3011 v->baseval = -(c->index);
3013 /* copy virtual function table of super class */
3015 for (i = 0; i < supervftbllength; i++)
3016 v->table[i] = super->vftbl->table[i];
3018 /* add method stubs into virtual function table */
3020 for (i = 0; i < c->methodscount; i++) {
3021 methodinfo *m = &(c->methods[i]);
3022 if (!(m->flags & ACC_STATIC)) {
3023 v->table[m->vftblindex] = m->stubroutine;
3027 /* compute instance size and offset of each field */
3029 for (i = 0; i < c->fieldscount; i++) {
3031 fieldinfo *f = &(c->fields[i]);
3033 if (!(f->flags & ACC_STATIC)) {
3034 dsize = desc_typesize(f->descriptor);
3035 c->instancesize = ALIGN(c->instancesize, dsize);
3036 f->offset = c->instancesize;
3037 c->instancesize += dsize;
3041 /* initialize interfacetable and interfacevftbllength */
3043 v->interfacevftbllength = MNEW(s4, interfacetablelength);
3045 #if defined(STATISTICS)
3047 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
3050 for (i = 0; i < interfacetablelength; i++) {
3051 v->interfacevftbllength[i] = 0;
3052 v->interfacetable[-i] = NULL;
3055 /* add interfaces */
3057 for (tc = c; tc != NULL; tc = tc->super) {
3058 for (i = 0; i < tc->interfacescount; i++) {
3059 class_addinterface(c, tc->interfaces[i]);
3063 /* add finalizer method (not for java.lang.Object) */
3068 fi = class_findmethod(c, utf_finalize, utf_fidesc);
3071 if (!(fi->flags & ACC_STATIC)) {
3079 loader_compute_subclasses(c);
3082 log_message_class("Linking done class: ", c);
3084 /* just return c to show that we didn't had a problem */
3090 /******************* Function: class_freepool **********************************
3092 Frees all resources used by this classes Constant Pool.
3094 *******************************************************************************/
3096 static void class_freecpool(classinfo *c)
3102 if (c->cptags && c->cpinfos) {
3103 for (idx = 0; idx < c->cpcount; idx++) {
3104 tag = c->cptags[idx];
3105 info = c->cpinfos[idx];
3109 case CONSTANT_Fieldref:
3110 case CONSTANT_Methodref:
3111 case CONSTANT_InterfaceMethodref:
3112 FREE(info, constant_FMIref);
3114 case CONSTANT_Integer:
3115 FREE(info, constant_integer);
3117 case CONSTANT_Float:
3118 FREE(info, constant_float);
3121 FREE(info, constant_long);
3123 case CONSTANT_Double:
3124 FREE(info, constant_double);
3126 case CONSTANT_NameAndType:
3127 FREE(info, constant_nameandtype);
3135 MFREE(c->cptags, u1, c->cpcount);
3138 MFREE(c->cpinfos, voidptr, c->cpcount);
3142 /*********************** Function: class_free **********************************
3144 Frees all resources used by the class.
3146 *******************************************************************************/
3148 void class_free(classinfo *c)
3156 MFREE(c->interfaces, classinfo*, c->interfacescount);
3159 for (i = 0; i < c->fieldscount; i++)
3160 field_free(&(c->fields[i]));
3161 /* MFREE(c->fields, fieldinfo, c->fieldscount); */
3165 for (i = 0; i < c->methodscount; i++)
3166 method_free(&(c->methods[i]));
3167 /* MFREE(c->methods, methodinfo, c->methodscount); */
3170 if ((v = c->vftbl) != NULL) {
3172 mem_free(v->arraydesc,sizeof(arraydescriptor));
3174 for (i = 0; i < v->interfacetablelength; i++) {
3175 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
3177 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
3179 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
3180 sizeof(methodptr*) * (v->interfacetablelength -
3181 (v->interfacetablelength > 0));
3182 v = (vftbl_t*) (((methodptr*) v) - (v->interfacetablelength - 1) *
3183 (v->interfacetablelength > 1));
3188 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
3190 /* if (c->classvftbl)
3191 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
3197 /************************* Function: class_findfield ***************************
3199 Searches a 'classinfo' structure for a field having the given name and
3202 *******************************************************************************/
3204 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
3208 for (i = 0; i < c->fieldscount; i++) {
3209 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
3210 return &(c->fields[i]);
3213 panic("Can not find field given in CONSTANT_Fieldref");
3215 /* keep compiler happy */
3220 /****************** Function: class_resolvefield_int ***************************
3222 This is an internally used helper function. Do not use this directly.
3224 Tries to resolve a field having the given name and type.
3225 If the field cannot be resolved, NULL is returned.
3227 *******************************************************************************/
3229 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
3234 /* search for field in class c */
3235 for (i = 0; i < c->fieldscount; i++) {
3236 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
3237 return &(c->fields[i]);
3241 /* try superinterfaces recursively */
3242 for (i = 0; i < c->interfacescount; ++i) {
3243 fi = class_resolvefield_int(c->interfaces[i], name, desc);
3248 /* try superclass */
3250 return class_resolvefield_int(c->super, name, desc);
3257 /********************* Function: class_resolvefield ***************************
3259 Resolves a reference from REFERER to a field with NAME and DESC in class C.
3261 If the field cannot be resolved the return value is NULL. If EXCEPT is
3262 true *exceptionptr is set, too.
3264 *******************************************************************************/
3266 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
3267 classinfo *referer, bool except)
3271 /* XXX resolve class c */
3272 /* XXX check access from REFERER to C */
3274 fi = class_resolvefield_int(c, name, desc);
3279 new_exception_utfmessage(string_java_lang_NoSuchFieldError,
3285 /* XXX check access rights */
3291 /************************* Function: class_findmethod **************************
3293 Searches a 'classinfo' structure for a method having the given name and
3294 type and returns the index in the class info structure.
3295 If type is NULL, it is ignored.
3297 *******************************************************************************/
3299 s4 class_findmethodIndex(classinfo *c, utf *name, utf *desc)
3303 for (i = 0; i < c->methodscount; i++) {
3305 /* utf_display_classname(c->name);printf("."); */
3306 /* utf_display(c->methods[i].name);printf("."); */
3307 /* utf_display(c->methods[i].descriptor); */
3310 if ((c->methods[i].name == name) && ((desc == NULL) ||
3311 (c->methods[i].descriptor == desc))) {
3320 /************************* Function: class_findmethod **************************
3322 Searches a 'classinfo' structure for a method having the given name and
3324 If type is NULL, it is ignored.
3326 *******************************************************************************/
3328 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
3330 s4 idx = class_findmethodIndex(c, name, desc);
3335 return &(c->methods[idx]);
3339 /*********************** Function: class_fetchmethod **************************
3341 like class_findmethod, but aborts with an error if the method is not found
3343 *******************************************************************************/
3345 methodinfo *class_fetchmethod(classinfo *c, utf *name, utf *desc)
3349 mi = class_findmethod(c, name, desc);
3352 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3353 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3354 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3355 panic("Method not found");
3362 /*********************** Function: class_findmethod_w**************************
3364 like class_findmethod, but logs a warning if the method is not found
3366 *******************************************************************************/
3368 methodinfo *class_findmethod_w(classinfo *c, utf *name, utf *desc, char *from)
3371 mi = class_findmethod(c, name, desc);
3374 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3375 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3376 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3378 if ( c->flags & ACC_PUBLIC ) log_plain(" PUBLIC ");
3379 if ( c->flags & ACC_PRIVATE ) log_plain(" PRIVATE ");
3380 if ( c->flags & ACC_PROTECTED ) log_plain(" PROTECTED ");
3381 if ( c->flags & ACC_STATIC ) log_plain(" STATIC ");
3382 if ( c->flags & ACC_FINAL ) log_plain(" FINAL ");
3383 if ( c->flags & ACC_SYNCHRONIZED ) log_plain(" SYNCHRONIZED ");
3384 if ( c->flags & ACC_VOLATILE ) log_plain(" VOLATILE ");
3385 if ( c->flags & ACC_TRANSIENT ) log_plain(" TRANSIENT ");
3386 if ( c->flags & ACC_NATIVE ) log_plain(" NATIVE ");
3387 if ( c->flags & ACC_INTERFACE ) log_plain(" INTERFACE ");
3388 if ( c->flags & ACC_ABSTRACT ) log_plain(" ABSTRACT ");
3391 log_plain(" : WARNING: Method not found");log_nl( );
3398 /************************* Function: class_findmethod_approx ******************
3400 like class_findmethod but ignores the return value when comparing the
3403 *******************************************************************************/
3405 methodinfo *class_findmethod_approx(classinfo *c, utf *name, utf *desc)
3409 for (i = 0; i < c->methodscount; i++) {
3410 if (c->methods[i].name == name) {
3411 utf *meth_descr = c->methods[i].descriptor;
3415 return &(c->methods[i]);
3417 if (desc->blength <= meth_descr->blength) {
3418 /* current position in utf text */
3419 char *desc_utf_ptr = desc->text;
3420 char *meth_utf_ptr = meth_descr->text;
3421 /* points behind utf strings */
3422 char *desc_end = utf_end(desc);
3423 char *meth_end = utf_end(meth_descr);
3426 /* compare argument types */
3427 while (desc_utf_ptr < desc_end && meth_utf_ptr < meth_end) {
3429 if ((ch = *desc_utf_ptr++) != (*meth_utf_ptr++))
3430 break; /* no match */
3433 return &(c->methods[i]); /* all parameter types equal */
3443 /***************** Function: class_resolvemethod_approx ***********************
3445 Searches a class and every super class for a method (without paying
3446 attention to the return value)
3448 *******************************************************************************/
3450 methodinfo *class_resolvemethod_approx(classinfo *c, utf *name, utf *desc)
3453 /* search for method (ignore returntype) */
3454 methodinfo *m = class_findmethod_approx(c, name, desc);
3457 /* search superclass */
3465 /************************* Function: class_resolvemethod ***********************
3467 Searches a class and every super class for a method.
3469 *******************************************************************************/
3471 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
3473 /*log_text("Trying to resolve a method");
3474 utf_display(c->name);
3476 utf_display(desc);*/
3479 /*log_text("Looking in:");
3480 utf_display(c->name);*/
3481 methodinfo *m = class_findmethod(c, name, desc);
3483 /* search superclass */
3486 /*log_text("method not found:");*/
3492 /****************** Function: class_resolveinterfacemethod_int ****************
3494 Internally used helper function. Do not use this directly.
3496 *******************************************************************************/
3499 methodinfo *class_resolveinterfacemethod_int(classinfo *c, utf *name, utf *desc)
3504 mi = class_findmethod(c,name,desc);
3508 /* try the superinterfaces */
3509 for (i=0; i<c->interfacescount; ++i) {
3510 mi = class_resolveinterfacemethod_int(c->interfaces[i],name,desc);
3518 /******************** Function: class_resolveinterfacemethod ******************
3520 Resolves a reference from REFERER to a method with NAME and DESC in
3523 If the method cannot be resolved the return value is NULL. If EXCEPT is
3524 true *exceptionptr is set, too.
3526 *******************************************************************************/
3528 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
3529 classinfo *referer, bool except)
3533 /* XXX resolve class c */
3534 /* XXX check access from REFERER to C */
3536 if (!(c->flags & ACC_INTERFACE)) {
3539 new_exception(string_java_lang_IncompatibleClassChangeError);
3544 mi = class_resolveinterfacemethod_int(c, name, desc);
3549 /* try class java.lang.Object */
3550 mi = class_findmethod(class_java_lang_Object, name, desc);
3557 new_exception_utfmessage(string_java_lang_NoSuchMethodError, name);
3563 /********************* Function: class_resolveclassmethod *********************
3565 Resolves a reference from REFERER to a method with NAME and DESC in
3568 If the method cannot be resolved the return value is NULL. If EXCEPT is
3569 true *exceptionptr is set, too.
3571 *******************************************************************************/
3573 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
3574 classinfo *referer, bool except)
3579 char msg[MAXLOGTEXT];
3581 /* XXX resolve class c */
3582 /* XXX check access from REFERER to C */
3584 /* if (c->flags & ACC_INTERFACE) { */
3586 /* *exceptionptr = */
3587 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
3591 /* try class c and its superclasses */
3594 mi = class_findmethod(cls, name, desc);
3597 } while ((cls = cls->super) != NULL); /* try the superclass */
3599 /* try the superinterfaces */
3600 for (i = 0; i < c->interfacescount; ++i) {
3601 mi = class_resolveinterfacemethod_int(c->interfaces[i], name, desc);
3607 utf_sprint(msg, c->name);
3608 sprintf(msg + strlen(msg), ".");
3609 utf_sprint(msg + strlen(msg), name);
3610 utf_sprint(msg + strlen(msg), desc);
3613 new_exception_message(string_java_lang_NoSuchMethodError, msg);
3619 if ((mi->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
3621 *exceptionptr = new_exception(string_java_lang_AbstractMethodError);
3626 /* XXX check access rights */
3632 /************************* Function: class_issubclass **************************
3634 Checks if sub is a descendant of super.
3636 *******************************************************************************/
3638 bool class_issubclass(classinfo *sub, classinfo *super)
3641 if (!sub) return false;
3642 if (sub == super) return true;
3648 /****************** Initialization function for classes ******************
3650 In Java, every class can have a static initialization function. This
3651 function has to be called BEFORE calling other methods or accessing static
3654 *******************************************************************************/
3656 static classinfo *class_init_intern(classinfo *c);
3658 classinfo *class_init(classinfo *c)
3662 if (!makeinitializations)
3665 /* enter a monitor on the class */
3667 builtin_monitorenter((java_objectheader *) c);
3669 /* maybe the class is already initalized or the current thread, which can
3670 pass the monitor, is currently initalizing this class */
3672 if (c->initialized || c->initializing) {
3673 builtin_monitorexit((java_objectheader *) c);
3678 /* this initalizing run begins NOW */
3679 c->initializing = true;
3681 /* call the internal function */
3682 r = class_init_intern(c);
3684 /* if return value is not NULL everything was ok and the class is
3687 c->initialized = true;
3689 /* this initalizing run is done */
3690 c->initializing = false;
3692 /* leave the monitor */
3694 builtin_monitorexit((java_objectheader *) c);
3700 /* this function MUST NOT be called directly, because of thread <clinit>
3703 static classinfo *class_init_intern(classinfo *c)
3707 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3711 /* maybe the class is not already loaded */
3716 /* maybe the class is not already linked */
3721 #if defined(STATISTICS)
3723 count_class_inits++;
3726 /* initialize super class */
3729 if (!c->super->initialized) {
3731 char logtext[MAXLOGTEXT];
3732 sprintf(logtext, "Initialize super class ");
3733 utf_sprint_classname(logtext + strlen(logtext), c->super->name);
3734 sprintf(logtext + strlen(logtext), " from ");
3735 utf_sprint_classname(logtext + strlen(logtext), c->name);
3739 if (!class_init(c->super))
3744 /* initialize interface classes */
3746 for (i = 0; i < c->interfacescount; i++) {
3747 if (!c->interfaces[i]->initialized) {
3749 char logtext[MAXLOGTEXT];
3750 sprintf(logtext, "Initialize interface class ");
3751 utf_sprint_classname(logtext + strlen(logtext), c->interfaces[i]->name);
3752 sprintf(logtext + strlen(logtext), " from ");
3753 utf_sprint_classname(logtext + strlen(logtext), c->name);
3757 if (!class_init(c->interfaces[i]))
3762 m = class_findmethod(c, utf_clinit, utf_fidesc);
3766 char logtext[MAXLOGTEXT];
3767 sprintf(logtext, "Class ");
3768 utf_sprint_classname(logtext + strlen(logtext), c->name);
3769 sprintf(logtext + strlen(logtext), " has no static class initializer");
3776 /* Sun's and IBM's JVM don't care about the static flag */
3777 /* if (!(m->flags & ACC_STATIC)) { */
3778 /* panic("Class initializer is not static!"); */
3781 log_message_class("Starting static class initializer for class: ", c);
3783 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3788 /* now call the initializer */
3789 asm_calljavafunction(m, NULL, NULL, NULL, NULL);
3791 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3792 assert(blockInts == 0);
3796 /* we have an exception or error */
3797 if (*exceptionptr) {
3798 /* class is NOT initialized */
3799 c->initialized = false;
3801 /* is this an exception, than wrap it */
3802 if (builtin_instanceof(*exceptionptr, class_java_lang_Exception)) {
3803 java_objectheader *xptr;
3804 java_objectheader *cause;
3807 cause = *exceptionptr;
3809 /* clear exception, because we are calling jit code again */
3810 *exceptionptr = NULL;
3812 /* wrap the exception */
3814 new_exception_throwable(string_java_lang_ExceptionInInitializerError,
3815 (java_lang_Throwable *) cause);
3817 /* XXX should we exit here? */
3821 /* set new exception */
3822 *exceptionptr = xptr;
3829 log_message_class("Finished static class initializer for class: ", c);
3835 /********* Function: find_class_method_constant *********/
3837 int find_class_method_constant (classinfo *c, utf * c1, utf* m1, utf* d1)
3842 for (i=0; i<c->cpcount; i++) {
3844 e = c -> cpinfos [i];
3847 switch (c -> cptags [i]) {
3848 case CONSTANT_Methodref:
3850 constant_FMIref *fmi = e;
3851 if ( (fmi->class->name == c1)
3852 && (fmi->name == m1)
3853 && (fmi->descriptor == d1)) {
3860 case CONSTANT_InterfaceMethodref:
3862 constant_FMIref *fmi = e;
3863 if ( (fmi->class->name == c1)
3864 && (fmi->name == m1)
3865 && (fmi->descriptor == d1)) {
3879 void class_showconstanti(classinfo *c, int ii)
3885 printf ("#%d: ", (int) i);
3887 switch (c->cptags [i]) {
3888 case CONSTANT_Class:
3889 printf("Classreference -> ");
3890 utf_display(((classinfo*)e)->name);
3893 case CONSTANT_Fieldref:
3894 printf("Fieldref -> "); goto displayFMIi;
3895 case CONSTANT_Methodref:
3896 printf("Methodref -> "); goto displayFMIi;
3897 case CONSTANT_InterfaceMethodref:
3898 printf("InterfaceMethod -> "); goto displayFMIi;
3901 constant_FMIref *fmi = e;
3902 utf_display(fmi->class->name);
3904 utf_display(fmi->name);
3906 utf_display(fmi->descriptor);
3910 case CONSTANT_String:
3911 printf("String -> ");
3914 case CONSTANT_Integer:
3915 printf("Integer -> %d", (int) (((constant_integer*)e)->value));
3917 case CONSTANT_Float:
3918 printf("Float -> %f", ((constant_float*)e)->value);
3920 case CONSTANT_Double:
3921 printf("Double -> %f", ((constant_double*)e)->value);
3925 u8 v = ((constant_long*)e)->value;
3927 printf("Long -> %ld", (long int) v);
3929 printf("Long -> HI: %ld, LO: %ld\n",
3930 (long int) v.high, (long int) v.low);
3934 case CONSTANT_NameAndType:
3936 constant_nameandtype *cnt = e;
3937 printf("NameAndType: ");
3938 utf_display(cnt->name);
3940 utf_display(cnt->descriptor);
3948 panic("Invalid type of ConstantPool-Entry");
3955 void class_showconstantpool (classinfo *c)
3960 printf ("---- dump of constant pool ----\n");
3962 for (i=0; i<c->cpcount; i++) {
3963 printf ("#%d: ", (int) i);
3965 e = c -> cpinfos [i];
3968 switch (c -> cptags [i]) {
3969 case CONSTANT_Class:
3970 printf ("Classreference -> ");
3971 utf_display ( ((classinfo*)e) -> name );
3974 case CONSTANT_Fieldref:
3975 printf ("Fieldref -> "); goto displayFMI;
3976 case CONSTANT_Methodref:
3977 printf ("Methodref -> "); goto displayFMI;
3978 case CONSTANT_InterfaceMethodref:
3979 printf ("InterfaceMethod -> "); goto displayFMI;
3982 constant_FMIref *fmi = e;
3983 utf_display ( fmi->class->name );
3985 utf_display ( fmi->name);
3987 utf_display ( fmi->descriptor );
3991 case CONSTANT_String:
3992 printf ("String -> ");
3995 case CONSTANT_Integer:
3996 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
3998 case CONSTANT_Float:
3999 printf ("Float -> %f", ((constant_float*)e) -> value);
4001 case CONSTANT_Double:
4002 printf ("Double -> %f", ((constant_double*)e) -> value);
4006 u8 v = ((constant_long*)e) -> value;
4008 printf ("Long -> %ld", (long int) v);
4010 printf ("Long -> HI: %ld, LO: %ld\n",
4011 (long int) v.high, (long int) v.low);
4015 case CONSTANT_NameAndType:
4017 constant_nameandtype *cnt = e;
4018 printf ("NameAndType: ");
4019 utf_display (cnt->name);
4021 utf_display (cnt->descriptor);
4025 printf ("Utf8 -> ");
4029 panic ("Invalid type of ConstantPool-Entry");
4039 /********** Function: class_showmethods (debugging only) *************/
4041 void class_showmethods (classinfo *c)
4045 printf ("--------- Fields and Methods ----------------\n");
4046 printf ("Flags: "); printflags (c->flags); printf ("\n");
4048 printf ("This: "); utf_display (c->name); printf ("\n");
4050 printf ("Super: "); utf_display (c->super->name); printf ("\n");
4052 printf ("Index: %d\n", c->index);
4054 printf ("interfaces:\n");
4055 for (i=0; i < c-> interfacescount; i++) {
4057 utf_display (c -> interfaces[i] -> name);
4058 printf (" (%d)\n", c->interfaces[i] -> index);
4061 printf ("fields:\n");
4062 for (i=0; i < c -> fieldscount; i++) {
4063 field_display (&(c -> fields[i]));
4066 printf ("methods:\n");
4067 for (i=0; i < c -> methodscount; i++) {
4068 methodinfo *m = &(c->methods[i]);
4069 if ( !(m->flags & ACC_STATIC))
4070 printf ("vftblindex: %d ", m->vftblindex);
4072 method_display ( m );
4076 printf ("Virtual function table:\n");
4077 for (i=0; i<c->vftbl->vftbllength; i++) {
4078 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]) );
4084 /******************************************************************************/
4085 /******************* General functions for the class loader *******************/
4086 /******************************************************************************/
4088 /**************** function: create_primitive_classes ***************************
4090 create classes representing primitive types
4092 *******************************************************************************/
4094 static bool create_primitive_classes()
4098 for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
4099 /* create primitive class */
4101 class_new_intern(utf_new_char(primitivetype_table[i].name));
4102 c->classUsed = NOTUSED; /* not used initially CO-RT */
4105 /* prevent loader from loading primitive class */
4110 primitivetype_table[i].class_primitive = c;
4112 /* create class for wrapping the primitive type */
4113 c = class_new_intern(utf_new_char(primitivetype_table[i].wrapname));
4114 primitivetype_table[i].class_wrap = c;
4115 primitivetype_table[i].class_wrap->classUsed = NOTUSED; /* not used initially CO-RT */
4116 primitivetype_table[i].class_wrap->impldBy = NULL;
4118 /* create the primitive array class */
4119 if (primitivetype_table[i].arrayname) {
4120 c = class_new_intern(utf_new_char(primitivetype_table[i].arrayname));
4121 primitivetype_table[i].arrayclass = c;
4126 primitivetype_table[i].arrayvftbl = c->vftbl;
4134 /**************** function: class_primitive_from_sig ***************************
4136 return the primitive class indicated by the given signature character
4138 If the descriptor does not indicate a valid primitive type the
4139 return value is NULL.
4141 ********************************************************************************/
4143 classinfo *class_primitive_from_sig(char sig)
4146 case 'I': return primitivetype_table[PRIMITIVETYPE_INT].class_primitive;
4147 case 'J': return primitivetype_table[PRIMITIVETYPE_LONG].class_primitive;
4148 case 'F': return primitivetype_table[PRIMITIVETYPE_FLOAT].class_primitive;
4149 case 'D': return primitivetype_table[PRIMITIVETYPE_DOUBLE].class_primitive;
4150 case 'B': return primitivetype_table[PRIMITIVETYPE_BYTE].class_primitive;
4151 case 'C': return primitivetype_table[PRIMITIVETYPE_CHAR].class_primitive;
4152 case 'S': return primitivetype_table[PRIMITIVETYPE_SHORT].class_primitive;
4153 case 'Z': return primitivetype_table[PRIMITIVETYPE_BOOLEAN].class_primitive;
4154 case 'V': return primitivetype_table[PRIMITIVETYPE_VOID].class_primitive;
4159 /****************** function: class_from_descriptor ****************************
4161 return the class indicated by the given descriptor
4163 utf_ptr....first character of descriptor
4164 end_ptr....first character after the end of the string
4165 next.......if non-NULL, *next is set to the first character after
4166 the descriptor. (Undefined if an error occurs.)
4168 mode.......a combination (binary or) of the following flags:
4170 (Flags marked with * are the default settings.)
4172 What to do if a reference type descriptor is parsed successfully:
4174 CLASSLOAD_SKIP...skip it and return something != NULL
4175 * CLASSLOAD_NEW....get classinfo * via class_new
4176 CLASSLOAD_LOAD...get classinfo * via loader_load
4178 How to handle primitive types:
4180 * CLASSLOAD_PRIMITIVE.......return primitive class (eg. "int")
4181 CLASSLOAD_NULLPRIMITIVE...return NULL for primitive types
4183 How to handle "V" descriptors:
4185 * CLASSLOAD_VOID.....handle it like other primitive types
4186 CLASSLOAD_NOVOID...treat it as an error
4188 How to deal with extra characters after the end of the
4191 * CLASSLOAD_NOCHECKEND...ignore (useful for parameter lists)
4192 CLASSLOAD_CHECKEND.....treat them as an error
4194 How to deal with errors:
4196 * CLASSLOAD_PANIC....abort execution with an error message
4197 CLASSLOAD_NOPANIC..return NULL on error
4199 *******************************************************************************/
4201 classinfo *class_from_descriptor(char *utf_ptr, char *end_ptr,
4202 char **next, int mode)
4204 char *start = utf_ptr;
4208 SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr, end_ptr, error);
4210 if (mode & CLASSLOAD_CHECKEND)
4211 error |= (utf_ptr != end_ptr);
4214 if (next) *next = utf_ptr;
4218 if (mode & CLASSLOAD_NOVOID)
4229 return (mode & CLASSLOAD_NULLPRIMITIVE)
4231 : class_primitive_from_sig(*start);
4238 if (mode & CLASSLOAD_SKIP) return class_java_lang_Object;
4239 name = utf_new(start, utf_ptr - start);
4243 tc = class_new_intern(name);
4245 list_addfirst(&unlinkedclasses, tc);
4250 return (mode & CLASSLOAD_LOAD)
4251 ? class_load(class_new(name)) : class_new(name); /* XXX handle errors */
4256 /* An error occurred */
4257 if (mode & CLASSLOAD_NOPANIC)
4260 log_plain("Invalid descriptor at beginning of '");
4261 log_plain_utf(utf_new(start, end_ptr - start));
4265 panic("Invalid descriptor");
4267 /* keep compiler happy */
4272 /******************* function: type_from_descriptor ****************************
4274 return the basic type indicated by the given descriptor
4276 This function parses a descriptor and returns its basic type as
4277 TYPE_INT, TYPE_LONG, TYPE_FLOAT, TYPE_DOUBLE, TYPE_ADDRESS or TYPE_VOID.
4279 cls...if non-NULL the referenced variable is set to the classinfo *
4280 returned by class_from_descriptor.
4282 For documentation of the arguments utf_ptr, end_ptr, next and mode
4283 see class_from_descriptor. The only difference is that
4284 type_from_descriptor always uses CLASSLOAD_PANIC.
4286 ********************************************************************************/
4288 int type_from_descriptor(classinfo **cls, char *utf_ptr, char *end_ptr,
4289 char **next, int mode)
4292 if (!cls) cls = &mycls;
4293 *cls = class_from_descriptor(utf_ptr, end_ptr, next, mode & (~CLASSLOAD_NOPANIC));
4310 return TYPE_ADDRESS;
4314 /*************** function: create_pseudo_classes *******************************
4316 create pseudo classes used by the typechecker
4318 ********************************************************************************/
4320 static void create_pseudo_classes()
4322 /* pseudo class for Arraystubs (extends java.lang.Object) */
4324 pseudo_class_Arraystub = class_new_intern(utf_new_char("$ARRAYSTUB$"));
4325 pseudo_class_Arraystub->loaded = true;
4326 pseudo_class_Arraystub->super = class_java_lang_Object;
4327 pseudo_class_Arraystub->interfacescount = 2;
4328 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
4329 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
4330 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
4332 class_link(pseudo_class_Arraystub);
4334 pseudo_class_Arraystub_vftbl = pseudo_class_Arraystub->vftbl;
4336 /* pseudo class representing the null type */
4338 pseudo_class_Null = class_new_intern(utf_new_char("$NULL$"));
4339 pseudo_class_Null->loaded = true;
4340 pseudo_class_Null->super = class_java_lang_Object;
4341 class_link(pseudo_class_Null);
4343 /* pseudo class representing new uninitialized objects */
4345 pseudo_class_New = class_new_intern(utf_new_char("$NEW$"));
4346 pseudo_class_New->loaded = true;
4347 pseudo_class_New->linked = true;
4348 pseudo_class_New->super = class_java_lang_Object;
4349 /* class_link(pseudo_class_New); */
4353 /********************** Function: loader_init **********************************
4355 Initializes all lists and loads all classes required for the system or the
4358 *******************************************************************************/
4360 void loader_init(u1 *stackbottom)
4364 /* create utf-symbols for pointer comparison of frequently used strings */
4365 utf_innerclasses = utf_new_char("InnerClasses");
4366 utf_constantvalue = utf_new_char("ConstantValue");
4367 utf_code = utf_new_char("Code");
4368 utf_exceptions = utf_new_char("Exceptions");
4369 utf_linenumbertable = utf_new_char("LineNumberTable");
4370 utf_sourcefile = utf_new_char("SourceFile");
4371 utf_finalize = utf_new_char("finalize");
4372 utf_fidesc = utf_new_char("()V");
4373 utf_init = utf_new_char("<init>");
4374 utf_clinit = utf_new_char("<clinit>");
4375 utf_initsystemclass = utf_new_char("initializeSystemClass");
4376 utf_systemclass = utf_new_char("java/lang/System");
4377 utf_vmclassloader = utf_new_char("java/lang/VMClassLoader");
4378 utf_initialize = utf_new_char("initialize");
4379 utf_initializedesc = utf_new_char("(I)V");
4380 utf_vmclass = utf_new_char("java/lang/VMClass");
4381 utf_java_lang_Object= utf_new_char("java/lang/Object");
4382 array_packagename = utf_new_char("<the array package>");
4383 utf_fillInStackTrace_name = utf_new_char("fillInStackTrace");
4384 utf_fillInStackTrace_desc = utf_new_char("()Ljava/lang/Throwable;");
4386 /* create some important classes */
4387 /* These classes have to be created now because the classinfo
4388 * pointers are used in the loading code.
4390 class_java_lang_Object = class_new_intern(utf_java_lang_Object);
4391 class_load(class_java_lang_Object);
4392 class_link(class_java_lang_Object);
4394 class_java_lang_String = class_new(utf_new_char("java/lang/String"));
4395 class_load(class_java_lang_String);
4396 class_link(class_java_lang_String);
4398 class_java_lang_Cloneable = class_new(utf_new_char("java/lang/Cloneable"));
4399 class_load(class_java_lang_Cloneable);
4400 class_link(class_java_lang_Cloneable);
4402 class_java_io_Serializable =
4403 class_new(utf_new_char("java/io/Serializable"));
4404 class_load(class_java_io_Serializable);
4405 class_link(class_java_io_Serializable);
4407 /* create classes representing primitive types */
4408 create_primitive_classes();
4410 /* create classes used by the typechecker */
4411 create_pseudo_classes();
4413 /* correct vftbl-entries (retarded loading of class java/lang/String) */
4414 stringtable_update();
4416 #if defined(USE_THREADS)
4417 if (stackbottom != 0)
4423 /* loader_compute_subclasses ***************************************************
4427 *******************************************************************************/
4429 static void loader_compute_class_values(classinfo *c);
4431 void loader_compute_subclasses(classinfo *c)
4433 #if defined(USE_THREADS)
4434 #if defined(NATIVE_THREADS)
4441 if (!(c->flags & ACC_INTERFACE)) {
4446 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
4447 c->nextsub = c->super->sub;
4453 /* this is the java.lang.Object special case */
4455 if (!class_java_lang_Object) {
4456 loader_compute_class_values(c);
4459 loader_compute_class_values(class_java_lang_Object);
4462 #if defined(USE_THREADS)
4463 #if defined(NATIVE_THREADS)
4472 /* loader_compute_class_values *************************************************
4476 *******************************************************************************/
4478 static void loader_compute_class_values(classinfo *c)
4482 c->vftbl->baseval = ++classvalue;
4486 loader_compute_class_values(subs);
4487 subs = subs->nextsub;
4490 c->vftbl->diffval = classvalue - c->vftbl->baseval;
4494 /******************** Function: loader_close ***********************************
4498 *******************************************************************************/
4505 for (slot = 0; slot < class_hash.size; slot++) {
4506 c = class_hash.ptr[slot];
4517 * These are local overrides for various environment variables in Emacs.
4518 * Please do not remove this and leave it at the end of the file, where
4519 * Emacs will automagically detect them.
4520 * ---------------------------------------------------------------------
4523 * indent-tabs-mode: t