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 1372 2004-08-01 21:56:10Z stefan $
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)
1147 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1148 initObjectLock(&m->header);
1153 count_all_methods++;
1156 m->thrownexceptionscount = 0;
1157 m->linenumbercount = 0;
1160 m->nativelyoverloaded = false;
1162 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1165 m->flags = suck_u2(cb);
1166 m->name = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1167 m->descriptor = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1170 if (!is_valid_name_utf(m->name))
1171 panic("Method with invalid name");
1173 if (m->name->text[0] == '<'
1174 && m->name != utf_init && m->name != utf_clinit)
1175 panic("Method with invalid special name");
1178 argcount = checkmethoddescriptor(c, m->descriptor);
1180 if (!(m->flags & ACC_STATIC))
1181 argcount++; /* count the 'this' argument */
1185 panic("Too many arguments in signature");
1187 /* check flag consistency */
1188 if (m->name != utf_clinit) {
1189 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1191 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED)
1192 panic("Method has invalid access flags");
1194 if ((m->flags & ACC_ABSTRACT) != 0) {
1195 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1196 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1198 new_classformaterror(c,
1199 "Illegal method modifiers: 0x%x",
1206 if ((c->flags & ACC_INTERFACE) != 0) {
1207 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC))
1208 != (ACC_ABSTRACT | ACC_PUBLIC))
1209 panic("Interface method is not declared abstract and public");
1212 if (m->name == utf_init) {
1213 if ((m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED
1214 | ACC_NATIVE | ACC_ABSTRACT)) != 0)
1215 panic("Instance initialization method has invalid flags set");
1221 m->basicblockcount = 0;
1222 m->basicblocks = NULL;
1223 m->basicblockindex = NULL;
1224 m->instructioncount = 0;
1225 m->instructions = NULL;
1228 m->exceptiontable = NULL;
1229 m->registerdata = NULL;
1230 m->stubroutine = NULL;
1232 m->entrypoint = NULL;
1233 m->methodUsed = NOTUSED;
1236 m->subRedefsUsed = 0;
1240 if (!(m->flags & ACC_NATIVE)) {
1241 m->stubroutine = createcompilerstub(m);
1244 functionptr f = native_findfunction(c->name, m->name, m->descriptor,
1245 (m->flags & ACC_STATIC) != 0);
1247 m->stubroutine = createnativestub(f, m);
1251 if (!check_classbuffer_size(cb, 2))
1254 attrnum = suck_u2(cb);
1255 for (i = 0; i < attrnum; i++) {
1258 if (!check_classbuffer_size(cb, 2))
1261 aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1263 if (aname != utf_code) {
1264 if (aname == utf_exceptions) {
1267 if (!check_classbuffer_size(cb, 4 + 2))
1270 suck_u4(cb); /*length*/
1271 m->thrownexceptionscount = suck_u2(cb);
1273 if (!check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1276 m->thrownexceptions = MNEW(classinfo*, m->thrownexceptionscount);
1278 for (j = 0; j < m->thrownexceptionscount; j++) {
1279 (m->thrownexceptions)[j] =
1280 class_getconstant(c, suck_u2(cb), CONSTANT_Class);
1284 if (!skipattributebody(cb))
1289 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1291 new_classformaterror(c,
1292 "Code attribute in native or abstract methods");
1299 new_classformaterror(c, "Multiple Code attributes");
1304 if (!check_classbuffer_size(cb, 4 + 2 + 2))
1308 m->maxstack = suck_u2(cb);
1309 m->maxlocals = suck_u2(cb);
1311 if (m->maxlocals < argcount) {
1313 new_classformaterror(c, "Arguments can't fit into locals");
1318 if (!check_classbuffer_size(cb, 4))
1321 m->jcodelength = suck_u4(cb);
1323 if (m->jcodelength == 0) {
1325 new_classformaterror(c, "Code of a method has length 0");
1330 if (m->jcodelength > 65535) {
1332 new_classformaterror(c,
1333 "Code of a method longer than 65535 bytes");
1338 if (!check_classbuffer_size(cb, m->jcodelength))
1341 m->jcode = MNEW(u1, m->jcodelength);
1342 suck_nbytes(m->jcode, cb, m->jcodelength);
1344 if (!check_classbuffer_size(cb, 2))
1347 m->exceptiontablelength = suck_u2(cb);
1349 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->exceptiontablelength))
1352 m->exceptiontable = MNEW(exceptiontable, m->exceptiontablelength);
1354 #if defined(STATISTICS)
1356 count_vmcode_len += m->jcodelength + 18;
1357 count_extable_len += 8 * m->exceptiontablelength;
1361 for (j = 0; j < m->exceptiontablelength; j++) {
1363 m->exceptiontable[j].startpc = suck_u2(cb);
1364 m->exceptiontable[j].endpc = suck_u2(cb);
1365 m->exceptiontable[j].handlerpc = suck_u2(cb);
1369 m->exceptiontable[j].catchtype = NULL;
1372 m->exceptiontable[j].catchtype =
1373 class_getconstant(c, idx, CONSTANT_Class);
1377 if (!check_classbuffer_size(cb, 2))
1380 codeattrnum = suck_u2(cb);
1382 for (; codeattrnum > 0; codeattrnum--) {
1385 if (!check_classbuffer_size(cb, 2))
1388 caname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1390 if (caname == utf_linenumbertable) {
1393 if (!check_classbuffer_size(cb, 4 + 2))
1397 m->linenumbercount = suck_u2(cb);
1399 if (!check_classbuffer_size(cb,
1400 (2 + 2) * m->linenumbercount))
1403 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1405 for (lncid = 0; lncid < m->linenumbercount; lncid++) {
1406 m->linenumbers[lncid].start_pc = suck_u2(cb);
1407 m->linenumbers[lncid].line_number = suck_u2(cb);
1411 if (!skipattributes(cb, codeattrnum))
1416 if (!skipattributebody(cb))
1423 if (!m->jcode && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1424 *exceptionptr = new_classformaterror(c, "Missing Code attribute");
1429 /* everything was ok */
1435 /********************* Function: method_free ***********************************
1437 frees all memory that was allocated for this method
1439 *******************************************************************************/
1441 static void method_free(methodinfo *m)
1444 MFREE(m->jcode, u1, m->jcodelength);
1446 if (m->exceptiontable)
1447 MFREE(m->exceptiontable, exceptiontable, m->exceptiontablelength);
1450 CFREE(m->mcode, m->mcodelength);
1452 if (m->stubroutine) {
1453 if (m->flags & ACC_NATIVE) {
1454 removenativestub(m->stubroutine);
1457 removecompilerstub(m->stubroutine);
1463 /************** Function: method_display (debugging only) **************/
1465 void method_display(methodinfo *m)
1468 printflags(m->flags);
1470 utf_display(m->name);
1472 utf_display(m->descriptor);
1476 /************** Function: method_display_flags_last (debugging only) **************/
1478 void method_display_flags_last(methodinfo *m)
1481 utf_display(m->name);
1483 utf_display(m->descriptor);
1485 printflags(m->flags);
1490 /******************** Function: method_canoverwrite ****************************
1492 Check if m and old are identical with respect to type and name. This means
1493 that old can be overwritten with m.
1495 *******************************************************************************/
1497 static bool method_canoverwrite(methodinfo *m, methodinfo *old)
1499 if (m->name != old->name) return false;
1500 if (m->descriptor != old->descriptor) return false;
1501 if (m->flags & ACC_STATIC) return false;
1506 /******************************************************************************/
1507 /************************ Functions for class *********************************/
1508 /******************************************************************************/
1511 /******************** function:: class_getconstant *****************************
1513 retrieves the value at position 'pos' of the constantpool of a class
1514 if the type of the value is other than 'ctype' the system is stopped
1516 *******************************************************************************/
1518 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
1520 /* invalid position in constantpool */
1521 /* (pos == 0 is caught by type comparison) */
1522 if (pos >= c->cpcount)
1523 panic("Attempt to access constant outside range");
1525 /* check type of constantpool entry */
1527 if (c->cptags[pos] != ctype) {
1528 class_showconstantpool(c);
1529 error("Type mismatch on constant: %d requested, %d here (class_getconstant)",
1530 (int) ctype, (int) c->cptags[pos]);
1533 return c->cpinfos[pos];
1537 /********************* Function: class_constanttype ****************************
1539 Determines the type of a class entry in the ConstantPool
1541 *******************************************************************************/
1543 u4 class_constanttype(classinfo *c, u4 pos)
1545 if (pos >= c->cpcount)
1546 panic("Attempt to access constant outside range");
1548 return c->cptags[pos];
1552 /******************** function: class_loadcpool ********************************
1554 loads the constantpool of a class,
1555 the entries are transformed into a simpler format
1556 by resolving references
1557 (a detailed overview of the compact structures can be found in global.h)
1559 *******************************************************************************/
1561 static bool class_loadcpool(classbuffer *cb, classinfo *c)
1564 /* The following structures are used to save information which cannot be
1565 processed during the first pass. After the complete constantpool has
1566 been traversed the references can be resolved.
1567 (only in specific order) */
1569 /* CONSTANT_Class_info entries */
1570 typedef struct forward_class {
1571 struct forward_class *next;
1576 /* CONSTANT_String */
1577 typedef struct forward_string {
1578 struct forward_string *next;
1583 /* CONSTANT_NameAndType */
1584 typedef struct forward_nameandtype {
1585 struct forward_nameandtype *next;
1589 } forward_nameandtype;
1591 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
1592 typedef struct forward_fieldmethint {
1593 struct forward_fieldmethint *next;
1597 u2 nameandtype_index;
1598 } forward_fieldmethint;
1602 long int dumpsize = dump_size ();
1604 forward_class *forward_classes = NULL;
1605 forward_string *forward_strings = NULL;
1606 forward_nameandtype *forward_nameandtypes = NULL;
1607 forward_fieldmethint *forward_fieldmethints = NULL;
1613 /* number of entries in the constant_pool table plus one */
1614 if (!check_classbuffer_size(cb, 2))
1617 cpcount = c->cpcount = suck_u2(cb);
1619 /* allocate memory */
1620 cptags = c->cptags = MNEW(u1, cpcount);
1621 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
1624 panic("Invalid constant_pool_count (0)");
1626 #if defined(STATISTICS)
1628 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
1631 /* initialize constantpool */
1632 for (idx = 0; idx < cpcount; idx++) {
1633 cptags[idx] = CONSTANT_UNUSED;
1634 cpinfos[idx] = NULL;
1638 /******* first pass *******/
1639 /* entries which cannot be resolved now are written into
1640 temporary structures and traversed again later */
1643 while (idx < cpcount) {
1646 /* get constant type */
1647 if (!check_classbuffer_size(cb, 1))
1653 case CONSTANT_Class: {
1654 forward_class *nfc = DNEW(forward_class);
1656 nfc->next = forward_classes;
1657 forward_classes = nfc;
1659 nfc->thisindex = idx;
1660 /* reference to CONSTANT_NameAndType */
1661 if (!check_classbuffer_size(cb, 2))
1664 nfc->name_index = suck_u2(cb);
1670 case CONSTANT_Fieldref:
1671 case CONSTANT_Methodref:
1672 case CONSTANT_InterfaceMethodref: {
1673 forward_fieldmethint *nff = DNEW(forward_fieldmethint);
1675 nff->next = forward_fieldmethints;
1676 forward_fieldmethints = nff;
1678 nff->thisindex = idx;
1682 if (!check_classbuffer_size(cb, 2 + 2))
1685 /* class or interface type that contains the declaration of the
1687 nff->class_index = suck_u2(cb);
1689 /* name and descriptor of the field or method */
1690 nff->nameandtype_index = suck_u2(cb);
1696 case CONSTANT_String: {
1697 forward_string *nfs = DNEW(forward_string);
1699 nfs->next = forward_strings;
1700 forward_strings = nfs;
1702 nfs->thisindex = idx;
1704 /* reference to CONSTANT_Utf8_info with string characters */
1705 if (!check_classbuffer_size(cb, 2))
1708 nfs->string_index = suck_u2(cb);
1714 case CONSTANT_NameAndType: {
1715 forward_nameandtype *nfn = DNEW(forward_nameandtype);
1717 nfn->next = forward_nameandtypes;
1718 forward_nameandtypes = nfn;
1720 nfn->thisindex = idx;
1722 if (!check_classbuffer_size(cb, 2 + 2))
1725 /* reference to CONSTANT_Utf8_info containing simple name */
1726 nfn->name_index = suck_u2(cb);
1728 /* reference to CONSTANT_Utf8_info containing field or method
1730 nfn->sig_index = suck_u2(cb);
1736 case CONSTANT_Integer: {
1737 constant_integer *ci = NEW(constant_integer);
1739 #if defined(STATISTICS)
1741 count_const_pool_len += sizeof(constant_integer);
1744 if (!check_classbuffer_size(cb, 4))
1747 ci->value = suck_s4(cb);
1748 cptags[idx] = CONSTANT_Integer;
1755 case CONSTANT_Float: {
1756 constant_float *cf = NEW(constant_float);
1758 #if defined(STATISTICS)
1760 count_const_pool_len += sizeof(constant_float);
1763 if (!check_classbuffer_size(cb, 4))
1766 cf->value = suck_float(cb);
1767 cptags[idx] = CONSTANT_Float;
1774 case CONSTANT_Long: {
1775 constant_long *cl = NEW(constant_long);
1777 #if defined(STATISTICS)
1779 count_const_pool_len += sizeof(constant_long);
1782 if (!check_classbuffer_size(cb, 8))
1785 cl->value = suck_s8(cb);
1786 cptags[idx] = CONSTANT_Long;
1790 panic("Long constant exceeds constant pool");
1794 case CONSTANT_Double: {
1795 constant_double *cd = NEW(constant_double);
1797 #if defined(STATISTICS)
1799 count_const_pool_len += sizeof(constant_double);
1802 if (!check_classbuffer_size(cb, 8))
1805 cd->value = suck_double(cb);
1806 cptags[idx] = CONSTANT_Double;
1810 panic("Double constant exceeds constant pool");
1814 case CONSTANT_Utf8: {
1817 /* number of bytes in the bytes array (not string-length) */
1818 if (!check_classbuffer_size(cb, 2))
1821 length = suck_u2(cb);
1822 cptags[idx] = CONSTANT_Utf8;
1824 /* validate the string */
1825 if (!check_classbuffer_size(cb, length))
1829 !is_valid_utf(cb->pos + 1, cb->pos + 1 + length)) {
1830 dolog("Invalid UTF-8 string (constant pool index %d)",idx);
1831 panic("Invalid UTF-8 string");
1833 /* insert utf-string into the utf-symboltable */
1834 cpinfos[idx] = utf_new_intern(cb->pos + 1, length);
1836 /* skip bytes of the string (buffer size check above) */
1837 skip_nbytes(cb, length);
1843 error("Unkown constant type: %d",(int) t);
1848 /* resolve entries in temporary structures */
1850 while (forward_classes) {
1852 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
1854 if (opt_verify && !is_valid_name_utf(name))
1855 panic("Class reference with invalid name");
1857 cptags[forward_classes->thisindex] = CONSTANT_Class;
1858 /* retrieve class from class-table */
1861 tc = class_new_intern(name);
1863 if (!class_load(tc))
1866 /* link the class later, so we cannot link the currently loaded
1868 list_addfirst(&unlinkedclasses, tc);
1870 cpinfos[forward_classes->thisindex] = tc;
1873 cpinfos[forward_classes->thisindex] = class_new(name);
1876 forward_classes = forward_classes->next;
1879 while (forward_strings) {
1881 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
1883 /* resolve utf-string */
1884 cptags[forward_strings->thisindex] = CONSTANT_String;
1885 cpinfos[forward_strings->thisindex] = text;
1887 forward_strings = forward_strings->next;
1890 while (forward_nameandtypes) {
1891 constant_nameandtype *cn = NEW(constant_nameandtype);
1893 #if defined(STATISTICS)
1895 count_const_pool_len += sizeof(constant_nameandtype);
1898 /* resolve simple name and descriptor */
1899 cn->name = class_getconstant(c,
1900 forward_nameandtypes->name_index,
1903 cn->descriptor = class_getconstant(c,
1904 forward_nameandtypes->sig_index,
1909 if (!is_valid_name_utf(cn->name))
1910 panic("NameAndType with invalid name");
1911 /* disallow referencing <clinit> among others */
1912 if (cn->name->text[0] == '<' && cn->name != utf_init)
1913 panic("NameAndType with invalid special name");
1916 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
1917 cpinfos[forward_nameandtypes->thisindex] = cn;
1919 forward_nameandtypes = forward_nameandtypes->next;
1922 while (forward_fieldmethints) {
1923 constant_nameandtype *nat;
1924 constant_FMIref *fmi = NEW(constant_FMIref);
1926 #if defined(STATISTICS)
1928 count_const_pool_len += sizeof(constant_FMIref);
1930 /* resolve simple name and descriptor */
1931 nat = class_getconstant(c,
1932 forward_fieldmethints->nameandtype_index,
1933 CONSTANT_NameAndType);
1935 fmi->class = class_getconstant(c,
1936 forward_fieldmethints->class_index,
1938 fmi->name = nat->name;
1939 fmi->descriptor = nat->descriptor;
1941 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
1942 cpinfos[forward_fieldmethints->thisindex] = fmi;
1944 switch (forward_fieldmethints->tag) {
1945 case CONSTANT_Fieldref: /* check validity of descriptor */
1946 checkfielddescriptor(fmi->descriptor->text,
1947 utf_end(fmi->descriptor));
1949 case CONSTANT_InterfaceMethodref:
1950 case CONSTANT_Methodref: /* check validity of descriptor */
1951 checkmethoddescriptor(c, fmi->descriptor);
1955 forward_fieldmethints = forward_fieldmethints->next;
1958 dump_release(dumpsize);
1960 /* everything was ok */
1966 /********************** Function: class_load ***********************************
1968 Loads everything interesting about a class from the class file. The
1969 'classinfo' structure must have been allocated previously.
1971 The super class and the interfaces implemented by this class need not be
1972 loaded. The link is set later by the function 'class_link'.
1974 The loaded class is removed from the list 'unloadedclasses' and added to
1975 the list 'unlinkedclasses'.
1977 *******************************************************************************/
1979 classinfo *class_load_intern(classbuffer *cb);
1981 classinfo *class_load(classinfo *c)
1988 /* enter a monitor on the class */
1990 builtin_monitorenter((java_objectheader *) c);
1992 /* maybe the class is already loaded */
1994 builtin_monitorexit((java_objectheader *) c);
2001 starttime = getcputime();
2003 /* load classdata, throw exception on error */
2005 if ((cb = suck_start(c)) == NULL) {
2006 /* this means, the classpath was not set properly */
2007 if (c->name == utf_java_lang_Object)
2008 throw_cacao_exception_exit(string_java_lang_NoClassDefFoundError,
2009 "java/lang/Object");
2012 new_exception_utfmessage(string_java_lang_NoClassDefFoundError,
2015 builtin_monitorexit((java_objectheader *) c);
2020 /* call the internal function */
2021 r = class_load_intern(cb);
2023 /* if return value is NULL, we had a problem and the class is not loaded */
2027 /* now free the allocated memory, otherwise we could ran into a DOS */
2035 if (getloadingtime) {
2036 stoptime = getcputime();
2037 loadingtime += (stoptime - starttime);
2040 /* leave the monitor */
2042 builtin_monitorexit((java_objectheader *) c);
2048 classinfo *class_load_intern(classbuffer *cb)
2053 /* s4 classdata_left; */
2054 char msg[MAXLOGTEXT]; /* maybe we get an exception */
2056 /* get the classbuffer's class */
2059 /* maybe the class is already loaded */
2063 #if defined(STATISTICS)
2065 count_class_loads++;
2068 /* output for debugging purposes */
2070 log_message_class("Loading class: ", c);
2072 /* class is somewhat loaded */
2075 if (!check_classbuffer_size(cb, 4 + 2 + 2))
2078 /* check signature */
2079 if (suck_u4(cb) != MAGIC) {
2080 *exceptionptr = new_classformaterror(c, "Bad magic number");
2089 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
2091 new_classformaterror(c,
2092 "Unsupported major.minor version %d.%d",
2098 if (!class_loadcpool(cb, c))
2102 c->erroneous_state = 0;
2103 c->initializing_thread = 0;
2105 c->classUsed = NOTUSED; /* not used initially CO-RT */
2109 if (!check_classbuffer_size(cb, 2))
2112 c->flags = suck_u2(cb);
2113 /*if (!(c->flags & ACC_PUBLIC)) { log_text("CLASS NOT PUBLIC"); } JOWENN*/
2115 /* check ACC flags consistency */
2116 if (c->flags & ACC_INTERFACE) {
2117 if (!(c->flags & ACC_ABSTRACT)) {
2118 /* We work around this because interfaces in JDK 1.1 are
2119 * not declared abstract. */
2121 c->flags |= ACC_ABSTRACT;
2122 /* panic("Interface class not declared abstract"); */
2125 if (c->flags & ACC_FINAL) {
2127 new_classformaterror(c,
2128 "Illegal class modifiers: 0x%x", c->flags);
2133 if (c->flags & ACC_SUPER) {
2134 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
2138 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
2140 new_classformaterror(c, "Illegal class modifiers: 0x%x", c->flags);
2145 if (!check_classbuffer_size(cb, 2 + 2))
2150 if (class_getconstant(c, i, CONSTANT_Class) != c) {
2151 utf_sprint(msg, c->name);
2152 sprintf(msg + strlen(msg), " (wrong name: ");
2153 utf_sprint(msg + strlen(msg),
2154 ((classinfo *) class_getconstant(c, i, CONSTANT_Class))->name);
2155 sprintf(msg + strlen(msg), ")");
2158 new_exception_message(string_java_lang_NoClassDefFoundError, msg);
2163 /* retrieve superclass */
2164 if ((i = suck_u2(cb))) {
2165 c->super = class_getconstant(c, i, CONSTANT_Class);
2167 /* java.lang.Object may not have a super class. */
2168 if (c->name == utf_java_lang_Object) {
2170 new_exception_message(string_java_lang_ClassFormatError,
2171 "java.lang.Object with superclass");
2176 /* Interfaces must have java.lang.Object as super class. */
2177 if ((c->flags & ACC_INTERFACE) &&
2178 c->super->name != utf_java_lang_Object) {
2180 new_exception_message(string_java_lang_ClassFormatError,
2181 "Interfaces must have java.lang.Object as superclass");
2189 /* This is only allowed for java.lang.Object. */
2190 if (c->name != utf_java_lang_Object) {
2191 *exceptionptr = new_classformaterror(c, "Bad superclass index");
2198 /* retrieve interfaces */
2199 if (!check_classbuffer_size(cb, 2))
2202 c->interfacescount = suck_u2(cb);
2204 if (!check_classbuffer_size(cb, 2 * c->interfacescount))
2207 c->interfaces = MNEW(classinfo*, c->interfacescount);
2208 for (i = 0; i < c->interfacescount; i++) {
2209 c->interfaces[i] = class_getconstant(c, suck_u2(cb), CONSTANT_Class);
2213 if (!check_classbuffer_size(cb, 2))
2216 c->fieldscount = suck_u2(cb);
2217 c->fields = GCNEW(fieldinfo, c->fieldscount);
2218 /* c->fields = MNEW(fieldinfo, c->fieldscount); */
2219 for (i = 0; i < c->fieldscount; i++) {
2220 if (!field_load(cb, c, &(c->fields[i])))
2225 if (!check_classbuffer_size(cb, 2))
2228 c->methodscount = suck_u2(cb);
2229 c->methods = GCNEW(methodinfo, c->methodscount);
2230 /* c->methods = MNEW(methodinfo, c->methodscount); */
2231 for (i = 0; i < c->methodscount; i++) {
2232 if (!method_load(cb, c, &(c->methods[i])))
2236 /* Check if all fields and methods can be uniquely
2237 * identified by (name,descriptor). */
2239 /* We use a hash table here to avoid making the
2240 * average case quadratic in # of methods, fields.
2242 static int shift = 0;
2244 u2 *next; /* for chaining colliding hash entries */
2250 /* Allocate hashtable */
2251 len = c->methodscount;
2252 if (len < c->fieldscount) len = c->fieldscount;
2254 hashtab = MNEW(u2,(hashlen + len));
2255 next = hashtab + hashlen;
2257 /* Determine bitshift (to get good hash values) */
2267 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2269 for (i = 0; i < c->fieldscount; ++i) {
2270 fieldinfo *fi = c->fields + i;
2272 /* It's ok if we lose bits here */
2273 index = ((((size_t) fi->name) +
2274 ((size_t) fi->descriptor)) >> shift) % hashlen;
2276 if ((old = hashtab[index])) {
2280 if (c->fields[old].name == fi->name &&
2281 c->fields[old].descriptor == fi->descriptor) {
2283 new_classformaterror(c,
2284 "Repetitive field name/signature");
2288 } while ((old = next[old]));
2290 hashtab[index] = i + 1;
2294 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2296 for (i = 0; i < c->methodscount; ++i) {
2297 methodinfo *mi = c->methods + i;
2299 /* It's ok if we lose bits here */
2300 index = ((((size_t) mi->name) +
2301 ((size_t) mi->descriptor)) >> shift) % hashlen;
2303 if ((old = hashtab[index])) {
2307 if (c->methods[old].name == mi->name &&
2308 c->methods[old].descriptor == mi->descriptor) {
2310 new_classformaterror(c,
2311 "Repetitive method name/signature");
2315 } while ((old = next[old]));
2317 hashtab[index] = i + 1;
2320 MFREE(hashtab, u2, (hashlen + len));
2323 #if defined(STATISTICS)
2325 count_class_infos += sizeof(classinfo*) * c->interfacescount;
2326 count_class_infos += sizeof(fieldinfo) * c->fieldscount;
2327 count_class_infos += sizeof(methodinfo) * c->methodscount;
2331 /* load variable-length attribute structures */
2332 if (!check_classbuffer_size(cb, 2))
2335 if (!attribute_load(cb, c, suck_u2(cb)))
2339 /* XXX TWISTI is this still in the JVM spec? SUN and IBM don't complain about it */
2341 /* check if all data has been read */
2342 classdata_left = ((cb->data + cb->size) - cb->pos - 1);
2344 if (classdata_left > 0) {
2346 dolog("There are %d extra bytes at end of classfile", classdata_left);
2347 /* The JVM spec disallows extra bytes. */
2348 panic("Extra bytes at end of classfile");
2353 log_message_class("Loading done class: ", c);
2360 /************** internal Function: class_highestinterface **********************
2362 Used by the function class_link to determine the amount of memory needed
2363 for the interface table.
2365 *******************************************************************************/
2367 static s4 class_highestinterface(classinfo *c)
2372 if (!(c->flags & ACC_INTERFACE)) {
2373 char logtext[MAXLOGTEXT];
2374 sprintf(logtext, "Interface-methods count requested for non-interface: ");
2375 utf_sprint(logtext + strlen(logtext), c->name);
2376 error("%s",logtext);
2380 for (i = 0; i < c->interfacescount; i++) {
2381 s4 h2 = class_highestinterface(c->interfaces[i]);
2389 /* class_addinterface **********************************************************
2391 Is needed by class_link for adding a VTBL to a class. All interfaces
2392 implemented by ic are added as well.
2394 *******************************************************************************/
2396 static void class_addinterface(classinfo *c, classinfo *ic)
2400 vftbl_t *vftbl = c->vftbl;
2402 if (i >= vftbl->interfacetablelength)
2403 panic ("Inernal error: interfacetable overflow");
2405 if (vftbl->interfacetable[-i])
2408 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
2409 vftbl->interfacevftbllength[i] = 1;
2410 vftbl->interfacetable[-i] = MNEW(methodptr, 1);
2411 vftbl->interfacetable[-i][0] = NULL;
2414 vftbl->interfacevftbllength[i] = ic->methodscount;
2415 vftbl->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
2419 count_vftbl_len += sizeof(methodptr) *
2420 (ic->methodscount + (ic->methodscount == 0));
2423 for (j = 0; j < ic->methodscount; j++) {
2426 for (m = 0; m < sc->methodscount; m++) {
2427 methodinfo *mi = &(sc->methods[m]);
2428 if (method_canoverwrite(mi, &(ic->methods[j]))) {
2429 vftbl->interfacetable[-i][j] =
2430 vftbl->table[mi->vftblindex];
2441 for (j = 0; j < ic->interfacescount; j++)
2442 class_addinterface(c, ic->interfaces[j]);
2446 /******************* Function: class_new_array *********************************
2448 This function is called by class_new to setup an array class.
2450 *******************************************************************************/
2452 void class_new_array(classinfo *c)
2454 classinfo *comp = NULL;
2458 /* Check array class name */
2459 namelen = c->name->blength;
2460 if (namelen < 2 || c->name->text[0] != '[')
2461 panic("Invalid array class name");
2463 /* Check the component type */
2464 switch (c->name->text[1]) {
2466 /* c is an array of arrays. We have to create the component class. */
2468 comp = class_new_intern(utf_new_intern(c->name->text + 1,
2471 list_addfirst(&unlinkedclasses, comp);
2474 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2479 /* c is an array of objects. */
2480 if (namelen < 4 || c->name->text[namelen - 1] != ';')
2481 panic("Invalid array class name");
2484 comp = class_new_intern(utf_new_intern(c->name->text + 2,
2487 list_addfirst(&unlinkedclasses, comp);
2490 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2495 /* Setup the array class */
2496 c->super = class_java_lang_Object;
2497 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2499 c->interfacescount = 2;
2500 c->interfaces = MNEW(classinfo*, 2);
2505 tc = class_new_intern(utf_new_char("java/lang/Cloneable"));
2507 list_addfirst(&unlinkedclasses, tc);
2508 c->interfaces[0] = tc;
2510 tc = class_new_intern(utf_new_char("java/io/Serializable"));
2512 list_addfirst(&unlinkedclasses, tc);
2513 c->interfaces[1] = tc;
2516 c->interfaces[0] = class_new(utf_new_char("java/lang/Cloneable"));
2517 c->interfaces[1] = class_new(utf_new_char("java/io/Serializable"));
2520 c->methodscount = 1;
2521 c->methods = MNEW(methodinfo, c->methodscount);
2524 memset(clone, 0, sizeof(methodinfo));
2525 clone->flags = ACC_PUBLIC;
2526 clone->name = utf_new_char("clone");
2527 clone->descriptor = utf_new_char("()Ljava/lang/Object;");
2529 clone->stubroutine = createnativestub((functionptr) &builtin_clone_array, clone);
2530 clone->monoPoly = MONO;
2532 /* XXX: field: length? */
2534 /* array classes are not loaded from class files */
2539 /****************** Function: class_link_array *********************************
2541 This function is called by class_link to create the
2542 arraydescriptor for an array class.
2544 This function returns NULL if the array cannot be linked because
2545 the component type has not been linked yet.
2547 *******************************************************************************/
2549 static arraydescriptor *class_link_array(classinfo *c)
2551 classinfo *comp = NULL;
2552 s4 namelen = c->name->blength;
2553 arraydescriptor *desc;
2556 /* Check the component type */
2557 switch (c->name->text[1]) {
2559 /* c is an array of arrays. */
2560 /* comp = class_get(utf_new_intern(c->name->text + 1, namelen - 1)); */
2561 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2563 panic("Could not find component array class.");
2567 /* c is an array of objects. */
2568 /* comp = class_get(utf_new_intern(c->name->text + 2, namelen - 3)); */
2569 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2571 panic("Could not find component class.");
2575 /* If the component type has not been linked, link it now */
2576 if (comp && !comp->linked) {
2582 /* Allocate the arraydescriptor */
2583 desc = NEW(arraydescriptor);
2586 /* c is an array of references */
2587 desc->arraytype = ARRAYTYPE_OBJECT;
2588 desc->componentsize = sizeof(void*);
2589 desc->dataoffset = OFFSET(java_objectarray, data);
2591 compvftbl = comp->vftbl;
2593 panic("Component class has no vftbl");
2594 desc->componentvftbl = compvftbl;
2596 if (compvftbl->arraydesc) {
2597 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
2598 if (compvftbl->arraydesc->dimension >= 255)
2599 panic("Creating array of dimension >255");
2600 desc->dimension = compvftbl->arraydesc->dimension + 1;
2601 desc->elementtype = compvftbl->arraydesc->elementtype;
2604 desc->elementvftbl = compvftbl;
2605 desc->dimension = 1;
2606 desc->elementtype = ARRAYTYPE_OBJECT;
2610 /* c is an array of a primitive type */
2611 switch (c->name->text[1]) {
2613 desc->arraytype = ARRAYTYPE_BOOLEAN;
2614 desc->dataoffset = OFFSET(java_booleanarray,data);
2615 desc->componentsize = sizeof(u1);
2619 desc->arraytype = ARRAYTYPE_BYTE;
2620 desc->dataoffset = OFFSET(java_bytearray,data);
2621 desc->componentsize = sizeof(u1);
2625 desc->arraytype = ARRAYTYPE_CHAR;
2626 desc->dataoffset = OFFSET(java_chararray,data);
2627 desc->componentsize = sizeof(u2);
2631 desc->arraytype = ARRAYTYPE_DOUBLE;
2632 desc->dataoffset = OFFSET(java_doublearray,data);
2633 desc->componentsize = sizeof(double);
2637 desc->arraytype = ARRAYTYPE_FLOAT;
2638 desc->dataoffset = OFFSET(java_floatarray,data);
2639 desc->componentsize = sizeof(float);
2643 desc->arraytype = ARRAYTYPE_INT;
2644 desc->dataoffset = OFFSET(java_intarray,data);
2645 desc->componentsize = sizeof(s4);
2649 desc->arraytype = ARRAYTYPE_LONG;
2650 desc->dataoffset = OFFSET(java_longarray,data);
2651 desc->componentsize = sizeof(s8);
2655 desc->arraytype = ARRAYTYPE_SHORT;
2656 desc->dataoffset = OFFSET(java_shortarray,data);
2657 desc->componentsize = sizeof(s2);
2661 panic("Invalid array class name");
2664 desc->componentvftbl = NULL;
2665 desc->elementvftbl = NULL;
2666 desc->dimension = 1;
2667 desc->elementtype = desc->arraytype;
2674 /********************** Function: class_link ***********************************
2676 Tries to link a class. The function calculates the length in bytes that
2677 an instance of this class requires as well as the VTBL for methods and
2680 *******************************************************************************/
2682 static classinfo *class_link_intern(classinfo *c);
2684 classinfo *class_link(classinfo *c)
2690 /* enter a monitor on the class */
2692 builtin_monitorenter((java_objectheader *) c);
2694 /* maybe the class is already linked */
2696 builtin_monitorexit((java_objectheader *) c);
2703 starttime = getcputime();
2705 /* call the internal function */
2706 r = class_link_intern(c);
2708 /* if return value is NULL, we had a problem and the class is not linked */
2713 if (getloadingtime) {
2714 stoptime = getcputime();
2715 loadingtime += (stoptime - starttime);
2718 /* leave the monitor */
2720 builtin_monitorexit((java_objectheader *) c);
2726 static classinfo *class_link_intern(classinfo *c)
2728 s4 supervftbllength; /* vftbllegnth of super class */
2729 s4 vftbllength; /* vftbllength of current class */
2730 s4 interfacetablelength; /* interface table length */
2731 classinfo *super = c->super; /* super class */
2732 classinfo *ic, *c2; /* intermediate class variables */
2733 vftbl_t *v; /* vftbl of current class */
2734 s4 i; /* interface/method/field counter */
2735 arraydescriptor *arraydesc = NULL; /* descriptor for array classes */
2737 /* maybe the class is already linked */
2742 log_message_class("Linking class: ", c);
2744 /* ok, this class is somewhat linked */
2747 /* check interfaces */
2749 for (i = 0; i < c->interfacescount; i++) {
2750 ic = c->interfaces[i];
2752 /* detect circularity */
2755 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2762 if (!class_load(ic))
2766 if (!class_link(ic))
2769 if (!(ic->flags & ACC_INTERFACE)) {
2770 dolog("Specified interface is not declared as interface:");
2774 panic("Specified interface is not declared as interface");
2778 /* check super class */
2780 if (super == NULL) { /* class java.lang.Object */
2782 c->classUsed = USED; /* Object class is always used CO-RT*/
2784 c->instancesize = sizeof(java_objectheader);
2786 vftbllength = supervftbllength = 0;
2788 c->finalizer = NULL;
2791 /* detect circularity */
2794 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2801 if (!class_load(super))
2805 if (!class_link(super))
2808 if (super->flags & ACC_INTERFACE)
2809 panic("Interface specified as super class");
2811 /* handle array classes */
2812 /* The component class must have been linked already. */
2813 if (c->name->text[0] == '[') {
2814 if ((arraydesc = class_link_array(c)) == NULL) {
2815 panic("class_link: class_link_array");
2819 /* Don't allow extending final classes */
2820 if (super->flags & ACC_FINAL)
2821 panic("Trying to extend final class");
2823 if (c->flags & ACC_INTERFACE)
2824 c->index = interfaceindex++;
2826 c->index = super->index + 1;
2828 c->instancesize = super->instancesize;
2830 vftbllength = supervftbllength = super->vftbl->vftbllength;
2832 c->finalizer = super->finalizer;
2835 /* compute vftbl length */
2837 for (i = 0; i < c->methodscount; i++) {
2838 methodinfo *m = &(c->methods[i]);
2840 if (!(m->flags & ACC_STATIC)) { /* is instance method */
2841 classinfo *sc = super;
2844 for (j = 0; j < sc->methodscount; j++) {
2845 if (method_canoverwrite(m, &(sc->methods[j]))) {
2846 if ((sc->methods[j].flags & ACC_PRIVATE) != 0)
2847 goto notfoundvftblindex;
2849 if ((sc->methods[j].flags & ACC_FINAL) != 0) {
2852 log_utf(sc->methods[j].name);
2853 log_utf(sc->methods[j].descriptor);
2854 panic("Trying to overwrite final method");
2856 m->vftblindex = sc->methods[j].vftblindex;
2857 goto foundvftblindex;
2863 m->vftblindex = (vftbllength++);
2869 #if defined(STATISTICS)
2872 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
2875 /* compute interfacetable length */
2877 interfacetablelength = 0;
2880 for (i = 0; i < c2->interfacescount; i++) {
2881 s4 h = class_highestinterface(c2->interfaces[i]) + 1;
2882 if (h > interfacetablelength)
2883 interfacetablelength = h;
2888 /* allocate virtual function table */
2890 v = (vftbl_t*) mem_alloc(sizeof(vftbl_t) + sizeof(methodptr) *
2891 (vftbllength - 1) + sizeof(methodptr*) *
2892 (interfacetablelength - (interfacetablelength > 0)));
2893 v = (vftbl_t*) (((methodptr*) v) + (interfacetablelength - 1) *
2894 (interfacetablelength > 1));
2895 c->header.vftbl = c->vftbl = v;
2896 /* utf_display_classname(c->name);printf(", c->header.vftbl=%p\n", c->header.vftbl); */
2898 v->vftbllength = vftbllength;
2899 v->interfacetablelength = interfacetablelength;
2900 v->arraydesc = arraydesc;
2902 /* store interface index in vftbl */
2903 if (c->flags & ACC_INTERFACE)
2904 v->baseval = -(c->index);
2906 /* copy virtual function table of super class */
2908 for (i = 0; i < supervftbllength; i++)
2909 v->table[i] = super->vftbl->table[i];
2911 /* add method stubs into virtual function table */
2913 for (i = 0; i < c->methodscount; i++) {
2914 methodinfo *m = &(c->methods[i]);
2915 if (!(m->flags & ACC_STATIC)) {
2916 v->table[m->vftblindex] = m->stubroutine;
2920 /* compute instance size and offset of each field */
2922 for (i = 0; i < c->fieldscount; i++) {
2924 fieldinfo *f = &(c->fields[i]);
2926 if (!(f->flags & ACC_STATIC)) {
2927 dsize = desc_typesize(f->descriptor);
2928 c->instancesize = ALIGN(c->instancesize, dsize);
2929 f->offset = c->instancesize;
2930 c->instancesize += dsize;
2934 /* initialize interfacetable and interfacevftbllength */
2936 v->interfacevftbllength = MNEW(s4, interfacetablelength);
2938 #if defined(STATISTICS)
2940 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
2943 for (i = 0; i < interfacetablelength; i++) {
2944 v->interfacevftbllength[i] = 0;
2945 v->interfacetable[-i] = NULL;
2948 /* add interfaces */
2950 for (c2 = c; c2 != NULL; c2 = c2->super)
2951 for (i = 0; i < c2->interfacescount; i++) {
2952 class_addinterface(c, c2->interfaces[i]);
2955 /* add finalizer method (not for java.lang.Object) */
2957 if (super != NULL) {
2959 static utf *finame = NULL;
2960 static utf *fidesc = NULL;
2963 finame = utf_finalize;
2965 fidesc = utf_fidesc;
2967 fi = class_findmethod(c, finame, fidesc);
2969 if (!(fi->flags & ACC_STATIC)) {
2977 loader_compute_subclasses(c);
2980 log_message_class("Linking done class: ", c);
2982 /* just return c to show that we didn't had a problem */
2988 /******************* Function: class_freepool **********************************
2990 Frees all resources used by this classes Constant Pool.
2992 *******************************************************************************/
2994 static void class_freecpool(classinfo *c)
3000 if (c->cptags && c->cpinfos) {
3001 for (idx = 0; idx < c->cpcount; idx++) {
3002 tag = c->cptags[idx];
3003 info = c->cpinfos[idx];
3007 case CONSTANT_Fieldref:
3008 case CONSTANT_Methodref:
3009 case CONSTANT_InterfaceMethodref:
3010 FREE(info, constant_FMIref);
3012 case CONSTANT_Integer:
3013 FREE(info, constant_integer);
3015 case CONSTANT_Float:
3016 FREE(info, constant_float);
3019 FREE(info, constant_long);
3021 case CONSTANT_Double:
3022 FREE(info, constant_double);
3024 case CONSTANT_NameAndType:
3025 FREE(info, constant_nameandtype);
3033 MFREE(c->cptags, u1, c->cpcount);
3036 MFREE(c->cpinfos, voidptr, c->cpcount);
3040 /*********************** Function: class_free **********************************
3042 Frees all resources used by the class.
3044 *******************************************************************************/
3046 void class_free(classinfo *c)
3054 MFREE(c->interfaces, classinfo*, c->interfacescount);
3057 for (i = 0; i < c->fieldscount; i++)
3058 field_free(&(c->fields[i]));
3059 /* MFREE(c->fields, fieldinfo, c->fieldscount); */
3063 for (i = 0; i < c->methodscount; i++)
3064 method_free(&(c->methods[i]));
3065 /* MFREE(c->methods, methodinfo, c->methodscount); */
3068 if ((v = c->vftbl) != NULL) {
3070 mem_free(v->arraydesc,sizeof(arraydescriptor));
3072 for (i = 0; i < v->interfacetablelength; i++) {
3073 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
3075 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
3077 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
3078 sizeof(methodptr*) * (v->interfacetablelength -
3079 (v->interfacetablelength > 0));
3080 v = (vftbl_t*) (((methodptr*) v) - (v->interfacetablelength - 1) *
3081 (v->interfacetablelength > 1));
3086 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
3088 /* if (c->classvftbl)
3089 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
3095 /************************* Function: class_findfield ***************************
3097 Searches a 'classinfo' structure for a field having the given name and
3100 *******************************************************************************/
3102 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
3106 for (i = 0; i < c->fieldscount; i++) {
3107 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
3108 return &(c->fields[i]);
3111 panic("Can not find field given in CONSTANT_Fieldref");
3113 /* keep compiler happy */
3118 /****************** Function: class_resolvefield_int ***************************
3120 This is an internally used helper function. Do not use this directly.
3122 Tries to resolve a field having the given name and type.
3123 If the field cannot be resolved, NULL is returned.
3125 *******************************************************************************/
3127 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
3132 /* search for field in class c */
3133 for (i = 0; i < c->fieldscount; i++) {
3134 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
3135 return &(c->fields[i]);
3139 /* try superinterfaces recursively */
3140 for (i = 0; i < c->interfacescount; ++i) {
3141 fi = class_resolvefield_int(c->interfaces[i], name, desc);
3146 /* try superclass */
3148 return class_resolvefield_int(c->super, name, desc);
3155 /********************* Function: class_resolvefield ***************************
3157 Resolves a reference from REFERER to a field with NAME and DESC in class C.
3159 If the field cannot be resolved the return value is NULL. If EXCEPT is
3160 true *exceptionptr is set, too.
3162 *******************************************************************************/
3164 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
3165 classinfo *referer, bool except)
3169 /* XXX resolve class c */
3170 /* XXX check access from REFERER to C */
3172 fi = class_resolvefield_int(c, name, desc);
3177 new_exception_utfmessage(string_java_lang_NoSuchFieldError,
3183 /* XXX check access rights */
3189 /************************* Function: class_findmethod **************************
3191 Searches a 'classinfo' structure for a method having the given name and
3192 type and returns the index in the class info structure.
3193 If type is NULL, it is ignored.
3195 *******************************************************************************/
3197 s4 class_findmethodIndex(classinfo *c, utf *name, utf *desc)
3201 for (i = 0; i < c->methodscount; i++) {
3203 /* utf_display_classname(c->name);printf("."); */
3204 /* utf_display(c->methods[i].name);printf("."); */
3205 /* utf_display(c->methods[i].descriptor); */
3208 if ((c->methods[i].name == name) && ((desc == NULL) ||
3209 (c->methods[i].descriptor == desc))) {
3218 /************************* Function: class_findmethod **************************
3220 Searches a 'classinfo' structure for a method having the given name and
3222 If type is NULL, it is ignored.
3224 *******************************************************************************/
3226 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
3228 s4 idx = class_findmethodIndex(c, name, desc);
3233 return &(c->methods[idx]);
3237 /*********************** Function: class_fetchmethod **************************
3239 like class_findmethod, but aborts with an error if the method is not found
3241 *******************************************************************************/
3243 methodinfo *class_fetchmethod(classinfo *c, utf *name, utf *desc)
3247 mi = class_findmethod(c, name, desc);
3250 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3251 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3252 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3253 panic("Method not found");
3260 /*********************** Function: class_findmethod_w**************************
3262 like class_findmethod, but logs a warning if the method is not found
3264 *******************************************************************************/
3266 methodinfo *class_findmethod_w(classinfo *c, utf *name, utf *desc, char *from)
3269 mi = class_findmethod(c, name, desc);
3272 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3273 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3274 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3276 if ( c->flags & ACC_PUBLIC ) log_plain(" PUBLIC ");
3277 if ( c->flags & ACC_PRIVATE ) log_plain(" PRIVATE ");
3278 if ( c->flags & ACC_PROTECTED ) log_plain(" PROTECTED ");
3279 if ( c->flags & ACC_STATIC ) log_plain(" STATIC ");
3280 if ( c->flags & ACC_FINAL ) log_plain(" FINAL ");
3281 if ( c->flags & ACC_SYNCHRONIZED ) log_plain(" SYNCHRONIZED ");
3282 if ( c->flags & ACC_VOLATILE ) log_plain(" VOLATILE ");
3283 if ( c->flags & ACC_TRANSIENT ) log_plain(" TRANSIENT ");
3284 if ( c->flags & ACC_NATIVE ) log_plain(" NATIVE ");
3285 if ( c->flags & ACC_INTERFACE ) log_plain(" INTERFACE ");
3286 if ( c->flags & ACC_ABSTRACT ) log_plain(" ABSTRACT ");
3289 log_plain(" : WARNING: Method not found");log_nl( );
3296 /************************* Function: class_findmethod_approx ******************
3298 like class_findmethod but ignores the return value when comparing the
3301 *******************************************************************************/
3303 methodinfo *class_findmethod_approx(classinfo *c, utf *name, utf *desc)
3307 for (i = 0; i < c->methodscount; i++) {
3308 if (c->methods[i].name == name) {
3309 utf *meth_descr = c->methods[i].descriptor;
3313 return &(c->methods[i]);
3315 if (desc->blength <= meth_descr->blength) {
3316 /* current position in utf text */
3317 char *desc_utf_ptr = desc->text;
3318 char *meth_utf_ptr = meth_descr->text;
3319 /* points behind utf strings */
3320 char *desc_end = utf_end(desc);
3321 char *meth_end = utf_end(meth_descr);
3324 /* compare argument types */
3325 while (desc_utf_ptr < desc_end && meth_utf_ptr < meth_end) {
3327 if ((ch = *desc_utf_ptr++) != (*meth_utf_ptr++))
3328 break; /* no match */
3331 return &(c->methods[i]); /* all parameter types equal */
3341 /***************** Function: class_resolvemethod_approx ***********************
3343 Searches a class and every super class for a method (without paying
3344 attention to the return value)
3346 *******************************************************************************/
3348 methodinfo *class_resolvemethod_approx(classinfo *c, utf *name, utf *desc)
3351 /* search for method (ignore returntype) */
3352 methodinfo *m = class_findmethod_approx(c, name, desc);
3355 /* search superclass */
3363 /************************* Function: class_resolvemethod ***********************
3365 Searches a class and every super class for a method.
3367 *******************************************************************************/
3369 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
3371 /*log_text("Trying to resolve a method");
3372 utf_display(c->name);
3374 utf_display(desc);*/
3377 /*log_text("Looking in:");
3378 utf_display(c->name);*/
3379 methodinfo *m = class_findmethod(c, name, desc);
3381 /* search superclass */
3384 /*log_text("method not found:");*/
3390 /****************** Function: class_resolveinterfacemethod_int ****************
3392 Internally used helper function. Do not use this directly.
3394 *******************************************************************************/
3397 methodinfo *class_resolveinterfacemethod_int(classinfo *c, utf *name, utf *desc)
3402 mi = class_findmethod(c,name,desc);
3406 /* try the superinterfaces */
3407 for (i=0; i<c->interfacescount; ++i) {
3408 mi = class_resolveinterfacemethod_int(c->interfaces[i],name,desc);
3416 /******************** Function: class_resolveinterfacemethod ******************
3418 Resolves a reference from REFERER to a method with NAME and DESC in
3421 If the method cannot be resolved the return value is NULL. If EXCEPT is
3422 true *exceptionptr is set, too.
3424 *******************************************************************************/
3426 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
3427 classinfo *referer, bool except)
3431 /* XXX resolve class c */
3432 /* XXX check access from REFERER to C */
3434 if (!(c->flags & ACC_INTERFACE)) {
3437 new_exception(string_java_lang_IncompatibleClassChangeError);
3442 mi = class_resolveinterfacemethod_int(c, name, desc);
3447 /* try class java.lang.Object */
3448 mi = class_findmethod(class_java_lang_Object, name, desc);
3455 new_exception_utfmessage(string_java_lang_NoSuchMethodError, name);
3461 /********************* Function: class_resolveclassmethod *********************
3463 Resolves a reference from REFERER to a method with NAME and DESC in
3466 If the method cannot be resolved the return value is NULL. If EXCEPT is
3467 true *exceptionptr is set, too.
3469 *******************************************************************************/
3471 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
3472 classinfo *referer, bool except)
3477 char msg[MAXLOGTEXT];
3479 /* XXX resolve class c */
3480 /* XXX check access from REFERER to C */
3482 /* if (c->flags & ACC_INTERFACE) { */
3484 /* *exceptionptr = */
3485 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
3489 /* try class c and its superclasses */
3492 mi = class_findmethod(cls, name, desc);
3495 } while ((cls = cls->super) != NULL); /* try the superclass */
3497 /* try the superinterfaces */
3498 for (i = 0; i < c->interfacescount; ++i) {
3499 mi = class_resolveinterfacemethod_int(c->interfaces[i], name, desc);
3505 utf_sprint(msg, c->name);
3506 sprintf(msg + strlen(msg), ".");
3507 utf_sprint(msg + strlen(msg), name);
3508 utf_sprint(msg + strlen(msg), desc);
3511 new_exception_message(string_java_lang_NoSuchMethodError, msg);
3517 if ((mi->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
3519 *exceptionptr = new_exception(string_java_lang_AbstractMethodError);
3524 /* XXX check access rights */
3530 /************************* Function: class_issubclass **************************
3532 Checks if sub is a descendant of super.
3534 *******************************************************************************/
3536 bool class_issubclass(classinfo *sub, classinfo *super)
3539 if (!sub) return false;
3540 if (sub == super) return true;
3546 /****************** Initialization function for classes ******************
3548 In Java, every class can have a static initialization function. This
3549 function has to be called BEFORE calling other methods or accessing static
3552 *******************************************************************************/
3554 static classinfo *class_init_intern(classinfo *c);
3556 classinfo *class_init(classinfo *c)
3560 if (!makeinitializations)
3563 /* enter a monitor on the class */
3565 builtin_monitorenter((java_objectheader *) c);
3567 /* maybe the class is already initalized or the current thread, which can
3568 pass the monitor, is currently initalizing this class */
3570 if (c->initialized || c->initializing) {
3571 builtin_monitorexit((java_objectheader *) c);
3576 /* this initalizing run begins NOW */
3577 c->initializing = true;
3579 /* call the internal function */
3580 r = class_init_intern(c);
3582 /* if return value is not NULL everything was ok and the class is
3585 c->initialized = true;
3587 /* this initalizing run is done */
3588 c->initializing = false;
3590 /* leave the monitor */
3592 builtin_monitorexit((java_objectheader *) c);
3598 /* this function MUST NOT be called directly, because of thread <clinit>
3601 static classinfo *class_init_intern(classinfo *c)
3605 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3617 #if defined(STATISTICS)
3619 count_class_inits++;
3622 /* initialize super class */
3624 if (!c->super->loaded)
3625 if (!class_load(c->super))
3628 if (!c->super->linked)
3629 if (!class_link(c->super))
3632 if (!c->super->initialized) {
3634 char logtext[MAXLOGTEXT];
3635 sprintf(logtext, "Initialize super class ");
3636 utf_sprint_classname(logtext + strlen(logtext), c->super->name);
3637 sprintf(logtext + strlen(logtext), " from ");
3638 utf_sprint_classname(logtext + strlen(logtext), c->name);
3642 if (!class_init(c->super))
3647 /* initialize interface classes */
3648 for (i = 0; i < c->interfacescount; i++) {
3649 if (!c->interfaces[i]->loaded)
3650 if (!class_load(c->interfaces[i]))
3653 if (!c->interfaces[i]->linked)
3654 if (!class_link(c->interfaces[i]))
3657 if (!c->interfaces[i]->initialized) {
3659 char logtext[MAXLOGTEXT];
3660 sprintf(logtext, "Initialize interface class ");
3661 utf_sprint_classname(logtext + strlen(logtext), c->interfaces[i]->name);
3662 sprintf(logtext + strlen(logtext), " from ");
3663 utf_sprint_classname(logtext + strlen(logtext), c->name);
3667 if (!class_init(c->interfaces[i]))
3672 m = class_findmethod(c, utf_clinit, utf_fidesc);
3676 char logtext[MAXLOGTEXT];
3677 sprintf(logtext, "Class ");
3678 utf_sprint_classname(logtext + strlen(logtext), c->name);
3679 sprintf(logtext + strlen(logtext), " has no static class initializer");
3686 if (!(m->flags & ACC_STATIC))
3687 panic("Class initializer is not static!");
3690 log_message_class("Starting static class initializer for class: ", c);
3692 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3697 /* now call the initializer */
3698 asm_calljavafunction(m, NULL, NULL, NULL, NULL);
3700 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3701 assert(blockInts == 0);
3705 /* we have an exception or error */
3706 if (*exceptionptr) {
3707 /* is this an exception, than wrap it */
3708 if (builtin_instanceof(*exceptionptr, class_java_lang_Exception)) {
3709 java_objectheader *xptr;
3710 java_objectheader *cause;
3712 /* class is NOT initialized */
3713 c->initialized = false;
3716 cause = *exceptionptr;
3718 /* clear exception, because we are calling jit code again */
3719 *exceptionptr = NULL;
3721 /* wrap the exception */
3723 new_exception_throwable(string_java_lang_ExceptionInInitializerError,
3724 (java_lang_Throwable *) cause);
3726 /* XXX should we exit here? */
3730 /* set new exception */
3731 *exceptionptr = xptr;
3738 log_message_class("Finished static class initializer for class: ", c);
3744 /********* Function: find_class_method_constant *********/
3746 int find_class_method_constant (classinfo *c, utf * c1, utf* m1, utf* d1)
3751 for (i=0; i<c->cpcount; i++) {
3753 e = c -> cpinfos [i];
3756 switch (c -> cptags [i]) {
3757 case CONSTANT_Methodref:
3759 constant_FMIref *fmi = e;
3760 if ( (fmi->class->name == c1)
3761 && (fmi->name == m1)
3762 && (fmi->descriptor == d1)) {
3769 case CONSTANT_InterfaceMethodref:
3771 constant_FMIref *fmi = e;
3772 if ( (fmi->class->name == c1)
3773 && (fmi->name == m1)
3774 && (fmi->descriptor == d1)) {
3788 void class_showconstanti(classinfo *c, int ii)
3794 printf ("#%d: ", (int) i);
3796 switch (c->cptags [i]) {
3797 case CONSTANT_Class:
3798 printf("Classreference -> ");
3799 utf_display(((classinfo*)e)->name);
3802 case CONSTANT_Fieldref:
3803 printf("Fieldref -> "); goto displayFMIi;
3804 case CONSTANT_Methodref:
3805 printf("Methodref -> "); goto displayFMIi;
3806 case CONSTANT_InterfaceMethodref:
3807 printf("InterfaceMethod -> "); goto displayFMIi;
3810 constant_FMIref *fmi = e;
3811 utf_display(fmi->class->name);
3813 utf_display(fmi->name);
3815 utf_display(fmi->descriptor);
3819 case CONSTANT_String:
3820 printf("String -> ");
3823 case CONSTANT_Integer:
3824 printf("Integer -> %d", (int) (((constant_integer*)e)->value));
3826 case CONSTANT_Float:
3827 printf("Float -> %f", ((constant_float*)e)->value);
3829 case CONSTANT_Double:
3830 printf("Double -> %f", ((constant_double*)e)->value);
3834 u8 v = ((constant_long*)e)->value;
3836 printf("Long -> %ld", (long int) v);
3838 printf("Long -> HI: %ld, LO: %ld\n",
3839 (long int) v.high, (long int) v.low);
3843 case CONSTANT_NameAndType:
3845 constant_nameandtype *cnt = e;
3846 printf("NameAndType: ");
3847 utf_display(cnt->name);
3849 utf_display(cnt->descriptor);
3857 panic("Invalid type of ConstantPool-Entry");
3864 void class_showconstantpool (classinfo *c)
3869 printf ("---- dump of constant pool ----\n");
3871 for (i=0; i<c->cpcount; i++) {
3872 printf ("#%d: ", (int) i);
3874 e = c -> cpinfos [i];
3877 switch (c -> cptags [i]) {
3878 case CONSTANT_Class:
3879 printf ("Classreference -> ");
3880 utf_display ( ((classinfo*)e) -> name );
3883 case CONSTANT_Fieldref:
3884 printf ("Fieldref -> "); goto displayFMI;
3885 case CONSTANT_Methodref:
3886 printf ("Methodref -> "); goto displayFMI;
3887 case CONSTANT_InterfaceMethodref:
3888 printf ("InterfaceMethod -> "); goto displayFMI;
3891 constant_FMIref *fmi = e;
3892 utf_display ( fmi->class->name );
3894 utf_display ( fmi->name);
3896 utf_display ( fmi->descriptor );
3900 case CONSTANT_String:
3901 printf ("String -> ");
3904 case CONSTANT_Integer:
3905 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
3907 case CONSTANT_Float:
3908 printf ("Float -> %f", ((constant_float*)e) -> value);
3910 case CONSTANT_Double:
3911 printf ("Double -> %f", ((constant_double*)e) -> value);
3915 u8 v = ((constant_long*)e) -> value;
3917 printf ("Long -> %ld", (long int) v);
3919 printf ("Long -> HI: %ld, LO: %ld\n",
3920 (long int) v.high, (long int) v.low);
3924 case CONSTANT_NameAndType:
3926 constant_nameandtype *cnt = e;
3927 printf ("NameAndType: ");
3928 utf_display (cnt->name);
3930 utf_display (cnt->descriptor);
3934 printf ("Utf8 -> ");
3938 panic ("Invalid type of ConstantPool-Entry");
3948 /********** Function: class_showmethods (debugging only) *************/
3950 void class_showmethods (classinfo *c)
3954 printf ("--------- Fields and Methods ----------------\n");
3955 printf ("Flags: "); printflags (c->flags); printf ("\n");
3957 printf ("This: "); utf_display (c->name); printf ("\n");
3959 printf ("Super: "); utf_display (c->super->name); printf ("\n");
3961 printf ("Index: %d\n", c->index);
3963 printf ("interfaces:\n");
3964 for (i=0; i < c-> interfacescount; i++) {
3966 utf_display (c -> interfaces[i] -> name);
3967 printf (" (%d)\n", c->interfaces[i] -> index);
3970 printf ("fields:\n");
3971 for (i=0; i < c -> fieldscount; i++) {
3972 field_display (&(c -> fields[i]));
3975 printf ("methods:\n");
3976 for (i=0; i < c -> methodscount; i++) {
3977 methodinfo *m = &(c->methods[i]);
3978 if ( !(m->flags & ACC_STATIC))
3979 printf ("vftblindex: %d ", m->vftblindex);
3981 method_display ( m );
3985 printf ("Virtual function table:\n");
3986 for (i=0; i<c->vftbl->vftbllength; i++) {
3987 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]) );
3993 /******************************************************************************/
3994 /******************* General functions for the class loader *******************/
3995 /******************************************************************************/
3997 /**************** function: create_primitive_classes ***************************
3999 create classes representing primitive types
4001 *******************************************************************************/
4003 void create_primitive_classes()
4007 for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
4008 /* create primitive class */
4010 class_new_intern(utf_new_char(primitivetype_table[i].name));
4011 c->classUsed = NOTUSED; /* not used initially CO-RT */
4014 /* prevent loader from loading primitive class */
4018 primitivetype_table[i].class_primitive = c;
4020 /* create class for wrapping the primitive type */
4021 c = class_new_intern(utf_new_char(primitivetype_table[i].wrapname));
4022 primitivetype_table[i].class_wrap = c;
4023 primitivetype_table[i].class_wrap->classUsed = NOTUSED; /* not used initially CO-RT */
4024 primitivetype_table[i].class_wrap->impldBy = NULL;
4026 /* create the primitive array class */
4027 if (primitivetype_table[i].arrayname) {
4028 c = class_new_intern(utf_new_char(primitivetype_table[i].arrayname));
4029 primitivetype_table[i].arrayclass = c;
4033 primitivetype_table[i].arrayvftbl = c->vftbl;
4039 /**************** function: class_primitive_from_sig ***************************
4041 return the primitive class indicated by the given signature character
4043 If the descriptor does not indicate a valid primitive type the
4044 return value is NULL.
4046 ********************************************************************************/
4048 classinfo *class_primitive_from_sig(char sig)
4051 case 'I': return primitivetype_table[PRIMITIVETYPE_INT].class_primitive;
4052 case 'J': return primitivetype_table[PRIMITIVETYPE_LONG].class_primitive;
4053 case 'F': return primitivetype_table[PRIMITIVETYPE_FLOAT].class_primitive;
4054 case 'D': return primitivetype_table[PRIMITIVETYPE_DOUBLE].class_primitive;
4055 case 'B': return primitivetype_table[PRIMITIVETYPE_BYTE].class_primitive;
4056 case 'C': return primitivetype_table[PRIMITIVETYPE_CHAR].class_primitive;
4057 case 'S': return primitivetype_table[PRIMITIVETYPE_SHORT].class_primitive;
4058 case 'Z': return primitivetype_table[PRIMITIVETYPE_BOOLEAN].class_primitive;
4059 case 'V': return primitivetype_table[PRIMITIVETYPE_VOID].class_primitive;
4064 /****************** function: class_from_descriptor ****************************
4066 return the class indicated by the given descriptor
4068 utf_ptr....first character of descriptor
4069 end_ptr....first character after the end of the string
4070 next.......if non-NULL, *next is set to the first character after
4071 the descriptor. (Undefined if an error occurs.)
4073 mode.......a combination (binary or) of the following flags:
4075 (Flags marked with * are the default settings.)
4077 What to do if a reference type descriptor is parsed successfully:
4079 CLASSLOAD_SKIP...skip it and return something != NULL
4080 * CLASSLOAD_NEW....get classinfo * via class_new
4081 CLASSLOAD_LOAD...get classinfo * via loader_load
4083 How to handle primitive types:
4085 * CLASSLOAD_PRIMITIVE.......return primitive class (eg. "int")
4086 CLASSLOAD_NULLPRIMITIVE...return NULL for primitive types
4088 How to handle "V" descriptors:
4090 * CLASSLOAD_VOID.....handle it like other primitive types
4091 CLASSLOAD_NOVOID...treat it as an error
4093 How to deal with extra characters after the end of the
4096 * CLASSLOAD_NOCHECKEND...ignore (useful for parameter lists)
4097 CLASSLOAD_CHECKEND.....treat them as an error
4099 How to deal with errors:
4101 * CLASSLOAD_PANIC....abort execution with an error message
4102 CLASSLOAD_NOPANIC..return NULL on error
4104 *******************************************************************************/
4106 classinfo *class_from_descriptor(char *utf_ptr, char *end_ptr,
4107 char **next, int mode)
4109 char *start = utf_ptr;
4113 SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr, end_ptr, error);
4115 if (mode & CLASSLOAD_CHECKEND)
4116 error |= (utf_ptr != end_ptr);
4119 if (next) *next = utf_ptr;
4123 if (mode & CLASSLOAD_NOVOID)
4134 return (mode & CLASSLOAD_NULLPRIMITIVE)
4136 : class_primitive_from_sig(*start);
4143 if (mode & CLASSLOAD_SKIP) return class_java_lang_Object;
4144 name = utf_new(start, utf_ptr - start);
4148 tc = class_new_intern(name);
4150 list_addfirst(&unlinkedclasses, tc);
4155 return (mode & CLASSLOAD_LOAD)
4156 ? class_load(class_new(name)) : class_new(name); /* XXX handle errors */
4161 /* An error occurred */
4162 if (mode & CLASSLOAD_NOPANIC)
4165 log_plain("Invalid descriptor at beginning of '");
4166 log_plain_utf(utf_new(start, end_ptr - start));
4170 panic("Invalid descriptor");
4172 /* keep compiler happy */
4177 /******************* function: type_from_descriptor ****************************
4179 return the basic type indicated by the given descriptor
4181 This function parses a descriptor and returns its basic type as
4182 TYPE_INT, TYPE_LONG, TYPE_FLOAT, TYPE_DOUBLE, TYPE_ADDRESS or TYPE_VOID.
4184 cls...if non-NULL the referenced variable is set to the classinfo *
4185 returned by class_from_descriptor.
4187 For documentation of the arguments utf_ptr, end_ptr, next and mode
4188 see class_from_descriptor. The only difference is that
4189 type_from_descriptor always uses CLASSLOAD_PANIC.
4191 ********************************************************************************/
4193 int type_from_descriptor(classinfo **cls, char *utf_ptr, char *end_ptr,
4194 char **next, int mode)
4197 if (!cls) cls = &mycls;
4198 *cls = class_from_descriptor(utf_ptr, end_ptr, next, mode & (~CLASSLOAD_NOPANIC));
4215 return TYPE_ADDRESS;
4219 /*************** function: create_pseudo_classes *******************************
4221 create pseudo classes used by the typechecker
4223 ********************************************************************************/
4225 static void create_pseudo_classes()
4227 /* pseudo class for Arraystubs (extends java.lang.Object) */
4229 pseudo_class_Arraystub = class_new_intern(utf_new_char("$ARRAYSTUB$"));
4230 pseudo_class_Arraystub->loaded = true;
4231 pseudo_class_Arraystub->super = class_java_lang_Object;
4232 pseudo_class_Arraystub->interfacescount = 2;
4233 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
4234 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
4235 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
4237 class_link(pseudo_class_Arraystub);
4239 pseudo_class_Arraystub_vftbl = pseudo_class_Arraystub->vftbl;
4241 /* pseudo class representing the null type */
4243 pseudo_class_Null = class_new_intern(utf_new_char("$NULL$"));
4244 pseudo_class_Null->loaded = true;
4245 pseudo_class_Null->super = class_java_lang_Object;
4246 class_link(pseudo_class_Null);
4248 /* pseudo class representing new uninitialized objects */
4250 pseudo_class_New = class_new_intern(utf_new_char("$NEW$"));
4251 pseudo_class_New->loaded = true;
4252 pseudo_class_New->linked = true;
4253 pseudo_class_New->super = class_java_lang_Object;
4254 /* class_link(pseudo_class_New); */
4258 /********************** Function: loader_init **********************************
4260 Initializes all lists and loads all classes required for the system or the
4263 *******************************************************************************/
4265 void loader_init(u1 *stackbottom)
4269 /* create utf-symbols for pointer comparison of frequently used strings */
4270 utf_innerclasses = utf_new_char("InnerClasses");
4271 utf_constantvalue = utf_new_char("ConstantValue");
4272 utf_code = utf_new_char("Code");
4273 utf_exceptions = utf_new_char("Exceptions");
4274 utf_linenumbertable = utf_new_char("LineNumberTable");
4275 utf_sourcefile = utf_new_char("SourceFile");
4276 utf_finalize = utf_new_char("finalize");
4277 utf_fidesc = utf_new_char("()V");
4278 utf_init = utf_new_char("<init>");
4279 utf_clinit = utf_new_char("<clinit>");
4280 utf_initsystemclass = utf_new_char("initializeSystemClass");
4281 utf_systemclass = utf_new_char("java/lang/System");
4282 utf_vmclassloader = utf_new_char("java/lang/VMClassLoader");
4283 utf_initialize = utf_new_char("initialize");
4284 utf_initializedesc = utf_new_char("(I)V");
4285 utf_vmclass = utf_new_char("java/lang/VMClass");
4286 utf_java_lang_Object= utf_new_char("java/lang/Object");
4287 array_packagename = utf_new_char("<the array package>");
4288 utf_fillInStackTrace_name = utf_new_char("fillInStackTrace");
4289 utf_fillInStackTrace_desc = utf_new_char("()Ljava/lang/Throwable;");
4291 /* create some important classes */
4292 /* These classes have to be created now because the classinfo
4293 * pointers are used in the loading code.
4295 class_java_lang_Object =
4296 class_new_intern(utf_java_lang_Object);
4297 class_load(class_java_lang_Object);
4298 class_link(class_java_lang_Object);
4300 class_java_lang_String =
4301 class_new_intern(utf_new_char("java/lang/String"));
4302 class_load(class_java_lang_String);
4303 class_link(class_java_lang_String);
4305 class_java_lang_Cloneable =
4306 class_new_intern(utf_new_char("java/lang/Cloneable"));
4307 class_load(class_java_lang_Cloneable);
4308 class_link(class_java_lang_Cloneable);
4310 class_java_io_Serializable =
4311 class_new_intern(utf_new_char("java/io/Serializable"));
4312 class_load(class_java_io_Serializable);
4313 class_link(class_java_io_Serializable);
4315 /* create classes representing primitive types */
4316 create_primitive_classes();
4318 /* create classes used by the typechecker */
4319 create_pseudo_classes();
4321 /* correct vftbl-entries (retarded loading of class java/lang/String) */
4322 stringtable_update();
4324 #if defined(USE_THREADS)
4325 if (stackbottom != 0)
4331 static void loader_compute_class_values(classinfo *c)
4335 c->vftbl->baseval = ++classvalue;
4338 while (subs != NULL) {
4339 loader_compute_class_values(subs);
4340 subs = subs->nextsub;
4343 c->vftbl->diffval = classvalue - c->vftbl->baseval;
4347 void loader_compute_subclasses(classinfo *c)
4349 #if defined(USE_THREADS)
4350 #if defined(NATIVE_THREADS)
4357 if (!(c->flags & ACC_INTERFACE)) {
4362 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
4363 c->nextsub = c->super->sub;
4369 /* this is the java.lang.Object special case */
4370 if (!class_java_lang_Object) {
4371 loader_compute_class_values(c);
4374 loader_compute_class_values(class_java_lang_Object);
4377 #if defined(USE_THREADS)
4378 #if defined(NATIVE_THREADS)
4387 /******************** Function: loader_close ***********************************
4391 *******************************************************************************/
4398 for (slot = 0; slot < class_hash.size; slot++) {
4399 c = class_hash.ptr[slot];
4410 * These are local overrides for various environment variables in Emacs.
4411 * Please do not remove this and leave it at the end of the file, where
4412 * Emacs will automagically detect them.
4413 * ---------------------------------------------------------------------
4416 * indent-tabs-mode: t