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 1237 2004-06-30 19:54:59Z twisti $
53 #include "statistics.h"
54 #include "toolbox/memory.h"
55 #include "toolbox/logging.h"
56 #include "threads/thread.h"
57 #include "threads/locks.h"
58 #include "nat/java_lang_Throwable.h"
68 /* global variables ***********************************************************/
70 static s4 interfaceindex; /* sequential numbering of interfaces */
74 /* utf-symbols for pointer comparison of frequently used strings */
76 static utf *utf_innerclasses; /* InnerClasses */
77 static utf *utf_constantvalue; /* ConstantValue */
78 static utf *utf_code; /* Code */
79 static utf *utf_exceptions; /* Exceptions */
80 static utf *utf_linenumbertable; /* LineNumberTable */
81 static utf *utf_sourcefile; /* SourceFile */
82 static utf *utf_finalize; /* finalize */
83 static utf *utf_fidesc; /* ()V changed */
84 static utf *utf_init; /* <init> */
85 static utf *utf_clinit; /* <clinit> */
86 static utf *utf_initsystemclass; /* initializeSystemClass */
87 static utf *utf_systemclass; /* java/lang/System */
88 static utf *utf_vmclassloader; /* java/lang/VMClassLoader */
89 static utf *utf_vmclass; /* java/lang/VMClassLoader */
90 static utf *utf_initialize;
91 static utf *utf_initializedesc;
92 static utf *utf_java_lang_Object; /* java/lang/Object */
94 utf *utf_fillInStackTrace_name;
95 utf *utf_fillInStackTrace_desc;
105 /* important system classes ***************************************************/
107 classinfo *class_java_lang_Object;
108 classinfo *class_java_lang_String;
109 classinfo *class_java_lang_Cloneable;
110 classinfo *class_java_io_Serializable;
112 /* Pseudo classes for the typechecker */
113 classinfo *pseudo_class_Arraystub = NULL;
114 classinfo *pseudo_class_Null = NULL;
115 classinfo *pseudo_class_New = NULL;
116 vftbl *pseudo_class_Arraystub_vftbl = NULL;
118 utf *array_packagename = NULL;
121 /********************************************************************
122 list of classpath entries (either filesystem directories or
124 ********************************************************************/
125 static classpath_info *classpath_entries=0;
128 /******************************************************************************
130 structure for primitive classes: contains the class for wrapping the
131 primitive type, the primitive class, the name of the class for wrapping,
132 the one character type signature and the name of the primitive class
134 ******************************************************************************/
136 /* CAUTION: Don't change the order of the types. This table is indexed
137 * by the ARRAYTYPE_ constants (expcept ARRAYTYPE_OBJECT).
139 primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = {
140 { NULL, NULL, "java/lang/Integer", 'I', "int" , "[I", NULL, NULL },
141 { NULL, NULL, "java/lang/Long", 'J', "long" , "[J", NULL, NULL },
142 { NULL, NULL, "java/lang/Float", 'F', "float" , "[F", NULL, NULL },
143 { NULL, NULL, "java/lang/Double", 'D', "double" , "[D", NULL, NULL },
144 { NULL, NULL, "java/lang/Byte", 'B', "byte" , "[B", NULL, NULL },
145 { NULL, NULL, "java/lang/Character", 'C', "char" , "[C", NULL, NULL },
146 { NULL, NULL, "java/lang/Short", 'S', "short" , "[S", NULL, NULL },
147 { NULL, NULL, "java/lang/Boolean", 'Z', "boolean" , "[Z", NULL, NULL },
148 { NULL, NULL, "java/lang/Void", 'V', "void" , NULL, NULL, NULL }
152 /* instances of important system classes **************************************/
154 java_objectheader *proto_java_lang_NullPointerException;
157 /************* functions for reading classdata *********************************
159 getting classdata in blocks of variable size
160 (8,16,32,64-bit integer or float)
162 *******************************************************************************/
164 static char *classpath = ""; /* searchpath for classfiles */
167 static java_objectheader *new_classformaterror(classinfo *c, char *message, ...)
169 char cfmessage[MAXLOGTEXT];
172 utf_sprint_classname(cfmessage, c->name);
173 sprintf(cfmessage + strlen(cfmessage), " (");
175 va_start(ap, message);
176 vsprintf(cfmessage + strlen(cfmessage), message, ap);
179 sprintf(cfmessage + strlen(cfmessage), ")");
181 return new_exception_message(string_java_lang_ClassFormatError, cfmessage);
185 /* check_classbuffer_size ******************************************************
187 assert that at least <len> bytes are left to read
188 <len> is limited to the range of non-negative s4 values
190 *******************************************************************************/
192 static inline bool check_classbuffer_size(classbuffer *cb, s4 len)
194 if (len < 0 || ((cb->data + cb->size) - cb->pos - 1) < len) {
196 new_classformaterror((cb)->class, "Truncated class file");
205 /* suck_nbytes *****************************************************************
207 transfer block of classfile data into a buffer
209 *******************************************************************************/
211 inline void suck_nbytes(u1 *buffer, classbuffer *cb, s4 len)
213 memcpy(buffer, cb->pos + 1, len);
218 /* skip_nbytes ****************************************************************
220 skip block of classfile data
222 *******************************************************************************/
224 inline void skip_nbytes(classbuffer *cb, s4 len)
230 inline u1 suck_u1(classbuffer *cb)
236 inline u2 suck_u2(classbuffer *cb)
240 return ((u2) a << 8) + (u2) b;
244 inline u4 suck_u4(classbuffer *cb)
250 return ((u4) a << 24) + ((u4) b << 16) + ((u4) c << 8) + (u4) d;
253 #define suck_s8(a) (s8) suck_u8((a))
254 #define suck_s2(a) (s2) suck_u2((a))
255 #define suck_s4(a) (s4) suck_u4((a))
256 #define suck_s1(a) (s1) suck_u1((a))
259 /* get u8 from classfile data */
260 static u8 suck_u8(classbuffer *cb)
266 return (hi << 32) + lo;
269 v.high = suck_u4(cb);
276 /* get float from classfile data */
277 static float suck_float(classbuffer *cb)
285 for (i = 0; i < 4; i++)
286 buffer[3 - i] = suck_u1(cb);
288 memcpy((u1*) (&f), buffer, 4);
290 suck_nbytes((u1*) (&f), cb, 4);
293 if (sizeof(float) != 4) {
294 *exceptionptr = new_exception_message(string_java_lang_InternalError,
295 "Incompatible float-format");
297 /* XXX should we exit in such a case? */
298 throw_exception_exit();
305 /* get double from classfile data */
306 static double suck_double(classbuffer *cb)
314 for (i = 0; i < 8; i++)
315 buffer[7 - i] = suck_u1(cb);
317 memcpy((u1*) (&d), buffer, 8);
319 suck_nbytes((u1*) (&d), cb, 8);
322 if (sizeof(double) != 8) {
323 *exceptionptr = new_exception_message(string_java_lang_InternalError,
324 "Incompatible double-format");
326 /* XXX should we exit in such a case? */
327 throw_exception_exit();
334 /************************** function suck_init *********************************
336 called once at startup, sets the searchpath for the classfiles
338 *******************************************************************************/
340 void suck_init(char *cpath)
347 union classpath_info *tmp;
348 union classpath_info *insertAfter=0;
355 if (classpath_entries)
356 panic("suck_init should be called only once");
358 for (start = classpath; (*start) != '\0';) {
359 for (end = start; ((*end) != '\0') && ((*end) != ':'); end++);
363 filenamelen = end - start;
366 if (strncasecmp(end - 3, "zip", 3) == 0 ||
367 strncasecmp(end - 3, "jar", 3) == 0) {
372 if (filenamelen >= (CLASSPATH_MAXFILENAME - 1))
373 panic("path length >= MAXFILENAME in suck_init");
376 filename = MNEW(char, CLASSPATH_MAXFILENAME);
378 strncpy(filename, start, filenamelen);
379 filename[filenamelen + 1] = '\0';
384 unzFile uf = unzOpen(filename);
387 tmp = (union classpath_info *) NEW(classpath_info);
388 tmp->archive.type = CLASSPATH_ARCHIVE;
389 tmp->archive.uf = uf;
390 tmp->archive.next = 0;
394 panic("Zip/JAR not supported");
398 tmp = (union classpath_info *) NEW(classpath_info);
399 tmp->filepath.type = CLASSPATH_PATH;
400 tmp->filepath.next = 0;
402 if (filename[filenamelen - 1] != '/') {/*PERHAPS THIS SHOULD BE READ FROM A GLOBAL CONFIGURATION */
403 filename[filenamelen] = '/';
404 filename[filenamelen + 1] = '\0';
408 tmp->filepath.filename = filename;
409 tmp->filepath.pathlen = filenamelen;
415 insertAfter->filepath.next = tmp;
418 classpath_entries = tmp;
430 MFREE(filename, char, CLASSPATH_MAXFILENAME);
437 void create_all_classes()
441 for (cpi = classpath_entries; cpi != 0; cpi = cpi->filepath.next) {
442 #if defined(USE_ZLIB)
443 if (cpi->filepath.type == CLASSPATH_ARCHIVE) {
447 s = (unz_s *) cpi->archive.uf;
448 ce = s->cacao_dir_list;
451 (void) class_new(ce->name);
457 #if defined(USE_ZLIB)
464 /************************** function suck_start ********************************
466 returns true if classbuffer is already loaded or a file for the
467 specified class has succussfully been read in. All directories of
468 the searchpath are used to find the classfile (<classname>.class).
469 Returns false if no classfile is found and writes an error message.
471 *******************************************************************************/
473 classbuffer *suck_start(classinfo *c)
475 classpath_info *currPos;
478 char filename[CLASSPATH_MAXFILENAME+10]; /* room for '.class' */
485 utf_ptr = c->name->text;
487 while (utf_ptr < utf_end(c->name)) {
488 if (filenamelen >= CLASSPATH_MAXFILENAME) {
490 new_exception_message(string_java_lang_InternalError,
491 "Filename too long");
493 /* XXX should we exit in such a case? */
494 throw_exception_exit();
498 if ((ch <= ' ' || ch > 'z') && (ch != '/')) /* invalid character */
500 filename[filenamelen++] = ch;
503 strcpy(filename + filenamelen, ".class");
506 for (currPos = classpath_entries; currPos != 0; currPos = currPos->filepath.next) {
508 if (currPos->filepath.type == CLASSPATH_ARCHIVE) {
509 if (cacao_locate(currPos->archive.uf, c->name) == UNZ_OK) {
510 unz_file_info file_info;
511 /*log_text("Class found in zip file");*/
512 if (unzGetCurrentFileInfo(currPos->archive.uf, &file_info, filename,
513 sizeof(filename), NULL, 0, NULL, 0) == UNZ_OK) {
514 if (unzOpenCurrentFile(currPos->archive.uf) == UNZ_OK) {
515 cb = NEW(classbuffer);
517 cb->size = file_info.uncompressed_size;
518 cb->data = MNEW(u1, cb->size);
519 cb->pos = cb->data - 1;
520 /*printf("classfile size: %d\n",file_info.uncompressed_size);*/
521 if (unzReadCurrentFile(currPos->archive.uf, cb->data, cb->size) == cb->size) {
522 unzCloseCurrentFile(currPos->archive.uf);
526 MFREE(cb->data, u1, cb->size);
527 FREE(cb, classbuffer);
528 log_text("Error while unzipping");
530 } else log_text("Error while opening file in archive");
531 } else log_text("Error while retrieving fileinfo");
533 unzCloseCurrentFile(currPos->archive.uf);
537 if ((currPos->filepath.pathlen + filenamelen) >= CLASSPATH_MAXFILENAME) continue;
538 strcpy(currPos->filepath.filename + currPos->filepath.pathlen, filename);
539 classfile = fopen(currPos->filepath.filename, "r");
540 if (classfile) { /* file exists */
542 /* determine size of classfile */
544 /* dolog("File: %s",filename); */
545 err = stat(currPos->filepath.filename, &buffer);
547 if (!err) { /* read classfile data */
548 cb = NEW(classbuffer);
550 cb->size = buffer.st_size;
551 cb->data = MNEW(u1, cb->size);
552 cb->pos = cb->data - 1;
553 fread(cb->data, 1, cb->size, classfile);
565 dolog("Warning: Can not open class file '%s'", filename);
572 /************************** function suck_stop *********************************
574 frees memory for buffer with classfile data.
575 Caution: this function may only be called if buffer has been allocated
576 by suck_start with reading a file
578 *******************************************************************************/
580 void suck_stop(classbuffer *cb)
584 MFREE(cb->data, u1, cb->size);
585 FREE(cb, classbuffer);
589 /******************************************************************************/
590 /******************* Some support functions ***********************************/
591 /******************************************************************************/
593 void fprintflags (FILE *fp, u2 f)
595 if ( f & ACC_PUBLIC ) fprintf (fp," PUBLIC");
596 if ( f & ACC_PRIVATE ) fprintf (fp," PRIVATE");
597 if ( f & ACC_PROTECTED ) fprintf (fp," PROTECTED");
598 if ( f & ACC_STATIC ) fprintf (fp," STATIC");
599 if ( f & ACC_FINAL ) fprintf (fp," FINAL");
600 if ( f & ACC_SYNCHRONIZED ) fprintf (fp," SYNCHRONIZED");
601 if ( f & ACC_VOLATILE ) fprintf (fp," VOLATILE");
602 if ( f & ACC_TRANSIENT ) fprintf (fp," TRANSIENT");
603 if ( f & ACC_NATIVE ) fprintf (fp," NATIVE");
604 if ( f & ACC_INTERFACE ) fprintf (fp," INTERFACE");
605 if ( f & ACC_ABSTRACT ) fprintf (fp," ABSTRACT");
609 /********** internal function: printflags (only for debugging) ***************/
611 void printflags(u2 f)
613 if ( f & ACC_PUBLIC ) printf (" PUBLIC");
614 if ( f & ACC_PRIVATE ) printf (" PRIVATE");
615 if ( f & ACC_PROTECTED ) printf (" PROTECTED");
616 if ( f & ACC_STATIC ) printf (" STATIC");
617 if ( f & ACC_FINAL ) printf (" FINAL");
618 if ( f & ACC_SYNCHRONIZED ) printf (" SYNCHRONIZED");
619 if ( f & ACC_VOLATILE ) printf (" VOLATILE");
620 if ( f & ACC_TRANSIENT ) printf (" TRANSIENT");
621 if ( f & ACC_NATIVE ) printf (" NATIVE");
622 if ( f & ACC_INTERFACE ) printf (" INTERFACE");
623 if ( f & ACC_ABSTRACT ) printf (" ABSTRACT");
627 /********************** Function: skipattributebody ****************************
629 skips an attribute after the 16 bit reference to attribute_name has already
632 *******************************************************************************/
634 static bool skipattributebody(classbuffer *cb)
638 if (!check_classbuffer_size(cb, 4))
643 if (!check_classbuffer_size(cb, len))
646 skip_nbytes(cb, len);
652 /************************* Function: skipattributes ****************************
654 skips num attribute structures
656 *******************************************************************************/
658 static bool skipattributes(classbuffer *cb, u4 num)
663 for (i = 0; i < num; i++) {
664 if (!check_classbuffer_size(cb, 2 + 4))
670 if (!check_classbuffer_size(cb, len))
673 skip_nbytes(cb, len);
680 /******************** function: innerclass_getconstant ************************
682 like class_getconstant, but if cptags is ZERO null is returned
684 *******************************************************************************/
686 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
688 /* invalid position in constantpool */
689 if (pos >= c->cpcount)
690 panic("Attempt to access constant outside range");
692 /* constantpool entry of type 0 */
696 /* check type of constantpool entry */
697 if (c->cptags[pos] != ctype) {
698 error("Type mismatch on constant: %d requested, %d here (innerclass_getconstant)",
699 (int) ctype, (int) c->cptags[pos] );
702 return c->cpinfos[pos];
706 /************************ function: attribute_load ****************************
708 read attributes from classfile
710 *******************************************************************************/
712 static bool attribute_load(classbuffer *cb, classinfo *c, u4 num)
716 for (i = 0; i < num; i++) {
719 /* retrieve attribute name */
720 if (!check_classbuffer_size(cb, 2))
723 aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
725 if (aname == utf_innerclasses) {
726 /* innerclasses attribute */
727 if (c->innerclass != NULL)
728 panic("Class has more than one InnerClasses attribute");
730 if (!check_classbuffer_size(cb, 4 + 2))
733 /* skip attribute length */
736 /* number of records */
737 c->innerclasscount = suck_u2(cb);
739 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
742 /* allocate memory for innerclass structure */
743 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
745 for (j = 0; j < c->innerclasscount; j++) {
746 /* The innerclass structure contains a class with an encoded
747 name, its defining scope, its simple name and a bitmask of
748 the access flags. If an inner class is not a member, its
749 outer_class is NULL, if a class is anonymous, its name is
752 innerclassinfo *info = c->innerclass + j;
755 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
757 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
759 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
760 info->flags = suck_u2(cb);
763 } else if (aname == utf_sourcefile) {
764 if (!check_classbuffer_size(cb, 4 + 2))
768 c->sourcefile = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
771 /* unknown attribute */
772 if (!skipattributebody(cb))
781 /******************* function: checkfielddescriptor ****************************
783 checks whether a field-descriptor is valid and aborts otherwise
784 all referenced classes are inserted into the list of unloaded classes
786 *******************************************************************************/
788 static void checkfielddescriptor (char *utf_ptr, char *end_pos)
790 class_from_descriptor(utf_ptr,end_pos,NULL,
792 | CLASSLOAD_NULLPRIMITIVE
794 | CLASSLOAD_CHECKEND);
796 /* XXX use the following if -noverify */
798 char *tstart; /* pointer to start of classname */
800 char *start = utf_ptr;
802 switch (*utf_ptr++) {
816 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
817 panic ("Ill formed descriptor");
821 panic ("Ill formed descriptor");
824 /* exceeding characters */
825 if (utf_ptr!=end_pos) panic ("descriptor has exceeding chars");
830 /******************* function checkmethoddescriptor ****************************
832 checks whether a method-descriptor is valid and aborts otherwise.
833 All referenced classes are inserted into the list of unloaded classes.
835 The number of arguments is returned. A long or double argument is counted
838 *******************************************************************************/
840 static int checkmethoddescriptor(classinfo *c, utf *descriptor)
842 char *utf_ptr; /* current position in utf text */
843 char *end_pos; /* points behind utf string */
844 s4 argcount = 0; /* number of arguments */
846 utf_ptr = descriptor->text;
847 end_pos = utf_end(descriptor);
849 /* method descriptor must start with parenthesis */
850 if (utf_ptr == end_pos || *utf_ptr++ != '(')
851 panic ("Missing '(' in method descriptor");
853 /* check arguments */
854 while (utf_ptr != end_pos && *utf_ptr != ')') {
855 /* We cannot count the this argument here because
856 * we don't know if the method is static. */
857 if (*utf_ptr == 'J' || *utf_ptr == 'D')
861 class_from_descriptor(utf_ptr,end_pos,&utf_ptr,
863 | CLASSLOAD_NULLPRIMITIVE
867 if (utf_ptr == end_pos)
868 panic("Missing ')' in method descriptor");
870 utf_ptr++; /* skip ')' */
872 class_from_descriptor(utf_ptr,
876 CLASSLOAD_NULLPRIMITIVE |
879 if (argcount > 255) {
881 new_classformaterror(c, "Too many arguments in signature");
888 /* XXX use the following if -noverify */
890 /* check arguments */
891 while ((c = *utf_ptr++) != ')') {
908 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
909 panic ("Ill formed method descriptor");
913 panic ("Ill formed methodtype-descriptor");
917 /* check returntype */
919 /* returntype void */
920 if ((utf_ptr+1) != end_pos) panic ("Method-descriptor has exceeding chars");
923 /* treat as field-descriptor */
924 checkfielddescriptor (utf_ptr,end_pos);
929 /***************** Function: print_arraydescriptor ****************************
931 Debugging helper for displaying an arraydescriptor
933 *******************************************************************************/
935 void print_arraydescriptor(FILE *file, arraydescriptor *desc)
938 fprintf(file, "<NULL>");
943 if (desc->componentvftbl) {
944 if (desc->componentvftbl->class)
945 utf_fprint(file, desc->componentvftbl->class->name);
947 fprintf(file, "<no classinfo>");
953 if (desc->elementvftbl) {
954 if (desc->elementvftbl->class)
955 utf_fprint(file, desc->elementvftbl->class->name);
957 fprintf(file, "<no classinfo>");
961 fprintf(file, ",%d,%d,%d,%d}", desc->arraytype, desc->dimension,
962 desc->dataoffset, desc->componentsize);
966 /******************************************************************************/
967 /************************** Functions for fields ****************************/
968 /******************************************************************************/
971 /* field_load ******************************************************************
973 Load everything about a class field from the class file and fill a
974 'fieldinfo' structure. For static fields, space in the data segment is
977 *******************************************************************************/
979 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
981 static bool field_load(classbuffer *cb, classinfo *c, fieldinfo *f)
985 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
987 if (!check_classbuffer_size(cb, 2 + 2 + 2))
990 f->flags = suck_u2(cb);
991 f->name = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
992 f->descriptor = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
996 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<')
997 panic("Field with invalid name");
999 /* check flag consistency */
1000 i = (f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1002 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED)
1003 panic("Field has invalid access flags");
1005 if ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))
1006 panic("Field is declared final and volatile");
1008 if ((c->flags & ACC_INTERFACE) != 0) {
1009 if ((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
1010 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
1011 panic("Interface field is not declared static final public");
1013 if ((f->flags & ACC_TRANSIENT) != 0)
1014 panic("Interface field declared transient");
1017 /* check descriptor */
1018 checkfielddescriptor(f->descriptor->text, utf_end(f->descriptor));
1021 f->type = jtype = desc_to_type(f->descriptor); /* data type */
1022 f->offset = 0; /* offset from start of object */
1027 case TYPE_INT: f->value.i = 0; break;
1028 case TYPE_FLOAT: f->value.f = 0.0; break;
1029 case TYPE_DOUBLE: f->value.d = 0.0; break;
1030 case TYPE_ADDRESS: f->value.a = NULL; break;
1033 f->value.l = 0; break;
1035 f->value.l.low = 0; f->value.l.high = 0; break;
1039 /* read attributes */
1040 if (!check_classbuffer_size(cb, 2))
1043 attrnum = suck_u2(cb);
1044 for (i = 0; i < attrnum; i++) {
1047 if (!check_classbuffer_size(cb, 2))
1050 aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1052 if (aname != utf_constantvalue) {
1053 /* unknown attribute */
1054 if (!skipattributebody(cb))
1058 /* constant value attribute */
1059 if (pindex != field_load_NOVALUE)
1060 panic("Field has more than one ConstantValue attribute");
1062 if (!check_classbuffer_size(cb, 4 + 2))
1065 /* check attribute length */
1066 if (suck_u4(cb) != 2)
1067 panic("ConstantValue attribute has invalid length");
1069 /* index of value in constantpool */
1070 pindex = suck_u2(cb);
1072 /* initialize field with value from constantpool */
1075 constant_integer *ci =
1076 class_getconstant(c, pindex, CONSTANT_Integer);
1077 f->value.i = ci->value;
1083 class_getconstant(c, pindex, CONSTANT_Long);
1084 f->value.l = cl->value;
1089 constant_float *cf =
1090 class_getconstant(c, pindex, CONSTANT_Float);
1091 f->value.f = cf->value;
1096 constant_double *cd =
1097 class_getconstant(c, pindex, CONSTANT_Double);
1098 f->value.d = cd->value;
1102 case TYPE_ADDRESS: {
1103 utf *u = class_getconstant(c, pindex, CONSTANT_String);
1104 /* create javastring from compressed utf8-string */
1105 f->value.a = literalstring_new(u);
1110 log_text ("Invalid Constant - Type");
1115 /* everything was ok */
1121 /********************** function: field_free **********************************/
1123 static void field_free(fieldinfo *f)
1129 /**************** Function: field_display (debugging only) ********************/
1131 void field_display(fieldinfo *f)
1134 printflags(f->flags);
1136 utf_display(f->name);
1138 utf_display(f->descriptor);
1139 printf(" offset: %ld\n", (long int) (f->offset));
1143 /******************************************************************************/
1144 /************************* Functions for methods ******************************/
1145 /******************************************************************************/
1148 /* method_load *****************************************************************
1150 Loads a method from the class file and fills an existing 'methodinfo'
1151 structure. For native methods, the function pointer field is set to the
1152 real function pointer, for JavaVM methods a pointer to the compiler is used
1155 *******************************************************************************/
1157 static bool method_load(classbuffer *cb, classinfo *c, methodinfo *m)
1166 count_all_methods++;
1169 m->thrownexceptionscount = 0;
1170 m->linenumbercount = 0;
1173 m->nativelyoverloaded = false;
1175 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1178 m->flags = suck_u2(cb);
1179 m->name = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1180 m->descriptor = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1183 if (!is_valid_name_utf(m->name))
1184 panic("Method with invalid name");
1186 if (m->name->text[0] == '<'
1187 && m->name != utf_init && m->name != utf_clinit)
1188 panic("Method with invalid special name");
1191 argcount = checkmethoddescriptor(c, m->descriptor);
1193 if (!(m->flags & ACC_STATIC))
1194 argcount++; /* count the 'this' argument */
1198 panic("Too many arguments in signature");
1200 /* check flag consistency */
1201 if (m->name != utf_clinit) {
1202 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1204 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED)
1205 panic("Method has invalid access flags");
1207 if ((m->flags & ACC_ABSTRACT) != 0) {
1208 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1209 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1211 new_classformaterror(c,
1212 "Illegal method modifiers: 0x%x",
1219 if ((c->flags & ACC_INTERFACE) != 0) {
1220 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC))
1221 != (ACC_ABSTRACT | ACC_PUBLIC))
1222 panic("Interface method is not declared abstract and public");
1225 if (m->name == utf_init) {
1226 if ((m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED
1227 | ACC_NATIVE | ACC_ABSTRACT)) != 0)
1228 panic("Instance initialization method has invalid flags set");
1234 m->basicblockcount = 0;
1235 m->basicblocks = NULL;
1236 m->basicblockindex = NULL;
1237 m->instructioncount = 0;
1238 m->instructions = NULL;
1241 m->exceptiontable = NULL;
1242 m->registerdata = NULL;
1243 m->stubroutine = NULL;
1245 m->entrypoint = NULL;
1246 m->methodUsed = NOTUSED;
1249 m->subRedefsUsed = 0;
1253 if (!(m->flags & ACC_NATIVE)) {
1254 m->stubroutine = createcompilerstub(m);
1257 functionptr f = native_findfunction(c->name, m->name, m->descriptor,
1258 (m->flags & ACC_STATIC) != 0);
1260 m->stubroutine = createnativestub(f, m);
1264 if (!check_classbuffer_size(cb, 2))
1267 attrnum = suck_u2(cb);
1268 for (i = 0; i < attrnum; i++) {
1271 if (!check_classbuffer_size(cb, 2))
1274 aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1276 if (aname != utf_code) {
1277 if (aname == utf_exceptions) {
1280 if (!check_classbuffer_size(cb, 4 + 2))
1283 suck_u4(cb); /*length*/
1284 m->thrownexceptionscount = suck_u2(cb);
1286 if (!check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1289 m->thrownexceptions = MNEW(classinfo*, m->thrownexceptionscount);
1291 for (j = 0; j < m->thrownexceptionscount; j++) {
1292 (m->thrownexceptions)[j] =
1293 class_getconstant(c, suck_u2(cb), CONSTANT_Class);
1297 if (!skipattributebody(cb))
1302 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1304 new_classformaterror(c,
1305 "Code attribute in native or abstract methods");
1312 new_classformaterror(c, "Multiple Code attributes");
1317 if (!check_classbuffer_size(cb, 4 + 2 + 2))
1321 m->maxstack = suck_u2(cb);
1322 m->maxlocals = suck_u2(cb);
1324 if (m->maxlocals < argcount) {
1326 new_classformaterror(c, "Arguments can't fit into locals");
1331 if (!check_classbuffer_size(cb, 4))
1334 m->jcodelength = suck_u4(cb);
1336 if (m->jcodelength == 0)
1337 panic("bytecode has zero length");
1339 if (m->jcodelength > 65535) {
1341 new_classformaterror(c,
1342 "Code of a method longer than 65535 bytes");
1347 if (!check_classbuffer_size(cb, m->jcodelength))
1350 m->jcode = MNEW(u1, m->jcodelength);
1351 suck_nbytes(m->jcode, cb, m->jcodelength);
1353 if (!check_classbuffer_size(cb, 2))
1356 m->exceptiontablelength = suck_u2(cb);
1358 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->exceptiontablelength))
1361 m->exceptiontable = MNEW(exceptiontable, m->exceptiontablelength);
1363 #if defined(STATISTICS)
1365 count_vmcode_len += m->jcodelength + 18;
1366 count_extable_len += 8 * m->exceptiontablelength;
1370 for (j = 0; j < m->exceptiontablelength; j++) {
1372 m->exceptiontable[j].startpc = suck_u2(cb);
1373 m->exceptiontable[j].endpc = suck_u2(cb);
1374 m->exceptiontable[j].handlerpc = suck_u2(cb);
1378 m->exceptiontable[j].catchtype = NULL;
1381 m->exceptiontable[j].catchtype =
1382 class_getconstant(c, idx, CONSTANT_Class);
1386 if (!check_classbuffer_size(cb, 2))
1389 codeattrnum = suck_u2(cb);
1391 for (; codeattrnum > 0; codeattrnum--) {
1394 if (!check_classbuffer_size(cb, 2))
1397 caname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1399 if (caname == utf_linenumbertable) {
1402 if (!check_classbuffer_size(cb, 4 + 2))
1406 m->linenumbercount = suck_u2(cb);
1408 if (!check_classbuffer_size(cb,
1409 (2 + 2) * m->linenumbercount))
1412 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1414 for (lncid = 0; lncid < m->linenumbercount; lncid++) {
1415 m->linenumbers[lncid].start_pc = suck_u2(cb);
1416 m->linenumbers[lncid].line_number = suck_u2(cb);
1420 if (!skipattributes(cb, codeattrnum))
1425 if (!skipattributebody(cb))
1432 if (!m->jcode && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1433 *exceptionptr = new_classformaterror(c, "Missing Code attribute");
1438 /* everything was ok */
1444 /********************* Function: method_free ***********************************
1446 frees all memory that was allocated for this method
1448 *******************************************************************************/
1450 static void method_free(methodinfo *m)
1453 MFREE(m->jcode, u1, m->jcodelength);
1455 if (m->exceptiontable)
1456 MFREE(m->exceptiontable, exceptiontable, m->exceptiontablelength);
1459 CFREE(m->mcode, m->mcodelength);
1461 if (m->stubroutine) {
1462 if (m->flags & ACC_NATIVE) {
1463 removenativestub(m->stubroutine);
1466 removecompilerstub(m->stubroutine);
1472 /************** Function: method_display (debugging only) **************/
1474 void method_display(methodinfo *m)
1477 printflags(m->flags);
1479 utf_display(m->name);
1481 utf_display(m->descriptor);
1485 /************** Function: method_display_flags_last (debugging only) **************/
1487 void method_display_flags_last(methodinfo *m)
1490 utf_display(m->name);
1492 utf_display(m->descriptor);
1494 printflags(m->flags);
1499 /******************** Function: method_canoverwrite ****************************
1501 Check if m and old are identical with respect to type and name. This means
1502 that old can be overwritten with m.
1504 *******************************************************************************/
1506 static bool method_canoverwrite(methodinfo *m, methodinfo *old)
1508 if (m->name != old->name) return false;
1509 if (m->descriptor != old->descriptor) return false;
1510 if (m->flags & ACC_STATIC) return false;
1515 /******************************************************************************/
1516 /************************ Functions for class *********************************/
1517 /******************************************************************************/
1520 /******************** function:: class_getconstant *****************************
1522 retrieves the value at position 'pos' of the constantpool of a class
1523 if the type of the value is other than 'ctype' the system is stopped
1525 *******************************************************************************/
1527 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
1529 /* invalid position in constantpool */
1530 /* (pos == 0 is caught by type comparison) */
1531 if (pos >= c->cpcount)
1532 panic("Attempt to access constant outside range");
1534 /* check type of constantpool entry */
1536 if (c->cptags[pos] != ctype) {
1537 class_showconstantpool(c);
1538 error("Type mismatch on constant: %d requested, %d here (class_getconstant)",
1539 (int) ctype, (int) c->cptags[pos]);
1542 return c->cpinfos[pos];
1546 /********************* Function: class_constanttype ****************************
1548 Determines the type of a class entry in the ConstantPool
1550 *******************************************************************************/
1552 u4 class_constanttype(classinfo *c, u4 pos)
1554 if (pos >= c->cpcount)
1555 panic("Attempt to access constant outside range");
1557 return c->cptags[pos];
1561 /******************** function: class_loadcpool ********************************
1563 loads the constantpool of a class,
1564 the entries are transformed into a simpler format
1565 by resolving references
1566 (a detailed overview of the compact structures can be found in global.h)
1568 *******************************************************************************/
1570 static bool class_loadcpool(classbuffer *cb, classinfo *c)
1573 /* The following structures are used to save information which cannot be
1574 processed during the first pass. After the complete constantpool has
1575 been traversed the references can be resolved.
1576 (only in specific order) */
1578 /* CONSTANT_Class_info entries */
1579 typedef struct forward_class {
1580 struct forward_class *next;
1585 /* CONSTANT_String */
1586 typedef struct forward_string {
1587 struct forward_string *next;
1592 /* CONSTANT_NameAndType */
1593 typedef struct forward_nameandtype {
1594 struct forward_nameandtype *next;
1598 } forward_nameandtype;
1600 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
1601 typedef struct forward_fieldmethint {
1602 struct forward_fieldmethint *next;
1606 u2 nameandtype_index;
1607 } forward_fieldmethint;
1611 long int dumpsize = dump_size ();
1613 forward_class *forward_classes = NULL;
1614 forward_string *forward_strings = NULL;
1615 forward_nameandtype *forward_nameandtypes = NULL;
1616 forward_fieldmethint *forward_fieldmethints = NULL;
1622 /* number of entries in the constant_pool table plus one */
1623 if (!check_classbuffer_size(cb, 2))
1626 cpcount = c->cpcount = suck_u2(cb);
1628 /* allocate memory */
1629 cptags = c->cptags = MNEW(u1, cpcount);
1630 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
1633 panic("Invalid constant_pool_count (0)");
1635 #if defined(STATISTICS)
1637 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
1640 /* initialize constantpool */
1641 for (idx = 0; idx < cpcount; idx++) {
1642 cptags[idx] = CONSTANT_UNUSED;
1643 cpinfos[idx] = NULL;
1647 /******* first pass *******/
1648 /* entries which cannot be resolved now are written into
1649 temporary structures and traversed again later */
1652 while (idx < cpcount) {
1655 /* get constant type */
1656 if (!check_classbuffer_size(cb, 1))
1662 case CONSTANT_Class: {
1663 forward_class *nfc = DNEW(forward_class);
1665 nfc->next = forward_classes;
1666 forward_classes = nfc;
1668 nfc->thisindex = idx;
1669 /* reference to CONSTANT_NameAndType */
1670 if (!check_classbuffer_size(cb, 2))
1673 nfc->name_index = suck_u2(cb);
1679 case CONSTANT_Fieldref:
1680 case CONSTANT_Methodref:
1681 case CONSTANT_InterfaceMethodref: {
1682 forward_fieldmethint *nff = DNEW(forward_fieldmethint);
1684 nff->next = forward_fieldmethints;
1685 forward_fieldmethints = nff;
1687 nff->thisindex = idx;
1691 if (!check_classbuffer_size(cb, 2 + 2))
1694 /* class or interface type that contains the declaration of the
1696 nff->class_index = suck_u2(cb);
1698 /* name and descriptor of the field or method */
1699 nff->nameandtype_index = suck_u2(cb);
1705 case CONSTANT_String: {
1706 forward_string *nfs = DNEW(forward_string);
1708 nfs->next = forward_strings;
1709 forward_strings = nfs;
1711 nfs->thisindex = idx;
1713 /* reference to CONSTANT_Utf8_info with string characters */
1714 if (!check_classbuffer_size(cb, 2))
1717 nfs->string_index = suck_u2(cb);
1723 case CONSTANT_NameAndType: {
1724 forward_nameandtype *nfn = DNEW(forward_nameandtype);
1726 nfn->next = forward_nameandtypes;
1727 forward_nameandtypes = nfn;
1729 nfn->thisindex = idx;
1731 if (!check_classbuffer_size(cb, 2 + 2))
1734 /* reference to CONSTANT_Utf8_info containing simple name */
1735 nfn->name_index = suck_u2(cb);
1737 /* reference to CONSTANT_Utf8_info containing field or method
1739 nfn->sig_index = suck_u2(cb);
1745 case CONSTANT_Integer: {
1746 constant_integer *ci = NEW(constant_integer);
1748 #if defined(STATISTICS)
1750 count_const_pool_len += sizeof(constant_integer);
1753 if (!check_classbuffer_size(cb, 4))
1756 ci->value = suck_s4(cb);
1757 cptags[idx] = CONSTANT_Integer;
1764 case CONSTANT_Float: {
1765 constant_float *cf = NEW(constant_float);
1767 #if defined(STATISTICS)
1769 count_const_pool_len += sizeof(constant_float);
1772 if (!check_classbuffer_size(cb, 4))
1775 cf->value = suck_float(cb);
1776 cptags[idx] = CONSTANT_Float;
1783 case CONSTANT_Long: {
1784 constant_long *cl = NEW(constant_long);
1786 #if defined(STATISTICS)
1788 count_const_pool_len += sizeof(constant_long);
1791 if (!check_classbuffer_size(cb, 8))
1794 cl->value = suck_s8(cb);
1795 cptags[idx] = CONSTANT_Long;
1799 panic("Long constant exceeds constant pool");
1803 case CONSTANT_Double: {
1804 constant_double *cd = NEW(constant_double);
1806 #if defined(STATISTICS)
1808 count_const_pool_len += sizeof(constant_double);
1811 if (!check_classbuffer_size(cb, 8))
1814 cd->value = suck_double(cb);
1815 cptags[idx] = CONSTANT_Double;
1819 panic("Double constant exceeds constant pool");
1823 case CONSTANT_Utf8: {
1826 /* number of bytes in the bytes array (not string-length) */
1827 if (!check_classbuffer_size(cb, 2))
1830 length = suck_u2(cb);
1831 cptags[idx] = CONSTANT_Utf8;
1833 /* validate the string */
1834 if (!check_classbuffer_size(cb, length))
1838 !is_valid_utf(cb->pos + 1, cb->pos + 1 + length)) {
1839 dolog("Invalid UTF-8 string (constant pool index %d)",idx);
1840 panic("Invalid UTF-8 string");
1842 /* insert utf-string into the utf-symboltable */
1843 cpinfos[idx] = utf_new_intern(cb->pos + 1, length);
1845 /* skip bytes of the string (buffer size check above) */
1846 skip_nbytes(cb, length);
1852 error("Unkown constant type: %d",(int) t);
1857 /* resolve entries in temporary structures */
1859 while (forward_classes) {
1861 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
1863 if (opt_verify && !is_valid_name_utf(name))
1864 panic("Class reference with invalid name");
1866 cptags[forward_classes->thisindex] = CONSTANT_Class;
1867 /* retrieve class from class-table */
1870 tc = class_new_intern(name);
1872 if (!class_load(tc))
1875 /* link the class later, so we cannot link the currently loaded
1877 list_addfirst(&unlinkedclasses, tc);
1879 cpinfos[forward_classes->thisindex] = tc;
1882 cpinfos[forward_classes->thisindex] = class_new(name);
1885 forward_classes = forward_classes->next;
1888 while (forward_strings) {
1890 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
1892 /* resolve utf-string */
1893 cptags[forward_strings->thisindex] = CONSTANT_String;
1894 cpinfos[forward_strings->thisindex] = text;
1896 forward_strings = forward_strings->next;
1899 while (forward_nameandtypes) {
1900 constant_nameandtype *cn = NEW(constant_nameandtype);
1902 #if defined(STATISTICS)
1904 count_const_pool_len += sizeof(constant_nameandtype);
1907 /* resolve simple name and descriptor */
1908 cn->name = class_getconstant(c,
1909 forward_nameandtypes->name_index,
1912 cn->descriptor = class_getconstant(c,
1913 forward_nameandtypes->sig_index,
1918 if (!is_valid_name_utf(cn->name))
1919 panic("NameAndType with invalid name");
1920 /* disallow referencing <clinit> among others */
1921 if (cn->name->text[0] == '<' && cn->name != utf_init)
1922 panic("NameAndType with invalid special name");
1925 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
1926 cpinfos[forward_nameandtypes->thisindex] = cn;
1928 forward_nameandtypes = forward_nameandtypes->next;
1931 while (forward_fieldmethints) {
1932 constant_nameandtype *nat;
1933 constant_FMIref *fmi = NEW(constant_FMIref);
1935 #if defined(STATISTICS)
1937 count_const_pool_len += sizeof(constant_FMIref);
1939 /* resolve simple name and descriptor */
1940 nat = class_getconstant(c,
1941 forward_fieldmethints->nameandtype_index,
1942 CONSTANT_NameAndType);
1944 fmi->class = class_getconstant(c,
1945 forward_fieldmethints->class_index,
1947 fmi->name = nat->name;
1948 fmi->descriptor = nat->descriptor;
1950 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
1951 cpinfos[forward_fieldmethints->thisindex] = fmi;
1953 switch (forward_fieldmethints->tag) {
1954 case CONSTANT_Fieldref: /* check validity of descriptor */
1955 checkfielddescriptor(fmi->descriptor->text,
1956 utf_end(fmi->descriptor));
1958 case CONSTANT_InterfaceMethodref:
1959 case CONSTANT_Methodref: /* check validity of descriptor */
1960 checkmethoddescriptor(c, fmi->descriptor);
1964 forward_fieldmethints = forward_fieldmethints->next;
1967 dump_release(dumpsize);
1969 /* everything was ok */
1975 /********************** Function: class_load ***********************************
1977 Loads everything interesting about a class from the class file. The
1978 'classinfo' structure must have been allocated previously.
1980 The super class and the interfaces implemented by this class need not be
1981 loaded. The link is set later by the function 'class_link'.
1983 The loaded class is removed from the list 'unloadedclasses' and added to
1984 the list 'unlinkedclasses'.
1986 *******************************************************************************/
1988 classinfo *class_load_intern(classbuffer *cb);
1990 classinfo *class_load(classinfo *c)
1997 #if defined(USE_THREADS)
1998 #if defined(NATIVE_THREADS)
2006 /* maybe the class is already loaded */
2008 #if defined(USE_THREADS)
2009 #if defined(NATIVE_THREADS)
2022 starttime = getcputime();
2024 /* load classdata, throw exception on error */
2026 if ((cb = suck_start(c)) == NULL) {
2027 /* this means, the classpath was not set properly */
2028 if (c->name == utf_java_lang_Object)
2029 throw_cacao_exception_exit(string_java_lang_NoClassDefFoundError,
2030 "java/lang/Object");
2033 new_exception_utfmessage(string_java_lang_NoClassDefFoundError,
2036 #if defined(USE_THREADS)
2037 #if defined(NATIVE_THREADS)
2048 /* call the internal function */
2049 r = class_load_intern(cb);
2051 /* if return value is NULL, we had a problem and the class is not loaded */
2055 /* now free the allocated memory, otherwise we could ran into a DOS */
2063 if (getloadingtime) {
2064 stoptime = getcputime();
2065 loadingtime += (stoptime - starttime);
2068 #if defined(USE_THREADS)
2069 #if defined(NATIVE_THREADS)
2081 classinfo *class_load_intern(classbuffer *cb)
2086 /* s4 classdata_left; */
2087 char msg[MAXLOGTEXT]; /* maybe we get an exception */
2089 /* get the classbuffer's class */
2092 /* maybe the class is already loaded */
2096 #if defined(STATISTICS)
2098 count_class_loads++;
2101 /* output for debugging purposes */
2103 log_message_class("Loading class: ", c);
2105 /* class is somewhat loaded */
2108 if (!check_classbuffer_size(cb, 4 + 2 + 2))
2111 /* check signature */
2112 if (suck_u4(cb) != MAGIC) {
2113 *exceptionptr = new_classformaterror(c, "Bad magic number");
2122 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
2124 new_classformaterror(c,
2125 "Unsupported major.minor version %d.%d",
2131 if (!class_loadcpool(cb, c))
2135 c->erroneous_state = 0;
2136 c->initializing_thread = 0;
2138 c->classUsed = NOTUSED; /* not used initially CO-RT */
2142 if (!check_classbuffer_size(cb, 2))
2145 c->flags = suck_u2(cb);
2146 /*if (!(c->flags & ACC_PUBLIC)) { log_text("CLASS NOT PUBLIC"); } JOWENN*/
2148 /* check ACC flags consistency */
2149 if (c->flags & ACC_INTERFACE) {
2150 if (!(c->flags & ACC_ABSTRACT)) {
2151 /* We work around this because interfaces in JDK 1.1 are
2152 * not declared abstract. */
2154 c->flags |= ACC_ABSTRACT;
2155 /* panic("Interface class not declared abstract"); */
2158 if (c->flags & ACC_FINAL) {
2160 new_classformaterror(c,
2161 "Illegal class modifiers: 0x%x", c->flags);
2166 if (c->flags & ACC_SUPER) {
2167 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
2171 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
2173 new_classformaterror(c, "Illegal class modifiers: 0x%x", c->flags);
2178 if (!check_classbuffer_size(cb, 2 + 2))
2183 if (class_getconstant(c, i, CONSTANT_Class) != c) {
2184 utf_sprint(msg, c->name);
2185 sprintf(msg + strlen(msg), " (wrong name: ");
2186 utf_sprint(msg + strlen(msg),
2187 ((classinfo *) class_getconstant(c, i, CONSTANT_Class))->name);
2188 sprintf(msg + strlen(msg), ")");
2191 new_exception_message(string_java_lang_NoClassDefFoundError, msg);
2196 /* retrieve superclass */
2197 if ((i = suck_u2(cb))) {
2198 c->super = class_getconstant(c, i, CONSTANT_Class);
2200 /* java.lang.Object may not have a super class. */
2201 if (c->name == utf_java_lang_Object) {
2203 new_exception_message(string_java_lang_ClassFormatError,
2204 "java.lang.Object with superclass");
2209 /* Interfaces must have java.lang.Object as super class. */
2210 if ((c->flags & ACC_INTERFACE) &&
2211 c->super->name != utf_java_lang_Object) {
2213 new_exception_message(string_java_lang_ClassFormatError,
2214 "Interfaces must have java.lang.Object as superclass");
2222 /* This is only allowed for java.lang.Object. */
2223 if (c->name != utf_java_lang_Object) {
2224 *exceptionptr = new_classformaterror(c, "Bad superclass index");
2231 /* retrieve interfaces */
2232 if (!check_classbuffer_size(cb, 2))
2235 c->interfacescount = suck_u2(cb);
2237 if (!check_classbuffer_size(cb, 2 * c->interfacescount))
2240 c->interfaces = MNEW(classinfo*, c->interfacescount);
2241 for (i = 0; i < c->interfacescount; i++) {
2242 c->interfaces[i] = class_getconstant(c, suck_u2(cb), CONSTANT_Class);
2246 if (!check_classbuffer_size(cb, 2))
2249 c->fieldscount = suck_u2(cb);
2250 c->fields = GCNEW(fieldinfo, c->fieldscount);
2251 /* c->fields = MNEW(fieldinfo, c->fieldscount); */
2252 for (i = 0; i < c->fieldscount; i++) {
2253 if (!field_load(cb, c, &(c->fields[i])))
2258 if (!check_classbuffer_size(cb, 2))
2261 c->methodscount = suck_u2(cb);
2262 c->methods = GCNEW(methodinfo, c->methodscount);
2263 /* c->methods = MNEW(methodinfo, c->methodscount); */
2264 for (i = 0; i < c->methodscount; i++) {
2265 if (!method_load(cb, c, &(c->methods[i])))
2269 /* Check if all fields and methods can be uniquely
2270 * identified by (name,descriptor). */
2272 /* We use a hash table here to avoid making the
2273 * average case quadratic in # of methods, fields.
2275 static int shift = 0;
2277 u2 *next; /* for chaining colliding hash entries */
2283 /* Allocate hashtable */
2284 len = c->methodscount;
2285 if (len < c->fieldscount) len = c->fieldscount;
2287 hashtab = MNEW(u2,(hashlen + len));
2288 next = hashtab + hashlen;
2290 /* Determine bitshift (to get good hash values) */
2300 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2302 for (i = 0; i < c->fieldscount; ++i) {
2303 fieldinfo *fi = c->fields + i;
2305 /* It's ok if we lose bits here */
2306 index = ((((size_t) fi->name) +
2307 ((size_t) fi->descriptor)) >> shift) % hashlen;
2309 if ((old = hashtab[index])) {
2313 if (c->fields[old].name == fi->name &&
2314 c->fields[old].descriptor == fi->descriptor) {
2316 new_classformaterror(c,
2317 "Repetitive field name/signature");
2321 } while ((old = next[old]));
2323 hashtab[index] = i + 1;
2327 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2329 for (i = 0; i < c->methodscount; ++i) {
2330 methodinfo *mi = c->methods + i;
2332 /* It's ok if we lose bits here */
2333 index = ((((size_t) mi->name) +
2334 ((size_t) mi->descriptor)) >> shift) % hashlen;
2336 if ((old = hashtab[index])) {
2340 if (c->methods[old].name == mi->name &&
2341 c->methods[old].descriptor == mi->descriptor) {
2343 new_classformaterror(c,
2344 "Repetitive method name/signature");
2348 } while ((old = next[old]));
2350 hashtab[index] = i + 1;
2353 MFREE(hashtab, u2, (hashlen + len));
2356 #if defined(STATISTICS)
2358 count_class_infos += sizeof(classinfo*) * c->interfacescount;
2359 count_class_infos += sizeof(fieldinfo) * c->fieldscount;
2360 count_class_infos += sizeof(methodinfo) * c->methodscount;
2364 /* load variable-length attribute structures */
2365 if (!check_classbuffer_size(cb, 2))
2368 if (!attribute_load(cb, c, suck_u2(cb)))
2372 /* XXX TWISTI is this still in the JVM spec? SUN and IBM don't complain about it */
2374 /* check if all data has been read */
2375 classdata_left = ((cb->data + cb->size) - cb->pos - 1);
2377 if (classdata_left > 0) {
2379 dolog("There are %d extra bytes at end of classfile", classdata_left);
2380 /* The JVM spec disallows extra bytes. */
2381 panic("Extra bytes at end of classfile");
2386 log_message_class("Loading done class: ", c);
2393 /************** internal Function: class_highestinterface **********************
2395 Used by the function class_link to determine the amount of memory needed
2396 for the interface table.
2398 *******************************************************************************/
2400 static s4 class_highestinterface(classinfo *c)
2405 if (!(c->flags & ACC_INTERFACE)) {
2406 char logtext[MAXLOGTEXT];
2407 sprintf(logtext, "Interface-methods count requested for non-interface: ");
2408 utf_sprint(logtext + strlen(logtext), c->name);
2409 error("%s",logtext);
2413 for (i = 0; i < c->interfacescount; i++) {
2414 s4 h2 = class_highestinterface(c->interfaces[i]);
2422 /* class_addinterface **********************************************************
2424 Is needed by class_link for adding a VTBL to a class. All interfaces
2425 implemented by ic are added as well.
2427 *******************************************************************************/
2429 static void class_addinterface(classinfo *c, classinfo *ic)
2433 vftbl *vftbl = c->vftbl;
2435 if (i >= vftbl->interfacetablelength)
2436 panic ("Inernal error: interfacetable overflow");
2438 if (vftbl->interfacetable[-i])
2441 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
2442 vftbl->interfacevftbllength[i] = 1;
2443 vftbl->interfacetable[-i] = MNEW(methodptr, 1);
2444 vftbl->interfacetable[-i][0] = NULL;
2447 vftbl->interfacevftbllength[i] = ic->methodscount;
2448 vftbl->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
2452 count_vftbl_len += sizeof(methodptr) *
2453 (ic->methodscount + (ic->methodscount == 0));
2456 for (j = 0; j < ic->methodscount; j++) {
2459 for (m = 0; m < sc->methodscount; m++) {
2460 methodinfo *mi = &(sc->methods[m]);
2461 if (method_canoverwrite(mi, &(ic->methods[j]))) {
2462 vftbl->interfacetable[-i][j] =
2463 vftbl->table[mi->vftblindex];
2474 for (j = 0; j < ic->interfacescount; j++)
2475 class_addinterface(c, ic->interfaces[j]);
2479 /******************* Function: class_new_array *********************************
2481 This function is called by class_new to setup an array class.
2483 *******************************************************************************/
2485 void class_new_array(classinfo *c)
2487 classinfo *comp = NULL;
2491 /* Check array class name */
2492 namelen = c->name->blength;
2493 if (namelen < 2 || c->name->text[0] != '[')
2494 panic("Invalid array class name");
2496 /* Check the component type */
2497 switch (c->name->text[1]) {
2499 /* c is an array of arrays. We have to create the component class. */
2501 comp = class_new_intern(utf_new_intern(c->name->text + 1,
2504 list_addfirst(&unlinkedclasses, comp);
2507 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2512 /* c is an array of objects. */
2513 if (namelen < 4 || c->name->text[namelen - 1] != ';')
2514 panic("Invalid array class name");
2517 comp = class_new_intern(utf_new_intern(c->name->text + 2,
2520 list_addfirst(&unlinkedclasses, comp);
2523 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2528 /* Setup the array class */
2529 c->super = class_java_lang_Object;
2530 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2532 c->interfacescount = 2;
2533 c->interfaces = MNEW(classinfo*, 2);
2538 tc = class_new_intern(utf_new_char("java/lang/Cloneable"));
2540 list_addfirst(&unlinkedclasses, tc);
2541 c->interfaces[0] = tc;
2543 tc = class_new_intern(utf_new_char("java/io/Serializable"));
2545 list_addfirst(&unlinkedclasses, tc);
2546 c->interfaces[1] = tc;
2549 c->interfaces[0] = class_new(utf_new_char("java/lang/Cloneable"));
2550 c->interfaces[1] = class_new(utf_new_char("java/io/Serializable"));
2553 c->methodscount = 1;
2554 c->methods = MNEW(methodinfo, c->methodscount);
2557 memset(clone, 0, sizeof(methodinfo));
2558 clone->flags = ACC_PUBLIC;
2559 clone->name = utf_new_char("clone");
2560 clone->descriptor = utf_new_char("()Ljava/lang/Object;");
2562 clone->stubroutine = createnativestub((functionptr) &builtin_clone_array, clone);
2563 clone->monoPoly = MONO;
2565 /* XXX: field: length? */
2567 /* array classes are not loaded from class files */
2572 /****************** Function: class_link_array *********************************
2574 This function is called by class_link to create the
2575 arraydescriptor for an array class.
2577 This function returns NULL if the array cannot be linked because
2578 the component type has not been linked yet.
2580 *******************************************************************************/
2582 static arraydescriptor *class_link_array(classinfo *c)
2584 classinfo *comp = NULL;
2585 s4 namelen = c->name->blength;
2586 arraydescriptor *desc;
2589 /* Check the component type */
2590 switch (c->name->text[1]) {
2592 /* c is an array of arrays. */
2593 /* comp = class_get(utf_new_intern(c->name->text + 1, namelen - 1)); */
2594 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2596 panic("Could not find component array class.");
2600 /* c is an array of objects. */
2601 /* comp = class_get(utf_new_intern(c->name->text + 2, namelen - 3)); */
2602 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2604 panic("Could not find component class.");
2608 /* If the component type has not been linked, link it now */
2609 if (comp && !comp->linked) {
2615 /* Allocate the arraydescriptor */
2616 desc = NEW(arraydescriptor);
2619 /* c is an array of references */
2620 desc->arraytype = ARRAYTYPE_OBJECT;
2621 desc->componentsize = sizeof(void*);
2622 desc->dataoffset = OFFSET(java_objectarray, data);
2624 compvftbl = comp->vftbl;
2626 panic("Component class has no vftbl");
2627 desc->componentvftbl = compvftbl;
2629 if (compvftbl->arraydesc) {
2630 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
2631 if (compvftbl->arraydesc->dimension >= 255)
2632 panic("Creating array of dimension >255");
2633 desc->dimension = compvftbl->arraydesc->dimension + 1;
2634 desc->elementtype = compvftbl->arraydesc->elementtype;
2637 desc->elementvftbl = compvftbl;
2638 desc->dimension = 1;
2639 desc->elementtype = ARRAYTYPE_OBJECT;
2643 /* c is an array of a primitive type */
2644 switch (c->name->text[1]) {
2646 desc->arraytype = ARRAYTYPE_BOOLEAN;
2647 desc->dataoffset = OFFSET(java_booleanarray,data);
2648 desc->componentsize = sizeof(u1);
2652 desc->arraytype = ARRAYTYPE_BYTE;
2653 desc->dataoffset = OFFSET(java_bytearray,data);
2654 desc->componentsize = sizeof(u1);
2658 desc->arraytype = ARRAYTYPE_CHAR;
2659 desc->dataoffset = OFFSET(java_chararray,data);
2660 desc->componentsize = sizeof(u2);
2664 desc->arraytype = ARRAYTYPE_DOUBLE;
2665 desc->dataoffset = OFFSET(java_doublearray,data);
2666 desc->componentsize = sizeof(double);
2670 desc->arraytype = ARRAYTYPE_FLOAT;
2671 desc->dataoffset = OFFSET(java_floatarray,data);
2672 desc->componentsize = sizeof(float);
2676 desc->arraytype = ARRAYTYPE_INT;
2677 desc->dataoffset = OFFSET(java_intarray,data);
2678 desc->componentsize = sizeof(s4);
2682 desc->arraytype = ARRAYTYPE_LONG;
2683 desc->dataoffset = OFFSET(java_longarray,data);
2684 desc->componentsize = sizeof(s8);
2688 desc->arraytype = ARRAYTYPE_SHORT;
2689 desc->dataoffset = OFFSET(java_shortarray,data);
2690 desc->componentsize = sizeof(s2);
2694 panic("Invalid array class name");
2697 desc->componentvftbl = NULL;
2698 desc->elementvftbl = NULL;
2699 desc->dimension = 1;
2700 desc->elementtype = desc->arraytype;
2707 /********************** Function: class_link ***********************************
2709 Tries to link a class. The function calculates the length in bytes that
2710 an instance of this class requires as well as the VTBL for methods and
2713 *******************************************************************************/
2715 static classinfo *class_link_intern(classinfo *c);
2717 classinfo *class_link(classinfo *c)
2723 #if defined(USE_THREADS)
2724 #if defined(NATIVE_THREADS)
2732 /* maybe the class is already linked */
2734 #if defined(USE_THREADS)
2735 #if defined(NATIVE_THREADS)
2748 starttime = getcputime();
2750 /* call the internal function */
2751 r = class_link_intern(c);
2753 /* if return value is NULL, we had a problem and the class is not linked */
2758 if (getloadingtime) {
2759 stoptime = getcputime();
2760 loadingtime += (stoptime - starttime);
2763 #if defined(USE_THREADS)
2764 #if defined(NATIVE_THREADS)
2776 static classinfo *class_link_intern(classinfo *c)
2778 s4 supervftbllength; /* vftbllegnth of super class */
2779 s4 vftbllength; /* vftbllength of current class */
2780 s4 interfacetablelength; /* interface table length */
2781 classinfo *super = c->super; /* super class */
2782 classinfo *ic, *c2; /* intermediate class variables */
2783 vftbl *v; /* vftbl of current class */
2784 s4 i; /* interface/method/field counter */
2785 arraydescriptor *arraydesc = NULL; /* descriptor for array classes */
2787 /* maybe the class is already linked */
2792 log_message_class("Linking class: ", c);
2794 /* ok, this class is somewhat linked */
2797 /* check interfaces */
2799 for (i = 0; i < c->interfacescount; i++) {
2800 ic = c->interfaces[i];
2802 /* detect circularity */
2805 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2812 if (!class_load(ic))
2816 if (!class_link(ic))
2819 if (!(ic->flags & ACC_INTERFACE)) {
2820 dolog("Specified interface is not declared as interface:");
2824 panic("Specified interface is not declared as interface");
2828 /* check super class */
2830 if (super == NULL) { /* class java.lang.Object */
2832 c->classUsed = USED; /* Object class is always used CO-RT*/
2834 c->instancesize = sizeof(java_objectheader);
2836 vftbllength = supervftbllength = 0;
2838 c->finalizer = NULL;
2841 /* detect circularity */
2844 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2851 if (!class_load(super))
2855 if (!class_link(super))
2858 if (super->flags & ACC_INTERFACE)
2859 panic("Interface specified as super class");
2861 /* handle array classes */
2862 /* The component class must have been linked already. */
2863 if (c->name->text[0] == '[') {
2864 if ((arraydesc = class_link_array(c)) == NULL) {
2865 panic("class_link: class_link_array");
2869 /* Don't allow extending final classes */
2870 if (super->flags & ACC_FINAL)
2871 panic("Trying to extend final class");
2873 if (c->flags & ACC_INTERFACE)
2874 c->index = interfaceindex++;
2876 c->index = super->index + 1;
2878 c->instancesize = super->instancesize;
2880 vftbllength = supervftbllength = super->vftbl->vftbllength;
2882 c->finalizer = super->finalizer;
2885 /* compute vftbl length */
2887 for (i = 0; i < c->methodscount; i++) {
2888 methodinfo *m = &(c->methods[i]);
2890 if (!(m->flags & ACC_STATIC)) { /* is instance method */
2891 classinfo *sc = super;
2894 for (j = 0; j < sc->methodscount; j++) {
2895 if (method_canoverwrite(m, &(sc->methods[j]))) {
2896 if ((sc->methods[j].flags & ACC_PRIVATE) != 0)
2897 goto notfoundvftblindex;
2899 if ((sc->methods[j].flags & ACC_FINAL) != 0) {
2902 log_utf(sc->methods[j].name);
2903 log_utf(sc->methods[j].descriptor);
2904 panic("Trying to overwrite final method");
2906 m->vftblindex = sc->methods[j].vftblindex;
2907 goto foundvftblindex;
2913 m->vftblindex = (vftbllength++);
2922 sizeof(vftbl) + (sizeof(methodptr) * (vftbllength - 1));
2925 /* compute interfacetable length */
2927 interfacetablelength = 0;
2930 for (i = 0; i < c2->interfacescount; i++) {
2931 s4 h = class_highestinterface(c2->interfaces[i]) + 1;
2932 if (h > interfacetablelength)
2933 interfacetablelength = h;
2938 /* allocate virtual function table */
2940 v = (vftbl*) mem_alloc(sizeof(vftbl) + sizeof(methodptr) *
2941 (vftbllength - 1) + sizeof(methodptr*) *
2942 (interfacetablelength - (interfacetablelength > 0)));
2943 v = (vftbl*) (((methodptr*) v) + (interfacetablelength - 1) *
2944 (interfacetablelength > 1));
2945 c->header.vftbl = c->vftbl = v;
2946 /* utf_display_classname(c->name);printf(", c->header.vftbl=%p\n", c->header.vftbl); */
2948 v->vftbllength = vftbllength;
2949 v->interfacetablelength = interfacetablelength;
2950 v->arraydesc = arraydesc;
2952 /* store interface index in vftbl */
2953 if (c->flags & ACC_INTERFACE)
2954 v->baseval = -(c->index);
2956 /* copy virtual function table of super class */
2958 for (i = 0; i < supervftbllength; i++)
2959 v->table[i] = super->vftbl->table[i];
2961 /* add method stubs into virtual function table */
2963 for (i = 0; i < c->methodscount; i++) {
2964 methodinfo *m = &(c->methods[i]);
2965 if (!(m->flags & ACC_STATIC)) {
2966 v->table[m->vftblindex] = m->stubroutine;
2970 /* compute instance size and offset of each field */
2972 for (i = 0; i < c->fieldscount; i++) {
2974 fieldinfo *f = &(c->fields[i]);
2976 if (!(f->flags & ACC_STATIC)) {
2977 dsize = desc_typesize(f->descriptor);
2978 c->instancesize = ALIGN(c->instancesize, dsize);
2979 f->offset = c->instancesize;
2980 c->instancesize += dsize;
2984 /* initialize interfacetable and interfacevftbllength */
2986 v->interfacevftbllength = MNEW(s4, interfacetablelength);
2990 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
2993 for (i = 0; i < interfacetablelength; i++) {
2994 v->interfacevftbllength[i] = 0;
2995 v->interfacetable[-i] = NULL;
2998 /* add interfaces */
3000 for (c2 = c; c2 != NULL; c2 = c2->super)
3001 for (i = 0; i < c2->interfacescount; i++) {
3002 class_addinterface(c, c2->interfaces[i]);
3005 /* add finalizer method (not for java.lang.Object) */
3007 if (super != NULL) {
3009 static utf *finame = NULL;
3010 static utf *fidesc = NULL;
3013 finame = utf_finalize;
3015 fidesc = utf_fidesc;
3017 fi = class_findmethod(c, finame, fidesc);
3019 if (!(fi->flags & ACC_STATIC)) {
3027 loader_compute_subclasses(c);
3030 log_message_class("Linking done class: ", c);
3032 /* just return c to show that we didn't had a problem */
3038 /******************* Function: class_freepool **********************************
3040 Frees all resources used by this classes Constant Pool.
3042 *******************************************************************************/
3044 static void class_freecpool(classinfo *c)
3050 if (c->cptags && c->cpinfos) {
3051 for (idx = 0; idx < c->cpcount; idx++) {
3052 tag = c->cptags[idx];
3053 info = c->cpinfos[idx];
3057 case CONSTANT_Fieldref:
3058 case CONSTANT_Methodref:
3059 case CONSTANT_InterfaceMethodref:
3060 FREE(info, constant_FMIref);
3062 case CONSTANT_Integer:
3063 FREE(info, constant_integer);
3065 case CONSTANT_Float:
3066 FREE(info, constant_float);
3069 FREE(info, constant_long);
3071 case CONSTANT_Double:
3072 FREE(info, constant_double);
3074 case CONSTANT_NameAndType:
3075 FREE(info, constant_nameandtype);
3083 MFREE(c->cptags, u1, c->cpcount);
3086 MFREE(c->cpinfos, voidptr, c->cpcount);
3090 /*********************** Function: class_free **********************************
3092 Frees all resources used by the class.
3094 *******************************************************************************/
3096 void class_free(classinfo *c)
3104 MFREE(c->interfaces, classinfo*, c->interfacescount);
3107 for (i = 0; i < c->fieldscount; i++)
3108 field_free(&(c->fields[i]));
3109 /* MFREE(c->fields, fieldinfo, c->fieldscount); */
3113 for (i = 0; i < c->methodscount; i++)
3114 method_free(&(c->methods[i]));
3115 /* MFREE(c->methods, methodinfo, c->methodscount); */
3118 if ((v = c->vftbl) != NULL) {
3120 mem_free(v->arraydesc,sizeof(arraydescriptor));
3122 for (i = 0; i < v->interfacetablelength; i++) {
3123 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
3125 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
3127 i = sizeof(vftbl) + sizeof(methodptr) * (v->vftbllength - 1) +
3128 sizeof(methodptr*) * (v->interfacetablelength -
3129 (v->interfacetablelength > 0));
3130 v = (vftbl*) (((methodptr*) v) - (v->interfacetablelength - 1) *
3131 (v->interfacetablelength > 1));
3136 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
3138 /* if (c->classvftbl)
3139 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
3145 /************************* Function: class_findfield ***************************
3147 Searches a 'classinfo' structure for a field having the given name and
3150 *******************************************************************************/
3152 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
3156 for (i = 0; i < c->fieldscount; i++) {
3157 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
3158 return &(c->fields[i]);
3161 panic("Can not find field given in CONSTANT_Fieldref");
3163 /* keep compiler happy */
3168 /****************** Function: class_resolvefield_int ***************************
3170 This is an internally used helper function. Do not use this directly.
3172 Tries to resolve a field having the given name and type.
3173 If the field cannot be resolved, NULL is returned.
3175 *******************************************************************************/
3177 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
3182 /* search for field in class c */
3183 for (i = 0; i < c->fieldscount; i++) {
3184 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
3185 return &(c->fields[i]);
3189 /* try superinterfaces recursively */
3190 for (i = 0; i < c->interfacescount; ++i) {
3191 fi = class_resolvefield_int(c->interfaces[i], name, desc);
3196 /* try superclass */
3198 return class_resolvefield_int(c->super, name, desc);
3205 /********************* Function: class_resolvefield ***************************
3207 Resolves a reference from REFERER to a field with NAME and DESC in class C.
3209 If the field cannot be resolved the return value is NULL. If EXCEPT is
3210 true *exceptionptr is set, too.
3212 *******************************************************************************/
3214 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
3215 classinfo *referer, bool except)
3219 /* XXX resolve class c */
3220 /* XXX check access from REFERER to C */
3222 fi = class_resolvefield_int(c, name, desc);
3227 new_exception_utfmessage(string_java_lang_NoSuchFieldError,
3233 /* XXX check access rights */
3239 /************************* Function: class_findmethod **************************
3241 Searches a 'classinfo' structure for a method having the given name and
3242 type and returns the index in the class info structure.
3243 If type is NULL, it is ignored.
3245 *******************************************************************************/
3247 s4 class_findmethodIndex(classinfo *c, utf *name, utf *desc)
3251 for (i = 0; i < c->methodscount; i++) {
3253 /* utf_display_classname(c->name);printf("."); */
3254 /* utf_display(c->methods[i].name);printf("."); */
3255 /* utf_display(c->methods[i].descriptor); */
3258 if ((c->methods[i].name == name) && ((desc == NULL) ||
3259 (c->methods[i].descriptor == desc))) {
3268 /************************* Function: class_findmethod **************************
3270 Searches a 'classinfo' structure for a method having the given name and
3272 If type is NULL, it is ignored.
3274 *******************************************************************************/
3276 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
3278 s4 idx = class_findmethodIndex(c, name, desc);
3283 return &(c->methods[idx]);
3287 /*********************** Function: class_fetchmethod **************************
3289 like class_findmethod, but aborts with an error if the method is not found
3291 *******************************************************************************/
3293 methodinfo *class_fetchmethod(classinfo *c, utf *name, utf *desc)
3297 mi = class_findmethod(c, name, desc);
3300 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3301 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3302 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3303 panic("Method not found");
3310 /*********************** Function: class_findmethod_w**************************
3312 like class_findmethod, but logs a warning if the method is not found
3314 *******************************************************************************/
3316 methodinfo *class_findmethod_w(classinfo *c, utf *name, utf *desc, char *from)
3319 mi = class_findmethod(c, name, desc);
3322 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3323 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3324 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3326 if ( c->flags & ACC_PUBLIC ) log_plain(" PUBLIC ");
3327 if ( c->flags & ACC_PRIVATE ) log_plain(" PRIVATE ");
3328 if ( c->flags & ACC_PROTECTED ) log_plain(" PROTECTED ");
3329 if ( c->flags & ACC_STATIC ) log_plain(" STATIC ");
3330 if ( c->flags & ACC_FINAL ) log_plain(" FINAL ");
3331 if ( c->flags & ACC_SYNCHRONIZED ) log_plain(" SYNCHRONIZED ");
3332 if ( c->flags & ACC_VOLATILE ) log_plain(" VOLATILE ");
3333 if ( c->flags & ACC_TRANSIENT ) log_plain(" TRANSIENT ");
3334 if ( c->flags & ACC_NATIVE ) log_plain(" NATIVE ");
3335 if ( c->flags & ACC_INTERFACE ) log_plain(" INTERFACE ");
3336 if ( c->flags & ACC_ABSTRACT ) log_plain(" ABSTRACT ");
3339 log_plain(" : WARNING: Method not found");log_nl( );
3346 /************************* Function: class_findmethod_approx ******************
3348 like class_findmethod but ignores the return value when comparing the
3351 *******************************************************************************/
3353 methodinfo *class_findmethod_approx(classinfo *c, utf *name, utf *desc)
3357 for (i = 0; i < c->methodscount; i++) {
3358 if (c->methods[i].name == name) {
3359 utf *meth_descr = c->methods[i].descriptor;
3363 return &(c->methods[i]);
3365 if (desc->blength <= meth_descr->blength) {
3366 /* current position in utf text */
3367 char *desc_utf_ptr = desc->text;
3368 char *meth_utf_ptr = meth_descr->text;
3369 /* points behind utf strings */
3370 char *desc_end = utf_end(desc);
3371 char *meth_end = utf_end(meth_descr);
3374 /* compare argument types */
3375 while (desc_utf_ptr < desc_end && meth_utf_ptr < meth_end) {
3377 if ((ch = *desc_utf_ptr++) != (*meth_utf_ptr++))
3378 break; /* no match */
3381 return &(c->methods[i]); /* all parameter types equal */
3391 /***************** Function: class_resolvemethod_approx ***********************
3393 Searches a class and every super class for a method (without paying
3394 attention to the return value)
3396 *******************************************************************************/
3398 methodinfo *class_resolvemethod_approx(classinfo *c, utf *name, utf *desc)
3401 /* search for method (ignore returntype) */
3402 methodinfo *m = class_findmethod_approx(c, name, desc);
3405 /* search superclass */
3413 /************************* Function: class_resolvemethod ***********************
3415 Searches a class and every super class for a method.
3417 *******************************************************************************/
3419 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
3421 /*log_text("Trying to resolve a method");
3422 utf_display(c->name);
3424 utf_display(desc);*/
3427 /*log_text("Looking in:");
3428 utf_display(c->name);*/
3429 methodinfo *m = class_findmethod(c, name, desc);
3431 /* search superclass */
3434 /*log_text("method not found:");*/
3440 /****************** Function: class_resolveinterfacemethod_int ****************
3442 Internally used helper function. Do not use this directly.
3444 *******************************************************************************/
3447 methodinfo *class_resolveinterfacemethod_int(classinfo *c, utf *name, utf *desc)
3452 mi = class_findmethod(c,name,desc);
3456 /* try the superinterfaces */
3457 for (i=0; i<c->interfacescount; ++i) {
3458 mi = class_resolveinterfacemethod_int(c->interfaces[i],name,desc);
3466 /******************** Function: class_resolveinterfacemethod ******************
3468 Resolves a reference from REFERER to a method with NAME and DESC in
3471 If the method cannot be resolved the return value is NULL. If EXCEPT is
3472 true *exceptionptr is set, too.
3474 *******************************************************************************/
3476 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
3477 classinfo *referer, bool except)
3481 /* XXX resolve class c */
3482 /* XXX check access from REFERER to C */
3484 if (!(c->flags & ACC_INTERFACE)) {
3487 new_exception(string_java_lang_IncompatibleClassChangeError);
3492 mi = class_resolveinterfacemethod_int(c, name, desc);
3497 /* try class java.lang.Object */
3498 mi = class_findmethod(class_java_lang_Object, name, desc);
3505 new_exception_utfmessage(string_java_lang_NoSuchMethodError, name);
3511 /********************* Function: class_resolveclassmethod *********************
3513 Resolves a reference from REFERER to a method with NAME and DESC in
3516 If the method cannot be resolved the return value is NULL. If EXCEPT is
3517 true *exceptionptr is set, too.
3519 *******************************************************************************/
3521 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
3522 classinfo *referer, bool except)
3527 char msg[MAXLOGTEXT];
3529 /* XXX resolve class c */
3530 /* XXX check access from REFERER to C */
3532 /* if (c->flags & ACC_INTERFACE) { */
3534 /* *exceptionptr = */
3535 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
3539 /* try class c and its superclasses */
3542 mi = class_findmethod(cls, name, desc);
3545 } while ((cls = cls->super) != NULL); /* try the superclass */
3547 /* try the superinterfaces */
3548 for (i = 0; i < c->interfacescount; ++i) {
3549 mi = class_resolveinterfacemethod_int(c->interfaces[i], name, desc);
3555 utf_sprint(msg, c->name);
3556 sprintf(msg + strlen(msg), ".");
3557 utf_sprint(msg + strlen(msg), name);
3558 utf_sprint(msg + strlen(msg), desc);
3561 new_exception_message(string_java_lang_NoSuchMethodError, msg);
3567 if ((mi->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
3569 *exceptionptr = new_exception(string_java_lang_AbstractMethodError);
3574 /* XXX check access rights */
3580 /************************* Function: class_issubclass **************************
3582 Checks if sub is a descendant of super.
3584 *******************************************************************************/
3586 bool class_issubclass(classinfo *sub, classinfo *super)
3589 if (!sub) return false;
3590 if (sub == super) return true;
3596 /****************** Initialization function for classes ******************
3598 In Java, every class can have a static initialization function. This
3599 function has to be called BEFORE calling other methods or accessing static
3602 *******************************************************************************/
3604 static classinfo *class_init_intern(classinfo *c);
3606 classinfo *class_init(classinfo *c)
3610 if (!makeinitializations)
3613 /* enter a monitor on the class */
3615 builtin_monitorenter((java_objectheader *) c);
3617 /* maybe the class is already initalized or the current thread, which can
3618 pass the monitor, is currently initalizing this class */
3620 if (c->initialized || c->initializing) {
3621 builtin_monitorexit((java_objectheader *) c);
3626 /* this initalizing run begins NOW */
3627 c->initializing = true;
3629 /* call the internal function */
3630 r = class_init_intern(c);
3632 /* if return value is not NULL everything was ok and the class is
3635 c->initialized = true;
3637 /* this initalizing run is done */
3638 c->initializing = false;
3640 /* leave the monitor */
3642 builtin_monitorexit((java_objectheader *) c);
3648 /* this function MUST NOT be called directly, because of thread <clinit>
3651 static classinfo *class_init_intern(classinfo *c)
3655 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3667 #if defined(STATISTICS)
3669 count_class_inits++;
3672 /* initialize super class */
3674 if (!c->super->loaded)
3675 if (!class_load(c->super))
3678 if (!c->super->linked)
3679 if (!class_link(c->super))
3682 if (!c->super->initialized) {
3684 char logtext[MAXLOGTEXT];
3685 sprintf(logtext, "Initialize super class ");
3686 utf_sprint_classname(logtext + strlen(logtext), c->super->name);
3687 sprintf(logtext + strlen(logtext), " from ");
3688 utf_sprint_classname(logtext + strlen(logtext), c->name);
3692 if (!class_init(c->super))
3697 /* initialize interface classes */
3698 for (i = 0; i < c->interfacescount; i++) {
3699 if (!c->interfaces[i]->loaded)
3700 if (!class_load(c->interfaces[i]))
3703 if (!c->interfaces[i]->linked)
3704 if (!class_link(c->interfaces[i]))
3707 if (!c->interfaces[i]->initialized) {
3709 char logtext[MAXLOGTEXT];
3710 sprintf(logtext, "Initialize interface class ");
3711 utf_sprint_classname(logtext + strlen(logtext), c->interfaces[i]->name);
3712 sprintf(logtext + strlen(logtext), " from ");
3713 utf_sprint_classname(logtext + strlen(logtext), c->name);
3717 if (!class_init(c->interfaces[i]))
3722 m = class_findmethod(c, utf_clinit, utf_fidesc);
3726 char logtext[MAXLOGTEXT];
3727 sprintf(logtext, "Class ");
3728 utf_sprint_classname(logtext + strlen(logtext), c->name);
3729 sprintf(logtext + strlen(logtext), " has no static class initializer");
3736 if (!(m->flags & ACC_STATIC))
3737 panic("Class initializer is not static!");
3740 log_message_class("Starting static class initializer for class: ", c);
3742 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3747 /* now call the initializer */
3748 asm_calljavafunction(m, NULL, NULL, NULL, NULL);
3750 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3751 assert(blockInts == 0);
3755 /* we have an exception or error */
3756 if (*exceptionptr) {
3757 /* is this an exception, than wrap it */
3758 if (builtin_instanceof(*exceptionptr, class_java_lang_Exception)) {
3759 java_objectheader *xptr;
3760 java_objectheader *cause;
3762 /* class is NOT initialized */
3763 c->initialized = false;
3766 cause = *exceptionptr;
3768 /* clear exception, because we are calling jit code again */
3769 *exceptionptr = NULL;
3771 /* wrap the exception */
3773 new_exception_throwable(string_java_lang_ExceptionInInitializerError,
3774 (java_lang_Throwable *) cause);
3776 /* XXX should we exit here? */
3780 /* set new exception */
3781 *exceptionptr = xptr;
3788 log_message_class("Finished static class initializer for class: ", c);
3794 /********* Function: find_class_method_constant *********/
3796 int find_class_method_constant (classinfo *c, utf * c1, utf* m1, utf* d1)
3801 for (i=0; i<c->cpcount; i++) {
3803 e = c -> cpinfos [i];
3806 switch (c -> cptags [i]) {
3807 case CONSTANT_Methodref:
3809 constant_FMIref *fmi = e;
3810 if ( (fmi->class->name == c1)
3811 && (fmi->name == m1)
3812 && (fmi->descriptor == d1)) {
3819 case CONSTANT_InterfaceMethodref:
3821 constant_FMIref *fmi = e;
3822 if ( (fmi->class->name == c1)
3823 && (fmi->name == m1)
3824 && (fmi->descriptor == d1)) {
3838 void class_showconstanti(classinfo *c, int ii)
3844 printf ("#%d: ", (int) i);
3846 switch (c->cptags [i]) {
3847 case CONSTANT_Class:
3848 printf("Classreference -> ");
3849 utf_display(((classinfo*)e)->name);
3852 case CONSTANT_Fieldref:
3853 printf("Fieldref -> "); goto displayFMIi;
3854 case CONSTANT_Methodref:
3855 printf("Methodref -> "); goto displayFMIi;
3856 case CONSTANT_InterfaceMethodref:
3857 printf("InterfaceMethod -> "); goto displayFMIi;
3860 constant_FMIref *fmi = e;
3861 utf_display(fmi->class->name);
3863 utf_display(fmi->name);
3865 utf_display(fmi->descriptor);
3869 case CONSTANT_String:
3870 printf("String -> ");
3873 case CONSTANT_Integer:
3874 printf("Integer -> %d", (int) (((constant_integer*)e)->value));
3876 case CONSTANT_Float:
3877 printf("Float -> %f", ((constant_float*)e)->value);
3879 case CONSTANT_Double:
3880 printf("Double -> %f", ((constant_double*)e)->value);
3884 u8 v = ((constant_long*)e)->value;
3886 printf("Long -> %ld", (long int) v);
3888 printf("Long -> HI: %ld, LO: %ld\n",
3889 (long int) v.high, (long int) v.low);
3893 case CONSTANT_NameAndType:
3895 constant_nameandtype *cnt = e;
3896 printf("NameAndType: ");
3897 utf_display(cnt->name);
3899 utf_display(cnt->descriptor);
3907 panic("Invalid type of ConstantPool-Entry");
3914 void class_showconstantpool (classinfo *c)
3919 printf ("---- dump of constant pool ----\n");
3921 for (i=0; i<c->cpcount; i++) {
3922 printf ("#%d: ", (int) i);
3924 e = c -> cpinfos [i];
3927 switch (c -> cptags [i]) {
3928 case CONSTANT_Class:
3929 printf ("Classreference -> ");
3930 utf_display ( ((classinfo*)e) -> name );
3933 case CONSTANT_Fieldref:
3934 printf ("Fieldref -> "); goto displayFMI;
3935 case CONSTANT_Methodref:
3936 printf ("Methodref -> "); goto displayFMI;
3937 case CONSTANT_InterfaceMethodref:
3938 printf ("InterfaceMethod -> "); goto displayFMI;
3941 constant_FMIref *fmi = e;
3942 utf_display ( fmi->class->name );
3944 utf_display ( fmi->name);
3946 utf_display ( fmi->descriptor );
3950 case CONSTANT_String:
3951 printf ("String -> ");
3954 case CONSTANT_Integer:
3955 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
3957 case CONSTANT_Float:
3958 printf ("Float -> %f", ((constant_float*)e) -> value);
3960 case CONSTANT_Double:
3961 printf ("Double -> %f", ((constant_double*)e) -> value);
3965 u8 v = ((constant_long*)e) -> value;
3967 printf ("Long -> %ld", (long int) v);
3969 printf ("Long -> HI: %ld, LO: %ld\n",
3970 (long int) v.high, (long int) v.low);
3974 case CONSTANT_NameAndType:
3976 constant_nameandtype *cnt = e;
3977 printf ("NameAndType: ");
3978 utf_display (cnt->name);
3980 utf_display (cnt->descriptor);
3984 printf ("Utf8 -> ");
3988 panic ("Invalid type of ConstantPool-Entry");
3998 /********** Function: class_showmethods (debugging only) *************/
4000 void class_showmethods (classinfo *c)
4004 printf ("--------- Fields and Methods ----------------\n");
4005 printf ("Flags: "); printflags (c->flags); printf ("\n");
4007 printf ("This: "); utf_display (c->name); printf ("\n");
4009 printf ("Super: "); utf_display (c->super->name); printf ("\n");
4011 printf ("Index: %d\n", c->index);
4013 printf ("interfaces:\n");
4014 for (i=0; i < c-> interfacescount; i++) {
4016 utf_display (c -> interfaces[i] -> name);
4017 printf (" (%d)\n", c->interfaces[i] -> index);
4020 printf ("fields:\n");
4021 for (i=0; i < c -> fieldscount; i++) {
4022 field_display (&(c -> fields[i]));
4025 printf ("methods:\n");
4026 for (i=0; i < c -> methodscount; i++) {
4027 methodinfo *m = &(c->methods[i]);
4028 if ( !(m->flags & ACC_STATIC))
4029 printf ("vftblindex: %d ", m->vftblindex);
4031 method_display ( m );
4035 printf ("Virtual function table:\n");
4036 for (i=0; i<c->vftbl->vftbllength; i++) {
4037 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]) );
4043 /******************************************************************************/
4044 /******************* General functions for the class loader *******************/
4045 /******************************************************************************/
4047 /**************** function: create_primitive_classes ***************************
4049 create classes representing primitive types
4051 *******************************************************************************/
4053 void create_primitive_classes()
4057 for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
4058 /* create primitive class */
4060 class_new_intern(utf_new_char(primitivetype_table[i].name));
4061 c->classUsed = NOTUSED; /* not used initially CO-RT */
4064 /* prevent loader from loading primitive class */
4068 primitivetype_table[i].class_primitive = c;
4070 /* create class for wrapping the primitive type */
4071 c = class_new_intern(utf_new_char(primitivetype_table[i].wrapname));
4072 primitivetype_table[i].class_wrap = c;
4073 primitivetype_table[i].class_wrap->classUsed = NOTUSED; /* not used initially CO-RT */
4074 primitivetype_table[i].class_wrap->impldBy = NULL;
4076 /* create the primitive array class */
4077 if (primitivetype_table[i].arrayname) {
4078 c = class_new_intern(utf_new_char(primitivetype_table[i].arrayname));
4079 primitivetype_table[i].arrayclass = c;
4083 primitivetype_table[i].arrayvftbl = c->vftbl;
4089 /**************** function: class_primitive_from_sig ***************************
4091 return the primitive class indicated by the given signature character
4093 If the descriptor does not indicate a valid primitive type the
4094 return value is NULL.
4096 ********************************************************************************/
4098 classinfo *class_primitive_from_sig(char sig)
4101 case 'I': return primitivetype_table[PRIMITIVETYPE_INT].class_primitive;
4102 case 'J': return primitivetype_table[PRIMITIVETYPE_LONG].class_primitive;
4103 case 'F': return primitivetype_table[PRIMITIVETYPE_FLOAT].class_primitive;
4104 case 'D': return primitivetype_table[PRIMITIVETYPE_DOUBLE].class_primitive;
4105 case 'B': return primitivetype_table[PRIMITIVETYPE_BYTE].class_primitive;
4106 case 'C': return primitivetype_table[PRIMITIVETYPE_CHAR].class_primitive;
4107 case 'S': return primitivetype_table[PRIMITIVETYPE_SHORT].class_primitive;
4108 case 'Z': return primitivetype_table[PRIMITIVETYPE_BOOLEAN].class_primitive;
4109 case 'V': return primitivetype_table[PRIMITIVETYPE_VOID].class_primitive;
4114 /****************** function: class_from_descriptor ****************************
4116 return the class indicated by the given descriptor
4118 utf_ptr....first character of descriptor
4119 end_ptr....first character after the end of the string
4120 next.......if non-NULL, *next is set to the first character after
4121 the descriptor. (Undefined if an error occurs.)
4123 mode.......a combination (binary or) of the following flags:
4125 (Flags marked with * are the default settings.)
4127 What to do if a reference type descriptor is parsed successfully:
4129 CLASSLOAD_SKIP...skip it and return something != NULL
4130 * CLASSLOAD_NEW....get classinfo * via class_new
4131 CLASSLOAD_LOAD...get classinfo * via loader_load
4133 How to handle primitive types:
4135 * CLASSLOAD_PRIMITIVE.......return primitive class (eg. "int")
4136 CLASSLOAD_NULLPRIMITIVE...return NULL for primitive types
4138 How to handle "V" descriptors:
4140 * CLASSLOAD_VOID.....handle it like other primitive types
4141 CLASSLOAD_NOVOID...treat it as an error
4143 How to deal with extra characters after the end of the
4146 * CLASSLOAD_NOCHECKEND...ignore (useful for parameter lists)
4147 CLASSLOAD_CHECKEND.....treat them as an error
4149 How to deal with errors:
4151 * CLASSLOAD_PANIC....abort execution with an error message
4152 CLASSLOAD_NOPANIC..return NULL on error
4154 *******************************************************************************/
4156 classinfo *class_from_descriptor(char *utf_ptr, char *end_ptr,
4157 char **next, int mode)
4159 char *start = utf_ptr;
4163 SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr, end_ptr, error);
4165 if (mode & CLASSLOAD_CHECKEND)
4166 error |= (utf_ptr != end_ptr);
4169 if (next) *next = utf_ptr;
4173 if (mode & CLASSLOAD_NOVOID)
4184 return (mode & CLASSLOAD_NULLPRIMITIVE)
4186 : class_primitive_from_sig(*start);
4193 if (mode & CLASSLOAD_SKIP) return class_java_lang_Object;
4194 name = utf_new(start, utf_ptr - start);
4198 tc = class_new_intern(name);
4200 list_addfirst(&unlinkedclasses, tc);
4205 return (mode & CLASSLOAD_LOAD)
4206 ? class_load(class_new(name)) : class_new(name); /* XXX handle errors */
4211 /* An error occurred */
4212 if (mode & CLASSLOAD_NOPANIC)
4215 log_plain("Invalid descriptor at beginning of '");
4216 log_plain_utf(utf_new(start, end_ptr - start));
4220 panic("Invalid descriptor");
4222 /* keep compiler happy */
4227 /******************* function: type_from_descriptor ****************************
4229 return the basic type indicated by the given descriptor
4231 This function parses a descriptor and returns its basic type as
4232 TYPE_INT, TYPE_LONG, TYPE_FLOAT, TYPE_DOUBLE, TYPE_ADDRESS or TYPE_VOID.
4234 cls...if non-NULL the referenced variable is set to the classinfo *
4235 returned by class_from_descriptor.
4237 For documentation of the arguments utf_ptr, end_ptr, next and mode
4238 see class_from_descriptor. The only difference is that
4239 type_from_descriptor always uses CLASSLOAD_PANIC.
4241 ********************************************************************************/
4243 int type_from_descriptor(classinfo **cls, char *utf_ptr, char *end_ptr,
4244 char **next, int mode)
4247 if (!cls) cls = &mycls;
4248 *cls = class_from_descriptor(utf_ptr, end_ptr, next, mode & (~CLASSLOAD_NOPANIC));
4265 return TYPE_ADDRESS;
4269 /*************** function: create_pseudo_classes *******************************
4271 create pseudo classes used by the typechecker
4273 ********************************************************************************/
4275 static void create_pseudo_classes()
4277 /* pseudo class for Arraystubs (extends java.lang.Object) */
4279 pseudo_class_Arraystub = class_new_intern(utf_new_char("$ARRAYSTUB$"));
4280 pseudo_class_Arraystub->loaded = true;
4281 pseudo_class_Arraystub->super = class_java_lang_Object;
4282 pseudo_class_Arraystub->interfacescount = 2;
4283 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
4284 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
4285 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
4287 class_link(pseudo_class_Arraystub);
4289 pseudo_class_Arraystub_vftbl = pseudo_class_Arraystub->vftbl;
4291 /* pseudo class representing the null type */
4293 pseudo_class_Null = class_new_intern(utf_new_char("$NULL$"));
4294 pseudo_class_Null->loaded = true;
4295 pseudo_class_Null->super = class_java_lang_Object;
4296 class_link(pseudo_class_Null);
4298 /* pseudo class representing new uninitialized objects */
4300 pseudo_class_New = class_new_intern(utf_new_char("$NEW$"));
4301 pseudo_class_New->loaded = true;
4302 pseudo_class_New->linked = true;
4303 pseudo_class_New->super = class_java_lang_Object;
4304 /* class_link(pseudo_class_New); */
4308 /********************** Function: loader_init **********************************
4310 Initializes all lists and loads all classes required for the system or the
4313 *******************************************************************************/
4315 void loader_init(u1 *stackbottom)
4319 /* create utf-symbols for pointer comparison of frequently used strings */
4320 utf_innerclasses = utf_new_char("InnerClasses");
4321 utf_constantvalue = utf_new_char("ConstantValue");
4322 utf_code = utf_new_char("Code");
4323 utf_exceptions = utf_new_char("Exceptions");
4324 utf_linenumbertable = utf_new_char("LineNumberTable");
4325 utf_sourcefile = utf_new_char("SourceFile");
4326 utf_finalize = utf_new_char("finalize");
4327 utf_fidesc = utf_new_char("()V");
4328 utf_init = utf_new_char("<init>");
4329 utf_clinit = utf_new_char("<clinit>");
4330 utf_initsystemclass = utf_new_char("initializeSystemClass");
4331 utf_systemclass = utf_new_char("java/lang/System");
4332 utf_vmclassloader = utf_new_char("java/lang/VMClassLoader");
4333 utf_initialize = utf_new_char("initialize");
4334 utf_initializedesc = utf_new_char("(I)V");
4335 utf_vmclass = utf_new_char("java/lang/VMClass");
4336 utf_java_lang_Object= utf_new_char("java/lang/Object");
4337 array_packagename = utf_new_char("<the array package>");
4338 utf_fillInStackTrace_name = utf_new_char("fillInStackTrace");
4339 utf_fillInStackTrace_desc = utf_new_char("()Ljava/lang/Throwable;");
4341 /* create some important classes */
4342 /* These classes have to be created now because the classinfo
4343 * pointers are used in the loading code.
4345 class_java_lang_Object =
4346 class_new_intern(utf_java_lang_Object);
4347 class_load(class_java_lang_Object);
4348 class_link(class_java_lang_Object);
4350 class_java_lang_String =
4351 class_new_intern(utf_new_char("java/lang/String"));
4352 class_load(class_java_lang_String);
4353 class_link(class_java_lang_String);
4355 class_java_lang_Cloneable =
4356 class_new_intern(utf_new_char("java/lang/Cloneable"));
4357 class_load(class_java_lang_Cloneable);
4358 class_link(class_java_lang_Cloneable);
4360 class_java_io_Serializable =
4361 class_new_intern(utf_new_char("java/io/Serializable"));
4362 class_load(class_java_io_Serializable);
4363 class_link(class_java_io_Serializable);
4365 /* create classes representing primitive types */
4366 create_primitive_classes();
4368 /* create classes used by the typechecker */
4369 create_pseudo_classes();
4371 /* correct vftbl-entries (retarded loading of class java/lang/String) */
4372 stringtable_update();
4374 #if defined(USE_THREADS)
4375 if (stackbottom != 0)
4381 static void loader_compute_class_values(classinfo *c)
4385 c->vftbl->baseval = ++classvalue;
4388 while (subs != NULL) {
4389 loader_compute_class_values(subs);
4390 subs = subs->nextsub;
4393 c->vftbl->diffval = classvalue - c->vftbl->baseval;
4397 void loader_compute_subclasses(classinfo *c)
4399 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
4403 if (!(c->flags & ACC_INTERFACE)) {
4408 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
4409 c->nextsub = c->super->sub;
4415 /* this is the java.lang.Object special case */
4416 if (!class_java_lang_Object) {
4417 loader_compute_class_values(c);
4420 loader_compute_class_values(class_java_lang_Object);
4423 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
4429 /******************** Function: loader_close ***********************************
4433 *******************************************************************************/
4440 for (slot = 0; slot < class_hash.size; slot++) {
4441 c = class_hash.ptr[slot];
4452 * These are local overrides for various environment variables in Emacs.
4453 * Please do not remove this and leave it at the end of the file, where
4454 * Emacs will automagically detect them.
4455 * ---------------------------------------------------------------------
4458 * indent-tabs-mode: t