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 1508 2004-11-15 08:34:10Z carolyn $
44 #include "exceptions.h"
53 #include "statistics.h"
54 #include "toolbox/memory.h"
55 #include "toolbox/logging.h"
56 #include "threads/thread.h"
57 #include "threads/locks.h"
58 #include "nat/java_lang_Throwable.h"
68 /* global variables ***********************************************************/
70 static s4 interfaceindex; /* sequential numbering of interfaces */
74 /* utf-symbols for pointer comparison of frequently used strings */
76 static utf *utf_innerclasses; /* InnerClasses */
77 static utf *utf_constantvalue; /* ConstantValue */
78 static utf *utf_code; /* Code */
79 static utf *utf_exceptions; /* Exceptions */
80 static utf *utf_linenumbertable; /* LineNumberTable */
81 static utf *utf_sourcefile; /* SourceFile */
82 static utf *utf_finalize; /* finalize */
83 static utf *utf_fidesc; /* ()V changed */
84 static utf *utf_init; /* <init> */
85 static utf *utf_clinit; /* <clinit> */
86 static utf *utf_initsystemclass; /* initializeSystemClass */
87 static utf *utf_systemclass; /* java/lang/System */
88 static utf *utf_vmclassloader; /* java/lang/VMClassLoader */
89 static utf *utf_vmclass; /* java/lang/VMClassLoader */
90 static utf *utf_initialize;
91 static utf *utf_initializedesc;
92 static utf *utf_java_lang_Object; /* java/lang/Object */
94 utf *utf_fillInStackTrace_name;
95 utf *utf_fillInStackTrace_desc;
105 /* important system classes ***************************************************/
107 classinfo *class_java_lang_Object;
108 classinfo *class_java_lang_String;
109 classinfo *class_java_lang_Cloneable;
110 classinfo *class_java_io_Serializable;
112 /* Pseudo classes for the typechecker */
113 classinfo *pseudo_class_Arraystub = NULL;
114 classinfo *pseudo_class_Null = NULL;
115 classinfo *pseudo_class_New = NULL;
116 vftbl_t *pseudo_class_Arraystub_vftbl = NULL;
118 utf *array_packagename = NULL;
121 /********************************************************************
122 list of classpath entries (either filesystem directories or
124 ********************************************************************/
125 static classpath_info *classpath_entries=0;
128 /******************************************************************************
130 structure for primitive classes: contains the class for wrapping the
131 primitive type, the primitive class, the name of the class for wrapping,
132 the one character type signature and the name of the primitive class
134 ******************************************************************************/
136 /* CAUTION: Don't change the order of the types. This table is indexed
137 * by the ARRAYTYPE_ constants (expcept ARRAYTYPE_OBJECT).
139 primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = {
140 { NULL, NULL, "java/lang/Integer", 'I', "int" , "[I", NULL, NULL },
141 { NULL, NULL, "java/lang/Long", 'J', "long" , "[J", NULL, NULL },
142 { NULL, NULL, "java/lang/Float", 'F', "float" , "[F", NULL, NULL },
143 { NULL, NULL, "java/lang/Double", 'D', "double" , "[D", NULL, NULL },
144 { NULL, NULL, "java/lang/Byte", 'B', "byte" , "[B", NULL, NULL },
145 { NULL, NULL, "java/lang/Character", 'C', "char" , "[C", NULL, NULL },
146 { NULL, NULL, "java/lang/Short", 'S', "short" , "[S", NULL, NULL },
147 { NULL, NULL, "java/lang/Boolean", 'Z', "boolean" , "[Z", NULL, NULL },
148 { NULL, NULL, "java/lang/Void", 'V', "void" , NULL, NULL, NULL }
152 /************* functions for reading classdata *********************************
154 getting classdata in blocks of variable size
155 (8,16,32,64-bit integer or float)
157 *******************************************************************************/
159 /* check_classbuffer_size ******************************************************
161 assert that at least <len> bytes are left to read
162 <len> is limited to the range of non-negative s4 values
164 *******************************************************************************/
166 static inline bool check_classbuffer_size(classbuffer *cb, s4 len)
168 if (len < 0 || ((cb->data + cb->size) - cb->pos - 1) < len) {
170 new_classformaterror((cb)->class, "Truncated class file");
179 /* suck_nbytes *****************************************************************
181 transfer block of classfile data into a buffer
183 *******************************************************************************/
185 inline void suck_nbytes(u1 *buffer, classbuffer *cb, s4 len)
187 memcpy(buffer, cb->pos + 1, len);
192 /* skip_nbytes ****************************************************************
194 skip block of classfile data
196 *******************************************************************************/
198 inline void skip_nbytes(classbuffer *cb, s4 len)
204 inline u1 suck_u1(classbuffer *cb)
210 inline u2 suck_u2(classbuffer *cb)
214 return ((u2) a << 8) + (u2) b;
218 inline u4 suck_u4(classbuffer *cb)
224 return ((u4) a << 24) + ((u4) b << 16) + ((u4) c << 8) + (u4) d;
228 /* get u8 from classfile data */
229 static u8 suck_u8(classbuffer *cb)
235 return (hi << 32) + lo;
238 v.high = suck_u4(cb);
245 #define suck_s8(a) (s8) suck_u8((a))
246 #define suck_s2(a) (s2) suck_u2((a))
247 #define suck_s4(a) (s4) suck_u4((a))
248 #define suck_s1(a) (s1) suck_u1((a))
251 /* get float from classfile data */
252 static float suck_float(classbuffer *cb)
260 for (i = 0; i < 4; i++)
261 buffer[3 - i] = suck_u1(cb);
263 memcpy((u1*) (&f), buffer, 4);
265 suck_nbytes((u1*) (&f), cb, 4);
268 if (sizeof(float) != 4) {
269 *exceptionptr = new_exception_message(string_java_lang_InternalError,
270 "Incompatible float-format");
272 /* XXX should we exit in such a case? */
273 throw_exception_exit();
280 /* get double from classfile data */
281 static double suck_double(classbuffer *cb)
289 for (i = 0; i < 8; i++)
290 buffer[7 - i] = suck_u1(cb);
292 memcpy((u1*) (&d), buffer, 8);
294 suck_nbytes((u1*) (&d), cb, 8);
297 if (sizeof(double) != 8) {
298 *exceptionptr = new_exception_message(string_java_lang_InternalError,
299 "Incompatible double-format");
301 /* XXX should we exit in such a case? */
302 throw_exception_exit();
309 /************************** function suck_init *********************************
311 called once at startup, sets the searchpath for the classfiles
313 *******************************************************************************/
315 void suck_init(char *classpath)
322 union classpath_info *tmp;
323 union classpath_info *insertAfter=0;
328 if (classpath_entries)
329 panic("suck_init should be called only once");
331 for (start = classpath; (*start) != '\0';) {
332 for (end = start; ((*end) != '\0') && ((*end) != ':'); end++);
336 filenamelen = end - start;
338 if (filenamelen > 3) {
339 if (strncasecmp(end - 3, "zip", 3) == 0 ||
340 strncasecmp(end - 3, "jar", 3) == 0) {
345 if (filenamelen >= (CLASSPATH_MAXFILENAME - 1))
346 panic("path length >= MAXFILENAME in suck_init");
349 filename = MNEW(char, CLASSPATH_MAXFILENAME);
351 strncpy(filename, start, filenamelen);
352 filename[filenamelen + 1] = '\0';
356 #if defined(USE_ZLIB)
357 unzFile uf = unzOpen(filename);
360 tmp = (union classpath_info *) NEW(classpath_info);
361 tmp->archive.type = CLASSPATH_ARCHIVE;
362 tmp->archive.uf = uf;
363 tmp->archive.next = NULL;
367 throw_cacao_exception_exit(string_java_lang_InternalError,
368 "zip/jar files not supported");
372 tmp = (union classpath_info *) NEW(classpath_info);
373 tmp->filepath.type = CLASSPATH_PATH;
374 tmp->filepath.next = 0;
376 if (filename[filenamelen - 1] != '/') {/*PERHAPS THIS SHOULD BE READ FROM A GLOBAL CONFIGURATION */
377 filename[filenamelen] = '/';
378 filename[filenamelen + 1] = '\0';
382 tmp->filepath.filename = filename;
383 tmp->filepath.pathlen = filenamelen;
389 insertAfter->filepath.next = tmp;
392 classpath_entries = tmp;
404 MFREE(filename, char, CLASSPATH_MAXFILENAME);
411 void create_all_classes()
415 for (cpi = classpath_entries; cpi != 0; cpi = cpi->filepath.next) {
416 #if defined(USE_ZLIB)
417 if (cpi->filepath.type == CLASSPATH_ARCHIVE) {
421 s = (unz_s *) cpi->archive.uf;
422 ce = s->cacao_dir_list;
425 (void) class_new(ce->name);
431 #if defined(USE_ZLIB)
438 /************************** function suck_start ********************************
440 returns true if classbuffer is already loaded or a file for the
441 specified class has succussfully been read in. All directories of
442 the searchpath are used to find the classfile (<classname>.class).
443 Returns false if no classfile is found and writes an error message.
445 *******************************************************************************/
447 classbuffer *suck_start(classinfo *c)
449 classpath_info *currPos;
452 char filename[CLASSPATH_MAXFILENAME+10]; /* room for '.class' */
459 utf_ptr = c->name->text;
461 while (utf_ptr < utf_end(c->name)) {
462 if (filenamelen >= CLASSPATH_MAXFILENAME) {
464 new_exception_message(string_java_lang_InternalError,
465 "Filename too long");
467 /* XXX should we exit in such a case? */
468 throw_exception_exit();
472 if ((ch <= ' ' || ch > 'z') && (ch != '/')) /* invalid character */
474 filename[filenamelen++] = ch;
477 strcpy(filename + filenamelen, ".class");
480 for (currPos = classpath_entries; currPos != 0; currPos = currPos->filepath.next) {
481 #if defined(USE_ZLIB)
482 if (currPos->filepath.type == CLASSPATH_ARCHIVE) {
483 if (cacao_locate(currPos->archive.uf, c->name) == UNZ_OK) {
484 unz_file_info file_info;
485 /*log_text("Class found in zip file");*/
486 if (unzGetCurrentFileInfo(currPos->archive.uf, &file_info, filename,
487 sizeof(filename), NULL, 0, NULL, 0) == UNZ_OK) {
488 if (unzOpenCurrentFile(currPos->archive.uf) == UNZ_OK) {
489 cb = NEW(classbuffer);
491 cb->size = file_info.uncompressed_size;
492 cb->data = MNEW(u1, cb->size);
493 cb->pos = cb->data - 1;
494 /*printf("classfile size: %d\n",file_info.uncompressed_size);*/
495 if (unzReadCurrentFile(currPos->archive.uf, cb->data, cb->size) == cb->size) {
496 unzCloseCurrentFile(currPos->archive.uf);
500 MFREE(cb->data, u1, cb->size);
501 FREE(cb, classbuffer);
502 log_text("Error while unzipping");
504 } else log_text("Error while opening file in archive");
505 } else log_text("Error while retrieving fileinfo");
507 unzCloseCurrentFile(currPos->archive.uf);
511 if ((currPos->filepath.pathlen + filenamelen) >= CLASSPATH_MAXFILENAME) continue;
512 strcpy(currPos->filepath.filename + currPos->filepath.pathlen, filename);
513 classfile = fopen(currPos->filepath.filename, "r");
514 if (classfile) { /* file exists */
516 /* determine size of classfile */
518 /* dolog("File: %s",filename); */
519 err = stat(currPos->filepath.filename, &buffer);
521 if (!err) { /* read classfile data */
522 cb = NEW(classbuffer);
524 cb->size = buffer.st_size;
525 cb->data = MNEW(u1, cb->size);
526 cb->pos = cb->data - 1;
527 fread(cb->data, 1, cb->size, classfile);
533 #if defined(USE_ZLIB)
539 dolog("Warning: Can not open class file '%s'", filename);
546 /************************** function suck_stop *********************************
548 frees memory for buffer with classfile data.
549 Caution: this function may only be called if buffer has been allocated
550 by suck_start with reading a file
552 *******************************************************************************/
554 void suck_stop(classbuffer *cb)
558 MFREE(cb->data, u1, cb->size);
559 FREE(cb, classbuffer);
563 /******************************************************************************/
564 /******************* Some support functions ***********************************/
565 /******************************************************************************/
567 void fprintflags (FILE *fp, u2 f)
569 if ( f & ACC_PUBLIC ) fprintf (fp," PUBLIC");
570 if ( f & ACC_PRIVATE ) fprintf (fp," PRIVATE");
571 if ( f & ACC_PROTECTED ) fprintf (fp," PROTECTED");
572 if ( f & ACC_STATIC ) fprintf (fp," STATIC");
573 if ( f & ACC_FINAL ) fprintf (fp," FINAL");
574 if ( f & ACC_SYNCHRONIZED ) fprintf (fp," SYNCHRONIZED");
575 if ( f & ACC_VOLATILE ) fprintf (fp," VOLATILE");
576 if ( f & ACC_TRANSIENT ) fprintf (fp," TRANSIENT");
577 if ( f & ACC_NATIVE ) fprintf (fp," NATIVE");
578 if ( f & ACC_INTERFACE ) fprintf (fp," INTERFACE");
579 if ( f & ACC_ABSTRACT ) fprintf (fp," ABSTRACT");
583 /********** internal function: printflags (only for debugging) ***************/
585 void printflags(u2 f)
587 if ( f & ACC_PUBLIC ) printf (" PUBLIC");
588 if ( f & ACC_PRIVATE ) printf (" PRIVATE");
589 if ( f & ACC_PROTECTED ) printf (" PROTECTED");
590 if ( f & ACC_STATIC ) printf (" STATIC");
591 if ( f & ACC_FINAL ) printf (" FINAL");
592 if ( f & ACC_SYNCHRONIZED ) printf (" SYNCHRONIZED");
593 if ( f & ACC_VOLATILE ) printf (" VOLATILE");
594 if ( f & ACC_TRANSIENT ) printf (" TRANSIENT");
595 if ( f & ACC_NATIVE ) printf (" NATIVE");
596 if ( f & ACC_INTERFACE ) printf (" INTERFACE");
597 if ( f & ACC_ABSTRACT ) printf (" ABSTRACT");
601 /********************** Function: skipattributebody ****************************
603 skips an attribute after the 16 bit reference to attribute_name has already
606 *******************************************************************************/
608 static bool skipattributebody(classbuffer *cb)
612 if (!check_classbuffer_size(cb, 4))
617 if (!check_classbuffer_size(cb, len))
620 skip_nbytes(cb, len);
626 /************************* Function: skipattributes ****************************
628 skips num attribute structures
630 *******************************************************************************/
632 static bool skipattributes(classbuffer *cb, u4 num)
637 for (i = 0; i < num; i++) {
638 if (!check_classbuffer_size(cb, 2 + 4))
644 if (!check_classbuffer_size(cb, len))
647 skip_nbytes(cb, len);
654 /******************** function:: class_getconstant *****************************
656 retrieves the value at position 'pos' of the constantpool of a class
657 if the type of the value is other than 'ctype' the system is stopped
659 *******************************************************************************/
661 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
663 /* check index and type of constantpool entry */
664 /* (pos == 0 is caught by type comparison) */
665 if (pos >= c->cpcount || c->cptags[pos] != ctype) {
666 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
670 return c->cpinfos[pos];
674 /******************** function: innerclass_getconstant ************************
676 like class_getconstant, but if cptags is ZERO null is returned
678 *******************************************************************************/
680 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
682 /* invalid position in constantpool */
683 if (pos >= c->cpcount) {
684 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
688 /* constantpool entry of type 0 */
692 /* check type of constantpool entry */
693 if (c->cptags[pos] != ctype) {
694 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
698 return c->cpinfos[pos];
702 /********************* Function: class_constanttype ****************************
704 Determines the type of a class entry in the ConstantPool
706 *******************************************************************************/
708 u4 class_constanttype(classinfo *c, u4 pos)
710 if (pos <= 0 || pos >= c->cpcount) {
711 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
715 return c->cptags[pos];
719 /************************ function: attribute_load ****************************
721 read attributes from classfile
723 *******************************************************************************/
725 static bool attribute_load(classbuffer *cb, classinfo *c, u4 num)
730 for (i = 0; i < num; i++) {
731 /* retrieve attribute name */
732 if (!check_classbuffer_size(cb, 2))
735 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
738 if (aname == utf_innerclasses) {
739 /* innerclasses attribute */
742 new_classformaterror(c, "Multiple InnerClasses attributes");
746 if (!check_classbuffer_size(cb, 4 + 2))
749 /* skip attribute length */
752 /* number of records */
753 c->innerclasscount = suck_u2(cb);
755 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
758 /* allocate memory for innerclass structure */
759 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
761 for (j = 0; j < c->innerclasscount; j++) {
762 /* The innerclass structure contains a class with an encoded
763 name, its defining scope, its simple name and a bitmask of
764 the access flags. If an inner class is not a member, its
765 outer_class is NULL, if a class is anonymous, its name is
768 innerclassinfo *info = c->innerclass + j;
771 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
773 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
775 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
776 info->flags = suck_u2(cb);
779 } else if (aname == utf_sourcefile) {
780 if (!check_classbuffer_size(cb, 4 + 2))
783 if (suck_u4(cb) != 2) {
785 new_classformaterror(c, "Wrong size for VALUE attribute");
791 new_classformaterror(c, "Multiple SourceFile attributes");
795 if (!(c->sourcefile = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
799 /* unknown attribute */
800 if (!skipattributebody(cb))
809 /******************* function: checkfielddescriptor ****************************
811 checks whether a field-descriptor is valid and aborts otherwise
812 all referenced classes are inserted into the list of unloaded classes
814 *******************************************************************************/
816 static void checkfielddescriptor (char *utf_ptr, char *end_pos)
818 class_from_descriptor(utf_ptr,end_pos,NULL,
820 | CLASSLOAD_NULLPRIMITIVE
822 | CLASSLOAD_CHECKEND);
824 /* XXX use the following if -noverify */
826 char *tstart; /* pointer to start of classname */
828 char *start = utf_ptr;
830 switch (*utf_ptr++) {
844 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
845 panic ("Ill formed descriptor");
849 panic ("Ill formed descriptor");
852 /* exceeding characters */
853 if (utf_ptr!=end_pos) panic ("descriptor has exceeding chars");
858 /******************* function checkmethoddescriptor ****************************
860 checks whether a method-descriptor is valid and aborts otherwise.
861 All referenced classes are inserted into the list of unloaded classes.
863 The number of arguments is returned. A long or double argument is counted
866 *******************************************************************************/
868 static int checkmethoddescriptor(classinfo *c, utf *descriptor)
870 char *utf_ptr; /* current position in utf text */
871 char *end_pos; /* points behind utf string */
872 s4 argcount = 0; /* number of arguments */
874 utf_ptr = descriptor->text;
875 end_pos = utf_end(descriptor);
877 /* method descriptor must start with parenthesis */
878 if (utf_ptr == end_pos || *utf_ptr++ != '(')
879 panic ("Missing '(' in method descriptor");
881 /* check arguments */
882 while (utf_ptr != end_pos && *utf_ptr != ')') {
883 /* We cannot count the this argument here because
884 * we don't know if the method is static. */
885 if (*utf_ptr == 'J' || *utf_ptr == 'D')
889 class_from_descriptor(utf_ptr,end_pos,&utf_ptr,
891 | CLASSLOAD_NULLPRIMITIVE
895 if (utf_ptr == end_pos)
896 panic("Missing ')' in method descriptor");
898 utf_ptr++; /* skip ')' */
900 class_from_descriptor(utf_ptr,
904 CLASSLOAD_NULLPRIMITIVE |
907 if (argcount > 255) {
909 new_classformaterror(c, "Too many arguments in signature");
916 /* XXX use the following if -noverify */
918 /* check arguments */
919 while ((c = *utf_ptr++) != ')') {
936 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
937 panic ("Ill formed method descriptor");
941 panic ("Ill formed methodtype-descriptor");
945 /* check returntype */
947 /* returntype void */
948 if ((utf_ptr+1) != end_pos) panic ("Method-descriptor has exceeding chars");
951 /* treat as field-descriptor */
952 checkfielddescriptor (utf_ptr,end_pos);
957 /***************** Function: print_arraydescriptor ****************************
959 Debugging helper for displaying an arraydescriptor
961 *******************************************************************************/
963 void print_arraydescriptor(FILE *file, arraydescriptor *desc)
966 fprintf(file, "<NULL>");
971 if (desc->componentvftbl) {
972 if (desc->componentvftbl->class)
973 utf_fprint(file, desc->componentvftbl->class->name);
975 fprintf(file, "<no classinfo>");
981 if (desc->elementvftbl) {
982 if (desc->elementvftbl->class)
983 utf_fprint(file, desc->elementvftbl->class->name);
985 fprintf(file, "<no classinfo>");
989 fprintf(file, ",%d,%d,%d,%d}", desc->arraytype, desc->dimension,
990 desc->dataoffset, desc->componentsize);
994 /******************************************************************************/
995 /************************** Functions for fields ****************************/
996 /******************************************************************************/
999 /* field_load ******************************************************************
1001 Load everything about a class field from the class file and fill a
1002 'fieldinfo' structure. For static fields, space in the data segment is
1005 *******************************************************************************/
1007 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
1009 static bool field_load(classbuffer *cb, classinfo *c, fieldinfo *f)
1013 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
1016 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1019 f->flags = suck_u2(cb);
1021 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1025 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1031 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<')
1032 panic("Field with invalid name");
1034 /* check flag consistency */
1035 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
1037 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
1038 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
1040 new_classformaterror(c,
1041 "Illegal field modifiers: 0x%X",
1046 if (c->flags & ACC_INTERFACE) {
1047 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
1048 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
1049 f->flags & ACC_TRANSIENT) {
1051 new_classformaterror(c,
1052 "Illegal field modifiers: 0x%X",
1058 /* check descriptor */
1059 checkfielddescriptor(f->descriptor->text, utf_end(f->descriptor));
1062 f->type = jtype = desc_to_type(f->descriptor); /* data type */
1063 f->offset = 0; /* offset from start of object */
1068 case TYPE_INT: f->value.i = 0; break;
1069 case TYPE_FLOAT: f->value.f = 0.0; break;
1070 case TYPE_DOUBLE: f->value.d = 0.0; break;
1071 case TYPE_ADDRESS: f->value.a = NULL; break;
1074 f->value.l = 0; break;
1076 f->value.l.low = 0; f->value.l.high = 0; break;
1080 /* read attributes */
1081 if (!check_classbuffer_size(cb, 2))
1084 attrnum = suck_u2(cb);
1085 for (i = 0; i < attrnum; i++) {
1086 if (!check_classbuffer_size(cb, 2))
1089 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1092 if (u == utf_constantvalue) {
1093 if (!check_classbuffer_size(cb, 4 + 2))
1096 /* check attribute length */
1097 if (suck_u4(cb) != 2) {
1099 new_classformaterror(c, "Wrong size for VALUE attribute");
1103 /* constant value attribute */
1104 if (pindex != field_load_NOVALUE) {
1106 new_classformaterror(c,
1107 "Multiple ConstantValue attributes");
1111 /* index of value in constantpool */
1112 pindex = suck_u2(cb);
1114 /* initialize field with value from constantpool */
1117 constant_integer *ci;
1119 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
1122 f->value.i = ci->value;
1129 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
1132 f->value.l = cl->value;
1139 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
1142 f->value.f = cf->value;
1147 constant_double *cd;
1149 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
1152 f->value.d = cd->value;
1157 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
1160 /* create javastring from compressed utf8-string */
1161 f->value.a = literalstring_new(u);
1165 log_text("Invalid Constant - Type");
1169 /* unknown attribute */
1170 if (!skipattributebody(cb))
1175 /* everything was ok */
1181 /********************** function: field_free **********************************/
1183 static void field_free(fieldinfo *f)
1189 /**************** Function: field_display (debugging only) ********************/
1191 void field_display(fieldinfo *f)
1194 printflags(f->flags);
1196 utf_display(f->name);
1198 utf_display(f->descriptor);
1199 printf(" offset: %ld\n", (long int) (f->offset));
1203 /******************************************************************************/
1204 /************************* Functions for methods ******************************/
1205 /******************************************************************************/
1208 /* method_load *****************************************************************
1210 Loads a method from the class file and fills an existing 'methodinfo'
1211 structure. For native methods, the function pointer field is set to the
1212 real function pointer, for JavaVM methods a pointer to the compiler is used
1215 *******************************************************************************/
1217 static bool method_load(classbuffer *cb, classinfo *c, methodinfo *m)
1225 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1226 initObjectLock(&m->header);
1231 count_all_methods++;
1234 m->thrownexceptionscount = 0;
1235 m->linenumbercount = 0;
1238 m->nativelyoverloaded = false;
1240 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1243 m->flags = suck_u2(cb);
1245 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1249 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1254 if (!is_valid_name_utf(m->name))
1255 panic("Method with invalid name");
1257 if (m->name->text[0] == '<'
1258 && m->name != utf_init && m->name != utf_clinit)
1259 panic("Method with invalid special name");
1262 argcount = checkmethoddescriptor(c, m->descriptor);
1264 if (!(m->flags & ACC_STATIC))
1265 argcount++; /* count the 'this' argument */
1268 if (argcount > 255) {
1270 new_classformaterror(c, "Too many arguments in signature");
1274 /* check flag consistency */
1275 if (m->name != utf_clinit) {
1276 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1278 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1280 new_classformaterror(c,
1281 "Illegal method modifiers: 0x%X",
1286 if (m->flags & ACC_ABSTRACT) {
1287 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1288 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1290 new_classformaterror(c,
1291 "Illegal method modifiers: 0x%X",
1297 if (c->flags & ACC_INTERFACE) {
1298 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1300 new_classformaterror(c,
1301 "Illegal method modifiers: 0x%X",
1307 if (m->name == utf_init) {
1308 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1309 ACC_NATIVE | ACC_ABSTRACT))
1310 panic("Instance initialization method has invalid flags set");
1316 m->basicblockcount = 0;
1317 m->basicblocks = NULL;
1318 m->basicblockindex = NULL;
1319 m->instructioncount = 0;
1320 m->instructions = NULL;
1323 m->exceptiontable = NULL;
1324 m->stubroutine = NULL;
1326 m->entrypoint = NULL;
1327 m->methodUsed = NOTUSED;
1330 m->subRedefsUsed = 0;
1334 if (!(m->flags & ACC_NATIVE)) {
1335 m->stubroutine = createcompilerstub(m);
1338 /*if (useinlining) {
1339 log_text("creating native stub:");
1342 functionptr f = native_findfunction(c->name, m->name, m->descriptor,
1343 (m->flags & ACC_STATIC) != 0);
1344 #ifdef STATIC_CLASSPATH
1348 m->stubroutine = createnativestub(f, m);
1352 if (!check_classbuffer_size(cb, 2))
1355 attrnum = suck_u2(cb);
1356 for (i = 0; i < attrnum; i++) {
1359 if (!check_classbuffer_size(cb, 2))
1362 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1365 if (aname == utf_code) {
1366 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1368 new_classformaterror(c,
1369 "Code attribute in native or abstract methods");
1376 new_classformaterror(c, "Multiple Code attributes");
1381 if (!check_classbuffer_size(cb, 4 + 2 + 2))
1385 m->maxstack = suck_u2(cb);
1386 m->maxlocals = suck_u2(cb);
1388 if (m->maxlocals < argcount) {
1390 new_classformaterror(c, "Arguments can't fit into locals");
1395 if (!check_classbuffer_size(cb, 4))
1398 m->jcodelength = suck_u4(cb);
1400 if (m->jcodelength == 0) {
1402 new_classformaterror(c, "Code of a method has length 0");
1407 if (m->jcodelength > 65535) {
1409 new_classformaterror(c,
1410 "Code of a method longer than 65535 bytes");
1415 if (!check_classbuffer_size(cb, m->jcodelength))
1418 m->jcode = MNEW(u1, m->jcodelength);
1419 suck_nbytes(m->jcode, cb, m->jcodelength);
1421 if (!check_classbuffer_size(cb, 2))
1424 m->exceptiontablelength = suck_u2(cb);
1425 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->exceptiontablelength))
1428 m->exceptiontable = MNEW(exceptiontable, m->exceptiontablelength);
1430 #if defined(STATISTICS)
1432 count_vmcode_len += m->jcodelength + 18;
1433 count_extable_len += 8 * m->exceptiontablelength;
1437 for (j = 0; j < m->exceptiontablelength; j++) {
1439 m->exceptiontable[j].startpc = suck_u2(cb);
1440 m->exceptiontable[j].endpc = suck_u2(cb);
1441 m->exceptiontable[j].handlerpc = suck_u2(cb);
1445 m->exceptiontable[j].catchtype = NULL;
1448 if (!(m->exceptiontable[j].catchtype =
1449 class_getconstant(c, idx, CONSTANT_Class)))
1454 if (!check_classbuffer_size(cb, 2))
1457 codeattrnum = suck_u2(cb);
1459 for (; codeattrnum > 0; codeattrnum--) {
1462 if (!check_classbuffer_size(cb, 2))
1465 if (!(caname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1468 if (caname == utf_linenumbertable) {
1471 if (!check_classbuffer_size(cb, 4 + 2))
1475 m->linenumbercount = suck_u2(cb);
1477 if (!check_classbuffer_size(cb,
1478 (2 + 2) * m->linenumbercount))
1481 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1483 for (lncid = 0; lncid < m->linenumbercount; lncid++) {
1484 m->linenumbers[lncid].start_pc = suck_u2(cb);
1485 m->linenumbers[lncid].line_number = suck_u2(cb);
1489 if (!skipattributes(cb, codeattrnum))
1495 if (!skipattributebody(cb))
1500 } else if (aname == utf_exceptions) {
1503 if (m->thrownexceptions) {
1505 new_classformaterror(c, "Multiple Exceptions attributes");
1509 if (!check_classbuffer_size(cb, 4 + 2))
1512 suck_u4(cb); /* length */
1513 m->thrownexceptionscount = suck_u2(cb);
1515 if (!check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1518 m->thrownexceptions = MNEW(classinfo*, m->thrownexceptionscount);
1520 for (j = 0; j < m->thrownexceptionscount; j++) {
1521 if (!((m->thrownexceptions)[j] =
1522 class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1527 if (!skipattributebody(cb))
1532 if (!m->jcode && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1533 *exceptionptr = new_classformaterror(c, "Missing Code attribute");
1538 /* everything was ok */
1539 /* utf_display(m->name);
1540 printf("\nexceptiontablelength:%ld\n",m->exceptiontablelength);*/
1546 /********************* Function: method_free ***********************************
1548 frees all memory that was allocated for this method
1550 *******************************************************************************/
1552 static void method_free(methodinfo *m)
1555 MFREE(m->jcode, u1, m->jcodelength);
1557 if (m->exceptiontable)
1558 MFREE(m->exceptiontable, exceptiontable, m->exceptiontablelength);
1561 CFREE(m->mcode, m->mcodelength);
1563 if (m->stubroutine) {
1564 if (m->flags & ACC_NATIVE) {
1565 removenativestub(m->stubroutine);
1568 removecompilerstub(m->stubroutine);
1574 /************** Function: method_display (debugging only) **************/
1576 void method_display(methodinfo *m)
1579 printflags(m->flags);
1581 utf_display(m->name);
1583 utf_display(m->descriptor);
1587 /************** Function: method_display_flags_last (debugging only) **************/
1589 void method_display_flags_last(methodinfo *m)
1592 utf_display(m->name);
1594 utf_display(m->descriptor);
1596 printflags(m->flags);
1601 /******************** Function: method_canoverwrite ****************************
1603 Check if m and old are identical with respect to type and name. This means
1604 that old can be overwritten with m.
1606 *******************************************************************************/
1608 static bool method_canoverwrite(methodinfo *m, methodinfo *old)
1610 if (m->name != old->name) return false;
1611 if (m->descriptor != old->descriptor) return false;
1612 if (m->flags & ACC_STATIC) return false;
1617 /******************** function: class_loadcpool ********************************
1619 loads the constantpool of a class,
1620 the entries are transformed into a simpler format
1621 by resolving references
1622 (a detailed overview of the compact structures can be found in global.h)
1624 *******************************************************************************/
1626 static bool class_loadcpool(classbuffer *cb, classinfo *c)
1629 /* The following structures are used to save information which cannot be
1630 processed during the first pass. After the complete constantpool has
1631 been traversed the references can be resolved.
1632 (only in specific order) */
1634 /* CONSTANT_Class entries */
1635 typedef struct forward_class {
1636 struct forward_class *next;
1641 /* CONSTANT_String */
1642 typedef struct forward_string {
1643 struct forward_string *next;
1648 /* CONSTANT_NameAndType */
1649 typedef struct forward_nameandtype {
1650 struct forward_nameandtype *next;
1654 } forward_nameandtype;
1656 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
1657 typedef struct forward_fieldmethint {
1658 struct forward_fieldmethint *next;
1662 u2 nameandtype_index;
1663 } forward_fieldmethint;
1668 forward_class *forward_classes = NULL;
1669 forward_string *forward_strings = NULL;
1670 forward_nameandtype *forward_nameandtypes = NULL;
1671 forward_fieldmethint *forward_fieldmethints = NULL;
1674 forward_string *nfs;
1675 forward_nameandtype *nfn;
1676 forward_fieldmethint *nff;
1682 /* number of entries in the constant_pool table plus one */
1683 if (!check_classbuffer_size(cb, 2))
1686 cpcount = c->cpcount = suck_u2(cb);
1688 /* allocate memory */
1689 cptags = c->cptags = MNEW(u1, cpcount);
1690 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
1693 *exceptionptr = new_classformaterror(c, "Illegal constant pool size");
1697 #if defined(STATISTICS)
1699 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
1702 /* initialize constantpool */
1703 for (idx = 0; idx < cpcount; idx++) {
1704 cptags[idx] = CONSTANT_UNUSED;
1705 cpinfos[idx] = NULL;
1709 /******* first pass *******/
1710 /* entries which cannot be resolved now are written into
1711 temporary structures and traversed again later */
1714 while (idx < cpcount) {
1717 /* get constant type */
1718 if (!check_classbuffer_size(cb, 1))
1724 case CONSTANT_Class:
1725 nfc = NEW(forward_class);
1727 nfc->next = forward_classes;
1728 forward_classes = nfc;
1730 nfc->thisindex = idx;
1731 /* reference to CONSTANT_NameAndType */
1732 if (!check_classbuffer_size(cb, 2))
1735 nfc->name_index = suck_u2(cb);
1740 case CONSTANT_String:
1741 nfs = NEW(forward_string);
1743 nfs->next = forward_strings;
1744 forward_strings = nfs;
1746 nfs->thisindex = idx;
1748 /* reference to CONSTANT_Utf8_info with string characters */
1749 if (!check_classbuffer_size(cb, 2))
1752 nfs->string_index = suck_u2(cb);
1757 case CONSTANT_NameAndType:
1758 nfn = NEW(forward_nameandtype);
1760 nfn->next = forward_nameandtypes;
1761 forward_nameandtypes = nfn;
1763 nfn->thisindex = idx;
1765 if (!check_classbuffer_size(cb, 2 + 2))
1768 /* reference to CONSTANT_Utf8_info containing simple name */
1769 nfn->name_index = suck_u2(cb);
1771 /* reference to CONSTANT_Utf8_info containing field or method
1773 nfn->sig_index = suck_u2(cb);
1778 case CONSTANT_Fieldref:
1779 case CONSTANT_Methodref:
1780 case CONSTANT_InterfaceMethodref:
1781 nff = NEW(forward_fieldmethint);
1783 nff->next = forward_fieldmethints;
1784 forward_fieldmethints = nff;
1786 nff->thisindex = idx;
1790 if (!check_classbuffer_size(cb, 2 + 2))
1793 /* class or interface type that contains the declaration of the
1795 nff->class_index = suck_u2(cb);
1797 /* name and descriptor of the field or method */
1798 nff->nameandtype_index = suck_u2(cb);
1803 case CONSTANT_Integer: {
1804 constant_integer *ci = NEW(constant_integer);
1806 #if defined(STATISTICS)
1808 count_const_pool_len += sizeof(constant_integer);
1811 if (!check_classbuffer_size(cb, 4))
1814 ci->value = suck_s4(cb);
1815 cptags[idx] = CONSTANT_Integer;
1822 case CONSTANT_Float: {
1823 constant_float *cf = NEW(constant_float);
1825 #if defined(STATISTICS)
1827 count_const_pool_len += sizeof(constant_float);
1830 if (!check_classbuffer_size(cb, 4))
1833 cf->value = suck_float(cb);
1834 cptags[idx] = CONSTANT_Float;
1841 case CONSTANT_Long: {
1842 constant_long *cl = NEW(constant_long);
1844 #if defined(STATISTICS)
1846 count_const_pool_len += sizeof(constant_long);
1849 if (!check_classbuffer_size(cb, 8))
1852 cl->value = suck_s8(cb);
1853 cptags[idx] = CONSTANT_Long;
1856 if (idx > cpcount) {
1858 new_classformaterror(c, "Invalid constant pool entry");
1864 case CONSTANT_Double: {
1865 constant_double *cd = NEW(constant_double);
1867 #if defined(STATISTICS)
1869 count_const_pool_len += sizeof(constant_double);
1872 if (!check_classbuffer_size(cb, 8))
1875 cd->value = suck_double(cb);
1876 cptags[idx] = CONSTANT_Double;
1879 if (idx > cpcount) {
1881 new_classformaterror(c, "Invalid constant pool entry");
1887 case CONSTANT_Utf8: {
1890 /* number of bytes in the bytes array (not string-length) */
1891 if (!check_classbuffer_size(cb, 2))
1894 length = suck_u2(cb);
1895 cptags[idx] = CONSTANT_Utf8;
1897 /* validate the string */
1898 if (!check_classbuffer_size(cb, length))
1902 !is_valid_utf((char *) (cb->pos + 1),
1903 (char *) (cb->pos + 1 + length))) {
1904 dolog("Invalid UTF-8 string (constant pool index %d)",idx);
1905 panic("Invalid UTF-8 string");
1907 /* insert utf-string into the utf-symboltable */
1908 cpinfos[idx] = utf_new_intern((char *) (cb->pos + 1), length);
1910 /* skip bytes of the string (buffer size check above) */
1911 skip_nbytes(cb, length);
1918 new_classformaterror(c, "Illegal constant pool type");
1924 /* resolve entries in temporary structures */
1926 while (forward_classes) {
1928 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
1930 if (opt_verify && !is_valid_name_utf(name))
1931 panic("Class reference with invalid name");
1933 cptags[forward_classes->thisindex] = CONSTANT_Class;
1934 /* retrieve class from class-table */
1937 tc = class_new_intern(name);
1939 if (!class_load(tc))
1942 /* link the class later, because we cannot link the class currently
1944 list_addfirst(&unlinkedclasses, tc);
1946 cpinfos[forward_classes->thisindex] = tc;
1949 cpinfos[forward_classes->thisindex] = class_new(name);
1952 nfc = forward_classes;
1953 forward_classes = forward_classes->next;
1954 FREE(nfc, forward_class);
1957 while (forward_strings) {
1959 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
1961 /* resolve utf-string */
1962 cptags[forward_strings->thisindex] = CONSTANT_String;
1963 cpinfos[forward_strings->thisindex] = text;
1965 nfs = forward_strings;
1966 forward_strings = forward_strings->next;
1967 FREE(nfs, forward_string);
1970 while (forward_nameandtypes) {
1971 constant_nameandtype *cn = NEW(constant_nameandtype);
1973 #if defined(STATISTICS)
1975 count_const_pool_len += sizeof(constant_nameandtype);
1978 /* resolve simple name and descriptor */
1979 cn->name = class_getconstant(c,
1980 forward_nameandtypes->name_index,
1983 cn->descriptor = class_getconstant(c,
1984 forward_nameandtypes->sig_index,
1989 if (!is_valid_name_utf(cn->name))
1990 panic("NameAndType with invalid name");
1991 /* disallow referencing <clinit> among others */
1992 if (cn->name->text[0] == '<' && cn->name != utf_init)
1993 panic("NameAndType with invalid special name");
1996 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
1997 cpinfos[forward_nameandtypes->thisindex] = cn;
1999 nfn = forward_nameandtypes;
2000 forward_nameandtypes = forward_nameandtypes->next;
2001 FREE(nfn, forward_nameandtype);
2004 while (forward_fieldmethints) {
2005 constant_nameandtype *nat;
2006 constant_FMIref *fmi = NEW(constant_FMIref);
2008 #if defined(STATISTICS)
2010 count_const_pool_len += sizeof(constant_FMIref);
2012 /* resolve simple name and descriptor */
2013 nat = class_getconstant(c,
2014 forward_fieldmethints->nameandtype_index,
2015 CONSTANT_NameAndType);
2017 fmi->class = class_getconstant(c,
2018 forward_fieldmethints->class_index,
2020 fmi->name = nat->name;
2021 fmi->descriptor = nat->descriptor;
2023 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
2024 cpinfos[forward_fieldmethints->thisindex] = fmi;
2026 switch (forward_fieldmethints->tag) {
2027 case CONSTANT_Fieldref: /* check validity of descriptor */
2028 checkfielddescriptor(fmi->descriptor->text,
2029 utf_end(fmi->descriptor));
2031 case CONSTANT_InterfaceMethodref:
2032 case CONSTANT_Methodref: /* check validity of descriptor */
2033 checkmethoddescriptor(c, fmi->descriptor);
2037 nff = forward_fieldmethints;
2038 forward_fieldmethints = forward_fieldmethints->next;
2039 FREE(nff, forward_fieldmethint);
2042 /* everything was ok */
2048 /********************** Function: class_load ***********************************
2050 Loads everything interesting about a class from the class file. The
2051 'classinfo' structure must have been allocated previously.
2053 The super class and the interfaces implemented by this class need not be
2054 loaded. The link is set later by the function 'class_link'.
2056 The loaded class is removed from the list 'unloadedclasses' and added to
2057 the list 'unlinkedclasses'.
2059 *******************************************************************************/
2061 classinfo *class_load_intern(classbuffer *cb);
2063 classinfo *class_load(classinfo *c)
2068 /* enter a monitor on the class */
2070 builtin_monitorenter((java_objectheader *) c);
2072 /* maybe the class is already loaded */
2074 builtin_monitorexit((java_objectheader *) c);
2081 if (getcompilingtime)
2082 compilingtime_stop();
2085 loadingtime_start();
2087 /* load classdata, throw exception on error */
2089 if ((cb = suck_start(c)) == NULL) {
2090 /* this means, the classpath was not set properly */
2091 if (c->name == utf_java_lang_Object)
2092 throw_cacao_exception_exit(string_java_lang_NoClassDefFoundError,
2093 "java/lang/Object");
2096 new_exception_utfmessage(string_java_lang_NoClassDefFoundError,
2099 builtin_monitorexit((java_objectheader *) c);
2104 /* call the internal function */
2105 r = class_load_intern(cb);
2107 /* if return value is NULL, we had a problem and the class is not loaded */
2111 /* now free the allocated memory, otherwise we could ran into a DOS */
2123 if (getcompilingtime)
2124 compilingtime_start();
2126 /* leave the monitor */
2128 builtin_monitorexit((java_objectheader *) c);
2134 classinfo *class_load_intern(classbuffer *cb)
2140 char msg[MAXLOGTEXT]; /* maybe we get an exception */
2142 /* get the classbuffer's class */
2145 /* maybe the class is already loaded */
2149 #if defined(STATISTICS)
2151 count_class_loads++;
2154 /* output for debugging purposes */
2156 log_message_class("Loading class: ", c);
2158 /* class is somewhat loaded */
2161 if (!check_classbuffer_size(cb, 4 + 2 + 2))
2164 /* check signature */
2165 if (suck_u4(cb) != MAGIC) {
2166 *exceptionptr = new_classformaterror(c, "Bad magic number");
2175 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
2177 new_unsupportedclassversionerror(c,
2178 "Unsupported major.minor version %d.%d",
2184 /* load the constant pool */
2185 if (!class_loadcpool(cb, c))
2189 c->erroneous_state = 0;
2190 c->initializing_thread = 0;
2192 c->classUsed = NOTUSED; /* not used initially CO-RT */
2196 if (!check_classbuffer_size(cb, 2))
2199 c->flags = suck_u2(cb);
2200 /*if (!(c->flags & ACC_PUBLIC)) { log_text("CLASS NOT PUBLIC"); } JOWENN*/
2202 /* check ACC flags consistency */
2203 if (c->flags & ACC_INTERFACE) {
2204 if (!(c->flags & ACC_ABSTRACT)) {
2205 /* We work around this because interfaces in JDK 1.1 are
2206 * not declared abstract. */
2208 c->flags |= ACC_ABSTRACT;
2209 /* panic("Interface class not declared abstract"); */
2212 if (c->flags & ACC_FINAL) {
2214 new_classformaterror(c,
2215 "Illegal class modifiers: 0x%X", c->flags);
2220 if (c->flags & ACC_SUPER) {
2221 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
2225 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
2227 new_classformaterror(c, "Illegal class modifiers: 0x%X", c->flags);
2232 if (!check_classbuffer_size(cb, 2 + 2))
2237 if (!(tc = class_getconstant(c, i, CONSTANT_Class)))
2241 utf_sprint(msg, c->name);
2242 sprintf(msg + strlen(msg), " (wrong name: ");
2243 utf_sprint(msg + strlen(msg), tc->name);
2244 sprintf(msg + strlen(msg), ")");
2247 new_exception_message(string_java_lang_NoClassDefFoundError, msg);
2252 /* retrieve superclass */
2253 if ((i = suck_u2(cb))) {
2254 if (!(c->super = class_getconstant(c, i, CONSTANT_Class)))
2257 /* java.lang.Object may not have a super class. */
2258 if (c->name == utf_java_lang_Object) {
2260 new_exception_message(string_java_lang_ClassFormatError,
2261 "java.lang.Object with superclass");
2266 /* Interfaces must have java.lang.Object as super class. */
2267 if ((c->flags & ACC_INTERFACE) &&
2268 c->super->name != utf_java_lang_Object) {
2270 new_exception_message(string_java_lang_ClassFormatError,
2271 "Interfaces must have java.lang.Object as superclass");
2279 /* This is only allowed for java.lang.Object. */
2280 if (c->name != utf_java_lang_Object) {
2281 *exceptionptr = new_classformaterror(c, "Bad superclass index");
2287 /* retrieve interfaces */
2288 if (!check_classbuffer_size(cb, 2))
2291 c->interfacescount = suck_u2(cb);
2293 if (!check_classbuffer_size(cb, 2 * c->interfacescount))
2296 c->interfaces = MNEW(classinfo*, c->interfacescount);
2297 for (i = 0; i < c->interfacescount; i++) {
2298 if (!(c->interfaces[i] = class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2303 if (!check_classbuffer_size(cb, 2))
2306 c->fieldscount = suck_u2(cb);
2307 c->fields = GCNEW(fieldinfo, c->fieldscount);
2308 /* c->fields = MNEW(fieldinfo, c->fieldscount); */
2309 for (i = 0; i < c->fieldscount; i++) {
2310 if (!field_load(cb, c, &(c->fields[i])))
2315 if (!check_classbuffer_size(cb, 2))
2318 c->methodscount = suck_u2(cb);
2319 c->methods = GCNEW(methodinfo, c->methodscount);
2320 /* c->methods = MNEW(methodinfo, c->methodscount); */
2321 for (i = 0; i < c->methodscount; i++) {
2322 if (!method_load(cb, c, &(c->methods[i])))
2326 /* Check if all fields and methods can be uniquely
2327 * identified by (name,descriptor). */
2329 /* We use a hash table here to avoid making the
2330 * average case quadratic in # of methods, fields.
2332 static int shift = 0;
2334 u2 *next; /* for chaining colliding hash entries */
2340 /* Allocate hashtable */
2341 len = c->methodscount;
2342 if (len < c->fieldscount) len = c->fieldscount;
2344 hashtab = MNEW(u2,(hashlen + len));
2345 next = hashtab + hashlen;
2347 /* Determine bitshift (to get good hash values) */
2357 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2359 for (i = 0; i < c->fieldscount; ++i) {
2360 fieldinfo *fi = c->fields + i;
2362 /* It's ok if we lose bits here */
2363 index = ((((size_t) fi->name) +
2364 ((size_t) fi->descriptor)) >> shift) % hashlen;
2366 if ((old = hashtab[index])) {
2370 if (c->fields[old].name == fi->name &&
2371 c->fields[old].descriptor == fi->descriptor) {
2373 new_classformaterror(c,
2374 "Repetitive field name/signature");
2378 } while ((old = next[old]));
2380 hashtab[index] = i + 1;
2384 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2386 for (i = 0; i < c->methodscount; ++i) {
2387 methodinfo *mi = c->methods + i;
2389 /* It's ok if we lose bits here */
2390 index = ((((size_t) mi->name) +
2391 ((size_t) mi->descriptor)) >> shift) % hashlen;
2395 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2396 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2400 if ((old = hashtab[index])) {
2404 if (c->methods[old].name == mi->name &&
2405 c->methods[old].descriptor == mi->descriptor) {
2407 new_classformaterror(c,
2408 "Repetitive method name/signature");
2412 } while ((old = next[old]));
2414 hashtab[index] = i + 1;
2417 MFREE(hashtab, u2, (hashlen + len));
2420 #if defined(STATISTICS)
2422 count_class_infos += sizeof(classinfo*) * c->interfacescount;
2423 count_class_infos += sizeof(fieldinfo) * c->fieldscount;
2424 count_class_infos += sizeof(methodinfo) * c->methodscount;
2428 /* load attribute structures */
2429 if (!check_classbuffer_size(cb, 2))
2432 if (!attribute_load(cb, c, suck_u2(cb)))
2436 /* Pre java 1.5 version don't check this. This implementation is like
2437 java 1.5 do it: for class file version 45.3 we don't check it, older
2438 versions are checked.
2440 if ((ma == 45 && mi > 3) || ma > 45) {
2441 /* check if all data has been read */
2442 s4 classdata_left = ((cb->data + cb->size) - cb->pos - 1);
2444 if (classdata_left > 0) {
2446 new_classformaterror(c, "Extra bytes at the end of class file");
2453 log_message_class("Loading done class: ", c);
2460 /************** internal Function: class_highestinterface **********************
2462 Used by the function class_link to determine the amount of memory needed
2463 for the interface table.
2465 *******************************************************************************/
2467 static s4 class_highestinterface(classinfo *c)
2472 /* check for ACC_INTERFACE bit already done in class_link_intern */
2475 for (i = 0; i < c->interfacescount; i++) {
2476 s4 h2 = class_highestinterface(c->interfaces[i]);
2484 /* class_addinterface **********************************************************
2486 Is needed by class_link for adding a VTBL to a class. All interfaces
2487 implemented by ic are added as well.
2489 *******************************************************************************/
2491 static void class_addinterface(classinfo *c, classinfo *ic)
2495 vftbl_t *v = c->vftbl;
2497 if (i >= v->interfacetablelength)
2498 panic ("Inernal error: interfacetable overflow");
2500 if (v->interfacetable[-i])
2503 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
2504 v->interfacevftbllength[i] = 1;
2505 v->interfacetable[-i] = MNEW(methodptr, 1);
2506 v->interfacetable[-i][0] = NULL;
2509 v->interfacevftbllength[i] = ic->methodscount;
2510 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
2512 #if defined(STATISTICS)
2514 count_vftbl_len += sizeof(methodptr) *
2515 (ic->methodscount + (ic->methodscount == 0));
2518 for (j = 0; j < ic->methodscount; j++) {
2521 for (m = 0; m < sc->methodscount; m++) {
2522 methodinfo *mi = &(sc->methods[m]);
2523 if (method_canoverwrite(mi, &(ic->methods[j]))) {
2524 v->interfacetable[-i][j] = v->table[mi->vftblindex];
2535 for (j = 0; j < ic->interfacescount; j++)
2536 class_addinterface(c, ic->interfaces[j]);
2540 /******************* Function: class_new_array *********************************
2542 This function is called by class_new to setup an array class.
2544 *******************************************************************************/
2546 void class_new_array(classinfo *c)
2548 classinfo *comp = NULL;
2552 /* Check array class name */
2553 namelen = c->name->blength;
2554 if (namelen < 2 || c->name->text[0] != '[')
2555 panic("Invalid array class name");
2557 /* Check the component type */
2558 switch (c->name->text[1]) {
2560 /* c is an array of arrays. We have to create the component class. */
2562 comp = class_new_intern(utf_new_intern(c->name->text + 1,
2565 list_addfirst(&unlinkedclasses, comp);
2568 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2573 /* c is an array of objects. */
2574 if (namelen < 4 || c->name->text[namelen - 1] != ';')
2575 panic("Invalid array class name");
2578 comp = class_new_intern(utf_new_intern(c->name->text + 2,
2581 list_addfirst(&unlinkedclasses, comp);
2584 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2589 /* Setup the array class */
2590 c->super = class_java_lang_Object;
2591 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2593 c->interfacescount = 2;
2594 c->interfaces = MNEW(classinfo*, 2);
2599 tc = class_new_intern(utf_new_char("java/lang/Cloneable"));
2601 list_addfirst(&unlinkedclasses, tc);
2602 c->interfaces[0] = tc;
2604 tc = class_new_intern(utf_new_char("java/io/Serializable"));
2606 list_addfirst(&unlinkedclasses, tc);
2607 c->interfaces[1] = tc;
2610 c->interfaces[0] = class_new(utf_new_char("java/lang/Cloneable"));
2611 c->interfaces[1] = class_new(utf_new_char("java/io/Serializable"));
2614 c->methodscount = 1;
2615 c->methods = MNEW(methodinfo, c->methodscount);
2618 memset(clone, 0, sizeof(methodinfo));
2619 clone->flags = ACC_PUBLIC;
2620 clone->name = utf_new_char("clone");
2621 clone->descriptor = utf_new_char("()Ljava/lang/Object;");
2623 clone->stubroutine = createnativestub((functionptr) &builtin_clone_array, clone);
2624 clone->monoPoly = MONO;
2626 /* XXX: field: length? */
2628 /* array classes are not loaded from class files */
2633 /****************** Function: class_link_array *********************************
2635 This function is called by class_link to create the
2636 arraydescriptor for an array class.
2638 This function returns NULL if the array cannot be linked because
2639 the component type has not been linked yet.
2641 *******************************************************************************/
2643 static arraydescriptor *class_link_array(classinfo *c)
2645 classinfo *comp = NULL;
2646 s4 namelen = c->name->blength;
2647 arraydescriptor *desc;
2650 /* Check the component type */
2651 switch (c->name->text[1]) {
2653 /* c is an array of arrays. */
2654 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2656 panic("Could not find component array class.");
2660 /* c is an array of objects. */
2661 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2663 panic("Could not find component class.");
2667 /* If the component type has not been linked, link it now */
2668 if (comp && !comp->linked) {
2670 if (!class_load(comp))
2673 if (!class_link(comp))
2677 /* Allocate the arraydescriptor */
2678 desc = NEW(arraydescriptor);
2681 /* c is an array of references */
2682 desc->arraytype = ARRAYTYPE_OBJECT;
2683 desc->componentsize = sizeof(void*);
2684 desc->dataoffset = OFFSET(java_objectarray, data);
2686 compvftbl = comp->vftbl;
2688 panic("Component class has no vftbl");
2689 desc->componentvftbl = compvftbl;
2691 if (compvftbl->arraydesc) {
2692 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
2693 if (compvftbl->arraydesc->dimension >= 255)
2694 panic("Creating array of dimension >255");
2695 desc->dimension = compvftbl->arraydesc->dimension + 1;
2696 desc->elementtype = compvftbl->arraydesc->elementtype;
2699 desc->elementvftbl = compvftbl;
2700 desc->dimension = 1;
2701 desc->elementtype = ARRAYTYPE_OBJECT;
2705 /* c is an array of a primitive type */
2706 switch (c->name->text[1]) {
2708 desc->arraytype = ARRAYTYPE_BOOLEAN;
2709 desc->dataoffset = OFFSET(java_booleanarray,data);
2710 desc->componentsize = sizeof(u1);
2714 desc->arraytype = ARRAYTYPE_BYTE;
2715 desc->dataoffset = OFFSET(java_bytearray,data);
2716 desc->componentsize = sizeof(u1);
2720 desc->arraytype = ARRAYTYPE_CHAR;
2721 desc->dataoffset = OFFSET(java_chararray,data);
2722 desc->componentsize = sizeof(u2);
2726 desc->arraytype = ARRAYTYPE_DOUBLE;
2727 desc->dataoffset = OFFSET(java_doublearray,data);
2728 desc->componentsize = sizeof(double);
2732 desc->arraytype = ARRAYTYPE_FLOAT;
2733 desc->dataoffset = OFFSET(java_floatarray,data);
2734 desc->componentsize = sizeof(float);
2738 desc->arraytype = ARRAYTYPE_INT;
2739 desc->dataoffset = OFFSET(java_intarray,data);
2740 desc->componentsize = sizeof(s4);
2744 desc->arraytype = ARRAYTYPE_LONG;
2745 desc->dataoffset = OFFSET(java_longarray,data);
2746 desc->componentsize = sizeof(s8);
2750 desc->arraytype = ARRAYTYPE_SHORT;
2751 desc->dataoffset = OFFSET(java_shortarray,data);
2752 desc->componentsize = sizeof(s2);
2756 panic("Invalid array class name");
2759 desc->componentvftbl = NULL;
2760 desc->elementvftbl = NULL;
2761 desc->dimension = 1;
2762 desc->elementtype = desc->arraytype;
2769 /********************** Function: class_link ***********************************
2771 Tries to link a class. The function calculates the length in bytes that
2772 an instance of this class requires as well as the VTBL for methods and
2775 *******************************************************************************/
2777 static classinfo *class_link_intern(classinfo *c);
2779 classinfo *class_link(classinfo *c)
2783 /* enter a monitor on the class */
2785 builtin_monitorenter((java_objectheader *) c);
2787 /* maybe the class is already linked */
2789 builtin_monitorexit((java_objectheader *) c);
2796 if (getcompilingtime)
2797 compilingtime_stop();
2800 loadingtime_start();
2802 /* call the internal function */
2803 r = class_link_intern(c);
2805 /* if return value is NULL, we had a problem and the class is not linked */
2814 if (getcompilingtime)
2815 compilingtime_start();
2817 /* leave the monitor */
2819 builtin_monitorexit((java_objectheader *) c);
2825 static classinfo *class_link_intern(classinfo *c)
2827 s4 supervftbllength; /* vftbllegnth of super class */
2828 s4 vftbllength; /* vftbllength of current class */
2829 s4 interfacetablelength; /* interface table length */
2830 classinfo *super; /* super class */
2831 classinfo *tc; /* temporary class variable */
2832 vftbl_t *v; /* vftbl of current class */
2833 s4 i; /* interface/method/field counter */
2834 arraydescriptor *arraydesc; /* descriptor for array classes */
2836 /* maybe the class is already linked */
2840 /* maybe the class is not loaded */
2846 log_message_class("Linking class: ", c);
2848 /* ok, this class is somewhat linked */
2853 /* check interfaces */
2855 for (i = 0; i < c->interfacescount; i++) {
2856 tc = c->interfaces[i];
2858 /* detect circularity */
2861 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2867 if (!class_load(tc))
2870 if (!(tc->flags & ACC_INTERFACE)) {
2872 new_exception_message(string_java_lang_IncompatibleClassChangeError,
2873 "Implementing class");
2878 if (!class_link(tc))
2882 /* check super class */
2886 if (super == NULL) { /* class java.lang.Object */
2888 c->classUsed = USED; /* Object class is always used CO-RT*/
2890 c->instancesize = sizeof(java_objectheader);
2892 vftbllength = supervftbllength = 0;
2894 c->finalizer = NULL;
2897 /* detect circularity */
2900 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2906 if (!class_load(super))
2909 if (super->flags & ACC_INTERFACE) {
2910 /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
2911 panic("Interface specified as super class");
2914 /* Don't allow extending final classes */
2915 if (super->flags & ACC_FINAL) {
2917 new_exception_message(string_java_lang_VerifyError,
2918 "Cannot inherit from final class");
2923 if (!class_link(super))
2926 /* handle array classes */
2927 if (c->name->text[0] == '[')
2928 if (!(arraydesc = class_link_array(c)))
2931 if (c->flags & ACC_INTERFACE)
2932 c->index = interfaceindex++;
2934 c->index = super->index + 1;
2936 c->instancesize = super->instancesize;
2938 vftbllength = supervftbllength = super->vftbl->vftbllength;
2940 c->finalizer = super->finalizer;
2943 /* compute vftbl length */
2945 for (i = 0; i < c->methodscount; i++) {
2946 methodinfo *m = &(c->methods[i]);
2948 if (!(m->flags & ACC_STATIC)) { /* is instance method */
2953 for (j = 0; j < tc->methodscount; j++) {
2954 if (method_canoverwrite(m, &(tc->methods[j]))) {
2955 if (tc->methods[j].flags & ACC_PRIVATE)
2956 goto notfoundvftblindex;
2958 if (tc->methods[j].flags & ACC_FINAL) {
2959 /* class a overrides final method . */
2961 new_exception(string_java_lang_VerifyError);
2964 m->vftblindex = tc->methods[j].vftblindex;
2965 goto foundvftblindex;
2971 m->vftblindex = (vftbllength++);
2977 #if defined(STATISTICS)
2980 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
2983 /* compute interfacetable length */
2985 interfacetablelength = 0;
2988 for (i = 0; i < tc->interfacescount; i++) {
2989 s4 h = class_highestinterface(tc->interfaces[i]) + 1;
2990 if (h > interfacetablelength)
2991 interfacetablelength = h;
2996 /* allocate virtual function table */
2998 v = (vftbl_t*) mem_alloc(sizeof(vftbl_t) + sizeof(methodptr) *
2999 (vftbllength - 1) + sizeof(methodptr*) *
3000 (interfacetablelength - (interfacetablelength > 0)));
3001 v = (vftbl_t*) (((methodptr*) v) + (interfacetablelength - 1) *
3002 (interfacetablelength > 1));
3003 c->header.vftbl = c->vftbl = v;
3005 v->vftbllength = vftbllength;
3006 v->interfacetablelength = interfacetablelength;
3007 v->arraydesc = arraydesc;
3009 /* store interface index in vftbl */
3010 if (c->flags & ACC_INTERFACE)
3011 v->baseval = -(c->index);
3013 /* copy virtual function table of super class */
3015 for (i = 0; i < supervftbllength; i++)
3016 v->table[i] = super->vftbl->table[i];
3018 /* add method stubs into virtual function table */
3020 for (i = 0; i < c->methodscount; i++) {
3021 methodinfo *m = &(c->methods[i]);
3022 if (!(m->flags & ACC_STATIC)) {
3023 v->table[m->vftblindex] = m->stubroutine;
3027 /* compute instance size and offset of each field */
3029 for (i = 0; i < c->fieldscount; i++) {
3031 fieldinfo *f = &(c->fields[i]);
3033 if (!(f->flags & ACC_STATIC)) {
3034 dsize = desc_typesize(f->descriptor);
3035 c->instancesize = ALIGN(c->instancesize, dsize);
3036 f->offset = c->instancesize;
3037 c->instancesize += dsize;
3041 /* initialize interfacetable and interfacevftbllength */
3043 v->interfacevftbllength = MNEW(s4, interfacetablelength);
3045 #if defined(STATISTICS)
3047 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
3050 for (i = 0; i < interfacetablelength; i++) {
3051 v->interfacevftbllength[i] = 0;
3052 v->interfacetable[-i] = NULL;
3055 /* add interfaces */
3057 for (tc = c; tc != NULL; tc = tc->super) {
3058 for (i = 0; i < tc->interfacescount; i++) {
3059 class_addinterface(c, tc->interfaces[i]);
3063 /* add finalizer method (not for java.lang.Object) */
3068 fi = class_findmethod(c, utf_finalize, utf_fidesc);
3071 if (!(fi->flags & ACC_STATIC)) {
3079 loader_compute_subclasses(c);
3082 log_message_class("Linking done class: ", c);
3084 /* just return c to show that we didn't had a problem */
3090 /******************* Function: class_freepool **********************************
3092 Frees all resources used by this classes Constant Pool.
3094 *******************************************************************************/
3096 static void class_freecpool(classinfo *c)
3102 if (c->cptags && c->cpinfos) {
3103 for (idx = 0; idx < c->cpcount; idx++) {
3104 tag = c->cptags[idx];
3105 info = c->cpinfos[idx];
3109 case CONSTANT_Fieldref:
3110 case CONSTANT_Methodref:
3111 case CONSTANT_InterfaceMethodref:
3112 FREE(info, constant_FMIref);
3114 case CONSTANT_Integer:
3115 FREE(info, constant_integer);
3117 case CONSTANT_Float:
3118 FREE(info, constant_float);
3121 FREE(info, constant_long);
3123 case CONSTANT_Double:
3124 FREE(info, constant_double);
3126 case CONSTANT_NameAndType:
3127 FREE(info, constant_nameandtype);
3135 MFREE(c->cptags, u1, c->cpcount);
3138 MFREE(c->cpinfos, voidptr, c->cpcount);
3142 /*********************** Function: class_free **********************************
3144 Frees all resources used by the class.
3146 *******************************************************************************/
3148 void class_free(classinfo *c)
3156 MFREE(c->interfaces, classinfo*, c->interfacescount);
3159 for (i = 0; i < c->fieldscount; i++)
3160 field_free(&(c->fields[i]));
3161 /* MFREE(c->fields, fieldinfo, c->fieldscount); */
3165 for (i = 0; i < c->methodscount; i++)
3166 method_free(&(c->methods[i]));
3167 /* MFREE(c->methods, methodinfo, c->methodscount); */
3170 if ((v = c->vftbl) != NULL) {
3172 mem_free(v->arraydesc,sizeof(arraydescriptor));
3174 for (i = 0; i < v->interfacetablelength; i++) {
3175 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
3177 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
3179 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
3180 sizeof(methodptr*) * (v->interfacetablelength -
3181 (v->interfacetablelength > 0));
3182 v = (vftbl_t*) (((methodptr*) v) - (v->interfacetablelength - 1) *
3183 (v->interfacetablelength > 1));
3188 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
3190 /* if (c->classvftbl)
3191 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
3197 /************************* Function: class_findfield ***************************
3199 Searches a 'classinfo' structure for a field having the given name and
3202 *******************************************************************************/
3204 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
3208 for (i = 0; i < c->fieldscount; i++) {
3209 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
3210 return &(c->fields[i]);
3213 panic("Can not find field given in CONSTANT_Fieldref");
3215 /* keep compiler happy */
3220 /****************** Function: class_resolvefield_int ***************************
3222 This is an internally used helper function. Do not use this directly.
3224 Tries to resolve a field having the given name and type.
3225 If the field cannot be resolved, NULL is returned.
3227 *******************************************************************************/
3229 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
3234 /* search for field in class c */
3235 for (i = 0; i < c->fieldscount; i++) {
3236 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
3237 return &(c->fields[i]);
3241 /* try superinterfaces recursively */
3242 for (i = 0; i < c->interfacescount; ++i) {
3243 fi = class_resolvefield_int(c->interfaces[i], name, desc);
3248 /* try superclass */
3250 return class_resolvefield_int(c->super, name, desc);
3257 /********************* Function: class_resolvefield ***************************
3259 Resolves a reference from REFERER to a field with NAME and DESC in class C.
3261 If the field cannot be resolved the return value is NULL. If EXCEPT is
3262 true *exceptionptr is set, too.
3264 *******************************************************************************/
3266 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
3267 classinfo *referer, bool except)
3271 /* XXX resolve class c */
3272 /* XXX check access from REFERER to C */
3274 fi = class_resolvefield_int(c, name, desc);
3279 new_exception_utfmessage(string_java_lang_NoSuchFieldError,
3285 /* XXX check access rights */
3291 /************************* Function: class_findmethod **************************
3293 Searches a 'classinfo' structure for a method having the given name and
3294 type and returns the index in the class info structure.
3295 If type is NULL, it is ignored.
3297 *******************************************************************************/
3299 s4 class_findmethodIndex(classinfo *c, utf *name, utf *desc)
3303 for (i = 0; i < c->methodscount; i++) {
3305 /* utf_display_classname(c->name);printf("."); */
3306 /* utf_display(c->methods[i].name);printf("."); */
3307 /* utf_display(c->methods[i].descriptor); */
3310 if ((c->methods[i].name == name) && ((desc == NULL) ||
3311 (c->methods[i].descriptor == desc))) {
3320 /************************* Function: class_findmethod **************************
3322 Searches a 'classinfo' structure for a method having the given name and
3324 If type is NULL, it is ignored.
3326 *******************************************************************************/
3328 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
3330 s4 idx = class_findmethodIndex(c, name, desc);
3335 return &(c->methods[idx]);
3339 /*********************** Function: class_fetchmethod **************************
3341 like class_findmethod, but aborts with an error if the method is not found
3343 *******************************************************************************/
3345 methodinfo *class_fetchmethod(classinfo *c, utf *name, utf *desc)
3349 mi = class_findmethod(c, name, desc);
3352 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3353 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3354 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3355 panic("Method not found");
3362 /*********************** Function: class_findmethod_w**************************
3364 like class_findmethod, but logs a warning if the method is not found
3366 *******************************************************************************/
3368 methodinfo *class_findmethod_w(classinfo *c, utf *name, utf *desc, char *from)
3371 mi = class_findmethod(c, name, desc);
3374 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3375 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3376 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3378 if ( c->flags & ACC_PUBLIC ) log_plain(" PUBLIC ");
3379 if ( c->flags & ACC_PRIVATE ) log_plain(" PRIVATE ");
3380 if ( c->flags & ACC_PROTECTED ) log_plain(" PROTECTED ");
3381 if ( c->flags & ACC_STATIC ) log_plain(" STATIC ");
3382 if ( c->flags & ACC_FINAL ) log_plain(" FINAL ");
3383 if ( c->flags & ACC_SYNCHRONIZED ) log_plain(" SYNCHRONIZED ");
3384 if ( c->flags & ACC_VOLATILE ) log_plain(" VOLATILE ");
3385 if ( c->flags & ACC_TRANSIENT ) log_plain(" TRANSIENT ");
3386 if ( c->flags & ACC_NATIVE ) log_plain(" NATIVE ");
3387 if ( c->flags & ACC_INTERFACE ) log_plain(" INTERFACE ");
3388 if ( c->flags & ACC_ABSTRACT ) log_plain(" ABSTRACT ");
3391 log_plain(" : WARNING: Method not found");log_nl( );
3398 /************************* Function: class_findmethod_approx ******************
3400 like class_findmethod but ignores the return value when comparing the
3403 *******************************************************************************/
3405 methodinfo *class_findmethod_approx(classinfo *c, utf *name, utf *desc)
3409 for (i = 0; i < c->methodscount; i++) {
3410 if (c->methods[i].name == name) {
3411 utf *meth_descr = c->methods[i].descriptor;
3415 return &(c->methods[i]);
3417 if (desc->blength <= meth_descr->blength) {
3418 /* current position in utf text */
3419 char *desc_utf_ptr = desc->text;
3420 char *meth_utf_ptr = meth_descr->text;
3421 /* points behind utf strings */
3422 char *desc_end = utf_end(desc);
3423 char *meth_end = utf_end(meth_descr);
3426 /* compare argument types */
3427 while (desc_utf_ptr < desc_end && meth_utf_ptr < meth_end) {
3429 if ((ch = *desc_utf_ptr++) != (*meth_utf_ptr++))
3430 break; /* no match */
3433 return &(c->methods[i]); /* all parameter types equal */
3443 /***************** Function: class_resolvemethod_approx ***********************
3445 Searches a class and every super class for a method (without paying
3446 attention to the return value)
3448 *******************************************************************************/
3450 methodinfo *class_resolvemethod_approx(classinfo *c, utf *name, utf *desc)
3453 /* search for method (ignore returntype) */
3454 methodinfo *m = class_findmethod_approx(c, name, desc);
3457 /* search superclass */
3465 /************************* Function: class_resolvemethod ***********************
3467 Searches a class and every super class for a method.
3469 *******************************************************************************/
3471 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
3473 /*log_text("Trying to resolve a method");
3474 utf_display(c->name);
3476 utf_display(desc);*/
3479 /*log_text("Looking in:");
3480 utf_display(c->name);*/
3481 methodinfo *m = class_findmethod(c, name, desc);
3483 /* search superclass */
3486 /*log_text("method not found:");*/
3492 /****************** Function: class_resolveinterfacemethod_int ****************
3494 Internally used helper function. Do not use this directly.
3496 *******************************************************************************/
3499 methodinfo *class_resolveinterfacemethod_int(classinfo *c, utf *name, utf *desc)
3504 mi = class_findmethod(c,name,desc);
3508 /* try the superinterfaces */
3509 for (i=0; i<c->interfacescount; ++i) {
3510 mi = class_resolveinterfacemethod_int(c->interfaces[i],name,desc);
3518 /******************** Function: class_resolveinterfacemethod ******************
3520 Resolves a reference from REFERER to a method with NAME and DESC in
3523 If the method cannot be resolved the return value is NULL. If EXCEPT is
3524 true *exceptionptr is set, too.
3526 *******************************************************************************/
3528 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
3529 classinfo *referer, bool except)
3533 /* XXX resolve class c */
3534 /* XXX check access from REFERER to C */
3536 if (!(c->flags & ACC_INTERFACE)) {
3539 new_exception(string_java_lang_IncompatibleClassChangeError);
3544 mi = class_resolveinterfacemethod_int(c, name, desc);
3549 /* try class java.lang.Object */
3550 mi = class_findmethod(class_java_lang_Object, name, desc);
3557 new_exception_utfmessage(string_java_lang_NoSuchMethodError, name);
3563 /********************* Function: class_resolveclassmethod *********************
3565 Resolves a reference from REFERER to a method with NAME and DESC in
3568 If the method cannot be resolved the return value is NULL. If EXCEPT is
3569 true *exceptionptr is set, too.
3571 *******************************************************************************/
3573 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
3574 classinfo *referer, bool except)
3579 char msg[MAXLOGTEXT];
3581 /* XXX resolve class c */
3582 /* XXX check access from REFERER to C */
3584 /* if (c->flags & ACC_INTERFACE) { */
3586 /* *exceptionptr = */
3587 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
3591 /* try class c and its superclasses */
3594 mi = class_findmethod(cls, name, desc);
3597 } while ((cls = cls->super) != NULL); /* try the superclass */
3599 /* try the superinterfaces */
3600 for (i = 0; i < c->interfacescount; ++i) {
3601 mi = class_resolveinterfacemethod_int(c->interfaces[i], name, desc);
3607 utf_sprint(msg, c->name);
3608 sprintf(msg + strlen(msg), ".");
3609 utf_sprint(msg + strlen(msg), name);
3610 utf_sprint(msg + strlen(msg), desc);
3613 new_exception_message(string_java_lang_NoSuchMethodError, msg);
3619 if ((mi->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
3621 *exceptionptr = new_exception(string_java_lang_AbstractMethodError);
3626 /* XXX check access rights */
3632 /************************* Function: class_issubclass **************************
3634 Checks if sub is a descendant of super.
3636 *******************************************************************************/
3638 bool class_issubclass(classinfo *sub, classinfo *super)
3641 if (!sub) return false;
3642 if (sub == super) return true;
3648 /****************** Initialization function for classes ******************
3650 In Java, every class can have a static initialization function. This
3651 function has to be called BEFORE calling other methods or accessing static
3654 *******************************************************************************/
3656 static classinfo *class_init_intern(classinfo *c);
3658 classinfo *class_init(classinfo *c)
3662 if (!makeinitializations)
3665 /* enter a monitor on the class */
3667 builtin_monitorenter((java_objectheader *) c);
3669 /* maybe the class is already initalized or the current thread, which can
3670 pass the monitor, is currently initalizing this class */
3672 if (c->initialized || c->initializing) {
3673 builtin_monitorexit((java_objectheader *) c);
3678 /* this initalizing run begins NOW */
3679 c->initializing = true;
3681 /* call the internal function */
3682 r = class_init_intern(c);
3684 /* if return value is not NULL everything was ok and the class is
3687 c->initialized = true;
3689 /* this initalizing run is done */
3690 c->initializing = false;
3692 /* leave the monitor */
3694 builtin_monitorexit((java_objectheader *) c);
3700 /* this function MUST NOT be called directly, because of thread <clinit>
3703 static classinfo *class_init_intern(classinfo *c)
3707 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3711 /* maybe the class is not already loaded */
3716 /* maybe the class is not already linked */
3721 #if defined(STATISTICS)
3723 count_class_inits++;
3726 /* initialize super class */
3729 if (!c->super->initialized) {
3731 char logtext[MAXLOGTEXT];
3732 sprintf(logtext, "Initialize super class ");
3733 utf_sprint_classname(logtext + strlen(logtext), c->super->name);
3734 sprintf(logtext + strlen(logtext), " from ");
3735 utf_sprint_classname(logtext + strlen(logtext), c->name);
3739 if (!class_init(c->super))
3744 /* initialize interface classes */
3746 for (i = 0; i < c->interfacescount; i++) {
3747 if (!c->interfaces[i]->initialized) {
3749 char logtext[MAXLOGTEXT];
3750 sprintf(logtext, "Initialize interface class ");
3751 utf_sprint_classname(logtext + strlen(logtext), c->interfaces[i]->name);
3752 sprintf(logtext + strlen(logtext), " from ");
3753 utf_sprint_classname(logtext + strlen(logtext), c->name);
3757 if (!class_init(c->interfaces[i]))
3762 m = class_findmethod(c, utf_clinit, utf_fidesc);
3766 char logtext[MAXLOGTEXT];
3767 sprintf(logtext, "Class ");
3768 utf_sprint_classname(logtext + strlen(logtext), c->name);
3769 sprintf(logtext + strlen(logtext), " has no static class initializer");
3776 /* Sun's and IBM's JVM don't care about the static flag */
3777 /* if (!(m->flags & ACC_STATIC)) { */
3778 /* panic("Class initializer is not static!"); */
3781 log_message_class("Starting static class initializer for class: ", c);
3783 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3788 /* now call the initializer */
3789 asm_calljavafunction(m, NULL, NULL, NULL, NULL);
3791 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3792 assert(blockInts == 0);
3796 /* we have an exception or error */
3797 if (*exceptionptr) {
3798 /* class is NOT initialized */
3799 c->initialized = false;
3801 /* is this an exception, than wrap it */
3802 if (builtin_instanceof(*exceptionptr, class_java_lang_Exception)) {
3803 java_objectheader *xptr;
3804 java_objectheader *cause;
3807 cause = *exceptionptr;
3809 /* clear exception, because we are calling jit code again */
3810 *exceptionptr = NULL;
3812 /* wrap the exception */
3814 new_exception_throwable(string_java_lang_ExceptionInInitializerError,
3815 (java_lang_Throwable *) cause);
3817 /* XXX should we exit here? */
3821 /* set new exception */
3822 *exceptionptr = xptr;
3829 log_message_class("Finished static class initializer for class: ", c);
3835 /********* Function: find_class_method_constant *********/
3837 int find_class_method_constant (classinfo *c, utf * c1, utf* m1, utf* d1)
3842 for (i=0; i<c->cpcount; i++) {
3844 e = c -> cpinfos [i];
3847 switch (c -> cptags [i]) {
3848 case CONSTANT_Methodref:
3850 constant_FMIref *fmi = e;
3851 if ( (fmi->class->name == c1)
3852 && (fmi->name == m1)
3853 && (fmi->descriptor == d1)) {
3860 case CONSTANT_InterfaceMethodref:
3862 constant_FMIref *fmi = e;
3863 if ( (fmi->class->name == c1)
3864 && (fmi->name == m1)
3865 && (fmi->descriptor == d1)) {
3879 void class_showconstanti(classinfo *c, int ii)
3885 printf ("#%d: ", (int) i);
3887 switch (c->cptags [i]) {
3888 case CONSTANT_Class:
3889 printf("Classreference -> ");
3890 utf_display(((classinfo*)e)->name);
3893 case CONSTANT_Fieldref:
3894 printf("Fieldref -> "); goto displayFMIi;
3895 case CONSTANT_Methodref:
3896 printf("Methodref -> "); goto displayFMIi;
3897 case CONSTANT_InterfaceMethodref:
3898 printf("InterfaceMethod -> "); goto displayFMIi;
3901 constant_FMIref *fmi = e;
3902 utf_display(fmi->class->name);
3904 utf_display(fmi->name);
3906 utf_display(fmi->descriptor);
3910 case CONSTANT_String:
3911 printf("String -> ");
3914 case CONSTANT_Integer:
3915 printf("Integer -> %d", (int) (((constant_integer*)e)->value));
3917 case CONSTANT_Float:
3918 printf("Float -> %f", ((constant_float*)e)->value);
3920 case CONSTANT_Double:
3921 printf("Double -> %f", ((constant_double*)e)->value);
3925 u8 v = ((constant_long*)e)->value;
3927 printf("Long -> %ld", (long int) v);
3929 printf("Long -> HI: %ld, LO: %ld\n",
3930 (long int) v.high, (long int) v.low);
3934 case CONSTANT_NameAndType:
3936 constant_nameandtype *cnt = e;
3937 printf("NameAndType: ");
3938 utf_display(cnt->name);
3940 utf_display(cnt->descriptor);
3948 panic("Invalid type of ConstantPool-Entry");
3955 void class_showconstantpool (classinfo *c)
3960 printf ("---- dump of constant pool ----\n");
3962 for (i=0; i<c->cpcount; i++) {
3963 printf ("#%d: ", (int) i);
3965 e = c -> cpinfos [i];
3968 switch (c -> cptags [i]) {
3969 case CONSTANT_Class:
3970 printf ("Classreference -> ");
3971 utf_display ( ((classinfo*)e) -> name );
3974 case CONSTANT_Fieldref:
3975 printf ("Fieldref -> "); goto displayFMI;
3976 case CONSTANT_Methodref:
3977 printf ("Methodref -> "); goto displayFMI;
3978 case CONSTANT_InterfaceMethodref:
3979 printf ("InterfaceMethod -> "); goto displayFMI;
3982 constant_FMIref *fmi = e;
3983 utf_display ( fmi->class->name );
3985 utf_display ( fmi->name);
3987 utf_display ( fmi->descriptor );
3991 case CONSTANT_String:
3992 printf ("String -> ");
3995 case CONSTANT_Integer:
3996 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
3998 case CONSTANT_Float:
3999 printf ("Float -> %f", ((constant_float*)e) -> value);
4001 case CONSTANT_Double:
4002 printf ("Double -> %f", ((constant_double*)e) -> value);
4006 u8 v = ((constant_long*)e) -> value;
4008 printf ("Long -> %ld", (long int) v);
4010 printf ("Long -> HI: %ld, LO: %ld\n",
4011 (long int) v.high, (long int) v.low);
4015 case CONSTANT_NameAndType:
4017 constant_nameandtype *cnt = e;
4018 printf ("NameAndType: ");
4019 utf_display (cnt->name);
4021 utf_display (cnt->descriptor);
4025 printf ("Utf8 -> ");
4029 panic ("Invalid type of ConstantPool-Entry");
4039 /********** Function: class_showmethods (debugging only) *************/
4041 void class_showmethods (classinfo *c)
4045 printf ("--------- Fields and Methods ----------------\n");
4046 printf ("Flags: "); printflags (c->flags); printf ("\n");
4048 printf ("This: "); utf_display (c->name); printf ("\n");
4050 printf ("Super: "); utf_display (c->super->name); printf ("\n");
4052 printf ("Index: %d\n", c->index);
4054 printf ("interfaces:\n");
4055 for (i=0; i < c-> interfacescount; i++) {
4057 utf_display (c -> interfaces[i] -> name);
4058 printf (" (%d)\n", c->interfaces[i] -> index);
4061 printf ("fields:\n");
4062 for (i=0; i < c -> fieldscount; i++) {
4063 field_display (&(c -> fields[i]));
4066 printf ("methods:\n");
4067 for (i=0; i < c -> methodscount; i++) {
4068 methodinfo *m = &(c->methods[i]);
4069 if ( !(m->flags & ACC_STATIC))
4070 printf ("vftblindex: %d ", m->vftblindex);
4072 method_display ( m );
4076 printf ("Virtual function table:\n");
4077 for (i=0; i<c->vftbl->vftbllength; i++) {
4078 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]) );
4084 /******************************************************************************/
4085 /******************* General functions for the class loader *******************/
4086 /******************************************************************************/
4088 /**************** function: create_primitive_classes ***************************
4090 create classes representing primitive types
4092 *******************************************************************************/
4094 static bool create_primitive_classes()
4098 for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
4099 /* create primitive class */
4101 class_new_intern(utf_new_char(primitivetype_table[i].name));
4102 c->classUsed = NOTUSED; /* not used initially CO-RT */
4105 /* prevent loader from loading primitive class */
4110 primitivetype_table[i].class_primitive = c;
4112 /* create class for wrapping the primitive type */
4113 c = class_new_intern(utf_new_char(primitivetype_table[i].wrapname));
4114 primitivetype_table[i].class_wrap = c;
4115 primitivetype_table[i].class_wrap->classUsed = NOTUSED; /* not used initially CO-RT */
4116 primitivetype_table[i].class_wrap->impldBy = NULL;
4118 /* create the primitive array class */
4119 if (primitivetype_table[i].arrayname) {
4120 c = class_new_intern(utf_new_char(primitivetype_table[i].arrayname));
4121 primitivetype_table[i].arrayclass = c;
4126 primitivetype_table[i].arrayvftbl = c->vftbl;
4134 /**************** function: class_primitive_from_sig ***************************
4136 return the primitive class indicated by the given signature character
4138 If the descriptor does not indicate a valid primitive type the
4139 return value is NULL.
4141 ********************************************************************************/
4143 classinfo *class_primitive_from_sig(char sig)
4146 case 'I': return primitivetype_table[PRIMITIVETYPE_INT].class_primitive;
4147 case 'J': return primitivetype_table[PRIMITIVETYPE_LONG].class_primitive;
4148 case 'F': return primitivetype_table[PRIMITIVETYPE_FLOAT].class_primitive;
4149 case 'D': return primitivetype_table[PRIMITIVETYPE_DOUBLE].class_primitive;
4150 case 'B': return primitivetype_table[PRIMITIVETYPE_BYTE].class_primitive;
4151 case 'C': return primitivetype_table[PRIMITIVETYPE_CHAR].class_primitive;
4152 case 'S': return primitivetype_table[PRIMITIVETYPE_SHORT].class_primitive;
4153 case 'Z': return primitivetype_table[PRIMITIVETYPE_BOOLEAN].class_primitive;
4154 case 'V': return primitivetype_table[PRIMITIVETYPE_VOID].class_primitive;
4159 /****************** function: class_from_descriptor ****************************
4161 return the class indicated by the given descriptor
4163 utf_ptr....first character of descriptor
4164 end_ptr....first character after the end of the string
4165 next.......if non-NULL, *next is set to the first character after
4166 the descriptor. (Undefined if an error occurs.)
4168 mode.......a combination (binary or) of the following flags:
4170 (Flags marked with * are the default settings.)
4172 What to do if a reference type descriptor is parsed successfully:
4174 CLASSLOAD_SKIP...skip it and return something != NULL
4175 * CLASSLOAD_NEW....get classinfo * via class_new
4176 CLASSLOAD_LOAD...get classinfo * via loader_load
4178 How to handle primitive types:
4180 * CLASSLOAD_PRIMITIVE.......return primitive class (eg. "int")
4181 CLASSLOAD_NULLPRIMITIVE...return NULL for primitive types
4183 How to handle "V" descriptors:
4185 * CLASSLOAD_VOID.....handle it like other primitive types
4186 CLASSLOAD_NOVOID...treat it as an error
4188 How to deal with extra characters after the end of the
4191 * CLASSLOAD_NOCHECKEND...ignore (useful for parameter lists)
4192 CLASSLOAD_CHECKEND.....treat them as an error
4194 How to deal with errors:
4196 * CLASSLOAD_PANIC....abort execution with an error message
4197 CLASSLOAD_NOPANIC..return NULL on error
4199 *******************************************************************************/
4201 classinfo *class_from_descriptor(char *utf_ptr, char *end_ptr,
4202 char **next, int mode)
4204 char *start = utf_ptr;
4208 SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr, end_ptr, error);
4210 if (mode & CLASSLOAD_CHECKEND)
4211 error |= (utf_ptr != end_ptr);
4214 if (next) *next = utf_ptr;
4218 if (mode & CLASSLOAD_NOVOID)
4229 return (mode & CLASSLOAD_NULLPRIMITIVE)
4231 : class_primitive_from_sig(*start);
4238 if (mode & CLASSLOAD_SKIP) return class_java_lang_Object;
4239 name = utf_new(start, utf_ptr - start);
4243 tc = class_new_intern(name);
4245 list_addfirst(&unlinkedclasses, tc);
4250 return (mode & CLASSLOAD_LOAD)
4251 ? class_load(class_new(name)) : class_new(name); /* XXX handle errors */
4256 /* An error occurred */
4257 if (mode & CLASSLOAD_NOPANIC)
4260 log_plain("Invalid descriptor at beginning of '");
4261 log_plain_utf(utf_new(start, end_ptr - start));
4265 panic("Invalid descriptor");
4267 /* keep compiler happy */
4272 /******************* function: type_from_descriptor ****************************
4274 return the basic type indicated by the given descriptor
4276 This function parses a descriptor and returns its basic type as
4277 TYPE_INT, TYPE_LONG, TYPE_FLOAT, TYPE_DOUBLE, TYPE_ADDRESS or TYPE_VOID.
4279 cls...if non-NULL the referenced variable is set to the classinfo *
4280 returned by class_from_descriptor.
4282 For documentation of the arguments utf_ptr, end_ptr, next and mode
4283 see class_from_descriptor. The only difference is that
4284 type_from_descriptor always uses CLASSLOAD_PANIC.
4286 ********************************************************************************/
4288 int type_from_descriptor(classinfo **cls, char *utf_ptr, char *end_ptr,
4289 char **next, int mode)
4292 if (!cls) cls = &mycls;
4293 *cls = class_from_descriptor(utf_ptr, end_ptr, next, mode & (~CLASSLOAD_NOPANIC));
4310 return TYPE_ADDRESS;
4314 /*************** function: create_pseudo_classes *******************************
4316 create pseudo classes used by the typechecker
4318 ********************************************************************************/
4320 static void create_pseudo_classes()
4322 /* pseudo class for Arraystubs (extends java.lang.Object) */
4324 pseudo_class_Arraystub = class_new_intern(utf_new_char("$ARRAYSTUB$"));
4325 pseudo_class_Arraystub->loaded = true;
4326 pseudo_class_Arraystub->super = class_java_lang_Object;
4327 pseudo_class_Arraystub->interfacescount = 2;
4328 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
4329 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
4330 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
4332 class_link(pseudo_class_Arraystub);
4334 pseudo_class_Arraystub_vftbl = pseudo_class_Arraystub->vftbl;
4336 /* pseudo class representing the null type */
4338 pseudo_class_Null = class_new_intern(utf_new_char("$NULL$"));
4339 pseudo_class_Null->loaded = true;
4340 pseudo_class_Null->super = class_java_lang_Object;
4341 class_link(pseudo_class_Null);
4343 /* pseudo class representing new uninitialized objects */
4345 pseudo_class_New = class_new_intern(utf_new_char("$NEW$"));
4346 pseudo_class_New->loaded = true;
4347 pseudo_class_New->linked = true;
4348 pseudo_class_New->super = class_java_lang_Object;
4349 /* class_link(pseudo_class_New); */
4353 /********************** Function: loader_init **********************************
4355 Initializes all lists and loads all classes required for the system or the
4358 *******************************************************************************/
4360 void loader_init(u1 *stackbottom)
4364 /* create utf-symbols for pointer comparison of frequently used strings */
4365 utf_innerclasses = utf_new_char("InnerClasses");
4366 utf_constantvalue = utf_new_char("ConstantValue");
4367 utf_code = utf_new_char("Code");
4368 utf_exceptions = utf_new_char("Exceptions");
4369 utf_linenumbertable = utf_new_char("LineNumberTable");
4370 utf_sourcefile = utf_new_char("SourceFile");
4371 utf_finalize = utf_new_char("finalize");
4372 utf_fidesc = utf_new_char("()V");
4373 utf_init = utf_new_char("<init>");
4374 utf_clinit = utf_new_char("<clinit>");
4375 utf_initsystemclass = utf_new_char("initializeSystemClass");
4376 utf_systemclass = utf_new_char("java/lang/System");
4377 utf_vmclassloader = utf_new_char("java/lang/VMClassLoader");
4378 utf_initialize = utf_new_char("initialize");
4379 utf_initializedesc = utf_new_char("(I)V");
4380 utf_vmclass = utf_new_char("java/lang/VMClass");
4381 utf_java_lang_Object= utf_new_char("java/lang/Object");
4382 array_packagename = utf_new_char("<the array package>");
4383 utf_fillInStackTrace_name = utf_new_char("fillInStackTrace");
4384 utf_fillInStackTrace_desc = utf_new_char("()Ljava/lang/Throwable;");
4386 /* create some important classes */
4387 /* These classes have to be created now because the classinfo
4388 * pointers are used in the loading code.
4390 class_java_lang_Object = class_new_intern(utf_java_lang_Object);
4391 class_load(class_java_lang_Object);
4392 class_link(class_java_lang_Object);
4394 class_java_lang_String = class_new(utf_new_char("java/lang/String"));
4395 class_load(class_java_lang_String);
4396 class_link(class_java_lang_String);
4398 class_java_lang_Cloneable = class_new(utf_new_char("java/lang/Cloneable"));
4399 class_load(class_java_lang_Cloneable);
4400 class_link(class_java_lang_Cloneable);
4402 class_java_io_Serializable =
4403 class_new(utf_new_char("java/io/Serializable"));
4404 class_load(class_java_io_Serializable);
4405 class_link(class_java_io_Serializable);
4407 /* create classes representing primitive types */
4408 create_primitive_classes();
4410 /* create classes used by the typechecker */
4411 create_pseudo_classes();
4413 /* correct vftbl-entries (retarded loading of class java/lang/String) */
4414 stringtable_update();
4416 #if defined(USE_THREADS)
4417 if (stackbottom != 0)
4423 /* loader_compute_subclasses ***************************************************
4427 *******************************************************************************/
4429 static void loader_compute_class_values(classinfo *c);
4431 void loader_compute_subclasses(classinfo *c)
4433 #if defined(USE_THREADS)
4434 #if defined(NATIVE_THREADS)
4441 if (!(c->flags & ACC_INTERFACE)) {
4446 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
4447 c->nextsub = c->super->sub;
4453 /* this is the java.lang.Object special case */
4455 if (!class_java_lang_Object) {
4456 loader_compute_class_values(c);
4459 loader_compute_class_values(class_java_lang_Object);
4462 #if defined(USE_THREADS)
4463 #if defined(NATIVE_THREADS)
4472 /* loader_compute_class_values *************************************************
4476 *******************************************************************************/
4478 static void loader_compute_class_values(classinfo *c)
4482 c->vftbl->baseval = ++classvalue;
4486 loader_compute_class_values(subs);
4487 subs = subs->nextsub;
4490 c->vftbl->diffval = classvalue - c->vftbl->baseval;
4494 /******************** Function: loader_close ***********************************
4498 *******************************************************************************/
4505 for (slot = 0; slot < class_hash.size; slot++) {
4506 c = class_hash.ptr[slot];
4517 * These are local overrides for various environment variables in Emacs.
4518 * Please do not remove this and leave it at the end of the file, where
4519 * Emacs will automagically detect them.
4520 * ---------------------------------------------------------------------
4523 * indent-tabs-mode: t