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 1888 2005-01-27 21:04:09Z 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;
380 throw_cacao_exception_exit(string_java_lang_InternalError,
381 "zip/jar files not supported");
385 cpi = NEW(classpath_info);
386 cpi->type = CLASSPATH_PATH;
388 cpi->pd = NULL; /* ProtectionDomain not set yet */
390 if (filename[filenamelen - 1] != '/') {/*PERHAPS THIS SHOULD BE READ FROM A GLOBAL CONFIGURATION */
391 filename[filenamelen] = '/';
392 filename[filenamelen + 1] = '\0';
396 cpi->path = filename;
397 cpi->pathlen = filenamelen;
400 /* attach current classpath entry */
403 if (!classpath_entries) {
404 classpath_entries = cpi;
414 /* goto next classpath entry, skip ':' delimiter */
426 void create_all_classes()
430 for (cpi = classpath_entries; cpi != 0; cpi = cpi->next) {
431 #if defined(USE_ZLIB)
432 if (cpi->type == CLASSPATH_ARCHIVE) {
436 s = (unz_s *) cpi->uf;
437 ce = s->cacao_dir_list;
440 (void) class_new(ce->name);
446 #if defined(USE_ZLIB)
453 /************************** function suck_start ********************************
455 returns true if classbuffer is already loaded or a file for the
456 specified class has succussfully been read in. All directories of
457 the searchpath are used to find the classfile (<classname>.class).
458 Returns false if no classfile is found and writes an error message.
460 *******************************************************************************/
462 classbuffer *suck_start(classinfo *c)
476 /* initialize return value */
481 filenamelen = utf_strlen(c->name) + 7; /* 7 = ".class\0" */
482 filename = MNEW(char, filenamelen);
484 utf_sprint(filename, c->name);
485 strcat(filename, ".class");
487 /* walk through all classpath entries */
489 for (cpi = classpath_entries; cpi != NULL && cb == NULL; cpi = cpi->next) {
490 #if defined(USE_ZLIB)
491 if (cpi->type == CLASSPATH_ARCHIVE) {
492 if (cacao_locate(cpi->uf, c->name) == UNZ_OK) {
493 unz_file_info file_info;
495 if (unzGetCurrentFileInfo(cpi->uf, &file_info, filename,
496 sizeof(filename), NULL, 0, NULL, 0) == UNZ_OK) {
497 if (unzOpenCurrentFile(cpi->uf) == UNZ_OK) {
498 cb = NEW(classbuffer);
500 cb->size = file_info.uncompressed_size;
501 cb->data = MNEW(u1, cb->size);
502 cb->pos = cb->data - 1;
503 /* we need this later in use_class_as_object to set a correct
504 ProtectionDomain and CodeSource */
507 len = unzReadCurrentFile(cpi->uf, cb->data, cb->size);
509 if (len != cb->size) {
511 log_text("Error while unzipping");
518 log_text("Error while opening file in archive");
522 log_text("Error while retrieving fileinfo");
525 unzCloseCurrentFile(cpi->uf);
528 #endif /* USE_ZLIB */
530 path = MNEW(char, cpi->pathlen + filenamelen + 1);
531 strcpy(path, cpi->path);
532 strcat(path, filename);
534 classfile = fopen(path, "r");
536 if (classfile) { /* file exists */
537 if (!stat(path, &buffer)) { /* read classfile data */
538 cb = NEW(classbuffer);
540 cb->size = buffer.st_size;
541 cb->data = MNEW(u1, cb->size);
542 cb->pos = cb->data - 1;
543 /* we need this later in use_class_as_object to set a correct
544 ProtectionDomain and CodeSource */
547 /* read class data */
548 len = fread(cb->data, 1, cb->size, classfile);
550 if (len != buffer.st_size) {
552 /* if (ferror(classfile)) { */
561 MFREE(path, char, cpi->pathlen + filenamelen + 1);
562 #if defined(USE_ZLIB)
569 dolog("Warning: Can not open class file '%s'", filename);
572 MFREE(filename, char, filenamelen);
578 /************************** function suck_stop *********************************
580 frees memory for buffer with classfile data.
581 Caution: this function may only be called if buffer has been allocated
582 by suck_start with reading a file
584 *******************************************************************************/
586 void suck_stop(classbuffer *cb)
590 MFREE(cb->data, u1, cb->size);
591 FREE(cb, classbuffer);
595 /******************************************************************************/
596 /******************* Some support functions ***********************************/
597 /******************************************************************************/
599 void fprintflags (FILE *fp, u2 f)
601 if ( f & ACC_PUBLIC ) fprintf (fp," PUBLIC");
602 if ( f & ACC_PRIVATE ) fprintf (fp," PRIVATE");
603 if ( f & ACC_PROTECTED ) fprintf (fp," PROTECTED");
604 if ( f & ACC_STATIC ) fprintf (fp," STATIC");
605 if ( f & ACC_FINAL ) fprintf (fp," FINAL");
606 if ( f & ACC_SYNCHRONIZED ) fprintf (fp," SYNCHRONIZED");
607 if ( f & ACC_VOLATILE ) fprintf (fp," VOLATILE");
608 if ( f & ACC_TRANSIENT ) fprintf (fp," TRANSIENT");
609 if ( f & ACC_NATIVE ) fprintf (fp," NATIVE");
610 if ( f & ACC_INTERFACE ) fprintf (fp," INTERFACE");
611 if ( f & ACC_ABSTRACT ) fprintf (fp," ABSTRACT");
615 /********** internal function: printflags (only for debugging) ***************/
617 void printflags(u2 f)
619 if ( f & ACC_PUBLIC ) printf (" PUBLIC");
620 if ( f & ACC_PRIVATE ) printf (" PRIVATE");
621 if ( f & ACC_PROTECTED ) printf (" PROTECTED");
622 if ( f & ACC_STATIC ) printf (" STATIC");
623 if ( f & ACC_FINAL ) printf (" FINAL");
624 if ( f & ACC_SYNCHRONIZED ) printf (" SYNCHRONIZED");
625 if ( f & ACC_VOLATILE ) printf (" VOLATILE");
626 if ( f & ACC_TRANSIENT ) printf (" TRANSIENT");
627 if ( f & ACC_NATIVE ) printf (" NATIVE");
628 if ( f & ACC_INTERFACE ) printf (" INTERFACE");
629 if ( f & ACC_ABSTRACT ) printf (" ABSTRACT");
633 /********************** Function: skipattributebody ****************************
635 skips an attribute after the 16 bit reference to attribute_name has already
638 *******************************************************************************/
640 static bool skipattributebody(classbuffer *cb)
644 if (!check_classbuffer_size(cb, 4))
649 if (!check_classbuffer_size(cb, len))
652 skip_nbytes(cb, len);
658 /************************* Function: skipattributes ****************************
660 skips num attribute structures
662 *******************************************************************************/
664 static bool skipattributes(classbuffer *cb, u4 num)
669 for (i = 0; i < num; i++) {
670 if (!check_classbuffer_size(cb, 2 + 4))
676 if (!check_classbuffer_size(cb, len))
679 skip_nbytes(cb, len);
686 /******************** function:: class_getconstant *****************************
688 retrieves the value at position 'pos' of the constantpool of a class
689 if the type of the value is other than 'ctype' the system is stopped
691 *******************************************************************************/
693 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
695 /* check index and type of constantpool entry */
696 /* (pos == 0 is caught by type comparison) */
697 if (pos >= c->cpcount || c->cptags[pos] != ctype) {
698 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
702 return c->cpinfos[pos];
706 /******************** function: innerclass_getconstant ************************
708 like class_getconstant, but if cptags is ZERO null is returned
710 *******************************************************************************/
712 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
714 /* invalid position in constantpool */
715 if (pos >= c->cpcount) {
716 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
720 /* constantpool entry of type 0 */
724 /* check type of constantpool entry */
725 if (c->cptags[pos] != ctype) {
726 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
730 return c->cpinfos[pos];
734 /********************* Function: class_constanttype ****************************
736 Determines the type of a class entry in the ConstantPool
738 *******************************************************************************/
740 u4 class_constanttype(classinfo *c, u4 pos)
742 if (pos <= 0 || pos >= c->cpcount) {
743 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
747 return c->cptags[pos];
751 /************************ function: attribute_load ****************************
753 read attributes from classfile
755 *******************************************************************************/
757 static bool attribute_load(classbuffer *cb, classinfo *c, u4 num)
762 for (i = 0; i < num; i++) {
763 /* retrieve attribute name */
764 if (!check_classbuffer_size(cb, 2))
767 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
770 if (aname == utf_innerclasses) {
771 /* innerclasses attribute */
774 new_classformaterror(c, "Multiple InnerClasses attributes");
778 if (!check_classbuffer_size(cb, 4 + 2))
781 /* skip attribute length */
784 /* number of records */
785 c->innerclasscount = suck_u2(cb);
787 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
790 /* allocate memory for innerclass structure */
791 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
793 for (j = 0; j < c->innerclasscount; j++) {
794 /* The innerclass structure contains a class with an encoded
795 name, its defining scope, its simple name and a bitmask of
796 the access flags. If an inner class is not a member, its
797 outer_class is NULL, if a class is anonymous, its name is
800 innerclassinfo *info = c->innerclass + j;
803 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
805 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
807 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
808 info->flags = suck_u2(cb);
811 } else if (aname == utf_sourcefile) {
812 if (!check_classbuffer_size(cb, 4 + 2))
815 if (suck_u4(cb) != 2) {
817 new_classformaterror(c, "Wrong size for VALUE attribute");
823 new_classformaterror(c, "Multiple SourceFile attributes");
827 if (!(c->sourcefile = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
831 /* unknown attribute */
832 if (!skipattributebody(cb))
841 /******************* function: checkfielddescriptor ****************************
843 checks whether a field-descriptor is valid and aborts otherwise
844 all referenced classes are inserted into the list of unloaded classes
846 *******************************************************************************/
848 static void checkfielddescriptor (char *utf_ptr, char *end_pos)
850 class_from_descriptor(utf_ptr,end_pos,NULL,
852 | CLASSLOAD_NULLPRIMITIVE
854 | CLASSLOAD_CHECKEND);
856 /* XXX use the following if -noverify */
858 char *tstart; /* pointer to start of classname */
860 char *start = utf_ptr;
862 switch (*utf_ptr++) {
876 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
877 panic ("Ill formed descriptor");
881 panic ("Ill formed descriptor");
884 /* exceeding characters */
885 if (utf_ptr!=end_pos) panic ("descriptor has exceeding chars");
890 /******************* function checkmethoddescriptor ****************************
892 checks whether a method-descriptor is valid and aborts otherwise.
893 All referenced classes are inserted into the list of unloaded classes.
895 The number of arguments is returned. A long or double argument is counted
898 *******************************************************************************/
900 static int checkmethoddescriptor(classinfo *c, utf *descriptor)
902 char *utf_ptr; /* current position in utf text */
903 char *end_pos; /* points behind utf string */
904 s4 argcount = 0; /* number of arguments */
906 utf_ptr = descriptor->text;
907 end_pos = utf_end(descriptor);
909 /* method descriptor must start with parenthesis */
910 if (utf_ptr == end_pos || *utf_ptr++ != '(')
911 panic ("Missing '(' in method descriptor");
913 /* check arguments */
914 while (utf_ptr != end_pos && *utf_ptr != ')') {
915 /* We cannot count the this argument here because
916 * we don't know if the method is static. */
917 if (*utf_ptr == 'J' || *utf_ptr == 'D')
921 class_from_descriptor(utf_ptr,end_pos,&utf_ptr,
923 | CLASSLOAD_NULLPRIMITIVE
927 if (utf_ptr == end_pos)
928 panic("Missing ')' in method descriptor");
930 utf_ptr++; /* skip ')' */
932 class_from_descriptor(utf_ptr,
936 CLASSLOAD_NULLPRIMITIVE |
939 if (argcount > 255) {
941 new_classformaterror(c, "Too many arguments in signature");
948 /* XXX use the following if -noverify */
950 /* check arguments */
951 while ((c = *utf_ptr++) != ')') {
968 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
969 panic ("Ill formed method descriptor");
973 panic ("Ill formed methodtype-descriptor");
977 /* check returntype */
979 /* returntype void */
980 if ((utf_ptr+1) != end_pos) panic ("Method-descriptor has exceeding chars");
983 /* treat as field-descriptor */
984 checkfielddescriptor (utf_ptr,end_pos);
989 /***************** Function: print_arraydescriptor ****************************
991 Debugging helper for displaying an arraydescriptor
993 *******************************************************************************/
995 void print_arraydescriptor(FILE *file, arraydescriptor *desc)
998 fprintf(file, "<NULL>");
1003 if (desc->componentvftbl) {
1004 if (desc->componentvftbl->class)
1005 utf_fprint(file, desc->componentvftbl->class->name);
1007 fprintf(file, "<no classinfo>");
1013 if (desc->elementvftbl) {
1014 if (desc->elementvftbl->class)
1015 utf_fprint(file, desc->elementvftbl->class->name);
1017 fprintf(file, "<no classinfo>");
1021 fprintf(file, ",%d,%d,%d,%d}", desc->arraytype, desc->dimension,
1022 desc->dataoffset, desc->componentsize);
1026 /******************************************************************************/
1027 /************************** Functions for fields ****************************/
1028 /******************************************************************************/
1031 /* field_load ******************************************************************
1033 Load everything about a class field from the class file and fill a
1034 'fieldinfo' structure. For static fields, space in the data segment is
1037 *******************************************************************************/
1039 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
1041 static bool field_load(classbuffer *cb, classinfo *c, fieldinfo *f)
1045 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
1048 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1051 f->flags = suck_u2(cb);
1053 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1057 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1063 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<')
1064 panic("Field with invalid name");
1066 /* check flag consistency */
1067 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
1069 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
1070 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
1072 new_classformaterror(c,
1073 "Illegal field modifiers: 0x%X",
1078 if (c->flags & ACC_INTERFACE) {
1079 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
1080 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
1081 f->flags & ACC_TRANSIENT) {
1083 new_classformaterror(c,
1084 "Illegal field modifiers: 0x%X",
1090 /* check descriptor */
1091 checkfielddescriptor(f->descriptor->text, utf_end(f->descriptor));
1094 f->type = jtype = desc_to_type(f->descriptor); /* data type */
1095 f->offset = 0; /* offset from start of object */
1100 case TYPE_INT: f->value.i = 0; break;
1101 case TYPE_FLOAT: f->value.f = 0.0; break;
1102 case TYPE_DOUBLE: f->value.d = 0.0; break;
1103 case TYPE_ADDRESS: f->value.a = NULL; break;
1106 f->value.l = 0; break;
1108 f->value.l.low = 0; f->value.l.high = 0; break;
1112 /* read attributes */
1113 if (!check_classbuffer_size(cb, 2))
1116 attrnum = suck_u2(cb);
1117 for (i = 0; i < attrnum; i++) {
1118 if (!check_classbuffer_size(cb, 2))
1121 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1124 if (u == utf_constantvalue) {
1125 if (!check_classbuffer_size(cb, 4 + 2))
1128 /* check attribute length */
1129 if (suck_u4(cb) != 2) {
1131 new_classformaterror(c, "Wrong size for VALUE attribute");
1135 /* constant value attribute */
1136 if (pindex != field_load_NOVALUE) {
1138 new_classformaterror(c,
1139 "Multiple ConstantValue attributes");
1143 /* index of value in constantpool */
1144 pindex = suck_u2(cb);
1146 /* initialize field with value from constantpool */
1149 constant_integer *ci;
1151 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
1154 f->value.i = ci->value;
1161 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
1164 f->value.l = cl->value;
1171 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
1174 f->value.f = cf->value;
1179 constant_double *cd;
1181 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
1184 f->value.d = cd->value;
1189 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
1192 /* create javastring from compressed utf8-string */
1193 f->value.a = literalstring_new(u);
1197 log_text("Invalid Constant - Type");
1201 /* unknown attribute */
1202 if (!skipattributebody(cb))
1207 /* everything was ok */
1213 /********************** function: field_free **********************************/
1215 static void field_free(fieldinfo *f)
1221 /**************** Function: field_display (debugging only) ********************/
1223 void field_display(fieldinfo *f)
1226 printflags(f->flags);
1228 utf_display(f->name);
1230 utf_display(f->descriptor);
1231 printf(" offset: %ld\n", (long int) (f->offset));
1235 /******************************************************************************/
1236 /************************* Functions for methods ******************************/
1237 /******************************************************************************/
1240 /* method_load *****************************************************************
1242 Loads a method from the class file and fills an existing 'methodinfo'
1243 structure. For native methods, the function pointer field is set to the
1244 real function pointer, for JavaVM methods a pointer to the compiler is used
1247 *******************************************************************************/
1249 static bool method_load(classbuffer *cb, classinfo *c, methodinfo *m)
1257 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1258 initObjectLock(&m->header);
1263 count_all_methods++;
1266 m->thrownexceptionscount = 0;
1267 m->linenumbercount = 0;
1270 m->nativelyoverloaded = false;
1272 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1275 m->flags = suck_u2(cb);
1277 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1281 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1286 if (!is_valid_name_utf(m->name))
1287 panic("Method with invalid name");
1289 if (m->name->text[0] == '<'
1290 && m->name != utf_init && m->name != utf_clinit)
1291 panic("Method with invalid special name");
1294 argcount = checkmethoddescriptor(c, m->descriptor);
1296 if (!(m->flags & ACC_STATIC))
1297 argcount++; /* count the 'this' argument */
1300 if (argcount > 255) {
1302 new_classformaterror(c, "Too many arguments in signature");
1306 /* check flag consistency */
1307 if (m->name != utf_clinit) {
1308 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1310 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1312 new_classformaterror(c,
1313 "Illegal method modifiers: 0x%X",
1318 if (m->flags & ACC_ABSTRACT) {
1319 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1320 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1322 new_classformaterror(c,
1323 "Illegal method modifiers: 0x%X",
1329 if (c->flags & ACC_INTERFACE) {
1330 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1332 new_classformaterror(c,
1333 "Illegal method modifiers: 0x%X",
1339 if (m->name == utf_init) {
1340 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1341 ACC_NATIVE | ACC_ABSTRACT))
1342 panic("Instance initialization method has invalid flags set");
1348 m->basicblockcount = 0;
1349 m->basicblocks = NULL;
1350 m->basicblockindex = NULL;
1351 m->instructioncount = 0;
1352 m->instructions = NULL;
1355 m->exceptiontable = NULL;
1356 m->stubroutine = NULL;
1358 m->entrypoint = NULL;
1359 m->methodUsed = NOTUSED;
1362 m->subRedefsUsed = 0;
1366 if (!(m->flags & ACC_NATIVE)) {
1367 m->stubroutine = createcompilerstub(m);
1370 /*if (useinlining) {
1371 log_text("creating native stub:");
1374 functionptr f = native_findfunction(c->name, m->name, m->descriptor,
1375 (m->flags & ACC_STATIC) != 0);
1376 #ifdef STATIC_CLASSPATH
1380 m->stubroutine = createnativestub(f, m);
1384 if (!check_classbuffer_size(cb, 2))
1387 attrnum = suck_u2(cb);
1388 for (i = 0; i < attrnum; i++) {
1391 if (!check_classbuffer_size(cb, 2))
1394 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1397 if (aname == utf_code) {
1398 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1400 new_classformaterror(c,
1401 "Code attribute in native or abstract methods");
1408 new_classformaterror(c, "Multiple Code attributes");
1413 if (!check_classbuffer_size(cb, 4 + 2 + 2))
1417 m->maxstack = suck_u2(cb);
1418 m->maxlocals = suck_u2(cb);
1420 if (m->maxlocals < argcount) {
1422 new_classformaterror(c, "Arguments can't fit into locals");
1427 if (!check_classbuffer_size(cb, 4))
1430 m->jcodelength = suck_u4(cb);
1432 if (m->jcodelength == 0) {
1434 new_classformaterror(c, "Code of a method has length 0");
1439 if (m->jcodelength > 65535) {
1441 new_classformaterror(c,
1442 "Code of a method longer than 65535 bytes");
1447 if (!check_classbuffer_size(cb, m->jcodelength))
1450 m->jcode = MNEW(u1, m->jcodelength);
1451 suck_nbytes(m->jcode, cb, m->jcodelength);
1453 if (!check_classbuffer_size(cb, 2))
1456 m->exceptiontablelength = suck_u2(cb);
1457 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->exceptiontablelength))
1460 m->exceptiontable = MNEW(exceptiontable, m->exceptiontablelength);
1462 #if defined(STATISTICS)
1464 count_vmcode_len += m->jcodelength + 18;
1465 count_extable_len += 8 * m->exceptiontablelength;
1469 for (j = 0; j < m->exceptiontablelength; j++) {
1471 m->exceptiontable[j].startpc = suck_u2(cb);
1472 m->exceptiontable[j].endpc = suck_u2(cb);
1473 m->exceptiontable[j].handlerpc = suck_u2(cb);
1477 m->exceptiontable[j].catchtype = NULL;
1480 if (!(m->exceptiontable[j].catchtype =
1481 class_getconstant(c, idx, CONSTANT_Class)))
1486 if (!check_classbuffer_size(cb, 2))
1489 codeattrnum = suck_u2(cb);
1491 for (; codeattrnum > 0; codeattrnum--) {
1494 if (!check_classbuffer_size(cb, 2))
1497 if (!(caname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1500 if (caname == utf_linenumbertable) {
1503 if (!check_classbuffer_size(cb, 4 + 2))
1507 m->linenumbercount = suck_u2(cb);
1509 if (!check_classbuffer_size(cb,
1510 (2 + 2) * m->linenumbercount))
1513 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1515 for (lncid = 0; lncid < m->linenumbercount; lncid++) {
1516 m->linenumbers[lncid].start_pc = suck_u2(cb);
1517 m->linenumbers[lncid].line_number = suck_u2(cb);
1521 if (!skipattributes(cb, codeattrnum))
1527 if (!skipattributebody(cb))
1532 } else if (aname == utf_exceptions) {
1535 if (m->thrownexceptions) {
1537 new_classformaterror(c, "Multiple Exceptions attributes");
1541 if (!check_classbuffer_size(cb, 4 + 2))
1544 suck_u4(cb); /* length */
1545 m->thrownexceptionscount = suck_u2(cb);
1547 if (!check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1550 m->thrownexceptions = MNEW(classinfo*, m->thrownexceptionscount);
1552 for (j = 0; j < m->thrownexceptionscount; j++) {
1553 if (!((m->thrownexceptions)[j] =
1554 class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1559 if (!skipattributebody(cb))
1564 if (!m->jcode && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1565 *exceptionptr = new_classformaterror(c, "Missing Code attribute");
1570 /* everything was ok */
1571 /* utf_display(m->name);
1572 printf("\nexceptiontablelength:%ld\n",m->exceptiontablelength);*/
1578 /********************* Function: method_free ***********************************
1580 frees all memory that was allocated for this method
1582 *******************************************************************************/
1584 static void method_free(methodinfo *m)
1587 MFREE(m->jcode, u1, m->jcodelength);
1589 if (m->exceptiontable)
1590 MFREE(m->exceptiontable, exceptiontable, m->exceptiontablelength);
1593 CFREE(m->mcode, m->mcodelength);
1595 if (m->stubroutine) {
1596 if (m->flags & ACC_NATIVE) {
1597 removenativestub(m->stubroutine);
1600 removecompilerstub(m->stubroutine);
1606 /************** Function: method_display (debugging only) **************/
1608 void method_display(methodinfo *m)
1611 printflags(m->flags);
1613 utf_display(m->name);
1615 utf_display(m->descriptor);
1619 /************** Function: method_display_w_class (debugging only) **************/
1621 void method_display_w_class(methodinfo *m)
1623 printflags(m->class->flags);
1624 printf(" "); fflush(stdout);
1625 utf_display(m->class->name);
1626 printf(".");fflush(stdout);
1629 printflags(m->flags);
1630 printf(" "); fflush(stdout);
1631 utf_display(m->name);
1632 printf(" "); fflush(stdout);
1633 utf_display(m->descriptor);
1634 printf("\n"); fflush(stdout);
1637 /************** Function: method_display_flags_last (debugging only) **************/
1639 void method_display_flags_last(methodinfo *m)
1642 utf_display(m->name);
1644 utf_display(m->descriptor);
1646 printflags(m->flags);
1651 /******************** Function: method_canoverwrite ****************************
1653 Check if m and old are identical with respect to type and name. This means
1654 that old can be overwritten with m.
1656 *******************************************************************************/
1658 static bool method_canoverwrite(methodinfo *m, methodinfo *old)
1660 if (m->name != old->name) return false;
1661 if (m->descriptor != old->descriptor) return false;
1662 if (m->flags & ACC_STATIC) return false;
1667 /******************** function: class_loadcpool ********************************
1669 loads the constantpool of a class,
1670 the entries are transformed into a simpler format
1671 by resolving references
1672 (a detailed overview of the compact structures can be found in global.h)
1674 *******************************************************************************/
1676 static bool class_loadcpool(classbuffer *cb, classinfo *c)
1679 /* The following structures are used to save information which cannot be
1680 processed during the first pass. After the complete constantpool has
1681 been traversed the references can be resolved.
1682 (only in specific order) */
1684 /* CONSTANT_Class entries */
1685 typedef struct forward_class {
1686 struct forward_class *next;
1691 /* CONSTANT_String */
1692 typedef struct forward_string {
1693 struct forward_string *next;
1698 /* CONSTANT_NameAndType */
1699 typedef struct forward_nameandtype {
1700 struct forward_nameandtype *next;
1704 } forward_nameandtype;
1706 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
1707 typedef struct forward_fieldmethint {
1708 struct forward_fieldmethint *next;
1712 u2 nameandtype_index;
1713 } forward_fieldmethint;
1718 forward_class *forward_classes = NULL;
1719 forward_string *forward_strings = NULL;
1720 forward_nameandtype *forward_nameandtypes = NULL;
1721 forward_fieldmethint *forward_fieldmethints = NULL;
1724 forward_string *nfs;
1725 forward_nameandtype *nfn;
1726 forward_fieldmethint *nff;
1732 /* number of entries in the constant_pool table plus one */
1733 if (!check_classbuffer_size(cb, 2))
1736 cpcount = c->cpcount = suck_u2(cb);
1738 /* allocate memory */
1739 cptags = c->cptags = MNEW(u1, cpcount);
1740 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
1743 *exceptionptr = new_classformaterror(c, "Illegal constant pool size");
1747 #if defined(STATISTICS)
1749 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
1752 /* initialize constantpool */
1753 for (idx = 0; idx < cpcount; idx++) {
1754 cptags[idx] = CONSTANT_UNUSED;
1755 cpinfos[idx] = NULL;
1759 /******* first pass *******/
1760 /* entries which cannot be resolved now are written into
1761 temporary structures and traversed again later */
1764 while (idx < cpcount) {
1767 /* get constant type */
1768 if (!check_classbuffer_size(cb, 1))
1774 case CONSTANT_Class:
1775 nfc = NEW(forward_class);
1777 nfc->next = forward_classes;
1778 forward_classes = nfc;
1780 nfc->thisindex = idx;
1781 /* reference to CONSTANT_NameAndType */
1782 if (!check_classbuffer_size(cb, 2))
1785 nfc->name_index = suck_u2(cb);
1790 case CONSTANT_String:
1791 nfs = NEW(forward_string);
1793 nfs->next = forward_strings;
1794 forward_strings = nfs;
1796 nfs->thisindex = idx;
1798 /* reference to CONSTANT_Utf8_info with string characters */
1799 if (!check_classbuffer_size(cb, 2))
1802 nfs->string_index = suck_u2(cb);
1807 case CONSTANT_NameAndType:
1808 nfn = NEW(forward_nameandtype);
1810 nfn->next = forward_nameandtypes;
1811 forward_nameandtypes = nfn;
1813 nfn->thisindex = idx;
1815 if (!check_classbuffer_size(cb, 2 + 2))
1818 /* reference to CONSTANT_Utf8_info containing simple name */
1819 nfn->name_index = suck_u2(cb);
1821 /* reference to CONSTANT_Utf8_info containing field or method
1823 nfn->sig_index = suck_u2(cb);
1828 case CONSTANT_Fieldref:
1829 case CONSTANT_Methodref:
1830 case CONSTANT_InterfaceMethodref:
1831 nff = NEW(forward_fieldmethint);
1833 nff->next = forward_fieldmethints;
1834 forward_fieldmethints = nff;
1836 nff->thisindex = idx;
1840 if (!check_classbuffer_size(cb, 2 + 2))
1843 /* class or interface type that contains the declaration of the
1845 nff->class_index = suck_u2(cb);
1847 /* name and descriptor of the field or method */
1848 nff->nameandtype_index = suck_u2(cb);
1853 case CONSTANT_Integer: {
1854 constant_integer *ci = NEW(constant_integer);
1856 #if defined(STATISTICS)
1858 count_const_pool_len += sizeof(constant_integer);
1861 if (!check_classbuffer_size(cb, 4))
1864 ci->value = suck_s4(cb);
1865 cptags[idx] = CONSTANT_Integer;
1872 case CONSTANT_Float: {
1873 constant_float *cf = NEW(constant_float);
1875 #if defined(STATISTICS)
1877 count_const_pool_len += sizeof(constant_float);
1880 if (!check_classbuffer_size(cb, 4))
1883 cf->value = suck_float(cb);
1884 cptags[idx] = CONSTANT_Float;
1891 case CONSTANT_Long: {
1892 constant_long *cl = NEW(constant_long);
1894 #if defined(STATISTICS)
1896 count_const_pool_len += sizeof(constant_long);
1899 if (!check_classbuffer_size(cb, 8))
1902 cl->value = suck_s8(cb);
1903 cptags[idx] = CONSTANT_Long;
1906 if (idx > cpcount) {
1908 new_classformaterror(c, "Invalid constant pool entry");
1914 case CONSTANT_Double: {
1915 constant_double *cd = NEW(constant_double);
1917 #if defined(STATISTICS)
1919 count_const_pool_len += sizeof(constant_double);
1922 if (!check_classbuffer_size(cb, 8))
1925 cd->value = suck_double(cb);
1926 cptags[idx] = CONSTANT_Double;
1929 if (idx > cpcount) {
1931 new_classformaterror(c, "Invalid constant pool entry");
1937 case CONSTANT_Utf8: {
1940 /* number of bytes in the bytes array (not string-length) */
1941 if (!check_classbuffer_size(cb, 2))
1944 length = suck_u2(cb);
1945 cptags[idx] = CONSTANT_Utf8;
1947 /* validate the string */
1948 if (!check_classbuffer_size(cb, length))
1952 !is_valid_utf((char *) (cb->pos + 1),
1953 (char *) (cb->pos + 1 + length))) {
1954 dolog("Invalid UTF-8 string (constant pool index %d)",idx);
1955 panic("Invalid UTF-8 string");
1957 /* insert utf-string into the utf-symboltable */
1958 cpinfos[idx] = utf_new_intern((char *) (cb->pos + 1), length);
1960 /* skip bytes of the string (buffer size check above) */
1961 skip_nbytes(cb, length);
1968 new_classformaterror(c, "Illegal constant pool type");
1974 /* resolve entries in temporary structures */
1976 while (forward_classes) {
1978 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
1980 if (opt_verify && !is_valid_name_utf(name))
1981 panic("Class reference with invalid name");
1983 cptags[forward_classes->thisindex] = CONSTANT_Class;
1984 /* retrieve class from class-table */
1987 tc = class_new_intern(name);
1989 if (!class_load(tc))
1992 /* link the class later, because we cannot link the class currently
1994 list_addfirst(&unlinkedclasses, tc);
1996 cpinfos[forward_classes->thisindex] = tc;
1999 cpinfos[forward_classes->thisindex] = class_new(name);
2002 nfc = forward_classes;
2003 forward_classes = forward_classes->next;
2004 FREE(nfc, forward_class);
2007 while (forward_strings) {
2009 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
2011 /* resolve utf-string */
2012 cptags[forward_strings->thisindex] = CONSTANT_String;
2013 cpinfos[forward_strings->thisindex] = text;
2015 nfs = forward_strings;
2016 forward_strings = forward_strings->next;
2017 FREE(nfs, forward_string);
2020 while (forward_nameandtypes) {
2021 constant_nameandtype *cn = NEW(constant_nameandtype);
2023 #if defined(STATISTICS)
2025 count_const_pool_len += sizeof(constant_nameandtype);
2028 /* resolve simple name and descriptor */
2029 cn->name = class_getconstant(c,
2030 forward_nameandtypes->name_index,
2033 cn->descriptor = class_getconstant(c,
2034 forward_nameandtypes->sig_index,
2039 if (!is_valid_name_utf(cn->name))
2040 panic("NameAndType with invalid name");
2041 /* disallow referencing <clinit> among others */
2042 if (cn->name->text[0] == '<' && cn->name != utf_init)
2043 panic("NameAndType with invalid special name");
2046 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
2047 cpinfos[forward_nameandtypes->thisindex] = cn;
2049 nfn = forward_nameandtypes;
2050 forward_nameandtypes = forward_nameandtypes->next;
2051 FREE(nfn, forward_nameandtype);
2054 while (forward_fieldmethints) {
2055 constant_nameandtype *nat;
2056 constant_FMIref *fmi = NEW(constant_FMIref);
2058 #if defined(STATISTICS)
2060 count_const_pool_len += sizeof(constant_FMIref);
2062 /* resolve simple name and descriptor */
2063 nat = class_getconstant(c,
2064 forward_fieldmethints->nameandtype_index,
2065 CONSTANT_NameAndType);
2067 fmi->class = class_getconstant(c,
2068 forward_fieldmethints->class_index,
2070 fmi->name = nat->name;
2071 fmi->descriptor = nat->descriptor;
2073 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
2074 cpinfos[forward_fieldmethints->thisindex] = fmi;
2076 switch (forward_fieldmethints->tag) {
2077 case CONSTANT_Fieldref: /* check validity of descriptor */
2078 checkfielddescriptor(fmi->descriptor->text,
2079 utf_end(fmi->descriptor));
2081 case CONSTANT_InterfaceMethodref:
2082 case CONSTANT_Methodref: /* check validity of descriptor */
2083 checkmethoddescriptor(c, fmi->descriptor);
2087 nff = forward_fieldmethints;
2088 forward_fieldmethints = forward_fieldmethints->next;
2089 FREE(nff, forward_fieldmethint);
2092 /* everything was ok */
2098 /********************** Function: class_load ***********************************
2100 Loads everything interesting about a class from the class file. The
2101 'classinfo' structure must have been allocated previously.
2103 The super class and the interfaces implemented by this class need not be
2104 loaded. The link is set later by the function 'class_link'.
2106 The loaded class is removed from the list 'unloadedclasses' and added to
2107 the list 'unlinkedclasses'.
2109 *******************************************************************************/
2111 classinfo *class_load_intern(classbuffer *cb);
2113 classinfo *class_load(classinfo *c)
2118 #if defined(USE_THREADS)
2119 /* enter a monitor on the class */
2121 builtin_monitorenter((java_objectheader *) c);
2124 /* maybe the class is already loaded */
2126 #if defined(USE_THREADS)
2127 builtin_monitorexit((java_objectheader *) c);
2135 if (getcompilingtime)
2136 compilingtime_stop();
2139 loadingtime_start();
2141 /* load classdata, throw exception on error */
2143 if ((cb = suck_start(c)) == NULL) {
2144 /* this means, the classpath was not set properly */
2145 if (c->name == utf_java_lang_Object)
2146 throw_cacao_exception_exit(string_java_lang_NoClassDefFoundError,
2147 "java/lang/Object");
2150 new_exception_utfmessage(string_java_lang_NoClassDefFoundError,
2153 #if defined(USE_THREADS)
2154 builtin_monitorexit((java_objectheader *) c);
2160 /* call the internal function */
2161 r = class_load_intern(cb);
2163 /* if return value is NULL, we had a problem and the class is not loaded */
2167 /* now free the allocated memory, otherwise we could ran into a DOS */
2179 if (getcompilingtime)
2180 compilingtime_start();
2182 #if defined(USE_THREADS)
2183 /* leave the monitor */
2185 builtin_monitorexit((java_objectheader *) c);
2192 classinfo *class_load_intern(classbuffer *cb)
2198 char msg[MAXLOGTEXT]; /* maybe we get an exception */
2200 /* get the classbuffer's class */
2203 /* maybe the class is already loaded */
2207 #if defined(STATISTICS)
2209 count_class_loads++;
2212 /* output for debugging purposes */
2214 log_message_class("Loading class: ", c);
2216 /* class is somewhat loaded */
2219 if (!check_classbuffer_size(cb, 4 + 2 + 2))
2222 /* check signature */
2223 if (suck_u4(cb) != MAGIC) {
2224 *exceptionptr = new_classformaterror(c, "Bad magic number");
2233 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
2235 new_unsupportedclassversionerror(c,
2236 "Unsupported major.minor version %d.%d",
2242 /* load the constant pool */
2243 if (!class_loadcpool(cb, c))
2247 c->erroneous_state = 0;
2248 c->initializing_thread = 0;
2250 c->classUsed = NOTUSED; /* not used initially CO-RT */
2254 if (!check_classbuffer_size(cb, 2))
2257 c->flags = suck_u2(cb);
2258 /*if (!(c->flags & ACC_PUBLIC)) { log_text("CLASS NOT PUBLIC"); } JOWENN*/
2260 /* check ACC flags consistency */
2261 if (c->flags & ACC_INTERFACE) {
2262 if (!(c->flags & ACC_ABSTRACT)) {
2263 /* We work around this because interfaces in JDK 1.1 are
2264 * not declared abstract. */
2266 c->flags |= ACC_ABSTRACT;
2267 /* panic("Interface class not declared abstract"); */
2270 if (c->flags & ACC_FINAL) {
2272 new_classformaterror(c,
2273 "Illegal class modifiers: 0x%X", c->flags);
2278 if (c->flags & ACC_SUPER) {
2279 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
2283 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
2285 new_classformaterror(c, "Illegal class modifiers: 0x%X", c->flags);
2290 if (!check_classbuffer_size(cb, 2 + 2))
2295 if (!(tc = class_getconstant(c, i, CONSTANT_Class)))
2299 utf_sprint(msg, c->name);
2300 sprintf(msg + strlen(msg), " (wrong name: ");
2301 utf_sprint(msg + strlen(msg), tc->name);
2302 sprintf(msg + strlen(msg), ")");
2305 new_exception_message(string_java_lang_NoClassDefFoundError, msg);
2310 /* retrieve superclass */
2311 if ((i = suck_u2(cb))) {
2312 if (!(c->super = class_getconstant(c, i, CONSTANT_Class)))
2315 /* java.lang.Object may not have a super class. */
2316 if (c->name == utf_java_lang_Object) {
2318 new_exception_message(string_java_lang_ClassFormatError,
2319 "java.lang.Object with superclass");
2324 /* Interfaces must have java.lang.Object as super class. */
2325 if ((c->flags & ACC_INTERFACE) &&
2326 c->super->name != utf_java_lang_Object) {
2328 new_exception_message(string_java_lang_ClassFormatError,
2329 "Interfaces must have java.lang.Object as superclass");
2337 /* This is only allowed for java.lang.Object. */
2338 if (c->name != utf_java_lang_Object) {
2339 *exceptionptr = new_classformaterror(c, "Bad superclass index");
2345 /* retrieve interfaces */
2346 if (!check_classbuffer_size(cb, 2))
2349 c->interfacescount = suck_u2(cb);
2351 if (!check_classbuffer_size(cb, 2 * c->interfacescount))
2354 c->interfaces = MNEW(classinfo*, c->interfacescount);
2355 for (i = 0; i < c->interfacescount; i++) {
2356 if (!(c->interfaces[i] = class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2361 if (!check_classbuffer_size(cb, 2))
2364 c->fieldscount = suck_u2(cb);
2365 c->fields = GCNEW(fieldinfo, c->fieldscount);
2366 /* c->fields = MNEW(fieldinfo, c->fieldscount); */
2367 for (i = 0; i < c->fieldscount; i++) {
2368 if (!field_load(cb, c, &(c->fields[i])))
2373 if (!check_classbuffer_size(cb, 2))
2376 c->methodscount = suck_u2(cb);
2377 c->methods = GCNEW(methodinfo, c->methodscount);
2378 /* c->methods = MNEW(methodinfo, c->methodscount); */
2379 for (i = 0; i < c->methodscount; i++) {
2380 if (!method_load(cb, c, &(c->methods[i])))
2384 /* Check if all fields and methods can be uniquely
2385 * identified by (name,descriptor). */
2387 /* We use a hash table here to avoid making the
2388 * average case quadratic in # of methods, fields.
2390 static int shift = 0;
2392 u2 *next; /* for chaining colliding hash entries */
2398 /* Allocate hashtable */
2399 len = c->methodscount;
2400 if (len < c->fieldscount) len = c->fieldscount;
2402 hashtab = MNEW(u2,(hashlen + len));
2403 next = hashtab + hashlen;
2405 /* Determine bitshift (to get good hash values) */
2415 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2417 for (i = 0; i < c->fieldscount; ++i) {
2418 fieldinfo *fi = c->fields + i;
2420 /* It's ok if we lose bits here */
2421 index = ((((size_t) fi->name) +
2422 ((size_t) fi->descriptor)) >> shift) % hashlen;
2424 if ((old = hashtab[index])) {
2428 if (c->fields[old].name == fi->name &&
2429 c->fields[old].descriptor == fi->descriptor) {
2431 new_classformaterror(c,
2432 "Repetitive field name/signature");
2436 } while ((old = next[old]));
2438 hashtab[index] = i + 1;
2442 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2444 for (i = 0; i < c->methodscount; ++i) {
2445 methodinfo *mi = c->methods + i;
2447 /* It's ok if we lose bits here */
2448 index = ((((size_t) mi->name) +
2449 ((size_t) mi->descriptor)) >> shift) % hashlen;
2453 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2454 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2458 if ((old = hashtab[index])) {
2462 if (c->methods[old].name == mi->name &&
2463 c->methods[old].descriptor == mi->descriptor) {
2465 new_classformaterror(c,
2466 "Repetitive method name/signature");
2470 } while ((old = next[old]));
2472 hashtab[index] = i + 1;
2475 MFREE(hashtab, u2, (hashlen + len));
2478 #if defined(STATISTICS)
2480 count_class_infos += sizeof(classinfo*) * c->interfacescount;
2481 count_class_infos += sizeof(fieldinfo) * c->fieldscount;
2482 count_class_infos += sizeof(methodinfo) * c->methodscount;
2486 /* load attribute structures */
2487 if (!check_classbuffer_size(cb, 2))
2490 if (!attribute_load(cb, c, suck_u2(cb)))
2494 /* Pre java 1.5 version don't check this. This implementation is like
2495 java 1.5 do it: for class file version 45.3 we don't check it, older
2496 versions are checked.
2498 if ((ma == 45 && mi > 3) || ma > 45) {
2499 /* check if all data has been read */
2500 s4 classdata_left = ((cb->data + cb->size) - cb->pos - 1);
2502 if (classdata_left > 0) {
2504 new_classformaterror(c, "Extra bytes at the end of class file");
2511 log_message_class("Loading done class: ", c);
2518 /************** internal Function: class_highestinterface **********************
2520 Used by the function class_link to determine the amount of memory needed
2521 for the interface table.
2523 *******************************************************************************/
2525 static s4 class_highestinterface(classinfo *c)
2530 /* check for ACC_INTERFACE bit already done in class_link_intern */
2533 for (i = 0; i < c->interfacescount; i++) {
2534 s4 h2 = class_highestinterface(c->interfaces[i]);
2542 /* class_addinterface **********************************************************
2544 Is needed by class_link for adding a VTBL to a class. All interfaces
2545 implemented by ic are added as well.
2547 *******************************************************************************/
2549 static void class_addinterface(classinfo *c, classinfo *ic)
2553 vftbl_t *v = c->vftbl;
2555 if (i >= v->interfacetablelength)
2556 panic ("Inernal error: interfacetable overflow");
2558 if (v->interfacetable[-i])
2561 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
2562 v->interfacevftbllength[i] = 1;
2563 v->interfacetable[-i] = MNEW(methodptr, 1);
2564 v->interfacetable[-i][0] = NULL;
2567 v->interfacevftbllength[i] = ic->methodscount;
2568 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
2570 #if defined(STATISTICS)
2572 count_vftbl_len += sizeof(methodptr) *
2573 (ic->methodscount + (ic->methodscount == 0));
2576 for (j = 0; j < ic->methodscount; j++) {
2579 for (m = 0; m < sc->methodscount; m++) {
2580 methodinfo *mi = &(sc->methods[m]);
2581 if (method_canoverwrite(mi, &(ic->methods[j]))) {
2582 v->interfacetable[-i][j] = v->table[mi->vftblindex];
2593 for (j = 0; j < ic->interfacescount; j++)
2594 class_addinterface(c, ic->interfaces[j]);
2598 /******************* Function: class_new_array *********************************
2600 This function is called by class_new to setup an array class.
2602 *******************************************************************************/
2604 void class_new_array(classinfo *c)
2606 classinfo *comp = NULL;
2610 /* Check array class name */
2611 namelen = c->name->blength;
2612 if (namelen < 2 || c->name->text[0] != '[')
2613 panic("Invalid array class name");
2615 /* Check the component type */
2616 switch (c->name->text[1]) {
2618 /* c is an array of arrays. We have to create the component class. */
2620 comp = class_new_intern(utf_new_intern(c->name->text + 1,
2623 list_addfirst(&unlinkedclasses, comp);
2626 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2631 /* c is an array of objects. */
2632 if (namelen < 4 || c->name->text[namelen - 1] != ';')
2633 panic("Invalid array class name");
2636 comp = class_new_intern(utf_new_intern(c->name->text + 2,
2639 list_addfirst(&unlinkedclasses, comp);
2642 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2647 /* Setup the array class */
2648 c->super = class_java_lang_Object;
2649 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2651 c->interfacescount = 2;
2652 c->interfaces = MNEW(classinfo*, 2);
2657 tc = class_new_intern(utf_new_char("java/lang/Cloneable"));
2659 list_addfirst(&unlinkedclasses, tc);
2660 c->interfaces[0] = tc;
2662 tc = class_new_intern(utf_new_char("java/io/Serializable"));
2664 list_addfirst(&unlinkedclasses, tc);
2665 c->interfaces[1] = tc;
2668 c->interfaces[0] = class_new(utf_new_char("java/lang/Cloneable"));
2669 c->interfaces[1] = class_new(utf_new_char("java/io/Serializable"));
2672 c->methodscount = 1;
2673 c->methods = MNEW(methodinfo, c->methodscount);
2676 memset(clone, 0, sizeof(methodinfo));
2677 clone->flags = ACC_PUBLIC;
2678 clone->name = utf_new_char("clone");
2679 clone->descriptor = utf_new_char("()Ljava/lang/Object;");
2681 clone->stubroutine = createnativestub((functionptr) &builtin_clone_array, clone);
2682 clone->monoPoly = MONO;
2684 /* XXX: field: length? */
2686 /* array classes are not loaded from class files */
2691 /****************** Function: class_link_array *********************************
2693 This function is called by class_link to create the
2694 arraydescriptor for an array class.
2696 This function returns NULL if the array cannot be linked because
2697 the component type has not been linked yet.
2699 *******************************************************************************/
2701 static arraydescriptor *class_link_array(classinfo *c)
2703 classinfo *comp = NULL;
2704 s4 namelen = c->name->blength;
2705 arraydescriptor *desc;
2708 /* Check the component type */
2709 switch (c->name->text[1]) {
2711 /* c is an array of arrays. */
2712 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2714 panic("Could not find component array class.");
2718 /* c is an array of objects. */
2719 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2721 panic("Could not find component class.");
2725 /* If the component type has not been linked, link it now */
2726 if (comp && !comp->linked) {
2728 if (!class_load(comp))
2731 if (!class_link(comp))
2735 /* Allocate the arraydescriptor */
2736 desc = NEW(arraydescriptor);
2739 /* c is an array of references */
2740 desc->arraytype = ARRAYTYPE_OBJECT;
2741 desc->componentsize = sizeof(void*);
2742 desc->dataoffset = OFFSET(java_objectarray, data);
2744 compvftbl = comp->vftbl;
2746 panic("Component class has no vftbl");
2747 desc->componentvftbl = compvftbl;
2749 if (compvftbl->arraydesc) {
2750 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
2751 if (compvftbl->arraydesc->dimension >= 255)
2752 panic("Creating array of dimension >255");
2753 desc->dimension = compvftbl->arraydesc->dimension + 1;
2754 desc->elementtype = compvftbl->arraydesc->elementtype;
2757 desc->elementvftbl = compvftbl;
2758 desc->dimension = 1;
2759 desc->elementtype = ARRAYTYPE_OBJECT;
2763 /* c is an array of a primitive type */
2764 switch (c->name->text[1]) {
2766 desc->arraytype = ARRAYTYPE_BOOLEAN;
2767 desc->dataoffset = OFFSET(java_booleanarray,data);
2768 desc->componentsize = sizeof(u1);
2772 desc->arraytype = ARRAYTYPE_BYTE;
2773 desc->dataoffset = OFFSET(java_bytearray,data);
2774 desc->componentsize = sizeof(u1);
2778 desc->arraytype = ARRAYTYPE_CHAR;
2779 desc->dataoffset = OFFSET(java_chararray,data);
2780 desc->componentsize = sizeof(u2);
2784 desc->arraytype = ARRAYTYPE_DOUBLE;
2785 desc->dataoffset = OFFSET(java_doublearray,data);
2786 desc->componentsize = sizeof(double);
2790 desc->arraytype = ARRAYTYPE_FLOAT;
2791 desc->dataoffset = OFFSET(java_floatarray,data);
2792 desc->componentsize = sizeof(float);
2796 desc->arraytype = ARRAYTYPE_INT;
2797 desc->dataoffset = OFFSET(java_intarray,data);
2798 desc->componentsize = sizeof(s4);
2802 desc->arraytype = ARRAYTYPE_LONG;
2803 desc->dataoffset = OFFSET(java_longarray,data);
2804 desc->componentsize = sizeof(s8);
2808 desc->arraytype = ARRAYTYPE_SHORT;
2809 desc->dataoffset = OFFSET(java_shortarray,data);
2810 desc->componentsize = sizeof(s2);
2814 panic("Invalid array class name");
2817 desc->componentvftbl = NULL;
2818 desc->elementvftbl = NULL;
2819 desc->dimension = 1;
2820 desc->elementtype = desc->arraytype;
2827 /********************** Function: class_link ***********************************
2829 Tries to link a class. The function calculates the length in bytes that
2830 an instance of this class requires as well as the VTBL for methods and
2833 *******************************************************************************/
2835 static classinfo *class_link_intern(classinfo *c);
2837 classinfo *class_link(classinfo *c)
2841 #if defined(USE_THREADS)
2842 /* enter a monitor on the class */
2844 builtin_monitorenter((java_objectheader *) c);
2847 /* maybe the class is already linked */
2849 #if defined(USE_THREADS)
2850 builtin_monitorexit((java_objectheader *) c);
2858 if (getcompilingtime)
2859 compilingtime_stop();
2862 loadingtime_start();
2864 /* call the internal function */
2865 r = class_link_intern(c);
2867 /* if return value is NULL, we had a problem and the class is not linked */
2876 if (getcompilingtime)
2877 compilingtime_start();
2879 #if defined(USE_THREADS)
2880 /* leave the monitor */
2882 builtin_monitorexit((java_objectheader *) c);
2889 static classinfo *class_link_intern(classinfo *c)
2891 s4 supervftbllength; /* vftbllegnth of super class */
2892 s4 vftbllength; /* vftbllength of current class */
2893 s4 interfacetablelength; /* interface table length */
2894 classinfo *super; /* super class */
2895 classinfo *tc; /* temporary class variable */
2896 vftbl_t *v; /* vftbl of current class */
2897 s4 i; /* interface/method/field counter */
2898 arraydescriptor *arraydesc; /* descriptor for array classes */
2900 /* maybe the class is already linked */
2904 /* maybe the class is not loaded */
2910 log_message_class("Linking class: ", c);
2912 /* ok, this class is somewhat linked */
2917 /* check interfaces */
2919 for (i = 0; i < c->interfacescount; i++) {
2920 tc = c->interfaces[i];
2922 /* detect circularity */
2925 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2931 if (!class_load(tc))
2934 if (!(tc->flags & ACC_INTERFACE)) {
2936 new_exception_message(string_java_lang_IncompatibleClassChangeError,
2937 "Implementing class");
2942 if (!class_link(tc))
2946 /* check super class */
2950 if (super == NULL) { /* class java.lang.Object */
2952 c->classUsed = USED; /* Object class is always used CO-RT*/
2954 c->instancesize = sizeof(java_objectheader);
2956 vftbllength = supervftbllength = 0;
2958 c->finalizer = NULL;
2961 /* detect circularity */
2964 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2970 if (!class_load(super))
2973 if (super->flags & ACC_INTERFACE) {
2974 /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
2975 panic("Interface specified as super class");
2978 /* Don't allow extending final classes */
2979 if (super->flags & ACC_FINAL) {
2981 new_exception_message(string_java_lang_VerifyError,
2982 "Cannot inherit from final class");
2987 if (!class_link(super))
2990 /* handle array classes */
2991 if (c->name->text[0] == '[')
2992 if (!(arraydesc = class_link_array(c)))
2995 if (c->flags & ACC_INTERFACE)
2996 c->index = interfaceindex++;
2998 c->index = super->index + 1;
3000 c->instancesize = super->instancesize;
3002 vftbllength = supervftbllength = super->vftbl->vftbllength;
3004 c->finalizer = super->finalizer;
3007 /* compute vftbl length */
3009 for (i = 0; i < c->methodscount; i++) {
3010 methodinfo *m = &(c->methods[i]);
3012 if (!(m->flags & ACC_STATIC)) { /* is instance method */
3017 for (j = 0; j < tc->methodscount; j++) {
3018 if (method_canoverwrite(m, &(tc->methods[j]))) {
3019 if (tc->methods[j].flags & ACC_PRIVATE)
3020 goto notfoundvftblindex;
3022 if (tc->methods[j].flags & ACC_FINAL) {
3023 /* class a overrides final method . */
3025 new_exception(string_java_lang_VerifyError);
3028 m->vftblindex = tc->methods[j].vftblindex;
3029 goto foundvftblindex;
3035 m->vftblindex = (vftbllength++);
3041 #if defined(STATISTICS)
3044 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
3047 /* compute interfacetable length */
3049 interfacetablelength = 0;
3052 for (i = 0; i < tc->interfacescount; i++) {
3053 s4 h = class_highestinterface(tc->interfaces[i]) + 1;
3054 if (h > interfacetablelength)
3055 interfacetablelength = h;
3060 /* allocate virtual function table */
3062 v = (vftbl_t*) mem_alloc(sizeof(vftbl_t) + sizeof(methodptr) *
3063 (vftbllength - 1) + sizeof(methodptr*) *
3064 (interfacetablelength - (interfacetablelength > 0)));
3065 v = (vftbl_t*) (((methodptr*) v) + (interfacetablelength - 1) *
3066 (interfacetablelength > 1));
3067 c->header.vftbl = c->vftbl = v;
3069 v->vftbllength = vftbllength;
3070 v->interfacetablelength = interfacetablelength;
3071 v->arraydesc = arraydesc;
3073 /* store interface index in vftbl */
3074 if (c->flags & ACC_INTERFACE)
3075 v->baseval = -(c->index);
3077 /* copy virtual function table of super class */
3079 for (i = 0; i < supervftbllength; i++)
3080 v->table[i] = super->vftbl->table[i];
3082 /* add method stubs into virtual function table */
3084 for (i = 0; i < c->methodscount; i++) {
3085 methodinfo *m = &(c->methods[i]);
3086 if (!(m->flags & ACC_STATIC)) {
3087 v->table[m->vftblindex] = m->stubroutine;
3091 /* compute instance size and offset of each field */
3093 for (i = 0; i < c->fieldscount; i++) {
3095 fieldinfo *f = &(c->fields[i]);
3097 if (!(f->flags & ACC_STATIC)) {
3098 dsize = desc_typesize(f->descriptor);
3099 c->instancesize = ALIGN(c->instancesize, dsize);
3100 f->offset = c->instancesize;
3101 c->instancesize += dsize;
3105 /* initialize interfacetable and interfacevftbllength */
3107 v->interfacevftbllength = MNEW(s4, interfacetablelength);
3109 #if defined(STATISTICS)
3111 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
3114 for (i = 0; i < interfacetablelength; i++) {
3115 v->interfacevftbllength[i] = 0;
3116 v->interfacetable[-i] = NULL;
3119 /* add interfaces */
3121 for (tc = c; tc != NULL; tc = tc->super) {
3122 for (i = 0; i < tc->interfacescount; i++) {
3123 class_addinterface(c, tc->interfaces[i]);
3127 /* add finalizer method (not for java.lang.Object) */
3132 fi = class_findmethod(c, utf_finalize, utf_fidesc);
3135 if (!(fi->flags & ACC_STATIC)) {
3143 loader_compute_subclasses(c);
3146 log_message_class("Linking done class: ", c);
3148 /* just return c to show that we didn't had a problem */
3154 /******************* Function: class_freepool **********************************
3156 Frees all resources used by this classes Constant Pool.
3158 *******************************************************************************/
3160 static void class_freecpool(classinfo *c)
3166 if (c->cptags && c->cpinfos) {
3167 for (idx = 0; idx < c->cpcount; idx++) {
3168 tag = c->cptags[idx];
3169 info = c->cpinfos[idx];
3173 case CONSTANT_Fieldref:
3174 case CONSTANT_Methodref:
3175 case CONSTANT_InterfaceMethodref:
3176 FREE(info, constant_FMIref);
3178 case CONSTANT_Integer:
3179 FREE(info, constant_integer);
3181 case CONSTANT_Float:
3182 FREE(info, constant_float);
3185 FREE(info, constant_long);
3187 case CONSTANT_Double:
3188 FREE(info, constant_double);
3190 case CONSTANT_NameAndType:
3191 FREE(info, constant_nameandtype);
3199 MFREE(c->cptags, u1, c->cpcount);
3202 MFREE(c->cpinfos, voidptr, c->cpcount);
3206 /*********************** Function: class_free **********************************
3208 Frees all resources used by the class.
3210 *******************************************************************************/
3212 void class_free(classinfo *c)
3220 MFREE(c->interfaces, classinfo*, c->interfacescount);
3223 for (i = 0; i < c->fieldscount; i++)
3224 field_free(&(c->fields[i]));
3225 /* MFREE(c->fields, fieldinfo, c->fieldscount); */
3229 for (i = 0; i < c->methodscount; i++)
3230 method_free(&(c->methods[i]));
3231 /* MFREE(c->methods, methodinfo, c->methodscount); */
3234 if ((v = c->vftbl) != NULL) {
3236 mem_free(v->arraydesc,sizeof(arraydescriptor));
3238 for (i = 0; i < v->interfacetablelength; i++) {
3239 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
3241 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
3243 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
3244 sizeof(methodptr*) * (v->interfacetablelength -
3245 (v->interfacetablelength > 0));
3246 v = (vftbl_t*) (((methodptr*) v) - (v->interfacetablelength - 1) *
3247 (v->interfacetablelength > 1));
3252 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
3254 /* if (c->classvftbl)
3255 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
3261 /************************* Function: class_findfield ***************************
3263 Searches a 'classinfo' structure for a field having the given name and
3266 *******************************************************************************/
3268 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
3272 for (i = 0; i < c->fieldscount; i++) {
3273 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
3274 return &(c->fields[i]);
3277 panic("Can not find field given in CONSTANT_Fieldref");
3279 /* keep compiler happy */
3284 /****************** Function: class_resolvefield_int ***************************
3286 This is an internally used helper function. Do not use this directly.
3288 Tries to resolve a field having the given name and type.
3289 If the field cannot be resolved, NULL is returned.
3291 *******************************************************************************/
3293 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
3298 /* search for field in class c */
3299 for (i = 0; i < c->fieldscount; i++) {
3300 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
3301 return &(c->fields[i]);
3305 /* try superinterfaces recursively */
3306 for (i = 0; i < c->interfacescount; ++i) {
3307 fi = class_resolvefield_int(c->interfaces[i], name, desc);
3312 /* try superclass */
3314 return class_resolvefield_int(c->super, name, desc);
3321 /********************* Function: class_resolvefield ***************************
3323 Resolves a reference from REFERER to a field with NAME and DESC in class C.
3325 If the field cannot be resolved the return value is NULL. If EXCEPT is
3326 true *exceptionptr is set, too.
3328 *******************************************************************************/
3330 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
3331 classinfo *referer, bool except)
3335 /* XXX resolve class c */
3336 /* XXX check access from REFERER to C */
3338 fi = class_resolvefield_int(c, name, desc);
3343 new_exception_utfmessage(string_java_lang_NoSuchFieldError,
3349 /* XXX check access rights */
3355 /************************* Function: class_findmethod **************************
3357 Searches a 'classinfo' structure for a method having the given name and
3358 type and returns the index in the class info structure.
3359 If type is NULL, it is ignored.
3361 *******************************************************************************/
3363 s4 class_findmethodIndex(classinfo *c, utf *name, utf *desc)
3367 for (i = 0; i < c->methodscount; i++) {
3369 /* utf_display_classname(c->name);printf("."); */
3370 /* utf_display(c->methods[i].name);printf("."); */
3371 /* utf_display(c->methods[i].descriptor); */
3374 if ((c->methods[i].name == name) && ((desc == NULL) ||
3375 (c->methods[i].descriptor == desc))) {
3384 /************************* Function: class_findmethod **************************
3386 Searches a 'classinfo' structure for a method having the given name and
3388 If type is NULL, it is ignored.
3390 *******************************************************************************/
3392 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
3394 s4 idx = class_findmethodIndex(c, name, desc);
3399 return &(c->methods[idx]);
3403 /*********************** Function: class_fetchmethod **************************
3405 like class_findmethod, but aborts with an error if the method is not found
3407 *******************************************************************************/
3409 methodinfo *class_fetchmethod(classinfo *c, utf *name, utf *desc)
3413 mi = class_findmethod(c, name, desc);
3416 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3417 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3418 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3419 panic("Method not found");
3426 /*********************** Function: class_findmethod_w**************************
3428 like class_findmethod, but logs a warning if the method is not found
3430 *******************************************************************************/
3432 methodinfo *class_findmethod_w(classinfo *c, utf *name, utf *desc, char *from)
3435 mi = class_findmethod(c, name, desc);
3438 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3439 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3440 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3442 if ( c->flags & ACC_PUBLIC ) log_plain(" PUBLIC ");
3443 if ( c->flags & ACC_PRIVATE ) log_plain(" PRIVATE ");
3444 if ( c->flags & ACC_PROTECTED ) log_plain(" PROTECTED ");
3445 if ( c->flags & ACC_STATIC ) log_plain(" STATIC ");
3446 if ( c->flags & ACC_FINAL ) log_plain(" FINAL ");
3447 if ( c->flags & ACC_SYNCHRONIZED ) log_plain(" SYNCHRONIZED ");
3448 if ( c->flags & ACC_VOLATILE ) log_plain(" VOLATILE ");
3449 if ( c->flags & ACC_TRANSIENT ) log_plain(" TRANSIENT ");
3450 if ( c->flags & ACC_NATIVE ) log_plain(" NATIVE ");
3451 if ( c->flags & ACC_INTERFACE ) log_plain(" INTERFACE ");
3452 if ( c->flags & ACC_ABSTRACT ) log_plain(" ABSTRACT ");
3455 log_plain(" : WARNING: Method not found");log_nl( );
3462 /************************* Function: class_findmethod_approx ******************
3464 like class_findmethod but ignores the return value when comparing the
3467 *******************************************************************************/
3469 methodinfo *class_findmethod_approx(classinfo *c, utf *name, utf *desc)
3473 for (i = 0; i < c->methodscount; i++) {
3474 if (c->methods[i].name == name) {
3475 utf *meth_descr = c->methods[i].descriptor;
3479 return &(c->methods[i]);
3481 if (desc->blength <= meth_descr->blength) {
3482 /* current position in utf text */
3483 char *desc_utf_ptr = desc->text;
3484 char *meth_utf_ptr = meth_descr->text;
3485 /* points behind utf strings */
3486 char *desc_end = utf_end(desc);
3487 char *meth_end = utf_end(meth_descr);
3490 /* compare argument types */
3491 while (desc_utf_ptr < desc_end && meth_utf_ptr < meth_end) {
3493 if ((ch = *desc_utf_ptr++) != (*meth_utf_ptr++))
3494 break; /* no match */
3497 return &(c->methods[i]); /* all parameter types equal */
3507 /***************** Function: class_resolvemethod_approx ***********************
3509 Searches a class and every super class for a method (without paying
3510 attention to the return value)
3512 *******************************************************************************/
3514 methodinfo *class_resolvemethod_approx(classinfo *c, utf *name, utf *desc)
3517 /* search for method (ignore returntype) */
3518 methodinfo *m = class_findmethod_approx(c, name, desc);
3521 /* search superclass */
3529 /************************* Function: class_resolvemethod ***********************
3531 Searches a class and every super class for a method.
3533 *******************************************************************************/
3535 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
3537 /*log_text("Trying to resolve a method");
3538 utf_display(c->name);
3540 utf_display(desc);*/
3543 /*log_text("Looking in:");
3544 utf_display(c->name);*/
3545 methodinfo *m = class_findmethod(c, name, desc);
3547 /* search superclass */
3550 /*log_text("method not found:");*/
3556 /****************** Function: class_resolveinterfacemethod_int ****************
3558 Internally used helper function. Do not use this directly.
3560 *******************************************************************************/
3563 methodinfo *class_resolveinterfacemethod_int(classinfo *c, utf *name, utf *desc)
3568 mi = class_findmethod(c,name,desc);
3572 /* try the superinterfaces */
3573 for (i=0; i<c->interfacescount; ++i) {
3574 mi = class_resolveinterfacemethod_int(c->interfaces[i],name,desc);
3582 /******************** Function: class_resolveinterfacemethod ******************
3584 Resolves a reference from REFERER to a method with NAME and DESC in
3587 If the method cannot be resolved the return value is NULL. If EXCEPT is
3588 true *exceptionptr is set, too.
3590 *******************************************************************************/
3592 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
3593 classinfo *referer, bool except)
3597 /* XXX resolve class c */
3598 /* XXX check access from REFERER to C */
3600 if (!(c->flags & ACC_INTERFACE)) {
3603 new_exception(string_java_lang_IncompatibleClassChangeError);
3608 mi = class_resolveinterfacemethod_int(c, name, desc);
3613 /* try class java.lang.Object */
3614 mi = class_findmethod(class_java_lang_Object, name, desc);
3621 new_exception_utfmessage(string_java_lang_NoSuchMethodError, name);
3627 /********************* Function: class_resolveclassmethod *********************
3629 Resolves a reference from REFERER to a method with NAME and DESC in
3632 If the method cannot be resolved the return value is NULL. If EXCEPT is
3633 true *exceptionptr is set, too.
3635 *******************************************************************************/
3637 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
3638 classinfo *referer, bool except)
3643 char msg[MAXLOGTEXT];
3645 /* XXX resolve class c */
3646 /* XXX check access from REFERER to C */
3648 /* if (c->flags & ACC_INTERFACE) { */
3650 /* *exceptionptr = */
3651 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
3655 /* try class c and its superclasses */
3658 mi = class_findmethod(cls, name, desc);
3661 } while ((cls = cls->super) != NULL); /* try the superclass */
3663 /* try the superinterfaces */
3664 for (i = 0; i < c->interfacescount; ++i) {
3665 mi = class_resolveinterfacemethod_int(c->interfaces[i], name, desc);
3671 utf_sprint(msg, c->name);
3672 sprintf(msg + strlen(msg), ".");
3673 utf_sprint(msg + strlen(msg), name);
3674 utf_sprint(msg + strlen(msg), desc);
3677 new_exception_message(string_java_lang_NoSuchMethodError, msg);
3683 if ((mi->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
3685 *exceptionptr = new_exception(string_java_lang_AbstractMethodError);
3690 /* XXX check access rights */
3696 /************************* Function: class_issubclass **************************
3698 Checks if sub is a descendant of super.
3700 *******************************************************************************/
3702 bool class_issubclass(classinfo *sub, classinfo *super)
3705 if (!sub) return false;
3706 if (sub == super) return true;
3712 /****************** Initialization function for classes ******************
3714 In Java, every class can have a static initialization function. This
3715 function has to be called BEFORE calling other methods or accessing static
3718 *******************************************************************************/
3720 static classinfo *class_init_intern(classinfo *c);
3722 classinfo *class_init(classinfo *c)
3726 if (!makeinitializations)
3729 #if defined(USE_THREADS)
3730 /* enter a monitor on the class */
3732 builtin_monitorenter((java_objectheader *) c);
3735 /* maybe the class is already initalized or the current thread, which can
3736 pass the monitor, is currently initalizing this class */
3738 /* JOWENN: In future we need an additinal flag: initializationfailed,
3739 since further access to the class should cause a NoClassDefFound,
3740 if the static initializer failed once
3743 if (c->initialized || c->initializing) {
3744 #if defined(USE_THREADS)
3745 builtin_monitorexit((java_objectheader *) c);
3751 /* this initalizing run begins NOW */
3752 c->initializing = true;
3754 /* call the internal function */
3755 r = class_init_intern(c);
3757 /* if return value is not NULL everything was ok and the class is
3760 c->initialized = true;
3762 /* this initalizing run is done */
3763 c->initializing = false;
3765 #if defined(USE_THREADS)
3766 /* leave the monitor */
3768 builtin_monitorexit((java_objectheader *) c);
3775 /* this function MUST NOT be called directly, because of thread <clinit>
3778 static classinfo *class_init_intern(classinfo *c)
3782 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3786 /* maybe the class is not already loaded */
3791 /* maybe the class is not already linked */
3796 #if defined(STATISTICS)
3798 count_class_inits++;
3801 /* initialize super class */
3804 if (!c->super->initialized) {
3806 char logtext[MAXLOGTEXT];
3807 sprintf(logtext, "Initialize super class ");
3808 utf_sprint_classname(logtext + strlen(logtext), c->super->name);
3809 sprintf(logtext + strlen(logtext), " from ");
3810 utf_sprint_classname(logtext + strlen(logtext), c->name);
3814 if (!class_init(c->super))
3819 /* initialize interface classes */
3821 for (i = 0; i < c->interfacescount; i++) {
3822 if (!c->interfaces[i]->initialized) {
3824 char logtext[MAXLOGTEXT];
3825 sprintf(logtext, "Initialize interface class ");
3826 utf_sprint_classname(logtext + strlen(logtext), c->interfaces[i]->name);
3827 sprintf(logtext + strlen(logtext), " from ");
3828 utf_sprint_classname(logtext + strlen(logtext), c->name);
3832 if (!class_init(c->interfaces[i]))
3837 m = class_findmethod(c, utf_clinit, utf_fidesc);
3841 char logtext[MAXLOGTEXT];
3842 sprintf(logtext, "Class ");
3843 utf_sprint_classname(logtext + strlen(logtext), c->name);
3844 sprintf(logtext + strlen(logtext), " has no static class initializer");
3851 /* Sun's and IBM's JVM don't care about the static flag */
3852 /* if (!(m->flags & ACC_STATIC)) { */
3853 /* panic("Class initializer is not static!"); */
3856 log_message_class("Starting static class initializer for class: ", c);
3858 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3863 /* now call the initializer */
3864 asm_calljavafunction(m, NULL, NULL, NULL, NULL);
3866 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3867 assert(blockInts == 0);
3871 /* we have an exception or error */
3872 if (*exceptionptr) {
3873 /* class is NOT initialized */
3874 c->initialized = false;
3876 /* is this an exception, than wrap it */
3877 if (builtin_instanceof(*exceptionptr, class_java_lang_Exception)) {
3878 java_objectheader *xptr;
3879 java_objectheader *cause;
3882 cause = *exceptionptr;
3884 /* clear exception, because we are calling jit code again */
3885 *exceptionptr = NULL;
3887 /* wrap the exception */
3889 new_exception_throwable(string_java_lang_ExceptionInInitializerError,
3890 (java_lang_Throwable *) cause);
3892 /* XXX should we exit here? */
3896 /* set new exception */
3897 *exceptionptr = xptr;
3904 log_message_class("Finished static class initializer for class: ", c);
3910 /********* Function: find_class_method_constant *********/
3912 int find_class_method_constant (classinfo *c, utf * c1, utf* m1, utf* d1)
3917 for (i=0; i<c->cpcount; i++) {
3919 e = c -> cpinfos [i];
3922 switch (c -> cptags [i]) {
3923 case CONSTANT_Methodref:
3925 constant_FMIref *fmi = e;
3926 if ( (fmi->class->name == c1)
3927 && (fmi->name == m1)
3928 && (fmi->descriptor == d1)) {
3935 case CONSTANT_InterfaceMethodref:
3937 constant_FMIref *fmi = e;
3938 if ( (fmi->class->name == c1)
3939 && (fmi->name == m1)
3940 && (fmi->descriptor == d1)) {
3954 void class_showconstanti(classinfo *c, int ii)
3960 printf ("#%d: ", (int) i);
3962 switch (c->cptags [i]) {
3963 case CONSTANT_Class:
3964 printf("Classreference -> ");
3965 utf_display(((classinfo*)e)->name);
3968 case CONSTANT_Fieldref:
3969 printf("Fieldref -> "); goto displayFMIi;
3970 case CONSTANT_Methodref:
3971 printf("Methodref -> "); goto displayFMIi;
3972 case CONSTANT_InterfaceMethodref:
3973 printf("InterfaceMethod -> "); goto displayFMIi;
3976 constant_FMIref *fmi = e;
3977 utf_display(fmi->class->name);
3979 utf_display(fmi->name);
3981 utf_display(fmi->descriptor);
3985 case CONSTANT_String:
3986 printf("String -> ");
3989 case CONSTANT_Integer:
3990 printf("Integer -> %d", (int) (((constant_integer*)e)->value));
3992 case CONSTANT_Float:
3993 printf("Float -> %f", ((constant_float*)e)->value);
3995 case CONSTANT_Double:
3996 printf("Double -> %f", ((constant_double*)e)->value);
4000 u8 v = ((constant_long*)e)->value;
4002 printf("Long -> %ld", (long int) v);
4004 printf("Long -> HI: %ld, LO: %ld\n",
4005 (long int) v.high, (long int) v.low);
4009 case CONSTANT_NameAndType:
4011 constant_nameandtype *cnt = e;
4012 printf("NameAndType: ");
4013 utf_display(cnt->name);
4015 utf_display(cnt->descriptor);
4023 panic("Invalid type of ConstantPool-Entry");
4030 void class_showconstantpool (classinfo *c)
4035 printf ("---- dump of constant pool ----\n");
4037 for (i=0; i<c->cpcount; i++) {
4038 printf ("#%d: ", (int) i);
4040 e = c -> cpinfos [i];
4043 switch (c -> cptags [i]) {
4044 case CONSTANT_Class:
4045 printf ("Classreference -> ");
4046 utf_display ( ((classinfo*)e) -> name );
4049 case CONSTANT_Fieldref:
4050 printf ("Fieldref -> "); goto displayFMI;
4051 case CONSTANT_Methodref:
4052 printf ("Methodref -> "); goto displayFMI;
4053 case CONSTANT_InterfaceMethodref:
4054 printf ("InterfaceMethod -> "); goto displayFMI;
4057 constant_FMIref *fmi = e;
4058 utf_display ( fmi->class->name );
4060 utf_display ( fmi->name);
4062 utf_display ( fmi->descriptor );
4066 case CONSTANT_String:
4067 printf ("String -> ");
4070 case CONSTANT_Integer:
4071 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
4073 case CONSTANT_Float:
4074 printf ("Float -> %f", ((constant_float*)e) -> value);
4076 case CONSTANT_Double:
4077 printf ("Double -> %f", ((constant_double*)e) -> value);
4081 u8 v = ((constant_long*)e) -> value;
4083 printf ("Long -> %ld", (long int) v);
4085 printf ("Long -> HI: %ld, LO: %ld\n",
4086 (long int) v.high, (long int) v.low);
4090 case CONSTANT_NameAndType:
4092 constant_nameandtype *cnt = e;
4093 printf ("NameAndType: ");
4094 utf_display (cnt->name);
4096 utf_display (cnt->descriptor);
4100 printf ("Utf8 -> ");
4104 panic ("Invalid type of ConstantPool-Entry");
4114 /********** Function: class_showmethods (debugging only) *************/
4116 void class_showmethods (classinfo *c)
4120 printf ("--------- Fields and Methods ----------------\n");
4121 printf ("Flags: "); printflags (c->flags); printf ("\n");
4123 printf ("This: "); utf_display (c->name); printf ("\n");
4125 printf ("Super: "); utf_display (c->super->name); printf ("\n");
4127 printf ("Index: %d\n", c->index);
4129 printf ("interfaces:\n");
4130 for (i=0; i < c-> interfacescount; i++) {
4132 utf_display (c -> interfaces[i] -> name);
4133 printf (" (%d)\n", c->interfaces[i] -> index);
4136 printf ("fields:\n");
4137 for (i=0; i < c -> fieldscount; i++) {
4138 field_display (&(c -> fields[i]));
4141 printf ("methods:\n");
4142 for (i=0; i < c -> methodscount; i++) {
4143 methodinfo *m = &(c->methods[i]);
4144 if ( !(m->flags & ACC_STATIC))
4145 printf ("vftblindex: %d ", m->vftblindex);
4147 method_display ( m );
4151 printf ("Virtual function table:\n");
4152 for (i=0; i<c->vftbl->vftbllength; i++) {
4153 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]) );
4159 /******************************************************************************/
4160 /******************* General functions for the class loader *******************/
4161 /******************************************************************************/
4163 /**************** function: create_primitive_classes ***************************
4165 create classes representing primitive types
4167 *******************************************************************************/
4169 static bool create_primitive_classes()
4173 for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
4174 /* create primitive class */
4176 class_new_intern(utf_new_char(primitivetype_table[i].name));
4177 c->classUsed = NOTUSED; /* not used initially CO-RT */
4180 /* prevent loader from loading primitive class */
4185 primitivetype_table[i].class_primitive = c;
4187 /* create class for wrapping the primitive type */
4188 c = class_new_intern(utf_new_char(primitivetype_table[i].wrapname));
4189 primitivetype_table[i].class_wrap = c;
4190 primitivetype_table[i].class_wrap->classUsed = NOTUSED; /* not used initially CO-RT */
4191 primitivetype_table[i].class_wrap->impldBy = NULL;
4193 /* create the primitive array class */
4194 if (primitivetype_table[i].arrayname) {
4195 c = class_new_intern(utf_new_char(primitivetype_table[i].arrayname));
4196 primitivetype_table[i].arrayclass = c;
4201 primitivetype_table[i].arrayvftbl = c->vftbl;
4209 /**************** function: class_primitive_from_sig ***************************
4211 return the primitive class indicated by the given signature character
4213 If the descriptor does not indicate a valid primitive type the
4214 return value is NULL.
4216 ********************************************************************************/
4218 classinfo *class_primitive_from_sig(char sig)
4221 case 'I': return primitivetype_table[PRIMITIVETYPE_INT].class_primitive;
4222 case 'J': return primitivetype_table[PRIMITIVETYPE_LONG].class_primitive;
4223 case 'F': return primitivetype_table[PRIMITIVETYPE_FLOAT].class_primitive;
4224 case 'D': return primitivetype_table[PRIMITIVETYPE_DOUBLE].class_primitive;
4225 case 'B': return primitivetype_table[PRIMITIVETYPE_BYTE].class_primitive;
4226 case 'C': return primitivetype_table[PRIMITIVETYPE_CHAR].class_primitive;
4227 case 'S': return primitivetype_table[PRIMITIVETYPE_SHORT].class_primitive;
4228 case 'Z': return primitivetype_table[PRIMITIVETYPE_BOOLEAN].class_primitive;
4229 case 'V': return primitivetype_table[PRIMITIVETYPE_VOID].class_primitive;
4234 /****************** function: class_from_descriptor ****************************
4236 return the class indicated by the given descriptor
4238 utf_ptr....first character of descriptor
4239 end_ptr....first character after the end of the string
4240 next.......if non-NULL, *next is set to the first character after
4241 the descriptor. (Undefined if an error occurs.)
4243 mode.......a combination (binary or) of the following flags:
4245 (Flags marked with * are the default settings.)
4247 What to do if a reference type descriptor is parsed successfully:
4249 CLASSLOAD_SKIP...skip it and return something != NULL
4250 * CLASSLOAD_NEW....get classinfo * via class_new
4251 CLASSLOAD_LOAD...get classinfo * via loader_load
4253 How to handle primitive types:
4255 * CLASSLOAD_PRIMITIVE.......return primitive class (eg. "int")
4256 CLASSLOAD_NULLPRIMITIVE...return NULL for primitive types
4258 How to handle "V" descriptors:
4260 * CLASSLOAD_VOID.....handle it like other primitive types
4261 CLASSLOAD_NOVOID...treat it as an error
4263 How to deal with extra characters after the end of the
4266 * CLASSLOAD_NOCHECKEND...ignore (useful for parameter lists)
4267 CLASSLOAD_CHECKEND.....treat them as an error
4269 How to deal with errors:
4271 * CLASSLOAD_PANIC....abort execution with an error message
4272 CLASSLOAD_NOPANIC..return NULL on error
4274 *******************************************************************************/
4276 classinfo *class_from_descriptor(char *utf_ptr, char *end_ptr,
4277 char **next, int mode)
4279 char *start = utf_ptr;
4283 SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr, end_ptr, error);
4285 if (mode & CLASSLOAD_CHECKEND)
4286 error |= (utf_ptr != end_ptr);
4289 if (next) *next = utf_ptr;
4293 if (mode & CLASSLOAD_NOVOID)
4304 return (mode & CLASSLOAD_NULLPRIMITIVE)
4306 : class_primitive_from_sig(*start);
4313 if (mode & CLASSLOAD_SKIP) return class_java_lang_Object;
4314 name = utf_new(start, utf_ptr - start);
4318 tc = class_new_intern(name);
4320 list_addfirst(&unlinkedclasses, tc);
4325 return (mode & CLASSLOAD_LOAD)
4326 ? class_load(class_new(name)) : class_new(name); /* XXX handle errors */
4331 /* An error occurred */
4332 if (mode & CLASSLOAD_NOPANIC)
4335 log_plain("Invalid descriptor at beginning of '");
4336 log_plain_utf(utf_new(start, end_ptr - start));
4340 panic("Invalid descriptor");
4342 /* keep compiler happy */
4347 /******************* function: type_from_descriptor ****************************
4349 return the basic type indicated by the given descriptor
4351 This function parses a descriptor and returns its basic type as
4352 TYPE_INT, TYPE_LONG, TYPE_FLOAT, TYPE_DOUBLE, TYPE_ADDRESS or TYPE_VOID.
4354 cls...if non-NULL the referenced variable is set to the classinfo *
4355 returned by class_from_descriptor.
4357 For documentation of the arguments utf_ptr, end_ptr, next and mode
4358 see class_from_descriptor. The only difference is that
4359 type_from_descriptor always uses CLASSLOAD_PANIC.
4361 ********************************************************************************/
4363 int type_from_descriptor(classinfo **cls, char *utf_ptr, char *end_ptr,
4364 char **next, int mode)
4367 if (!cls) cls = &mycls;
4368 *cls = class_from_descriptor(utf_ptr, end_ptr, next, mode & (~CLASSLOAD_NOPANIC));
4385 return TYPE_ADDRESS;
4389 /*************** function: create_pseudo_classes *******************************
4391 create pseudo classes used by the typechecker
4393 ********************************************************************************/
4395 static void create_pseudo_classes()
4397 /* pseudo class for Arraystubs (extends java.lang.Object) */
4399 pseudo_class_Arraystub = class_new_intern(utf_new_char("$ARRAYSTUB$"));
4400 pseudo_class_Arraystub->loaded = true;
4401 pseudo_class_Arraystub->super = class_java_lang_Object;
4402 pseudo_class_Arraystub->interfacescount = 2;
4403 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
4404 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
4405 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
4407 class_link(pseudo_class_Arraystub);
4409 pseudo_class_Arraystub_vftbl = pseudo_class_Arraystub->vftbl;
4411 /* pseudo class representing the null type */
4413 pseudo_class_Null = class_new_intern(utf_new_char("$NULL$"));
4414 pseudo_class_Null->loaded = true;
4415 pseudo_class_Null->super = class_java_lang_Object;
4416 class_link(pseudo_class_Null);
4418 /* pseudo class representing new uninitialized objects */
4420 pseudo_class_New = class_new_intern(utf_new_char("$NEW$"));
4421 pseudo_class_New->loaded = true;
4422 pseudo_class_New->linked = true;
4423 pseudo_class_New->super = class_java_lang_Object;
4424 /* class_link(pseudo_class_New); */
4428 /********************** Function: loader_init **********************************
4430 Initializes all lists and loads all classes required for the system or the
4433 *******************************************************************************/
4435 void loader_init(u1 *stackbottom)
4439 /* create utf-symbols for pointer comparison of frequently used strings */
4440 utf_innerclasses = utf_new_char("InnerClasses");
4441 utf_constantvalue = utf_new_char("ConstantValue");
4442 utf_code = utf_new_char("Code");
4443 utf_exceptions = utf_new_char("Exceptions");
4444 utf_linenumbertable = utf_new_char("LineNumberTable");
4445 utf_sourcefile = utf_new_char("SourceFile");
4446 utf_finalize = utf_new_char("finalize");
4447 utf_fidesc = utf_new_char("()V");
4448 utf_init = utf_new_char("<init>");
4449 utf_clinit = utf_new_char("<clinit>");
4450 utf_initsystemclass = utf_new_char("initializeSystemClass");
4451 utf_systemclass = utf_new_char("java/lang/System");
4452 utf_vmclassloader = utf_new_char("java/lang/VMClassLoader");
4453 utf_initialize = utf_new_char("initialize");
4454 utf_initializedesc = utf_new_char("(I)V");
4455 utf_vmclass = utf_new_char("java/lang/VMClass");
4456 utf_java_lang_Object= utf_new_char("java/lang/Object");
4457 array_packagename = utf_new_char("<the array package>");
4458 utf_fillInStackTrace_name = utf_new_char("fillInStackTrace");
4459 utf_fillInStackTrace_desc = utf_new_char("()Ljava/lang/Throwable;");
4461 /* create some important classes */
4462 /* These classes have to be created now because the classinfo
4463 * pointers are used in the loading code.
4465 class_java_lang_Object = class_new_intern(utf_java_lang_Object);
4466 class_load(class_java_lang_Object);
4467 class_link(class_java_lang_Object);
4469 class_java_lang_String = class_new(utf_new_char("java/lang/String"));
4470 class_load(class_java_lang_String);
4471 class_link(class_java_lang_String);
4473 class_java_lang_Cloneable = class_new(utf_new_char("java/lang/Cloneable"));
4474 class_load(class_java_lang_Cloneable);
4475 class_link(class_java_lang_Cloneable);
4477 class_java_io_Serializable =
4478 class_new(utf_new_char("java/io/Serializable"));
4479 class_load(class_java_io_Serializable);
4480 class_link(class_java_io_Serializable);
4482 /* create classes representing primitive types */
4483 create_primitive_classes();
4485 /* create classes used by the typechecker */
4486 create_pseudo_classes();
4488 /* correct vftbl-entries (retarded loading of class java/lang/String) */
4489 stringtable_update();
4491 #if defined(USE_THREADS)
4492 if (stackbottom != 0)
4498 /* loader_compute_subclasses ***************************************************
4502 *******************************************************************************/
4504 static void loader_compute_class_values(classinfo *c);
4506 void loader_compute_subclasses(classinfo *c)
4508 #if defined(USE_THREADS)
4509 #if defined(NATIVE_THREADS)
4516 if (!(c->flags & ACC_INTERFACE)) {
4521 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
4522 c->nextsub = c->super->sub;
4528 /* this is the java.lang.Object special case */
4530 if (!class_java_lang_Object) {
4531 loader_compute_class_values(c);
4534 loader_compute_class_values(class_java_lang_Object);
4537 #if defined(USE_THREADS)
4538 #if defined(NATIVE_THREADS)
4547 /* loader_compute_class_values *************************************************
4551 *******************************************************************************/
4553 static void loader_compute_class_values(classinfo *c)
4557 c->vftbl->baseval = ++classvalue;
4561 loader_compute_class_values(subs);
4562 subs = subs->nextsub;
4565 c->vftbl->diffval = classvalue - c->vftbl->baseval;
4569 /******************** Function: loader_close ***********************************
4573 *******************************************************************************/
4580 for (slot = 0; slot < class_hash.size; slot++) {
4581 c = class_hash.ptr[slot];
4592 * These are local overrides for various environment variables in Emacs.
4593 * Please do not remove this and leave it at the end of the file, where
4594 * Emacs will automagically detect them.
4595 * ---------------------------------------------------------------------
4598 * indent-tabs-mode: t