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 1494 2004-11-12 13:34:26Z 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((char *) (cb->pos + 1),
1904 (char *) (cb->pos + 1 + length))) {
1905 dolog("Invalid UTF-8 string (constant pool index %d)",idx);
1906 panic("Invalid UTF-8 string");
1908 /* insert utf-string into the utf-symboltable */
1909 cpinfos[idx] = utf_new_intern((char *) (cb->pos + 1), length);
1911 /* skip bytes of the string (buffer size check above) */
1912 skip_nbytes(cb, length);
1919 new_classformaterror(c, "Illegal constant pool type");
1925 /* resolve entries in temporary structures */
1927 while (forward_classes) {
1929 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
1931 if (opt_verify && !is_valid_name_utf(name))
1932 panic("Class reference with invalid name");
1934 cptags[forward_classes->thisindex] = CONSTANT_Class;
1935 /* retrieve class from class-table */
1938 tc = class_new_intern(name);
1940 if (!class_load(tc))
1943 /* link the class later, because we cannot link the class currently
1945 list_addfirst(&unlinkedclasses, tc);
1947 cpinfos[forward_classes->thisindex] = tc;
1950 cpinfos[forward_classes->thisindex] = class_new(name);
1953 nfc = forward_classes;
1954 forward_classes = forward_classes->next;
1955 FREE(nfc, forward_class);
1958 while (forward_strings) {
1960 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
1962 /* resolve utf-string */
1963 cptags[forward_strings->thisindex] = CONSTANT_String;
1964 cpinfos[forward_strings->thisindex] = text;
1966 nfs = forward_strings;
1967 forward_strings = forward_strings->next;
1968 FREE(nfs, forward_string);
1971 while (forward_nameandtypes) {
1972 constant_nameandtype *cn = NEW(constant_nameandtype);
1974 #if defined(STATISTICS)
1976 count_const_pool_len += sizeof(constant_nameandtype);
1979 /* resolve simple name and descriptor */
1980 cn->name = class_getconstant(c,
1981 forward_nameandtypes->name_index,
1984 cn->descriptor = class_getconstant(c,
1985 forward_nameandtypes->sig_index,
1990 if (!is_valid_name_utf(cn->name))
1991 panic("NameAndType with invalid name");
1992 /* disallow referencing <clinit> among others */
1993 if (cn->name->text[0] == '<' && cn->name != utf_init)
1994 panic("NameAndType with invalid special name");
1997 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
1998 cpinfos[forward_nameandtypes->thisindex] = cn;
2000 nfn = forward_nameandtypes;
2001 forward_nameandtypes = forward_nameandtypes->next;
2002 FREE(nfn, forward_nameandtype);
2005 while (forward_fieldmethints) {
2006 constant_nameandtype *nat;
2007 constant_FMIref *fmi = NEW(constant_FMIref);
2009 #if defined(STATISTICS)
2011 count_const_pool_len += sizeof(constant_FMIref);
2013 /* resolve simple name and descriptor */
2014 nat = class_getconstant(c,
2015 forward_fieldmethints->nameandtype_index,
2016 CONSTANT_NameAndType);
2018 fmi->class = class_getconstant(c,
2019 forward_fieldmethints->class_index,
2021 fmi->name = nat->name;
2022 fmi->descriptor = nat->descriptor;
2024 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
2025 cpinfos[forward_fieldmethints->thisindex] = fmi;
2027 switch (forward_fieldmethints->tag) {
2028 case CONSTANT_Fieldref: /* check validity of descriptor */
2029 checkfielddescriptor(fmi->descriptor->text,
2030 utf_end(fmi->descriptor));
2032 case CONSTANT_InterfaceMethodref:
2033 case CONSTANT_Methodref: /* check validity of descriptor */
2034 checkmethoddescriptor(c, fmi->descriptor);
2038 nff = forward_fieldmethints;
2039 forward_fieldmethints = forward_fieldmethints->next;
2040 FREE(nff, forward_fieldmethint);
2043 /* everything was ok */
2049 /********************** Function: class_load ***********************************
2051 Loads everything interesting about a class from the class file. The
2052 'classinfo' structure must have been allocated previously.
2054 The super class and the interfaces implemented by this class need not be
2055 loaded. The link is set later by the function 'class_link'.
2057 The loaded class is removed from the list 'unloadedclasses' and added to
2058 the list 'unlinkedclasses'.
2060 *******************************************************************************/
2062 classinfo *class_load_intern(classbuffer *cb);
2064 classinfo *class_load(classinfo *c)
2069 /* enter a monitor on the class */
2071 builtin_monitorenter((java_objectheader *) c);
2073 /* maybe the class is already loaded */
2075 builtin_monitorexit((java_objectheader *) c);
2082 if (getcompilingtime)
2083 compilingtime_stop();
2086 loadingtime_start();
2088 /* load classdata, throw exception on error */
2090 if ((cb = suck_start(c)) == NULL) {
2091 /* this means, the classpath was not set properly */
2092 if (c->name == utf_java_lang_Object)
2093 throw_cacao_exception_exit(string_java_lang_NoClassDefFoundError,
2094 "java/lang/Object");
2097 new_exception_utfmessage(string_java_lang_NoClassDefFoundError,
2100 builtin_monitorexit((java_objectheader *) c);
2105 /* call the internal function */
2106 r = class_load_intern(cb);
2108 /* if return value is NULL, we had a problem and the class is not loaded */
2112 /* now free the allocated memory, otherwise we could ran into a DOS */
2124 if (getcompilingtime)
2125 compilingtime_start();
2127 /* leave the monitor */
2129 builtin_monitorexit((java_objectheader *) c);
2135 classinfo *class_load_intern(classbuffer *cb)
2141 char msg[MAXLOGTEXT]; /* maybe we get an exception */
2143 /* get the classbuffer's class */
2146 /* maybe the class is already loaded */
2150 #if defined(STATISTICS)
2152 count_class_loads++;
2155 /* output for debugging purposes */
2157 log_message_class("Loading class: ", c);
2159 /* class is somewhat loaded */
2162 if (!check_classbuffer_size(cb, 4 + 2 + 2))
2165 /* check signature */
2166 if (suck_u4(cb) != MAGIC) {
2167 *exceptionptr = new_classformaterror(c, "Bad magic number");
2176 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
2178 new_unsupportedclassversionerror(c,
2179 "Unsupported major.minor version %d.%d",
2185 /* load the constant pool */
2186 if (!class_loadcpool(cb, c))
2190 c->erroneous_state = 0;
2191 c->initializing_thread = 0;
2193 c->classUsed = NOTUSED; /* not used initially CO-RT */
2197 if (!check_classbuffer_size(cb, 2))
2200 c->flags = suck_u2(cb);
2201 /*if (!(c->flags & ACC_PUBLIC)) { log_text("CLASS NOT PUBLIC"); } JOWENN*/
2203 /* check ACC flags consistency */
2204 if (c->flags & ACC_INTERFACE) {
2205 if (!(c->flags & ACC_ABSTRACT)) {
2206 /* We work around this because interfaces in JDK 1.1 are
2207 * not declared abstract. */
2209 c->flags |= ACC_ABSTRACT;
2210 /* panic("Interface class not declared abstract"); */
2213 if (c->flags & ACC_FINAL) {
2215 new_classformaterror(c,
2216 "Illegal class modifiers: 0x%X", c->flags);
2221 if (c->flags & ACC_SUPER) {
2222 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
2226 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
2228 new_classformaterror(c, "Illegal class modifiers: 0x%X", c->flags);
2233 if (!check_classbuffer_size(cb, 2 + 2))
2238 if (!(tc = class_getconstant(c, i, CONSTANT_Class)))
2242 utf_sprint(msg, c->name);
2243 sprintf(msg + strlen(msg), " (wrong name: ");
2244 utf_sprint(msg + strlen(msg), tc->name);
2245 sprintf(msg + strlen(msg), ")");
2248 new_exception_message(string_java_lang_NoClassDefFoundError, msg);
2253 /* retrieve superclass */
2254 if ((i = suck_u2(cb))) {
2255 if (!(c->super = class_getconstant(c, i, CONSTANT_Class)))
2258 /* java.lang.Object may not have a super class. */
2259 if (c->name == utf_java_lang_Object) {
2261 new_exception_message(string_java_lang_ClassFormatError,
2262 "java.lang.Object with superclass");
2267 /* Interfaces must have java.lang.Object as super class. */
2268 if ((c->flags & ACC_INTERFACE) &&
2269 c->super->name != utf_java_lang_Object) {
2271 new_exception_message(string_java_lang_ClassFormatError,
2272 "Interfaces must have java.lang.Object as superclass");
2280 /* This is only allowed for java.lang.Object. */
2281 if (c->name != utf_java_lang_Object) {
2282 *exceptionptr = new_classformaterror(c, "Bad superclass index");
2288 /* retrieve interfaces */
2289 if (!check_classbuffer_size(cb, 2))
2292 c->interfacescount = suck_u2(cb);
2294 if (!check_classbuffer_size(cb, 2 * c->interfacescount))
2297 c->interfaces = MNEW(classinfo*, c->interfacescount);
2298 for (i = 0; i < c->interfacescount; i++) {
2299 if (!(c->interfaces[i] = class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2304 if (!check_classbuffer_size(cb, 2))
2307 c->fieldscount = suck_u2(cb);
2308 c->fields = GCNEW(fieldinfo, c->fieldscount);
2309 /* c->fields = MNEW(fieldinfo, c->fieldscount); */
2310 for (i = 0; i < c->fieldscount; i++) {
2311 if (!field_load(cb, c, &(c->fields[i])))
2316 if (!check_classbuffer_size(cb, 2))
2319 c->methodscount = suck_u2(cb);
2320 c->methods = GCNEW(methodinfo, c->methodscount);
2321 /* c->methods = MNEW(methodinfo, c->methodscount); */
2322 for (i = 0; i < c->methodscount; i++) {
2323 if (!method_load(cb, c, &(c->methods[i])))
2327 /* Check if all fields and methods can be uniquely
2328 * identified by (name,descriptor). */
2330 /* We use a hash table here to avoid making the
2331 * average case quadratic in # of methods, fields.
2333 static int shift = 0;
2335 u2 *next; /* for chaining colliding hash entries */
2341 /* Allocate hashtable */
2342 len = c->methodscount;
2343 if (len < c->fieldscount) len = c->fieldscount;
2345 hashtab = MNEW(u2,(hashlen + len));
2346 next = hashtab + hashlen;
2348 /* Determine bitshift (to get good hash values) */
2358 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2360 for (i = 0; i < c->fieldscount; ++i) {
2361 fieldinfo *fi = c->fields + i;
2363 /* It's ok if we lose bits here */
2364 index = ((((size_t) fi->name) +
2365 ((size_t) fi->descriptor)) >> shift) % hashlen;
2367 if ((old = hashtab[index])) {
2371 if (c->fields[old].name == fi->name &&
2372 c->fields[old].descriptor == fi->descriptor) {
2374 new_classformaterror(c,
2375 "Repetitive field name/signature");
2379 } while ((old = next[old]));
2381 hashtab[index] = i + 1;
2385 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2387 for (i = 0; i < c->methodscount; ++i) {
2388 methodinfo *mi = c->methods + i;
2390 /* It's ok if we lose bits here */
2391 index = ((((size_t) mi->name) +
2392 ((size_t) mi->descriptor)) >> shift) % hashlen;
2396 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2397 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2401 if ((old = hashtab[index])) {
2405 if (c->methods[old].name == mi->name &&
2406 c->methods[old].descriptor == mi->descriptor) {
2408 new_classformaterror(c,
2409 "Repetitive method name/signature");
2413 } while ((old = next[old]));
2415 hashtab[index] = i + 1;
2418 MFREE(hashtab, u2, (hashlen + len));
2421 #if defined(STATISTICS)
2423 count_class_infos += sizeof(classinfo*) * c->interfacescount;
2424 count_class_infos += sizeof(fieldinfo) * c->fieldscount;
2425 count_class_infos += sizeof(methodinfo) * c->methodscount;
2429 /* load attribute structures */
2430 if (!check_classbuffer_size(cb, 2))
2433 if (!attribute_load(cb, c, suck_u2(cb)))
2437 /* Pre java 1.5 version don't check this. This implementation is like
2438 java 1.5 do it: for class file version 45.3 we don't check it, older
2439 versions are checked.
2441 if ((ma == 45 && mi > 3) || ma > 45) {
2442 /* check if all data has been read */
2443 s4 classdata_left = ((cb->data + cb->size) - cb->pos - 1);
2445 if (classdata_left > 0) {
2447 new_classformaterror(c, "Extra bytes at the end of class file");
2454 log_message_class("Loading done class: ", c);
2461 /************** internal Function: class_highestinterface **********************
2463 Used by the function class_link to determine the amount of memory needed
2464 for the interface table.
2466 *******************************************************************************/
2468 static s4 class_highestinterface(classinfo *c)
2473 /* check for ACC_INTERFACE bit already done in class_link_intern */
2476 for (i = 0; i < c->interfacescount; i++) {
2477 s4 h2 = class_highestinterface(c->interfaces[i]);
2485 /* class_addinterface **********************************************************
2487 Is needed by class_link for adding a VTBL to a class. All interfaces
2488 implemented by ic are added as well.
2490 *******************************************************************************/
2492 static void class_addinterface(classinfo *c, classinfo *ic)
2496 vftbl_t *v = c->vftbl;
2498 if (i >= v->interfacetablelength)
2499 panic ("Inernal error: interfacetable overflow");
2501 if (v->interfacetable[-i])
2504 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
2505 v->interfacevftbllength[i] = 1;
2506 v->interfacetable[-i] = MNEW(methodptr, 1);
2507 v->interfacetable[-i][0] = NULL;
2510 v->interfacevftbllength[i] = ic->methodscount;
2511 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
2513 #if defined(STATISTICS)
2515 count_vftbl_len += sizeof(methodptr) *
2516 (ic->methodscount + (ic->methodscount == 0));
2519 for (j = 0; j < ic->methodscount; j++) {
2522 for (m = 0; m < sc->methodscount; m++) {
2523 methodinfo *mi = &(sc->methods[m]);
2524 if (method_canoverwrite(mi, &(ic->methods[j]))) {
2525 v->interfacetable[-i][j] = v->table[mi->vftblindex];
2536 for (j = 0; j < ic->interfacescount; j++)
2537 class_addinterface(c, ic->interfaces[j]);
2541 /******************* Function: class_new_array *********************************
2543 This function is called by class_new to setup an array class.
2545 *******************************************************************************/
2547 void class_new_array(classinfo *c)
2549 classinfo *comp = NULL;
2553 /* Check array class name */
2554 namelen = c->name->blength;
2555 if (namelen < 2 || c->name->text[0] != '[')
2556 panic("Invalid array class name");
2558 /* Check the component type */
2559 switch (c->name->text[1]) {
2561 /* c is an array of arrays. We have to create the component class. */
2563 comp = class_new_intern(utf_new_intern(c->name->text + 1,
2566 list_addfirst(&unlinkedclasses, comp);
2569 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2574 /* c is an array of objects. */
2575 if (namelen < 4 || c->name->text[namelen - 1] != ';')
2576 panic("Invalid array class name");
2579 comp = class_new_intern(utf_new_intern(c->name->text + 2,
2582 list_addfirst(&unlinkedclasses, comp);
2585 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2590 /* Setup the array class */
2591 c->super = class_java_lang_Object;
2592 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2594 c->interfacescount = 2;
2595 c->interfaces = MNEW(classinfo*, 2);
2600 tc = class_new_intern(utf_new_char("java/lang/Cloneable"));
2602 list_addfirst(&unlinkedclasses, tc);
2603 c->interfaces[0] = tc;
2605 tc = class_new_intern(utf_new_char("java/io/Serializable"));
2607 list_addfirst(&unlinkedclasses, tc);
2608 c->interfaces[1] = tc;
2611 c->interfaces[0] = class_new(utf_new_char("java/lang/Cloneable"));
2612 c->interfaces[1] = class_new(utf_new_char("java/io/Serializable"));
2615 c->methodscount = 1;
2616 c->methods = MNEW(methodinfo, c->methodscount);
2619 memset(clone, 0, sizeof(methodinfo));
2620 clone->flags = ACC_PUBLIC;
2621 clone->name = utf_new_char("clone");
2622 clone->descriptor = utf_new_char("()Ljava/lang/Object;");
2624 clone->stubroutine = createnativestub((functionptr) &builtin_clone_array, clone);
2625 clone->monoPoly = MONO;
2627 /* XXX: field: length? */
2629 /* array classes are not loaded from class files */
2634 /****************** Function: class_link_array *********************************
2636 This function is called by class_link to create the
2637 arraydescriptor for an array class.
2639 This function returns NULL if the array cannot be linked because
2640 the component type has not been linked yet.
2642 *******************************************************************************/
2644 static arraydescriptor *class_link_array(classinfo *c)
2646 classinfo *comp = NULL;
2647 s4 namelen = c->name->blength;
2648 arraydescriptor *desc;
2651 /* Check the component type */
2652 switch (c->name->text[1]) {
2654 /* c is an array of arrays. */
2655 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2657 panic("Could not find component array class.");
2661 /* c is an array of objects. */
2662 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2664 panic("Could not find component class.");
2668 /* If the component type has not been linked, link it now */
2669 if (comp && !comp->linked) {
2671 if (!class_load(comp))
2674 if (!class_link(comp))
2678 /* Allocate the arraydescriptor */
2679 desc = NEW(arraydescriptor);
2682 /* c is an array of references */
2683 desc->arraytype = ARRAYTYPE_OBJECT;
2684 desc->componentsize = sizeof(void*);
2685 desc->dataoffset = OFFSET(java_objectarray, data);
2687 compvftbl = comp->vftbl;
2689 panic("Component class has no vftbl");
2690 desc->componentvftbl = compvftbl;
2692 if (compvftbl->arraydesc) {
2693 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
2694 if (compvftbl->arraydesc->dimension >= 255)
2695 panic("Creating array of dimension >255");
2696 desc->dimension = compvftbl->arraydesc->dimension + 1;
2697 desc->elementtype = compvftbl->arraydesc->elementtype;
2700 desc->elementvftbl = compvftbl;
2701 desc->dimension = 1;
2702 desc->elementtype = ARRAYTYPE_OBJECT;
2706 /* c is an array of a primitive type */
2707 switch (c->name->text[1]) {
2709 desc->arraytype = ARRAYTYPE_BOOLEAN;
2710 desc->dataoffset = OFFSET(java_booleanarray,data);
2711 desc->componentsize = sizeof(u1);
2715 desc->arraytype = ARRAYTYPE_BYTE;
2716 desc->dataoffset = OFFSET(java_bytearray,data);
2717 desc->componentsize = sizeof(u1);
2721 desc->arraytype = ARRAYTYPE_CHAR;
2722 desc->dataoffset = OFFSET(java_chararray,data);
2723 desc->componentsize = sizeof(u2);
2727 desc->arraytype = ARRAYTYPE_DOUBLE;
2728 desc->dataoffset = OFFSET(java_doublearray,data);
2729 desc->componentsize = sizeof(double);
2733 desc->arraytype = ARRAYTYPE_FLOAT;
2734 desc->dataoffset = OFFSET(java_floatarray,data);
2735 desc->componentsize = sizeof(float);
2739 desc->arraytype = ARRAYTYPE_INT;
2740 desc->dataoffset = OFFSET(java_intarray,data);
2741 desc->componentsize = sizeof(s4);
2745 desc->arraytype = ARRAYTYPE_LONG;
2746 desc->dataoffset = OFFSET(java_longarray,data);
2747 desc->componentsize = sizeof(s8);
2751 desc->arraytype = ARRAYTYPE_SHORT;
2752 desc->dataoffset = OFFSET(java_shortarray,data);
2753 desc->componentsize = sizeof(s2);
2757 panic("Invalid array class name");
2760 desc->componentvftbl = NULL;
2761 desc->elementvftbl = NULL;
2762 desc->dimension = 1;
2763 desc->elementtype = desc->arraytype;
2770 /********************** Function: class_link ***********************************
2772 Tries to link a class. The function calculates the length in bytes that
2773 an instance of this class requires as well as the VTBL for methods and
2776 *******************************************************************************/
2778 static classinfo *class_link_intern(classinfo *c);
2780 classinfo *class_link(classinfo *c)
2784 /* enter a monitor on the class */
2786 builtin_monitorenter((java_objectheader *) c);
2788 /* maybe the class is already linked */
2790 builtin_monitorexit((java_objectheader *) c);
2797 if (getcompilingtime)
2798 compilingtime_stop();
2801 loadingtime_start();
2803 /* call the internal function */
2804 r = class_link_intern(c);
2806 /* if return value is NULL, we had a problem and the class is not linked */
2815 if (getcompilingtime)
2816 compilingtime_start();
2818 /* leave the monitor */
2820 builtin_monitorexit((java_objectheader *) c);
2826 static classinfo *class_link_intern(classinfo *c)
2828 s4 supervftbllength; /* vftbllegnth of super class */
2829 s4 vftbllength; /* vftbllength of current class */
2830 s4 interfacetablelength; /* interface table length */
2831 classinfo *super; /* super class */
2832 classinfo *tc; /* temporary class variable */
2833 vftbl_t *v; /* vftbl of current class */
2834 s4 i; /* interface/method/field counter */
2835 arraydescriptor *arraydesc; /* descriptor for array classes */
2837 /* maybe the class is already linked */
2841 /* maybe the class is not loaded */
2847 log_message_class("Linking class: ", c);
2849 /* ok, this class is somewhat linked */
2854 /* check interfaces */
2856 for (i = 0; i < c->interfacescount; i++) {
2857 tc = c->interfaces[i];
2859 /* detect circularity */
2862 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2868 if (!class_load(tc))
2871 if (!(tc->flags & ACC_INTERFACE)) {
2873 new_exception_message(string_java_lang_IncompatibleClassChangeError,
2874 "Implementing class");
2879 if (!class_link(tc))
2883 /* check super class */
2887 if (super == NULL) { /* class java.lang.Object */
2889 c->classUsed = USED; /* Object class is always used CO-RT*/
2891 c->instancesize = sizeof(java_objectheader);
2893 vftbllength = supervftbllength = 0;
2895 c->finalizer = NULL;
2898 /* detect circularity */
2901 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2907 if (!class_load(super))
2910 if (super->flags & ACC_INTERFACE) {
2911 /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
2912 panic("Interface specified as super class");
2915 /* Don't allow extending final classes */
2916 if (super->flags & ACC_FINAL) {
2918 new_exception_message(string_java_lang_VerifyError,
2919 "Cannot inherit from final class");
2924 if (!class_link(super))
2927 /* handle array classes */
2928 if (c->name->text[0] == '[')
2929 if (!(arraydesc = class_link_array(c)))
2932 if (c->flags & ACC_INTERFACE)
2933 c->index = interfaceindex++;
2935 c->index = super->index + 1;
2937 c->instancesize = super->instancesize;
2939 vftbllength = supervftbllength = super->vftbl->vftbllength;
2941 c->finalizer = super->finalizer;
2944 /* compute vftbl length */
2946 for (i = 0; i < c->methodscount; i++) {
2947 methodinfo *m = &(c->methods[i]);
2949 if (!(m->flags & ACC_STATIC)) { /* is instance method */
2954 for (j = 0; j < tc->methodscount; j++) {
2955 if (method_canoverwrite(m, &(tc->methods[j]))) {
2956 if (tc->methods[j].flags & ACC_PRIVATE)
2957 goto notfoundvftblindex;
2959 if (tc->methods[j].flags & ACC_FINAL) {
2960 /* class a overrides final method . */
2962 new_exception(string_java_lang_VerifyError);
2965 m->vftblindex = tc->methods[j].vftblindex;
2966 goto foundvftblindex;
2972 m->vftblindex = (vftbllength++);
2978 #if defined(STATISTICS)
2981 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
2984 /* compute interfacetable length */
2986 interfacetablelength = 0;
2989 for (i = 0; i < tc->interfacescount; i++) {
2990 s4 h = class_highestinterface(tc->interfaces[i]) + 1;
2991 if (h > interfacetablelength)
2992 interfacetablelength = h;
2997 /* allocate virtual function table */
2999 v = (vftbl_t*) mem_alloc(sizeof(vftbl_t) + sizeof(methodptr) *
3000 (vftbllength - 1) + sizeof(methodptr*) *
3001 (interfacetablelength - (interfacetablelength > 0)));
3002 v = (vftbl_t*) (((methodptr*) v) + (interfacetablelength - 1) *
3003 (interfacetablelength > 1));
3004 c->header.vftbl = c->vftbl = v;
3006 v->vftbllength = vftbllength;
3007 v->interfacetablelength = interfacetablelength;
3008 v->arraydesc = arraydesc;
3010 /* store interface index in vftbl */
3011 if (c->flags & ACC_INTERFACE)
3012 v->baseval = -(c->index);
3014 /* copy virtual function table of super class */
3016 for (i = 0; i < supervftbllength; i++)
3017 v->table[i] = super->vftbl->table[i];
3019 /* add method stubs into virtual function table */
3021 for (i = 0; i < c->methodscount; i++) {
3022 methodinfo *m = &(c->methods[i]);
3023 if (!(m->flags & ACC_STATIC)) {
3024 v->table[m->vftblindex] = m->stubroutine;
3028 /* compute instance size and offset of each field */
3030 for (i = 0; i < c->fieldscount; i++) {
3032 fieldinfo *f = &(c->fields[i]);
3034 if (!(f->flags & ACC_STATIC)) {
3035 dsize = desc_typesize(f->descriptor);
3036 c->instancesize = ALIGN(c->instancesize, dsize);
3037 f->offset = c->instancesize;
3038 c->instancesize += dsize;
3042 /* initialize interfacetable and interfacevftbllength */
3044 v->interfacevftbllength = MNEW(s4, interfacetablelength);
3046 #if defined(STATISTICS)
3048 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
3051 for (i = 0; i < interfacetablelength; i++) {
3052 v->interfacevftbllength[i] = 0;
3053 v->interfacetable[-i] = NULL;
3056 /* add interfaces */
3058 for (tc = c; tc != NULL; tc = tc->super) {
3059 for (i = 0; i < tc->interfacescount; i++) {
3060 class_addinterface(c, tc->interfaces[i]);
3064 /* add finalizer method (not for java.lang.Object) */
3069 fi = class_findmethod(c, utf_finalize, utf_fidesc);
3072 if (!(fi->flags & ACC_STATIC)) {
3080 loader_compute_subclasses(c);
3083 log_message_class("Linking done class: ", c);
3085 /* just return c to show that we didn't had a problem */
3091 /******************* Function: class_freepool **********************************
3093 Frees all resources used by this classes Constant Pool.
3095 *******************************************************************************/
3097 static void class_freecpool(classinfo *c)
3103 if (c->cptags && c->cpinfos) {
3104 for (idx = 0; idx < c->cpcount; idx++) {
3105 tag = c->cptags[idx];
3106 info = c->cpinfos[idx];
3110 case CONSTANT_Fieldref:
3111 case CONSTANT_Methodref:
3112 case CONSTANT_InterfaceMethodref:
3113 FREE(info, constant_FMIref);
3115 case CONSTANT_Integer:
3116 FREE(info, constant_integer);
3118 case CONSTANT_Float:
3119 FREE(info, constant_float);
3122 FREE(info, constant_long);
3124 case CONSTANT_Double:
3125 FREE(info, constant_double);
3127 case CONSTANT_NameAndType:
3128 FREE(info, constant_nameandtype);
3136 MFREE(c->cptags, u1, c->cpcount);
3139 MFREE(c->cpinfos, voidptr, c->cpcount);
3143 /*********************** Function: class_free **********************************
3145 Frees all resources used by the class.
3147 *******************************************************************************/
3149 void class_free(classinfo *c)
3157 MFREE(c->interfaces, classinfo*, c->interfacescount);
3160 for (i = 0; i < c->fieldscount; i++)
3161 field_free(&(c->fields[i]));
3162 /* MFREE(c->fields, fieldinfo, c->fieldscount); */
3166 for (i = 0; i < c->methodscount; i++)
3167 method_free(&(c->methods[i]));
3168 /* MFREE(c->methods, methodinfo, c->methodscount); */
3171 if ((v = c->vftbl) != NULL) {
3173 mem_free(v->arraydesc,sizeof(arraydescriptor));
3175 for (i = 0; i < v->interfacetablelength; i++) {
3176 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
3178 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
3180 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
3181 sizeof(methodptr*) * (v->interfacetablelength -
3182 (v->interfacetablelength > 0));
3183 v = (vftbl_t*) (((methodptr*) v) - (v->interfacetablelength - 1) *
3184 (v->interfacetablelength > 1));
3189 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
3191 /* if (c->classvftbl)
3192 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
3198 /************************* Function: class_findfield ***************************
3200 Searches a 'classinfo' structure for a field having the given name and
3203 *******************************************************************************/
3205 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
3209 for (i = 0; i < c->fieldscount; i++) {
3210 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
3211 return &(c->fields[i]);
3214 panic("Can not find field given in CONSTANT_Fieldref");
3216 /* keep compiler happy */
3221 /****************** Function: class_resolvefield_int ***************************
3223 This is an internally used helper function. Do not use this directly.
3225 Tries to resolve a field having the given name and type.
3226 If the field cannot be resolved, NULL is returned.
3228 *******************************************************************************/
3230 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
3235 /* search for field in class c */
3236 for (i = 0; i < c->fieldscount; i++) {
3237 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
3238 return &(c->fields[i]);
3242 /* try superinterfaces recursively */
3243 for (i = 0; i < c->interfacescount; ++i) {
3244 fi = class_resolvefield_int(c->interfaces[i], name, desc);
3249 /* try superclass */
3251 return class_resolvefield_int(c->super, name, desc);
3258 /********************* Function: class_resolvefield ***************************
3260 Resolves a reference from REFERER to a field with NAME and DESC in class C.
3262 If the field cannot be resolved the return value is NULL. If EXCEPT is
3263 true *exceptionptr is set, too.
3265 *******************************************************************************/
3267 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
3268 classinfo *referer, bool except)
3272 /* XXX resolve class c */
3273 /* XXX check access from REFERER to C */
3275 fi = class_resolvefield_int(c, name, desc);
3280 new_exception_utfmessage(string_java_lang_NoSuchFieldError,
3286 /* XXX check access rights */
3292 /************************* Function: class_findmethod **************************
3294 Searches a 'classinfo' structure for a method having the given name and
3295 type and returns the index in the class info structure.
3296 If type is NULL, it is ignored.
3298 *******************************************************************************/
3300 s4 class_findmethodIndex(classinfo *c, utf *name, utf *desc)
3304 for (i = 0; i < c->methodscount; i++) {
3306 /* utf_display_classname(c->name);printf("."); */
3307 /* utf_display(c->methods[i].name);printf("."); */
3308 /* utf_display(c->methods[i].descriptor); */
3311 if ((c->methods[i].name == name) && ((desc == NULL) ||
3312 (c->methods[i].descriptor == desc))) {
3321 /************************* Function: class_findmethod **************************
3323 Searches a 'classinfo' structure for a method having the given name and
3325 If type is NULL, it is ignored.
3327 *******************************************************************************/
3329 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
3331 s4 idx = class_findmethodIndex(c, name, desc);
3336 return &(c->methods[idx]);
3340 /*********************** Function: class_fetchmethod **************************
3342 like class_findmethod, but aborts with an error if the method is not found
3344 *******************************************************************************/
3346 methodinfo *class_fetchmethod(classinfo *c, utf *name, utf *desc)
3350 mi = class_findmethod(c, name, desc);
3353 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3354 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3355 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3356 panic("Method not found");
3363 /*********************** Function: class_findmethod_w**************************
3365 like class_findmethod, but logs a warning if the method is not found
3367 *******************************************************************************/
3369 methodinfo *class_findmethod_w(classinfo *c, utf *name, utf *desc, char *from)
3372 mi = class_findmethod(c, name, desc);
3375 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3376 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3377 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3379 if ( c->flags & ACC_PUBLIC ) log_plain(" PUBLIC ");
3380 if ( c->flags & ACC_PRIVATE ) log_plain(" PRIVATE ");
3381 if ( c->flags & ACC_PROTECTED ) log_plain(" PROTECTED ");
3382 if ( c->flags & ACC_STATIC ) log_plain(" STATIC ");
3383 if ( c->flags & ACC_FINAL ) log_plain(" FINAL ");
3384 if ( c->flags & ACC_SYNCHRONIZED ) log_plain(" SYNCHRONIZED ");
3385 if ( c->flags & ACC_VOLATILE ) log_plain(" VOLATILE ");
3386 if ( c->flags & ACC_TRANSIENT ) log_plain(" TRANSIENT ");
3387 if ( c->flags & ACC_NATIVE ) log_plain(" NATIVE ");
3388 if ( c->flags & ACC_INTERFACE ) log_plain(" INTERFACE ");
3389 if ( c->flags & ACC_ABSTRACT ) log_plain(" ABSTRACT ");
3392 log_plain(" : WARNING: Method not found");log_nl( );
3399 /************************* Function: class_findmethod_approx ******************
3401 like class_findmethod but ignores the return value when comparing the
3404 *******************************************************************************/
3406 methodinfo *class_findmethod_approx(classinfo *c, utf *name, utf *desc)
3410 for (i = 0; i < c->methodscount; i++) {
3411 if (c->methods[i].name == name) {
3412 utf *meth_descr = c->methods[i].descriptor;
3416 return &(c->methods[i]);
3418 if (desc->blength <= meth_descr->blength) {
3419 /* current position in utf text */
3420 char *desc_utf_ptr = desc->text;
3421 char *meth_utf_ptr = meth_descr->text;
3422 /* points behind utf strings */
3423 char *desc_end = utf_end(desc);
3424 char *meth_end = utf_end(meth_descr);
3427 /* compare argument types */
3428 while (desc_utf_ptr < desc_end && meth_utf_ptr < meth_end) {
3430 if ((ch = *desc_utf_ptr++) != (*meth_utf_ptr++))
3431 break; /* no match */
3434 return &(c->methods[i]); /* all parameter types equal */
3444 /***************** Function: class_resolvemethod_approx ***********************
3446 Searches a class and every super class for a method (without paying
3447 attention to the return value)
3449 *******************************************************************************/
3451 methodinfo *class_resolvemethod_approx(classinfo *c, utf *name, utf *desc)
3454 /* search for method (ignore returntype) */
3455 methodinfo *m = class_findmethod_approx(c, name, desc);
3458 /* search superclass */
3466 /************************* Function: class_resolvemethod ***********************
3468 Searches a class and every super class for a method.
3470 *******************************************************************************/
3472 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
3474 /*log_text("Trying to resolve a method");
3475 utf_display(c->name);
3477 utf_display(desc);*/
3480 /*log_text("Looking in:");
3481 utf_display(c->name);*/
3482 methodinfo *m = class_findmethod(c, name, desc);
3484 /* search superclass */
3487 /*log_text("method not found:");*/
3493 /****************** Function: class_resolveinterfacemethod_int ****************
3495 Internally used helper function. Do not use this directly.
3497 *******************************************************************************/
3500 methodinfo *class_resolveinterfacemethod_int(classinfo *c, utf *name, utf *desc)
3505 mi = class_findmethod(c,name,desc);
3509 /* try the superinterfaces */
3510 for (i=0; i<c->interfacescount; ++i) {
3511 mi = class_resolveinterfacemethod_int(c->interfaces[i],name,desc);
3519 /******************** Function: class_resolveinterfacemethod ******************
3521 Resolves a reference from REFERER to a method with NAME and DESC in
3524 If the method cannot be resolved the return value is NULL. If EXCEPT is
3525 true *exceptionptr is set, too.
3527 *******************************************************************************/
3529 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
3530 classinfo *referer, bool except)
3534 /* XXX resolve class c */
3535 /* XXX check access from REFERER to C */
3537 if (!(c->flags & ACC_INTERFACE)) {
3540 new_exception(string_java_lang_IncompatibleClassChangeError);
3545 mi = class_resolveinterfacemethod_int(c, name, desc);
3550 /* try class java.lang.Object */
3551 mi = class_findmethod(class_java_lang_Object, name, desc);
3558 new_exception_utfmessage(string_java_lang_NoSuchMethodError, name);
3564 /********************* Function: class_resolveclassmethod *********************
3566 Resolves a reference from REFERER to a method with NAME and DESC in
3569 If the method cannot be resolved the return value is NULL. If EXCEPT is
3570 true *exceptionptr is set, too.
3572 *******************************************************************************/
3574 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
3575 classinfo *referer, bool except)
3580 char msg[MAXLOGTEXT];
3582 /* XXX resolve class c */
3583 /* XXX check access from REFERER to C */
3585 /* if (c->flags & ACC_INTERFACE) { */
3587 /* *exceptionptr = */
3588 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
3592 /* try class c and its superclasses */
3595 mi = class_findmethod(cls, name, desc);
3598 } while ((cls = cls->super) != NULL); /* try the superclass */
3600 /* try the superinterfaces */
3601 for (i = 0; i < c->interfacescount; ++i) {
3602 mi = class_resolveinterfacemethod_int(c->interfaces[i], name, desc);
3608 utf_sprint(msg, c->name);
3609 sprintf(msg + strlen(msg), ".");
3610 utf_sprint(msg + strlen(msg), name);
3611 utf_sprint(msg + strlen(msg), desc);
3614 new_exception_message(string_java_lang_NoSuchMethodError, msg);
3620 if ((mi->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
3622 *exceptionptr = new_exception(string_java_lang_AbstractMethodError);
3627 /* XXX check access rights */
3633 /************************* Function: class_issubclass **************************
3635 Checks if sub is a descendant of super.
3637 *******************************************************************************/
3639 bool class_issubclass(classinfo *sub, classinfo *super)
3642 if (!sub) return false;
3643 if (sub == super) return true;
3649 /****************** Initialization function for classes ******************
3651 In Java, every class can have a static initialization function. This
3652 function has to be called BEFORE calling other methods or accessing static
3655 *******************************************************************************/
3657 static classinfo *class_init_intern(classinfo *c);
3659 classinfo *class_init(classinfo *c)
3663 if (!makeinitializations)
3666 /* enter a monitor on the class */
3668 builtin_monitorenter((java_objectheader *) c);
3670 /* maybe the class is already initalized or the current thread, which can
3671 pass the monitor, is currently initalizing this class */
3673 if (c->initialized || c->initializing) {
3674 builtin_monitorexit((java_objectheader *) c);
3679 /* this initalizing run begins NOW */
3680 c->initializing = true;
3682 /* call the internal function */
3683 r = class_init_intern(c);
3685 /* if return value is not NULL everything was ok and the class is
3688 c->initialized = true;
3690 /* this initalizing run is done */
3691 c->initializing = false;
3693 /* leave the monitor */
3695 builtin_monitorexit((java_objectheader *) c);
3701 /* this function MUST NOT be called directly, because of thread <clinit>
3704 static classinfo *class_init_intern(classinfo *c)
3708 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3712 /* maybe the class is not already loaded */
3717 /* maybe the class is not already linked */
3722 #if defined(STATISTICS)
3724 count_class_inits++;
3727 /* initialize super class */
3730 if (!c->super->initialized) {
3732 char logtext[MAXLOGTEXT];
3733 sprintf(logtext, "Initialize super class ");
3734 utf_sprint_classname(logtext + strlen(logtext), c->super->name);
3735 sprintf(logtext + strlen(logtext), " from ");
3736 utf_sprint_classname(logtext + strlen(logtext), c->name);
3740 if (!class_init(c->super))
3745 /* initialize interface classes */
3747 for (i = 0; i < c->interfacescount; i++) {
3748 if (!c->interfaces[i]->initialized) {
3750 char logtext[MAXLOGTEXT];
3751 sprintf(logtext, "Initialize interface class ");
3752 utf_sprint_classname(logtext + strlen(logtext), c->interfaces[i]->name);
3753 sprintf(logtext + strlen(logtext), " from ");
3754 utf_sprint_classname(logtext + strlen(logtext), c->name);
3758 if (!class_init(c->interfaces[i]))
3763 m = class_findmethod(c, utf_clinit, utf_fidesc);
3767 char logtext[MAXLOGTEXT];
3768 sprintf(logtext, "Class ");
3769 utf_sprint_classname(logtext + strlen(logtext), c->name);
3770 sprintf(logtext + strlen(logtext), " has no static class initializer");
3777 /* Sun's and IBM's JVM don't care about the static flag */
3778 /* if (!(m->flags & ACC_STATIC)) { */
3779 /* panic("Class initializer is not static!"); */
3782 log_message_class("Starting static class initializer for class: ", c);
3784 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3789 /* now call the initializer */
3790 asm_calljavafunction(m, NULL, NULL, NULL, NULL);
3792 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3793 assert(blockInts == 0);
3797 /* we have an exception or error */
3798 if (*exceptionptr) {
3799 /* class is NOT initialized */
3800 c->initialized = false;
3802 /* is this an exception, than wrap it */
3803 if (builtin_instanceof(*exceptionptr, class_java_lang_Exception)) {
3804 java_objectheader *xptr;
3805 java_objectheader *cause;
3808 cause = *exceptionptr;
3810 /* clear exception, because we are calling jit code again */
3811 *exceptionptr = NULL;
3813 /* wrap the exception */
3815 new_exception_throwable(string_java_lang_ExceptionInInitializerError,
3816 (java_lang_Throwable *) cause);
3818 /* XXX should we exit here? */
3822 /* set new exception */
3823 *exceptionptr = xptr;
3830 log_message_class("Finished static class initializer for class: ", c);
3836 /********* Function: find_class_method_constant *********/
3838 int find_class_method_constant (classinfo *c, utf * c1, utf* m1, utf* d1)
3843 for (i=0; i<c->cpcount; i++) {
3845 e = c -> cpinfos [i];
3848 switch (c -> cptags [i]) {
3849 case CONSTANT_Methodref:
3851 constant_FMIref *fmi = e;
3852 if ( (fmi->class->name == c1)
3853 && (fmi->name == m1)
3854 && (fmi->descriptor == d1)) {
3861 case CONSTANT_InterfaceMethodref:
3863 constant_FMIref *fmi = e;
3864 if ( (fmi->class->name == c1)
3865 && (fmi->name == m1)
3866 && (fmi->descriptor == d1)) {
3880 void class_showconstanti(classinfo *c, int ii)
3886 printf ("#%d: ", (int) i);
3888 switch (c->cptags [i]) {
3889 case CONSTANT_Class:
3890 printf("Classreference -> ");
3891 utf_display(((classinfo*)e)->name);
3894 case CONSTANT_Fieldref:
3895 printf("Fieldref -> "); goto displayFMIi;
3896 case CONSTANT_Methodref:
3897 printf("Methodref -> "); goto displayFMIi;
3898 case CONSTANT_InterfaceMethodref:
3899 printf("InterfaceMethod -> "); goto displayFMIi;
3902 constant_FMIref *fmi = e;
3903 utf_display(fmi->class->name);
3905 utf_display(fmi->name);
3907 utf_display(fmi->descriptor);
3911 case CONSTANT_String:
3912 printf("String -> ");
3915 case CONSTANT_Integer:
3916 printf("Integer -> %d", (int) (((constant_integer*)e)->value));
3918 case CONSTANT_Float:
3919 printf("Float -> %f", ((constant_float*)e)->value);
3921 case CONSTANT_Double:
3922 printf("Double -> %f", ((constant_double*)e)->value);
3926 u8 v = ((constant_long*)e)->value;
3928 printf("Long -> %ld", (long int) v);
3930 printf("Long -> HI: %ld, LO: %ld\n",
3931 (long int) v.high, (long int) v.low);
3935 case CONSTANT_NameAndType:
3937 constant_nameandtype *cnt = e;
3938 printf("NameAndType: ");
3939 utf_display(cnt->name);
3941 utf_display(cnt->descriptor);
3949 panic("Invalid type of ConstantPool-Entry");
3956 void class_showconstantpool (classinfo *c)
3961 printf ("---- dump of constant pool ----\n");
3963 for (i=0; i<c->cpcount; i++) {
3964 printf ("#%d: ", (int) i);
3966 e = c -> cpinfos [i];
3969 switch (c -> cptags [i]) {
3970 case CONSTANT_Class:
3971 printf ("Classreference -> ");
3972 utf_display ( ((classinfo*)e) -> name );
3975 case CONSTANT_Fieldref:
3976 printf ("Fieldref -> "); goto displayFMI;
3977 case CONSTANT_Methodref:
3978 printf ("Methodref -> "); goto displayFMI;
3979 case CONSTANT_InterfaceMethodref:
3980 printf ("InterfaceMethod -> "); goto displayFMI;
3983 constant_FMIref *fmi = e;
3984 utf_display ( fmi->class->name );
3986 utf_display ( fmi->name);
3988 utf_display ( fmi->descriptor );
3992 case CONSTANT_String:
3993 printf ("String -> ");
3996 case CONSTANT_Integer:
3997 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
3999 case CONSTANT_Float:
4000 printf ("Float -> %f", ((constant_float*)e) -> value);
4002 case CONSTANT_Double:
4003 printf ("Double -> %f", ((constant_double*)e) -> value);
4007 u8 v = ((constant_long*)e) -> value;
4009 printf ("Long -> %ld", (long int) v);
4011 printf ("Long -> HI: %ld, LO: %ld\n",
4012 (long int) v.high, (long int) v.low);
4016 case CONSTANT_NameAndType:
4018 constant_nameandtype *cnt = e;
4019 printf ("NameAndType: ");
4020 utf_display (cnt->name);
4022 utf_display (cnt->descriptor);
4026 printf ("Utf8 -> ");
4030 panic ("Invalid type of ConstantPool-Entry");
4040 /********** Function: class_showmethods (debugging only) *************/
4042 void class_showmethods (classinfo *c)
4046 printf ("--------- Fields and Methods ----------------\n");
4047 printf ("Flags: "); printflags (c->flags); printf ("\n");
4049 printf ("This: "); utf_display (c->name); printf ("\n");
4051 printf ("Super: "); utf_display (c->super->name); printf ("\n");
4053 printf ("Index: %d\n", c->index);
4055 printf ("interfaces:\n");
4056 for (i=0; i < c-> interfacescount; i++) {
4058 utf_display (c -> interfaces[i] -> name);
4059 printf (" (%d)\n", c->interfaces[i] -> index);
4062 printf ("fields:\n");
4063 for (i=0; i < c -> fieldscount; i++) {
4064 field_display (&(c -> fields[i]));
4067 printf ("methods:\n");
4068 for (i=0; i < c -> methodscount; i++) {
4069 methodinfo *m = &(c->methods[i]);
4070 if ( !(m->flags & ACC_STATIC))
4071 printf ("vftblindex: %d ", m->vftblindex);
4073 method_display ( m );
4077 printf ("Virtual function table:\n");
4078 for (i=0; i<c->vftbl->vftbllength; i++) {
4079 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]) );
4085 /******************************************************************************/
4086 /******************* General functions for the class loader *******************/
4087 /******************************************************************************/
4089 /**************** function: create_primitive_classes ***************************
4091 create classes representing primitive types
4093 *******************************************************************************/
4095 static bool create_primitive_classes()
4099 for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
4100 /* create primitive class */
4102 class_new_intern(utf_new_char(primitivetype_table[i].name));
4103 c->classUsed = NOTUSED; /* not used initially CO-RT */
4106 /* prevent loader from loading primitive class */
4111 primitivetype_table[i].class_primitive = c;
4113 /* create class for wrapping the primitive type */
4114 c = class_new_intern(utf_new_char(primitivetype_table[i].wrapname));
4115 primitivetype_table[i].class_wrap = c;
4116 primitivetype_table[i].class_wrap->classUsed = NOTUSED; /* not used initially CO-RT */
4117 primitivetype_table[i].class_wrap->impldBy = NULL;
4119 /* create the primitive array class */
4120 if (primitivetype_table[i].arrayname) {
4121 c = class_new_intern(utf_new_char(primitivetype_table[i].arrayname));
4122 primitivetype_table[i].arrayclass = c;
4127 primitivetype_table[i].arrayvftbl = c->vftbl;
4135 /**************** function: class_primitive_from_sig ***************************
4137 return the primitive class indicated by the given signature character
4139 If the descriptor does not indicate a valid primitive type the
4140 return value is NULL.
4142 ********************************************************************************/
4144 classinfo *class_primitive_from_sig(char sig)
4147 case 'I': return primitivetype_table[PRIMITIVETYPE_INT].class_primitive;
4148 case 'J': return primitivetype_table[PRIMITIVETYPE_LONG].class_primitive;
4149 case 'F': return primitivetype_table[PRIMITIVETYPE_FLOAT].class_primitive;
4150 case 'D': return primitivetype_table[PRIMITIVETYPE_DOUBLE].class_primitive;
4151 case 'B': return primitivetype_table[PRIMITIVETYPE_BYTE].class_primitive;
4152 case 'C': return primitivetype_table[PRIMITIVETYPE_CHAR].class_primitive;
4153 case 'S': return primitivetype_table[PRIMITIVETYPE_SHORT].class_primitive;
4154 case 'Z': return primitivetype_table[PRIMITIVETYPE_BOOLEAN].class_primitive;
4155 case 'V': return primitivetype_table[PRIMITIVETYPE_VOID].class_primitive;
4160 /****************** function: class_from_descriptor ****************************
4162 return the class indicated by the given descriptor
4164 utf_ptr....first character of descriptor
4165 end_ptr....first character after the end of the string
4166 next.......if non-NULL, *next is set to the first character after
4167 the descriptor. (Undefined if an error occurs.)
4169 mode.......a combination (binary or) of the following flags:
4171 (Flags marked with * are the default settings.)
4173 What to do if a reference type descriptor is parsed successfully:
4175 CLASSLOAD_SKIP...skip it and return something != NULL
4176 * CLASSLOAD_NEW....get classinfo * via class_new
4177 CLASSLOAD_LOAD...get classinfo * via loader_load
4179 How to handle primitive types:
4181 * CLASSLOAD_PRIMITIVE.......return primitive class (eg. "int")
4182 CLASSLOAD_NULLPRIMITIVE...return NULL for primitive types
4184 How to handle "V" descriptors:
4186 * CLASSLOAD_VOID.....handle it like other primitive types
4187 CLASSLOAD_NOVOID...treat it as an error
4189 How to deal with extra characters after the end of the
4192 * CLASSLOAD_NOCHECKEND...ignore (useful for parameter lists)
4193 CLASSLOAD_CHECKEND.....treat them as an error
4195 How to deal with errors:
4197 * CLASSLOAD_PANIC....abort execution with an error message
4198 CLASSLOAD_NOPANIC..return NULL on error
4200 *******************************************************************************/
4202 classinfo *class_from_descriptor(char *utf_ptr, char *end_ptr,
4203 char **next, int mode)
4205 char *start = utf_ptr;
4209 SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr, end_ptr, error);
4211 if (mode & CLASSLOAD_CHECKEND)
4212 error |= (utf_ptr != end_ptr);
4215 if (next) *next = utf_ptr;
4219 if (mode & CLASSLOAD_NOVOID)
4230 return (mode & CLASSLOAD_NULLPRIMITIVE)
4232 : class_primitive_from_sig(*start);
4239 if (mode & CLASSLOAD_SKIP) return class_java_lang_Object;
4240 name = utf_new(start, utf_ptr - start);
4244 tc = class_new_intern(name);
4246 list_addfirst(&unlinkedclasses, tc);
4251 return (mode & CLASSLOAD_LOAD)
4252 ? class_load(class_new(name)) : class_new(name); /* XXX handle errors */
4257 /* An error occurred */
4258 if (mode & CLASSLOAD_NOPANIC)
4261 log_plain("Invalid descriptor at beginning of '");
4262 log_plain_utf(utf_new(start, end_ptr - start));
4266 panic("Invalid descriptor");
4268 /* keep compiler happy */
4273 /******************* function: type_from_descriptor ****************************
4275 return the basic type indicated by the given descriptor
4277 This function parses a descriptor and returns its basic type as
4278 TYPE_INT, TYPE_LONG, TYPE_FLOAT, TYPE_DOUBLE, TYPE_ADDRESS or TYPE_VOID.
4280 cls...if non-NULL the referenced variable is set to the classinfo *
4281 returned by class_from_descriptor.
4283 For documentation of the arguments utf_ptr, end_ptr, next and mode
4284 see class_from_descriptor. The only difference is that
4285 type_from_descriptor always uses CLASSLOAD_PANIC.
4287 ********************************************************************************/
4289 int type_from_descriptor(classinfo **cls, char *utf_ptr, char *end_ptr,
4290 char **next, int mode)
4293 if (!cls) cls = &mycls;
4294 *cls = class_from_descriptor(utf_ptr, end_ptr, next, mode & (~CLASSLOAD_NOPANIC));
4311 return TYPE_ADDRESS;
4315 /*************** function: create_pseudo_classes *******************************
4317 create pseudo classes used by the typechecker
4319 ********************************************************************************/
4321 static void create_pseudo_classes()
4323 /* pseudo class for Arraystubs (extends java.lang.Object) */
4325 pseudo_class_Arraystub = class_new_intern(utf_new_char("$ARRAYSTUB$"));
4326 pseudo_class_Arraystub->loaded = true;
4327 pseudo_class_Arraystub->super = class_java_lang_Object;
4328 pseudo_class_Arraystub->interfacescount = 2;
4329 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
4330 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
4331 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
4333 class_link(pseudo_class_Arraystub);
4335 pseudo_class_Arraystub_vftbl = pseudo_class_Arraystub->vftbl;
4337 /* pseudo class representing the null type */
4339 pseudo_class_Null = class_new_intern(utf_new_char("$NULL$"));
4340 pseudo_class_Null->loaded = true;
4341 pseudo_class_Null->super = class_java_lang_Object;
4342 class_link(pseudo_class_Null);
4344 /* pseudo class representing new uninitialized objects */
4346 pseudo_class_New = class_new_intern(utf_new_char("$NEW$"));
4347 pseudo_class_New->loaded = true;
4348 pseudo_class_New->linked = true;
4349 pseudo_class_New->super = class_java_lang_Object;
4350 /* class_link(pseudo_class_New); */
4354 /********************** Function: loader_init **********************************
4356 Initializes all lists and loads all classes required for the system or the
4359 *******************************************************************************/
4361 void loader_init(u1 *stackbottom)
4365 /* create utf-symbols for pointer comparison of frequently used strings */
4366 utf_innerclasses = utf_new_char("InnerClasses");
4367 utf_constantvalue = utf_new_char("ConstantValue");
4368 utf_code = utf_new_char("Code");
4369 utf_exceptions = utf_new_char("Exceptions");
4370 utf_linenumbertable = utf_new_char("LineNumberTable");
4371 utf_sourcefile = utf_new_char("SourceFile");
4372 utf_finalize = utf_new_char("finalize");
4373 utf_fidesc = utf_new_char("()V");
4374 utf_init = utf_new_char("<init>");
4375 utf_clinit = utf_new_char("<clinit>");
4376 utf_initsystemclass = utf_new_char("initializeSystemClass");
4377 utf_systemclass = utf_new_char("java/lang/System");
4378 utf_vmclassloader = utf_new_char("java/lang/VMClassLoader");
4379 utf_initialize = utf_new_char("initialize");
4380 utf_initializedesc = utf_new_char("(I)V");
4381 utf_vmclass = utf_new_char("java/lang/VMClass");
4382 utf_java_lang_Object= utf_new_char("java/lang/Object");
4383 array_packagename = utf_new_char("<the array package>");
4384 utf_fillInStackTrace_name = utf_new_char("fillInStackTrace");
4385 utf_fillInStackTrace_desc = utf_new_char("()Ljava/lang/Throwable;");
4387 /* create some important classes */
4388 /* These classes have to be created now because the classinfo
4389 * pointers are used in the loading code.
4391 class_java_lang_Object = class_new_intern(utf_java_lang_Object);
4392 class_load(class_java_lang_Object);
4393 class_link(class_java_lang_Object);
4395 class_java_lang_String = class_new(utf_new_char("java/lang/String"));
4396 class_load(class_java_lang_String);
4397 class_link(class_java_lang_String);
4399 class_java_lang_Cloneable = class_new(utf_new_char("java/lang/Cloneable"));
4400 class_load(class_java_lang_Cloneable);
4401 class_link(class_java_lang_Cloneable);
4403 class_java_io_Serializable =
4404 class_new(utf_new_char("java/io/Serializable"));
4405 class_load(class_java_io_Serializable);
4406 class_link(class_java_io_Serializable);
4408 /* create classes representing primitive types */
4409 create_primitive_classes();
4411 /* create classes used by the typechecker */
4412 create_pseudo_classes();
4414 /* correct vftbl-entries (retarded loading of class java/lang/String) */
4415 stringtable_update();
4417 #if defined(USE_THREADS)
4418 if (stackbottom != 0)
4424 /* loader_compute_subclasses ***************************************************
4428 *******************************************************************************/
4430 static void loader_compute_class_values(classinfo *c);
4432 void loader_compute_subclasses(classinfo *c)
4434 #if defined(USE_THREADS)
4435 #if defined(NATIVE_THREADS)
4442 if (!(c->flags & ACC_INTERFACE)) {
4447 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
4448 c->nextsub = c->super->sub;
4454 /* this is the java.lang.Object special case */
4456 if (!class_java_lang_Object) {
4457 loader_compute_class_values(c);
4460 loader_compute_class_values(class_java_lang_Object);
4463 #if defined(USE_THREADS)
4464 #if defined(NATIVE_THREADS)
4473 /* loader_compute_class_values *************************************************
4477 *******************************************************************************/
4479 static void loader_compute_class_values(classinfo *c)
4483 c->vftbl->baseval = ++classvalue;
4487 loader_compute_class_values(subs);
4488 subs = subs->nextsub;
4491 c->vftbl->diffval = classvalue - c->vftbl->baseval;
4495 /******************** Function: loader_close ***********************************
4499 *******************************************************************************/
4506 for (slot = 0; slot < class_hash.size; slot++) {
4507 c = class_hash.ptr[slot];
4518 * These are local overrides for various environment variables in Emacs.
4519 * Please do not remove this and leave it at the end of the file, where
4520 * Emacs will automagically detect them.
4521 * ---------------------------------------------------------------------
4524 * indent-tabs-mode: t