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 1182 2004-06-19 12:13:45Z twisti $
52 #include "toolbox/memory.h"
53 #include "toolbox/logging.h"
54 #include "threads/thread.h"
55 #include "threads/locks.h"
56 #include "nat/java_lang_Throwable.h"
66 /* global variables ***********************************************************/
68 int count_class_infos = 0; /* variables for measurements */
69 int count_const_pool_len = 0;
70 int count_vftbl_len = 0;
71 int count_all_methods = 0;
72 int count_vmcode_len = 0;
73 int count_extable_len = 0;
74 int count_class_loads = 0;
75 int count_class_inits = 0;
77 static s4 interfaceindex; /* sequential numbering of interfaces */
81 /* utf-symbols for pointer comparison of frequently used strings */
83 static utf *utf_innerclasses; /* InnerClasses */
84 static utf *utf_constantvalue; /* ConstantValue */
85 static utf *utf_code; /* Code */
86 static utf *utf_exceptions; /* Exceptions */
87 static utf *utf_linenumbertable; /* LineNumberTable */
88 static utf *utf_sourcefile; /* SourceFile */
89 static utf *utf_finalize; /* finalize */
90 static utf *utf_fidesc; /* ()V changed */
91 static utf *utf_init; /* <init> */
92 static utf *utf_clinit; /* <clinit> */
93 static utf *utf_initsystemclass; /* initializeSystemClass */
94 static utf *utf_systemclass; /* java/lang/System */
95 static utf *utf_vmclassloader; /* java/lang/VMClassLoader */
96 static utf *utf_vmclass; /* java/lang/VMClassLoader */
97 static utf *utf_initialize;
98 static utf *utf_initializedesc;
99 static utf *utf_java_lang_Object; /* java/lang/Object */
101 utf *utf_fillInStackTrace_name;
102 utf *utf_fillInStackTrace_desc;
112 /* important system classes ***************************************************/
114 classinfo *class_java_lang_Object;
115 classinfo *class_java_lang_String;
116 classinfo *class_java_lang_Cloneable;
117 classinfo *class_java_io_Serializable;
119 /* Pseudo classes for the typechecker */
120 classinfo *pseudo_class_Arraystub = NULL;
121 classinfo *pseudo_class_Null = NULL;
122 classinfo *pseudo_class_New = NULL;
123 vftbl *pseudo_class_Arraystub_vftbl = NULL;
125 utf *array_packagename = NULL;
128 /********************************************************************
129 list of classpath entries (either filesystem directories or
131 ********************************************************************/
132 static classpath_info *classpath_entries=0;
135 /******************************************************************************
137 structure for primitive classes: contains the class for wrapping the
138 primitive type, the primitive class, the name of the class for wrapping,
139 the one character type signature and the name of the primitive class
141 ******************************************************************************/
143 /* CAUTION: Don't change the order of the types. This table is indexed
144 * by the ARRAYTYPE_ constants (expcept ARRAYTYPE_OBJECT).
146 primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = {
147 { NULL, NULL, "java/lang/Integer", 'I', "int" , "[I", NULL, NULL },
148 { NULL, NULL, "java/lang/Long", 'J', "long" , "[J", NULL, NULL },
149 { NULL, NULL, "java/lang/Float", 'F', "float" , "[F", NULL, NULL },
150 { NULL, NULL, "java/lang/Double", 'D', "double" , "[D", NULL, NULL },
151 { NULL, NULL, "java/lang/Byte", 'B', "byte" , "[B", NULL, NULL },
152 { NULL, NULL, "java/lang/Character", 'C', "char" , "[C", NULL, NULL },
153 { NULL, NULL, "java/lang/Short", 'S', "short" , "[S", NULL, NULL },
154 { NULL, NULL, "java/lang/Boolean", 'Z', "boolean" , "[Z", NULL, NULL },
155 { NULL, NULL, "java/lang/Void", 'V', "void" , NULL, NULL, NULL }
159 /* instances of important system classes **************************************/
161 java_objectheader *proto_java_lang_NullPointerException;
164 /************* functions for reading classdata *********************************
166 getting classdata in blocks of variable size
167 (8,16,32,64-bit integer or float)
169 *******************************************************************************/
171 static char *classpath = ""; /* searchpath for classfiles */
174 static java_objectheader *new_classformaterror(classinfo *c, char *message, ...)
176 char cfmessage[MAXLOGTEXT];
179 utf_sprint_classname(cfmessage, c->name);
180 sprintf(cfmessage + strlen(cfmessage), " (");
182 va_start(ap, message);
183 vsprintf(cfmessage + strlen(cfmessage), message, ap);
186 sprintf(cfmessage + strlen(cfmessage), ")");
188 return new_exception_message(string_java_lang_ClassFormatError, cfmessage);
192 /* check_classbuffer_size ******************************************************
194 assert that at least <len> bytes are left to read
195 <len> is limited to the range of non-negative s4 values
197 *******************************************************************************/
199 static inline bool check_classbuffer_size(classbuffer *cb, s4 len)
201 if (len < 0 || ((cb->data + cb->size) - cb->pos - 1) < len) {
203 new_classformaterror((cb)->class, "Truncated class file");
212 /* suck_nbytes *****************************************************************
214 transfer block of classfile data into a buffer
216 *******************************************************************************/
218 inline void suck_nbytes(u1 *buffer, classbuffer *cb, s4 len)
220 memcpy(buffer, cb->pos + 1, len);
225 /* skip_nbytes ****************************************************************
227 skip block of classfile data
229 *******************************************************************************/
231 inline void skip_nbytes(classbuffer *cb, s4 len)
237 inline u1 suck_u1(classbuffer *cb)
243 inline u2 suck_u2(classbuffer *cb)
247 return ((u2) a << 8) + (u2) b;
251 inline u4 suck_u4(classbuffer *cb)
257 return ((u4) a << 24) + ((u4) b << 16) + ((u4) c << 8) + (u4) d;
260 #define suck_s8(a) (s8) suck_u8((a))
261 #define suck_s2(a) (s2) suck_u2((a))
262 #define suck_s4(a) (s4) suck_u4((a))
263 #define suck_s1(a) (s1) suck_u1((a))
266 /* get u8 from classfile data */
267 static u8 suck_u8(classbuffer *cb)
273 return (hi << 32) + lo;
276 v.high = suck_u4(cb);
283 /* get float from classfile data */
284 static float suck_float(classbuffer *cb)
292 for (i = 0; i < 4; i++)
293 buffer[3 - i] = suck_u1(cb);
295 memcpy((u1*) (&f), buffer, 4);
297 suck_nbytes((u1*) (&f), cb, 4);
300 if (sizeof(float) != 4) {
301 *exceptionptr = new_exception_message(string_java_lang_InternalError,
302 "Incompatible float-format");
304 /* XXX should we exit in such a case? */
305 throw_exception_exit();
312 /* get double from classfile data */
313 static double suck_double(classbuffer *cb)
321 for (i = 0; i < 8; i++)
322 buffer[7 - i] = suck_u1(cb);
324 memcpy((u1*) (&d), buffer, 8);
326 suck_nbytes((u1*) (&d), cb, 8);
329 if (sizeof(double) != 8) {
330 *exceptionptr = new_exception_message(string_java_lang_InternalError,
331 "Incompatible double-format");
333 /* XXX should we exit in such a case? */
334 throw_exception_exit();
341 /************************** function suck_init *********************************
343 called once at startup, sets the searchpath for the classfiles
345 *******************************************************************************/
347 void suck_init(char *cpath)
354 union classpath_info *tmp;
355 union classpath_info *insertAfter=0;
362 if (classpath_entries)
363 panic("suck_init should be called only once");
365 for (start = classpath; (*start) != '\0';) {
366 for (end = start; ((*end) != '\0') && ((*end) != ':'); end++);
370 filenamelen = end - start;
373 if (strncasecmp(end - 3, "zip", 3) == 0 ||
374 strncasecmp(end - 3, "jar", 3) == 0) {
379 if (filenamelen >= (CLASSPATH_MAXFILENAME - 1))
380 panic("path length >= MAXFILENAME in suck_init");
383 filename = MNEW(char, CLASSPATH_MAXFILENAME);
385 strncpy(filename, start, filenamelen);
386 filename[filenamelen + 1] = '\0';
391 unzFile uf = unzOpen(filename);
394 tmp = (union classpath_info *) NEW(classpath_info);
395 tmp->archive.type = CLASSPATH_ARCHIVE;
396 tmp->archive.uf = uf;
397 tmp->archive.next = 0;
401 panic("Zip/JAR not supported");
405 tmp = (union classpath_info *) NEW(classpath_info);
406 tmp->filepath.type = CLASSPATH_PATH;
407 tmp->filepath.next = 0;
409 if (filename[filenamelen - 1] != '/') {/*PERHAPS THIS SHOULD BE READ FROM A GLOBAL CONFIGURATION */
410 filename[filenamelen] = '/';
411 filename[filenamelen + 1] = '\0';
415 tmp->filepath.filename = filename;
416 tmp->filepath.pathlen = filenamelen;
422 insertAfter->filepath.next = tmp;
425 classpath_entries = tmp;
437 MFREE(filename, char, CLASSPATH_MAXFILENAME);
444 void create_all_classes()
448 for (cpi = classpath_entries; cpi != 0; cpi = cpi->filepath.next) {
449 #if defined(USE_ZLIB)
450 if (cpi->filepath.type == CLASSPATH_ARCHIVE) {
454 s = (unz_s *) cpi->archive.uf;
455 ce = s->cacao_dir_list;
458 (void) class_new(ce->name);
464 #if defined(USE_ZLIB)
471 /************************** function suck_start ********************************
473 returns true if classbuffer is already loaded or a file for the
474 specified class has succussfully been read in. All directories of
475 the searchpath are used to find the classfile (<classname>.class).
476 Returns false if no classfile is found and writes an error message.
478 *******************************************************************************/
480 classbuffer *suck_start(classinfo *c)
482 classpath_info *currPos;
485 char filename[CLASSPATH_MAXFILENAME+10]; /* room for '.class' */
492 utf_ptr = c->name->text;
494 while (utf_ptr < utf_end(c->name)) {
495 if (filenamelen >= CLASSPATH_MAXFILENAME) {
497 new_exception_message(string_java_lang_InternalError,
498 "Filename too long");
500 /* XXX should we exit in such a case? */
501 throw_exception_exit();
505 if ((ch <= ' ' || ch > 'z') && (ch != '/')) /* invalid character */
507 filename[filenamelen++] = ch;
510 strcpy(filename + filenamelen, ".class");
513 for (currPos = classpath_entries; currPos != 0; currPos = currPos->filepath.next) {
515 if (currPos->filepath.type == CLASSPATH_ARCHIVE) {
516 if (cacao_locate(currPos->archive.uf, c->name) == UNZ_OK) {
517 unz_file_info file_info;
518 /*log_text("Class found in zip file");*/
519 if (unzGetCurrentFileInfo(currPos->archive.uf, &file_info, filename,
520 sizeof(filename), NULL, 0, NULL, 0) == UNZ_OK) {
521 if (unzOpenCurrentFile(currPos->archive.uf) == UNZ_OK) {
522 cb = NEW(classbuffer);
524 cb->size = file_info.uncompressed_size;
525 cb->data = MNEW(u1, cb->size);
526 cb->pos = cb->data - 1;
527 /*printf("classfile size: %d\n",file_info.uncompressed_size);*/
528 if (unzReadCurrentFile(currPos->archive.uf, cb->data, cb->size) == cb->size) {
529 unzCloseCurrentFile(currPos->archive.uf);
533 MFREE(cb->data, u1, cb->size);
534 FREE(cb, classbuffer);
535 log_text("Error while unzipping");
537 } else log_text("Error while opening file in archive");
538 } else log_text("Error while retrieving fileinfo");
540 unzCloseCurrentFile(currPos->archive.uf);
544 if ((currPos->filepath.pathlen + filenamelen) >= CLASSPATH_MAXFILENAME) continue;
545 strcpy(currPos->filepath.filename + currPos->filepath.pathlen, filename);
546 classfile = fopen(currPos->filepath.filename, "r");
547 if (classfile) { /* file exists */
549 /* determine size of classfile */
551 /* dolog("File: %s",filename); */
552 err = stat(currPos->filepath.filename, &buffer);
554 if (!err) { /* read classfile data */
555 cb = NEW(classbuffer);
557 cb->size = buffer.st_size;
558 cb->data = MNEW(u1, cb->size);
559 cb->pos = cb->data - 1;
560 fread(cb->data, 1, cb->size, classfile);
572 dolog("Warning: Can not open class file '%s'", filename);
579 /************************** function suck_stop *********************************
581 frees memory for buffer with classfile data.
582 Caution: this function may only be called if buffer has been allocated
583 by suck_start with reading a file
585 *******************************************************************************/
587 void suck_stop(classbuffer *cb)
591 MFREE(cb->data, u1, cb->size);
592 FREE(cb, classbuffer);
596 /******************************************************************************/
597 /******************* Some support functions ***********************************/
598 /******************************************************************************/
600 void fprintflags (FILE *fp, u2 f)
602 if ( f & ACC_PUBLIC ) fprintf (fp," PUBLIC");
603 if ( f & ACC_PRIVATE ) fprintf (fp," PRIVATE");
604 if ( f & ACC_PROTECTED ) fprintf (fp," PROTECTED");
605 if ( f & ACC_STATIC ) fprintf (fp," STATIC");
606 if ( f & ACC_FINAL ) fprintf (fp," FINAL");
607 if ( f & ACC_SYNCHRONIZED ) fprintf (fp," SYNCHRONIZED");
608 if ( f & ACC_VOLATILE ) fprintf (fp," VOLATILE");
609 if ( f & ACC_TRANSIENT ) fprintf (fp," TRANSIENT");
610 if ( f & ACC_NATIVE ) fprintf (fp," NATIVE");
611 if ( f & ACC_INTERFACE ) fprintf (fp," INTERFACE");
612 if ( f & ACC_ABSTRACT ) fprintf (fp," ABSTRACT");
616 /********** internal function: printflags (only for debugging) ***************/
618 void printflags(u2 f)
620 if ( f & ACC_PUBLIC ) printf (" PUBLIC");
621 if ( f & ACC_PRIVATE ) printf (" PRIVATE");
622 if ( f & ACC_PROTECTED ) printf (" PROTECTED");
623 if ( f & ACC_STATIC ) printf (" STATIC");
624 if ( f & ACC_FINAL ) printf (" FINAL");
625 if ( f & ACC_SYNCHRONIZED ) printf (" SYNCHRONIZED");
626 if ( f & ACC_VOLATILE ) printf (" VOLATILE");
627 if ( f & ACC_TRANSIENT ) printf (" TRANSIENT");
628 if ( f & ACC_NATIVE ) printf (" NATIVE");
629 if ( f & ACC_INTERFACE ) printf (" INTERFACE");
630 if ( f & ACC_ABSTRACT ) printf (" ABSTRACT");
634 /********************** Function: skipattributebody ****************************
636 skips an attribute after the 16 bit reference to attribute_name has already
639 *******************************************************************************/
641 static bool skipattributebody(classbuffer *cb)
645 if (!check_classbuffer_size(cb, 4))
650 if (!check_classbuffer_size(cb, len))
653 skip_nbytes(cb, len);
659 /************************* Function: skipattributes ****************************
661 skips num attribute structures
663 *******************************************************************************/
665 static bool skipattributes(classbuffer *cb, u4 num)
670 for (i = 0; i < num; i++) {
671 if (!check_classbuffer_size(cb, 2 + 4))
677 if (!check_classbuffer_size(cb, len))
680 skip_nbytes(cb, len);
687 /******************** function: innerclass_getconstant ************************
689 like class_getconstant, but if cptags is ZERO null is returned
691 *******************************************************************************/
693 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
695 /* invalid position in constantpool */
696 if (pos >= c->cpcount)
697 panic("Attempt to access constant outside range");
699 /* constantpool entry of type 0 */
703 /* check type of constantpool entry */
704 if (c->cptags[pos] != ctype) {
705 error("Type mismatch on constant: %d requested, %d here (innerclass_getconstant)",
706 (int) ctype, (int) c->cptags[pos] );
709 return c->cpinfos[pos];
713 /************************ function: attribute_load ****************************
715 read attributes from classfile
717 *******************************************************************************/
719 static bool attribute_load(classbuffer *cb, classinfo *c, u4 num)
723 for (i = 0; i < num; i++) {
724 /* retrieve attribute name */
725 if (!check_classbuffer_size(cb, 2))
728 utf *aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
730 if (aname == utf_innerclasses) {
731 /* innerclasses attribute */
732 if (c->innerclass != NULL)
733 panic("Class has more than one InnerClasses attribute");
735 if (!check_classbuffer_size(cb, 4 + 2))
738 /* skip attribute length */
741 /* number of records */
742 c->innerclasscount = suck_u2(cb);
744 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
747 /* allocate memory for innerclass structure */
748 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
750 for (j = 0; j < c->innerclasscount; j++) {
751 /* The innerclass structure contains a class with an encoded
752 name, its defining scope, its simple name and a bitmask of
753 the access flags. If an inner class is not a member, its
754 outer_class is NULL, if a class is anonymous, its name is
757 innerclassinfo *info = c->innerclass + j;
760 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
762 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
764 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
765 info->flags = suck_u2(cb);
768 } else if (aname==utf_sourcefile) {
769 if (!check_classbuffer_size(cb, 4 + 2))
773 c->sourcefile = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
776 /* unknown attribute */
777 if (!skipattributebody(cb))
786 /******************* function: checkfielddescriptor ****************************
788 checks whether a field-descriptor is valid and aborts otherwise
789 all referenced classes are inserted into the list of unloaded classes
791 *******************************************************************************/
793 static void checkfielddescriptor (char *utf_ptr, char *end_pos)
795 class_from_descriptor(utf_ptr,end_pos,NULL,
797 | CLASSLOAD_NULLPRIMITIVE
799 | CLASSLOAD_CHECKEND);
801 /* XXX use the following if -noverify */
803 char *tstart; /* pointer to start of classname */
805 char *start = utf_ptr;
807 switch (*utf_ptr++) {
821 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
822 panic ("Ill formed descriptor");
826 panic ("Ill formed descriptor");
829 /* exceeding characters */
830 if (utf_ptr!=end_pos) panic ("descriptor has exceeding chars");
835 /******************* function checkmethoddescriptor ****************************
837 checks whether a method-descriptor is valid and aborts otherwise.
838 All referenced classes are inserted into the list of unloaded classes.
840 The number of arguments is returned. A long or double argument is counted
843 *******************************************************************************/
845 static int checkmethoddescriptor(classinfo *c, utf *descriptor)
847 char *utf_ptr; /* current position in utf text */
848 char *end_pos; /* points behind utf string */
849 s4 argcount = 0; /* number of arguments */
851 utf_ptr = descriptor->text;
852 end_pos = utf_end(descriptor);
854 /* method descriptor must start with parenthesis */
855 if (utf_ptr == end_pos || *utf_ptr++ != '(')
856 panic ("Missing '(' in method descriptor");
858 /* check arguments */
859 while (utf_ptr != end_pos && *utf_ptr != ')') {
860 /* We cannot count the this argument here because
861 * we don't know if the method is static. */
862 if (*utf_ptr == 'J' || *utf_ptr == 'D')
866 class_from_descriptor(utf_ptr,end_pos,&utf_ptr,
868 | CLASSLOAD_NULLPRIMITIVE
872 if (utf_ptr == end_pos)
873 panic("Missing ')' in method descriptor");
875 utf_ptr++; /* skip ')' */
877 class_from_descriptor(utf_ptr,
881 CLASSLOAD_NULLPRIMITIVE |
884 if (argcount > 255) {
886 new_classformaterror(c, "Too many arguments in signature");
893 /* XXX use the following if -noverify */
895 /* check arguments */
896 while ((c = *utf_ptr++) != ')') {
913 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
914 panic ("Ill formed method descriptor");
918 panic ("Ill formed methodtype-descriptor");
922 /* check returntype */
924 /* returntype void */
925 if ((utf_ptr+1) != end_pos) panic ("Method-descriptor has exceeding chars");
928 /* treat as field-descriptor */
929 checkfielddescriptor (utf_ptr,end_pos);
934 /***************** Function: print_arraydescriptor ****************************
936 Debugging helper for displaying an arraydescriptor
938 *******************************************************************************/
940 void print_arraydescriptor(FILE *file, arraydescriptor *desc)
943 fprintf(file, "<NULL>");
948 if (desc->componentvftbl) {
949 if (desc->componentvftbl->class)
950 utf_fprint(file, desc->componentvftbl->class->name);
952 fprintf(file, "<no classinfo>");
958 if (desc->elementvftbl) {
959 if (desc->elementvftbl->class)
960 utf_fprint(file, desc->elementvftbl->class->name);
962 fprintf(file, "<no classinfo>");
966 fprintf(file, ",%d,%d,%d,%d}", desc->arraytype, desc->dimension,
967 desc->dataoffset, desc->componentsize);
971 /******************************************************************************/
972 /************************** Functions for fields ****************************/
973 /******************************************************************************/
976 /* field_load ******************************************************************
978 Load everything about a class field from the class file and fill a
979 'fieldinfo' structure. For static fields, space in the data segment is
982 *******************************************************************************/
984 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
986 static bool field_load(classbuffer *cb, classinfo *c, fieldinfo *f)
990 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
992 if (!check_classbuffer_size(cb, 2 + 2 + 2))
995 f->flags = suck_u2(cb);
996 f->name = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
997 f->descriptor = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1001 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<')
1002 panic("Field with invalid name");
1004 /* check flag consistency */
1005 i = (f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1007 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED)
1008 panic("Field has invalid access flags");
1010 if ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))
1011 panic("Field is declared final and volatile");
1013 if ((c->flags & ACC_INTERFACE) != 0) {
1014 if ((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
1015 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
1016 panic("Interface field is not declared static final public");
1018 if ((f->flags & ACC_TRANSIENT) != 0)
1019 panic("Interface field declared transient");
1022 /* check descriptor */
1023 checkfielddescriptor(f->descriptor->text, utf_end(f->descriptor));
1026 f->type = jtype = desc_to_type(f->descriptor); /* data type */
1027 f->offset = 0; /* offset from start of object */
1032 case TYPE_INT: f->value.i = 0; break;
1033 case TYPE_FLOAT: f->value.f = 0.0; break;
1034 case TYPE_DOUBLE: f->value.d = 0.0; break;
1035 case TYPE_ADDRESS: f->value.a = NULL; break;
1038 f->value.l = 0; break;
1040 f->value.l.low = 0; f->value.l.high = 0; break;
1044 /* read attributes */
1045 if (!check_classbuffer_size(cb, 2))
1048 attrnum = suck_u2(cb);
1049 for (i = 0; i < attrnum; i++) {
1052 if (!check_classbuffer_size(cb, 2))
1055 aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1057 if (aname != utf_constantvalue) {
1058 /* unknown attribute */
1059 if (!skipattributebody(cb))
1063 /* constant value attribute */
1064 if (pindex != field_load_NOVALUE)
1065 panic("Field has more than one ConstantValue attribute");
1067 if (!check_classbuffer_size(cb, 4 + 2))
1070 /* check attribute length */
1071 if (suck_u4(cb) != 2)
1072 panic("ConstantValue attribute has invalid length");
1074 /* index of value in constantpool */
1075 pindex = suck_u2(cb);
1077 /* initialize field with value from constantpool */
1080 constant_integer *ci =
1081 class_getconstant(c, pindex, CONSTANT_Integer);
1082 f->value.i = ci->value;
1088 class_getconstant(c, pindex, CONSTANT_Long);
1089 f->value.l = cl->value;
1094 constant_float *cf =
1095 class_getconstant(c, pindex, CONSTANT_Float);
1096 f->value.f = cf->value;
1101 constant_double *cd =
1102 class_getconstant(c, pindex, CONSTANT_Double);
1103 f->value.d = cd->value;
1107 case TYPE_ADDRESS: {
1108 utf *u = class_getconstant(c, pindex, CONSTANT_String);
1109 /* create javastring from compressed utf8-string */
1110 f->value.a = literalstring_new(u);
1115 log_text ("Invalid Constant - Type");
1120 /* everything was ok */
1126 /********************** function: field_free **********************************/
1128 static void field_free(fieldinfo *f)
1134 /**************** Function: field_display (debugging only) ********************/
1136 void field_display(fieldinfo *f)
1139 printflags(f->flags);
1141 utf_display(f->name);
1143 utf_display(f->descriptor);
1144 printf(" offset: %ld\n", (long int) (f->offset));
1148 /******************************************************************************/
1149 /************************* Functions for methods ******************************/
1150 /******************************************************************************/
1153 /* method_load *****************************************************************
1155 Loads a method from the class file and fills an existing 'methodinfo'
1156 structure. For native methods, the function pointer field is set to the
1157 real function pointer, for JavaVM methods a pointer to the compiler is used
1160 *******************************************************************************/
1162 static bool method_load(classbuffer *cb, classinfo *c, methodinfo *m)
1171 count_all_methods++;
1174 m->thrownexceptionscount = 0;
1175 m->linenumbercount = 0;
1178 m->nativelyoverloaded = false;
1180 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1183 m->flags = suck_u2(cb);
1184 m->name = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1185 m->descriptor = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1188 if (!is_valid_name_utf(m->name))
1189 panic("Method with invalid name");
1191 if (m->name->text[0] == '<'
1192 && m->name != utf_init && m->name != utf_clinit)
1193 panic("Method with invalid special name");
1196 argcount = checkmethoddescriptor(c, m->descriptor);
1198 if (!(m->flags & ACC_STATIC))
1199 argcount++; /* count the 'this' argument */
1203 panic("Too many arguments in signature");
1205 /* check flag consistency */
1206 if (m->name != utf_clinit) {
1207 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1209 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED)
1210 panic("Method has invalid access flags");
1212 if ((m->flags & ACC_ABSTRACT) != 0) {
1213 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1214 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1216 new_classformaterror(c,
1217 "Illegal method modifiers: 0x%x",
1224 if ((c->flags & ACC_INTERFACE) != 0) {
1225 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC))
1226 != (ACC_ABSTRACT | ACC_PUBLIC))
1227 panic("Interface method is not declared abstract and public");
1230 if (m->name == utf_init) {
1231 if ((m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED
1232 | ACC_NATIVE | ACC_ABSTRACT)) != 0)
1233 panic("Instance initialization method has invalid flags set");
1239 m->exceptiontable = NULL;
1240 m->entrypoint = NULL;
1242 m->stubroutine = NULL;
1243 m->methodUsed = NOTUSED;
1246 m->subRedefsUsed = 0;
1250 if (!(m->flags & ACC_NATIVE)) {
1251 m->stubroutine = createcompilerstub(m);
1254 functionptr f = native_findfunction(c->name, m->name, m->descriptor,
1255 (m->flags & ACC_STATIC) != 0);
1257 m->stubroutine = createnativestub(f, m);
1261 if (!check_classbuffer_size(cb, 2))
1264 attrnum = suck_u2(cb);
1265 for (i = 0; i < attrnum; i++) {
1268 if (!check_classbuffer_size(cb, 2))
1271 aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1273 if (aname != utf_code) {
1274 if (aname == utf_exceptions) {
1277 if (!check_classbuffer_size(cb, 4 + 2))
1280 suck_u4(cb); /*length*/
1281 m->thrownexceptionscount = suck_u2(cb);
1283 if (!check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1286 m->thrownexceptions = MNEW(classinfo*, m->thrownexceptionscount);
1288 for (j = 0; j < m->thrownexceptionscount; j++) {
1289 (m->thrownexceptions)[j] =
1290 class_getconstant(c, suck_u2(cb), CONSTANT_Class);
1294 if (!skipattributebody(cb))
1299 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1301 new_classformaterror(c,
1302 "Code attribute in native or abstract methods");
1309 new_classformaterror(c, "Multiple Code attributes");
1314 if (!check_classbuffer_size(cb, 4 + 2 + 2))
1318 m->maxstack = suck_u2(cb);
1319 m->maxlocals = suck_u2(cb);
1321 if (m->maxlocals < argcount) {
1323 new_classformaterror(c, "Arguments can't fit into locals");
1328 if (!check_classbuffer_size(cb, 4))
1331 m->jcodelength = suck_u4(cb);
1333 if (m->jcodelength == 0)
1334 panic("bytecode has zero length");
1336 if (m->jcodelength > 65535) {
1338 new_classformaterror(c,
1339 "Code of a method longer than 65535 bytes");
1344 if (!check_classbuffer_size(cb, m->jcodelength))
1347 m->jcode = MNEW(u1, m->jcodelength);
1348 suck_nbytes(m->jcode, cb, m->jcodelength);
1350 if (!check_classbuffer_size(cb, 2))
1353 m->exceptiontablelength = suck_u2(cb);
1355 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->exceptiontablelength))
1358 m->exceptiontable = MNEW(exceptiontable, m->exceptiontablelength);
1360 #if defined(STATISTICS)
1362 count_vmcode_len += m->jcodelength + 18;
1363 count_extable_len += 8 * m->exceptiontablelength;
1367 for (j = 0; j < m->exceptiontablelength; j++) {
1369 m->exceptiontable[j].startpc = suck_u2(cb);
1370 m->exceptiontable[j].endpc = suck_u2(cb);
1371 m->exceptiontable[j].handlerpc = suck_u2(cb);
1375 m->exceptiontable[j].catchtype = NULL;
1378 m->exceptiontable[j].catchtype =
1379 class_getconstant(c, idx, CONSTANT_Class);
1383 if (!check_classbuffer_size(cb, 2))
1386 codeattrnum = suck_u2(cb);
1388 for (; codeattrnum > 0; codeattrnum--) {
1391 if (!check_classbuffer_size(cb, 2))
1394 caname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1396 if (caname == utf_linenumbertable) {
1399 if (!check_classbuffer_size(cb, 4 + 2))
1403 m->linenumbercount = suck_u2(cb);
1405 if (!check_classbuffer_size(cb,
1406 (2 + 2) * m->linenumbercount))
1409 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1411 for (lncid = 0; lncid < m->linenumbercount; lncid++) {
1412 m->linenumbers[lncid].start_pc = suck_u2(cb);
1413 m->linenumbers[lncid].line_number = suck_u2(cb);
1417 if (!skipattributes(cb, codeattrnum))
1422 if (!skipattributebody(cb))
1429 if (!m->jcode && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1430 *exceptionptr = new_classformaterror(c, "Missing Code attribute");
1435 /* everything was ok */
1441 /********************* Function: method_free ***********************************
1443 frees all memory that was allocated for this method
1445 *******************************************************************************/
1447 static void method_free(methodinfo *m)
1450 MFREE(m->jcode, u1, m->jcodelength);
1452 if (m->exceptiontable)
1453 MFREE(m->exceptiontable, exceptiontable, m->exceptiontablelength);
1456 CFREE(m->mcode, m->mcodelength);
1458 if (m->stubroutine) {
1459 if (m->flags & ACC_NATIVE) {
1460 removenativestub(m->stubroutine);
1463 removecompilerstub(m->stubroutine);
1469 /************** Function: method_display (debugging only) **************/
1471 void method_display(methodinfo *m)
1474 printflags(m->flags);
1476 utf_display(m->name);
1478 utf_display(m->descriptor);
1482 /************** Function: method_display_flags_last (debugging only) **************/
1484 void method_display_flags_last(methodinfo *m)
1487 utf_display(m->name);
1489 utf_display(m->descriptor);
1491 printflags(m->flags);
1496 /******************** Function: method_canoverwrite ****************************
1498 Check if m and old are identical with respect to type and name. This means
1499 that old can be overwritten with m.
1501 *******************************************************************************/
1503 static bool method_canoverwrite(methodinfo *m, methodinfo *old)
1505 if (m->name != old->name) return false;
1506 if (m->descriptor != old->descriptor) return false;
1507 if (m->flags & ACC_STATIC) return false;
1512 /******************************************************************************/
1513 /************************ Functions for class *********************************/
1514 /******************************************************************************/
1517 /******************** function:: class_getconstant *****************************
1519 retrieves the value at position 'pos' of the constantpool of a class
1520 if the type of the value is other than 'ctype' the system is stopped
1522 *******************************************************************************/
1524 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
1526 /* invalid position in constantpool */
1527 /* (pos == 0 is caught by type comparison) */
1528 if (pos >= c->cpcount)
1529 panic("Attempt to access constant outside range");
1531 /* check type of constantpool entry */
1533 if (c->cptags[pos] != ctype) {
1534 class_showconstantpool(c);
1535 error("Type mismatch on constant: %d requested, %d here (class_getconstant)",
1536 (int) ctype, (int) c->cptags[pos]);
1539 return c->cpinfos[pos];
1543 /********************* Function: class_constanttype ****************************
1545 Determines the type of a class entry in the ConstantPool
1547 *******************************************************************************/
1549 u4 class_constanttype(classinfo *c, u4 pos)
1551 if (pos >= c->cpcount)
1552 panic("Attempt to access constant outside range");
1554 return c->cptags[pos];
1558 /******************** function: class_loadcpool ********************************
1560 loads the constantpool of a class,
1561 the entries are transformed into a simpler format
1562 by resolving references
1563 (a detailed overview of the compact structures can be found in global.h)
1565 *******************************************************************************/
1567 static bool class_loadcpool(classbuffer *cb, classinfo *c)
1570 /* The following structures are used to save information which cannot be
1571 processed during the first pass. After the complete constantpool has
1572 been traversed the references can be resolved.
1573 (only in specific order) */
1575 /* CONSTANT_Class_info entries */
1576 typedef struct forward_class {
1577 struct forward_class *next;
1582 /* CONSTANT_String */
1583 typedef struct forward_string {
1584 struct forward_string *next;
1589 /* CONSTANT_NameAndType */
1590 typedef struct forward_nameandtype {
1591 struct forward_nameandtype *next;
1595 } forward_nameandtype;
1597 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
1598 typedef struct forward_fieldmethint {
1599 struct forward_fieldmethint *next;
1603 u2 nameandtype_index;
1604 } forward_fieldmethint;
1608 long int dumpsize = dump_size ();
1610 forward_class *forward_classes = NULL;
1611 forward_string *forward_strings = NULL;
1612 forward_nameandtype *forward_nameandtypes = NULL;
1613 forward_fieldmethint *forward_fieldmethints = NULL;
1615 /* number of entries in the constant_pool table plus one */
1616 if (!check_classbuffer_size(cb, 2))
1619 u4 cpcount = c->cpcount = suck_u2(cb);
1621 /* allocate memory */
1622 u1 *cptags = c->cptags = MNEW(u1, cpcount);
1623 voidptr *cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
1626 panic("Invalid constant_pool_count (0)");
1628 #if defined(STATISTICS)
1630 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
1633 /* initialize constantpool */
1634 for (idx = 0; idx < cpcount; idx++) {
1635 cptags[idx] = CONSTANT_UNUSED;
1636 cpinfos[idx] = NULL;
1640 /******* first pass *******/
1641 /* entries which cannot be resolved now are written into
1642 temporary structures and traversed again later */
1645 while (idx < cpcount) {
1646 /* get constant type */
1647 if (!check_classbuffer_size(cb, 1))
1653 case CONSTANT_Class: {
1654 forward_class *nfc = DNEW(forward_class);
1656 nfc->next = forward_classes;
1657 forward_classes = nfc;
1659 nfc->thisindex = idx;
1660 /* reference to CONSTANT_NameAndType */
1661 if (!check_classbuffer_size(cb, 2))
1664 nfc->name_index = suck_u2(cb);
1670 case CONSTANT_Fieldref:
1671 case CONSTANT_Methodref:
1672 case CONSTANT_InterfaceMethodref: {
1673 forward_fieldmethint *nff = DNEW(forward_fieldmethint);
1675 nff->next = forward_fieldmethints;
1676 forward_fieldmethints = nff;
1678 nff->thisindex = idx;
1682 if (!check_classbuffer_size(cb, 2 + 2))
1685 /* class or interface type that contains the declaration of the
1687 nff->class_index = suck_u2(cb);
1689 /* name and descriptor of the field or method */
1690 nff->nameandtype_index = suck_u2(cb);
1696 case CONSTANT_String: {
1697 forward_string *nfs = DNEW(forward_string);
1699 nfs->next = forward_strings;
1700 forward_strings = nfs;
1702 nfs->thisindex = idx;
1704 /* reference to CONSTANT_Utf8_info with string characters */
1705 if (!check_classbuffer_size(cb, 2))
1708 nfs->string_index = suck_u2(cb);
1714 case CONSTANT_NameAndType: {
1715 forward_nameandtype *nfn = DNEW(forward_nameandtype);
1717 nfn->next = forward_nameandtypes;
1718 forward_nameandtypes = nfn;
1720 nfn->thisindex = idx;
1722 if (!check_classbuffer_size(cb, 2 + 2))
1725 /* reference to CONSTANT_Utf8_info containing simple name */
1726 nfn->name_index = suck_u2(cb);
1728 /* reference to CONSTANT_Utf8_info containing field or method
1730 nfn->sig_index = suck_u2(cb);
1736 case CONSTANT_Integer: {
1737 constant_integer *ci = NEW(constant_integer);
1739 #if defined(STATISTICS)
1741 count_const_pool_len += sizeof(constant_integer);
1744 if (!check_classbuffer_size(cb, 4))
1747 ci->value = suck_s4(cb);
1748 cptags[idx] = CONSTANT_Integer;
1755 case CONSTANT_Float: {
1756 constant_float *cf = NEW(constant_float);
1758 #if defined(STATISTICS)
1760 count_const_pool_len += sizeof(constant_float);
1763 if (!check_classbuffer_size(cb, 4))
1766 cf->value = suck_float(cb);
1767 cptags[idx] = CONSTANT_Float;
1774 case CONSTANT_Long: {
1775 constant_long *cl = NEW(constant_long);
1777 #if defined(STATISTICS)
1779 count_const_pool_len += sizeof(constant_long);
1782 if (!check_classbuffer_size(cb, 8))
1785 cl->value = suck_s8(cb);
1786 cptags[idx] = CONSTANT_Long;
1790 panic("Long constant exceeds constant pool");
1794 case CONSTANT_Double: {
1795 constant_double *cd = NEW(constant_double);
1797 #if defined(STATISTICS)
1799 count_const_pool_len += sizeof(constant_double);
1802 if (!check_classbuffer_size(cb, 8))
1805 cd->value = suck_double(cb);
1806 cptags[idx] = CONSTANT_Double;
1810 panic("Double constant exceeds constant pool");
1814 case CONSTANT_Utf8: {
1815 /* number of bytes in the bytes array (not string-length) */
1816 if (!check_classbuffer_size(cb, 2))
1819 u4 length = suck_u2(cb);
1820 cptags[idx] = CONSTANT_Utf8;
1822 /* validate the string */
1823 if (!check_classbuffer_size(cb, length))
1827 !is_valid_utf(cb->pos + 1, cb->pos + 1 + length)) {
1828 dolog("Invalid UTF-8 string (constant pool index %d)",idx);
1829 panic("Invalid UTF-8 string");
1831 /* insert utf-string into the utf-symboltable */
1832 cpinfos[idx] = utf_new_intern(cb->pos + 1, length);
1834 /* skip bytes of the string (buffer size check above) */
1835 skip_nbytes(cb, length);
1841 error("Unkown constant type: %d",(int) t);
1846 /* resolve entries in temporary structures */
1848 while (forward_classes) {
1850 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
1852 if (opt_verify && !is_valid_name_utf(name))
1853 panic("Class reference with invalid name");
1855 cptags[forward_classes->thisindex] = CONSTANT_Class;
1856 /* retrieve class from class-table */
1859 tc = class_new_intern(name);
1861 if (!class_load(tc))
1864 /* link the class later, so we cannot link the currently loaded
1866 list_addfirst(&unlinkedclasses, tc);
1868 cpinfos[forward_classes->thisindex] = tc;
1871 cpinfos[forward_classes->thisindex] = class_new(name);
1874 forward_classes = forward_classes->next;
1877 while (forward_strings) {
1879 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
1881 /* resolve utf-string */
1882 cptags[forward_strings->thisindex] = CONSTANT_String;
1883 cpinfos[forward_strings->thisindex] = text;
1885 forward_strings = forward_strings->next;
1888 while (forward_nameandtypes) {
1889 constant_nameandtype *cn = NEW(constant_nameandtype);
1891 #if defined(STATISTICS)
1893 count_const_pool_len += sizeof(constant_nameandtype);
1896 /* resolve simple name and descriptor */
1897 cn->name = class_getconstant(c,
1898 forward_nameandtypes->name_index,
1901 cn->descriptor = class_getconstant(c,
1902 forward_nameandtypes->sig_index,
1907 if (!is_valid_name_utf(cn->name))
1908 panic("NameAndType with invalid name");
1909 /* disallow referencing <clinit> among others */
1910 if (cn->name->text[0] == '<' && cn->name != utf_init)
1911 panic("NameAndType with invalid special name");
1914 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
1915 cpinfos[forward_nameandtypes->thisindex] = cn;
1917 forward_nameandtypes = forward_nameandtypes->next;
1920 while (forward_fieldmethints) {
1921 constant_nameandtype *nat;
1922 constant_FMIref *fmi = NEW(constant_FMIref);
1924 #if defined(STATISTICS)
1926 count_const_pool_len += sizeof(constant_FMIref);
1928 /* resolve simple name and descriptor */
1929 nat = class_getconstant(c,
1930 forward_fieldmethints->nameandtype_index,
1931 CONSTANT_NameAndType);
1933 fmi->class = class_getconstant(c,
1934 forward_fieldmethints->class_index,
1936 fmi->name = nat->name;
1937 fmi->descriptor = nat->descriptor;
1939 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
1940 cpinfos[forward_fieldmethints->thisindex] = fmi;
1942 switch (forward_fieldmethints->tag) {
1943 case CONSTANT_Fieldref: /* check validity of descriptor */
1944 checkfielddescriptor(fmi->descriptor->text,
1945 utf_end(fmi->descriptor));
1947 case CONSTANT_InterfaceMethodref:
1948 case CONSTANT_Methodref: /* check validity of descriptor */
1949 checkmethoddescriptor(c, fmi->descriptor);
1953 forward_fieldmethints = forward_fieldmethints->next;
1956 dump_release(dumpsize);
1958 /* everything was ok */
1964 /********************** Function: class_load ***********************************
1966 Loads everything interesting about a class from the class file. The
1967 'classinfo' structure must have been allocated previously.
1969 The super class and the interfaces implemented by this class need not be
1970 loaded. The link is set later by the function 'class_link'.
1972 The loaded class is removed from the list 'unloadedclasses' and added to
1973 the list 'unlinkedclasses'.
1975 *******************************************************************************/
1977 classinfo *class_load_intern(classbuffer *cb);
1979 classinfo *class_load(classinfo *c)
1986 #if defined(USE_THREADS)
1987 #if defined(NATIVE_THREADS)
1995 /* maybe the class is already loaded */
1997 #if defined(USE_THREADS)
1998 #if defined(NATIVE_THREADS)
2011 starttime = getcputime();
2013 /* load classdata, throw exception on error */
2015 if ((cb = suck_start(c)) == NULL) {
2016 /* this means, the classpath was not set properly */
2017 if (c->name == utf_java_lang_Object)
2018 throw_cacao_exception_exit(string_java_lang_NoClassDefFoundError,
2019 "java/lang/Object");
2022 new_exception_utfmessage(string_java_lang_NoClassDefFoundError,
2025 #if defined(USE_THREADS)
2026 #if defined(NATIVE_THREADS)
2037 /* call the internal function */
2038 r = class_load_intern(cb);
2040 /* if return value is NULL, we had a problem and the class is not loaded */
2044 /* now free the allocated memory, otherwise we could ran into a DOS */
2052 if (getloadingtime) {
2053 stoptime = getcputime();
2054 loadingtime += (stoptime - starttime);
2057 #if defined(USE_THREADS)
2058 #if defined(NATIVE_THREADS)
2070 classinfo *class_load_intern(classbuffer *cb)
2075 /* s4 classdata_left; */
2076 char msg[MAXLOGTEXT]; /* maybe we get an exception */
2078 /* get the classbuffer's class */
2081 /* maybe the class is already loaded */
2085 #if defined(STATISTICS)
2087 count_class_loads++;
2090 /* output for debugging purposes */
2092 log_message_class("Loading class: ", c);
2094 /* class is somewhat loaded */
2097 if (!check_classbuffer_size(cb, 4 + 2 + 2))
2100 /* check signature */
2101 if (suck_u4(cb) != MAGIC) {
2102 *exceptionptr = new_classformaterror(c, "Bad magic number");
2111 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
2113 new_classformaterror(c,
2114 "Unsupported major.minor version %d.%d",
2120 if (!class_loadcpool(cb, c))
2124 c->erroneous_state = 0;
2125 c->initializing_thread = 0;
2127 c->classUsed = NOTUSED; /* not used initially CO-RT */
2131 if (!check_classbuffer_size(cb, 2))
2134 c->flags = suck_u2(cb);
2135 /*if (!(c->flags & ACC_PUBLIC)) { log_text("CLASS NOT PUBLIC"); } JOWENN*/
2137 /* check ACC flags consistency */
2138 if (c->flags & ACC_INTERFACE) {
2139 if (!(c->flags & ACC_ABSTRACT)) {
2140 /* We work around this because interfaces in JDK 1.1 are
2141 * not declared abstract. */
2143 c->flags |= ACC_ABSTRACT;
2144 /* panic("Interface class not declared abstract"); */
2147 if (c->flags & ACC_FINAL) {
2149 new_classformaterror(c,
2150 "Illegal class modifiers: 0x%x", c->flags);
2155 if (c->flags & ACC_SUPER) {
2156 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
2160 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
2162 new_classformaterror(c, "Illegal class modifiers: 0x%x", c->flags);
2167 if (!check_classbuffer_size(cb, 2 + 2))
2172 if (class_getconstant(c, i, CONSTANT_Class) != c) {
2173 utf_sprint(msg, c->name);
2174 sprintf(msg + strlen(msg), " (wrong name: ");
2175 utf_sprint(msg + strlen(msg),
2176 ((classinfo *) class_getconstant(c, i, CONSTANT_Class))->name);
2177 sprintf(msg + strlen(msg), ")");
2180 new_exception_message(string_java_lang_NoClassDefFoundError, msg);
2185 /* retrieve superclass */
2186 if ((i = suck_u2(cb))) {
2187 c->super = class_getconstant(c, i, CONSTANT_Class);
2189 /* java.lang.Object may not have a super class. */
2190 if (c->name == utf_java_lang_Object) {
2192 new_exception_message(string_java_lang_ClassFormatError,
2193 "java.lang.Object with superclass");
2198 /* Interfaces must have java.lang.Object as super class. */
2199 if ((c->flags & ACC_INTERFACE) &&
2200 c->super->name != utf_java_lang_Object) {
2202 new_exception_message(string_java_lang_ClassFormatError,
2203 "Interfaces must have java.lang.Object as superclass");
2211 /* This is only allowed for java.lang.Object. */
2212 if (c->name != utf_java_lang_Object) {
2213 *exceptionptr = new_classformaterror(c, "Bad superclass index");
2220 /* retrieve interfaces */
2221 if (!check_classbuffer_size(cb, 2))
2224 c->interfacescount = suck_u2(cb);
2226 if (!check_classbuffer_size(cb, 2 * c->interfacescount))
2229 c->interfaces = MNEW(classinfo*, c->interfacescount);
2230 for (i = 0; i < c->interfacescount; i++) {
2231 c->interfaces[i] = class_getconstant(c, suck_u2(cb), CONSTANT_Class);
2235 if (!check_classbuffer_size(cb, 2))
2238 c->fieldscount = suck_u2(cb);
2239 c->fields = GCNEW(fieldinfo, c->fieldscount);
2240 /* c->fields = MNEW(fieldinfo, c->fieldscount); */
2241 for (i = 0; i < c->fieldscount; i++) {
2242 if (!field_load(cb, c, &(c->fields[i])))
2247 if (!check_classbuffer_size(cb, 2))
2250 c->methodscount = suck_u2(cb);
2251 c->methods = GCNEW(methodinfo, c->methodscount);
2252 /* c->methods = MNEW(methodinfo, c->methodscount); */
2253 for (i = 0; i < c->methodscount; i++) {
2254 if (!method_load(cb, c, &(c->methods[i])))
2258 /* Check if all fields and methods can be uniquely
2259 * identified by (name,descriptor). */
2261 /* We use a hash table here to avoid making the
2262 * average case quadratic in # of methods, fields.
2264 static int shift = 0;
2266 u2 *next; /* for chaining colliding hash entries */
2272 /* Allocate hashtable */
2273 len = c->methodscount;
2274 if (len < c->fieldscount) len = c->fieldscount;
2276 hashtab = MNEW(u2,(hashlen + len));
2277 next = hashtab + hashlen;
2279 /* Determine bitshift (to get good hash values) */
2289 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2291 for (i = 0; i < c->fieldscount; ++i) {
2292 fieldinfo *fi = c->fields + i;
2294 /* It's ok if we lose bits here */
2295 index = ((((size_t) fi->name) +
2296 ((size_t) fi->descriptor)) >> shift) % hashlen;
2298 if ((old = hashtab[index])) {
2302 if (c->fields[old].name == fi->name &&
2303 c->fields[old].descriptor == fi->descriptor) {
2305 new_classformaterror(c,
2306 "Repetitive field name/signature");
2310 } while ((old = next[old]));
2312 hashtab[index] = i + 1;
2316 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2318 for (i = 0; i < c->methodscount; ++i) {
2319 methodinfo *mi = c->methods + i;
2321 /* It's ok if we lose bits here */
2322 index = ((((size_t) mi->name) +
2323 ((size_t) mi->descriptor)) >> shift) % hashlen;
2325 if ((old = hashtab[index])) {
2329 if (c->methods[old].name == mi->name &&
2330 c->methods[old].descriptor == mi->descriptor) {
2332 new_classformaterror(c,
2333 "Repetitive method name/signature");
2337 } while ((old = next[old]));
2339 hashtab[index] = i + 1;
2342 MFREE(hashtab, u2, (hashlen + len));
2345 #if defined(STATISTICS)
2347 count_class_infos += sizeof(classinfo*) * c->interfacescount;
2348 count_class_infos += sizeof(fieldinfo) * c->fieldscount;
2349 count_class_infos += sizeof(methodinfo) * c->methodscount;
2353 /* load variable-length attribute structures */
2354 if (!check_classbuffer_size(cb, 2))
2357 if (!attribute_load(cb, c, suck_u2(cb)))
2361 /* XXX TWISTI is this still in the JVM spec? SUN and IBM don't complain about it */
2363 /* check if all data has been read */
2364 classdata_left = ((cb->data + cb->size) - cb->pos - 1);
2366 if (classdata_left > 0) {
2368 dolog("There are %d extra bytes at end of classfile", classdata_left);
2369 /* The JVM spec disallows extra bytes. */
2370 panic("Extra bytes at end of classfile");
2375 log_message_class("Loading done class: ", c);
2382 /************** internal Function: class_highestinterface **********************
2384 Used by the function class_link to determine the amount of memory needed
2385 for the interface table.
2387 *******************************************************************************/
2389 static s4 class_highestinterface(classinfo *c)
2394 if (!(c->flags & ACC_INTERFACE)) {
2395 char logtext[MAXLOGTEXT];
2396 sprintf(logtext, "Interface-methods count requested for non-interface: ");
2397 utf_sprint(logtext + strlen(logtext), c->name);
2398 error("%s",logtext);
2402 for (i = 0; i < c->interfacescount; i++) {
2403 s4 h2 = class_highestinterface(c->interfaces[i]);
2411 /* class_addinterface **********************************************************
2413 Is needed by class_link for adding a VTBL to a class. All interfaces
2414 implemented by ic are added as well.
2416 *******************************************************************************/
2418 static void class_addinterface(classinfo *c, classinfo *ic)
2422 vftbl *vftbl = c->vftbl;
2424 if (i >= vftbl->interfacetablelength)
2425 panic ("Inernal error: interfacetable overflow");
2427 if (vftbl->interfacetable[-i])
2430 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
2431 vftbl->interfacevftbllength[i] = 1;
2432 vftbl->interfacetable[-i] = MNEW(methodptr, 1);
2433 vftbl->interfacetable[-i][0] = NULL;
2436 vftbl->interfacevftbllength[i] = ic->methodscount;
2437 vftbl->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
2441 count_vftbl_len += sizeof(methodptr) *
2442 (ic->methodscount + (ic->methodscount == 0));
2445 for (j = 0; j < ic->methodscount; j++) {
2448 for (m = 0; m < sc->methodscount; m++) {
2449 methodinfo *mi = &(sc->methods[m]);
2450 if (method_canoverwrite(mi, &(ic->methods[j]))) {
2451 vftbl->interfacetable[-i][j] =
2452 vftbl->table[mi->vftblindex];
2463 for (j = 0; j < ic->interfacescount; j++)
2464 class_addinterface(c, ic->interfaces[j]);
2468 /******************* Function: class_new_array *********************************
2470 This function is called by class_new to setup an array class.
2472 *******************************************************************************/
2474 void class_new_array(classinfo *c)
2476 classinfo *comp = NULL;
2480 /* Check array class name */
2481 namelen = c->name->blength;
2482 if (namelen < 2 || c->name->text[0] != '[')
2483 panic("Invalid array class name");
2485 /* Check the component type */
2486 switch (c->name->text[1]) {
2488 /* c is an array of arrays. We have to create the component class. */
2490 comp = class_new_intern(utf_new_intern(c->name->text + 1,
2493 list_addfirst(&unlinkedclasses, comp);
2496 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2501 /* c is an array of objects. */
2502 if (namelen < 4 || c->name->text[namelen - 1] != ';')
2503 panic("Invalid array class name");
2506 comp = class_new_intern(utf_new_intern(c->name->text + 2,
2509 list_addfirst(&unlinkedclasses, comp);
2512 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2517 /* Setup the array class */
2518 c->super = class_java_lang_Object;
2519 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2521 c->interfacescount = 2;
2522 c->interfaces = MNEW(classinfo*, 2);
2527 tc = class_new_intern(utf_new_char("java/lang/Cloneable"));
2529 list_addfirst(&unlinkedclasses, tc);
2530 c->interfaces[0] = tc;
2532 tc = class_new_intern(utf_new_char("java/io/Serializable"));
2534 list_addfirst(&unlinkedclasses, tc);
2535 c->interfaces[1] = tc;
2538 c->interfaces[0] = class_new(utf_new_char("java/lang/Cloneable"));
2539 c->interfaces[1] = class_new(utf_new_char("java/io/Serializable"));
2542 c->methodscount = 1;
2543 c->methods = MNEW(methodinfo, c->methodscount);
2546 memset(clone, 0, sizeof(methodinfo));
2547 clone->flags = ACC_PUBLIC;
2548 clone->name = utf_new_char("clone");
2549 clone->descriptor = utf_new_char("()Ljava/lang/Object;");
2551 clone->stubroutine = createnativestub((functionptr) &builtin_clone_array, clone);
2552 clone->monoPoly = MONO;
2554 /* XXX: field: length? */
2556 /* array classes are not loaded from class files */
2561 /****************** Function: class_link_array *********************************
2563 This function is called by class_link to create the
2564 arraydescriptor for an array class.
2566 This function returns NULL if the array cannot be linked because
2567 the component type has not been linked yet.
2569 *******************************************************************************/
2571 static arraydescriptor *class_link_array(classinfo *c)
2573 classinfo *comp = NULL;
2574 s4 namelen = c->name->blength;
2575 arraydescriptor *desc;
2578 /* Check the component type */
2579 switch (c->name->text[1]) {
2581 /* c is an array of arrays. */
2582 /* comp = class_get(utf_new_intern(c->name->text + 1, namelen - 1)); */
2583 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2585 panic("Could not find component array class.");
2589 /* c is an array of objects. */
2590 /* comp = class_get(utf_new_intern(c->name->text + 2, namelen - 3)); */
2591 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2593 panic("Could not find component class.");
2597 /* If the component type has not been linked, link it now */
2598 if (comp && !comp->linked) {
2604 /* Allocate the arraydescriptor */
2605 desc = NEW(arraydescriptor);
2608 /* c is an array of references */
2609 desc->arraytype = ARRAYTYPE_OBJECT;
2610 desc->componentsize = sizeof(void*);
2611 desc->dataoffset = OFFSET(java_objectarray, data);
2613 compvftbl = comp->vftbl;
2615 panic("Component class has no vftbl");
2616 desc->componentvftbl = compvftbl;
2618 if (compvftbl->arraydesc) {
2619 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
2620 if (compvftbl->arraydesc->dimension >= 255)
2621 panic("Creating array of dimension >255");
2622 desc->dimension = compvftbl->arraydesc->dimension + 1;
2623 desc->elementtype = compvftbl->arraydesc->elementtype;
2626 desc->elementvftbl = compvftbl;
2627 desc->dimension = 1;
2628 desc->elementtype = ARRAYTYPE_OBJECT;
2632 /* c is an array of a primitive type */
2633 switch (c->name->text[1]) {
2635 desc->arraytype = ARRAYTYPE_BOOLEAN;
2636 desc->dataoffset = OFFSET(java_booleanarray,data);
2637 desc->componentsize = sizeof(u1);
2641 desc->arraytype = ARRAYTYPE_BYTE;
2642 desc->dataoffset = OFFSET(java_bytearray,data);
2643 desc->componentsize = sizeof(u1);
2647 desc->arraytype = ARRAYTYPE_CHAR;
2648 desc->dataoffset = OFFSET(java_chararray,data);
2649 desc->componentsize = sizeof(u2);
2653 desc->arraytype = ARRAYTYPE_DOUBLE;
2654 desc->dataoffset = OFFSET(java_doublearray,data);
2655 desc->componentsize = sizeof(double);
2659 desc->arraytype = ARRAYTYPE_FLOAT;
2660 desc->dataoffset = OFFSET(java_floatarray,data);
2661 desc->componentsize = sizeof(float);
2665 desc->arraytype = ARRAYTYPE_INT;
2666 desc->dataoffset = OFFSET(java_intarray,data);
2667 desc->componentsize = sizeof(s4);
2671 desc->arraytype = ARRAYTYPE_LONG;
2672 desc->dataoffset = OFFSET(java_longarray,data);
2673 desc->componentsize = sizeof(s8);
2677 desc->arraytype = ARRAYTYPE_SHORT;
2678 desc->dataoffset = OFFSET(java_shortarray,data);
2679 desc->componentsize = sizeof(s2);
2683 panic("Invalid array class name");
2686 desc->componentvftbl = NULL;
2687 desc->elementvftbl = NULL;
2688 desc->dimension = 1;
2689 desc->elementtype = desc->arraytype;
2696 /********************** Function: class_link ***********************************
2698 Tries to link a class. The function calculates the length in bytes that
2699 an instance of this class requires as well as the VTBL for methods and
2702 *******************************************************************************/
2704 static classinfo *class_link_intern(classinfo *c);
2706 classinfo *class_link(classinfo *c)
2712 #if defined(USE_THREADS)
2713 #if defined(NATIVE_THREADS)
2721 /* maybe the class is already linked */
2723 #if defined(USE_THREADS)
2724 #if defined(NATIVE_THREADS)
2737 starttime = getcputime();
2739 /* call the internal function */
2740 r = class_link_intern(c);
2742 /* if return value is NULL, we had a problem and the class is not linked */
2747 if (getloadingtime) {
2748 stoptime = getcputime();
2749 loadingtime += (stoptime - starttime);
2752 #if defined(USE_THREADS)
2753 #if defined(NATIVE_THREADS)
2765 static classinfo *class_link_intern(classinfo *c)
2767 s4 supervftbllength; /* vftbllegnth of super class */
2768 s4 vftbllength; /* vftbllength of current class */
2769 s4 interfacetablelength; /* interface table length */
2770 classinfo *super = c->super; /* super class */
2771 classinfo *ic, *c2; /* intermediate class variables */
2772 vftbl *v; /* vftbl of current class */
2773 s4 i; /* interface/method/field counter */
2774 arraydescriptor *arraydesc = NULL; /* descriptor for array classes */
2776 /* maybe the class is already linked */
2781 log_message_class("Linking class: ", c);
2783 /* ok, this class is somewhat linked */
2786 /* check interfaces */
2788 for (i = 0; i < c->interfacescount; i++) {
2789 ic = c->interfaces[i];
2791 /* detect circularity */
2794 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2801 if (!class_load(ic))
2805 if (!class_link(ic))
2808 if (!(ic->flags & ACC_INTERFACE)) {
2809 dolog("Specified interface is not declared as interface:");
2813 panic("Specified interface is not declared as interface");
2817 /* check super class */
2819 if (super == NULL) { /* class java.lang.Object */
2821 c->classUsed = USED; /* Object class is always used CO-RT*/
2823 c->instancesize = sizeof(java_objectheader);
2825 vftbllength = supervftbllength = 0;
2827 c->finalizer = NULL;
2830 /* detect circularity */
2833 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2840 if (!class_load(super))
2844 if (!class_link(super))
2847 if (super->flags & ACC_INTERFACE)
2848 panic("Interface specified as super class");
2850 /* handle array classes */
2851 /* The component class must have been linked already. */
2852 if (c->name->text[0] == '[') {
2853 if ((arraydesc = class_link_array(c)) == NULL) {
2854 panic("class_link: class_link_array");
2858 /* Don't allow extending final classes */
2859 if (super->flags & ACC_FINAL)
2860 panic("Trying to extend final class");
2862 if (c->flags & ACC_INTERFACE)
2863 c->index = interfaceindex++;
2865 c->index = super->index + 1;
2867 c->instancesize = super->instancesize;
2869 vftbllength = supervftbllength = super->vftbl->vftbllength;
2871 c->finalizer = super->finalizer;
2874 /* compute vftbl length */
2876 for (i = 0; i < c->methodscount; i++) {
2877 methodinfo *m = &(c->methods[i]);
2879 if (!(m->flags & ACC_STATIC)) { /* is instance method */
2880 classinfo *sc = super;
2883 for (j = 0; j < sc->methodscount; j++) {
2884 if (method_canoverwrite(m, &(sc->methods[j]))) {
2885 if ((sc->methods[j].flags & ACC_PRIVATE) != 0)
2886 goto notfoundvftblindex;
2888 if ((sc->methods[j].flags & ACC_FINAL) != 0) {
2891 log_utf(sc->methods[j].name);
2892 log_utf(sc->methods[j].descriptor);
2893 panic("Trying to overwrite final method");
2895 m->vftblindex = sc->methods[j].vftblindex;
2896 goto foundvftblindex;
2902 m->vftblindex = (vftbllength++);
2911 sizeof(vftbl) + (sizeof(methodptr) * (vftbllength - 1));
2914 /* compute interfacetable length */
2916 interfacetablelength = 0;
2919 for (i = 0; i < c2->interfacescount; i++) {
2920 s4 h = class_highestinterface(c2->interfaces[i]) + 1;
2921 if (h > interfacetablelength)
2922 interfacetablelength = h;
2927 /* allocate virtual function table */
2929 v = (vftbl*) mem_alloc(sizeof(vftbl) + sizeof(methodptr) *
2930 (vftbllength - 1) + sizeof(methodptr*) *
2931 (interfacetablelength - (interfacetablelength > 0)));
2932 v = (vftbl*) (((methodptr*) v) + (interfacetablelength - 1) *
2933 (interfacetablelength > 1));
2934 c->header.vftbl = c->vftbl = v;
2935 /* utf_display_classname(c->name);printf(", c->header.vftbl=%p\n", c->header.vftbl); */
2937 v->vftbllength = vftbllength;
2938 v->interfacetablelength = interfacetablelength;
2939 v->arraydesc = arraydesc;
2941 /* store interface index in vftbl */
2942 if (c->flags & ACC_INTERFACE)
2943 v->baseval = -(c->index);
2945 /* copy virtual function table of super class */
2947 for (i = 0; i < supervftbllength; i++)
2948 v->table[i] = super->vftbl->table[i];
2950 /* add method stubs into virtual function table */
2952 for (i = 0; i < c->methodscount; i++) {
2953 methodinfo *m = &(c->methods[i]);
2954 if (!(m->flags & ACC_STATIC)) {
2955 v->table[m->vftblindex] = m->stubroutine;
2959 /* compute instance size and offset of each field */
2961 for (i = 0; i < c->fieldscount; i++) {
2963 fieldinfo *f = &(c->fields[i]);
2965 if (!(f->flags & ACC_STATIC)) {
2966 dsize = desc_typesize(f->descriptor);
2967 c->instancesize = ALIGN(c->instancesize, dsize);
2968 f->offset = c->instancesize;
2969 c->instancesize += dsize;
2973 /* initialize interfacetable and interfacevftbllength */
2975 v->interfacevftbllength = MNEW(s4, interfacetablelength);
2979 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
2982 for (i = 0; i < interfacetablelength; i++) {
2983 v->interfacevftbllength[i] = 0;
2984 v->interfacetable[-i] = NULL;
2987 /* add interfaces */
2989 for (c2 = c; c2 != NULL; c2 = c2->super)
2990 for (i = 0; i < c2->interfacescount; i++) {
2991 class_addinterface(c, c2->interfaces[i]);
2994 /* add finalizer method (not for java.lang.Object) */
2996 if (super != NULL) {
2998 static utf *finame = NULL;
2999 static utf *fidesc = NULL;
3002 finame = utf_finalize;
3004 fidesc = utf_fidesc;
3006 fi = class_findmethod(c, finame, fidesc);
3008 if (!(fi->flags & ACC_STATIC)) {
3016 loader_compute_subclasses(c);
3019 log_message_class("Linking done class: ", c);
3021 /* just return c to show that we didn't had a problem */
3027 /******************* Function: class_freepool **********************************
3029 Frees all resources used by this classes Constant Pool.
3031 *******************************************************************************/
3033 static void class_freecpool(classinfo *c)
3039 if (c->cptags && c->cpinfos) {
3040 for (idx = 0; idx < c->cpcount; idx++) {
3041 tag = c->cptags[idx];
3042 info = c->cpinfos[idx];
3046 case CONSTANT_Fieldref:
3047 case CONSTANT_Methodref:
3048 case CONSTANT_InterfaceMethodref:
3049 FREE(info, constant_FMIref);
3051 case CONSTANT_Integer:
3052 FREE(info, constant_integer);
3054 case CONSTANT_Float:
3055 FREE(info, constant_float);
3058 FREE(info, constant_long);
3060 case CONSTANT_Double:
3061 FREE(info, constant_double);
3063 case CONSTANT_NameAndType:
3064 FREE(info, constant_nameandtype);
3072 MFREE(c->cptags, u1, c->cpcount);
3075 MFREE(c->cpinfos, voidptr, c->cpcount);
3079 /*********************** Function: class_free **********************************
3081 Frees all resources used by the class.
3083 *******************************************************************************/
3085 void class_free(classinfo *c)
3093 MFREE(c->interfaces, classinfo*, c->interfacescount);
3096 for (i = 0; i < c->fieldscount; i++)
3097 field_free(&(c->fields[i]));
3098 /* MFREE(c->fields, fieldinfo, c->fieldscount); */
3102 for (i = 0; i < c->methodscount; i++)
3103 method_free(&(c->methods[i]));
3104 /* MFREE(c->methods, methodinfo, c->methodscount); */
3107 if ((v = c->vftbl) != NULL) {
3109 mem_free(v->arraydesc,sizeof(arraydescriptor));
3111 for (i = 0; i < v->interfacetablelength; i++) {
3112 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
3114 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
3116 i = sizeof(vftbl) + sizeof(methodptr) * (v->vftbllength - 1) +
3117 sizeof(methodptr*) * (v->interfacetablelength -
3118 (v->interfacetablelength > 0));
3119 v = (vftbl*) (((methodptr*) v) - (v->interfacetablelength - 1) *
3120 (v->interfacetablelength > 1));
3125 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
3127 /* if (c->classvftbl)
3128 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
3134 /************************* Function: class_findfield ***************************
3136 Searches a 'classinfo' structure for a field having the given name and
3139 *******************************************************************************/
3141 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
3145 for (i = 0; i < c->fieldscount; i++) {
3146 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
3147 return &(c->fields[i]);
3150 panic("Can not find field given in CONSTANT_Fieldref");
3152 /* keep compiler happy */
3157 /****************** Function: class_resolvefield_int ***************************
3159 This is an internally used helper function. Do not use this directly.
3161 Tries to resolve a field having the given name and type.
3162 If the field cannot be resolved, NULL is returned.
3164 *******************************************************************************/
3166 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
3171 /* search for field in class c */
3172 for (i = 0; i < c->fieldscount; i++) {
3173 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
3174 return &(c->fields[i]);
3178 /* try superinterfaces recursively */
3179 for (i = 0; i < c->interfacescount; ++i) {
3180 fi = class_resolvefield_int(c->interfaces[i], name, desc);
3185 /* try superclass */
3187 return class_resolvefield_int(c->super, name, desc);
3194 /********************* Function: class_resolvefield ***************************
3196 Resolves a reference from REFERER to a field with NAME and DESC in class C.
3198 If the field cannot be resolved the return value is NULL. If EXCEPT is
3199 true *exceptionptr is set, too.
3201 *******************************************************************************/
3203 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
3204 classinfo *referer, bool except)
3208 /* XXX resolve class c */
3209 /* XXX check access from REFERER to C */
3211 fi = class_resolvefield_int(c, name, desc);
3216 new_exception_utfmessage(string_java_lang_NoSuchFieldError,
3222 /* XXX check access rights */
3228 /************************* Function: class_findmethod **************************
3230 Searches a 'classinfo' structure for a method having the given name and
3231 type and returns the index in the class info structure.
3232 If type is NULL, it is ignored.
3234 *******************************************************************************/
3236 s4 class_findmethodIndex(classinfo *c, utf *name, utf *desc)
3240 for (i = 0; i < c->methodscount; i++) {
3242 /* utf_display_classname(c->name);printf("."); */
3243 /* utf_display(c->methods[i].name);printf("."); */
3244 /* utf_display(c->methods[i].descriptor); */
3247 if ((c->methods[i].name == name) && ((desc == NULL) ||
3248 (c->methods[i].descriptor == desc))) {
3257 /************************* Function: class_findmethod **************************
3259 Searches a 'classinfo' structure for a method having the given name and
3261 If type is NULL, it is ignored.
3263 *******************************************************************************/
3265 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
3267 s4 idx = class_findmethodIndex(c, name, desc);
3272 return &(c->methods[idx]);
3276 /*********************** Function: class_fetchmethod **************************
3278 like class_findmethod, but aborts with an error if the method is not found
3280 *******************************************************************************/
3282 methodinfo *class_fetchmethod(classinfo *c, utf *name, utf *desc)
3286 mi = class_findmethod(c, name, desc);
3289 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3290 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3291 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3292 panic("Method not found");
3299 /*********************** Function: class_findmethod_w**************************
3301 like class_findmethod, but logs a warning if the method is not found
3303 *******************************************************************************/
3305 methodinfo *class_findmethod_w(classinfo *c, utf *name, utf *desc, char *from)
3308 mi = class_findmethod(c, name, desc);
3311 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3312 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3313 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3315 if ( c->flags & ACC_PUBLIC ) log_plain(" PUBLIC ");
3316 if ( c->flags & ACC_PRIVATE ) log_plain(" PRIVATE ");
3317 if ( c->flags & ACC_PROTECTED ) log_plain(" PROTECTED ");
3318 if ( c->flags & ACC_STATIC ) log_plain(" STATIC ");
3319 if ( c->flags & ACC_FINAL ) log_plain(" FINAL ");
3320 if ( c->flags & ACC_SYNCHRONIZED ) log_plain(" SYNCHRONIZED ");
3321 if ( c->flags & ACC_VOLATILE ) log_plain(" VOLATILE ");
3322 if ( c->flags & ACC_TRANSIENT ) log_plain(" TRANSIENT ");
3323 if ( c->flags & ACC_NATIVE ) log_plain(" NATIVE ");
3324 if ( c->flags & ACC_INTERFACE ) log_plain(" INTERFACE ");
3325 if ( c->flags & ACC_ABSTRACT ) log_plain(" ABSTRACT ");
3328 log_plain(" : WARNING: Method not found");log_nl( );
3335 /************************* Function: class_findmethod_approx ******************
3337 like class_findmethod but ignores the return value when comparing the
3340 *******************************************************************************/
3342 methodinfo *class_findmethod_approx(classinfo *c, utf *name, utf *desc)
3346 for (i = 0; i < c->methodscount; i++) {
3347 if (c->methods[i].name == name) {
3348 utf *meth_descr = c->methods[i].descriptor;
3352 return &(c->methods[i]);
3354 if (desc->blength <= meth_descr->blength) {
3355 /* current position in utf text */
3356 char *desc_utf_ptr = desc->text;
3357 char *meth_utf_ptr = meth_descr->text;
3358 /* points behind utf strings */
3359 char *desc_end = utf_end(desc);
3360 char *meth_end = utf_end(meth_descr);
3363 /* compare argument types */
3364 while (desc_utf_ptr < desc_end && meth_utf_ptr < meth_end) {
3366 if ((ch = *desc_utf_ptr++) != (*meth_utf_ptr++))
3367 break; /* no match */
3370 return &(c->methods[i]); /* all parameter types equal */
3380 /***************** Function: class_resolvemethod_approx ***********************
3382 Searches a class and every super class for a method (without paying
3383 attention to the return value)
3385 *******************************************************************************/
3387 methodinfo *class_resolvemethod_approx(classinfo *c, utf *name, utf *desc)
3390 /* search for method (ignore returntype) */
3391 methodinfo *m = class_findmethod_approx(c, name, desc);
3394 /* search superclass */
3402 /************************* Function: class_resolvemethod ***********************
3404 Searches a class and every super class for a method.
3406 *******************************************************************************/
3408 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
3410 /*log_text("Trying to resolve a method");
3411 utf_display(c->name);
3413 utf_display(desc);*/
3416 /*log_text("Looking in:");
3417 utf_display(c->name);*/
3418 methodinfo *m = class_findmethod(c, name, desc);
3420 /* search superclass */
3423 /*log_text("method not found:");*/
3429 /****************** Function: class_resolveinterfacemethod_int ****************
3431 Internally used helper function. Do not use this directly.
3433 *******************************************************************************/
3436 methodinfo *class_resolveinterfacemethod_int(classinfo *c, utf *name, utf *desc)
3441 mi = class_findmethod(c,name,desc);
3445 /* try the superinterfaces */
3446 for (i=0; i<c->interfacescount; ++i) {
3447 mi = class_resolveinterfacemethod_int(c->interfaces[i],name,desc);
3455 /******************** Function: class_resolveinterfacemethod ******************
3457 Resolves a reference from REFERER to a method with NAME and DESC in
3460 If the method cannot be resolved the return value is NULL. If EXCEPT is
3461 true *exceptionptr is set, too.
3463 *******************************************************************************/
3465 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
3466 classinfo *referer, bool except)
3470 /* XXX resolve class c */
3471 /* XXX check access from REFERER to C */
3473 if (!(c->flags & ACC_INTERFACE)) {
3476 new_exception(string_java_lang_IncompatibleClassChangeError);
3481 mi = class_resolveinterfacemethod_int(c, name, desc);
3486 /* try class java.lang.Object */
3487 mi = class_findmethod(class_java_lang_Object, name, desc);
3494 new_exception_utfmessage(string_java_lang_NoSuchMethodError, name);
3500 /********************* Function: class_resolveclassmethod *********************
3502 Resolves a reference from REFERER to a method with NAME and DESC in
3505 If the method cannot be resolved the return value is NULL. If EXCEPT is
3506 true *exceptionptr is set, too.
3508 *******************************************************************************/
3510 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
3511 classinfo *referer, bool except)
3516 char msg[MAXLOGTEXT];
3518 /* XXX resolve class c */
3519 /* XXX check access from REFERER to C */
3521 /* if (c->flags & ACC_INTERFACE) { */
3523 /* *exceptionptr = */
3524 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
3528 /* try class c and its superclasses */
3531 mi = class_findmethod(cls, name, desc);
3534 } while ((cls = cls->super) != NULL); /* try the superclass */
3536 /* try the superinterfaces */
3537 for (i = 0; i < c->interfacescount; ++i) {
3538 mi = class_resolveinterfacemethod_int(c->interfaces[i], name, desc);
3544 utf_sprint(msg, c->name);
3545 sprintf(msg + strlen(msg), ".");
3546 utf_sprint(msg + strlen(msg), name);
3547 utf_sprint(msg + strlen(msg), desc);
3550 new_exception_message(string_java_lang_NoSuchMethodError, msg);
3556 if ((mi->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
3558 *exceptionptr = new_exception(string_java_lang_AbstractMethodError);
3563 /* XXX check access rights */
3569 /************************* Function: class_issubclass **************************
3571 Checks if sub is a descendant of super.
3573 *******************************************************************************/
3575 bool class_issubclass(classinfo *sub, classinfo *super)
3578 if (!sub) return false;
3579 if (sub == super) return true;
3585 /****************** Initialization function for classes ******************
3587 In Java, every class can have a static initialization function. This
3588 function has to be called BEFORE calling other methods or accessing static
3591 *******************************************************************************/
3593 static classinfo *class_init_intern(classinfo *c);
3595 classinfo *class_init(classinfo *c)
3599 if (!makeinitializations)
3602 /* enter a monitor on the class */
3604 builtin_monitorenter((java_objectheader *) c);
3606 /* maybe the class is already initalized or the current thread, which can
3607 pass the monitor, is currently initalizing this class */
3609 if (c->initialized || c->initializing) {
3610 builtin_monitorexit((java_objectheader *) c);
3615 /* this initalizing run begins NOW */
3616 c->initializing = true;
3618 /* call the internal function */
3619 r = class_init_intern(c);
3621 /* if return value is not NULL everything was ok and the class is
3624 c->initialized = true;
3626 /* this initalizing run is done */
3627 c->initializing = false;
3629 /* leave the monitor */
3631 builtin_monitorexit((java_objectheader *) c);
3637 /* this function MUST NOT be called directly, because of thread <clinit>
3640 static classinfo *class_init_intern(classinfo *c)
3644 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3656 #if defined(STATISTICS)
3658 count_class_inits++;
3661 /* initialize super class */
3663 if (!c->super->loaded)
3664 if (!class_load(c->super))
3667 if (!c->super->linked)
3668 if (!class_link(c->super))
3671 if (!c->super->initialized) {
3673 char logtext[MAXLOGTEXT];
3674 sprintf(logtext, "Initialize super class ");
3675 utf_sprint_classname(logtext + strlen(logtext), c->super->name);
3676 sprintf(logtext + strlen(logtext), " from ");
3677 utf_sprint_classname(logtext + strlen(logtext), c->name);
3681 if (!class_init(c->super))
3686 /* initialize interface classes */
3687 for (i = 0; i < c->interfacescount; i++) {
3688 if (!c->interfaces[i]->loaded)
3689 if (!class_load(c->interfaces[i]))
3692 if (!c->interfaces[i]->linked)
3693 if (!class_link(c->interfaces[i]))
3696 if (!c->interfaces[i]->initialized) {
3698 char logtext[MAXLOGTEXT];
3699 sprintf(logtext, "Initialize interface class ");
3700 utf_sprint_classname(logtext + strlen(logtext), c->interfaces[i]->name);
3701 sprintf(logtext + strlen(logtext), " from ");
3702 utf_sprint_classname(logtext + strlen(logtext), c->name);
3706 if (!class_init(c->interfaces[i]))
3711 m = class_findmethod(c, utf_clinit, utf_fidesc);
3715 char logtext[MAXLOGTEXT];
3716 sprintf(logtext, "Class ");
3717 utf_sprint_classname(logtext + strlen(logtext), c->name);
3718 sprintf(logtext + strlen(logtext), " has no static class initializer");
3725 if (!(m->flags & ACC_STATIC))
3726 panic("Class initializer is not static!");
3729 log_message_class("Starting static class initializer for class: ", c);
3731 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3736 /* now call the initializer */
3737 asm_calljavafunction(m, NULL, NULL, NULL, NULL);
3739 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3740 assert(blockInts == 0);
3744 /* we have an exception */
3745 if (*exceptionptr) {
3746 java_objectheader *xptr;
3747 java_objectheader *cause;
3749 /* class is NOT initialized */
3750 c->initialized = false;
3753 cause = *exceptionptr;
3755 /* clear exception, because we are calling jit code again */
3756 *exceptionptr = NULL;
3758 /* wrap the exception */
3760 new_exception_throwable(string_java_lang_ExceptionInInitializerError,
3761 (java_lang_Throwable *) cause);
3763 if (*exceptionptr) {
3767 /* set new exception */
3768 *exceptionptr = xptr;
3774 log_message_class("Finished static class initializer for class: ", c);
3780 /********* Function: find_class_method_constant *********/
3782 int find_class_method_constant (classinfo *c, utf * c1, utf* m1, utf* d1)
3787 for (i=0; i<c->cpcount; i++) {
3789 e = c -> cpinfos [i];
3792 switch (c -> cptags [i]) {
3793 case CONSTANT_Methodref:
3795 constant_FMIref *fmi = e;
3796 if ( (fmi->class->name == c1)
3797 && (fmi->name == m1)
3798 && (fmi->descriptor == d1)) {
3805 case CONSTANT_InterfaceMethodref:
3807 constant_FMIref *fmi = e;
3808 if ( (fmi->class->name == c1)
3809 && (fmi->name == m1)
3810 && (fmi->descriptor == d1)) {
3824 void class_showconstanti(classinfo *c, int ii)
3830 printf ("#%d: ", (int) i);
3832 switch (c->cptags [i]) {
3833 case CONSTANT_Class:
3834 printf("Classreference -> ");
3835 utf_display(((classinfo*)e)->name);
3838 case CONSTANT_Fieldref:
3839 printf("Fieldref -> "); goto displayFMIi;
3840 case CONSTANT_Methodref:
3841 printf("Methodref -> "); goto displayFMIi;
3842 case CONSTANT_InterfaceMethodref:
3843 printf("InterfaceMethod -> "); goto displayFMIi;
3846 constant_FMIref *fmi = e;
3847 utf_display(fmi->class->name);
3849 utf_display(fmi->name);
3851 utf_display(fmi->descriptor);
3855 case CONSTANT_String:
3856 printf("String -> ");
3859 case CONSTANT_Integer:
3860 printf("Integer -> %d", (int) (((constant_integer*)e)->value));
3862 case CONSTANT_Float:
3863 printf("Float -> %f", ((constant_float*)e)->value);
3865 case CONSTANT_Double:
3866 printf("Double -> %f", ((constant_double*)e)->value);
3870 u8 v = ((constant_long*)e)->value;
3872 printf("Long -> %ld", (long int) v);
3874 printf("Long -> HI: %ld, LO: %ld\n",
3875 (long int) v.high, (long int) v.low);
3879 case CONSTANT_NameAndType:
3881 constant_nameandtype *cnt = e;
3882 printf("NameAndType: ");
3883 utf_display(cnt->name);
3885 utf_display(cnt->descriptor);
3893 panic("Invalid type of ConstantPool-Entry");
3900 void class_showconstantpool (classinfo *c)
3905 printf ("---- dump of constant pool ----\n");
3907 for (i=0; i<c->cpcount; i++) {
3908 printf ("#%d: ", (int) i);
3910 e = c -> cpinfos [i];
3913 switch (c -> cptags [i]) {
3914 case CONSTANT_Class:
3915 printf ("Classreference -> ");
3916 utf_display ( ((classinfo*)e) -> name );
3919 case CONSTANT_Fieldref:
3920 printf ("Fieldref -> "); goto displayFMI;
3921 case CONSTANT_Methodref:
3922 printf ("Methodref -> "); goto displayFMI;
3923 case CONSTANT_InterfaceMethodref:
3924 printf ("InterfaceMethod -> "); goto displayFMI;
3927 constant_FMIref *fmi = e;
3928 utf_display ( fmi->class->name );
3930 utf_display ( fmi->name);
3932 utf_display ( fmi->descriptor );
3936 case CONSTANT_String:
3937 printf ("String -> ");
3940 case CONSTANT_Integer:
3941 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
3943 case CONSTANT_Float:
3944 printf ("Float -> %f", ((constant_float*)e) -> value);
3946 case CONSTANT_Double:
3947 printf ("Double -> %f", ((constant_double*)e) -> value);
3951 u8 v = ((constant_long*)e) -> value;
3953 printf ("Long -> %ld", (long int) v);
3955 printf ("Long -> HI: %ld, LO: %ld\n",
3956 (long int) v.high, (long int) v.low);
3960 case CONSTANT_NameAndType:
3962 constant_nameandtype *cnt = e;
3963 printf ("NameAndType: ");
3964 utf_display (cnt->name);
3966 utf_display (cnt->descriptor);
3970 printf ("Utf8 -> ");
3974 panic ("Invalid type of ConstantPool-Entry");
3984 /********** Function: class_showmethods (debugging only) *************/
3986 void class_showmethods (classinfo *c)
3990 printf ("--------- Fields and Methods ----------------\n");
3991 printf ("Flags: "); printflags (c->flags); printf ("\n");
3993 printf ("This: "); utf_display (c->name); printf ("\n");
3995 printf ("Super: "); utf_display (c->super->name); printf ("\n");
3997 printf ("Index: %d\n", c->index);
3999 printf ("interfaces:\n");
4000 for (i=0; i < c-> interfacescount; i++) {
4002 utf_display (c -> interfaces[i] -> name);
4003 printf (" (%d)\n", c->interfaces[i] -> index);
4006 printf ("fields:\n");
4007 for (i=0; i < c -> fieldscount; i++) {
4008 field_display (&(c -> fields[i]));
4011 printf ("methods:\n");
4012 for (i=0; i < c -> methodscount; i++) {
4013 methodinfo *m = &(c->methods[i]);
4014 if ( !(m->flags & ACC_STATIC))
4015 printf ("vftblindex: %d ", m->vftblindex);
4017 method_display ( m );
4021 printf ("Virtual function table:\n");
4022 for (i=0; i<c->vftbl->vftbllength; i++) {
4023 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]) );
4029 /******************************************************************************/
4030 /******************* General functions for the class loader *******************/
4031 /******************************************************************************/
4033 /**************** function: create_primitive_classes ***************************
4035 create classes representing primitive types
4037 *******************************************************************************/
4039 void create_primitive_classes()
4043 for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
4044 /* create primitive class */
4046 class_new_intern(utf_new_char(primitivetype_table[i].name));
4047 c->classUsed = NOTUSED; /* not used initially CO-RT */
4050 /* prevent loader from loading primitive class */
4054 primitivetype_table[i].class_primitive = c;
4056 /* create class for wrapping the primitive type */
4057 c = class_new_intern(utf_new_char(primitivetype_table[i].wrapname));
4058 primitivetype_table[i].class_wrap = c;
4059 primitivetype_table[i].class_wrap->classUsed = NOTUSED; /* not used initially CO-RT */
4060 primitivetype_table[i].class_wrap->impldBy = NULL;
4062 /* create the primitive array class */
4063 if (primitivetype_table[i].arrayname) {
4064 c = class_new_intern(utf_new_char(primitivetype_table[i].arrayname));
4065 primitivetype_table[i].arrayclass = c;
4069 primitivetype_table[i].arrayvftbl = c->vftbl;
4075 /**************** function: class_primitive_from_sig ***************************
4077 return the primitive class indicated by the given signature character
4079 If the descriptor does not indicate a valid primitive type the
4080 return value is NULL.
4082 ********************************************************************************/
4084 classinfo *class_primitive_from_sig(char sig)
4087 case 'I': return primitivetype_table[PRIMITIVETYPE_INT].class_primitive;
4088 case 'J': return primitivetype_table[PRIMITIVETYPE_LONG].class_primitive;
4089 case 'F': return primitivetype_table[PRIMITIVETYPE_FLOAT].class_primitive;
4090 case 'D': return primitivetype_table[PRIMITIVETYPE_DOUBLE].class_primitive;
4091 case 'B': return primitivetype_table[PRIMITIVETYPE_BYTE].class_primitive;
4092 case 'C': return primitivetype_table[PRIMITIVETYPE_CHAR].class_primitive;
4093 case 'S': return primitivetype_table[PRIMITIVETYPE_SHORT].class_primitive;
4094 case 'Z': return primitivetype_table[PRIMITIVETYPE_BOOLEAN].class_primitive;
4095 case 'V': return primitivetype_table[PRIMITIVETYPE_VOID].class_primitive;
4100 /****************** function: class_from_descriptor ****************************
4102 return the class indicated by the given descriptor
4104 utf_ptr....first character of descriptor
4105 end_ptr....first character after the end of the string
4106 next.......if non-NULL, *next is set to the first character after
4107 the descriptor. (Undefined if an error occurs.)
4109 mode.......a combination (binary or) of the following flags:
4111 (Flags marked with * are the default settings.)
4113 What to do if a reference type descriptor is parsed successfully:
4115 CLASSLOAD_SKIP...skip it and return something != NULL
4116 * CLASSLOAD_NEW....get classinfo * via class_new
4117 CLASSLOAD_LOAD...get classinfo * via loader_load
4119 How to handle primitive types:
4121 * CLASSLOAD_PRIMITIVE.......return primitive class (eg. "int")
4122 CLASSLOAD_NULLPRIMITIVE...return NULL for primitive types
4124 How to handle "V" descriptors:
4126 * CLASSLOAD_VOID.....handle it like other primitive types
4127 CLASSLOAD_NOVOID...treat it as an error
4129 How to deal with extra characters after the end of the
4132 * CLASSLOAD_NOCHECKEND...ignore (useful for parameter lists)
4133 CLASSLOAD_CHECKEND.....treat them as an error
4135 How to deal with errors:
4137 * CLASSLOAD_PANIC....abort execution with an error message
4138 CLASSLOAD_NOPANIC..return NULL on error
4140 *******************************************************************************/
4142 classinfo *class_from_descriptor(char *utf_ptr, char *end_ptr,
4143 char **next, int mode)
4145 char *start = utf_ptr;
4149 SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr, end_ptr, error);
4151 if (mode & CLASSLOAD_CHECKEND)
4152 error |= (utf_ptr != end_ptr);
4155 if (next) *next = utf_ptr;
4159 if (mode & CLASSLOAD_NOVOID)
4170 return (mode & CLASSLOAD_NULLPRIMITIVE)
4172 : class_primitive_from_sig(*start);
4179 if (mode & CLASSLOAD_SKIP) return class_java_lang_Object;
4180 name = utf_new(start, utf_ptr - start);
4184 tc = class_new_intern(name);
4186 list_addfirst(&unlinkedclasses, tc);
4191 return (mode & CLASSLOAD_LOAD)
4192 ? class_load(class_new(name)) : class_new(name); /* XXX handle errors */
4197 /* An error occurred */
4198 if (mode & CLASSLOAD_NOPANIC)
4201 log_plain("Invalid descriptor at beginning of '");
4202 log_plain_utf(utf_new(start, end_ptr - start));
4206 panic("Invalid descriptor");
4208 /* keep compiler happy */
4213 /******************* function: type_from_descriptor ****************************
4215 return the basic type indicated by the given descriptor
4217 This function parses a descriptor and returns its basic type as
4218 TYPE_INT, TYPE_LONG, TYPE_FLOAT, TYPE_DOUBLE, TYPE_ADDRESS or TYPE_VOID.
4220 cls...if non-NULL the referenced variable is set to the classinfo *
4221 returned by class_from_descriptor.
4223 For documentation of the arguments utf_ptr, end_ptr, next and mode
4224 see class_from_descriptor. The only difference is that
4225 type_from_descriptor always uses CLASSLOAD_PANIC.
4227 ********************************************************************************/
4229 int type_from_descriptor(classinfo **cls, char *utf_ptr, char *end_ptr,
4230 char **next, int mode)
4233 if (!cls) cls = &mycls;
4234 *cls = class_from_descriptor(utf_ptr, end_ptr, next, mode & (~CLASSLOAD_NOPANIC));
4251 return TYPE_ADDRESS;
4255 /*************** function: create_pseudo_classes *******************************
4257 create pseudo classes used by the typechecker
4259 ********************************************************************************/
4261 static void create_pseudo_classes()
4263 /* pseudo class for Arraystubs (extends java.lang.Object) */
4265 pseudo_class_Arraystub = class_new_intern(utf_new_char("$ARRAYSTUB$"));
4266 pseudo_class_Arraystub->loaded = true;
4267 pseudo_class_Arraystub->super = class_java_lang_Object;
4268 pseudo_class_Arraystub->interfacescount = 2;
4269 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
4270 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
4271 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
4273 class_link(pseudo_class_Arraystub);
4275 pseudo_class_Arraystub_vftbl = pseudo_class_Arraystub->vftbl;
4277 /* pseudo class representing the null type */
4279 pseudo_class_Null = class_new_intern(utf_new_char("$NULL$"));
4280 pseudo_class_Null->loaded = true;
4281 pseudo_class_Null->super = class_java_lang_Object;
4282 class_link(pseudo_class_Null);
4284 /* pseudo class representing new uninitialized objects */
4286 pseudo_class_New = class_new_intern(utf_new_char("$NEW$"));
4287 pseudo_class_New->loaded = true;
4288 pseudo_class_New->linked = true;
4289 pseudo_class_New->super = class_java_lang_Object;
4290 /* class_link(pseudo_class_New); */
4294 /********************** Function: loader_init **********************************
4296 Initializes all lists and loads all classes required for the system or the
4299 *******************************************************************************/
4301 void loader_init(u1 *stackbottom)
4305 /* create utf-symbols for pointer comparison of frequently used strings */
4306 utf_innerclasses = utf_new_char("InnerClasses");
4307 utf_constantvalue = utf_new_char("ConstantValue");
4308 utf_code = utf_new_char("Code");
4309 utf_exceptions = utf_new_char("Exceptions");
4310 utf_linenumbertable = utf_new_char("LineNumberTable");
4311 utf_sourcefile = utf_new_char("SourceFile");
4312 utf_finalize = utf_new_char("finalize");
4313 utf_fidesc = utf_new_char("()V");
4314 utf_init = utf_new_char("<init>");
4315 utf_clinit = utf_new_char("<clinit>");
4316 utf_initsystemclass = utf_new_char("initializeSystemClass");
4317 utf_systemclass = utf_new_char("java/lang/System");
4318 utf_vmclassloader = utf_new_char("java/lang/VMClassLoader");
4319 utf_initialize = utf_new_char("initialize");
4320 utf_initializedesc = utf_new_char("(I)V");
4321 utf_vmclass = utf_new_char("java/lang/VMClass");
4322 utf_java_lang_Object= utf_new_char("java/lang/Object");
4323 array_packagename = utf_new_char("<the array package>");
4324 utf_fillInStackTrace_name = utf_new_char("fillInStackTrace");
4325 utf_fillInStackTrace_desc = utf_new_char("()Ljava/lang/Throwable;");
4327 /* create some important classes */
4328 /* These classes have to be created now because the classinfo
4329 * pointers are used in the loading code.
4331 class_java_lang_Object =
4332 class_new_intern(utf_java_lang_Object);
4333 class_load(class_java_lang_Object);
4334 class_link(class_java_lang_Object);
4336 class_java_lang_String =
4337 class_new_intern(utf_new_char("java/lang/String"));
4338 class_load(class_java_lang_String);
4339 class_link(class_java_lang_String);
4341 class_java_lang_Cloneable =
4342 class_new_intern(utf_new_char("java/lang/Cloneable"));
4343 class_load(class_java_lang_Cloneable);
4344 class_link(class_java_lang_Cloneable);
4346 class_java_io_Serializable =
4347 class_new_intern(utf_new_char("java/io/Serializable"));
4348 class_load(class_java_io_Serializable);
4349 class_link(class_java_io_Serializable);
4351 /* create classes representing primitive types */
4352 create_primitive_classes();
4354 /* create classes used by the typechecker */
4355 create_pseudo_classes();
4357 /* correct vftbl-entries (retarded loading of class java/lang/String) */
4358 stringtable_update();
4360 #if defined(USE_THREADS)
4361 if (stackbottom != 0)
4367 static void loader_compute_class_values(classinfo *c)
4371 c->vftbl->baseval = ++classvalue;
4374 while (subs != NULL) {
4375 loader_compute_class_values(subs);
4376 subs = subs->nextsub;
4379 c->vftbl->diffval = classvalue - c->vftbl->baseval;
4383 void loader_compute_subclasses(classinfo *c)
4385 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
4389 if (!(c->flags & ACC_INTERFACE)) {
4394 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
4395 c->nextsub = c->super->sub;
4401 /* this is the java.lang.Object special case */
4402 if (!class_java_lang_Object) {
4403 loader_compute_class_values(c);
4406 loader_compute_class_values(class_java_lang_Object);
4409 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
4415 /******************** Function: loader_close ***********************************
4419 *******************************************************************************/
4426 for (slot = 0; slot < class_hash.size; slot++) {
4427 c = class_hash.ptr[slot];
4438 * These are local overrides for various environment variables in Emacs.
4439 * Please do not remove this and leave it at the end of the file, where
4440 * Emacs will automagically detect them.
4441 * ---------------------------------------------------------------------
4444 * indent-tabs-mode: t