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 1329 2004-07-21 15:36:33Z 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 /* instances of important system classes **************************************/
155 java_objectheader *proto_java_lang_NullPointerException;
158 /************* functions for reading classdata *********************************
160 getting classdata in blocks of variable size
161 (8,16,32,64-bit integer or float)
163 *******************************************************************************/
165 static char *classpath = ""; /* searchpath for classfiles */
168 /* check_classbuffer_size ******************************************************
170 assert that at least <len> bytes are left to read
171 <len> is limited to the range of non-negative s4 values
173 *******************************************************************************/
175 static inline bool check_classbuffer_size(classbuffer *cb, s4 len)
177 if (len < 0 || ((cb->data + cb->size) - cb->pos - 1) < len) {
179 new_classformaterror((cb)->class, "Truncated class file");
188 /* suck_nbytes *****************************************************************
190 transfer block of classfile data into a buffer
192 *******************************************************************************/
194 inline void suck_nbytes(u1 *buffer, classbuffer *cb, s4 len)
196 memcpy(buffer, cb->pos + 1, len);
201 /* skip_nbytes ****************************************************************
203 skip block of classfile data
205 *******************************************************************************/
207 inline void skip_nbytes(classbuffer *cb, s4 len)
213 inline u1 suck_u1(classbuffer *cb)
219 inline u2 suck_u2(classbuffer *cb)
223 return ((u2) a << 8) + (u2) b;
227 inline u4 suck_u4(classbuffer *cb)
233 return ((u4) a << 24) + ((u4) b << 16) + ((u4) c << 8) + (u4) d;
236 #define suck_s8(a) (s8) suck_u8((a))
237 #define suck_s2(a) (s2) suck_u2((a))
238 #define suck_s4(a) (s4) suck_u4((a))
239 #define suck_s1(a) (s1) suck_u1((a))
242 /* get u8 from classfile data */
243 static u8 suck_u8(classbuffer *cb)
249 return (hi << 32) + lo;
252 v.high = suck_u4(cb);
259 /* get float from classfile data */
260 static float suck_float(classbuffer *cb)
268 for (i = 0; i < 4; i++)
269 buffer[3 - i] = suck_u1(cb);
271 memcpy((u1*) (&f), buffer, 4);
273 suck_nbytes((u1*) (&f), cb, 4);
276 if (sizeof(float) != 4) {
277 *exceptionptr = new_exception_message(string_java_lang_InternalError,
278 "Incompatible float-format");
280 /* XXX should we exit in such a case? */
281 throw_exception_exit();
288 /* get double from classfile data */
289 static double suck_double(classbuffer *cb)
297 for (i = 0; i < 8; i++)
298 buffer[7 - i] = suck_u1(cb);
300 memcpy((u1*) (&d), buffer, 8);
302 suck_nbytes((u1*) (&d), cb, 8);
305 if (sizeof(double) != 8) {
306 *exceptionptr = new_exception_message(string_java_lang_InternalError,
307 "Incompatible double-format");
309 /* XXX should we exit in such a case? */
310 throw_exception_exit();
317 /************************** function suck_init *********************************
319 called once at startup, sets the searchpath for the classfiles
321 *******************************************************************************/
323 void suck_init(char *cpath)
330 union classpath_info *tmp;
331 union classpath_info *insertAfter=0;
338 if (classpath_entries)
339 panic("suck_init should be called only once");
341 for (start = classpath; (*start) != '\0';) {
342 for (end = start; ((*end) != '\0') && ((*end) != ':'); end++);
346 filenamelen = end - start;
348 if (filenamelen > 3) {
349 if (strncasecmp(end - 3, "zip", 3) == 0 ||
350 strncasecmp(end - 3, "jar", 3) == 0) {
355 if (filenamelen >= (CLASSPATH_MAXFILENAME - 1))
356 panic("path length >= MAXFILENAME in suck_init");
359 filename = MNEW(char, CLASSPATH_MAXFILENAME);
361 strncpy(filename, start, filenamelen);
362 filename[filenamelen + 1] = '\0';
366 #if defined(USE_ZLIB)
367 unzFile uf = unzOpen(filename);
370 tmp = (union classpath_info *) NEW(classpath_info);
371 tmp->archive.type = CLASSPATH_ARCHIVE;
372 tmp->archive.uf = uf;
373 tmp->archive.next = NULL;
377 throw_cacao_exception_exit(string_java_lang_InternalError, "zip/jar files not supported");
381 tmp = (union classpath_info *) NEW(classpath_info);
382 tmp->filepath.type = CLASSPATH_PATH;
383 tmp->filepath.next = 0;
385 if (filename[filenamelen - 1] != '/') {/*PERHAPS THIS SHOULD BE READ FROM A GLOBAL CONFIGURATION */
386 filename[filenamelen] = '/';
387 filename[filenamelen + 1] = '\0';
391 tmp->filepath.filename = filename;
392 tmp->filepath.pathlen = filenamelen;
398 insertAfter->filepath.next = tmp;
401 classpath_entries = tmp;
413 MFREE(filename, char, CLASSPATH_MAXFILENAME);
420 void create_all_classes()
424 for (cpi = classpath_entries; cpi != 0; cpi = cpi->filepath.next) {
425 #if defined(USE_ZLIB)
426 if (cpi->filepath.type == CLASSPATH_ARCHIVE) {
430 s = (unz_s *) cpi->archive.uf;
431 ce = s->cacao_dir_list;
434 (void) class_new(ce->name);
440 #if defined(USE_ZLIB)
447 /************************** function suck_start ********************************
449 returns true if classbuffer is already loaded or a file for the
450 specified class has succussfully been read in. All directories of
451 the searchpath are used to find the classfile (<classname>.class).
452 Returns false if no classfile is found and writes an error message.
454 *******************************************************************************/
456 classbuffer *suck_start(classinfo *c)
458 classpath_info *currPos;
461 char filename[CLASSPATH_MAXFILENAME+10]; /* room for '.class' */
468 utf_ptr = c->name->text;
470 while (utf_ptr < utf_end(c->name)) {
471 if (filenamelen >= CLASSPATH_MAXFILENAME) {
473 new_exception_message(string_java_lang_InternalError,
474 "Filename too long");
476 /* XXX should we exit in such a case? */
477 throw_exception_exit();
481 if ((ch <= ' ' || ch > 'z') && (ch != '/')) /* invalid character */
483 filename[filenamelen++] = ch;
486 strcpy(filename + filenamelen, ".class");
489 for (currPos = classpath_entries; currPos != 0; currPos = currPos->filepath.next) {
490 #if defined(USE_ZLIB)
491 if (currPos->filepath.type == CLASSPATH_ARCHIVE) {
492 if (cacao_locate(currPos->archive.uf, c->name) == UNZ_OK) {
493 unz_file_info file_info;
494 /*log_text("Class found in zip file");*/
495 if (unzGetCurrentFileInfo(currPos->archive.uf, &file_info, filename,
496 sizeof(filename), NULL, 0, NULL, 0) == UNZ_OK) {
497 if (unzOpenCurrentFile(currPos->archive.uf) == UNZ_OK) {
498 cb = NEW(classbuffer);
500 cb->size = file_info.uncompressed_size;
501 cb->data = MNEW(u1, cb->size);
502 cb->pos = cb->data - 1;
503 /*printf("classfile size: %d\n",file_info.uncompressed_size);*/
504 if (unzReadCurrentFile(currPos->archive.uf, cb->data, cb->size) == cb->size) {
505 unzCloseCurrentFile(currPos->archive.uf);
509 MFREE(cb->data, u1, cb->size);
510 FREE(cb, classbuffer);
511 log_text("Error while unzipping");
513 } else log_text("Error while opening file in archive");
514 } else log_text("Error while retrieving fileinfo");
516 unzCloseCurrentFile(currPos->archive.uf);
520 if ((currPos->filepath.pathlen + filenamelen) >= CLASSPATH_MAXFILENAME) continue;
521 strcpy(currPos->filepath.filename + currPos->filepath.pathlen, filename);
522 classfile = fopen(currPos->filepath.filename, "r");
523 if (classfile) { /* file exists */
525 /* determine size of classfile */
527 /* dolog("File: %s",filename); */
528 err = stat(currPos->filepath.filename, &buffer);
530 if (!err) { /* read classfile data */
531 cb = NEW(classbuffer);
533 cb->size = buffer.st_size;
534 cb->data = MNEW(u1, cb->size);
535 cb->pos = cb->data - 1;
536 fread(cb->data, 1, cb->size, classfile);
542 #if defined(USE_ZLIB)
548 dolog("Warning: Can not open class file '%s'", filename);
555 /************************** function suck_stop *********************************
557 frees memory for buffer with classfile data.
558 Caution: this function may only be called if buffer has been allocated
559 by suck_start with reading a file
561 *******************************************************************************/
563 void suck_stop(classbuffer *cb)
567 MFREE(cb->data, u1, cb->size);
568 FREE(cb, classbuffer);
572 /******************************************************************************/
573 /******************* Some support functions ***********************************/
574 /******************************************************************************/
576 void fprintflags (FILE *fp, u2 f)
578 if ( f & ACC_PUBLIC ) fprintf (fp," PUBLIC");
579 if ( f & ACC_PRIVATE ) fprintf (fp," PRIVATE");
580 if ( f & ACC_PROTECTED ) fprintf (fp," PROTECTED");
581 if ( f & ACC_STATIC ) fprintf (fp," STATIC");
582 if ( f & ACC_FINAL ) fprintf (fp," FINAL");
583 if ( f & ACC_SYNCHRONIZED ) fprintf (fp," SYNCHRONIZED");
584 if ( f & ACC_VOLATILE ) fprintf (fp," VOLATILE");
585 if ( f & ACC_TRANSIENT ) fprintf (fp," TRANSIENT");
586 if ( f & ACC_NATIVE ) fprintf (fp," NATIVE");
587 if ( f & ACC_INTERFACE ) fprintf (fp," INTERFACE");
588 if ( f & ACC_ABSTRACT ) fprintf (fp," ABSTRACT");
592 /********** internal function: printflags (only for debugging) ***************/
594 void printflags(u2 f)
596 if ( f & ACC_PUBLIC ) printf (" PUBLIC");
597 if ( f & ACC_PRIVATE ) printf (" PRIVATE");
598 if ( f & ACC_PROTECTED ) printf (" PROTECTED");
599 if ( f & ACC_STATIC ) printf (" STATIC");
600 if ( f & ACC_FINAL ) printf (" FINAL");
601 if ( f & ACC_SYNCHRONIZED ) printf (" SYNCHRONIZED");
602 if ( f & ACC_VOLATILE ) printf (" VOLATILE");
603 if ( f & ACC_TRANSIENT ) printf (" TRANSIENT");
604 if ( f & ACC_NATIVE ) printf (" NATIVE");
605 if ( f & ACC_INTERFACE ) printf (" INTERFACE");
606 if ( f & ACC_ABSTRACT ) printf (" ABSTRACT");
610 /********************** Function: skipattributebody ****************************
612 skips an attribute after the 16 bit reference to attribute_name has already
615 *******************************************************************************/
617 static bool skipattributebody(classbuffer *cb)
621 if (!check_classbuffer_size(cb, 4))
626 if (!check_classbuffer_size(cb, len))
629 skip_nbytes(cb, len);
635 /************************* Function: skipattributes ****************************
637 skips num attribute structures
639 *******************************************************************************/
641 static bool skipattributes(classbuffer *cb, u4 num)
646 for (i = 0; i < num; i++) {
647 if (!check_classbuffer_size(cb, 2 + 4))
653 if (!check_classbuffer_size(cb, len))
656 skip_nbytes(cb, len);
663 /******************** function: innerclass_getconstant ************************
665 like class_getconstant, but if cptags is ZERO null is returned
667 *******************************************************************************/
669 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
671 /* invalid position in constantpool */
672 if (pos >= c->cpcount)
673 panic("Attempt to access constant outside range");
675 /* constantpool entry of type 0 */
679 /* check type of constantpool entry */
680 if (c->cptags[pos] != ctype) {
681 error("Type mismatch on constant: %d requested, %d here (innerclass_getconstant)",
682 (int) ctype, (int) c->cptags[pos] );
685 return c->cpinfos[pos];
689 /************************ function: attribute_load ****************************
691 read attributes from classfile
693 *******************************************************************************/
695 static bool attribute_load(classbuffer *cb, classinfo *c, u4 num)
699 for (i = 0; i < num; i++) {
702 /* retrieve attribute name */
703 if (!check_classbuffer_size(cb, 2))
706 aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
708 if (aname == utf_innerclasses) {
709 /* innerclasses attribute */
710 if (c->innerclass != NULL)
711 panic("Class has more than one InnerClasses attribute");
713 if (!check_classbuffer_size(cb, 4 + 2))
716 /* skip attribute length */
719 /* number of records */
720 c->innerclasscount = suck_u2(cb);
722 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
725 /* allocate memory for innerclass structure */
726 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
728 for (j = 0; j < c->innerclasscount; j++) {
729 /* The innerclass structure contains a class with an encoded
730 name, its defining scope, its simple name and a bitmask of
731 the access flags. If an inner class is not a member, its
732 outer_class is NULL, if a class is anonymous, its name is
735 innerclassinfo *info = c->innerclass + j;
738 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
740 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
742 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
743 info->flags = suck_u2(cb);
746 } else if (aname == utf_sourcefile) {
747 if (!check_classbuffer_size(cb, 4 + 2))
751 c->sourcefile = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
754 /* unknown attribute */
755 if (!skipattributebody(cb))
764 /******************* function: checkfielddescriptor ****************************
766 checks whether a field-descriptor is valid and aborts otherwise
767 all referenced classes are inserted into the list of unloaded classes
769 *******************************************************************************/
771 static void checkfielddescriptor (char *utf_ptr, char *end_pos)
773 class_from_descriptor(utf_ptr,end_pos,NULL,
775 | CLASSLOAD_NULLPRIMITIVE
777 | CLASSLOAD_CHECKEND);
779 /* XXX use the following if -noverify */
781 char *tstart; /* pointer to start of classname */
783 char *start = utf_ptr;
785 switch (*utf_ptr++) {
799 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
800 panic ("Ill formed descriptor");
804 panic ("Ill formed descriptor");
807 /* exceeding characters */
808 if (utf_ptr!=end_pos) panic ("descriptor has exceeding chars");
813 /******************* function checkmethoddescriptor ****************************
815 checks whether a method-descriptor is valid and aborts otherwise.
816 All referenced classes are inserted into the list of unloaded classes.
818 The number of arguments is returned. A long or double argument is counted
821 *******************************************************************************/
823 static int checkmethoddescriptor(classinfo *c, utf *descriptor)
825 char *utf_ptr; /* current position in utf text */
826 char *end_pos; /* points behind utf string */
827 s4 argcount = 0; /* number of arguments */
829 utf_ptr = descriptor->text;
830 end_pos = utf_end(descriptor);
832 /* method descriptor must start with parenthesis */
833 if (utf_ptr == end_pos || *utf_ptr++ != '(')
834 panic ("Missing '(' in method descriptor");
836 /* check arguments */
837 while (utf_ptr != end_pos && *utf_ptr != ')') {
838 /* We cannot count the this argument here because
839 * we don't know if the method is static. */
840 if (*utf_ptr == 'J' || *utf_ptr == 'D')
844 class_from_descriptor(utf_ptr,end_pos,&utf_ptr,
846 | CLASSLOAD_NULLPRIMITIVE
850 if (utf_ptr == end_pos)
851 panic("Missing ')' in method descriptor");
853 utf_ptr++; /* skip ')' */
855 class_from_descriptor(utf_ptr,
859 CLASSLOAD_NULLPRIMITIVE |
862 if (argcount > 255) {
864 new_classformaterror(c, "Too many arguments in signature");
871 /* XXX use the following if -noverify */
873 /* check arguments */
874 while ((c = *utf_ptr++) != ')') {
891 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
892 panic ("Ill formed method descriptor");
896 panic ("Ill formed methodtype-descriptor");
900 /* check returntype */
902 /* returntype void */
903 if ((utf_ptr+1) != end_pos) panic ("Method-descriptor has exceeding chars");
906 /* treat as field-descriptor */
907 checkfielddescriptor (utf_ptr,end_pos);
912 /***************** Function: print_arraydescriptor ****************************
914 Debugging helper for displaying an arraydescriptor
916 *******************************************************************************/
918 void print_arraydescriptor(FILE *file, arraydescriptor *desc)
921 fprintf(file, "<NULL>");
926 if (desc->componentvftbl) {
927 if (desc->componentvftbl->class)
928 utf_fprint(file, desc->componentvftbl->class->name);
930 fprintf(file, "<no classinfo>");
936 if (desc->elementvftbl) {
937 if (desc->elementvftbl->class)
938 utf_fprint(file, desc->elementvftbl->class->name);
940 fprintf(file, "<no classinfo>");
944 fprintf(file, ",%d,%d,%d,%d}", desc->arraytype, desc->dimension,
945 desc->dataoffset, desc->componentsize);
949 /******************************************************************************/
950 /************************** Functions for fields ****************************/
951 /******************************************************************************/
954 /* field_load ******************************************************************
956 Load everything about a class field from the class file and fill a
957 'fieldinfo' structure. For static fields, space in the data segment is
960 *******************************************************************************/
962 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
964 static bool field_load(classbuffer *cb, classinfo *c, fieldinfo *f)
968 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
970 if (!check_classbuffer_size(cb, 2 + 2 + 2))
973 f->flags = suck_u2(cb);
974 f->name = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
975 f->descriptor = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
979 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<')
980 panic("Field with invalid name");
982 /* check flag consistency */
983 i = (f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
985 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED)
986 panic("Field has invalid access flags");
988 if ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))
989 panic("Field is declared final and volatile");
991 if ((c->flags & ACC_INTERFACE) != 0) {
992 if ((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
993 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
994 panic("Interface field is not declared static final public");
996 if ((f->flags & ACC_TRANSIENT) != 0)
997 panic("Interface field declared transient");
1000 /* check descriptor */
1001 checkfielddescriptor(f->descriptor->text, utf_end(f->descriptor));
1004 f->type = jtype = desc_to_type(f->descriptor); /* data type */
1005 f->offset = 0; /* offset from start of object */
1010 case TYPE_INT: f->value.i = 0; break;
1011 case TYPE_FLOAT: f->value.f = 0.0; break;
1012 case TYPE_DOUBLE: f->value.d = 0.0; break;
1013 case TYPE_ADDRESS: f->value.a = NULL; break;
1016 f->value.l = 0; break;
1018 f->value.l.low = 0; f->value.l.high = 0; break;
1022 /* read attributes */
1023 if (!check_classbuffer_size(cb, 2))
1026 attrnum = suck_u2(cb);
1027 for (i = 0; i < attrnum; i++) {
1030 if (!check_classbuffer_size(cb, 2))
1033 aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1035 if (aname != utf_constantvalue) {
1036 /* unknown attribute */
1037 if (!skipattributebody(cb))
1041 /* constant value attribute */
1042 if (pindex != field_load_NOVALUE)
1043 panic("Field has more than one ConstantValue attribute");
1045 if (!check_classbuffer_size(cb, 4 + 2))
1048 /* check attribute length */
1049 if (suck_u4(cb) != 2)
1050 panic("ConstantValue attribute has invalid length");
1052 /* index of value in constantpool */
1053 pindex = suck_u2(cb);
1055 /* initialize field with value from constantpool */
1058 constant_integer *ci =
1059 class_getconstant(c, pindex, CONSTANT_Integer);
1060 f->value.i = ci->value;
1066 class_getconstant(c, pindex, CONSTANT_Long);
1067 f->value.l = cl->value;
1072 constant_float *cf =
1073 class_getconstant(c, pindex, CONSTANT_Float);
1074 f->value.f = cf->value;
1079 constant_double *cd =
1080 class_getconstant(c, pindex, CONSTANT_Double);
1081 f->value.d = cd->value;
1085 case TYPE_ADDRESS: {
1086 utf *u = class_getconstant(c, pindex, CONSTANT_String);
1087 /* create javastring from compressed utf8-string */
1088 f->value.a = literalstring_new(u);
1093 log_text ("Invalid Constant - Type");
1098 /* everything was ok */
1104 /********************** function: field_free **********************************/
1106 static void field_free(fieldinfo *f)
1112 /**************** Function: field_display (debugging only) ********************/
1114 void field_display(fieldinfo *f)
1117 printflags(f->flags);
1119 utf_display(f->name);
1121 utf_display(f->descriptor);
1122 printf(" offset: %ld\n", (long int) (f->offset));
1126 /******************************************************************************/
1127 /************************* Functions for methods ******************************/
1128 /******************************************************************************/
1131 /* method_load *****************************************************************
1133 Loads a method from the class file and fills an existing 'methodinfo'
1134 structure. For native methods, the function pointer field is set to the
1135 real function pointer, for JavaVM methods a pointer to the compiler is used
1138 *******************************************************************************/
1140 static bool method_load(classbuffer *cb, classinfo *c, methodinfo *m)
1149 count_all_methods++;
1152 m->thrownexceptionscount = 0;
1153 m->linenumbercount = 0;
1156 m->nativelyoverloaded = false;
1158 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1161 m->flags = suck_u2(cb);
1162 m->name = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1163 m->descriptor = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1166 if (!is_valid_name_utf(m->name))
1167 panic("Method with invalid name");
1169 if (m->name->text[0] == '<'
1170 && m->name != utf_init && m->name != utf_clinit)
1171 panic("Method with invalid special name");
1174 argcount = checkmethoddescriptor(c, m->descriptor);
1176 if (!(m->flags & ACC_STATIC))
1177 argcount++; /* count the 'this' argument */
1181 panic("Too many arguments in signature");
1183 /* check flag consistency */
1184 if (m->name != utf_clinit) {
1185 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1187 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED)
1188 panic("Method has invalid access flags");
1190 if ((m->flags & ACC_ABSTRACT) != 0) {
1191 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1192 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1194 new_classformaterror(c,
1195 "Illegal method modifiers: 0x%x",
1202 if ((c->flags & ACC_INTERFACE) != 0) {
1203 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC))
1204 != (ACC_ABSTRACT | ACC_PUBLIC))
1205 panic("Interface method is not declared abstract and public");
1208 if (m->name == utf_init) {
1209 if ((m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED
1210 | ACC_NATIVE | ACC_ABSTRACT)) != 0)
1211 panic("Instance initialization method has invalid flags set");
1217 m->basicblockcount = 0;
1218 m->basicblocks = NULL;
1219 m->basicblockindex = NULL;
1220 m->instructioncount = 0;
1221 m->instructions = NULL;
1224 m->exceptiontable = NULL;
1225 m->registerdata = NULL;
1226 m->stubroutine = NULL;
1228 m->entrypoint = NULL;
1229 m->methodUsed = NOTUSED;
1232 m->subRedefsUsed = 0;
1236 if (!(m->flags & ACC_NATIVE)) {
1237 m->stubroutine = createcompilerstub(m);
1240 functionptr f = native_findfunction(c->name, m->name, m->descriptor,
1241 (m->flags & ACC_STATIC) != 0);
1243 m->stubroutine = createnativestub(f, m);
1247 if (!check_classbuffer_size(cb, 2))
1250 attrnum = suck_u2(cb);
1251 for (i = 0; i < attrnum; i++) {
1254 if (!check_classbuffer_size(cb, 2))
1257 aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1259 if (aname != utf_code) {
1260 if (aname == utf_exceptions) {
1263 if (!check_classbuffer_size(cb, 4 + 2))
1266 suck_u4(cb); /*length*/
1267 m->thrownexceptionscount = suck_u2(cb);
1269 if (!check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1272 m->thrownexceptions = MNEW(classinfo*, m->thrownexceptionscount);
1274 for (j = 0; j < m->thrownexceptionscount; j++) {
1275 (m->thrownexceptions)[j] =
1276 class_getconstant(c, suck_u2(cb), CONSTANT_Class);
1280 if (!skipattributebody(cb))
1285 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1287 new_classformaterror(c,
1288 "Code attribute in native or abstract methods");
1295 new_classformaterror(c, "Multiple Code attributes");
1300 if (!check_classbuffer_size(cb, 4 + 2 + 2))
1304 m->maxstack = suck_u2(cb);
1305 m->maxlocals = suck_u2(cb);
1307 if (m->maxlocals < argcount) {
1309 new_classformaterror(c, "Arguments can't fit into locals");
1314 if (!check_classbuffer_size(cb, 4))
1317 m->jcodelength = suck_u4(cb);
1319 if (m->jcodelength == 0) {
1321 new_classformaterror(c, "Code of a method has length 0");
1326 if (m->jcodelength > 65535) {
1328 new_classformaterror(c,
1329 "Code of a method longer than 65535 bytes");
1334 if (!check_classbuffer_size(cb, m->jcodelength))
1337 m->jcode = MNEW(u1, m->jcodelength);
1338 suck_nbytes(m->jcode, cb, m->jcodelength);
1340 if (!check_classbuffer_size(cb, 2))
1343 m->exceptiontablelength = suck_u2(cb);
1345 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->exceptiontablelength))
1348 m->exceptiontable = MNEW(exceptiontable, m->exceptiontablelength);
1350 #if defined(STATISTICS)
1352 count_vmcode_len += m->jcodelength + 18;
1353 count_extable_len += 8 * m->exceptiontablelength;
1357 for (j = 0; j < m->exceptiontablelength; j++) {
1359 m->exceptiontable[j].startpc = suck_u2(cb);
1360 m->exceptiontable[j].endpc = suck_u2(cb);
1361 m->exceptiontable[j].handlerpc = suck_u2(cb);
1365 m->exceptiontable[j].catchtype = NULL;
1368 m->exceptiontable[j].catchtype =
1369 class_getconstant(c, idx, CONSTANT_Class);
1373 if (!check_classbuffer_size(cb, 2))
1376 codeattrnum = suck_u2(cb);
1378 for (; codeattrnum > 0; codeattrnum--) {
1381 if (!check_classbuffer_size(cb, 2))
1384 caname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1386 if (caname == utf_linenumbertable) {
1389 if (!check_classbuffer_size(cb, 4 + 2))
1393 m->linenumbercount = suck_u2(cb);
1395 if (!check_classbuffer_size(cb,
1396 (2 + 2) * m->linenumbercount))
1399 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1401 for (lncid = 0; lncid < m->linenumbercount; lncid++) {
1402 m->linenumbers[lncid].start_pc = suck_u2(cb);
1403 m->linenumbers[lncid].line_number = suck_u2(cb);
1407 if (!skipattributes(cb, codeattrnum))
1412 if (!skipattributebody(cb))
1419 if (!m->jcode && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1420 *exceptionptr = new_classformaterror(c, "Missing Code attribute");
1425 /* everything was ok */
1431 /********************* Function: method_free ***********************************
1433 frees all memory that was allocated for this method
1435 *******************************************************************************/
1437 static void method_free(methodinfo *m)
1440 MFREE(m->jcode, u1, m->jcodelength);
1442 if (m->exceptiontable)
1443 MFREE(m->exceptiontable, exceptiontable, m->exceptiontablelength);
1446 CFREE(m->mcode, m->mcodelength);
1448 if (m->stubroutine) {
1449 if (m->flags & ACC_NATIVE) {
1450 removenativestub(m->stubroutine);
1453 removecompilerstub(m->stubroutine);
1459 /************** Function: method_display (debugging only) **************/
1461 void method_display(methodinfo *m)
1464 printflags(m->flags);
1466 utf_display(m->name);
1468 utf_display(m->descriptor);
1472 /************** Function: method_display_flags_last (debugging only) **************/
1474 void method_display_flags_last(methodinfo *m)
1477 utf_display(m->name);
1479 utf_display(m->descriptor);
1481 printflags(m->flags);
1486 /******************** Function: method_canoverwrite ****************************
1488 Check if m and old are identical with respect to type and name. This means
1489 that old can be overwritten with m.
1491 *******************************************************************************/
1493 static bool method_canoverwrite(methodinfo *m, methodinfo *old)
1495 if (m->name != old->name) return false;
1496 if (m->descriptor != old->descriptor) return false;
1497 if (m->flags & ACC_STATIC) return false;
1502 /******************************************************************************/
1503 /************************ Functions for class *********************************/
1504 /******************************************************************************/
1507 /******************** function:: class_getconstant *****************************
1509 retrieves the value at position 'pos' of the constantpool of a class
1510 if the type of the value is other than 'ctype' the system is stopped
1512 *******************************************************************************/
1514 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
1516 /* invalid position in constantpool */
1517 /* (pos == 0 is caught by type comparison) */
1518 if (pos >= c->cpcount)
1519 panic("Attempt to access constant outside range");
1521 /* check type of constantpool entry */
1523 if (c->cptags[pos] != ctype) {
1524 class_showconstantpool(c);
1525 error("Type mismatch on constant: %d requested, %d here (class_getconstant)",
1526 (int) ctype, (int) c->cptags[pos]);
1529 return c->cpinfos[pos];
1533 /********************* Function: class_constanttype ****************************
1535 Determines the type of a class entry in the ConstantPool
1537 *******************************************************************************/
1539 u4 class_constanttype(classinfo *c, u4 pos)
1541 if (pos >= c->cpcount)
1542 panic("Attempt to access constant outside range");
1544 return c->cptags[pos];
1548 /******************** function: class_loadcpool ********************************
1550 loads the constantpool of a class,
1551 the entries are transformed into a simpler format
1552 by resolving references
1553 (a detailed overview of the compact structures can be found in global.h)
1555 *******************************************************************************/
1557 static bool class_loadcpool(classbuffer *cb, classinfo *c)
1560 /* The following structures are used to save information which cannot be
1561 processed during the first pass. After the complete constantpool has
1562 been traversed the references can be resolved.
1563 (only in specific order) */
1565 /* CONSTANT_Class_info entries */
1566 typedef struct forward_class {
1567 struct forward_class *next;
1572 /* CONSTANT_String */
1573 typedef struct forward_string {
1574 struct forward_string *next;
1579 /* CONSTANT_NameAndType */
1580 typedef struct forward_nameandtype {
1581 struct forward_nameandtype *next;
1585 } forward_nameandtype;
1587 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
1588 typedef struct forward_fieldmethint {
1589 struct forward_fieldmethint *next;
1593 u2 nameandtype_index;
1594 } forward_fieldmethint;
1598 long int dumpsize = dump_size ();
1600 forward_class *forward_classes = NULL;
1601 forward_string *forward_strings = NULL;
1602 forward_nameandtype *forward_nameandtypes = NULL;
1603 forward_fieldmethint *forward_fieldmethints = NULL;
1609 /* number of entries in the constant_pool table plus one */
1610 if (!check_classbuffer_size(cb, 2))
1613 cpcount = c->cpcount = suck_u2(cb);
1615 /* allocate memory */
1616 cptags = c->cptags = MNEW(u1, cpcount);
1617 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
1620 panic("Invalid constant_pool_count (0)");
1622 #if defined(STATISTICS)
1624 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
1627 /* initialize constantpool */
1628 for (idx = 0; idx < cpcount; idx++) {
1629 cptags[idx] = CONSTANT_UNUSED;
1630 cpinfos[idx] = NULL;
1634 /******* first pass *******/
1635 /* entries which cannot be resolved now are written into
1636 temporary structures and traversed again later */
1639 while (idx < cpcount) {
1642 /* get constant type */
1643 if (!check_classbuffer_size(cb, 1))
1649 case CONSTANT_Class: {
1650 forward_class *nfc = DNEW(forward_class);
1652 nfc->next = forward_classes;
1653 forward_classes = nfc;
1655 nfc->thisindex = idx;
1656 /* reference to CONSTANT_NameAndType */
1657 if (!check_classbuffer_size(cb, 2))
1660 nfc->name_index = suck_u2(cb);
1666 case CONSTANT_Fieldref:
1667 case CONSTANT_Methodref:
1668 case CONSTANT_InterfaceMethodref: {
1669 forward_fieldmethint *nff = DNEW(forward_fieldmethint);
1671 nff->next = forward_fieldmethints;
1672 forward_fieldmethints = nff;
1674 nff->thisindex = idx;
1678 if (!check_classbuffer_size(cb, 2 + 2))
1681 /* class or interface type that contains the declaration of the
1683 nff->class_index = suck_u2(cb);
1685 /* name and descriptor of the field or method */
1686 nff->nameandtype_index = suck_u2(cb);
1692 case CONSTANT_String: {
1693 forward_string *nfs = DNEW(forward_string);
1695 nfs->next = forward_strings;
1696 forward_strings = nfs;
1698 nfs->thisindex = idx;
1700 /* reference to CONSTANT_Utf8_info with string characters */
1701 if (!check_classbuffer_size(cb, 2))
1704 nfs->string_index = suck_u2(cb);
1710 case CONSTANT_NameAndType: {
1711 forward_nameandtype *nfn = DNEW(forward_nameandtype);
1713 nfn->next = forward_nameandtypes;
1714 forward_nameandtypes = nfn;
1716 nfn->thisindex = idx;
1718 if (!check_classbuffer_size(cb, 2 + 2))
1721 /* reference to CONSTANT_Utf8_info containing simple name */
1722 nfn->name_index = suck_u2(cb);
1724 /* reference to CONSTANT_Utf8_info containing field or method
1726 nfn->sig_index = suck_u2(cb);
1732 case CONSTANT_Integer: {
1733 constant_integer *ci = NEW(constant_integer);
1735 #if defined(STATISTICS)
1737 count_const_pool_len += sizeof(constant_integer);
1740 if (!check_classbuffer_size(cb, 4))
1743 ci->value = suck_s4(cb);
1744 cptags[idx] = CONSTANT_Integer;
1751 case CONSTANT_Float: {
1752 constant_float *cf = NEW(constant_float);
1754 #if defined(STATISTICS)
1756 count_const_pool_len += sizeof(constant_float);
1759 if (!check_classbuffer_size(cb, 4))
1762 cf->value = suck_float(cb);
1763 cptags[idx] = CONSTANT_Float;
1770 case CONSTANT_Long: {
1771 constant_long *cl = NEW(constant_long);
1773 #if defined(STATISTICS)
1775 count_const_pool_len += sizeof(constant_long);
1778 if (!check_classbuffer_size(cb, 8))
1781 cl->value = suck_s8(cb);
1782 cptags[idx] = CONSTANT_Long;
1786 panic("Long constant exceeds constant pool");
1790 case CONSTANT_Double: {
1791 constant_double *cd = NEW(constant_double);
1793 #if defined(STATISTICS)
1795 count_const_pool_len += sizeof(constant_double);
1798 if (!check_classbuffer_size(cb, 8))
1801 cd->value = suck_double(cb);
1802 cptags[idx] = CONSTANT_Double;
1806 panic("Double constant exceeds constant pool");
1810 case CONSTANT_Utf8: {
1813 /* number of bytes in the bytes array (not string-length) */
1814 if (!check_classbuffer_size(cb, 2))
1817 length = suck_u2(cb);
1818 cptags[idx] = CONSTANT_Utf8;
1820 /* validate the string */
1821 if (!check_classbuffer_size(cb, length))
1825 !is_valid_utf(cb->pos + 1, cb->pos + 1 + length)) {
1826 dolog("Invalid UTF-8 string (constant pool index %d)",idx);
1827 panic("Invalid UTF-8 string");
1829 /* insert utf-string into the utf-symboltable */
1830 cpinfos[idx] = utf_new_intern(cb->pos + 1, length);
1832 /* skip bytes of the string (buffer size check above) */
1833 skip_nbytes(cb, length);
1839 error("Unkown constant type: %d",(int) t);
1844 /* resolve entries in temporary structures */
1846 while (forward_classes) {
1848 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
1850 if (opt_verify && !is_valid_name_utf(name))
1851 panic("Class reference with invalid name");
1853 cptags[forward_classes->thisindex] = CONSTANT_Class;
1854 /* retrieve class from class-table */
1857 tc = class_new_intern(name);
1859 if (!class_load(tc))
1862 /* link the class later, so we cannot link the currently loaded
1864 list_addfirst(&unlinkedclasses, tc);
1866 cpinfos[forward_classes->thisindex] = tc;
1869 cpinfos[forward_classes->thisindex] = class_new(name);
1872 forward_classes = forward_classes->next;
1875 while (forward_strings) {
1877 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
1879 /* resolve utf-string */
1880 cptags[forward_strings->thisindex] = CONSTANT_String;
1881 cpinfos[forward_strings->thisindex] = text;
1883 forward_strings = forward_strings->next;
1886 while (forward_nameandtypes) {
1887 constant_nameandtype *cn = NEW(constant_nameandtype);
1889 #if defined(STATISTICS)
1891 count_const_pool_len += sizeof(constant_nameandtype);
1894 /* resolve simple name and descriptor */
1895 cn->name = class_getconstant(c,
1896 forward_nameandtypes->name_index,
1899 cn->descriptor = class_getconstant(c,
1900 forward_nameandtypes->sig_index,
1905 if (!is_valid_name_utf(cn->name))
1906 panic("NameAndType with invalid name");
1907 /* disallow referencing <clinit> among others */
1908 if (cn->name->text[0] == '<' && cn->name != utf_init)
1909 panic("NameAndType with invalid special name");
1912 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
1913 cpinfos[forward_nameandtypes->thisindex] = cn;
1915 forward_nameandtypes = forward_nameandtypes->next;
1918 while (forward_fieldmethints) {
1919 constant_nameandtype *nat;
1920 constant_FMIref *fmi = NEW(constant_FMIref);
1922 #if defined(STATISTICS)
1924 count_const_pool_len += sizeof(constant_FMIref);
1926 /* resolve simple name and descriptor */
1927 nat = class_getconstant(c,
1928 forward_fieldmethints->nameandtype_index,
1929 CONSTANT_NameAndType);
1931 fmi->class = class_getconstant(c,
1932 forward_fieldmethints->class_index,
1934 fmi->name = nat->name;
1935 fmi->descriptor = nat->descriptor;
1937 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
1938 cpinfos[forward_fieldmethints->thisindex] = fmi;
1940 switch (forward_fieldmethints->tag) {
1941 case CONSTANT_Fieldref: /* check validity of descriptor */
1942 checkfielddescriptor(fmi->descriptor->text,
1943 utf_end(fmi->descriptor));
1945 case CONSTANT_InterfaceMethodref:
1946 case CONSTANT_Methodref: /* check validity of descriptor */
1947 checkmethoddescriptor(c, fmi->descriptor);
1951 forward_fieldmethints = forward_fieldmethints->next;
1954 dump_release(dumpsize);
1956 /* everything was ok */
1962 /********************** Function: class_load ***********************************
1964 Loads everything interesting about a class from the class file. The
1965 'classinfo' structure must have been allocated previously.
1967 The super class and the interfaces implemented by this class need not be
1968 loaded. The link is set later by the function 'class_link'.
1970 The loaded class is removed from the list 'unloadedclasses' and added to
1971 the list 'unlinkedclasses'.
1973 *******************************************************************************/
1975 classinfo *class_load_intern(classbuffer *cb);
1977 classinfo *class_load(classinfo *c)
1984 /* enter a monitor on the class */
1986 builtin_monitorenter((java_objectheader *) c);
1988 /* maybe the class is already loaded */
1990 builtin_monitorexit((java_objectheader *) c);
1997 starttime = getcputime();
1999 /* load classdata, throw exception on error */
2001 if ((cb = suck_start(c)) == NULL) {
2002 /* this means, the classpath was not set properly */
2003 if (c->name == utf_java_lang_Object)
2004 throw_cacao_exception_exit(string_java_lang_NoClassDefFoundError,
2005 "java/lang/Object");
2008 new_exception_utfmessage(string_java_lang_NoClassDefFoundError,
2011 builtin_monitorexit((java_objectheader *) c);
2016 /* call the internal function */
2017 r = class_load_intern(cb);
2019 /* if return value is NULL, we had a problem and the class is not loaded */
2023 /* now free the allocated memory, otherwise we could ran into a DOS */
2031 if (getloadingtime) {
2032 stoptime = getcputime();
2033 loadingtime += (stoptime - starttime);
2036 /* leave the monitor */
2038 builtin_monitorexit((java_objectheader *) c);
2044 classinfo *class_load_intern(classbuffer *cb)
2049 /* s4 classdata_left; */
2050 char msg[MAXLOGTEXT]; /* maybe we get an exception */
2052 /* get the classbuffer's class */
2055 /* maybe the class is already loaded */
2059 #if defined(STATISTICS)
2061 count_class_loads++;
2064 /* output for debugging purposes */
2066 log_message_class("Loading class: ", c);
2068 /* class is somewhat loaded */
2071 if (!check_classbuffer_size(cb, 4 + 2 + 2))
2074 /* check signature */
2075 if (suck_u4(cb) != MAGIC) {
2076 *exceptionptr = new_classformaterror(c, "Bad magic number");
2085 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
2087 new_classformaterror(c,
2088 "Unsupported major.minor version %d.%d",
2094 if (!class_loadcpool(cb, c))
2098 c->erroneous_state = 0;
2099 c->initializing_thread = 0;
2101 c->classUsed = NOTUSED; /* not used initially CO-RT */
2105 if (!check_classbuffer_size(cb, 2))
2108 c->flags = suck_u2(cb);
2109 /*if (!(c->flags & ACC_PUBLIC)) { log_text("CLASS NOT PUBLIC"); } JOWENN*/
2111 /* check ACC flags consistency */
2112 if (c->flags & ACC_INTERFACE) {
2113 if (!(c->flags & ACC_ABSTRACT)) {
2114 /* We work around this because interfaces in JDK 1.1 are
2115 * not declared abstract. */
2117 c->flags |= ACC_ABSTRACT;
2118 /* panic("Interface class not declared abstract"); */
2121 if (c->flags & ACC_FINAL) {
2123 new_classformaterror(c,
2124 "Illegal class modifiers: 0x%x", c->flags);
2129 if (c->flags & ACC_SUPER) {
2130 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
2134 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
2136 new_classformaterror(c, "Illegal class modifiers: 0x%x", c->flags);
2141 if (!check_classbuffer_size(cb, 2 + 2))
2146 if (class_getconstant(c, i, CONSTANT_Class) != c) {
2147 utf_sprint(msg, c->name);
2148 sprintf(msg + strlen(msg), " (wrong name: ");
2149 utf_sprint(msg + strlen(msg),
2150 ((classinfo *) class_getconstant(c, i, CONSTANT_Class))->name);
2151 sprintf(msg + strlen(msg), ")");
2154 new_exception_message(string_java_lang_NoClassDefFoundError, msg);
2159 /* retrieve superclass */
2160 if ((i = suck_u2(cb))) {
2161 c->super = class_getconstant(c, i, CONSTANT_Class);
2163 /* java.lang.Object may not have a super class. */
2164 if (c->name == utf_java_lang_Object) {
2166 new_exception_message(string_java_lang_ClassFormatError,
2167 "java.lang.Object with superclass");
2172 /* Interfaces must have java.lang.Object as super class. */
2173 if ((c->flags & ACC_INTERFACE) &&
2174 c->super->name != utf_java_lang_Object) {
2176 new_exception_message(string_java_lang_ClassFormatError,
2177 "Interfaces must have java.lang.Object as superclass");
2185 /* This is only allowed for java.lang.Object. */
2186 if (c->name != utf_java_lang_Object) {
2187 *exceptionptr = new_classformaterror(c, "Bad superclass index");
2194 /* retrieve interfaces */
2195 if (!check_classbuffer_size(cb, 2))
2198 c->interfacescount = suck_u2(cb);
2200 if (!check_classbuffer_size(cb, 2 * c->interfacescount))
2203 c->interfaces = MNEW(classinfo*, c->interfacescount);
2204 for (i = 0; i < c->interfacescount; i++) {
2205 c->interfaces[i] = class_getconstant(c, suck_u2(cb), CONSTANT_Class);
2209 if (!check_classbuffer_size(cb, 2))
2212 c->fieldscount = suck_u2(cb);
2213 c->fields = GCNEW(fieldinfo, c->fieldscount);
2214 /* c->fields = MNEW(fieldinfo, c->fieldscount); */
2215 for (i = 0; i < c->fieldscount; i++) {
2216 if (!field_load(cb, c, &(c->fields[i])))
2221 if (!check_classbuffer_size(cb, 2))
2224 c->methodscount = suck_u2(cb);
2225 c->methods = GCNEW(methodinfo, c->methodscount);
2226 /* c->methods = MNEW(methodinfo, c->methodscount); */
2227 for (i = 0; i < c->methodscount; i++) {
2228 if (!method_load(cb, c, &(c->methods[i])))
2232 /* Check if all fields and methods can be uniquely
2233 * identified by (name,descriptor). */
2235 /* We use a hash table here to avoid making the
2236 * average case quadratic in # of methods, fields.
2238 static int shift = 0;
2240 u2 *next; /* for chaining colliding hash entries */
2246 /* Allocate hashtable */
2247 len = c->methodscount;
2248 if (len < c->fieldscount) len = c->fieldscount;
2250 hashtab = MNEW(u2,(hashlen + len));
2251 next = hashtab + hashlen;
2253 /* Determine bitshift (to get good hash values) */
2263 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2265 for (i = 0; i < c->fieldscount; ++i) {
2266 fieldinfo *fi = c->fields + i;
2268 /* It's ok if we lose bits here */
2269 index = ((((size_t) fi->name) +
2270 ((size_t) fi->descriptor)) >> shift) % hashlen;
2272 if ((old = hashtab[index])) {
2276 if (c->fields[old].name == fi->name &&
2277 c->fields[old].descriptor == fi->descriptor) {
2279 new_classformaterror(c,
2280 "Repetitive field name/signature");
2284 } while ((old = next[old]));
2286 hashtab[index] = i + 1;
2290 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2292 for (i = 0; i < c->methodscount; ++i) {
2293 methodinfo *mi = c->methods + i;
2295 /* It's ok if we lose bits here */
2296 index = ((((size_t) mi->name) +
2297 ((size_t) mi->descriptor)) >> shift) % hashlen;
2299 if ((old = hashtab[index])) {
2303 if (c->methods[old].name == mi->name &&
2304 c->methods[old].descriptor == mi->descriptor) {
2306 new_classformaterror(c,
2307 "Repetitive method name/signature");
2311 } while ((old = next[old]));
2313 hashtab[index] = i + 1;
2316 MFREE(hashtab, u2, (hashlen + len));
2319 #if defined(STATISTICS)
2321 count_class_infos += sizeof(classinfo*) * c->interfacescount;
2322 count_class_infos += sizeof(fieldinfo) * c->fieldscount;
2323 count_class_infos += sizeof(methodinfo) * c->methodscount;
2327 /* load variable-length attribute structures */
2328 if (!check_classbuffer_size(cb, 2))
2331 if (!attribute_load(cb, c, suck_u2(cb)))
2335 /* XXX TWISTI is this still in the JVM spec? SUN and IBM don't complain about it */
2337 /* check if all data has been read */
2338 classdata_left = ((cb->data + cb->size) - cb->pos - 1);
2340 if (classdata_left > 0) {
2342 dolog("There are %d extra bytes at end of classfile", classdata_left);
2343 /* The JVM spec disallows extra bytes. */
2344 panic("Extra bytes at end of classfile");
2349 log_message_class("Loading done class: ", c);
2356 /************** internal Function: class_highestinterface **********************
2358 Used by the function class_link to determine the amount of memory needed
2359 for the interface table.
2361 *******************************************************************************/
2363 static s4 class_highestinterface(classinfo *c)
2368 if (!(c->flags & ACC_INTERFACE)) {
2369 char logtext[MAXLOGTEXT];
2370 sprintf(logtext, "Interface-methods count requested for non-interface: ");
2371 utf_sprint(logtext + strlen(logtext), c->name);
2372 error("%s",logtext);
2376 for (i = 0; i < c->interfacescount; i++) {
2377 s4 h2 = class_highestinterface(c->interfaces[i]);
2385 /* class_addinterface **********************************************************
2387 Is needed by class_link for adding a VTBL to a class. All interfaces
2388 implemented by ic are added as well.
2390 *******************************************************************************/
2392 static void class_addinterface(classinfo *c, classinfo *ic)
2396 vftbl_t *vftbl = c->vftbl;
2398 if (i >= vftbl->interfacetablelength)
2399 panic ("Inernal error: interfacetable overflow");
2401 if (vftbl->interfacetable[-i])
2404 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
2405 vftbl->interfacevftbllength[i] = 1;
2406 vftbl->interfacetable[-i] = MNEW(methodptr, 1);
2407 vftbl->interfacetable[-i][0] = NULL;
2410 vftbl->interfacevftbllength[i] = ic->methodscount;
2411 vftbl->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
2415 count_vftbl_len += sizeof(methodptr) *
2416 (ic->methodscount + (ic->methodscount == 0));
2419 for (j = 0; j < ic->methodscount; j++) {
2422 for (m = 0; m < sc->methodscount; m++) {
2423 methodinfo *mi = &(sc->methods[m]);
2424 if (method_canoverwrite(mi, &(ic->methods[j]))) {
2425 vftbl->interfacetable[-i][j] =
2426 vftbl->table[mi->vftblindex];
2437 for (j = 0; j < ic->interfacescount; j++)
2438 class_addinterface(c, ic->interfaces[j]);
2442 /******************* Function: class_new_array *********************************
2444 This function is called by class_new to setup an array class.
2446 *******************************************************************************/
2448 void class_new_array(classinfo *c)
2450 classinfo *comp = NULL;
2454 /* Check array class name */
2455 namelen = c->name->blength;
2456 if (namelen < 2 || c->name->text[0] != '[')
2457 panic("Invalid array class name");
2459 /* Check the component type */
2460 switch (c->name->text[1]) {
2462 /* c is an array of arrays. We have to create the component class. */
2464 comp = class_new_intern(utf_new_intern(c->name->text + 1,
2467 list_addfirst(&unlinkedclasses, comp);
2470 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2475 /* c is an array of objects. */
2476 if (namelen < 4 || c->name->text[namelen - 1] != ';')
2477 panic("Invalid array class name");
2480 comp = class_new_intern(utf_new_intern(c->name->text + 2,
2483 list_addfirst(&unlinkedclasses, comp);
2486 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2491 /* Setup the array class */
2492 c->super = class_java_lang_Object;
2493 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2495 c->interfacescount = 2;
2496 c->interfaces = MNEW(classinfo*, 2);
2501 tc = class_new_intern(utf_new_char("java/lang/Cloneable"));
2503 list_addfirst(&unlinkedclasses, tc);
2504 c->interfaces[0] = tc;
2506 tc = class_new_intern(utf_new_char("java/io/Serializable"));
2508 list_addfirst(&unlinkedclasses, tc);
2509 c->interfaces[1] = tc;
2512 c->interfaces[0] = class_new(utf_new_char("java/lang/Cloneable"));
2513 c->interfaces[1] = class_new(utf_new_char("java/io/Serializable"));
2516 c->methodscount = 1;
2517 c->methods = MNEW(methodinfo, c->methodscount);
2520 memset(clone, 0, sizeof(methodinfo));
2521 clone->flags = ACC_PUBLIC;
2522 clone->name = utf_new_char("clone");
2523 clone->descriptor = utf_new_char("()Ljava/lang/Object;");
2525 clone->stubroutine = createnativestub((functionptr) &builtin_clone_array, clone);
2526 clone->monoPoly = MONO;
2528 /* XXX: field: length? */
2530 /* array classes are not loaded from class files */
2535 /****************** Function: class_link_array *********************************
2537 This function is called by class_link to create the
2538 arraydescriptor for an array class.
2540 This function returns NULL if the array cannot be linked because
2541 the component type has not been linked yet.
2543 *******************************************************************************/
2545 static arraydescriptor *class_link_array(classinfo *c)
2547 classinfo *comp = NULL;
2548 s4 namelen = c->name->blength;
2549 arraydescriptor *desc;
2552 /* Check the component type */
2553 switch (c->name->text[1]) {
2555 /* c is an array of arrays. */
2556 /* comp = class_get(utf_new_intern(c->name->text + 1, namelen - 1)); */
2557 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2559 panic("Could not find component array class.");
2563 /* c is an array of objects. */
2564 /* comp = class_get(utf_new_intern(c->name->text + 2, namelen - 3)); */
2565 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2567 panic("Could not find component class.");
2571 /* If the component type has not been linked, link it now */
2572 if (comp && !comp->linked) {
2578 /* Allocate the arraydescriptor */
2579 desc = NEW(arraydescriptor);
2582 /* c is an array of references */
2583 desc->arraytype = ARRAYTYPE_OBJECT;
2584 desc->componentsize = sizeof(void*);
2585 desc->dataoffset = OFFSET(java_objectarray, data);
2587 compvftbl = comp->vftbl;
2589 panic("Component class has no vftbl");
2590 desc->componentvftbl = compvftbl;
2592 if (compvftbl->arraydesc) {
2593 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
2594 if (compvftbl->arraydesc->dimension >= 255)
2595 panic("Creating array of dimension >255");
2596 desc->dimension = compvftbl->arraydesc->dimension + 1;
2597 desc->elementtype = compvftbl->arraydesc->elementtype;
2600 desc->elementvftbl = compvftbl;
2601 desc->dimension = 1;
2602 desc->elementtype = ARRAYTYPE_OBJECT;
2606 /* c is an array of a primitive type */
2607 switch (c->name->text[1]) {
2609 desc->arraytype = ARRAYTYPE_BOOLEAN;
2610 desc->dataoffset = OFFSET(java_booleanarray,data);
2611 desc->componentsize = sizeof(u1);
2615 desc->arraytype = ARRAYTYPE_BYTE;
2616 desc->dataoffset = OFFSET(java_bytearray,data);
2617 desc->componentsize = sizeof(u1);
2621 desc->arraytype = ARRAYTYPE_CHAR;
2622 desc->dataoffset = OFFSET(java_chararray,data);
2623 desc->componentsize = sizeof(u2);
2627 desc->arraytype = ARRAYTYPE_DOUBLE;
2628 desc->dataoffset = OFFSET(java_doublearray,data);
2629 desc->componentsize = sizeof(double);
2633 desc->arraytype = ARRAYTYPE_FLOAT;
2634 desc->dataoffset = OFFSET(java_floatarray,data);
2635 desc->componentsize = sizeof(float);
2639 desc->arraytype = ARRAYTYPE_INT;
2640 desc->dataoffset = OFFSET(java_intarray,data);
2641 desc->componentsize = sizeof(s4);
2645 desc->arraytype = ARRAYTYPE_LONG;
2646 desc->dataoffset = OFFSET(java_longarray,data);
2647 desc->componentsize = sizeof(s8);
2651 desc->arraytype = ARRAYTYPE_SHORT;
2652 desc->dataoffset = OFFSET(java_shortarray,data);
2653 desc->componentsize = sizeof(s2);
2657 panic("Invalid array class name");
2660 desc->componentvftbl = NULL;
2661 desc->elementvftbl = NULL;
2662 desc->dimension = 1;
2663 desc->elementtype = desc->arraytype;
2670 /********************** Function: class_link ***********************************
2672 Tries to link a class. The function calculates the length in bytes that
2673 an instance of this class requires as well as the VTBL for methods and
2676 *******************************************************************************/
2678 static classinfo *class_link_intern(classinfo *c);
2680 classinfo *class_link(classinfo *c)
2686 /* enter a monitor on the class */
2688 builtin_monitorenter((java_objectheader *) c);
2690 /* maybe the class is already linked */
2692 builtin_monitorexit((java_objectheader *) c);
2699 starttime = getcputime();
2701 /* call the internal function */
2702 r = class_link_intern(c);
2704 /* if return value is NULL, we had a problem and the class is not linked */
2709 if (getloadingtime) {
2710 stoptime = getcputime();
2711 loadingtime += (stoptime - starttime);
2714 /* leave the monitor */
2716 builtin_monitorexit((java_objectheader *) c);
2722 static classinfo *class_link_intern(classinfo *c)
2724 s4 supervftbllength; /* vftbllegnth of super class */
2725 s4 vftbllength; /* vftbllength of current class */
2726 s4 interfacetablelength; /* interface table length */
2727 classinfo *super = c->super; /* super class */
2728 classinfo *ic, *c2; /* intermediate class variables */
2729 vftbl_t *v; /* vftbl of current class */
2730 s4 i; /* interface/method/field counter */
2731 arraydescriptor *arraydesc = NULL; /* descriptor for array classes */
2733 /* maybe the class is already linked */
2738 log_message_class("Linking class: ", c);
2740 /* ok, this class is somewhat linked */
2743 /* check interfaces */
2745 for (i = 0; i < c->interfacescount; i++) {
2746 ic = c->interfaces[i];
2748 /* detect circularity */
2751 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2758 if (!class_load(ic))
2762 if (!class_link(ic))
2765 if (!(ic->flags & ACC_INTERFACE)) {
2766 dolog("Specified interface is not declared as interface:");
2770 panic("Specified interface is not declared as interface");
2774 /* check super class */
2776 if (super == NULL) { /* class java.lang.Object */
2778 c->classUsed = USED; /* Object class is always used CO-RT*/
2780 c->instancesize = sizeof(java_objectheader);
2782 vftbllength = supervftbllength = 0;
2784 c->finalizer = NULL;
2787 /* detect circularity */
2790 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2797 if (!class_load(super))
2801 if (!class_link(super))
2804 if (super->flags & ACC_INTERFACE)
2805 panic("Interface specified as super class");
2807 /* handle array classes */
2808 /* The component class must have been linked already. */
2809 if (c->name->text[0] == '[') {
2810 if ((arraydesc = class_link_array(c)) == NULL) {
2811 panic("class_link: class_link_array");
2815 /* Don't allow extending final classes */
2816 if (super->flags & ACC_FINAL)
2817 panic("Trying to extend final class");
2819 if (c->flags & ACC_INTERFACE)
2820 c->index = interfaceindex++;
2822 c->index = super->index + 1;
2824 c->instancesize = super->instancesize;
2826 vftbllength = supervftbllength = super->vftbl->vftbllength;
2828 c->finalizer = super->finalizer;
2831 /* compute vftbl length */
2833 for (i = 0; i < c->methodscount; i++) {
2834 methodinfo *m = &(c->methods[i]);
2836 if (!(m->flags & ACC_STATIC)) { /* is instance method */
2837 classinfo *sc = super;
2840 for (j = 0; j < sc->methodscount; j++) {
2841 if (method_canoverwrite(m, &(sc->methods[j]))) {
2842 if ((sc->methods[j].flags & ACC_PRIVATE) != 0)
2843 goto notfoundvftblindex;
2845 if ((sc->methods[j].flags & ACC_FINAL) != 0) {
2848 log_utf(sc->methods[j].name);
2849 log_utf(sc->methods[j].descriptor);
2850 panic("Trying to overwrite final method");
2852 m->vftblindex = sc->methods[j].vftblindex;
2853 goto foundvftblindex;
2859 m->vftblindex = (vftbllength++);
2865 #if defined(STATISTICS)
2868 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
2871 /* compute interfacetable length */
2873 interfacetablelength = 0;
2876 for (i = 0; i < c2->interfacescount; i++) {
2877 s4 h = class_highestinterface(c2->interfaces[i]) + 1;
2878 if (h > interfacetablelength)
2879 interfacetablelength = h;
2884 /* allocate virtual function table */
2886 v = (vftbl_t*) mem_alloc(sizeof(vftbl_t) + sizeof(methodptr) *
2887 (vftbllength - 1) + sizeof(methodptr*) *
2888 (interfacetablelength - (interfacetablelength > 0)));
2889 v = (vftbl_t*) (((methodptr*) v) + (interfacetablelength - 1) *
2890 (interfacetablelength > 1));
2891 c->header.vftbl = c->vftbl = v;
2892 /* utf_display_classname(c->name);printf(", c->header.vftbl=%p\n", c->header.vftbl); */
2894 v->vftbllength = vftbllength;
2895 v->interfacetablelength = interfacetablelength;
2896 v->arraydesc = arraydesc;
2898 /* store interface index in vftbl */
2899 if (c->flags & ACC_INTERFACE)
2900 v->baseval = -(c->index);
2902 /* copy virtual function table of super class */
2904 for (i = 0; i < supervftbllength; i++)
2905 v->table[i] = super->vftbl->table[i];
2907 /* add method stubs into virtual function table */
2909 for (i = 0; i < c->methodscount; i++) {
2910 methodinfo *m = &(c->methods[i]);
2911 if (!(m->flags & ACC_STATIC)) {
2912 v->table[m->vftblindex] = m->stubroutine;
2916 /* compute instance size and offset of each field */
2918 for (i = 0; i < c->fieldscount; i++) {
2920 fieldinfo *f = &(c->fields[i]);
2922 if (!(f->flags & ACC_STATIC)) {
2923 dsize = desc_typesize(f->descriptor);
2924 c->instancesize = ALIGN(c->instancesize, dsize);
2925 f->offset = c->instancesize;
2926 c->instancesize += dsize;
2930 /* initialize interfacetable and interfacevftbllength */
2932 v->interfacevftbllength = MNEW(s4, interfacetablelength);
2934 #if defined(STATISTICS)
2936 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
2939 for (i = 0; i < interfacetablelength; i++) {
2940 v->interfacevftbllength[i] = 0;
2941 v->interfacetable[-i] = NULL;
2944 /* add interfaces */
2946 for (c2 = c; c2 != NULL; c2 = c2->super)
2947 for (i = 0; i < c2->interfacescount; i++) {
2948 class_addinterface(c, c2->interfaces[i]);
2951 /* add finalizer method (not for java.lang.Object) */
2953 if (super != NULL) {
2955 static utf *finame = NULL;
2956 static utf *fidesc = NULL;
2959 finame = utf_finalize;
2961 fidesc = utf_fidesc;
2963 fi = class_findmethod(c, finame, fidesc);
2965 if (!(fi->flags & ACC_STATIC)) {
2973 loader_compute_subclasses(c);
2976 log_message_class("Linking done class: ", c);
2978 /* just return c to show that we didn't had a problem */
2984 /******************* Function: class_freepool **********************************
2986 Frees all resources used by this classes Constant Pool.
2988 *******************************************************************************/
2990 static void class_freecpool(classinfo *c)
2996 if (c->cptags && c->cpinfos) {
2997 for (idx = 0; idx < c->cpcount; idx++) {
2998 tag = c->cptags[idx];
2999 info = c->cpinfos[idx];
3003 case CONSTANT_Fieldref:
3004 case CONSTANT_Methodref:
3005 case CONSTANT_InterfaceMethodref:
3006 FREE(info, constant_FMIref);
3008 case CONSTANT_Integer:
3009 FREE(info, constant_integer);
3011 case CONSTANT_Float:
3012 FREE(info, constant_float);
3015 FREE(info, constant_long);
3017 case CONSTANT_Double:
3018 FREE(info, constant_double);
3020 case CONSTANT_NameAndType:
3021 FREE(info, constant_nameandtype);
3029 MFREE(c->cptags, u1, c->cpcount);
3032 MFREE(c->cpinfos, voidptr, c->cpcount);
3036 /*********************** Function: class_free **********************************
3038 Frees all resources used by the class.
3040 *******************************************************************************/
3042 void class_free(classinfo *c)
3050 MFREE(c->interfaces, classinfo*, c->interfacescount);
3053 for (i = 0; i < c->fieldscount; i++)
3054 field_free(&(c->fields[i]));
3055 /* MFREE(c->fields, fieldinfo, c->fieldscount); */
3059 for (i = 0; i < c->methodscount; i++)
3060 method_free(&(c->methods[i]));
3061 /* MFREE(c->methods, methodinfo, c->methodscount); */
3064 if ((v = c->vftbl) != NULL) {
3066 mem_free(v->arraydesc,sizeof(arraydescriptor));
3068 for (i = 0; i < v->interfacetablelength; i++) {
3069 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
3071 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
3073 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
3074 sizeof(methodptr*) * (v->interfacetablelength -
3075 (v->interfacetablelength > 0));
3076 v = (vftbl_t*) (((methodptr*) v) - (v->interfacetablelength - 1) *
3077 (v->interfacetablelength > 1));
3082 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
3084 /* if (c->classvftbl)
3085 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
3091 /************************* Function: class_findfield ***************************
3093 Searches a 'classinfo' structure for a field having the given name and
3096 *******************************************************************************/
3098 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
3102 for (i = 0; i < c->fieldscount; i++) {
3103 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
3104 return &(c->fields[i]);
3107 panic("Can not find field given in CONSTANT_Fieldref");
3109 /* keep compiler happy */
3114 /****************** Function: class_resolvefield_int ***************************
3116 This is an internally used helper function. Do not use this directly.
3118 Tries to resolve a field having the given name and type.
3119 If the field cannot be resolved, NULL is returned.
3121 *******************************************************************************/
3123 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
3128 /* search for field in class c */
3129 for (i = 0; i < c->fieldscount; i++) {
3130 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
3131 return &(c->fields[i]);
3135 /* try superinterfaces recursively */
3136 for (i = 0; i < c->interfacescount; ++i) {
3137 fi = class_resolvefield_int(c->interfaces[i], name, desc);
3142 /* try superclass */
3144 return class_resolvefield_int(c->super, name, desc);
3151 /********************* Function: class_resolvefield ***************************
3153 Resolves a reference from REFERER to a field with NAME and DESC in class C.
3155 If the field cannot be resolved the return value is NULL. If EXCEPT is
3156 true *exceptionptr is set, too.
3158 *******************************************************************************/
3160 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
3161 classinfo *referer, bool except)
3165 /* XXX resolve class c */
3166 /* XXX check access from REFERER to C */
3168 fi = class_resolvefield_int(c, name, desc);
3173 new_exception_utfmessage(string_java_lang_NoSuchFieldError,
3179 /* XXX check access rights */
3185 /************************* Function: class_findmethod **************************
3187 Searches a 'classinfo' structure for a method having the given name and
3188 type and returns the index in the class info structure.
3189 If type is NULL, it is ignored.
3191 *******************************************************************************/
3193 s4 class_findmethodIndex(classinfo *c, utf *name, utf *desc)
3197 for (i = 0; i < c->methodscount; i++) {
3199 /* utf_display_classname(c->name);printf("."); */
3200 /* utf_display(c->methods[i].name);printf("."); */
3201 /* utf_display(c->methods[i].descriptor); */
3204 if ((c->methods[i].name == name) && ((desc == NULL) ||
3205 (c->methods[i].descriptor == desc))) {
3214 /************************* Function: class_findmethod **************************
3216 Searches a 'classinfo' structure for a method having the given name and
3218 If type is NULL, it is ignored.
3220 *******************************************************************************/
3222 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
3224 s4 idx = class_findmethodIndex(c, name, desc);
3229 return &(c->methods[idx]);
3233 /*********************** Function: class_fetchmethod **************************
3235 like class_findmethod, but aborts with an error if the method is not found
3237 *******************************************************************************/
3239 methodinfo *class_fetchmethod(classinfo *c, utf *name, utf *desc)
3243 mi = class_findmethod(c, name, desc);
3246 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3247 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3248 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3249 panic("Method not found");
3256 /*********************** Function: class_findmethod_w**************************
3258 like class_findmethod, but logs a warning if the method is not found
3260 *******************************************************************************/
3262 methodinfo *class_findmethod_w(classinfo *c, utf *name, utf *desc, char *from)
3265 mi = class_findmethod(c, name, desc);
3268 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3269 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3270 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3272 if ( c->flags & ACC_PUBLIC ) log_plain(" PUBLIC ");
3273 if ( c->flags & ACC_PRIVATE ) log_plain(" PRIVATE ");
3274 if ( c->flags & ACC_PROTECTED ) log_plain(" PROTECTED ");
3275 if ( c->flags & ACC_STATIC ) log_plain(" STATIC ");
3276 if ( c->flags & ACC_FINAL ) log_plain(" FINAL ");
3277 if ( c->flags & ACC_SYNCHRONIZED ) log_plain(" SYNCHRONIZED ");
3278 if ( c->flags & ACC_VOLATILE ) log_plain(" VOLATILE ");
3279 if ( c->flags & ACC_TRANSIENT ) log_plain(" TRANSIENT ");
3280 if ( c->flags & ACC_NATIVE ) log_plain(" NATIVE ");
3281 if ( c->flags & ACC_INTERFACE ) log_plain(" INTERFACE ");
3282 if ( c->flags & ACC_ABSTRACT ) log_plain(" ABSTRACT ");
3285 log_plain(" : WARNING: Method not found");log_nl( );
3292 /************************* Function: class_findmethod_approx ******************
3294 like class_findmethod but ignores the return value when comparing the
3297 *******************************************************************************/
3299 methodinfo *class_findmethod_approx(classinfo *c, utf *name, utf *desc)
3303 for (i = 0; i < c->methodscount; i++) {
3304 if (c->methods[i].name == name) {
3305 utf *meth_descr = c->methods[i].descriptor;
3309 return &(c->methods[i]);
3311 if (desc->blength <= meth_descr->blength) {
3312 /* current position in utf text */
3313 char *desc_utf_ptr = desc->text;
3314 char *meth_utf_ptr = meth_descr->text;
3315 /* points behind utf strings */
3316 char *desc_end = utf_end(desc);
3317 char *meth_end = utf_end(meth_descr);
3320 /* compare argument types */
3321 while (desc_utf_ptr < desc_end && meth_utf_ptr < meth_end) {
3323 if ((ch = *desc_utf_ptr++) != (*meth_utf_ptr++))
3324 break; /* no match */
3327 return &(c->methods[i]); /* all parameter types equal */
3337 /***************** Function: class_resolvemethod_approx ***********************
3339 Searches a class and every super class for a method (without paying
3340 attention to the return value)
3342 *******************************************************************************/
3344 methodinfo *class_resolvemethod_approx(classinfo *c, utf *name, utf *desc)
3347 /* search for method (ignore returntype) */
3348 methodinfo *m = class_findmethod_approx(c, name, desc);
3351 /* search superclass */
3359 /************************* Function: class_resolvemethod ***********************
3361 Searches a class and every super class for a method.
3363 *******************************************************************************/
3365 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
3367 /*log_text("Trying to resolve a method");
3368 utf_display(c->name);
3370 utf_display(desc);*/
3373 /*log_text("Looking in:");
3374 utf_display(c->name);*/
3375 methodinfo *m = class_findmethod(c, name, desc);
3377 /* search superclass */
3380 /*log_text("method not found:");*/
3386 /****************** Function: class_resolveinterfacemethod_int ****************
3388 Internally used helper function. Do not use this directly.
3390 *******************************************************************************/
3393 methodinfo *class_resolveinterfacemethod_int(classinfo *c, utf *name, utf *desc)
3398 mi = class_findmethod(c,name,desc);
3402 /* try the superinterfaces */
3403 for (i=0; i<c->interfacescount; ++i) {
3404 mi = class_resolveinterfacemethod_int(c->interfaces[i],name,desc);
3412 /******************** Function: class_resolveinterfacemethod ******************
3414 Resolves a reference from REFERER to a method with NAME and DESC in
3417 If the method cannot be resolved the return value is NULL. If EXCEPT is
3418 true *exceptionptr is set, too.
3420 *******************************************************************************/
3422 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
3423 classinfo *referer, bool except)
3427 /* XXX resolve class c */
3428 /* XXX check access from REFERER to C */
3430 if (!(c->flags & ACC_INTERFACE)) {
3433 new_exception(string_java_lang_IncompatibleClassChangeError);
3438 mi = class_resolveinterfacemethod_int(c, name, desc);
3443 /* try class java.lang.Object */
3444 mi = class_findmethod(class_java_lang_Object, name, desc);
3451 new_exception_utfmessage(string_java_lang_NoSuchMethodError, name);
3457 /********************* Function: class_resolveclassmethod *********************
3459 Resolves a reference from REFERER to a method with NAME and DESC in
3462 If the method cannot be resolved the return value is NULL. If EXCEPT is
3463 true *exceptionptr is set, too.
3465 *******************************************************************************/
3467 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
3468 classinfo *referer, bool except)
3473 char msg[MAXLOGTEXT];
3475 /* XXX resolve class c */
3476 /* XXX check access from REFERER to C */
3478 /* if (c->flags & ACC_INTERFACE) { */
3480 /* *exceptionptr = */
3481 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
3485 /* try class c and its superclasses */
3488 mi = class_findmethod(cls, name, desc);
3491 } while ((cls = cls->super) != NULL); /* try the superclass */
3493 /* try the superinterfaces */
3494 for (i = 0; i < c->interfacescount; ++i) {
3495 mi = class_resolveinterfacemethod_int(c->interfaces[i], name, desc);
3501 utf_sprint(msg, c->name);
3502 sprintf(msg + strlen(msg), ".");
3503 utf_sprint(msg + strlen(msg), name);
3504 utf_sprint(msg + strlen(msg), desc);
3507 new_exception_message(string_java_lang_NoSuchMethodError, msg);
3513 if ((mi->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
3515 *exceptionptr = new_exception(string_java_lang_AbstractMethodError);
3520 /* XXX check access rights */
3526 /************************* Function: class_issubclass **************************
3528 Checks if sub is a descendant of super.
3530 *******************************************************************************/
3532 bool class_issubclass(classinfo *sub, classinfo *super)
3535 if (!sub) return false;
3536 if (sub == super) return true;
3542 /****************** Initialization function for classes ******************
3544 In Java, every class can have a static initialization function. This
3545 function has to be called BEFORE calling other methods or accessing static
3548 *******************************************************************************/
3550 static classinfo *class_init_intern(classinfo *c);
3552 classinfo *class_init(classinfo *c)
3556 if (!makeinitializations)
3559 /* enter a monitor on the class */
3561 builtin_monitorenter((java_objectheader *) c);
3563 /* maybe the class is already initalized or the current thread, which can
3564 pass the monitor, is currently initalizing this class */
3566 if (c->initialized || c->initializing) {
3567 builtin_monitorexit((java_objectheader *) c);
3572 /* this initalizing run begins NOW */
3573 c->initializing = true;
3575 /* call the internal function */
3576 r = class_init_intern(c);
3578 /* if return value is not NULL everything was ok and the class is
3581 c->initialized = true;
3583 /* this initalizing run is done */
3584 c->initializing = false;
3586 /* leave the monitor */
3588 builtin_monitorexit((java_objectheader *) c);
3594 /* this function MUST NOT be called directly, because of thread <clinit>
3597 static classinfo *class_init_intern(classinfo *c)
3601 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3613 #if defined(STATISTICS)
3615 count_class_inits++;
3618 /* initialize super class */
3620 if (!c->super->loaded)
3621 if (!class_load(c->super))
3624 if (!c->super->linked)
3625 if (!class_link(c->super))
3628 if (!c->super->initialized) {
3630 char logtext[MAXLOGTEXT];
3631 sprintf(logtext, "Initialize super class ");
3632 utf_sprint_classname(logtext + strlen(logtext), c->super->name);
3633 sprintf(logtext + strlen(logtext), " from ");
3634 utf_sprint_classname(logtext + strlen(logtext), c->name);
3638 if (!class_init(c->super))
3643 /* initialize interface classes */
3644 for (i = 0; i < c->interfacescount; i++) {
3645 if (!c->interfaces[i]->loaded)
3646 if (!class_load(c->interfaces[i]))
3649 if (!c->interfaces[i]->linked)
3650 if (!class_link(c->interfaces[i]))
3653 if (!c->interfaces[i]->initialized) {
3655 char logtext[MAXLOGTEXT];
3656 sprintf(logtext, "Initialize interface class ");
3657 utf_sprint_classname(logtext + strlen(logtext), c->interfaces[i]->name);
3658 sprintf(logtext + strlen(logtext), " from ");
3659 utf_sprint_classname(logtext + strlen(logtext), c->name);
3663 if (!class_init(c->interfaces[i]))
3668 m = class_findmethod(c, utf_clinit, utf_fidesc);
3672 char logtext[MAXLOGTEXT];
3673 sprintf(logtext, "Class ");
3674 utf_sprint_classname(logtext + strlen(logtext), c->name);
3675 sprintf(logtext + strlen(logtext), " has no static class initializer");
3682 if (!(m->flags & ACC_STATIC))
3683 panic("Class initializer is not static!");
3686 log_message_class("Starting static class initializer for class: ", c);
3688 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3693 /* now call the initializer */
3694 asm_calljavafunction(m, NULL, NULL, NULL, NULL);
3696 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3697 assert(blockInts == 0);
3701 /* we have an exception or error */
3702 if (*exceptionptr) {
3703 /* is this an exception, than wrap it */
3704 if (builtin_instanceof(*exceptionptr, class_java_lang_Exception)) {
3705 java_objectheader *xptr;
3706 java_objectheader *cause;
3708 /* class is NOT initialized */
3709 c->initialized = false;
3712 cause = *exceptionptr;
3714 /* clear exception, because we are calling jit code again */
3715 *exceptionptr = NULL;
3717 /* wrap the exception */
3719 new_exception_throwable(string_java_lang_ExceptionInInitializerError,
3720 (java_lang_Throwable *) cause);
3722 /* XXX should we exit here? */
3726 /* set new exception */
3727 *exceptionptr = xptr;
3734 log_message_class("Finished static class initializer for class: ", c);
3740 /********* Function: find_class_method_constant *********/
3742 int find_class_method_constant (classinfo *c, utf * c1, utf* m1, utf* d1)
3747 for (i=0; i<c->cpcount; i++) {
3749 e = c -> cpinfos [i];
3752 switch (c -> cptags [i]) {
3753 case CONSTANT_Methodref:
3755 constant_FMIref *fmi = e;
3756 if ( (fmi->class->name == c1)
3757 && (fmi->name == m1)
3758 && (fmi->descriptor == d1)) {
3765 case CONSTANT_InterfaceMethodref:
3767 constant_FMIref *fmi = e;
3768 if ( (fmi->class->name == c1)
3769 && (fmi->name == m1)
3770 && (fmi->descriptor == d1)) {
3784 void class_showconstanti(classinfo *c, int ii)
3790 printf ("#%d: ", (int) i);
3792 switch (c->cptags [i]) {
3793 case CONSTANT_Class:
3794 printf("Classreference -> ");
3795 utf_display(((classinfo*)e)->name);
3798 case CONSTANT_Fieldref:
3799 printf("Fieldref -> "); goto displayFMIi;
3800 case CONSTANT_Methodref:
3801 printf("Methodref -> "); goto displayFMIi;
3802 case CONSTANT_InterfaceMethodref:
3803 printf("InterfaceMethod -> "); goto displayFMIi;
3806 constant_FMIref *fmi = e;
3807 utf_display(fmi->class->name);
3809 utf_display(fmi->name);
3811 utf_display(fmi->descriptor);
3815 case CONSTANT_String:
3816 printf("String -> ");
3819 case CONSTANT_Integer:
3820 printf("Integer -> %d", (int) (((constant_integer*)e)->value));
3822 case CONSTANT_Float:
3823 printf("Float -> %f", ((constant_float*)e)->value);
3825 case CONSTANT_Double:
3826 printf("Double -> %f", ((constant_double*)e)->value);
3830 u8 v = ((constant_long*)e)->value;
3832 printf("Long -> %ld", (long int) v);
3834 printf("Long -> HI: %ld, LO: %ld\n",
3835 (long int) v.high, (long int) v.low);
3839 case CONSTANT_NameAndType:
3841 constant_nameandtype *cnt = e;
3842 printf("NameAndType: ");
3843 utf_display(cnt->name);
3845 utf_display(cnt->descriptor);
3853 panic("Invalid type of ConstantPool-Entry");
3860 void class_showconstantpool (classinfo *c)
3865 printf ("---- dump of constant pool ----\n");
3867 for (i=0; i<c->cpcount; i++) {
3868 printf ("#%d: ", (int) i);
3870 e = c -> cpinfos [i];
3873 switch (c -> cptags [i]) {
3874 case CONSTANT_Class:
3875 printf ("Classreference -> ");
3876 utf_display ( ((classinfo*)e) -> name );
3879 case CONSTANT_Fieldref:
3880 printf ("Fieldref -> "); goto displayFMI;
3881 case CONSTANT_Methodref:
3882 printf ("Methodref -> "); goto displayFMI;
3883 case CONSTANT_InterfaceMethodref:
3884 printf ("InterfaceMethod -> "); goto displayFMI;
3887 constant_FMIref *fmi = e;
3888 utf_display ( fmi->class->name );
3890 utf_display ( fmi->name);
3892 utf_display ( fmi->descriptor );
3896 case CONSTANT_String:
3897 printf ("String -> ");
3900 case CONSTANT_Integer:
3901 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
3903 case CONSTANT_Float:
3904 printf ("Float -> %f", ((constant_float*)e) -> value);
3906 case CONSTANT_Double:
3907 printf ("Double -> %f", ((constant_double*)e) -> value);
3911 u8 v = ((constant_long*)e) -> value;
3913 printf ("Long -> %ld", (long int) v);
3915 printf ("Long -> HI: %ld, LO: %ld\n",
3916 (long int) v.high, (long int) v.low);
3920 case CONSTANT_NameAndType:
3922 constant_nameandtype *cnt = e;
3923 printf ("NameAndType: ");
3924 utf_display (cnt->name);
3926 utf_display (cnt->descriptor);
3930 printf ("Utf8 -> ");
3934 panic ("Invalid type of ConstantPool-Entry");
3944 /********** Function: class_showmethods (debugging only) *************/
3946 void class_showmethods (classinfo *c)
3950 printf ("--------- Fields and Methods ----------------\n");
3951 printf ("Flags: "); printflags (c->flags); printf ("\n");
3953 printf ("This: "); utf_display (c->name); printf ("\n");
3955 printf ("Super: "); utf_display (c->super->name); printf ("\n");
3957 printf ("Index: %d\n", c->index);
3959 printf ("interfaces:\n");
3960 for (i=0; i < c-> interfacescount; i++) {
3962 utf_display (c -> interfaces[i] -> name);
3963 printf (" (%d)\n", c->interfaces[i] -> index);
3966 printf ("fields:\n");
3967 for (i=0; i < c -> fieldscount; i++) {
3968 field_display (&(c -> fields[i]));
3971 printf ("methods:\n");
3972 for (i=0; i < c -> methodscount; i++) {
3973 methodinfo *m = &(c->methods[i]);
3974 if ( !(m->flags & ACC_STATIC))
3975 printf ("vftblindex: %d ", m->vftblindex);
3977 method_display ( m );
3981 printf ("Virtual function table:\n");
3982 for (i=0; i<c->vftbl->vftbllength; i++) {
3983 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]) );
3989 /******************************************************************************/
3990 /******************* General functions for the class loader *******************/
3991 /******************************************************************************/
3993 /**************** function: create_primitive_classes ***************************
3995 create classes representing primitive types
3997 *******************************************************************************/
3999 void create_primitive_classes()
4003 for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
4004 /* create primitive class */
4006 class_new_intern(utf_new_char(primitivetype_table[i].name));
4007 c->classUsed = NOTUSED; /* not used initially CO-RT */
4010 /* prevent loader from loading primitive class */
4014 primitivetype_table[i].class_primitive = c;
4016 /* create class for wrapping the primitive type */
4017 c = class_new_intern(utf_new_char(primitivetype_table[i].wrapname));
4018 primitivetype_table[i].class_wrap = c;
4019 primitivetype_table[i].class_wrap->classUsed = NOTUSED; /* not used initially CO-RT */
4020 primitivetype_table[i].class_wrap->impldBy = NULL;
4022 /* create the primitive array class */
4023 if (primitivetype_table[i].arrayname) {
4024 c = class_new_intern(utf_new_char(primitivetype_table[i].arrayname));
4025 primitivetype_table[i].arrayclass = c;
4029 primitivetype_table[i].arrayvftbl = c->vftbl;
4035 /**************** function: class_primitive_from_sig ***************************
4037 return the primitive class indicated by the given signature character
4039 If the descriptor does not indicate a valid primitive type the
4040 return value is NULL.
4042 ********************************************************************************/
4044 classinfo *class_primitive_from_sig(char sig)
4047 case 'I': return primitivetype_table[PRIMITIVETYPE_INT].class_primitive;
4048 case 'J': return primitivetype_table[PRIMITIVETYPE_LONG].class_primitive;
4049 case 'F': return primitivetype_table[PRIMITIVETYPE_FLOAT].class_primitive;
4050 case 'D': return primitivetype_table[PRIMITIVETYPE_DOUBLE].class_primitive;
4051 case 'B': return primitivetype_table[PRIMITIVETYPE_BYTE].class_primitive;
4052 case 'C': return primitivetype_table[PRIMITIVETYPE_CHAR].class_primitive;
4053 case 'S': return primitivetype_table[PRIMITIVETYPE_SHORT].class_primitive;
4054 case 'Z': return primitivetype_table[PRIMITIVETYPE_BOOLEAN].class_primitive;
4055 case 'V': return primitivetype_table[PRIMITIVETYPE_VOID].class_primitive;
4060 /****************** function: class_from_descriptor ****************************
4062 return the class indicated by the given descriptor
4064 utf_ptr....first character of descriptor
4065 end_ptr....first character after the end of the string
4066 next.......if non-NULL, *next is set to the first character after
4067 the descriptor. (Undefined if an error occurs.)
4069 mode.......a combination (binary or) of the following flags:
4071 (Flags marked with * are the default settings.)
4073 What to do if a reference type descriptor is parsed successfully:
4075 CLASSLOAD_SKIP...skip it and return something != NULL
4076 * CLASSLOAD_NEW....get classinfo * via class_new
4077 CLASSLOAD_LOAD...get classinfo * via loader_load
4079 How to handle primitive types:
4081 * CLASSLOAD_PRIMITIVE.......return primitive class (eg. "int")
4082 CLASSLOAD_NULLPRIMITIVE...return NULL for primitive types
4084 How to handle "V" descriptors:
4086 * CLASSLOAD_VOID.....handle it like other primitive types
4087 CLASSLOAD_NOVOID...treat it as an error
4089 How to deal with extra characters after the end of the
4092 * CLASSLOAD_NOCHECKEND...ignore (useful for parameter lists)
4093 CLASSLOAD_CHECKEND.....treat them as an error
4095 How to deal with errors:
4097 * CLASSLOAD_PANIC....abort execution with an error message
4098 CLASSLOAD_NOPANIC..return NULL on error
4100 *******************************************************************************/
4102 classinfo *class_from_descriptor(char *utf_ptr, char *end_ptr,
4103 char **next, int mode)
4105 char *start = utf_ptr;
4109 SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr, end_ptr, error);
4111 if (mode & CLASSLOAD_CHECKEND)
4112 error |= (utf_ptr != end_ptr);
4115 if (next) *next = utf_ptr;
4119 if (mode & CLASSLOAD_NOVOID)
4130 return (mode & CLASSLOAD_NULLPRIMITIVE)
4132 : class_primitive_from_sig(*start);
4139 if (mode & CLASSLOAD_SKIP) return class_java_lang_Object;
4140 name = utf_new(start, utf_ptr - start);
4144 tc = class_new_intern(name);
4146 list_addfirst(&unlinkedclasses, tc);
4151 return (mode & CLASSLOAD_LOAD)
4152 ? class_load(class_new(name)) : class_new(name); /* XXX handle errors */
4157 /* An error occurred */
4158 if (mode & CLASSLOAD_NOPANIC)
4161 log_plain("Invalid descriptor at beginning of '");
4162 log_plain_utf(utf_new(start, end_ptr - start));
4166 panic("Invalid descriptor");
4168 /* keep compiler happy */
4173 /******************* function: type_from_descriptor ****************************
4175 return the basic type indicated by the given descriptor
4177 This function parses a descriptor and returns its basic type as
4178 TYPE_INT, TYPE_LONG, TYPE_FLOAT, TYPE_DOUBLE, TYPE_ADDRESS or TYPE_VOID.
4180 cls...if non-NULL the referenced variable is set to the classinfo *
4181 returned by class_from_descriptor.
4183 For documentation of the arguments utf_ptr, end_ptr, next and mode
4184 see class_from_descriptor. The only difference is that
4185 type_from_descriptor always uses CLASSLOAD_PANIC.
4187 ********************************************************************************/
4189 int type_from_descriptor(classinfo **cls, char *utf_ptr, char *end_ptr,
4190 char **next, int mode)
4193 if (!cls) cls = &mycls;
4194 *cls = class_from_descriptor(utf_ptr, end_ptr, next, mode & (~CLASSLOAD_NOPANIC));
4211 return TYPE_ADDRESS;
4215 /*************** function: create_pseudo_classes *******************************
4217 create pseudo classes used by the typechecker
4219 ********************************************************************************/
4221 static void create_pseudo_classes()
4223 /* pseudo class for Arraystubs (extends java.lang.Object) */
4225 pseudo_class_Arraystub = class_new_intern(utf_new_char("$ARRAYSTUB$"));
4226 pseudo_class_Arraystub->loaded = true;
4227 pseudo_class_Arraystub->super = class_java_lang_Object;
4228 pseudo_class_Arraystub->interfacescount = 2;
4229 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
4230 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
4231 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
4233 class_link(pseudo_class_Arraystub);
4235 pseudo_class_Arraystub_vftbl = pseudo_class_Arraystub->vftbl;
4237 /* pseudo class representing the null type */
4239 pseudo_class_Null = class_new_intern(utf_new_char("$NULL$"));
4240 pseudo_class_Null->loaded = true;
4241 pseudo_class_Null->super = class_java_lang_Object;
4242 class_link(pseudo_class_Null);
4244 /* pseudo class representing new uninitialized objects */
4246 pseudo_class_New = class_new_intern(utf_new_char("$NEW$"));
4247 pseudo_class_New->loaded = true;
4248 pseudo_class_New->linked = true;
4249 pseudo_class_New->super = class_java_lang_Object;
4250 /* class_link(pseudo_class_New); */
4254 /********************** Function: loader_init **********************************
4256 Initializes all lists and loads all classes required for the system or the
4259 *******************************************************************************/
4261 void loader_init(u1 *stackbottom)
4265 /* create utf-symbols for pointer comparison of frequently used strings */
4266 utf_innerclasses = utf_new_char("InnerClasses");
4267 utf_constantvalue = utf_new_char("ConstantValue");
4268 utf_code = utf_new_char("Code");
4269 utf_exceptions = utf_new_char("Exceptions");
4270 utf_linenumbertable = utf_new_char("LineNumberTable");
4271 utf_sourcefile = utf_new_char("SourceFile");
4272 utf_finalize = utf_new_char("finalize");
4273 utf_fidesc = utf_new_char("()V");
4274 utf_init = utf_new_char("<init>");
4275 utf_clinit = utf_new_char("<clinit>");
4276 utf_initsystemclass = utf_new_char("initializeSystemClass");
4277 utf_systemclass = utf_new_char("java/lang/System");
4278 utf_vmclassloader = utf_new_char("java/lang/VMClassLoader");
4279 utf_initialize = utf_new_char("initialize");
4280 utf_initializedesc = utf_new_char("(I)V");
4281 utf_vmclass = utf_new_char("java/lang/VMClass");
4282 utf_java_lang_Object= utf_new_char("java/lang/Object");
4283 array_packagename = utf_new_char("<the array package>");
4284 utf_fillInStackTrace_name = utf_new_char("fillInStackTrace");
4285 utf_fillInStackTrace_desc = utf_new_char("()Ljava/lang/Throwable;");
4287 /* create some important classes */
4288 /* These classes have to be created now because the classinfo
4289 * pointers are used in the loading code.
4291 class_java_lang_Object =
4292 class_new_intern(utf_java_lang_Object);
4293 class_load(class_java_lang_Object);
4294 class_link(class_java_lang_Object);
4296 class_java_lang_String =
4297 class_new_intern(utf_new_char("java/lang/String"));
4298 class_load(class_java_lang_String);
4299 class_link(class_java_lang_String);
4301 class_java_lang_Cloneable =
4302 class_new_intern(utf_new_char("java/lang/Cloneable"));
4303 class_load(class_java_lang_Cloneable);
4304 class_link(class_java_lang_Cloneable);
4306 class_java_io_Serializable =
4307 class_new_intern(utf_new_char("java/io/Serializable"));
4308 class_load(class_java_io_Serializable);
4309 class_link(class_java_io_Serializable);
4311 /* create classes representing primitive types */
4312 create_primitive_classes();
4314 /* create classes used by the typechecker */
4315 create_pseudo_classes();
4317 /* correct vftbl-entries (retarded loading of class java/lang/String) */
4318 stringtable_update();
4320 #if defined(USE_THREADS)
4321 if (stackbottom != 0)
4327 static void loader_compute_class_values(classinfo *c)
4331 c->vftbl->baseval = ++classvalue;
4334 while (subs != NULL) {
4335 loader_compute_class_values(subs);
4336 subs = subs->nextsub;
4339 c->vftbl->diffval = classvalue - c->vftbl->baseval;
4343 void loader_compute_subclasses(classinfo *c)
4345 #if defined(USE_THREADS)
4346 #if defined(NATIVE_THREADS)
4353 if (!(c->flags & ACC_INTERFACE)) {
4358 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
4359 c->nextsub = c->super->sub;
4365 /* this is the java.lang.Object special case */
4366 if (!class_java_lang_Object) {
4367 loader_compute_class_values(c);
4370 loader_compute_class_values(class_java_lang_Object);
4373 #if defined(USE_THREADS)
4374 #if defined(NATIVE_THREADS)
4383 /******************** Function: loader_close ***********************************
4387 *******************************************************************************/
4394 for (slot = 0; slot < class_hash.size; slot++) {
4395 c = class_hash.ptr[slot];
4406 * These are local overrides for various environment variables in Emacs.
4407 * Please do not remove this and leave it at the end of the file, where
4408 * Emacs will automagically detect them.
4409 * ---------------------------------------------------------------------
4412 * indent-tabs-mode: t