1 /* vm/loader.c - class loader functions
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
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 1896 2005-02-03 16:15:35Z motse $
45 #include "mm/memory.h"
46 #include "native/native.h"
47 #include "native/include/java_lang_Throwable.h"
49 #if defined(USE_THREADS)
50 # if defined(NATIVE_THREADS)
51 # include "threads/native/threads.h"
53 # include "threads/green/threads.h"
54 # include "threads/green/locks.h"
58 #include "toolbox/logging.h"
59 #include "vm/exceptions.h"
60 #include "vm/builtin.h"
61 #include "vm/global.h"
62 #include "vm/loader.h"
63 #include "vm/options.h"
64 #include "vm/statistics.h"
65 #include "vm/tables.h"
68 # include "vm/unzip.h"
71 #include "vm/jit/asmpart.h"
72 #include "vm/jit/jit.h"
79 /* global variables ***********************************************************/
81 static s4 interfaceindex; /* sequential numbering of interfaces */
85 /* utf-symbols for pointer comparison of frequently used strings */
87 static utf *utf_innerclasses; /* InnerClasses */
88 static utf *utf_constantvalue; /* ConstantValue */
89 static utf *utf_code; /* Code */
90 static utf *utf_exceptions; /* Exceptions */
91 static utf *utf_linenumbertable; /* LineNumberTable */
92 static utf *utf_sourcefile; /* SourceFile */
93 static utf *utf_finalize; /* finalize */
94 static utf *utf_fidesc; /* ()V changed */
95 static utf *utf_init; /* <init> */
96 static utf *utf_clinit; /* <clinit> */
97 static utf *utf_initsystemclass; /* initializeSystemClass */
98 static utf *utf_systemclass; /* java/lang/System */
99 static utf *utf_vmclassloader; /* java/lang/VMClassLoader */
100 static utf *utf_vmclass; /* java/lang/VMClassLoader */
101 static utf *utf_initialize;
102 static utf *utf_initializedesc;
103 static utf *utf_java_lang_Object; /* java/lang/Object */
105 utf *utf_fillInStackTrace_name;
106 utf *utf_fillInStackTrace_desc;
116 /* important system classes ***************************************************/
118 classinfo *class_java_lang_Object;
119 classinfo *class_java_lang_String;
120 classinfo *class_java_lang_Cloneable;
121 classinfo *class_java_io_Serializable;
123 /* Pseudo classes for the typechecker */
124 classinfo *pseudo_class_Arraystub = NULL;
125 classinfo *pseudo_class_Null = NULL;
126 classinfo *pseudo_class_New = NULL;
127 vftbl_t *pseudo_class_Arraystub_vftbl = NULL;
129 utf *array_packagename = NULL;
132 /********************************************************************
133 list of classpath entries (either filesystem directories or
135 ********************************************************************/
137 static classpath_info *classpath_entries = NULL;
140 /******************************************************************************
142 structure for primitive classes: contains the class for wrapping the
143 primitive type, the primitive class, the name of the class for wrapping,
144 the one character type signature and the name of the primitive class
146 ******************************************************************************/
148 /* CAUTION: Don't change the order of the types. This table is indexed
149 * by the ARRAYTYPE_ constants (expcept ARRAYTYPE_OBJECT).
151 primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = {
152 { NULL, NULL, "java/lang/Integer", 'I', "int" , "[I", NULL, NULL },
153 { NULL, NULL, "java/lang/Long", 'J', "long" , "[J", NULL, NULL },
154 { NULL, NULL, "java/lang/Float", 'F', "float" , "[F", NULL, NULL },
155 { NULL, NULL, "java/lang/Double", 'D', "double" , "[D", NULL, NULL },
156 { NULL, NULL, "java/lang/Byte", 'B', "byte" , "[B", NULL, NULL },
157 { NULL, NULL, "java/lang/Character", 'C', "char" , "[C", NULL, NULL },
158 { NULL, NULL, "java/lang/Short", 'S', "short" , "[S", NULL, NULL },
159 { NULL, NULL, "java/lang/Boolean", 'Z', "boolean" , "[Z", NULL, NULL },
160 { NULL, NULL, "java/lang/Void", 'V', "void" , NULL, NULL, NULL }
164 /************* functions for reading classdata *********************************
166 getting classdata in blocks of variable size
167 (8,16,32,64-bit integer or float)
169 *******************************************************************************/
171 /* check_classbuffer_size ******************************************************
173 assert that at least <len> bytes are left to read
174 <len> is limited to the range of non-negative s4 values
176 *******************************************************************************/
178 static inline bool check_classbuffer_size(classbuffer *cb, s4 len)
180 if (len < 0 || ((cb->data + cb->size) - cb->pos - 1) < len) {
182 new_classformaterror((cb)->class, "Truncated class file");
191 /* suck_nbytes *****************************************************************
193 transfer block of classfile data into a buffer
195 *******************************************************************************/
197 inline void suck_nbytes(u1 *buffer, classbuffer *cb, s4 len)
199 memcpy(buffer, cb->pos + 1, len);
204 /* skip_nbytes ****************************************************************
206 skip block of classfile data
208 *******************************************************************************/
210 inline void skip_nbytes(classbuffer *cb, s4 len)
216 inline u1 suck_u1(classbuffer *cb)
222 inline u2 suck_u2(classbuffer *cb)
226 return ((u2) a << 8) + (u2) b;
230 inline u4 suck_u4(classbuffer *cb)
236 return ((u4) a << 24) + ((u4) b << 16) + ((u4) c << 8) + (u4) d;
240 /* get u8 from classfile data */
241 static u8 suck_u8(classbuffer *cb)
247 return (hi << 32) + lo;
250 v.high = suck_u4(cb);
257 #define suck_s8(a) (s8) suck_u8((a))
258 #define suck_s2(a) (s2) suck_u2((a))
259 #define suck_s4(a) (s4) suck_u4((a))
260 #define suck_s1(a) (s1) suck_u1((a))
263 /* get float from classfile data */
264 static float suck_float(classbuffer *cb)
272 for (i = 0; i < 4; i++)
273 buffer[3 - i] = suck_u1(cb);
275 memcpy((u1*) (&f), buffer, 4);
277 suck_nbytes((u1*) (&f), cb, 4);
280 if (sizeof(float) != 4) {
281 *exceptionptr = new_exception_message(string_java_lang_InternalError,
282 "Incompatible float-format");
284 /* XXX should we exit in such a case? */
285 throw_exception_exit();
292 /* get double from classfile data */
293 static double suck_double(classbuffer *cb)
301 for (i = 0; i < 8; i++)
302 buffer[7 - i] = suck_u1(cb);
304 memcpy((u1*) (&d), buffer, 8);
306 suck_nbytes((u1*) (&d), cb, 8);
309 if (sizeof(double) != 8) {
310 *exceptionptr = new_exception_message(string_java_lang_InternalError,
311 "Incompatible double-format");
313 /* XXX should we exit in such a case? */
314 throw_exception_exit();
321 /************************** function suck_init *********************************
323 called once at startup, sets the searchpath for the classfiles
325 *******************************************************************************/
327 void suck_init(char *classpath)
335 classpath_info *lastcpi;
337 /* search for last classpath entry (only if there already some) */
339 if ((lastcpi = classpath_entries)) {
340 while (lastcpi->next)
341 lastcpi = lastcpi->next;
344 for (start = classpath; (*start) != '\0';) {
346 /* search for ':' delimiter to get the end of the current entry */
347 for (end = start; ((*end) != '\0') && ((*end) != ':'); end++);
351 filenamelen = end - start;
353 if (filenamelen > 3) {
354 if (strncasecmp(end - 3, "zip", 3) == 0 ||
355 strncasecmp(end - 3, "jar", 3) == 0) {
360 /* allocate memory for filename and fill it */
362 filename = MNEW(char, filenamelen + 2); /* 2 = "/\0" */
363 strncpy(filename, start, filenamelen);
364 filename[filenamelen + 1] = '\0';
368 #if defined(USE_ZLIB)
369 unzFile uf = unzOpen(filename);
372 cpi = NEW(classpath_info);
373 cpi->type = CLASSPATH_ARCHIVE;
376 cpi->pd = NULL; /* ProtectionDomain not set yet */
377 cpi->path = filename;
378 cpi->lock = NULL; /* we'll be initialized later */
382 throw_cacao_exception_exit(string_java_lang_InternalError,
383 "zip/jar files not supported");
387 cpi = NEW(classpath_info);
388 cpi->type = CLASSPATH_PATH;
390 cpi->pd = NULL; /* ProtectionDomain not set yet */
392 if (filename[filenamelen - 1] != '/') {/*PERHAPS THIS SHOULD BE READ FROM A GLOBAL CONFIGURATION */
393 filename[filenamelen] = '/';
394 filename[filenamelen + 1] = '\0';
398 cpi->path = filename;
399 cpi->pathlen = filenamelen;
402 /* attach current classpath entry */
405 if (!classpath_entries) {
406 classpath_entries = cpi;
416 /* goto next classpath entry, skip ':' delimiter */
428 void create_all_classes()
432 for (cpi = classpath_entries; cpi != 0; cpi = cpi->next) {
433 #if defined(USE_ZLIB)
434 if (cpi->type == CLASSPATH_ARCHIVE) {
438 s = (unz_s *) cpi->uf;
439 ce = s->cacao_dir_list;
442 (void) class_new(ce->name);
448 #if defined(USE_ZLIB)
455 /************************** function suck_start ********************************
457 returns true if classbuffer is already loaded or a file for the
458 specified class has succussfully been read in. All directories of
459 the searchpath are used to find the classfile (<classname>.class).
460 Returns false if no classfile is found and writes an error message.
462 *******************************************************************************/
464 classbuffer *suck_start(classinfo *c)
478 /* initialize return value */
483 filenamelen = utf_strlen(c->name) + 7; /* 7 = ".class\0" */
484 filename = MNEW(char, filenamelen);
486 utf_sprint(filename, c->name);
487 strcat(filename, ".class");
489 /* walk through all classpath entries */
491 for (cpi = classpath_entries; cpi != NULL && cb == NULL; cpi = cpi->next) {
492 #if defined(USE_ZLIB)
493 if (cpi->type == CLASSPATH_ARCHIVE) {
494 if (cpi->lock != NULL)
495 builtin_monitorenter(cpi->lock);
496 if (cacao_locate(cpi->uf, c->name) == UNZ_OK) {
497 unz_file_info file_info;
499 if (unzGetCurrentFileInfo(cpi->uf, &file_info, filename,
500 sizeof(filename), NULL, 0, NULL, 0) == UNZ_OK) {
501 if (unzOpenCurrentFile(cpi->uf) == UNZ_OK) {
502 cb = NEW(classbuffer);
504 cb->size = file_info.uncompressed_size;
505 cb->data = MNEW(u1, cb->size);
506 cb->pos = cb->data - 1;
507 /* we need this later in use_class_as_object to set a correct
508 ProtectionDomain and CodeSource */
509 c->pd = (struct java_security_ProtectionDomain*) cpi;
511 len = unzReadCurrentFile(cpi->uf, cb->data, cb->size);
513 if (len != cb->size) {
515 log_text("Error while unzipping");
522 log_text("Error while opening file in archive");
526 log_text("Error while retrieving fileinfo");
529 unzCloseCurrentFile(cpi->uf);
530 if (cpi->lock != NULL)
531 builtin_monitorexit(cpi->lock);
533 #endif /* USE_ZLIB */
535 path = MNEW(char, cpi->pathlen + filenamelen + 1);
536 strcpy(path, cpi->path);
537 strcat(path, filename);
539 classfile = fopen(path, "r");
541 if (classfile) { /* file exists */
542 if (!stat(path, &buffer)) { /* read classfile data */
543 cb = NEW(classbuffer);
545 cb->size = buffer.st_size;
546 cb->data = MNEW(u1, cb->size);
547 cb->pos = cb->data - 1;
548 /* we need this later in use_class_as_object to set a correct
549 ProtectionDomain and CodeSource */
550 c->pd = (struct java_security_ProtectionDomain*)cpi;
552 /* read class data */
553 len = fread(cb->data, 1, cb->size, classfile);
555 if (len != buffer.st_size) {
557 /* if (ferror(classfile)) { */
566 MFREE(path, char, cpi->pathlen + filenamelen + 1);
567 #if defined(USE_ZLIB)
574 dolog("Warning: Can not open class file '%s'", filename);
577 MFREE(filename, char, filenamelen);
583 /************************** function suck_stop *********************************
585 frees memory for buffer with classfile data.
586 Caution: this function may only be called if buffer has been allocated
587 by suck_start with reading a file
589 *******************************************************************************/
591 void suck_stop(classbuffer *cb)
595 MFREE(cb->data, u1, cb->size);
596 FREE(cb, classbuffer);
600 /******************************************************************************/
601 /******************* Some support functions ***********************************/
602 /******************************************************************************/
604 void fprintflags (FILE *fp, u2 f)
606 if ( f & ACC_PUBLIC ) fprintf (fp," PUBLIC");
607 if ( f & ACC_PRIVATE ) fprintf (fp," PRIVATE");
608 if ( f & ACC_PROTECTED ) fprintf (fp," PROTECTED");
609 if ( f & ACC_STATIC ) fprintf (fp," STATIC");
610 if ( f & ACC_FINAL ) fprintf (fp," FINAL");
611 if ( f & ACC_SYNCHRONIZED ) fprintf (fp," SYNCHRONIZED");
612 if ( f & ACC_VOLATILE ) fprintf (fp," VOLATILE");
613 if ( f & ACC_TRANSIENT ) fprintf (fp," TRANSIENT");
614 if ( f & ACC_NATIVE ) fprintf (fp," NATIVE");
615 if ( f & ACC_INTERFACE ) fprintf (fp," INTERFACE");
616 if ( f & ACC_ABSTRACT ) fprintf (fp," ABSTRACT");
620 /********** internal function: printflags (only for debugging) ***************/
622 void printflags(u2 f)
624 if ( f & ACC_PUBLIC ) printf (" PUBLIC");
625 if ( f & ACC_PRIVATE ) printf (" PRIVATE");
626 if ( f & ACC_PROTECTED ) printf (" PROTECTED");
627 if ( f & ACC_STATIC ) printf (" STATIC");
628 if ( f & ACC_FINAL ) printf (" FINAL");
629 if ( f & ACC_SYNCHRONIZED ) printf (" SYNCHRONIZED");
630 if ( f & ACC_VOLATILE ) printf (" VOLATILE");
631 if ( f & ACC_TRANSIENT ) printf (" TRANSIENT");
632 if ( f & ACC_NATIVE ) printf (" NATIVE");
633 if ( f & ACC_INTERFACE ) printf (" INTERFACE");
634 if ( f & ACC_ABSTRACT ) printf (" ABSTRACT");
638 /********************** Function: skipattributebody ****************************
640 skips an attribute after the 16 bit reference to attribute_name has already
643 *******************************************************************************/
645 static bool skipattributebody(classbuffer *cb)
649 if (!check_classbuffer_size(cb, 4))
654 if (!check_classbuffer_size(cb, len))
657 skip_nbytes(cb, len);
663 /************************* Function: skipattributes ****************************
665 skips num attribute structures
667 *******************************************************************************/
669 static bool skipattributes(classbuffer *cb, u4 num)
674 for (i = 0; i < num; i++) {
675 if (!check_classbuffer_size(cb, 2 + 4))
681 if (!check_classbuffer_size(cb, len))
684 skip_nbytes(cb, len);
691 /******************** function:: class_getconstant *****************************
693 retrieves the value at position 'pos' of the constantpool of a class
694 if the type of the value is other than 'ctype' the system is stopped
696 *******************************************************************************/
698 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
700 /* check index and type of constantpool entry */
701 /* (pos == 0 is caught by type comparison) */
702 if (pos >= c->cpcount || c->cptags[pos] != ctype) {
703 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
707 return c->cpinfos[pos];
711 /******************** function: innerclass_getconstant ************************
713 like class_getconstant, but if cptags is ZERO null is returned
715 *******************************************************************************/
717 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
719 /* invalid position in constantpool */
720 if (pos >= c->cpcount) {
721 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
725 /* constantpool entry of type 0 */
729 /* check type of constantpool entry */
730 if (c->cptags[pos] != ctype) {
731 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
735 return c->cpinfos[pos];
739 /********************* Function: class_constanttype ****************************
741 Determines the type of a class entry in the ConstantPool
743 *******************************************************************************/
745 u4 class_constanttype(classinfo *c, u4 pos)
747 if (pos <= 0 || pos >= c->cpcount) {
748 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
752 return c->cptags[pos];
756 /************************ function: attribute_load ****************************
758 read attributes from classfile
760 *******************************************************************************/
762 static bool attribute_load(classbuffer *cb, classinfo *c, u4 num)
767 for (i = 0; i < num; i++) {
768 /* retrieve attribute name */
769 if (!check_classbuffer_size(cb, 2))
772 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
775 if (aname == utf_innerclasses) {
776 /* innerclasses attribute */
779 new_classformaterror(c, "Multiple InnerClasses attributes");
783 if (!check_classbuffer_size(cb, 4 + 2))
786 /* skip attribute length */
789 /* number of records */
790 c->innerclasscount = suck_u2(cb);
792 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
795 /* allocate memory for innerclass structure */
796 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
798 for (j = 0; j < c->innerclasscount; j++) {
799 /* The innerclass structure contains a class with an encoded
800 name, its defining scope, its simple name and a bitmask of
801 the access flags. If an inner class is not a member, its
802 outer_class is NULL, if a class is anonymous, its name is
805 innerclassinfo *info = c->innerclass + j;
808 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
810 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
812 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
813 info->flags = suck_u2(cb);
816 } else if (aname == utf_sourcefile) {
817 if (!check_classbuffer_size(cb, 4 + 2))
820 if (suck_u4(cb) != 2) {
822 new_classformaterror(c, "Wrong size for VALUE attribute");
828 new_classformaterror(c, "Multiple SourceFile attributes");
832 if (!(c->sourcefile = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
836 /* unknown attribute */
837 if (!skipattributebody(cb))
846 /******************* function: checkfielddescriptor ****************************
848 checks whether a field-descriptor is valid and aborts otherwise
849 all referenced classes are inserted into the list of unloaded classes
851 *******************************************************************************/
853 static void checkfielddescriptor (char *utf_ptr, char *end_pos)
855 class_from_descriptor(utf_ptr,end_pos,NULL,
857 | CLASSLOAD_NULLPRIMITIVE
859 | CLASSLOAD_CHECKEND);
861 /* XXX use the following if -noverify */
863 char *tstart; /* pointer to start of classname */
865 char *start = utf_ptr;
867 switch (*utf_ptr++) {
881 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
882 panic ("Ill formed descriptor");
886 panic ("Ill formed descriptor");
889 /* exceeding characters */
890 if (utf_ptr!=end_pos) panic ("descriptor has exceeding chars");
895 /******************* function checkmethoddescriptor ****************************
897 checks whether a method-descriptor is valid and aborts otherwise.
898 All referenced classes are inserted into the list of unloaded classes.
900 The number of arguments is returned. A long or double argument is counted
903 *******************************************************************************/
905 static int checkmethoddescriptor(classinfo *c, utf *descriptor)
907 char *utf_ptr; /* current position in utf text */
908 char *end_pos; /* points behind utf string */
909 s4 argcount = 0; /* number of arguments */
911 utf_ptr = descriptor->text;
912 end_pos = utf_end(descriptor);
914 /* method descriptor must start with parenthesis */
915 if (utf_ptr == end_pos || *utf_ptr++ != '(')
916 panic ("Missing '(' in method descriptor");
918 /* check arguments */
919 while (utf_ptr != end_pos && *utf_ptr != ')') {
920 /* We cannot count the this argument here because
921 * we don't know if the method is static. */
922 if (*utf_ptr == 'J' || *utf_ptr == 'D')
926 class_from_descriptor(utf_ptr,end_pos,&utf_ptr,
928 | CLASSLOAD_NULLPRIMITIVE
932 if (utf_ptr == end_pos)
933 panic("Missing ')' in method descriptor");
935 utf_ptr++; /* skip ')' */
937 class_from_descriptor(utf_ptr,
941 CLASSLOAD_NULLPRIMITIVE |
944 if (argcount > 255) {
946 new_classformaterror(c, "Too many arguments in signature");
953 /* XXX use the following if -noverify */
955 /* check arguments */
956 while ((c = *utf_ptr++) != ')') {
973 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
974 panic ("Ill formed method descriptor");
978 panic ("Ill formed methodtype-descriptor");
982 /* check returntype */
984 /* returntype void */
985 if ((utf_ptr+1) != end_pos) panic ("Method-descriptor has exceeding chars");
988 /* treat as field-descriptor */
989 checkfielddescriptor (utf_ptr,end_pos);
994 /***************** Function: print_arraydescriptor ****************************
996 Debugging helper for displaying an arraydescriptor
998 *******************************************************************************/
1000 void print_arraydescriptor(FILE *file, arraydescriptor *desc)
1003 fprintf(file, "<NULL>");
1008 if (desc->componentvftbl) {
1009 if (desc->componentvftbl->class)
1010 utf_fprint(file, desc->componentvftbl->class->name);
1012 fprintf(file, "<no classinfo>");
1018 if (desc->elementvftbl) {
1019 if (desc->elementvftbl->class)
1020 utf_fprint(file, desc->elementvftbl->class->name);
1022 fprintf(file, "<no classinfo>");
1026 fprintf(file, ",%d,%d,%d,%d}", desc->arraytype, desc->dimension,
1027 desc->dataoffset, desc->componentsize);
1031 /******************************************************************************/
1032 /************************** Functions for fields ****************************/
1033 /******************************************************************************/
1036 /* field_load ******************************************************************
1038 Load everything about a class field from the class file and fill a
1039 'fieldinfo' structure. For static fields, space in the data segment is
1042 *******************************************************************************/
1044 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
1046 static bool field_load(classbuffer *cb, classinfo *c, fieldinfo *f)
1050 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
1053 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1056 f->flags = suck_u2(cb);
1058 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1062 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1068 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<')
1069 panic("Field with invalid name");
1071 /* check flag consistency */
1072 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
1074 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
1075 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
1077 new_classformaterror(c,
1078 "Illegal field modifiers: 0x%X",
1083 if (c->flags & ACC_INTERFACE) {
1084 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
1085 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
1086 f->flags & ACC_TRANSIENT) {
1088 new_classformaterror(c,
1089 "Illegal field modifiers: 0x%X",
1095 /* check descriptor */
1096 checkfielddescriptor(f->descriptor->text, utf_end(f->descriptor));
1099 f->type = jtype = desc_to_type(f->descriptor); /* data type */
1100 f->offset = 0; /* offset from start of object */
1105 case TYPE_INT: f->value.i = 0; break;
1106 case TYPE_FLOAT: f->value.f = 0.0; break;
1107 case TYPE_DOUBLE: f->value.d = 0.0; break;
1108 case TYPE_ADDRESS: f->value.a = NULL; break;
1111 f->value.l = 0; break;
1113 f->value.l.low = 0; f->value.l.high = 0; break;
1117 /* read attributes */
1118 if (!check_classbuffer_size(cb, 2))
1121 attrnum = suck_u2(cb);
1122 for (i = 0; i < attrnum; i++) {
1123 if (!check_classbuffer_size(cb, 2))
1126 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1129 if (u == utf_constantvalue) {
1130 if (!check_classbuffer_size(cb, 4 + 2))
1133 /* check attribute length */
1134 if (suck_u4(cb) != 2) {
1136 new_classformaterror(c, "Wrong size for VALUE attribute");
1140 /* constant value attribute */
1141 if (pindex != field_load_NOVALUE) {
1143 new_classformaterror(c,
1144 "Multiple ConstantValue attributes");
1148 /* index of value in constantpool */
1149 pindex = suck_u2(cb);
1151 /* initialize field with value from constantpool */
1154 constant_integer *ci;
1156 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
1159 f->value.i = ci->value;
1166 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
1169 f->value.l = cl->value;
1176 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
1179 f->value.f = cf->value;
1184 constant_double *cd;
1186 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
1189 f->value.d = cd->value;
1194 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
1197 /* create javastring from compressed utf8-string */
1198 f->value.a = literalstring_new(u);
1202 log_text("Invalid Constant - Type");
1206 /* unknown attribute */
1207 if (!skipattributebody(cb))
1212 /* everything was ok */
1218 /********************** function: field_free **********************************/
1220 static void field_free(fieldinfo *f)
1226 /**************** Function: field_display (debugging only) ********************/
1228 void field_display(fieldinfo *f)
1231 printflags(f->flags);
1233 utf_display(f->name);
1235 utf_display(f->descriptor);
1236 printf(" offset: %ld\n", (long int) (f->offset));
1240 /******************************************************************************/
1241 /************************* Functions for methods ******************************/
1242 /******************************************************************************/
1245 /* method_load *****************************************************************
1247 Loads a method from the class file and fills an existing 'methodinfo'
1248 structure. For native methods, the function pointer field is set to the
1249 real function pointer, for JavaVM methods a pointer to the compiler is used
1252 *******************************************************************************/
1254 static bool method_load(classbuffer *cb, classinfo *c, methodinfo *m)
1262 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1263 initObjectLock(&m->header);
1268 count_all_methods++;
1271 m->thrownexceptionscount = 0;
1272 m->linenumbercount = 0;
1275 m->nativelyoverloaded = false;
1277 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1280 m->flags = suck_u2(cb);
1282 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1286 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1291 if (!is_valid_name_utf(m->name))
1292 panic("Method with invalid name");
1294 if (m->name->text[0] == '<'
1295 && m->name != utf_init && m->name != utf_clinit)
1296 panic("Method with invalid special name");
1299 argcount = checkmethoddescriptor(c, m->descriptor);
1301 if (!(m->flags & ACC_STATIC))
1302 argcount++; /* count the 'this' argument */
1305 if (argcount > 255) {
1307 new_classformaterror(c, "Too many arguments in signature");
1311 /* check flag consistency */
1312 if (m->name != utf_clinit) {
1313 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1315 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1317 new_classformaterror(c,
1318 "Illegal method modifiers: 0x%X",
1323 if (m->flags & ACC_ABSTRACT) {
1324 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1325 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1327 new_classformaterror(c,
1328 "Illegal method modifiers: 0x%X",
1334 if (c->flags & ACC_INTERFACE) {
1335 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1337 new_classformaterror(c,
1338 "Illegal method modifiers: 0x%X",
1344 if (m->name == utf_init) {
1345 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1346 ACC_NATIVE | ACC_ABSTRACT))
1347 panic("Instance initialization method has invalid flags set");
1353 m->basicblockcount = 0;
1354 m->basicblocks = NULL;
1355 m->basicblockindex = NULL;
1356 m->instructioncount = 0;
1357 m->instructions = NULL;
1360 m->exceptiontable = NULL;
1361 m->stubroutine = NULL;
1363 m->entrypoint = NULL;
1364 m->methodUsed = NOTUSED;
1367 m->subRedefsUsed = 0;
1371 if (!(m->flags & ACC_NATIVE)) {
1372 m->stubroutine = createcompilerstub(m);
1375 /*if (useinlining) {
1376 log_text("creating native stub:");
1379 functionptr f = native_findfunction(c->name, m->name, m->descriptor,
1380 (m->flags & ACC_STATIC) != 0);
1381 #ifdef STATIC_CLASSPATH
1385 m->stubroutine = createnativestub(f, m);
1389 if (!check_classbuffer_size(cb, 2))
1392 attrnum = suck_u2(cb);
1393 for (i = 0; i < attrnum; i++) {
1396 if (!check_classbuffer_size(cb, 2))
1399 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1402 if (aname == utf_code) {
1403 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1405 new_classformaterror(c,
1406 "Code attribute in native or abstract methods");
1413 new_classformaterror(c, "Multiple Code attributes");
1418 if (!check_classbuffer_size(cb, 4 + 2 + 2))
1422 m->maxstack = suck_u2(cb);
1423 m->maxlocals = suck_u2(cb);
1425 if (m->maxlocals < argcount) {
1427 new_classformaterror(c, "Arguments can't fit into locals");
1432 if (!check_classbuffer_size(cb, 4))
1435 m->jcodelength = suck_u4(cb);
1437 if (m->jcodelength == 0) {
1439 new_classformaterror(c, "Code of a method has length 0");
1444 if (m->jcodelength > 65535) {
1446 new_classformaterror(c,
1447 "Code of a method longer than 65535 bytes");
1452 if (!check_classbuffer_size(cb, m->jcodelength))
1455 m->jcode = MNEW(u1, m->jcodelength);
1456 suck_nbytes(m->jcode, cb, m->jcodelength);
1458 if (!check_classbuffer_size(cb, 2))
1461 m->exceptiontablelength = suck_u2(cb);
1462 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->exceptiontablelength))
1465 m->exceptiontable = MNEW(exceptiontable, m->exceptiontablelength);
1467 #if defined(STATISTICS)
1469 count_vmcode_len += m->jcodelength + 18;
1470 count_extable_len += 8 * m->exceptiontablelength;
1474 for (j = 0; j < m->exceptiontablelength; j++) {
1476 m->exceptiontable[j].startpc = suck_u2(cb);
1477 m->exceptiontable[j].endpc = suck_u2(cb);
1478 m->exceptiontable[j].handlerpc = suck_u2(cb);
1482 m->exceptiontable[j].catchtype = NULL;
1485 if (!(m->exceptiontable[j].catchtype =
1486 class_getconstant(c, idx, CONSTANT_Class)))
1491 if (!check_classbuffer_size(cb, 2))
1494 codeattrnum = suck_u2(cb);
1496 for (; codeattrnum > 0; codeattrnum--) {
1499 if (!check_classbuffer_size(cb, 2))
1502 if (!(caname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1505 if (caname == utf_linenumbertable) {
1508 if (!check_classbuffer_size(cb, 4 + 2))
1512 m->linenumbercount = suck_u2(cb);
1514 if (!check_classbuffer_size(cb,
1515 (2 + 2) * m->linenumbercount))
1518 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1520 for (lncid = 0; lncid < m->linenumbercount; lncid++) {
1521 m->linenumbers[lncid].start_pc = suck_u2(cb);
1522 m->linenumbers[lncid].line_number = suck_u2(cb);
1526 if (!skipattributes(cb, codeattrnum))
1532 if (!skipattributebody(cb))
1537 } else if (aname == utf_exceptions) {
1540 if (m->thrownexceptions) {
1542 new_classformaterror(c, "Multiple Exceptions attributes");
1546 if (!check_classbuffer_size(cb, 4 + 2))
1549 suck_u4(cb); /* length */
1550 m->thrownexceptionscount = suck_u2(cb);
1552 if (!check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1555 m->thrownexceptions = MNEW(classinfo*, m->thrownexceptionscount);
1557 for (j = 0; j < m->thrownexceptionscount; j++) {
1558 if (!((m->thrownexceptions)[j] =
1559 class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1564 if (!skipattributebody(cb))
1569 if (!m->jcode && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1570 *exceptionptr = new_classformaterror(c, "Missing Code attribute");
1575 /* everything was ok */
1576 /* utf_display(m->name);
1577 printf("\nexceptiontablelength:%ld\n",m->exceptiontablelength);*/
1583 /********************* Function: method_free ***********************************
1585 frees all memory that was allocated for this method
1587 *******************************************************************************/
1589 static void method_free(methodinfo *m)
1592 MFREE(m->jcode, u1, m->jcodelength);
1594 if (m->exceptiontable)
1595 MFREE(m->exceptiontable, exceptiontable, m->exceptiontablelength);
1598 CFREE(m->mcode, m->mcodelength);
1600 if (m->stubroutine) {
1601 if (m->flags & ACC_NATIVE) {
1602 removenativestub(m->stubroutine);
1605 removecompilerstub(m->stubroutine);
1611 /************** Function: method_display (debugging only) **************/
1613 void method_display(methodinfo *m)
1616 printflags(m->flags);
1618 utf_display(m->name);
1620 utf_display(m->descriptor);
1624 /************** Function: method_display_w_class (debugging only) **************/
1626 void method_display_w_class(methodinfo *m)
1628 printflags(m->class->flags);
1629 printf(" "); fflush(stdout);
1630 utf_display(m->class->name);
1631 printf(".");fflush(stdout);
1634 printflags(m->flags);
1635 printf(" "); fflush(stdout);
1636 utf_display(m->name);
1637 printf(" "); fflush(stdout);
1638 utf_display(m->descriptor);
1639 printf("\n"); fflush(stdout);
1642 /************** Function: method_display_flags_last (debugging only) **************/
1644 void method_display_flags_last(methodinfo *m)
1647 utf_display(m->name);
1649 utf_display(m->descriptor);
1651 printflags(m->flags);
1656 /******************** Function: method_canoverwrite ****************************
1658 Check if m and old are identical with respect to type and name. This means
1659 that old can be overwritten with m.
1661 *******************************************************************************/
1663 static bool method_canoverwrite(methodinfo *m, methodinfo *old)
1665 if (m->name != old->name) return false;
1666 if (m->descriptor != old->descriptor) return false;
1667 if (m->flags & ACC_STATIC) return false;
1672 /******************** function: class_loadcpool ********************************
1674 loads the constantpool of a class,
1675 the entries are transformed into a simpler format
1676 by resolving references
1677 (a detailed overview of the compact structures can be found in global.h)
1679 *******************************************************************************/
1681 static bool class_loadcpool(classbuffer *cb, classinfo *c)
1684 /* The following structures are used to save information which cannot be
1685 processed during the first pass. After the complete constantpool has
1686 been traversed the references can be resolved.
1687 (only in specific order) */
1689 /* CONSTANT_Class entries */
1690 typedef struct forward_class {
1691 struct forward_class *next;
1696 /* CONSTANT_String */
1697 typedef struct forward_string {
1698 struct forward_string *next;
1703 /* CONSTANT_NameAndType */
1704 typedef struct forward_nameandtype {
1705 struct forward_nameandtype *next;
1709 } forward_nameandtype;
1711 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
1712 typedef struct forward_fieldmethint {
1713 struct forward_fieldmethint *next;
1717 u2 nameandtype_index;
1718 } forward_fieldmethint;
1723 forward_class *forward_classes = NULL;
1724 forward_string *forward_strings = NULL;
1725 forward_nameandtype *forward_nameandtypes = NULL;
1726 forward_fieldmethint *forward_fieldmethints = NULL;
1729 forward_string *nfs;
1730 forward_nameandtype *nfn;
1731 forward_fieldmethint *nff;
1737 /* number of entries in the constant_pool table plus one */
1738 if (!check_classbuffer_size(cb, 2))
1741 cpcount = c->cpcount = suck_u2(cb);
1743 /* allocate memory */
1744 cptags = c->cptags = MNEW(u1, cpcount);
1745 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
1748 *exceptionptr = new_classformaterror(c, "Illegal constant pool size");
1752 #if defined(STATISTICS)
1754 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
1757 /* initialize constantpool */
1758 for (idx = 0; idx < cpcount; idx++) {
1759 cptags[idx] = CONSTANT_UNUSED;
1760 cpinfos[idx] = NULL;
1764 /******* first pass *******/
1765 /* entries which cannot be resolved now are written into
1766 temporary structures and traversed again later */
1769 while (idx < cpcount) {
1772 /* get constant type */
1773 if (!check_classbuffer_size(cb, 1))
1779 case CONSTANT_Class:
1780 nfc = NEW(forward_class);
1782 nfc->next = forward_classes;
1783 forward_classes = nfc;
1785 nfc->thisindex = idx;
1786 /* reference to CONSTANT_NameAndType */
1787 if (!check_classbuffer_size(cb, 2))
1790 nfc->name_index = suck_u2(cb);
1795 case CONSTANT_String:
1796 nfs = NEW(forward_string);
1798 nfs->next = forward_strings;
1799 forward_strings = nfs;
1801 nfs->thisindex = idx;
1803 /* reference to CONSTANT_Utf8_info with string characters */
1804 if (!check_classbuffer_size(cb, 2))
1807 nfs->string_index = suck_u2(cb);
1812 case CONSTANT_NameAndType:
1813 nfn = NEW(forward_nameandtype);
1815 nfn->next = forward_nameandtypes;
1816 forward_nameandtypes = nfn;
1818 nfn->thisindex = idx;
1820 if (!check_classbuffer_size(cb, 2 + 2))
1823 /* reference to CONSTANT_Utf8_info containing simple name */
1824 nfn->name_index = suck_u2(cb);
1826 /* reference to CONSTANT_Utf8_info containing field or method
1828 nfn->sig_index = suck_u2(cb);
1833 case CONSTANT_Fieldref:
1834 case CONSTANT_Methodref:
1835 case CONSTANT_InterfaceMethodref:
1836 nff = NEW(forward_fieldmethint);
1838 nff->next = forward_fieldmethints;
1839 forward_fieldmethints = nff;
1841 nff->thisindex = idx;
1845 if (!check_classbuffer_size(cb, 2 + 2))
1848 /* class or interface type that contains the declaration of the
1850 nff->class_index = suck_u2(cb);
1852 /* name and descriptor of the field or method */
1853 nff->nameandtype_index = suck_u2(cb);
1858 case CONSTANT_Integer: {
1859 constant_integer *ci = NEW(constant_integer);
1861 #if defined(STATISTICS)
1863 count_const_pool_len += sizeof(constant_integer);
1866 if (!check_classbuffer_size(cb, 4))
1869 ci->value = suck_s4(cb);
1870 cptags[idx] = CONSTANT_Integer;
1877 case CONSTANT_Float: {
1878 constant_float *cf = NEW(constant_float);
1880 #if defined(STATISTICS)
1882 count_const_pool_len += sizeof(constant_float);
1885 if (!check_classbuffer_size(cb, 4))
1888 cf->value = suck_float(cb);
1889 cptags[idx] = CONSTANT_Float;
1896 case CONSTANT_Long: {
1897 constant_long *cl = NEW(constant_long);
1899 #if defined(STATISTICS)
1901 count_const_pool_len += sizeof(constant_long);
1904 if (!check_classbuffer_size(cb, 8))
1907 cl->value = suck_s8(cb);
1908 cptags[idx] = CONSTANT_Long;
1911 if (idx > cpcount) {
1913 new_classformaterror(c, "Invalid constant pool entry");
1919 case CONSTANT_Double: {
1920 constant_double *cd = NEW(constant_double);
1922 #if defined(STATISTICS)
1924 count_const_pool_len += sizeof(constant_double);
1927 if (!check_classbuffer_size(cb, 8))
1930 cd->value = suck_double(cb);
1931 cptags[idx] = CONSTANT_Double;
1934 if (idx > cpcount) {
1936 new_classformaterror(c, "Invalid constant pool entry");
1942 case CONSTANT_Utf8: {
1945 /* number of bytes in the bytes array (not string-length) */
1946 if (!check_classbuffer_size(cb, 2))
1949 length = suck_u2(cb);
1950 cptags[idx] = CONSTANT_Utf8;
1952 /* validate the string */
1953 if (!check_classbuffer_size(cb, length))
1957 !is_valid_utf((char *) (cb->pos + 1),
1958 (char *) (cb->pos + 1 + length))) {
1959 dolog("Invalid UTF-8 string (constant pool index %d)",idx);
1960 panic("Invalid UTF-8 string");
1962 /* insert utf-string into the utf-symboltable */
1963 cpinfos[idx] = utf_new_intern((char *) (cb->pos + 1), length);
1965 /* skip bytes of the string (buffer size check above) */
1966 skip_nbytes(cb, length);
1973 new_classformaterror(c, "Illegal constant pool type");
1979 /* resolve entries in temporary structures */
1981 while (forward_classes) {
1983 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
1985 if (opt_verify && !is_valid_name_utf(name))
1986 panic("Class reference with invalid name");
1988 cptags[forward_classes->thisindex] = CONSTANT_Class;
1989 /* retrieve class from class-table */
1992 tc = class_new_intern(name);
1994 if (!class_load(tc))
1997 /* link the class later, because we cannot link the class currently
1999 list_addfirst(&unlinkedclasses, tc);
2001 cpinfos[forward_classes->thisindex] = tc;
2004 cpinfos[forward_classes->thisindex] = class_new(name);
2007 nfc = forward_classes;
2008 forward_classes = forward_classes->next;
2009 FREE(nfc, forward_class);
2012 while (forward_strings) {
2014 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
2016 /* resolve utf-string */
2017 cptags[forward_strings->thisindex] = CONSTANT_String;
2018 cpinfos[forward_strings->thisindex] = text;
2020 nfs = forward_strings;
2021 forward_strings = forward_strings->next;
2022 FREE(nfs, forward_string);
2025 while (forward_nameandtypes) {
2026 constant_nameandtype *cn = NEW(constant_nameandtype);
2028 #if defined(STATISTICS)
2030 count_const_pool_len += sizeof(constant_nameandtype);
2033 /* resolve simple name and descriptor */
2034 cn->name = class_getconstant(c,
2035 forward_nameandtypes->name_index,
2038 cn->descriptor = class_getconstant(c,
2039 forward_nameandtypes->sig_index,
2044 if (!is_valid_name_utf(cn->name))
2045 panic("NameAndType with invalid name");
2046 /* disallow referencing <clinit> among others */
2047 if (cn->name->text[0] == '<' && cn->name != utf_init)
2048 panic("NameAndType with invalid special name");
2051 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
2052 cpinfos[forward_nameandtypes->thisindex] = cn;
2054 nfn = forward_nameandtypes;
2055 forward_nameandtypes = forward_nameandtypes->next;
2056 FREE(nfn, forward_nameandtype);
2059 while (forward_fieldmethints) {
2060 constant_nameandtype *nat;
2061 constant_FMIref *fmi = NEW(constant_FMIref);
2063 #if defined(STATISTICS)
2065 count_const_pool_len += sizeof(constant_FMIref);
2067 /* resolve simple name and descriptor */
2068 nat = class_getconstant(c,
2069 forward_fieldmethints->nameandtype_index,
2070 CONSTANT_NameAndType);
2072 fmi->class = class_getconstant(c,
2073 forward_fieldmethints->class_index,
2075 fmi->name = nat->name;
2076 fmi->descriptor = nat->descriptor;
2078 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
2079 cpinfos[forward_fieldmethints->thisindex] = fmi;
2081 switch (forward_fieldmethints->tag) {
2082 case CONSTANT_Fieldref: /* check validity of descriptor */
2083 checkfielddescriptor(fmi->descriptor->text,
2084 utf_end(fmi->descriptor));
2086 case CONSTANT_InterfaceMethodref:
2087 case CONSTANT_Methodref: /* check validity of descriptor */
2088 checkmethoddescriptor(c, fmi->descriptor);
2092 nff = forward_fieldmethints;
2093 forward_fieldmethints = forward_fieldmethints->next;
2094 FREE(nff, forward_fieldmethint);
2097 /* everything was ok */
2103 /********************** Function: class_load ***********************************
2105 Loads everything interesting about a class from the class file. The
2106 'classinfo' structure must have been allocated previously.
2108 The super class and the interfaces implemented by this class need not be
2109 loaded. The link is set later by the function 'class_link'.
2111 The loaded class is removed from the list 'unloadedclasses' and added to
2112 the list 'unlinkedclasses'.
2114 *******************************************************************************/
2116 classinfo *class_load_intern(classbuffer *cb);
2118 classinfo *class_load(classinfo *c)
2123 #if defined(USE_THREADS)
2124 /* enter a monitor on the class */
2126 builtin_monitorenter((java_objectheader *) c);
2129 /* maybe the class is already loaded */
2131 #if defined(USE_THREADS)
2132 builtin_monitorexit((java_objectheader *) c);
2140 if (getcompilingtime)
2141 compilingtime_stop();
2144 loadingtime_start();
2146 /* load classdata, throw exception on error */
2148 if ((cb = suck_start(c)) == NULL) {
2149 /* this means, the classpath was not set properly */
2150 if (c->name == utf_java_lang_Object)
2151 throw_cacao_exception_exit(string_java_lang_NoClassDefFoundError,
2152 "java/lang/Object");
2155 new_exception_utfmessage(string_java_lang_NoClassDefFoundError,
2158 #if defined(USE_THREADS)
2159 builtin_monitorexit((java_objectheader *) c);
2165 /* call the internal function */
2166 r = class_load_intern(cb);
2168 /* if return value is NULL, we had a problem and the class is not loaded */
2172 /* now free the allocated memory, otherwise we could ran into a DOS */
2184 if (getcompilingtime)
2185 compilingtime_start();
2187 #if defined(USE_THREADS)
2188 /* leave the monitor */
2190 builtin_monitorexit((java_objectheader *) c);
2197 classinfo *class_load_intern(classbuffer *cb)
2203 char msg[MAXLOGTEXT]; /* maybe we get an exception */
2205 /* get the classbuffer's class */
2208 /* maybe the class is already loaded */
2212 #if defined(STATISTICS)
2214 count_class_loads++;
2217 /* output for debugging purposes */
2219 log_message_class("Loading class: ", c);
2221 /* class is somewhat loaded */
2224 if (!check_classbuffer_size(cb, 4 + 2 + 2))
2227 /* check signature */
2228 if (suck_u4(cb) != MAGIC) {
2229 *exceptionptr = new_classformaterror(c, "Bad magic number");
2238 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
2240 new_unsupportedclassversionerror(c,
2241 "Unsupported major.minor version %d.%d",
2247 /* load the constant pool */
2248 if (!class_loadcpool(cb, c))
2252 c->erroneous_state = 0;
2253 c->initializing_thread = 0;
2255 c->classUsed = NOTUSED; /* not used initially CO-RT */
2259 if (!check_classbuffer_size(cb, 2))
2262 c->flags = suck_u2(cb);
2263 /*if (!(c->flags & ACC_PUBLIC)) { log_text("CLASS NOT PUBLIC"); } JOWENN*/
2265 /* check ACC flags consistency */
2266 if (c->flags & ACC_INTERFACE) {
2267 if (!(c->flags & ACC_ABSTRACT)) {
2268 /* We work around this because interfaces in JDK 1.1 are
2269 * not declared abstract. */
2271 c->flags |= ACC_ABSTRACT;
2272 /* panic("Interface class not declared abstract"); */
2275 if (c->flags & ACC_FINAL) {
2277 new_classformaterror(c,
2278 "Illegal class modifiers: 0x%X", c->flags);
2283 if (c->flags & ACC_SUPER) {
2284 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
2288 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
2290 new_classformaterror(c, "Illegal class modifiers: 0x%X", c->flags);
2295 if (!check_classbuffer_size(cb, 2 + 2))
2300 if (!(tc = class_getconstant(c, i, CONSTANT_Class)))
2304 utf_sprint(msg, c->name);
2305 sprintf(msg + strlen(msg), " (wrong name: ");
2306 utf_sprint(msg + strlen(msg), tc->name);
2307 sprintf(msg + strlen(msg), ")");
2310 new_exception_message(string_java_lang_NoClassDefFoundError, msg);
2315 /* retrieve superclass */
2316 if ((i = suck_u2(cb))) {
2317 if (!(c->super = class_getconstant(c, i, CONSTANT_Class)))
2320 /* java.lang.Object may not have a super class. */
2321 if (c->name == utf_java_lang_Object) {
2323 new_exception_message(string_java_lang_ClassFormatError,
2324 "java.lang.Object with superclass");
2329 /* Interfaces must have java.lang.Object as super class. */
2330 if ((c->flags & ACC_INTERFACE) &&
2331 c->super->name != utf_java_lang_Object) {
2333 new_exception_message(string_java_lang_ClassFormatError,
2334 "Interfaces must have java.lang.Object as superclass");
2342 /* This is only allowed for java.lang.Object. */
2343 if (c->name != utf_java_lang_Object) {
2344 *exceptionptr = new_classformaterror(c, "Bad superclass index");
2350 /* retrieve interfaces */
2351 if (!check_classbuffer_size(cb, 2))
2354 c->interfacescount = suck_u2(cb);
2356 if (!check_classbuffer_size(cb, 2 * c->interfacescount))
2359 c->interfaces = MNEW(classinfo*, c->interfacescount);
2360 for (i = 0; i < c->interfacescount; i++) {
2361 if (!(c->interfaces[i] = class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2366 if (!check_classbuffer_size(cb, 2))
2369 c->fieldscount = suck_u2(cb);
2370 c->fields = GCNEW(fieldinfo, c->fieldscount);
2371 /* c->fields = MNEW(fieldinfo, c->fieldscount); */
2372 for (i = 0; i < c->fieldscount; i++) {
2373 if (!field_load(cb, c, &(c->fields[i])))
2378 if (!check_classbuffer_size(cb, 2))
2381 c->methodscount = suck_u2(cb);
2382 c->methods = GCNEW(methodinfo, c->methodscount);
2383 /* c->methods = MNEW(methodinfo, c->methodscount); */
2384 for (i = 0; i < c->methodscount; i++) {
2385 if (!method_load(cb, c, &(c->methods[i])))
2389 /* Check if all fields and methods can be uniquely
2390 * identified by (name,descriptor). */
2392 /* We use a hash table here to avoid making the
2393 * average case quadratic in # of methods, fields.
2395 static int shift = 0;
2397 u2 *next; /* for chaining colliding hash entries */
2403 /* Allocate hashtable */
2404 len = c->methodscount;
2405 if (len < c->fieldscount) len = c->fieldscount;
2407 hashtab = MNEW(u2,(hashlen + len));
2408 next = hashtab + hashlen;
2410 /* Determine bitshift (to get good hash values) */
2420 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2422 for (i = 0; i < c->fieldscount; ++i) {
2423 fieldinfo *fi = c->fields + i;
2425 /* It's ok if we lose bits here */
2426 index = ((((size_t) fi->name) +
2427 ((size_t) fi->descriptor)) >> shift) % hashlen;
2429 if ((old = hashtab[index])) {
2433 if (c->fields[old].name == fi->name &&
2434 c->fields[old].descriptor == fi->descriptor) {
2436 new_classformaterror(c,
2437 "Repetitive field name/signature");
2441 } while ((old = next[old]));
2443 hashtab[index] = i + 1;
2447 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2449 for (i = 0; i < c->methodscount; ++i) {
2450 methodinfo *mi = c->methods + i;
2452 /* It's ok if we lose bits here */
2453 index = ((((size_t) mi->name) +
2454 ((size_t) mi->descriptor)) >> shift) % hashlen;
2458 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2459 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2463 if ((old = hashtab[index])) {
2467 if (c->methods[old].name == mi->name &&
2468 c->methods[old].descriptor == mi->descriptor) {
2470 new_classformaterror(c,
2471 "Repetitive method name/signature");
2475 } while ((old = next[old]));
2477 hashtab[index] = i + 1;
2480 MFREE(hashtab, u2, (hashlen + len));
2483 #if defined(STATISTICS)
2485 count_class_infos += sizeof(classinfo*) * c->interfacescount;
2486 count_class_infos += sizeof(fieldinfo) * c->fieldscount;
2487 count_class_infos += sizeof(methodinfo) * c->methodscount;
2491 /* load attribute structures */
2492 if (!check_classbuffer_size(cb, 2))
2495 if (!attribute_load(cb, c, suck_u2(cb)))
2499 /* Pre java 1.5 version don't check this. This implementation is like
2500 java 1.5 do it: for class file version 45.3 we don't check it, older
2501 versions are checked.
2503 if ((ma == 45 && mi > 3) || ma > 45) {
2504 /* check if all data has been read */
2505 s4 classdata_left = ((cb->data + cb->size) - cb->pos - 1);
2507 if (classdata_left > 0) {
2509 new_classformaterror(c, "Extra bytes at the end of class file");
2516 log_message_class("Loading done class: ", c);
2523 /************** internal Function: class_highestinterface **********************
2525 Used by the function class_link to determine the amount of memory needed
2526 for the interface table.
2528 *******************************************************************************/
2530 static s4 class_highestinterface(classinfo *c)
2535 /* check for ACC_INTERFACE bit already done in class_link_intern */
2538 for (i = 0; i < c->interfacescount; i++) {
2539 s4 h2 = class_highestinterface(c->interfaces[i]);
2547 /* class_addinterface **********************************************************
2549 Is needed by class_link for adding a VTBL to a class. All interfaces
2550 implemented by ic are added as well.
2552 *******************************************************************************/
2554 static void class_addinterface(classinfo *c, classinfo *ic)
2558 vftbl_t *v = c->vftbl;
2560 if (i >= v->interfacetablelength)
2561 panic ("Inernal error: interfacetable overflow");
2563 if (v->interfacetable[-i])
2566 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
2567 v->interfacevftbllength[i] = 1;
2568 v->interfacetable[-i] = MNEW(methodptr, 1);
2569 v->interfacetable[-i][0] = NULL;
2572 v->interfacevftbllength[i] = ic->methodscount;
2573 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
2575 #if defined(STATISTICS)
2577 count_vftbl_len += sizeof(methodptr) *
2578 (ic->methodscount + (ic->methodscount == 0));
2581 for (j = 0; j < ic->methodscount; j++) {
2584 for (m = 0; m < sc->methodscount; m++) {
2585 methodinfo *mi = &(sc->methods[m]);
2586 if (method_canoverwrite(mi, &(ic->methods[j]))) {
2587 v->interfacetable[-i][j] = v->table[mi->vftblindex];
2598 for (j = 0; j < ic->interfacescount; j++)
2599 class_addinterface(c, ic->interfaces[j]);
2603 /******************* Function: class_new_array *********************************
2605 This function is called by class_new to setup an array class.
2607 *******************************************************************************/
2609 void class_new_array(classinfo *c)
2611 classinfo *comp = NULL;
2615 /* Check array class name */
2616 namelen = c->name->blength;
2617 if (namelen < 2 || c->name->text[0] != '[')
2618 panic("Invalid array class name");
2620 /* Check the component type */
2621 switch (c->name->text[1]) {
2623 /* c is an array of arrays. We have to create the component class. */
2625 comp = class_new_intern(utf_new_intern(c->name->text + 1,
2628 list_addfirst(&unlinkedclasses, comp);
2631 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2636 /* c is an array of objects. */
2637 if (namelen < 4 || c->name->text[namelen - 1] != ';')
2638 panic("Invalid array class name");
2641 comp = class_new_intern(utf_new_intern(c->name->text + 2,
2644 list_addfirst(&unlinkedclasses, comp);
2647 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2652 /* Setup the array class */
2653 c->super = class_java_lang_Object;
2654 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2656 c->interfacescount = 2;
2657 c->interfaces = MNEW(classinfo*, 2);
2662 tc = class_new_intern(utf_new_char("java/lang/Cloneable"));
2664 list_addfirst(&unlinkedclasses, tc);
2665 c->interfaces[0] = tc;
2667 tc = class_new_intern(utf_new_char("java/io/Serializable"));
2669 list_addfirst(&unlinkedclasses, tc);
2670 c->interfaces[1] = tc;
2673 c->interfaces[0] = class_new(utf_new_char("java/lang/Cloneable"));
2674 c->interfaces[1] = class_new(utf_new_char("java/io/Serializable"));
2677 c->methodscount = 1;
2678 c->methods = MNEW(methodinfo, c->methodscount);
2681 memset(clone, 0, sizeof(methodinfo));
2682 clone->flags = ACC_PUBLIC;
2683 clone->name = utf_new_char("clone");
2684 clone->descriptor = utf_new_char("()Ljava/lang/Object;");
2686 clone->stubroutine = createnativestub((functionptr) &builtin_clone_array, clone);
2687 clone->monoPoly = MONO;
2689 /* XXX: field: length? */
2691 /* array classes are not loaded from class files */
2696 /****************** Function: class_link_array *********************************
2698 This function is called by class_link to create the
2699 arraydescriptor for an array class.
2701 This function returns NULL if the array cannot be linked because
2702 the component type has not been linked yet.
2704 *******************************************************************************/
2706 static arraydescriptor *class_link_array(classinfo *c)
2708 classinfo *comp = NULL;
2709 s4 namelen = c->name->blength;
2710 arraydescriptor *desc;
2713 /* Check the component type */
2714 switch (c->name->text[1]) {
2716 /* c is an array of arrays. */
2717 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2719 panic("Could not find component array class.");
2723 /* c is an array of objects. */
2724 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2726 panic("Could not find component class.");
2730 /* If the component type has not been linked, link it now */
2731 if (comp && !comp->linked) {
2733 if (!class_load(comp))
2736 if (!class_link(comp))
2740 /* Allocate the arraydescriptor */
2741 desc = NEW(arraydescriptor);
2744 /* c is an array of references */
2745 desc->arraytype = ARRAYTYPE_OBJECT;
2746 desc->componentsize = sizeof(void*);
2747 desc->dataoffset = OFFSET(java_objectarray, data);
2749 compvftbl = comp->vftbl;
2751 panic("Component class has no vftbl");
2752 desc->componentvftbl = compvftbl;
2754 if (compvftbl->arraydesc) {
2755 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
2756 if (compvftbl->arraydesc->dimension >= 255)
2757 panic("Creating array of dimension >255");
2758 desc->dimension = compvftbl->arraydesc->dimension + 1;
2759 desc->elementtype = compvftbl->arraydesc->elementtype;
2762 desc->elementvftbl = compvftbl;
2763 desc->dimension = 1;
2764 desc->elementtype = ARRAYTYPE_OBJECT;
2768 /* c is an array of a primitive type */
2769 switch (c->name->text[1]) {
2771 desc->arraytype = ARRAYTYPE_BOOLEAN;
2772 desc->dataoffset = OFFSET(java_booleanarray,data);
2773 desc->componentsize = sizeof(u1);
2777 desc->arraytype = ARRAYTYPE_BYTE;
2778 desc->dataoffset = OFFSET(java_bytearray,data);
2779 desc->componentsize = sizeof(u1);
2783 desc->arraytype = ARRAYTYPE_CHAR;
2784 desc->dataoffset = OFFSET(java_chararray,data);
2785 desc->componentsize = sizeof(u2);
2789 desc->arraytype = ARRAYTYPE_DOUBLE;
2790 desc->dataoffset = OFFSET(java_doublearray,data);
2791 desc->componentsize = sizeof(double);
2795 desc->arraytype = ARRAYTYPE_FLOAT;
2796 desc->dataoffset = OFFSET(java_floatarray,data);
2797 desc->componentsize = sizeof(float);
2801 desc->arraytype = ARRAYTYPE_INT;
2802 desc->dataoffset = OFFSET(java_intarray,data);
2803 desc->componentsize = sizeof(s4);
2807 desc->arraytype = ARRAYTYPE_LONG;
2808 desc->dataoffset = OFFSET(java_longarray,data);
2809 desc->componentsize = sizeof(s8);
2813 desc->arraytype = ARRAYTYPE_SHORT;
2814 desc->dataoffset = OFFSET(java_shortarray,data);
2815 desc->componentsize = sizeof(s2);
2819 panic("Invalid array class name");
2822 desc->componentvftbl = NULL;
2823 desc->elementvftbl = NULL;
2824 desc->dimension = 1;
2825 desc->elementtype = desc->arraytype;
2832 /********************** Function: class_link ***********************************
2834 Tries to link a class. The function calculates the length in bytes that
2835 an instance of this class requires as well as the VTBL for methods and
2838 *******************************************************************************/
2840 static classinfo *class_link_intern(classinfo *c);
2842 classinfo *class_link(classinfo *c)
2846 #if defined(USE_THREADS)
2847 /* enter a monitor on the class */
2849 builtin_monitorenter((java_objectheader *) c);
2852 /* maybe the class is already linked */
2854 #if defined(USE_THREADS)
2855 builtin_monitorexit((java_objectheader *) c);
2863 if (getcompilingtime)
2864 compilingtime_stop();
2867 loadingtime_start();
2869 /* call the internal function */
2870 r = class_link_intern(c);
2872 /* if return value is NULL, we had a problem and the class is not linked */
2881 if (getcompilingtime)
2882 compilingtime_start();
2884 #if defined(USE_THREADS)
2885 /* leave the monitor */
2887 builtin_monitorexit((java_objectheader *) c);
2894 static classinfo *class_link_intern(classinfo *c)
2896 s4 supervftbllength; /* vftbllegnth of super class */
2897 s4 vftbllength; /* vftbllength of current class */
2898 s4 interfacetablelength; /* interface table length */
2899 classinfo *super; /* super class */
2900 classinfo *tc; /* temporary class variable */
2901 vftbl_t *v; /* vftbl of current class */
2902 s4 i; /* interface/method/field counter */
2903 arraydescriptor *arraydesc; /* descriptor for array classes */
2905 /* maybe the class is already linked */
2909 /* maybe the class is not loaded */
2915 log_message_class("Linking class: ", c);
2917 /* ok, this class is somewhat linked */
2922 /* check interfaces */
2924 for (i = 0; i < c->interfacescount; i++) {
2925 tc = c->interfaces[i];
2927 /* detect circularity */
2930 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2936 if (!class_load(tc))
2939 if (!(tc->flags & ACC_INTERFACE)) {
2941 new_exception_message(string_java_lang_IncompatibleClassChangeError,
2942 "Implementing class");
2947 if (!class_link(tc))
2951 /* check super class */
2955 if (super == NULL) { /* class java.lang.Object */
2957 c->classUsed = USED; /* Object class is always used CO-RT*/
2959 c->instancesize = sizeof(java_objectheader);
2961 vftbllength = supervftbllength = 0;
2963 c->finalizer = NULL;
2966 /* detect circularity */
2969 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2975 if (!class_load(super))
2978 if (super->flags & ACC_INTERFACE) {
2979 /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
2980 panic("Interface specified as super class");
2983 /* Don't allow extending final classes */
2984 if (super->flags & ACC_FINAL) {
2986 new_exception_message(string_java_lang_VerifyError,
2987 "Cannot inherit from final class");
2992 if (!class_link(super))
2995 /* handle array classes */
2996 if (c->name->text[0] == '[')
2997 if (!(arraydesc = class_link_array(c)))
3000 if (c->flags & ACC_INTERFACE)
3001 c->index = interfaceindex++;
3003 c->index = super->index + 1;
3005 c->instancesize = super->instancesize;
3007 vftbllength = supervftbllength = super->vftbl->vftbllength;
3009 c->finalizer = super->finalizer;
3012 /* compute vftbl length */
3014 for (i = 0; i < c->methodscount; i++) {
3015 methodinfo *m = &(c->methods[i]);
3017 if (!(m->flags & ACC_STATIC)) { /* is instance method */
3022 for (j = 0; j < tc->methodscount; j++) {
3023 if (method_canoverwrite(m, &(tc->methods[j]))) {
3024 if (tc->methods[j].flags & ACC_PRIVATE)
3025 goto notfoundvftblindex;
3027 if (tc->methods[j].flags & ACC_FINAL) {
3028 /* class a overrides final method . */
3030 new_exception(string_java_lang_VerifyError);
3033 m->vftblindex = tc->methods[j].vftblindex;
3034 goto foundvftblindex;
3040 m->vftblindex = (vftbllength++);
3046 #if defined(STATISTICS)
3049 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
3052 /* compute interfacetable length */
3054 interfacetablelength = 0;
3057 for (i = 0; i < tc->interfacescount; i++) {
3058 s4 h = class_highestinterface(tc->interfaces[i]) + 1;
3059 if (h > interfacetablelength)
3060 interfacetablelength = h;
3065 /* allocate virtual function table */
3067 v = (vftbl_t*) mem_alloc(sizeof(vftbl_t) + sizeof(methodptr) *
3068 (vftbllength - 1) + sizeof(methodptr*) *
3069 (interfacetablelength - (interfacetablelength > 0)));
3070 v = (vftbl_t*) (((methodptr*) v) + (interfacetablelength - 1) *
3071 (interfacetablelength > 1));
3072 c->header.vftbl = c->vftbl = v;
3074 v->vftbllength = vftbllength;
3075 v->interfacetablelength = interfacetablelength;
3076 v->arraydesc = arraydesc;
3078 /* store interface index in vftbl */
3079 if (c->flags & ACC_INTERFACE)
3080 v->baseval = -(c->index);
3082 /* copy virtual function table of super class */
3084 for (i = 0; i < supervftbllength; i++)
3085 v->table[i] = super->vftbl->table[i];
3087 /* add method stubs into virtual function table */
3089 for (i = 0; i < c->methodscount; i++) {
3090 methodinfo *m = &(c->methods[i]);
3091 if (!(m->flags & ACC_STATIC)) {
3092 v->table[m->vftblindex] = m->stubroutine;
3096 /* compute instance size and offset of each field */
3098 for (i = 0; i < c->fieldscount; i++) {
3100 fieldinfo *f = &(c->fields[i]);
3102 if (!(f->flags & ACC_STATIC)) {
3103 dsize = desc_typesize(f->descriptor);
3104 c->instancesize = ALIGN(c->instancesize, dsize);
3105 f->offset = c->instancesize;
3106 c->instancesize += dsize;
3110 /* initialize interfacetable and interfacevftbllength */
3112 v->interfacevftbllength = MNEW(s4, interfacetablelength);
3114 #if defined(STATISTICS)
3116 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
3119 for (i = 0; i < interfacetablelength; i++) {
3120 v->interfacevftbllength[i] = 0;
3121 v->interfacetable[-i] = NULL;
3124 /* add interfaces */
3126 for (tc = c; tc != NULL; tc = tc->super) {
3127 for (i = 0; i < tc->interfacescount; i++) {
3128 class_addinterface(c, tc->interfaces[i]);
3132 /* add finalizer method (not for java.lang.Object) */
3137 fi = class_findmethod(c, utf_finalize, utf_fidesc);
3140 if (!(fi->flags & ACC_STATIC)) {
3148 loader_compute_subclasses(c);
3151 log_message_class("Linking done class: ", c);
3153 /* just return c to show that we didn't had a problem */
3159 /******************* Function: class_freepool **********************************
3161 Frees all resources used by this classes Constant Pool.
3163 *******************************************************************************/
3165 static void class_freecpool(classinfo *c)
3171 if (c->cptags && c->cpinfos) {
3172 for (idx = 0; idx < c->cpcount; idx++) {
3173 tag = c->cptags[idx];
3174 info = c->cpinfos[idx];
3178 case CONSTANT_Fieldref:
3179 case CONSTANT_Methodref:
3180 case CONSTANT_InterfaceMethodref:
3181 FREE(info, constant_FMIref);
3183 case CONSTANT_Integer:
3184 FREE(info, constant_integer);
3186 case CONSTANT_Float:
3187 FREE(info, constant_float);
3190 FREE(info, constant_long);
3192 case CONSTANT_Double:
3193 FREE(info, constant_double);
3195 case CONSTANT_NameAndType:
3196 FREE(info, constant_nameandtype);
3204 MFREE(c->cptags, u1, c->cpcount);
3207 MFREE(c->cpinfos, voidptr, c->cpcount);
3211 /*********************** Function: class_free **********************************
3213 Frees all resources used by the class.
3215 *******************************************************************************/
3217 void class_free(classinfo *c)
3225 MFREE(c->interfaces, classinfo*, c->interfacescount);
3228 for (i = 0; i < c->fieldscount; i++)
3229 field_free(&(c->fields[i]));
3230 /* MFREE(c->fields, fieldinfo, c->fieldscount); */
3234 for (i = 0; i < c->methodscount; i++)
3235 method_free(&(c->methods[i]));
3236 /* MFREE(c->methods, methodinfo, c->methodscount); */
3239 if ((v = c->vftbl) != NULL) {
3241 mem_free(v->arraydesc,sizeof(arraydescriptor));
3243 for (i = 0; i < v->interfacetablelength; i++) {
3244 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
3246 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
3248 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
3249 sizeof(methodptr*) * (v->interfacetablelength -
3250 (v->interfacetablelength > 0));
3251 v = (vftbl_t*) (((methodptr*) v) - (v->interfacetablelength - 1) *
3252 (v->interfacetablelength > 1));
3257 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
3259 /* if (c->classvftbl)
3260 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
3266 /************************* Function: class_findfield ***************************
3268 Searches a 'classinfo' structure for a field having the given name and
3271 *******************************************************************************/
3273 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
3277 for (i = 0; i < c->fieldscount; i++) {
3278 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
3279 return &(c->fields[i]);
3282 panic("Can not find field given in CONSTANT_Fieldref");
3284 /* keep compiler happy */
3289 /****************** Function: class_resolvefield_int ***************************
3291 This is an internally used helper function. Do not use this directly.
3293 Tries to resolve a field having the given name and type.
3294 If the field cannot be resolved, NULL is returned.
3296 *******************************************************************************/
3298 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
3303 /* search for field in class c */
3304 for (i = 0; i < c->fieldscount; i++) {
3305 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
3306 return &(c->fields[i]);
3310 /* try superinterfaces recursively */
3311 for (i = 0; i < c->interfacescount; ++i) {
3312 fi = class_resolvefield_int(c->interfaces[i], name, desc);
3317 /* try superclass */
3319 return class_resolvefield_int(c->super, name, desc);
3326 /********************* Function: class_resolvefield ***************************
3328 Resolves a reference from REFERER to a field with NAME and DESC in class C.
3330 If the field cannot be resolved the return value is NULL. If EXCEPT is
3331 true *exceptionptr is set, too.
3333 *******************************************************************************/
3335 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
3336 classinfo *referer, bool except)
3340 /* XXX resolve class c */
3341 /* XXX check access from REFERER to C */
3343 fi = class_resolvefield_int(c, name, desc);
3348 new_exception_utfmessage(string_java_lang_NoSuchFieldError,
3354 /* XXX check access rights */
3360 /************************* Function: class_findmethod **************************
3362 Searches a 'classinfo' structure for a method having the given name and
3363 type and returns the index in the class info structure.
3364 If type is NULL, it is ignored.
3366 *******************************************************************************/
3368 s4 class_findmethodIndex(classinfo *c, utf *name, utf *desc)
3372 for (i = 0; i < c->methodscount; i++) {
3374 /* utf_display_classname(c->name);printf("."); */
3375 /* utf_display(c->methods[i].name);printf("."); */
3376 /* utf_display(c->methods[i].descriptor); */
3379 if ((c->methods[i].name == name) && ((desc == NULL) ||
3380 (c->methods[i].descriptor == desc))) {
3389 /************************* Function: class_findmethod **************************
3391 Searches a 'classinfo' structure for a method having the given name and
3393 If type is NULL, it is ignored.
3395 *******************************************************************************/
3397 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
3399 s4 idx = class_findmethodIndex(c, name, desc);
3404 return &(c->methods[idx]);
3408 /*********************** Function: class_fetchmethod **************************
3410 like class_findmethod, but aborts with an error if the method is not found
3412 *******************************************************************************/
3414 methodinfo *class_fetchmethod(classinfo *c, utf *name, utf *desc)
3418 mi = class_findmethod(c, name, desc);
3421 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3422 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3423 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3424 panic("Method not found");
3431 /*********************** Function: class_findmethod_w**************************
3433 like class_findmethod, but logs a warning if the method is not found
3435 *******************************************************************************/
3437 methodinfo *class_findmethod_w(classinfo *c, utf *name, utf *desc, char *from)
3440 mi = class_findmethod(c, name, desc);
3443 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3444 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3445 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3447 if ( c->flags & ACC_PUBLIC ) log_plain(" PUBLIC ");
3448 if ( c->flags & ACC_PRIVATE ) log_plain(" PRIVATE ");
3449 if ( c->flags & ACC_PROTECTED ) log_plain(" PROTECTED ");
3450 if ( c->flags & ACC_STATIC ) log_plain(" STATIC ");
3451 if ( c->flags & ACC_FINAL ) log_plain(" FINAL ");
3452 if ( c->flags & ACC_SYNCHRONIZED ) log_plain(" SYNCHRONIZED ");
3453 if ( c->flags & ACC_VOLATILE ) log_plain(" VOLATILE ");
3454 if ( c->flags & ACC_TRANSIENT ) log_plain(" TRANSIENT ");
3455 if ( c->flags & ACC_NATIVE ) log_plain(" NATIVE ");
3456 if ( c->flags & ACC_INTERFACE ) log_plain(" INTERFACE ");
3457 if ( c->flags & ACC_ABSTRACT ) log_plain(" ABSTRACT ");
3460 log_plain(" : WARNING: Method not found");log_nl( );
3467 /************************* Function: class_findmethod_approx ******************
3469 like class_findmethod but ignores the return value when comparing the
3472 *******************************************************************************/
3474 methodinfo *class_findmethod_approx(classinfo *c, utf *name, utf *desc)
3478 for (i = 0; i < c->methodscount; i++) {
3479 if (c->methods[i].name == name) {
3480 utf *meth_descr = c->methods[i].descriptor;
3484 return &(c->methods[i]);
3486 if (desc->blength <= meth_descr->blength) {
3487 /* current position in utf text */
3488 char *desc_utf_ptr = desc->text;
3489 char *meth_utf_ptr = meth_descr->text;
3490 /* points behind utf strings */
3491 char *desc_end = utf_end(desc);
3492 char *meth_end = utf_end(meth_descr);
3495 /* compare argument types */
3496 while (desc_utf_ptr < desc_end && meth_utf_ptr < meth_end) {
3498 if ((ch = *desc_utf_ptr++) != (*meth_utf_ptr++))
3499 break; /* no match */
3502 return &(c->methods[i]); /* all parameter types equal */
3512 /***************** Function: class_resolvemethod_approx ***********************
3514 Searches a class and every super class for a method (without paying
3515 attention to the return value)
3517 *******************************************************************************/
3519 methodinfo *class_resolvemethod_approx(classinfo *c, utf *name, utf *desc)
3522 /* search for method (ignore returntype) */
3523 methodinfo *m = class_findmethod_approx(c, name, desc);
3526 /* search superclass */
3534 /************************* Function: class_resolvemethod ***********************
3536 Searches a class and every super class for a method.
3538 *******************************************************************************/
3540 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
3542 /*log_text("Trying to resolve a method");
3543 utf_display(c->name);
3545 utf_display(desc);*/
3548 /*log_text("Looking in:");
3549 utf_display(c->name);*/
3550 methodinfo *m = class_findmethod(c, name, desc);
3552 /* search superclass */
3555 /*log_text("method not found:");*/
3561 /****************** Function: class_resolveinterfacemethod_int ****************
3563 Internally used helper function. Do not use this directly.
3565 *******************************************************************************/
3568 methodinfo *class_resolveinterfacemethod_int(classinfo *c, utf *name, utf *desc)
3573 mi = class_findmethod(c,name,desc);
3577 /* try the superinterfaces */
3578 for (i=0; i<c->interfacescount; ++i) {
3579 mi = class_resolveinterfacemethod_int(c->interfaces[i],name,desc);
3587 /******************** Function: class_resolveinterfacemethod ******************
3589 Resolves a reference from REFERER to a method with NAME and DESC in
3592 If the method cannot be resolved the return value is NULL. If EXCEPT is
3593 true *exceptionptr is set, too.
3595 *******************************************************************************/
3597 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
3598 classinfo *referer, bool except)
3602 /* XXX resolve class c */
3603 /* XXX check access from REFERER to C */
3605 if (!(c->flags & ACC_INTERFACE)) {
3608 new_exception(string_java_lang_IncompatibleClassChangeError);
3613 mi = class_resolveinterfacemethod_int(c, name, desc);
3618 /* try class java.lang.Object */
3619 mi = class_findmethod(class_java_lang_Object, name, desc);
3626 new_exception_utfmessage(string_java_lang_NoSuchMethodError, name);
3632 /********************* Function: class_resolveclassmethod *********************
3634 Resolves a reference from REFERER to a method with NAME and DESC in
3637 If the method cannot be resolved the return value is NULL. If EXCEPT is
3638 true *exceptionptr is set, too.
3640 *******************************************************************************/
3642 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
3643 classinfo *referer, bool except)
3648 char msg[MAXLOGTEXT];
3650 /* XXX resolve class c */
3651 /* XXX check access from REFERER to C */
3653 /* if (c->flags & ACC_INTERFACE) { */
3655 /* *exceptionptr = */
3656 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
3660 /* try class c and its superclasses */
3663 mi = class_findmethod(cls, name, desc);
3666 } while ((cls = cls->super) != NULL); /* try the superclass */
3668 /* try the superinterfaces */
3669 for (i = 0; i < c->interfacescount; ++i) {
3670 mi = class_resolveinterfacemethod_int(c->interfaces[i], name, desc);
3676 utf_sprint(msg, c->name);
3677 sprintf(msg + strlen(msg), ".");
3678 utf_sprint(msg + strlen(msg), name);
3679 utf_sprint(msg + strlen(msg), desc);
3682 new_exception_message(string_java_lang_NoSuchMethodError, msg);
3688 if ((mi->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
3690 *exceptionptr = new_exception(string_java_lang_AbstractMethodError);
3695 /* XXX check access rights */
3701 /************************* Function: class_issubclass **************************
3703 Checks if sub is a descendant of super.
3705 *******************************************************************************/
3707 bool class_issubclass(classinfo *sub, classinfo *super)
3710 if (!sub) return false;
3711 if (sub == super) return true;
3717 /****************** Initialization function for classes ******************
3719 In Java, every class can have a static initialization function. This
3720 function has to be called BEFORE calling other methods or accessing static
3723 *******************************************************************************/
3725 static classinfo *class_init_intern(classinfo *c);
3727 classinfo *class_init(classinfo *c)
3731 if (!makeinitializations)
3734 #if defined(USE_THREADS)
3735 /* enter a monitor on the class */
3737 builtin_monitorenter((java_objectheader *) c);
3740 /* maybe the class is already initalized or the current thread, which can
3741 pass the monitor, is currently initalizing this class */
3743 /* JOWENN: In future we need an additinal flag: initializationfailed,
3744 since further access to the class should cause a NoClassDefFound,
3745 if the static initializer failed once
3748 if (c->initialized || c->initializing) {
3749 #if defined(USE_THREADS)
3750 builtin_monitorexit((java_objectheader *) c);
3756 /* this initalizing run begins NOW */
3757 c->initializing = true;
3759 /* call the internal function */
3760 r = class_init_intern(c);
3762 /* if return value is not NULL everything was ok and the class is
3765 c->initialized = true;
3767 /* this initalizing run is done */
3768 c->initializing = false;
3770 #if defined(USE_THREADS)
3771 /* leave the monitor */
3773 builtin_monitorexit((java_objectheader *) c);
3780 /* this function MUST NOT be called directly, because of thread <clinit>
3783 static classinfo *class_init_intern(classinfo *c)
3787 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3791 /* maybe the class is not already loaded */
3796 /* maybe the class is not already linked */
3801 #if defined(STATISTICS)
3803 count_class_inits++;
3806 /* initialize super class */
3809 if (!c->super->initialized) {
3811 char logtext[MAXLOGTEXT];
3812 sprintf(logtext, "Initialize super class ");
3813 utf_sprint_classname(logtext + strlen(logtext), c->super->name);
3814 sprintf(logtext + strlen(logtext), " from ");
3815 utf_sprint_classname(logtext + strlen(logtext), c->name);
3819 if (!class_init(c->super))
3824 /* initialize interface classes */
3826 for (i = 0; i < c->interfacescount; i++) {
3827 if (!c->interfaces[i]->initialized) {
3829 char logtext[MAXLOGTEXT];
3830 sprintf(logtext, "Initialize interface class ");
3831 utf_sprint_classname(logtext + strlen(logtext), c->interfaces[i]->name);
3832 sprintf(logtext + strlen(logtext), " from ");
3833 utf_sprint_classname(logtext + strlen(logtext), c->name);
3837 if (!class_init(c->interfaces[i]))
3842 m = class_findmethod(c, utf_clinit, utf_fidesc);
3846 char logtext[MAXLOGTEXT];
3847 sprintf(logtext, "Class ");
3848 utf_sprint_classname(logtext + strlen(logtext), c->name);
3849 sprintf(logtext + strlen(logtext), " has no static class initializer");
3856 /* Sun's and IBM's JVM don't care about the static flag */
3857 /* if (!(m->flags & ACC_STATIC)) { */
3858 /* panic("Class initializer is not static!"); */
3861 log_message_class("Starting static class initializer for class: ", c);
3863 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3868 /* now call the initializer */
3869 asm_calljavafunction(m, NULL, NULL, NULL, NULL);
3871 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3872 assert(blockInts == 0);
3876 /* we have an exception or error */
3877 if (*exceptionptr) {
3878 /* class is NOT initialized */
3879 c->initialized = false;
3881 /* is this an exception, than wrap it */
3882 if (builtin_instanceof(*exceptionptr, class_java_lang_Exception)) {
3883 java_objectheader *xptr;
3884 java_objectheader *cause;
3887 cause = *exceptionptr;
3889 /* clear exception, because we are calling jit code again */
3890 *exceptionptr = NULL;
3892 /* wrap the exception */
3894 new_exception_throwable(string_java_lang_ExceptionInInitializerError,
3895 (java_lang_Throwable *) cause);
3897 /* XXX should we exit here? */
3901 /* set new exception */
3902 *exceptionptr = xptr;
3909 log_message_class("Finished static class initializer for class: ", c);
3915 /********* Function: find_class_method_constant *********/
3917 int find_class_method_constant (classinfo *c, utf * c1, utf* m1, utf* d1)
3922 for (i=0; i<c->cpcount; i++) {
3924 e = c -> cpinfos [i];
3927 switch (c -> cptags [i]) {
3928 case CONSTANT_Methodref:
3930 constant_FMIref *fmi = e;
3931 if ( (fmi->class->name == c1)
3932 && (fmi->name == m1)
3933 && (fmi->descriptor == d1)) {
3940 case CONSTANT_InterfaceMethodref:
3942 constant_FMIref *fmi = e;
3943 if ( (fmi->class->name == c1)
3944 && (fmi->name == m1)
3945 && (fmi->descriptor == d1)) {
3959 void class_showconstanti(classinfo *c, int ii)
3965 printf ("#%d: ", (int) i);
3967 switch (c->cptags [i]) {
3968 case CONSTANT_Class:
3969 printf("Classreference -> ");
3970 utf_display(((classinfo*)e)->name);
3973 case CONSTANT_Fieldref:
3974 printf("Fieldref -> "); goto displayFMIi;
3975 case CONSTANT_Methodref:
3976 printf("Methodref -> "); goto displayFMIi;
3977 case CONSTANT_InterfaceMethodref:
3978 printf("InterfaceMethod -> "); goto displayFMIi;
3981 constant_FMIref *fmi = e;
3982 utf_display(fmi->class->name);
3984 utf_display(fmi->name);
3986 utf_display(fmi->descriptor);
3990 case CONSTANT_String:
3991 printf("String -> ");
3994 case CONSTANT_Integer:
3995 printf("Integer -> %d", (int) (((constant_integer*)e)->value));
3997 case CONSTANT_Float:
3998 printf("Float -> %f", ((constant_float*)e)->value);
4000 case CONSTANT_Double:
4001 printf("Double -> %f", ((constant_double*)e)->value);
4005 u8 v = ((constant_long*)e)->value;
4007 printf("Long -> %ld", (long int) v);
4009 printf("Long -> HI: %ld, LO: %ld\n",
4010 (long int) v.high, (long int) v.low);
4014 case CONSTANT_NameAndType:
4016 constant_nameandtype *cnt = e;
4017 printf("NameAndType: ");
4018 utf_display(cnt->name);
4020 utf_display(cnt->descriptor);
4028 panic("Invalid type of ConstantPool-Entry");
4035 void class_showconstantpool (classinfo *c)
4040 printf ("---- dump of constant pool ----\n");
4042 for (i=0; i<c->cpcount; i++) {
4043 printf ("#%d: ", (int) i);
4045 e = c -> cpinfos [i];
4048 switch (c -> cptags [i]) {
4049 case CONSTANT_Class:
4050 printf ("Classreference -> ");
4051 utf_display ( ((classinfo*)e) -> name );
4054 case CONSTANT_Fieldref:
4055 printf ("Fieldref -> "); goto displayFMI;
4056 case CONSTANT_Methodref:
4057 printf ("Methodref -> "); goto displayFMI;
4058 case CONSTANT_InterfaceMethodref:
4059 printf ("InterfaceMethod -> "); goto displayFMI;
4062 constant_FMIref *fmi = e;
4063 utf_display ( fmi->class->name );
4065 utf_display ( fmi->name);
4067 utf_display ( fmi->descriptor );
4071 case CONSTANT_String:
4072 printf ("String -> ");
4075 case CONSTANT_Integer:
4076 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
4078 case CONSTANT_Float:
4079 printf ("Float -> %f", ((constant_float*)e) -> value);
4081 case CONSTANT_Double:
4082 printf ("Double -> %f", ((constant_double*)e) -> value);
4086 u8 v = ((constant_long*)e) -> value;
4088 printf ("Long -> %ld", (long int) v);
4090 printf ("Long -> HI: %ld, LO: %ld\n",
4091 (long int) v.high, (long int) v.low);
4095 case CONSTANT_NameAndType:
4097 constant_nameandtype *cnt = e;
4098 printf ("NameAndType: ");
4099 utf_display (cnt->name);
4101 utf_display (cnt->descriptor);
4105 printf ("Utf8 -> ");
4109 panic ("Invalid type of ConstantPool-Entry");
4119 /********** Function: class_showmethods (debugging only) *************/
4121 void class_showmethods (classinfo *c)
4125 printf ("--------- Fields and Methods ----------------\n");
4126 printf ("Flags: "); printflags (c->flags); printf ("\n");
4128 printf ("This: "); utf_display (c->name); printf ("\n");
4130 printf ("Super: "); utf_display (c->super->name); printf ("\n");
4132 printf ("Index: %d\n", c->index);
4134 printf ("interfaces:\n");
4135 for (i=0; i < c-> interfacescount; i++) {
4137 utf_display (c -> interfaces[i] -> name);
4138 printf (" (%d)\n", c->interfaces[i] -> index);
4141 printf ("fields:\n");
4142 for (i=0; i < c -> fieldscount; i++) {
4143 field_display (&(c -> fields[i]));
4146 printf ("methods:\n");
4147 for (i=0; i < c -> methodscount; i++) {
4148 methodinfo *m = &(c->methods[i]);
4149 if ( !(m->flags & ACC_STATIC))
4150 printf ("vftblindex: %d ", m->vftblindex);
4152 method_display ( m );
4156 printf ("Virtual function table:\n");
4157 for (i=0; i<c->vftbl->vftbllength; i++) {
4158 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]) );
4164 /******************************************************************************/
4165 /******************* General functions for the class loader *******************/
4166 /******************************************************************************/
4168 /**************** function: create_primitive_classes ***************************
4170 create classes representing primitive types
4172 *******************************************************************************/
4174 static bool create_primitive_classes()
4178 for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
4179 /* create primitive class */
4181 class_new_intern(utf_new_char(primitivetype_table[i].name));
4182 c->classUsed = NOTUSED; /* not used initially CO-RT */
4185 /* prevent loader from loading primitive class */
4190 primitivetype_table[i].class_primitive = c;
4192 /* create class for wrapping the primitive type */
4193 c = class_new_intern(utf_new_char(primitivetype_table[i].wrapname));
4194 primitivetype_table[i].class_wrap = c;
4195 primitivetype_table[i].class_wrap->classUsed = NOTUSED; /* not used initially CO-RT */
4196 primitivetype_table[i].class_wrap->impldBy = NULL;
4198 /* create the primitive array class */
4199 if (primitivetype_table[i].arrayname) {
4200 c = class_new_intern(utf_new_char(primitivetype_table[i].arrayname));
4201 primitivetype_table[i].arrayclass = c;
4206 primitivetype_table[i].arrayvftbl = c->vftbl;
4214 /**************** function: class_primitive_from_sig ***************************
4216 return the primitive class indicated by the given signature character
4218 If the descriptor does not indicate a valid primitive type the
4219 return value is NULL.
4221 ********************************************************************************/
4223 classinfo *class_primitive_from_sig(char sig)
4226 case 'I': return primitivetype_table[PRIMITIVETYPE_INT].class_primitive;
4227 case 'J': return primitivetype_table[PRIMITIVETYPE_LONG].class_primitive;
4228 case 'F': return primitivetype_table[PRIMITIVETYPE_FLOAT].class_primitive;
4229 case 'D': return primitivetype_table[PRIMITIVETYPE_DOUBLE].class_primitive;
4230 case 'B': return primitivetype_table[PRIMITIVETYPE_BYTE].class_primitive;
4231 case 'C': return primitivetype_table[PRIMITIVETYPE_CHAR].class_primitive;
4232 case 'S': return primitivetype_table[PRIMITIVETYPE_SHORT].class_primitive;
4233 case 'Z': return primitivetype_table[PRIMITIVETYPE_BOOLEAN].class_primitive;
4234 case 'V': return primitivetype_table[PRIMITIVETYPE_VOID].class_primitive;
4239 /****************** function: class_from_descriptor ****************************
4241 return the class indicated by the given descriptor
4243 utf_ptr....first character of descriptor
4244 end_ptr....first character after the end of the string
4245 next.......if non-NULL, *next is set to the first character after
4246 the descriptor. (Undefined if an error occurs.)
4248 mode.......a combination (binary or) of the following flags:
4250 (Flags marked with * are the default settings.)
4252 What to do if a reference type descriptor is parsed successfully:
4254 CLASSLOAD_SKIP...skip it and return something != NULL
4255 * CLASSLOAD_NEW....get classinfo * via class_new
4256 CLASSLOAD_LOAD...get classinfo * via loader_load
4258 How to handle primitive types:
4260 * CLASSLOAD_PRIMITIVE.......return primitive class (eg. "int")
4261 CLASSLOAD_NULLPRIMITIVE...return NULL for primitive types
4263 How to handle "V" descriptors:
4265 * CLASSLOAD_VOID.....handle it like other primitive types
4266 CLASSLOAD_NOVOID...treat it as an error
4268 How to deal with extra characters after the end of the
4271 * CLASSLOAD_NOCHECKEND...ignore (useful for parameter lists)
4272 CLASSLOAD_CHECKEND.....treat them as an error
4274 How to deal with errors:
4276 * CLASSLOAD_PANIC....abort execution with an error message
4277 CLASSLOAD_NOPANIC..return NULL on error
4279 *******************************************************************************/
4281 classinfo *class_from_descriptor(char *utf_ptr, char *end_ptr,
4282 char **next, int mode)
4284 char *start = utf_ptr;
4288 SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr, end_ptr, error);
4290 if (mode & CLASSLOAD_CHECKEND)
4291 error |= (utf_ptr != end_ptr);
4294 if (next) *next = utf_ptr;
4298 if (mode & CLASSLOAD_NOVOID)
4309 return (mode & CLASSLOAD_NULLPRIMITIVE)
4311 : class_primitive_from_sig(*start);
4318 if (mode & CLASSLOAD_SKIP) return class_java_lang_Object;
4319 name = utf_new(start, utf_ptr - start);
4323 tc = class_new_intern(name);
4325 list_addfirst(&unlinkedclasses, tc);
4330 return (mode & CLASSLOAD_LOAD)
4331 ? class_load(class_new(name)) : class_new(name); /* XXX handle errors */
4336 /* An error occurred */
4337 if (mode & CLASSLOAD_NOPANIC)
4340 log_plain("Invalid descriptor at beginning of '");
4341 log_plain_utf(utf_new(start, end_ptr - start));
4345 panic("Invalid descriptor");
4347 /* keep compiler happy */
4352 /******************* function: type_from_descriptor ****************************
4354 return the basic type indicated by the given descriptor
4356 This function parses a descriptor and returns its basic type as
4357 TYPE_INT, TYPE_LONG, TYPE_FLOAT, TYPE_DOUBLE, TYPE_ADDRESS or TYPE_VOID.
4359 cls...if non-NULL the referenced variable is set to the classinfo *
4360 returned by class_from_descriptor.
4362 For documentation of the arguments utf_ptr, end_ptr, next and mode
4363 see class_from_descriptor. The only difference is that
4364 type_from_descriptor always uses CLASSLOAD_PANIC.
4366 ********************************************************************************/
4368 int type_from_descriptor(classinfo **cls, char *utf_ptr, char *end_ptr,
4369 char **next, int mode)
4372 if (!cls) cls = &mycls;
4373 *cls = class_from_descriptor(utf_ptr, end_ptr, next, mode & (~CLASSLOAD_NOPANIC));
4390 return TYPE_ADDRESS;
4394 /*************** function: create_pseudo_classes *******************************
4396 create pseudo classes used by the typechecker
4398 ********************************************************************************/
4400 static void create_pseudo_classes()
4402 /* pseudo class for Arraystubs (extends java.lang.Object) */
4404 pseudo_class_Arraystub = class_new_intern(utf_new_char("$ARRAYSTUB$"));
4405 pseudo_class_Arraystub->loaded = true;
4406 pseudo_class_Arraystub->super = class_java_lang_Object;
4407 pseudo_class_Arraystub->interfacescount = 2;
4408 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
4409 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
4410 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
4412 class_link(pseudo_class_Arraystub);
4414 pseudo_class_Arraystub_vftbl = pseudo_class_Arraystub->vftbl;
4416 /* pseudo class representing the null type */
4418 pseudo_class_Null = class_new_intern(utf_new_char("$NULL$"));
4419 pseudo_class_Null->loaded = true;
4420 pseudo_class_Null->super = class_java_lang_Object;
4421 class_link(pseudo_class_Null);
4423 /* pseudo class representing new uninitialized objects */
4425 pseudo_class_New = class_new_intern(utf_new_char("$NEW$"));
4426 pseudo_class_New->loaded = true;
4427 pseudo_class_New->linked = true;
4428 pseudo_class_New->super = class_java_lang_Object;
4429 /* class_link(pseudo_class_New); */
4433 /********************** Function: loader_init **********************************
4435 Initializes all lists and loads all classes required for the system or the
4438 *******************************************************************************/
4440 void loader_init(u1 *stackbottom)
4442 classpath_info *cpi;
4445 /* create utf-symbols for pointer comparison of frequently used strings */
4446 utf_innerclasses = utf_new_char("InnerClasses");
4447 utf_constantvalue = utf_new_char("ConstantValue");
4448 utf_code = utf_new_char("Code");
4449 utf_exceptions = utf_new_char("Exceptions");
4450 utf_linenumbertable = utf_new_char("LineNumberTable");
4451 utf_sourcefile = utf_new_char("SourceFile");
4452 utf_finalize = utf_new_char("finalize");
4453 utf_fidesc = utf_new_char("()V");
4454 utf_init = utf_new_char("<init>");
4455 utf_clinit = utf_new_char("<clinit>");
4456 utf_initsystemclass = utf_new_char("initializeSystemClass");
4457 utf_systemclass = utf_new_char("java/lang/System");
4458 utf_vmclassloader = utf_new_char("java/lang/VMClassLoader");
4459 utf_initialize = utf_new_char("initialize");
4460 utf_initializedesc = utf_new_char("(I)V");
4461 utf_vmclass = utf_new_char("java/lang/VMClass");
4462 utf_java_lang_Object= utf_new_char("java/lang/Object");
4463 array_packagename = utf_new_char("<the array package>");
4464 utf_fillInStackTrace_name = utf_new_char("fillInStackTrace");
4465 utf_fillInStackTrace_desc = utf_new_char("()Ljava/lang/Throwable;");
4467 /* create some important classes */
4468 /* These classes have to be created now because the classinfo
4469 * pointers are used in the loading code.
4471 class_java_lang_Object = class_new_intern(utf_java_lang_Object);
4472 class_load(class_java_lang_Object);
4473 class_link(class_java_lang_Object);
4475 class_java_lang_String = class_new(utf_new_char("java/lang/String"));
4476 class_load(class_java_lang_String);
4477 class_link(class_java_lang_String);
4479 class_java_lang_Cloneable = class_new(utf_new_char("java/lang/Cloneable"));
4480 class_load(class_java_lang_Cloneable);
4481 class_link(class_java_lang_Cloneable);
4483 class_java_io_Serializable =
4484 class_new(utf_new_char("java/io/Serializable"));
4485 class_load(class_java_io_Serializable);
4486 class_link(class_java_io_Serializable);
4488 /* create classes representing primitive types */
4489 create_primitive_classes();
4491 /* create classes used by the typechecker */
4492 create_pseudo_classes();
4494 /* correct vftbl-entries (retarded loading of class java/lang/String) */
4495 stringtable_update();
4497 /* init cpi-locks */
4498 for (cpi = classpath_entries; cpi != NULL; cpi = cpi->next) {
4499 if (cpi->type == CLASSPATH_ARCHIVE)
4500 cpi->lock = builtin_new(class_java_lang_Object);
4502 #if defined(USE_THREADS)
4503 if (stackbottom != 0)
4509 /* loader_compute_subclasses ***************************************************
4513 *******************************************************************************/
4515 static void loader_compute_class_values(classinfo *c);
4517 void loader_compute_subclasses(classinfo *c)
4519 #if defined(USE_THREADS)
4520 #if defined(NATIVE_THREADS)
4527 if (!(c->flags & ACC_INTERFACE)) {
4532 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
4533 c->nextsub = c->super->sub;
4539 /* this is the java.lang.Object special case */
4541 if (!class_java_lang_Object) {
4542 loader_compute_class_values(c);
4545 loader_compute_class_values(class_java_lang_Object);
4548 #if defined(USE_THREADS)
4549 #if defined(NATIVE_THREADS)
4558 /* loader_compute_class_values *************************************************
4562 *******************************************************************************/
4564 static void loader_compute_class_values(classinfo *c)
4568 c->vftbl->baseval = ++classvalue;
4572 loader_compute_class_values(subs);
4573 subs = subs->nextsub;
4576 c->vftbl->diffval = classvalue - c->vftbl->baseval;
4580 /******************** Function: loader_close ***********************************
4584 *******************************************************************************/
4591 for (slot = 0; slot < class_hash.size; slot++) {
4592 c = class_hash.ptr[slot];
4603 * These are local overrides for various environment variables in Emacs.
4604 * Please do not remove this and leave it at the end of the file, where
4605 * Emacs will automagically detect them.
4606 * ---------------------------------------------------------------------
4609 * indent-tabs-mode: t