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 1735 2004-12-07 14:33:27Z twisti $
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;
340 for (start = classpath; (*start) != '\0';) {
342 /* search for ':' delimiter to get the end of the current entry */
343 for (end = start; ((*end) != '\0') && ((*end) != ':'); end++);
347 filenamelen = end - start;
349 if (filenamelen > 3) {
350 if (strncasecmp(end - 3, "zip", 3) == 0 ||
351 strncasecmp(end - 3, "jar", 3) == 0) {
356 /* allocate memory for filename and fill it */
358 filename = MNEW(char, filenamelen + 2); /* 2 = "/\0" */
359 strncpy(filename, start, filenamelen);
360 filename[filenamelen + 1] = '\0';
364 #if defined(USE_ZLIB)
365 unzFile uf = unzOpen(filename);
368 cpi = (union classpath_info *) NEW(classpath_info);
369 cpi->archive.type = CLASSPATH_ARCHIVE;
370 cpi->archive.uf = uf;
371 cpi->archive.next = NULL;
374 throw_cacao_exception_exit(string_java_lang_InternalError,
375 "zip/jar files not supported");
379 cpi = (union classpath_info *) NEW(classpath_info);
380 cpi->filepath.type = CLASSPATH_PATH;
381 cpi->filepath.next = NULL;
383 if (filename[filenamelen - 1] != '/') {/*PERHAPS THIS SHOULD BE READ FROM A GLOBAL CONFIGURATION */
384 filename[filenamelen] = '/';
385 filename[filenamelen + 1] = '\0';
389 cpi->filepath.path = filename;
390 cpi->filepath.pathlen = filenamelen;
393 /* attach current classpath entry */
396 if (!classpath_entries) {
397 classpath_entries = cpi;
400 lastcpi->filepath.next = cpi;
407 /* goto next classpath entry, skip ':' delimiter */
419 void create_all_classes()
423 for (cpi = classpath_entries; cpi != 0; cpi = cpi->filepath.next) {
424 #if defined(USE_ZLIB)
425 if (cpi->filepath.type == CLASSPATH_ARCHIVE) {
429 s = (unz_s *) cpi->archive.uf;
430 ce = s->cacao_dir_list;
433 (void) class_new(ce->name);
439 #if defined(USE_ZLIB)
446 /************************** function suck_start ********************************
448 returns true if classbuffer is already loaded or a file for the
449 specified class has succussfully been read in. All directories of
450 the searchpath are used to find the classfile (<classname>.class).
451 Returns false if no classfile is found and writes an error message.
453 *******************************************************************************/
455 classbuffer *suck_start(classinfo *c)
470 utf_ptr = c->name->text;
472 while (utf_ptr < utf_end(c->name)) {
473 if (filenamelen >= CLASSPATH_MAXFILENAME) {
475 new_exception_message(string_java_lang_InternalError,
476 "Filename too long");
478 /* XXX should we exit in such a case? */
479 throw_exception_exit();
483 if ((ch <= ' ' || ch > 'z') && (ch != '/')) /* invalid character */
485 filename[filenamelen++] = ch;
489 /* initialize return value */
494 filenamelen = utf_strlen(c->name) + 7; /* 7 = ".class\0" */
495 filename = MNEW(char, filenamelen);
497 utf_sprint(filename, c->name);
498 strcat(filename, ".class");
500 /* walk through all classpath entries */
502 for (cpi = classpath_entries; cpi != NULL && cb == NULL; cpi = cpi->filepath.next) {
503 #if defined(USE_ZLIB)
504 if (cpi->filepath.type == CLASSPATH_ARCHIVE) {
505 if (cacao_locate(cpi->archive.uf, c->name) == UNZ_OK) {
506 unz_file_info file_info;
508 if (unzGetCurrentFileInfo(cpi->archive.uf, &file_info, filename,
509 sizeof(filename), NULL, 0, NULL, 0) == UNZ_OK) {
510 if (unzOpenCurrentFile(cpi->archive.uf) == UNZ_OK) {
511 cb = NEW(classbuffer);
513 cb->size = file_info.uncompressed_size;
514 cb->data = MNEW(u1, cb->size);
515 cb->pos = cb->data - 1;
517 len = unzReadCurrentFile(cpi->archive.uf, cb->data, cb->size);
519 if (len != cb->size) {
521 log_text("Error while unzipping");
528 log_text("Error while opening file in archive");
532 log_text("Error while retrieving fileinfo");
535 unzCloseCurrentFile(cpi->archive.uf);
538 #endif /* USE_ZLIB */
540 path = MNEW(char, cpi->filepath.pathlen + filenamelen + 1);
541 strcpy(path, cpi->filepath.path);
542 strcat(path, filename);
544 classfile = fopen(path, "r");
546 if (classfile) { /* file exists */
547 if (!stat(path, &buffer)) { /* read classfile data */
548 cb = NEW(classbuffer);
550 cb->size = buffer.st_size;
551 cb->data = MNEW(u1, cb->size);
552 cb->pos = cb->data - 1;
554 /* read class data */
555 len = fread(cb->data, 1, cb->size, classfile);
557 if (len != buffer.st_size) {
559 /* if (ferror(classfile)) { */
568 MFREE(path, char, cpi->filepath.pathlen + filenamelen + 1);
569 #if defined(USE_ZLIB)
576 dolog("Warning: Can not open class file '%s'", filename);
579 MFREE(filename, char, filenamelen);
585 /************************** function suck_stop *********************************
587 frees memory for buffer with classfile data.
588 Caution: this function may only be called if buffer has been allocated
589 by suck_start with reading a file
591 *******************************************************************************/
593 void suck_stop(classbuffer *cb)
597 MFREE(cb->data, u1, cb->size);
598 FREE(cb, classbuffer);
602 /******************************************************************************/
603 /******************* Some support functions ***********************************/
604 /******************************************************************************/
606 void fprintflags (FILE *fp, u2 f)
608 if ( f & ACC_PUBLIC ) fprintf (fp," PUBLIC");
609 if ( f & ACC_PRIVATE ) fprintf (fp," PRIVATE");
610 if ( f & ACC_PROTECTED ) fprintf (fp," PROTECTED");
611 if ( f & ACC_STATIC ) fprintf (fp," STATIC");
612 if ( f & ACC_FINAL ) fprintf (fp," FINAL");
613 if ( f & ACC_SYNCHRONIZED ) fprintf (fp," SYNCHRONIZED");
614 if ( f & ACC_VOLATILE ) fprintf (fp," VOLATILE");
615 if ( f & ACC_TRANSIENT ) fprintf (fp," TRANSIENT");
616 if ( f & ACC_NATIVE ) fprintf (fp," NATIVE");
617 if ( f & ACC_INTERFACE ) fprintf (fp," INTERFACE");
618 if ( f & ACC_ABSTRACT ) fprintf (fp," ABSTRACT");
622 /********** internal function: printflags (only for debugging) ***************/
624 void printflags(u2 f)
626 if ( f & ACC_PUBLIC ) printf (" PUBLIC");
627 if ( f & ACC_PRIVATE ) printf (" PRIVATE");
628 if ( f & ACC_PROTECTED ) printf (" PROTECTED");
629 if ( f & ACC_STATIC ) printf (" STATIC");
630 if ( f & ACC_FINAL ) printf (" FINAL");
631 if ( f & ACC_SYNCHRONIZED ) printf (" SYNCHRONIZED");
632 if ( f & ACC_VOLATILE ) printf (" VOLATILE");
633 if ( f & ACC_TRANSIENT ) printf (" TRANSIENT");
634 if ( f & ACC_NATIVE ) printf (" NATIVE");
635 if ( f & ACC_INTERFACE ) printf (" INTERFACE");
636 if ( f & ACC_ABSTRACT ) printf (" ABSTRACT");
640 /********************** Function: skipattributebody ****************************
642 skips an attribute after the 16 bit reference to attribute_name has already
645 *******************************************************************************/
647 static bool skipattributebody(classbuffer *cb)
651 if (!check_classbuffer_size(cb, 4))
656 if (!check_classbuffer_size(cb, len))
659 skip_nbytes(cb, len);
665 /************************* Function: skipattributes ****************************
667 skips num attribute structures
669 *******************************************************************************/
671 static bool skipattributes(classbuffer *cb, u4 num)
676 for (i = 0; i < num; i++) {
677 if (!check_classbuffer_size(cb, 2 + 4))
683 if (!check_classbuffer_size(cb, len))
686 skip_nbytes(cb, len);
693 /******************** function:: class_getconstant *****************************
695 retrieves the value at position 'pos' of the constantpool of a class
696 if the type of the value is other than 'ctype' the system is stopped
698 *******************************************************************************/
700 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
702 /* check index and type of constantpool entry */
703 /* (pos == 0 is caught by type comparison) */
704 if (pos >= c->cpcount || c->cptags[pos] != ctype) {
705 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
709 return c->cpinfos[pos];
713 /******************** function: innerclass_getconstant ************************
715 like class_getconstant, but if cptags is ZERO null is returned
717 *******************************************************************************/
719 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
721 /* invalid position in constantpool */
722 if (pos >= c->cpcount) {
723 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
727 /* constantpool entry of type 0 */
731 /* check type of constantpool entry */
732 if (c->cptags[pos] != ctype) {
733 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
737 return c->cpinfos[pos];
741 /********************* Function: class_constanttype ****************************
743 Determines the type of a class entry in the ConstantPool
745 *******************************************************************************/
747 u4 class_constanttype(classinfo *c, u4 pos)
749 if (pos <= 0 || pos >= c->cpcount) {
750 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
754 return c->cptags[pos];
758 /************************ function: attribute_load ****************************
760 read attributes from classfile
762 *******************************************************************************/
764 static bool attribute_load(classbuffer *cb, classinfo *c, u4 num)
769 for (i = 0; i < num; i++) {
770 /* retrieve attribute name */
771 if (!check_classbuffer_size(cb, 2))
774 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
777 if (aname == utf_innerclasses) {
778 /* innerclasses attribute */
781 new_classformaterror(c, "Multiple InnerClasses attributes");
785 if (!check_classbuffer_size(cb, 4 + 2))
788 /* skip attribute length */
791 /* number of records */
792 c->innerclasscount = suck_u2(cb);
794 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
797 /* allocate memory for innerclass structure */
798 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
800 for (j = 0; j < c->innerclasscount; j++) {
801 /* The innerclass structure contains a class with an encoded
802 name, its defining scope, its simple name and a bitmask of
803 the access flags. If an inner class is not a member, its
804 outer_class is NULL, if a class is anonymous, its name is
807 innerclassinfo *info = c->innerclass + j;
810 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
812 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
814 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
815 info->flags = suck_u2(cb);
818 } else if (aname == utf_sourcefile) {
819 if (!check_classbuffer_size(cb, 4 + 2))
822 if (suck_u4(cb) != 2) {
824 new_classformaterror(c, "Wrong size for VALUE attribute");
830 new_classformaterror(c, "Multiple SourceFile attributes");
834 if (!(c->sourcefile = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
838 /* unknown attribute */
839 if (!skipattributebody(cb))
848 /******************* function: checkfielddescriptor ****************************
850 checks whether a field-descriptor is valid and aborts otherwise
851 all referenced classes are inserted into the list of unloaded classes
853 *******************************************************************************/
855 static void checkfielddescriptor (char *utf_ptr, char *end_pos)
857 class_from_descriptor(utf_ptr,end_pos,NULL,
859 | CLASSLOAD_NULLPRIMITIVE
861 | CLASSLOAD_CHECKEND);
863 /* XXX use the following if -noverify */
865 char *tstart; /* pointer to start of classname */
867 char *start = utf_ptr;
869 switch (*utf_ptr++) {
883 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
884 panic ("Ill formed descriptor");
888 panic ("Ill formed descriptor");
891 /* exceeding characters */
892 if (utf_ptr!=end_pos) panic ("descriptor has exceeding chars");
897 /******************* function checkmethoddescriptor ****************************
899 checks whether a method-descriptor is valid and aborts otherwise.
900 All referenced classes are inserted into the list of unloaded classes.
902 The number of arguments is returned. A long or double argument is counted
905 *******************************************************************************/
907 static int checkmethoddescriptor(classinfo *c, utf *descriptor)
909 char *utf_ptr; /* current position in utf text */
910 char *end_pos; /* points behind utf string */
911 s4 argcount = 0; /* number of arguments */
913 utf_ptr = descriptor->text;
914 end_pos = utf_end(descriptor);
916 /* method descriptor must start with parenthesis */
917 if (utf_ptr == end_pos || *utf_ptr++ != '(')
918 panic ("Missing '(' in method descriptor");
920 /* check arguments */
921 while (utf_ptr != end_pos && *utf_ptr != ')') {
922 /* We cannot count the this argument here because
923 * we don't know if the method is static. */
924 if (*utf_ptr == 'J' || *utf_ptr == 'D')
928 class_from_descriptor(utf_ptr,end_pos,&utf_ptr,
930 | CLASSLOAD_NULLPRIMITIVE
934 if (utf_ptr == end_pos)
935 panic("Missing ')' in method descriptor");
937 utf_ptr++; /* skip ')' */
939 class_from_descriptor(utf_ptr,
943 CLASSLOAD_NULLPRIMITIVE |
946 if (argcount > 255) {
948 new_classformaterror(c, "Too many arguments in signature");
955 /* XXX use the following if -noverify */
957 /* check arguments */
958 while ((c = *utf_ptr++) != ')') {
975 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
976 panic ("Ill formed method descriptor");
980 panic ("Ill formed methodtype-descriptor");
984 /* check returntype */
986 /* returntype void */
987 if ((utf_ptr+1) != end_pos) panic ("Method-descriptor has exceeding chars");
990 /* treat as field-descriptor */
991 checkfielddescriptor (utf_ptr,end_pos);
996 /***************** Function: print_arraydescriptor ****************************
998 Debugging helper for displaying an arraydescriptor
1000 *******************************************************************************/
1002 void print_arraydescriptor(FILE *file, arraydescriptor *desc)
1005 fprintf(file, "<NULL>");
1010 if (desc->componentvftbl) {
1011 if (desc->componentvftbl->class)
1012 utf_fprint(file, desc->componentvftbl->class->name);
1014 fprintf(file, "<no classinfo>");
1020 if (desc->elementvftbl) {
1021 if (desc->elementvftbl->class)
1022 utf_fprint(file, desc->elementvftbl->class->name);
1024 fprintf(file, "<no classinfo>");
1028 fprintf(file, ",%d,%d,%d,%d}", desc->arraytype, desc->dimension,
1029 desc->dataoffset, desc->componentsize);
1033 /******************************************************************************/
1034 /************************** Functions for fields ****************************/
1035 /******************************************************************************/
1038 /* field_load ******************************************************************
1040 Load everything about a class field from the class file and fill a
1041 'fieldinfo' structure. For static fields, space in the data segment is
1044 *******************************************************************************/
1046 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
1048 static bool field_load(classbuffer *cb, classinfo *c, fieldinfo *f)
1052 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
1055 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1058 f->flags = suck_u2(cb);
1060 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1064 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1070 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<')
1071 panic("Field with invalid name");
1073 /* check flag consistency */
1074 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
1076 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
1077 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
1079 new_classformaterror(c,
1080 "Illegal field modifiers: 0x%X",
1085 if (c->flags & ACC_INTERFACE) {
1086 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
1087 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
1088 f->flags & ACC_TRANSIENT) {
1090 new_classformaterror(c,
1091 "Illegal field modifiers: 0x%X",
1097 /* check descriptor */
1098 checkfielddescriptor(f->descriptor->text, utf_end(f->descriptor));
1101 f->type = jtype = desc_to_type(f->descriptor); /* data type */
1102 f->offset = 0; /* offset from start of object */
1107 case TYPE_INT: f->value.i = 0; break;
1108 case TYPE_FLOAT: f->value.f = 0.0; break;
1109 case TYPE_DOUBLE: f->value.d = 0.0; break;
1110 case TYPE_ADDRESS: f->value.a = NULL; break;
1113 f->value.l = 0; break;
1115 f->value.l.low = 0; f->value.l.high = 0; break;
1119 /* read attributes */
1120 if (!check_classbuffer_size(cb, 2))
1123 attrnum = suck_u2(cb);
1124 for (i = 0; i < attrnum; i++) {
1125 if (!check_classbuffer_size(cb, 2))
1128 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1131 if (u == utf_constantvalue) {
1132 if (!check_classbuffer_size(cb, 4 + 2))
1135 /* check attribute length */
1136 if (suck_u4(cb) != 2) {
1138 new_classformaterror(c, "Wrong size for VALUE attribute");
1142 /* constant value attribute */
1143 if (pindex != field_load_NOVALUE) {
1145 new_classformaterror(c,
1146 "Multiple ConstantValue attributes");
1150 /* index of value in constantpool */
1151 pindex = suck_u2(cb);
1153 /* initialize field with value from constantpool */
1156 constant_integer *ci;
1158 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
1161 f->value.i = ci->value;
1168 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
1171 f->value.l = cl->value;
1178 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
1181 f->value.f = cf->value;
1186 constant_double *cd;
1188 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
1191 f->value.d = cd->value;
1196 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
1199 /* create javastring from compressed utf8-string */
1200 f->value.a = literalstring_new(u);
1204 log_text("Invalid Constant - Type");
1208 /* unknown attribute */
1209 if (!skipattributebody(cb))
1214 /* everything was ok */
1220 /********************** function: field_free **********************************/
1222 static void field_free(fieldinfo *f)
1228 /**************** Function: field_display (debugging only) ********************/
1230 void field_display(fieldinfo *f)
1233 printflags(f->flags);
1235 utf_display(f->name);
1237 utf_display(f->descriptor);
1238 printf(" offset: %ld\n", (long int) (f->offset));
1242 /******************************************************************************/
1243 /************************* Functions for methods ******************************/
1244 /******************************************************************************/
1247 /* method_load *****************************************************************
1249 Loads a method from the class file and fills an existing 'methodinfo'
1250 structure. For native methods, the function pointer field is set to the
1251 real function pointer, for JavaVM methods a pointer to the compiler is used
1254 *******************************************************************************/
1256 static bool method_load(classbuffer *cb, classinfo *c, methodinfo *m)
1264 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1265 initObjectLock(&m->header);
1270 count_all_methods++;
1273 m->thrownexceptionscount = 0;
1274 m->linenumbercount = 0;
1277 m->nativelyoverloaded = false;
1279 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1282 m->flags = suck_u2(cb);
1284 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1288 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1293 if (!is_valid_name_utf(m->name))
1294 panic("Method with invalid name");
1296 if (m->name->text[0] == '<'
1297 && m->name != utf_init && m->name != utf_clinit)
1298 panic("Method with invalid special name");
1301 argcount = checkmethoddescriptor(c, m->descriptor);
1303 if (!(m->flags & ACC_STATIC))
1304 argcount++; /* count the 'this' argument */
1307 if (argcount > 255) {
1309 new_classformaterror(c, "Too many arguments in signature");
1313 /* check flag consistency */
1314 if (m->name != utf_clinit) {
1315 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1317 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1319 new_classformaterror(c,
1320 "Illegal method modifiers: 0x%X",
1325 if (m->flags & ACC_ABSTRACT) {
1326 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1327 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1329 new_classformaterror(c,
1330 "Illegal method modifiers: 0x%X",
1336 if (c->flags & ACC_INTERFACE) {
1337 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1339 new_classformaterror(c,
1340 "Illegal method modifiers: 0x%X",
1346 if (m->name == utf_init) {
1347 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1348 ACC_NATIVE | ACC_ABSTRACT))
1349 panic("Instance initialization method has invalid flags set");
1355 m->basicblockcount = 0;
1356 m->basicblocks = NULL;
1357 m->basicblockindex = NULL;
1358 m->instructioncount = 0;
1359 m->instructions = NULL;
1362 m->exceptiontable = NULL;
1363 m->stubroutine = NULL;
1365 m->entrypoint = NULL;
1366 m->methodUsed = NOTUSED;
1369 m->subRedefsUsed = 0;
1373 if (!(m->flags & ACC_NATIVE)) {
1374 m->stubroutine = createcompilerstub(m);
1377 /*if (useinlining) {
1378 log_text("creating native stub:");
1381 functionptr f = native_findfunction(c->name, m->name, m->descriptor,
1382 (m->flags & ACC_STATIC) != 0);
1383 #ifdef STATIC_CLASSPATH
1387 m->stubroutine = createnativestub(f, m);
1391 if (!check_classbuffer_size(cb, 2))
1394 attrnum = suck_u2(cb);
1395 for (i = 0; i < attrnum; i++) {
1398 if (!check_classbuffer_size(cb, 2))
1401 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1404 if (aname == utf_code) {
1405 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1407 new_classformaterror(c,
1408 "Code attribute in native or abstract methods");
1415 new_classformaterror(c, "Multiple Code attributes");
1420 if (!check_classbuffer_size(cb, 4 + 2 + 2))
1424 m->maxstack = suck_u2(cb);
1425 m->maxlocals = suck_u2(cb);
1427 if (m->maxlocals < argcount) {
1429 new_classformaterror(c, "Arguments can't fit into locals");
1434 if (!check_classbuffer_size(cb, 4))
1437 m->jcodelength = suck_u4(cb);
1439 if (m->jcodelength == 0) {
1441 new_classformaterror(c, "Code of a method has length 0");
1446 if (m->jcodelength > 65535) {
1448 new_classformaterror(c,
1449 "Code of a method longer than 65535 bytes");
1454 if (!check_classbuffer_size(cb, m->jcodelength))
1457 m->jcode = MNEW(u1, m->jcodelength);
1458 suck_nbytes(m->jcode, cb, m->jcodelength);
1460 if (!check_classbuffer_size(cb, 2))
1463 m->exceptiontablelength = suck_u2(cb);
1464 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->exceptiontablelength))
1467 m->exceptiontable = MNEW(exceptiontable, m->exceptiontablelength);
1469 #if defined(STATISTICS)
1471 count_vmcode_len += m->jcodelength + 18;
1472 count_extable_len += 8 * m->exceptiontablelength;
1476 for (j = 0; j < m->exceptiontablelength; j++) {
1478 m->exceptiontable[j].startpc = suck_u2(cb);
1479 m->exceptiontable[j].endpc = suck_u2(cb);
1480 m->exceptiontable[j].handlerpc = suck_u2(cb);
1484 m->exceptiontable[j].catchtype = NULL;
1487 if (!(m->exceptiontable[j].catchtype =
1488 class_getconstant(c, idx, CONSTANT_Class)))
1493 if (!check_classbuffer_size(cb, 2))
1496 codeattrnum = suck_u2(cb);
1498 for (; codeattrnum > 0; codeattrnum--) {
1501 if (!check_classbuffer_size(cb, 2))
1504 if (!(caname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1507 if (caname == utf_linenumbertable) {
1510 if (!check_classbuffer_size(cb, 4 + 2))
1514 m->linenumbercount = suck_u2(cb);
1516 if (!check_classbuffer_size(cb,
1517 (2 + 2) * m->linenumbercount))
1520 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1522 for (lncid = 0; lncid < m->linenumbercount; lncid++) {
1523 m->linenumbers[lncid].start_pc = suck_u2(cb);
1524 m->linenumbers[lncid].line_number = suck_u2(cb);
1528 if (!skipattributes(cb, codeattrnum))
1534 if (!skipattributebody(cb))
1539 } else if (aname == utf_exceptions) {
1542 if (m->thrownexceptions) {
1544 new_classformaterror(c, "Multiple Exceptions attributes");
1548 if (!check_classbuffer_size(cb, 4 + 2))
1551 suck_u4(cb); /* length */
1552 m->thrownexceptionscount = suck_u2(cb);
1554 if (!check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1557 m->thrownexceptions = MNEW(classinfo*, m->thrownexceptionscount);
1559 for (j = 0; j < m->thrownexceptionscount; j++) {
1560 if (!((m->thrownexceptions)[j] =
1561 class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1566 if (!skipattributebody(cb))
1571 if (!m->jcode && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1572 *exceptionptr = new_classformaterror(c, "Missing Code attribute");
1577 /* everything was ok */
1578 /* utf_display(m->name);
1579 printf("\nexceptiontablelength:%ld\n",m->exceptiontablelength);*/
1585 /********************* Function: method_free ***********************************
1587 frees all memory that was allocated for this method
1589 *******************************************************************************/
1591 static void method_free(methodinfo *m)
1594 MFREE(m->jcode, u1, m->jcodelength);
1596 if (m->exceptiontable)
1597 MFREE(m->exceptiontable, exceptiontable, m->exceptiontablelength);
1600 CFREE(m->mcode, m->mcodelength);
1602 if (m->stubroutine) {
1603 if (m->flags & ACC_NATIVE) {
1604 removenativestub(m->stubroutine);
1607 removecompilerstub(m->stubroutine);
1613 /************** Function: method_display (debugging only) **************/
1615 void method_display(methodinfo *m)
1618 printflags(m->flags);
1620 utf_display(m->name);
1622 utf_display(m->descriptor);
1626 /************** Function: method_display_w_class (debugging only) **************/
1628 void method_display_w_class(methodinfo *m)
1630 printflags(m->class->flags);
1631 printf(" "); fflush(stdout);
1632 utf_display(m->class->name);
1633 printf(".");fflush(stdout);
1636 printflags(m->flags);
1637 printf(" "); fflush(stdout);
1638 utf_display(m->name);
1639 printf(" "); fflush(stdout);
1640 utf_display(m->descriptor);
1641 printf("\n"); fflush(stdout);
1644 /************** Function: method_display_flags_last (debugging only) **************/
1646 void method_display_flags_last(methodinfo *m)
1649 utf_display(m->name);
1651 utf_display(m->descriptor);
1653 printflags(m->flags);
1658 /******************** Function: method_canoverwrite ****************************
1660 Check if m and old are identical with respect to type and name. This means
1661 that old can be overwritten with m.
1663 *******************************************************************************/
1665 static bool method_canoverwrite(methodinfo *m, methodinfo *old)
1667 if (m->name != old->name) return false;
1668 if (m->descriptor != old->descriptor) return false;
1669 if (m->flags & ACC_STATIC) return false;
1674 /******************** function: class_loadcpool ********************************
1676 loads the constantpool of a class,
1677 the entries are transformed into a simpler format
1678 by resolving references
1679 (a detailed overview of the compact structures can be found in global.h)
1681 *******************************************************************************/
1683 static bool class_loadcpool(classbuffer *cb, classinfo *c)
1686 /* The following structures are used to save information which cannot be
1687 processed during the first pass. After the complete constantpool has
1688 been traversed the references can be resolved.
1689 (only in specific order) */
1691 /* CONSTANT_Class entries */
1692 typedef struct forward_class {
1693 struct forward_class *next;
1698 /* CONSTANT_String */
1699 typedef struct forward_string {
1700 struct forward_string *next;
1705 /* CONSTANT_NameAndType */
1706 typedef struct forward_nameandtype {
1707 struct forward_nameandtype *next;
1711 } forward_nameandtype;
1713 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
1714 typedef struct forward_fieldmethint {
1715 struct forward_fieldmethint *next;
1719 u2 nameandtype_index;
1720 } forward_fieldmethint;
1725 forward_class *forward_classes = NULL;
1726 forward_string *forward_strings = NULL;
1727 forward_nameandtype *forward_nameandtypes = NULL;
1728 forward_fieldmethint *forward_fieldmethints = NULL;
1731 forward_string *nfs;
1732 forward_nameandtype *nfn;
1733 forward_fieldmethint *nff;
1739 /* number of entries in the constant_pool table plus one */
1740 if (!check_classbuffer_size(cb, 2))
1743 cpcount = c->cpcount = suck_u2(cb);
1745 /* allocate memory */
1746 cptags = c->cptags = MNEW(u1, cpcount);
1747 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
1750 *exceptionptr = new_classformaterror(c, "Illegal constant pool size");
1754 #if defined(STATISTICS)
1756 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
1759 /* initialize constantpool */
1760 for (idx = 0; idx < cpcount; idx++) {
1761 cptags[idx] = CONSTANT_UNUSED;
1762 cpinfos[idx] = NULL;
1766 /******* first pass *******/
1767 /* entries which cannot be resolved now are written into
1768 temporary structures and traversed again later */
1771 while (idx < cpcount) {
1774 /* get constant type */
1775 if (!check_classbuffer_size(cb, 1))
1781 case CONSTANT_Class:
1782 nfc = NEW(forward_class);
1784 nfc->next = forward_classes;
1785 forward_classes = nfc;
1787 nfc->thisindex = idx;
1788 /* reference to CONSTANT_NameAndType */
1789 if (!check_classbuffer_size(cb, 2))
1792 nfc->name_index = suck_u2(cb);
1797 case CONSTANT_String:
1798 nfs = NEW(forward_string);
1800 nfs->next = forward_strings;
1801 forward_strings = nfs;
1803 nfs->thisindex = idx;
1805 /* reference to CONSTANT_Utf8_info with string characters */
1806 if (!check_classbuffer_size(cb, 2))
1809 nfs->string_index = suck_u2(cb);
1814 case CONSTANT_NameAndType:
1815 nfn = NEW(forward_nameandtype);
1817 nfn->next = forward_nameandtypes;
1818 forward_nameandtypes = nfn;
1820 nfn->thisindex = idx;
1822 if (!check_classbuffer_size(cb, 2 + 2))
1825 /* reference to CONSTANT_Utf8_info containing simple name */
1826 nfn->name_index = suck_u2(cb);
1828 /* reference to CONSTANT_Utf8_info containing field or method
1830 nfn->sig_index = suck_u2(cb);
1835 case CONSTANT_Fieldref:
1836 case CONSTANT_Methodref:
1837 case CONSTANT_InterfaceMethodref:
1838 nff = NEW(forward_fieldmethint);
1840 nff->next = forward_fieldmethints;
1841 forward_fieldmethints = nff;
1843 nff->thisindex = idx;
1847 if (!check_classbuffer_size(cb, 2 + 2))
1850 /* class or interface type that contains the declaration of the
1852 nff->class_index = suck_u2(cb);
1854 /* name and descriptor of the field or method */
1855 nff->nameandtype_index = suck_u2(cb);
1860 case CONSTANT_Integer: {
1861 constant_integer *ci = NEW(constant_integer);
1863 #if defined(STATISTICS)
1865 count_const_pool_len += sizeof(constant_integer);
1868 if (!check_classbuffer_size(cb, 4))
1871 ci->value = suck_s4(cb);
1872 cptags[idx] = CONSTANT_Integer;
1879 case CONSTANT_Float: {
1880 constant_float *cf = NEW(constant_float);
1882 #if defined(STATISTICS)
1884 count_const_pool_len += sizeof(constant_float);
1887 if (!check_classbuffer_size(cb, 4))
1890 cf->value = suck_float(cb);
1891 cptags[idx] = CONSTANT_Float;
1898 case CONSTANT_Long: {
1899 constant_long *cl = NEW(constant_long);
1901 #if defined(STATISTICS)
1903 count_const_pool_len += sizeof(constant_long);
1906 if (!check_classbuffer_size(cb, 8))
1909 cl->value = suck_s8(cb);
1910 cptags[idx] = CONSTANT_Long;
1913 if (idx > cpcount) {
1915 new_classformaterror(c, "Invalid constant pool entry");
1921 case CONSTANT_Double: {
1922 constant_double *cd = NEW(constant_double);
1924 #if defined(STATISTICS)
1926 count_const_pool_len += sizeof(constant_double);
1929 if (!check_classbuffer_size(cb, 8))
1932 cd->value = suck_double(cb);
1933 cptags[idx] = CONSTANT_Double;
1936 if (idx > cpcount) {
1938 new_classformaterror(c, "Invalid constant pool entry");
1944 case CONSTANT_Utf8: {
1947 /* number of bytes in the bytes array (not string-length) */
1948 if (!check_classbuffer_size(cb, 2))
1951 length = suck_u2(cb);
1952 cptags[idx] = CONSTANT_Utf8;
1954 /* validate the string */
1955 if (!check_classbuffer_size(cb, length))
1959 !is_valid_utf((char *) (cb->pos + 1),
1960 (char *) (cb->pos + 1 + length))) {
1961 dolog("Invalid UTF-8 string (constant pool index %d)",idx);
1962 panic("Invalid UTF-8 string");
1964 /* insert utf-string into the utf-symboltable */
1965 cpinfos[idx] = utf_new_intern((char *) (cb->pos + 1), length);
1967 /* skip bytes of the string (buffer size check above) */
1968 skip_nbytes(cb, length);
1975 new_classformaterror(c, "Illegal constant pool type");
1981 /* resolve entries in temporary structures */
1983 while (forward_classes) {
1985 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
1987 if (opt_verify && !is_valid_name_utf(name))
1988 panic("Class reference with invalid name");
1990 cptags[forward_classes->thisindex] = CONSTANT_Class;
1991 /* retrieve class from class-table */
1994 tc = class_new_intern(name);
1996 if (!class_load(tc))
1999 /* link the class later, because we cannot link the class currently
2001 list_addfirst(&unlinkedclasses, tc);
2003 cpinfos[forward_classes->thisindex] = tc;
2006 cpinfos[forward_classes->thisindex] = class_new(name);
2009 nfc = forward_classes;
2010 forward_classes = forward_classes->next;
2011 FREE(nfc, forward_class);
2014 while (forward_strings) {
2016 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
2018 /* resolve utf-string */
2019 cptags[forward_strings->thisindex] = CONSTANT_String;
2020 cpinfos[forward_strings->thisindex] = text;
2022 nfs = forward_strings;
2023 forward_strings = forward_strings->next;
2024 FREE(nfs, forward_string);
2027 while (forward_nameandtypes) {
2028 constant_nameandtype *cn = NEW(constant_nameandtype);
2030 #if defined(STATISTICS)
2032 count_const_pool_len += sizeof(constant_nameandtype);
2035 /* resolve simple name and descriptor */
2036 cn->name = class_getconstant(c,
2037 forward_nameandtypes->name_index,
2040 cn->descriptor = class_getconstant(c,
2041 forward_nameandtypes->sig_index,
2046 if (!is_valid_name_utf(cn->name))
2047 panic("NameAndType with invalid name");
2048 /* disallow referencing <clinit> among others */
2049 if (cn->name->text[0] == '<' && cn->name != utf_init)
2050 panic("NameAndType with invalid special name");
2053 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
2054 cpinfos[forward_nameandtypes->thisindex] = cn;
2056 nfn = forward_nameandtypes;
2057 forward_nameandtypes = forward_nameandtypes->next;
2058 FREE(nfn, forward_nameandtype);
2061 while (forward_fieldmethints) {
2062 constant_nameandtype *nat;
2063 constant_FMIref *fmi = NEW(constant_FMIref);
2065 #if defined(STATISTICS)
2067 count_const_pool_len += sizeof(constant_FMIref);
2069 /* resolve simple name and descriptor */
2070 nat = class_getconstant(c,
2071 forward_fieldmethints->nameandtype_index,
2072 CONSTANT_NameAndType);
2074 fmi->class = class_getconstant(c,
2075 forward_fieldmethints->class_index,
2077 fmi->name = nat->name;
2078 fmi->descriptor = nat->descriptor;
2080 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
2081 cpinfos[forward_fieldmethints->thisindex] = fmi;
2083 switch (forward_fieldmethints->tag) {
2084 case CONSTANT_Fieldref: /* check validity of descriptor */
2085 checkfielddescriptor(fmi->descriptor->text,
2086 utf_end(fmi->descriptor));
2088 case CONSTANT_InterfaceMethodref:
2089 case CONSTANT_Methodref: /* check validity of descriptor */
2090 checkmethoddescriptor(c, fmi->descriptor);
2094 nff = forward_fieldmethints;
2095 forward_fieldmethints = forward_fieldmethints->next;
2096 FREE(nff, forward_fieldmethint);
2099 /* everything was ok */
2105 /********************** Function: class_load ***********************************
2107 Loads everything interesting about a class from the class file. The
2108 'classinfo' structure must have been allocated previously.
2110 The super class and the interfaces implemented by this class need not be
2111 loaded. The link is set later by the function 'class_link'.
2113 The loaded class is removed from the list 'unloadedclasses' and added to
2114 the list 'unlinkedclasses'.
2116 *******************************************************************************/
2118 classinfo *class_load_intern(classbuffer *cb);
2120 classinfo *class_load(classinfo *c)
2125 /* enter a monitor on the class */
2127 builtin_monitorenter((java_objectheader *) c);
2129 /* maybe the class is already loaded */
2131 builtin_monitorexit((java_objectheader *) c);
2138 if (getcompilingtime)
2139 compilingtime_stop();
2142 loadingtime_start();
2144 /* load classdata, throw exception on error */
2146 if ((cb = suck_start(c)) == NULL) {
2147 /* this means, the classpath was not set properly */
2148 if (c->name == utf_java_lang_Object)
2149 throw_cacao_exception_exit(string_java_lang_NoClassDefFoundError,
2150 "java/lang/Object");
2153 new_exception_utfmessage(string_java_lang_NoClassDefFoundError,
2156 builtin_monitorexit((java_objectheader *) c);
2161 /* call the internal function */
2162 r = class_load_intern(cb);
2164 /* if return value is NULL, we had a problem and the class is not loaded */
2168 /* now free the allocated memory, otherwise we could ran into a DOS */
2180 if (getcompilingtime)
2181 compilingtime_start();
2183 /* leave the monitor */
2185 builtin_monitorexit((java_objectheader *) c);
2191 classinfo *class_load_intern(classbuffer *cb)
2197 char msg[MAXLOGTEXT]; /* maybe we get an exception */
2199 /* get the classbuffer's class */
2202 /* maybe the class is already loaded */
2206 #if defined(STATISTICS)
2208 count_class_loads++;
2211 /* output for debugging purposes */
2213 log_message_class("Loading class: ", c);
2215 /* class is somewhat loaded */
2218 if (!check_classbuffer_size(cb, 4 + 2 + 2))
2221 /* check signature */
2222 if (suck_u4(cb) != MAGIC) {
2223 *exceptionptr = new_classformaterror(c, "Bad magic number");
2232 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
2234 new_unsupportedclassversionerror(c,
2235 "Unsupported major.minor version %d.%d",
2241 /* load the constant pool */
2242 if (!class_loadcpool(cb, c))
2246 c->erroneous_state = 0;
2247 c->initializing_thread = 0;
2249 c->classUsed = NOTUSED; /* not used initially CO-RT */
2253 if (!check_classbuffer_size(cb, 2))
2256 c->flags = suck_u2(cb);
2257 /*if (!(c->flags & ACC_PUBLIC)) { log_text("CLASS NOT PUBLIC"); } JOWENN*/
2259 /* check ACC flags consistency */
2260 if (c->flags & ACC_INTERFACE) {
2261 if (!(c->flags & ACC_ABSTRACT)) {
2262 /* We work around this because interfaces in JDK 1.1 are
2263 * not declared abstract. */
2265 c->flags |= ACC_ABSTRACT;
2266 /* panic("Interface class not declared abstract"); */
2269 if (c->flags & ACC_FINAL) {
2271 new_classformaterror(c,
2272 "Illegal class modifiers: 0x%X", c->flags);
2277 if (c->flags & ACC_SUPER) {
2278 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
2282 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
2284 new_classformaterror(c, "Illegal class modifiers: 0x%X", c->flags);
2289 if (!check_classbuffer_size(cb, 2 + 2))
2294 if (!(tc = class_getconstant(c, i, CONSTANT_Class)))
2298 utf_sprint(msg, c->name);
2299 sprintf(msg + strlen(msg), " (wrong name: ");
2300 utf_sprint(msg + strlen(msg), tc->name);
2301 sprintf(msg + strlen(msg), ")");
2304 new_exception_message(string_java_lang_NoClassDefFoundError, msg);
2309 /* retrieve superclass */
2310 if ((i = suck_u2(cb))) {
2311 if (!(c->super = class_getconstant(c, i, CONSTANT_Class)))
2314 /* java.lang.Object may not have a super class. */
2315 if (c->name == utf_java_lang_Object) {
2317 new_exception_message(string_java_lang_ClassFormatError,
2318 "java.lang.Object with superclass");
2323 /* Interfaces must have java.lang.Object as super class. */
2324 if ((c->flags & ACC_INTERFACE) &&
2325 c->super->name != utf_java_lang_Object) {
2327 new_exception_message(string_java_lang_ClassFormatError,
2328 "Interfaces must have java.lang.Object as superclass");
2336 /* This is only allowed for java.lang.Object. */
2337 if (c->name != utf_java_lang_Object) {
2338 *exceptionptr = new_classformaterror(c, "Bad superclass index");
2344 /* retrieve interfaces */
2345 if (!check_classbuffer_size(cb, 2))
2348 c->interfacescount = suck_u2(cb);
2350 if (!check_classbuffer_size(cb, 2 * c->interfacescount))
2353 c->interfaces = MNEW(classinfo*, c->interfacescount);
2354 for (i = 0; i < c->interfacescount; i++) {
2355 if (!(c->interfaces[i] = class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2360 if (!check_classbuffer_size(cb, 2))
2363 c->fieldscount = suck_u2(cb);
2364 c->fields = GCNEW(fieldinfo, c->fieldscount);
2365 /* c->fields = MNEW(fieldinfo, c->fieldscount); */
2366 for (i = 0; i < c->fieldscount; i++) {
2367 if (!field_load(cb, c, &(c->fields[i])))
2372 if (!check_classbuffer_size(cb, 2))
2375 c->methodscount = suck_u2(cb);
2376 c->methods = GCNEW(methodinfo, c->methodscount);
2377 /* c->methods = MNEW(methodinfo, c->methodscount); */
2378 for (i = 0; i < c->methodscount; i++) {
2379 if (!method_load(cb, c, &(c->methods[i])))
2383 /* Check if all fields and methods can be uniquely
2384 * identified by (name,descriptor). */
2386 /* We use a hash table here to avoid making the
2387 * average case quadratic in # of methods, fields.
2389 static int shift = 0;
2391 u2 *next; /* for chaining colliding hash entries */
2397 /* Allocate hashtable */
2398 len = c->methodscount;
2399 if (len < c->fieldscount) len = c->fieldscount;
2401 hashtab = MNEW(u2,(hashlen + len));
2402 next = hashtab + hashlen;
2404 /* Determine bitshift (to get good hash values) */
2414 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2416 for (i = 0; i < c->fieldscount; ++i) {
2417 fieldinfo *fi = c->fields + i;
2419 /* It's ok if we lose bits here */
2420 index = ((((size_t) fi->name) +
2421 ((size_t) fi->descriptor)) >> shift) % hashlen;
2423 if ((old = hashtab[index])) {
2427 if (c->fields[old].name == fi->name &&
2428 c->fields[old].descriptor == fi->descriptor) {
2430 new_classformaterror(c,
2431 "Repetitive field name/signature");
2435 } while ((old = next[old]));
2437 hashtab[index] = i + 1;
2441 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2443 for (i = 0; i < c->methodscount; ++i) {
2444 methodinfo *mi = c->methods + i;
2446 /* It's ok if we lose bits here */
2447 index = ((((size_t) mi->name) +
2448 ((size_t) mi->descriptor)) >> shift) % hashlen;
2452 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2453 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2457 if ((old = hashtab[index])) {
2461 if (c->methods[old].name == mi->name &&
2462 c->methods[old].descriptor == mi->descriptor) {
2464 new_classformaterror(c,
2465 "Repetitive method name/signature");
2469 } while ((old = next[old]));
2471 hashtab[index] = i + 1;
2474 MFREE(hashtab, u2, (hashlen + len));
2477 #if defined(STATISTICS)
2479 count_class_infos += sizeof(classinfo*) * c->interfacescount;
2480 count_class_infos += sizeof(fieldinfo) * c->fieldscount;
2481 count_class_infos += sizeof(methodinfo) * c->methodscount;
2485 /* load attribute structures */
2486 if (!check_classbuffer_size(cb, 2))
2489 if (!attribute_load(cb, c, suck_u2(cb)))
2493 /* Pre java 1.5 version don't check this. This implementation is like
2494 java 1.5 do it: for class file version 45.3 we don't check it, older
2495 versions are checked.
2497 if ((ma == 45 && mi > 3) || ma > 45) {
2498 /* check if all data has been read */
2499 s4 classdata_left = ((cb->data + cb->size) - cb->pos - 1);
2501 if (classdata_left > 0) {
2503 new_classformaterror(c, "Extra bytes at the end of class file");
2510 log_message_class("Loading done class: ", c);
2517 /************** internal Function: class_highestinterface **********************
2519 Used by the function class_link to determine the amount of memory needed
2520 for the interface table.
2522 *******************************************************************************/
2524 static s4 class_highestinterface(classinfo *c)
2529 /* check for ACC_INTERFACE bit already done in class_link_intern */
2532 for (i = 0; i < c->interfacescount; i++) {
2533 s4 h2 = class_highestinterface(c->interfaces[i]);
2541 /* class_addinterface **********************************************************
2543 Is needed by class_link for adding a VTBL to a class. All interfaces
2544 implemented by ic are added as well.
2546 *******************************************************************************/
2548 static void class_addinterface(classinfo *c, classinfo *ic)
2552 vftbl_t *v = c->vftbl;
2554 if (i >= v->interfacetablelength)
2555 panic ("Inernal error: interfacetable overflow");
2557 if (v->interfacetable[-i])
2560 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
2561 v->interfacevftbllength[i] = 1;
2562 v->interfacetable[-i] = MNEW(methodptr, 1);
2563 v->interfacetable[-i][0] = NULL;
2566 v->interfacevftbllength[i] = ic->methodscount;
2567 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
2569 #if defined(STATISTICS)
2571 count_vftbl_len += sizeof(methodptr) *
2572 (ic->methodscount + (ic->methodscount == 0));
2575 for (j = 0; j < ic->methodscount; j++) {
2578 for (m = 0; m < sc->methodscount; m++) {
2579 methodinfo *mi = &(sc->methods[m]);
2580 if (method_canoverwrite(mi, &(ic->methods[j]))) {
2581 v->interfacetable[-i][j] = v->table[mi->vftblindex];
2592 for (j = 0; j < ic->interfacescount; j++)
2593 class_addinterface(c, ic->interfaces[j]);
2597 /******************* Function: class_new_array *********************************
2599 This function is called by class_new to setup an array class.
2601 *******************************************************************************/
2603 void class_new_array(classinfo *c)
2605 classinfo *comp = NULL;
2609 /* Check array class name */
2610 namelen = c->name->blength;
2611 if (namelen < 2 || c->name->text[0] != '[')
2612 panic("Invalid array class name");
2614 /* Check the component type */
2615 switch (c->name->text[1]) {
2617 /* c is an array of arrays. We have to create the component class. */
2619 comp = class_new_intern(utf_new_intern(c->name->text + 1,
2622 list_addfirst(&unlinkedclasses, comp);
2625 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2630 /* c is an array of objects. */
2631 if (namelen < 4 || c->name->text[namelen - 1] != ';')
2632 panic("Invalid array class name");
2635 comp = class_new_intern(utf_new_intern(c->name->text + 2,
2638 list_addfirst(&unlinkedclasses, comp);
2641 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2646 /* Setup the array class */
2647 c->super = class_java_lang_Object;
2648 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2650 c->interfacescount = 2;
2651 c->interfaces = MNEW(classinfo*, 2);
2656 tc = class_new_intern(utf_new_char("java/lang/Cloneable"));
2658 list_addfirst(&unlinkedclasses, tc);
2659 c->interfaces[0] = tc;
2661 tc = class_new_intern(utf_new_char("java/io/Serializable"));
2663 list_addfirst(&unlinkedclasses, tc);
2664 c->interfaces[1] = tc;
2667 c->interfaces[0] = class_new(utf_new_char("java/lang/Cloneable"));
2668 c->interfaces[1] = class_new(utf_new_char("java/io/Serializable"));
2671 c->methodscount = 1;
2672 c->methods = MNEW(methodinfo, c->methodscount);
2675 memset(clone, 0, sizeof(methodinfo));
2676 clone->flags = ACC_PUBLIC;
2677 clone->name = utf_new_char("clone");
2678 clone->descriptor = utf_new_char("()Ljava/lang/Object;");
2680 clone->stubroutine = createnativestub((functionptr) &builtin_clone_array, clone);
2681 clone->monoPoly = MONO;
2683 /* XXX: field: length? */
2685 /* array classes are not loaded from class files */
2690 /****************** Function: class_link_array *********************************
2692 This function is called by class_link to create the
2693 arraydescriptor for an array class.
2695 This function returns NULL if the array cannot be linked because
2696 the component type has not been linked yet.
2698 *******************************************************************************/
2700 static arraydescriptor *class_link_array(classinfo *c)
2702 classinfo *comp = NULL;
2703 s4 namelen = c->name->blength;
2704 arraydescriptor *desc;
2707 /* Check the component type */
2708 switch (c->name->text[1]) {
2710 /* c is an array of arrays. */
2711 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2713 panic("Could not find component array class.");
2717 /* c is an array of objects. */
2718 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2720 panic("Could not find component class.");
2724 /* If the component type has not been linked, link it now */
2725 if (comp && !comp->linked) {
2727 if (!class_load(comp))
2730 if (!class_link(comp))
2734 /* Allocate the arraydescriptor */
2735 desc = NEW(arraydescriptor);
2738 /* c is an array of references */
2739 desc->arraytype = ARRAYTYPE_OBJECT;
2740 desc->componentsize = sizeof(void*);
2741 desc->dataoffset = OFFSET(java_objectarray, data);
2743 compvftbl = comp->vftbl;
2745 panic("Component class has no vftbl");
2746 desc->componentvftbl = compvftbl;
2748 if (compvftbl->arraydesc) {
2749 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
2750 if (compvftbl->arraydesc->dimension >= 255)
2751 panic("Creating array of dimension >255");
2752 desc->dimension = compvftbl->arraydesc->dimension + 1;
2753 desc->elementtype = compvftbl->arraydesc->elementtype;
2756 desc->elementvftbl = compvftbl;
2757 desc->dimension = 1;
2758 desc->elementtype = ARRAYTYPE_OBJECT;
2762 /* c is an array of a primitive type */
2763 switch (c->name->text[1]) {
2765 desc->arraytype = ARRAYTYPE_BOOLEAN;
2766 desc->dataoffset = OFFSET(java_booleanarray,data);
2767 desc->componentsize = sizeof(u1);
2771 desc->arraytype = ARRAYTYPE_BYTE;
2772 desc->dataoffset = OFFSET(java_bytearray,data);
2773 desc->componentsize = sizeof(u1);
2777 desc->arraytype = ARRAYTYPE_CHAR;
2778 desc->dataoffset = OFFSET(java_chararray,data);
2779 desc->componentsize = sizeof(u2);
2783 desc->arraytype = ARRAYTYPE_DOUBLE;
2784 desc->dataoffset = OFFSET(java_doublearray,data);
2785 desc->componentsize = sizeof(double);
2789 desc->arraytype = ARRAYTYPE_FLOAT;
2790 desc->dataoffset = OFFSET(java_floatarray,data);
2791 desc->componentsize = sizeof(float);
2795 desc->arraytype = ARRAYTYPE_INT;
2796 desc->dataoffset = OFFSET(java_intarray,data);
2797 desc->componentsize = sizeof(s4);
2801 desc->arraytype = ARRAYTYPE_LONG;
2802 desc->dataoffset = OFFSET(java_longarray,data);
2803 desc->componentsize = sizeof(s8);
2807 desc->arraytype = ARRAYTYPE_SHORT;
2808 desc->dataoffset = OFFSET(java_shortarray,data);
2809 desc->componentsize = sizeof(s2);
2813 panic("Invalid array class name");
2816 desc->componentvftbl = NULL;
2817 desc->elementvftbl = NULL;
2818 desc->dimension = 1;
2819 desc->elementtype = desc->arraytype;
2826 /********************** Function: class_link ***********************************
2828 Tries to link a class. The function calculates the length in bytes that
2829 an instance of this class requires as well as the VTBL for methods and
2832 *******************************************************************************/
2834 static classinfo *class_link_intern(classinfo *c);
2836 classinfo *class_link(classinfo *c)
2840 /* enter a monitor on the class */
2842 builtin_monitorenter((java_objectheader *) c);
2844 /* maybe the class is already linked */
2846 builtin_monitorexit((java_objectheader *) c);
2853 if (getcompilingtime)
2854 compilingtime_stop();
2857 loadingtime_start();
2859 /* call the internal function */
2860 r = class_link_intern(c);
2862 /* if return value is NULL, we had a problem and the class is not linked */
2871 if (getcompilingtime)
2872 compilingtime_start();
2874 /* leave the monitor */
2876 builtin_monitorexit((java_objectheader *) c);
2882 static classinfo *class_link_intern(classinfo *c)
2884 s4 supervftbllength; /* vftbllegnth of super class */
2885 s4 vftbllength; /* vftbllength of current class */
2886 s4 interfacetablelength; /* interface table length */
2887 classinfo *super; /* super class */
2888 classinfo *tc; /* temporary class variable */
2889 vftbl_t *v; /* vftbl of current class */
2890 s4 i; /* interface/method/field counter */
2891 arraydescriptor *arraydesc; /* descriptor for array classes */
2893 /* maybe the class is already linked */
2897 /* maybe the class is not loaded */
2903 log_message_class("Linking class: ", c);
2905 /* ok, this class is somewhat linked */
2910 /* check interfaces */
2912 for (i = 0; i < c->interfacescount; i++) {
2913 tc = c->interfaces[i];
2915 /* detect circularity */
2918 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2924 if (!class_load(tc))
2927 if (!(tc->flags & ACC_INTERFACE)) {
2929 new_exception_message(string_java_lang_IncompatibleClassChangeError,
2930 "Implementing class");
2935 if (!class_link(tc))
2939 /* check super class */
2943 if (super == NULL) { /* class java.lang.Object */
2945 c->classUsed = USED; /* Object class is always used CO-RT*/
2947 c->instancesize = sizeof(java_objectheader);
2949 vftbllength = supervftbllength = 0;
2951 c->finalizer = NULL;
2954 /* detect circularity */
2957 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2963 if (!class_load(super))
2966 if (super->flags & ACC_INTERFACE) {
2967 /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
2968 panic("Interface specified as super class");
2971 /* Don't allow extending final classes */
2972 if (super->flags & ACC_FINAL) {
2974 new_exception_message(string_java_lang_VerifyError,
2975 "Cannot inherit from final class");
2980 if (!class_link(super))
2983 /* handle array classes */
2984 if (c->name->text[0] == '[')
2985 if (!(arraydesc = class_link_array(c)))
2988 if (c->flags & ACC_INTERFACE)
2989 c->index = interfaceindex++;
2991 c->index = super->index + 1;
2993 c->instancesize = super->instancesize;
2995 vftbllength = supervftbllength = super->vftbl->vftbllength;
2997 c->finalizer = super->finalizer;
3000 /* compute vftbl length */
3002 for (i = 0; i < c->methodscount; i++) {
3003 methodinfo *m = &(c->methods[i]);
3005 if (!(m->flags & ACC_STATIC)) { /* is instance method */
3010 for (j = 0; j < tc->methodscount; j++) {
3011 if (method_canoverwrite(m, &(tc->methods[j]))) {
3012 if (tc->methods[j].flags & ACC_PRIVATE)
3013 goto notfoundvftblindex;
3015 if (tc->methods[j].flags & ACC_FINAL) {
3016 /* class a overrides final method . */
3018 new_exception(string_java_lang_VerifyError);
3021 m->vftblindex = tc->methods[j].vftblindex;
3022 goto foundvftblindex;
3028 m->vftblindex = (vftbllength++);
3034 #if defined(STATISTICS)
3037 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
3040 /* compute interfacetable length */
3042 interfacetablelength = 0;
3045 for (i = 0; i < tc->interfacescount; i++) {
3046 s4 h = class_highestinterface(tc->interfaces[i]) + 1;
3047 if (h > interfacetablelength)
3048 interfacetablelength = h;
3053 /* allocate virtual function table */
3055 v = (vftbl_t*) mem_alloc(sizeof(vftbl_t) + sizeof(methodptr) *
3056 (vftbllength - 1) + sizeof(methodptr*) *
3057 (interfacetablelength - (interfacetablelength > 0)));
3058 v = (vftbl_t*) (((methodptr*) v) + (interfacetablelength - 1) *
3059 (interfacetablelength > 1));
3060 c->header.vftbl = c->vftbl = v;
3062 v->vftbllength = vftbllength;
3063 v->interfacetablelength = interfacetablelength;
3064 v->arraydesc = arraydesc;
3066 /* store interface index in vftbl */
3067 if (c->flags & ACC_INTERFACE)
3068 v->baseval = -(c->index);
3070 /* copy virtual function table of super class */
3072 for (i = 0; i < supervftbllength; i++)
3073 v->table[i] = super->vftbl->table[i];
3075 /* add method stubs into virtual function table */
3077 for (i = 0; i < c->methodscount; i++) {
3078 methodinfo *m = &(c->methods[i]);
3079 if (!(m->flags & ACC_STATIC)) {
3080 v->table[m->vftblindex] = m->stubroutine;
3084 /* compute instance size and offset of each field */
3086 for (i = 0; i < c->fieldscount; i++) {
3088 fieldinfo *f = &(c->fields[i]);
3090 if (!(f->flags & ACC_STATIC)) {
3091 dsize = desc_typesize(f->descriptor);
3092 c->instancesize = ALIGN(c->instancesize, dsize);
3093 f->offset = c->instancesize;
3094 c->instancesize += dsize;
3098 /* initialize interfacetable and interfacevftbllength */
3100 v->interfacevftbllength = MNEW(s4, interfacetablelength);
3102 #if defined(STATISTICS)
3104 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
3107 for (i = 0; i < interfacetablelength; i++) {
3108 v->interfacevftbllength[i] = 0;
3109 v->interfacetable[-i] = NULL;
3112 /* add interfaces */
3114 for (tc = c; tc != NULL; tc = tc->super) {
3115 for (i = 0; i < tc->interfacescount; i++) {
3116 class_addinterface(c, tc->interfaces[i]);
3120 /* add finalizer method (not for java.lang.Object) */
3125 fi = class_findmethod(c, utf_finalize, utf_fidesc);
3128 if (!(fi->flags & ACC_STATIC)) {
3136 loader_compute_subclasses(c);
3139 log_message_class("Linking done class: ", c);
3141 /* just return c to show that we didn't had a problem */
3147 /******************* Function: class_freepool **********************************
3149 Frees all resources used by this classes Constant Pool.
3151 *******************************************************************************/
3153 static void class_freecpool(classinfo *c)
3159 if (c->cptags && c->cpinfos) {
3160 for (idx = 0; idx < c->cpcount; idx++) {
3161 tag = c->cptags[idx];
3162 info = c->cpinfos[idx];
3166 case CONSTANT_Fieldref:
3167 case CONSTANT_Methodref:
3168 case CONSTANT_InterfaceMethodref:
3169 FREE(info, constant_FMIref);
3171 case CONSTANT_Integer:
3172 FREE(info, constant_integer);
3174 case CONSTANT_Float:
3175 FREE(info, constant_float);
3178 FREE(info, constant_long);
3180 case CONSTANT_Double:
3181 FREE(info, constant_double);
3183 case CONSTANT_NameAndType:
3184 FREE(info, constant_nameandtype);
3192 MFREE(c->cptags, u1, c->cpcount);
3195 MFREE(c->cpinfos, voidptr, c->cpcount);
3199 /*********************** Function: class_free **********************************
3201 Frees all resources used by the class.
3203 *******************************************************************************/
3205 void class_free(classinfo *c)
3213 MFREE(c->interfaces, classinfo*, c->interfacescount);
3216 for (i = 0; i < c->fieldscount; i++)
3217 field_free(&(c->fields[i]));
3218 /* MFREE(c->fields, fieldinfo, c->fieldscount); */
3222 for (i = 0; i < c->methodscount; i++)
3223 method_free(&(c->methods[i]));
3224 /* MFREE(c->methods, methodinfo, c->methodscount); */
3227 if ((v = c->vftbl) != NULL) {
3229 mem_free(v->arraydesc,sizeof(arraydescriptor));
3231 for (i = 0; i < v->interfacetablelength; i++) {
3232 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
3234 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
3236 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
3237 sizeof(methodptr*) * (v->interfacetablelength -
3238 (v->interfacetablelength > 0));
3239 v = (vftbl_t*) (((methodptr*) v) - (v->interfacetablelength - 1) *
3240 (v->interfacetablelength > 1));
3245 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
3247 /* if (c->classvftbl)
3248 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
3254 /************************* Function: class_findfield ***************************
3256 Searches a 'classinfo' structure for a field having the given name and
3259 *******************************************************************************/
3261 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
3265 for (i = 0; i < c->fieldscount; i++) {
3266 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
3267 return &(c->fields[i]);
3270 panic("Can not find field given in CONSTANT_Fieldref");
3272 /* keep compiler happy */
3277 /****************** Function: class_resolvefield_int ***************************
3279 This is an internally used helper function. Do not use this directly.
3281 Tries to resolve a field having the given name and type.
3282 If the field cannot be resolved, NULL is returned.
3284 *******************************************************************************/
3286 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
3291 /* search for field in class c */
3292 for (i = 0; i < c->fieldscount; i++) {
3293 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
3294 return &(c->fields[i]);
3298 /* try superinterfaces recursively */
3299 for (i = 0; i < c->interfacescount; ++i) {
3300 fi = class_resolvefield_int(c->interfaces[i], name, desc);
3305 /* try superclass */
3307 return class_resolvefield_int(c->super, name, desc);
3314 /********************* Function: class_resolvefield ***************************
3316 Resolves a reference from REFERER to a field with NAME and DESC in class C.
3318 If the field cannot be resolved the return value is NULL. If EXCEPT is
3319 true *exceptionptr is set, too.
3321 *******************************************************************************/
3323 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
3324 classinfo *referer, bool except)
3328 /* XXX resolve class c */
3329 /* XXX check access from REFERER to C */
3331 fi = class_resolvefield_int(c, name, desc);
3336 new_exception_utfmessage(string_java_lang_NoSuchFieldError,
3342 /* XXX check access rights */
3348 /************************* Function: class_findmethod **************************
3350 Searches a 'classinfo' structure for a method having the given name and
3351 type and returns the index in the class info structure.
3352 If type is NULL, it is ignored.
3354 *******************************************************************************/
3356 s4 class_findmethodIndex(classinfo *c, utf *name, utf *desc)
3360 for (i = 0; i < c->methodscount; i++) {
3362 /* utf_display_classname(c->name);printf("."); */
3363 /* utf_display(c->methods[i].name);printf("."); */
3364 /* utf_display(c->methods[i].descriptor); */
3367 if ((c->methods[i].name == name) && ((desc == NULL) ||
3368 (c->methods[i].descriptor == desc))) {
3377 /************************* Function: class_findmethod **************************
3379 Searches a 'classinfo' structure for a method having the given name and
3381 If type is NULL, it is ignored.
3383 *******************************************************************************/
3385 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
3387 s4 idx = class_findmethodIndex(c, name, desc);
3392 return &(c->methods[idx]);
3396 /*********************** Function: class_fetchmethod **************************
3398 like class_findmethod, but aborts with an error if the method is not found
3400 *******************************************************************************/
3402 methodinfo *class_fetchmethod(classinfo *c, utf *name, utf *desc)
3406 mi = class_findmethod(c, name, desc);
3409 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3410 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3411 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3412 panic("Method not found");
3419 /*********************** Function: class_findmethod_w**************************
3421 like class_findmethod, but logs a warning if the method is not found
3423 *******************************************************************************/
3425 methodinfo *class_findmethod_w(classinfo *c, utf *name, utf *desc, char *from)
3428 mi = class_findmethod(c, name, desc);
3431 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3432 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3433 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3435 if ( c->flags & ACC_PUBLIC ) log_plain(" PUBLIC ");
3436 if ( c->flags & ACC_PRIVATE ) log_plain(" PRIVATE ");
3437 if ( c->flags & ACC_PROTECTED ) log_plain(" PROTECTED ");
3438 if ( c->flags & ACC_STATIC ) log_plain(" STATIC ");
3439 if ( c->flags & ACC_FINAL ) log_plain(" FINAL ");
3440 if ( c->flags & ACC_SYNCHRONIZED ) log_plain(" SYNCHRONIZED ");
3441 if ( c->flags & ACC_VOLATILE ) log_plain(" VOLATILE ");
3442 if ( c->flags & ACC_TRANSIENT ) log_plain(" TRANSIENT ");
3443 if ( c->flags & ACC_NATIVE ) log_plain(" NATIVE ");
3444 if ( c->flags & ACC_INTERFACE ) log_plain(" INTERFACE ");
3445 if ( c->flags & ACC_ABSTRACT ) log_plain(" ABSTRACT ");
3448 log_plain(" : WARNING: Method not found");log_nl( );
3455 /************************* Function: class_findmethod_approx ******************
3457 like class_findmethod but ignores the return value when comparing the
3460 *******************************************************************************/
3462 methodinfo *class_findmethod_approx(classinfo *c, utf *name, utf *desc)
3466 for (i = 0; i < c->methodscount; i++) {
3467 if (c->methods[i].name == name) {
3468 utf *meth_descr = c->methods[i].descriptor;
3472 return &(c->methods[i]);
3474 if (desc->blength <= meth_descr->blength) {
3475 /* current position in utf text */
3476 char *desc_utf_ptr = desc->text;
3477 char *meth_utf_ptr = meth_descr->text;
3478 /* points behind utf strings */
3479 char *desc_end = utf_end(desc);
3480 char *meth_end = utf_end(meth_descr);
3483 /* compare argument types */
3484 while (desc_utf_ptr < desc_end && meth_utf_ptr < meth_end) {
3486 if ((ch = *desc_utf_ptr++) != (*meth_utf_ptr++))
3487 break; /* no match */
3490 return &(c->methods[i]); /* all parameter types equal */
3500 /***************** Function: class_resolvemethod_approx ***********************
3502 Searches a class and every super class for a method (without paying
3503 attention to the return value)
3505 *******************************************************************************/
3507 methodinfo *class_resolvemethod_approx(classinfo *c, utf *name, utf *desc)
3510 /* search for method (ignore returntype) */
3511 methodinfo *m = class_findmethod_approx(c, name, desc);
3514 /* search superclass */
3522 /************************* Function: class_resolvemethod ***********************
3524 Searches a class and every super class for a method.
3526 *******************************************************************************/
3528 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
3530 /*log_text("Trying to resolve a method");
3531 utf_display(c->name);
3533 utf_display(desc);*/
3536 /*log_text("Looking in:");
3537 utf_display(c->name);*/
3538 methodinfo *m = class_findmethod(c, name, desc);
3540 /* search superclass */
3543 /*log_text("method not found:");*/
3549 /****************** Function: class_resolveinterfacemethod_int ****************
3551 Internally used helper function. Do not use this directly.
3553 *******************************************************************************/
3556 methodinfo *class_resolveinterfacemethod_int(classinfo *c, utf *name, utf *desc)
3561 mi = class_findmethod(c,name,desc);
3565 /* try the superinterfaces */
3566 for (i=0; i<c->interfacescount; ++i) {
3567 mi = class_resolveinterfacemethod_int(c->interfaces[i],name,desc);
3575 /******************** Function: class_resolveinterfacemethod ******************
3577 Resolves a reference from REFERER to a method with NAME and DESC in
3580 If the method cannot be resolved the return value is NULL. If EXCEPT is
3581 true *exceptionptr is set, too.
3583 *******************************************************************************/
3585 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
3586 classinfo *referer, bool except)
3590 /* XXX resolve class c */
3591 /* XXX check access from REFERER to C */
3593 if (!(c->flags & ACC_INTERFACE)) {
3596 new_exception(string_java_lang_IncompatibleClassChangeError);
3601 mi = class_resolveinterfacemethod_int(c, name, desc);
3606 /* try class java.lang.Object */
3607 mi = class_findmethod(class_java_lang_Object, name, desc);
3614 new_exception_utfmessage(string_java_lang_NoSuchMethodError, name);
3620 /********************* Function: class_resolveclassmethod *********************
3622 Resolves a reference from REFERER to a method with NAME and DESC in
3625 If the method cannot be resolved the return value is NULL. If EXCEPT is
3626 true *exceptionptr is set, too.
3628 *******************************************************************************/
3630 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
3631 classinfo *referer, bool except)
3636 char msg[MAXLOGTEXT];
3638 /* XXX resolve class c */
3639 /* XXX check access from REFERER to C */
3641 /* if (c->flags & ACC_INTERFACE) { */
3643 /* *exceptionptr = */
3644 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
3648 /* try class c and its superclasses */
3651 mi = class_findmethod(cls, name, desc);
3654 } while ((cls = cls->super) != NULL); /* try the superclass */
3656 /* try the superinterfaces */
3657 for (i = 0; i < c->interfacescount; ++i) {
3658 mi = class_resolveinterfacemethod_int(c->interfaces[i], name, desc);
3664 utf_sprint(msg, c->name);
3665 sprintf(msg + strlen(msg), ".");
3666 utf_sprint(msg + strlen(msg), name);
3667 utf_sprint(msg + strlen(msg), desc);
3670 new_exception_message(string_java_lang_NoSuchMethodError, msg);
3676 if ((mi->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
3678 *exceptionptr = new_exception(string_java_lang_AbstractMethodError);
3683 /* XXX check access rights */
3689 /************************* Function: class_issubclass **************************
3691 Checks if sub is a descendant of super.
3693 *******************************************************************************/
3695 bool class_issubclass(classinfo *sub, classinfo *super)
3698 if (!sub) return false;
3699 if (sub == super) return true;
3705 /****************** Initialization function for classes ******************
3707 In Java, every class can have a static initialization function. This
3708 function has to be called BEFORE calling other methods or accessing static
3711 *******************************************************************************/
3713 static classinfo *class_init_intern(classinfo *c);
3715 classinfo *class_init(classinfo *c)
3719 if (!makeinitializations)
3722 /* enter a monitor on the class */
3724 builtin_monitorenter((java_objectheader *) c);
3726 /* maybe the class is already initalized or the current thread, which can
3727 pass the monitor, is currently initalizing this class */
3729 if (c->initialized || c->initializing) {
3730 builtin_monitorexit((java_objectheader *) c);
3735 /* this initalizing run begins NOW */
3736 c->initializing = true;
3738 /* call the internal function */
3739 r = class_init_intern(c);
3741 /* if return value is not NULL everything was ok and the class is
3744 c->initialized = true;
3746 /* this initalizing run is done */
3747 c->initializing = false;
3749 /* leave the monitor */
3751 builtin_monitorexit((java_objectheader *) c);
3757 /* this function MUST NOT be called directly, because of thread <clinit>
3760 static classinfo *class_init_intern(classinfo *c)
3764 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3768 /* maybe the class is not already loaded */
3773 /* maybe the class is not already linked */
3778 #if defined(STATISTICS)
3780 count_class_inits++;
3783 /* initialize super class */
3786 if (!c->super->initialized) {
3788 char logtext[MAXLOGTEXT];
3789 sprintf(logtext, "Initialize super class ");
3790 utf_sprint_classname(logtext + strlen(logtext), c->super->name);
3791 sprintf(logtext + strlen(logtext), " from ");
3792 utf_sprint_classname(logtext + strlen(logtext), c->name);
3796 if (!class_init(c->super))
3801 /* initialize interface classes */
3803 for (i = 0; i < c->interfacescount; i++) {
3804 if (!c->interfaces[i]->initialized) {
3806 char logtext[MAXLOGTEXT];
3807 sprintf(logtext, "Initialize interface class ");
3808 utf_sprint_classname(logtext + strlen(logtext), c->interfaces[i]->name);
3809 sprintf(logtext + strlen(logtext), " from ");
3810 utf_sprint_classname(logtext + strlen(logtext), c->name);
3814 if (!class_init(c->interfaces[i]))
3819 m = class_findmethod(c, utf_clinit, utf_fidesc);
3823 char logtext[MAXLOGTEXT];
3824 sprintf(logtext, "Class ");
3825 utf_sprint_classname(logtext + strlen(logtext), c->name);
3826 sprintf(logtext + strlen(logtext), " has no static class initializer");
3833 /* Sun's and IBM's JVM don't care about the static flag */
3834 /* if (!(m->flags & ACC_STATIC)) { */
3835 /* panic("Class initializer is not static!"); */
3838 log_message_class("Starting static class initializer for class: ", c);
3840 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3845 /* now call the initializer */
3846 asm_calljavafunction(m, NULL, NULL, NULL, NULL);
3848 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3849 assert(blockInts == 0);
3853 /* we have an exception or error */
3854 if (*exceptionptr) {
3855 /* class is NOT initialized */
3856 c->initialized = false;
3858 /* is this an exception, than wrap it */
3859 if (builtin_instanceof(*exceptionptr, class_java_lang_Exception)) {
3860 java_objectheader *xptr;
3861 java_objectheader *cause;
3864 cause = *exceptionptr;
3866 /* clear exception, because we are calling jit code again */
3867 *exceptionptr = NULL;
3869 /* wrap the exception */
3871 new_exception_throwable(string_java_lang_ExceptionInInitializerError,
3872 (java_lang_Throwable *) cause);
3874 /* XXX should we exit here? */
3878 /* set new exception */
3879 *exceptionptr = xptr;
3886 log_message_class("Finished static class initializer for class: ", c);
3892 /********* Function: find_class_method_constant *********/
3894 int find_class_method_constant (classinfo *c, utf * c1, utf* m1, utf* d1)
3899 for (i=0; i<c->cpcount; i++) {
3901 e = c -> cpinfos [i];
3904 switch (c -> cptags [i]) {
3905 case CONSTANT_Methodref:
3907 constant_FMIref *fmi = e;
3908 if ( (fmi->class->name == c1)
3909 && (fmi->name == m1)
3910 && (fmi->descriptor == d1)) {
3917 case CONSTANT_InterfaceMethodref:
3919 constant_FMIref *fmi = e;
3920 if ( (fmi->class->name == c1)
3921 && (fmi->name == m1)
3922 && (fmi->descriptor == d1)) {
3936 void class_showconstanti(classinfo *c, int ii)
3942 printf ("#%d: ", (int) i);
3944 switch (c->cptags [i]) {
3945 case CONSTANT_Class:
3946 printf("Classreference -> ");
3947 utf_display(((classinfo*)e)->name);
3950 case CONSTANT_Fieldref:
3951 printf("Fieldref -> "); goto displayFMIi;
3952 case CONSTANT_Methodref:
3953 printf("Methodref -> "); goto displayFMIi;
3954 case CONSTANT_InterfaceMethodref:
3955 printf("InterfaceMethod -> "); goto displayFMIi;
3958 constant_FMIref *fmi = e;
3959 utf_display(fmi->class->name);
3961 utf_display(fmi->name);
3963 utf_display(fmi->descriptor);
3967 case CONSTANT_String:
3968 printf("String -> ");
3971 case CONSTANT_Integer:
3972 printf("Integer -> %d", (int) (((constant_integer*)e)->value));
3974 case CONSTANT_Float:
3975 printf("Float -> %f", ((constant_float*)e)->value);
3977 case CONSTANT_Double:
3978 printf("Double -> %f", ((constant_double*)e)->value);
3982 u8 v = ((constant_long*)e)->value;
3984 printf("Long -> %ld", (long int) v);
3986 printf("Long -> HI: %ld, LO: %ld\n",
3987 (long int) v.high, (long int) v.low);
3991 case CONSTANT_NameAndType:
3993 constant_nameandtype *cnt = e;
3994 printf("NameAndType: ");
3995 utf_display(cnt->name);
3997 utf_display(cnt->descriptor);
4005 panic("Invalid type of ConstantPool-Entry");
4012 void class_showconstantpool (classinfo *c)
4017 printf ("---- dump of constant pool ----\n");
4019 for (i=0; i<c->cpcount; i++) {
4020 printf ("#%d: ", (int) i);
4022 e = c -> cpinfos [i];
4025 switch (c -> cptags [i]) {
4026 case CONSTANT_Class:
4027 printf ("Classreference -> ");
4028 utf_display ( ((classinfo*)e) -> name );
4031 case CONSTANT_Fieldref:
4032 printf ("Fieldref -> "); goto displayFMI;
4033 case CONSTANT_Methodref:
4034 printf ("Methodref -> "); goto displayFMI;
4035 case CONSTANT_InterfaceMethodref:
4036 printf ("InterfaceMethod -> "); goto displayFMI;
4039 constant_FMIref *fmi = e;
4040 utf_display ( fmi->class->name );
4042 utf_display ( fmi->name);
4044 utf_display ( fmi->descriptor );
4048 case CONSTANT_String:
4049 printf ("String -> ");
4052 case CONSTANT_Integer:
4053 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
4055 case CONSTANT_Float:
4056 printf ("Float -> %f", ((constant_float*)e) -> value);
4058 case CONSTANT_Double:
4059 printf ("Double -> %f", ((constant_double*)e) -> value);
4063 u8 v = ((constant_long*)e) -> value;
4065 printf ("Long -> %ld", (long int) v);
4067 printf ("Long -> HI: %ld, LO: %ld\n",
4068 (long int) v.high, (long int) v.low);
4072 case CONSTANT_NameAndType:
4074 constant_nameandtype *cnt = e;
4075 printf ("NameAndType: ");
4076 utf_display (cnt->name);
4078 utf_display (cnt->descriptor);
4082 printf ("Utf8 -> ");
4086 panic ("Invalid type of ConstantPool-Entry");
4096 /********** Function: class_showmethods (debugging only) *************/
4098 void class_showmethods (classinfo *c)
4102 printf ("--------- Fields and Methods ----------------\n");
4103 printf ("Flags: "); printflags (c->flags); printf ("\n");
4105 printf ("This: "); utf_display (c->name); printf ("\n");
4107 printf ("Super: "); utf_display (c->super->name); printf ("\n");
4109 printf ("Index: %d\n", c->index);
4111 printf ("interfaces:\n");
4112 for (i=0; i < c-> interfacescount; i++) {
4114 utf_display (c -> interfaces[i] -> name);
4115 printf (" (%d)\n", c->interfaces[i] -> index);
4118 printf ("fields:\n");
4119 for (i=0; i < c -> fieldscount; i++) {
4120 field_display (&(c -> fields[i]));
4123 printf ("methods:\n");
4124 for (i=0; i < c -> methodscount; i++) {
4125 methodinfo *m = &(c->methods[i]);
4126 if ( !(m->flags & ACC_STATIC))
4127 printf ("vftblindex: %d ", m->vftblindex);
4129 method_display ( m );
4133 printf ("Virtual function table:\n");
4134 for (i=0; i<c->vftbl->vftbllength; i++) {
4135 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]) );
4141 /******************************************************************************/
4142 /******************* General functions for the class loader *******************/
4143 /******************************************************************************/
4145 /**************** function: create_primitive_classes ***************************
4147 create classes representing primitive types
4149 *******************************************************************************/
4151 static bool create_primitive_classes()
4155 for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
4156 /* create primitive class */
4158 class_new_intern(utf_new_char(primitivetype_table[i].name));
4159 c->classUsed = NOTUSED; /* not used initially CO-RT */
4162 /* prevent loader from loading primitive class */
4167 primitivetype_table[i].class_primitive = c;
4169 /* create class for wrapping the primitive type */
4170 c = class_new_intern(utf_new_char(primitivetype_table[i].wrapname));
4171 primitivetype_table[i].class_wrap = c;
4172 primitivetype_table[i].class_wrap->classUsed = NOTUSED; /* not used initially CO-RT */
4173 primitivetype_table[i].class_wrap->impldBy = NULL;
4175 /* create the primitive array class */
4176 if (primitivetype_table[i].arrayname) {
4177 c = class_new_intern(utf_new_char(primitivetype_table[i].arrayname));
4178 primitivetype_table[i].arrayclass = c;
4183 primitivetype_table[i].arrayvftbl = c->vftbl;
4191 /**************** function: class_primitive_from_sig ***************************
4193 return the primitive class indicated by the given signature character
4195 If the descriptor does not indicate a valid primitive type the
4196 return value is NULL.
4198 ********************************************************************************/
4200 classinfo *class_primitive_from_sig(char sig)
4203 case 'I': return primitivetype_table[PRIMITIVETYPE_INT].class_primitive;
4204 case 'J': return primitivetype_table[PRIMITIVETYPE_LONG].class_primitive;
4205 case 'F': return primitivetype_table[PRIMITIVETYPE_FLOAT].class_primitive;
4206 case 'D': return primitivetype_table[PRIMITIVETYPE_DOUBLE].class_primitive;
4207 case 'B': return primitivetype_table[PRIMITIVETYPE_BYTE].class_primitive;
4208 case 'C': return primitivetype_table[PRIMITIVETYPE_CHAR].class_primitive;
4209 case 'S': return primitivetype_table[PRIMITIVETYPE_SHORT].class_primitive;
4210 case 'Z': return primitivetype_table[PRIMITIVETYPE_BOOLEAN].class_primitive;
4211 case 'V': return primitivetype_table[PRIMITIVETYPE_VOID].class_primitive;
4216 /****************** function: class_from_descriptor ****************************
4218 return the class indicated by the given descriptor
4220 utf_ptr....first character of descriptor
4221 end_ptr....first character after the end of the string
4222 next.......if non-NULL, *next is set to the first character after
4223 the descriptor. (Undefined if an error occurs.)
4225 mode.......a combination (binary or) of the following flags:
4227 (Flags marked with * are the default settings.)
4229 What to do if a reference type descriptor is parsed successfully:
4231 CLASSLOAD_SKIP...skip it and return something != NULL
4232 * CLASSLOAD_NEW....get classinfo * via class_new
4233 CLASSLOAD_LOAD...get classinfo * via loader_load
4235 How to handle primitive types:
4237 * CLASSLOAD_PRIMITIVE.......return primitive class (eg. "int")
4238 CLASSLOAD_NULLPRIMITIVE...return NULL for primitive types
4240 How to handle "V" descriptors:
4242 * CLASSLOAD_VOID.....handle it like other primitive types
4243 CLASSLOAD_NOVOID...treat it as an error
4245 How to deal with extra characters after the end of the
4248 * CLASSLOAD_NOCHECKEND...ignore (useful for parameter lists)
4249 CLASSLOAD_CHECKEND.....treat them as an error
4251 How to deal with errors:
4253 * CLASSLOAD_PANIC....abort execution with an error message
4254 CLASSLOAD_NOPANIC..return NULL on error
4256 *******************************************************************************/
4258 classinfo *class_from_descriptor(char *utf_ptr, char *end_ptr,
4259 char **next, int mode)
4261 char *start = utf_ptr;
4265 SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr, end_ptr, error);
4267 if (mode & CLASSLOAD_CHECKEND)
4268 error |= (utf_ptr != end_ptr);
4271 if (next) *next = utf_ptr;
4275 if (mode & CLASSLOAD_NOVOID)
4286 return (mode & CLASSLOAD_NULLPRIMITIVE)
4288 : class_primitive_from_sig(*start);
4295 if (mode & CLASSLOAD_SKIP) return class_java_lang_Object;
4296 name = utf_new(start, utf_ptr - start);
4300 tc = class_new_intern(name);
4302 list_addfirst(&unlinkedclasses, tc);
4307 return (mode & CLASSLOAD_LOAD)
4308 ? class_load(class_new(name)) : class_new(name); /* XXX handle errors */
4313 /* An error occurred */
4314 if (mode & CLASSLOAD_NOPANIC)
4317 log_plain("Invalid descriptor at beginning of '");
4318 log_plain_utf(utf_new(start, end_ptr - start));
4322 panic("Invalid descriptor");
4324 /* keep compiler happy */
4329 /******************* function: type_from_descriptor ****************************
4331 return the basic type indicated by the given descriptor
4333 This function parses a descriptor and returns its basic type as
4334 TYPE_INT, TYPE_LONG, TYPE_FLOAT, TYPE_DOUBLE, TYPE_ADDRESS or TYPE_VOID.
4336 cls...if non-NULL the referenced variable is set to the classinfo *
4337 returned by class_from_descriptor.
4339 For documentation of the arguments utf_ptr, end_ptr, next and mode
4340 see class_from_descriptor. The only difference is that
4341 type_from_descriptor always uses CLASSLOAD_PANIC.
4343 ********************************************************************************/
4345 int type_from_descriptor(classinfo **cls, char *utf_ptr, char *end_ptr,
4346 char **next, int mode)
4349 if (!cls) cls = &mycls;
4350 *cls = class_from_descriptor(utf_ptr, end_ptr, next, mode & (~CLASSLOAD_NOPANIC));
4367 return TYPE_ADDRESS;
4371 /*************** function: create_pseudo_classes *******************************
4373 create pseudo classes used by the typechecker
4375 ********************************************************************************/
4377 static void create_pseudo_classes()
4379 /* pseudo class for Arraystubs (extends java.lang.Object) */
4381 pseudo_class_Arraystub = class_new_intern(utf_new_char("$ARRAYSTUB$"));
4382 pseudo_class_Arraystub->loaded = true;
4383 pseudo_class_Arraystub->super = class_java_lang_Object;
4384 pseudo_class_Arraystub->interfacescount = 2;
4385 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
4386 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
4387 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
4389 class_link(pseudo_class_Arraystub);
4391 pseudo_class_Arraystub_vftbl = pseudo_class_Arraystub->vftbl;
4393 /* pseudo class representing the null type */
4395 pseudo_class_Null = class_new_intern(utf_new_char("$NULL$"));
4396 pseudo_class_Null->loaded = true;
4397 pseudo_class_Null->super = class_java_lang_Object;
4398 class_link(pseudo_class_Null);
4400 /* pseudo class representing new uninitialized objects */
4402 pseudo_class_New = class_new_intern(utf_new_char("$NEW$"));
4403 pseudo_class_New->loaded = true;
4404 pseudo_class_New->linked = true;
4405 pseudo_class_New->super = class_java_lang_Object;
4406 /* class_link(pseudo_class_New); */
4410 /********************** Function: loader_init **********************************
4412 Initializes all lists and loads all classes required for the system or the
4415 *******************************************************************************/
4417 void loader_init(u1 *stackbottom)
4421 /* create utf-symbols for pointer comparison of frequently used strings */
4422 utf_innerclasses = utf_new_char("InnerClasses");
4423 utf_constantvalue = utf_new_char("ConstantValue");
4424 utf_code = utf_new_char("Code");
4425 utf_exceptions = utf_new_char("Exceptions");
4426 utf_linenumbertable = utf_new_char("LineNumberTable");
4427 utf_sourcefile = utf_new_char("SourceFile");
4428 utf_finalize = utf_new_char("finalize");
4429 utf_fidesc = utf_new_char("()V");
4430 utf_init = utf_new_char("<init>");
4431 utf_clinit = utf_new_char("<clinit>");
4432 utf_initsystemclass = utf_new_char("initializeSystemClass");
4433 utf_systemclass = utf_new_char("java/lang/System");
4434 utf_vmclassloader = utf_new_char("java/lang/VMClassLoader");
4435 utf_initialize = utf_new_char("initialize");
4436 utf_initializedesc = utf_new_char("(I)V");
4437 utf_vmclass = utf_new_char("java/lang/VMClass");
4438 utf_java_lang_Object= utf_new_char("java/lang/Object");
4439 array_packagename = utf_new_char("<the array package>");
4440 utf_fillInStackTrace_name = utf_new_char("fillInStackTrace");
4441 utf_fillInStackTrace_desc = utf_new_char("()Ljava/lang/Throwable;");
4443 /* create some important classes */
4444 /* These classes have to be created now because the classinfo
4445 * pointers are used in the loading code.
4447 class_java_lang_Object = class_new_intern(utf_java_lang_Object);
4448 class_load(class_java_lang_Object);
4449 class_link(class_java_lang_Object);
4451 class_java_lang_String = class_new(utf_new_char("java/lang/String"));
4452 class_load(class_java_lang_String);
4453 class_link(class_java_lang_String);
4455 class_java_lang_Cloneable = class_new(utf_new_char("java/lang/Cloneable"));
4456 class_load(class_java_lang_Cloneable);
4457 class_link(class_java_lang_Cloneable);
4459 class_java_io_Serializable =
4460 class_new(utf_new_char("java/io/Serializable"));
4461 class_load(class_java_io_Serializable);
4462 class_link(class_java_io_Serializable);
4464 /* create classes representing primitive types */
4465 create_primitive_classes();
4467 /* create classes used by the typechecker */
4468 create_pseudo_classes();
4470 /* correct vftbl-entries (retarded loading of class java/lang/String) */
4471 stringtable_update();
4473 #if defined(USE_THREADS)
4474 if (stackbottom != 0)
4480 /* loader_compute_subclasses ***************************************************
4484 *******************************************************************************/
4486 static void loader_compute_class_values(classinfo *c);
4488 void loader_compute_subclasses(classinfo *c)
4490 #if defined(USE_THREADS)
4491 #if defined(NATIVE_THREADS)
4498 if (!(c->flags & ACC_INTERFACE)) {
4503 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
4504 c->nextsub = c->super->sub;
4510 /* this is the java.lang.Object special case */
4512 if (!class_java_lang_Object) {
4513 loader_compute_class_values(c);
4516 loader_compute_class_values(class_java_lang_Object);
4519 #if defined(USE_THREADS)
4520 #if defined(NATIVE_THREADS)
4529 /* loader_compute_class_values *************************************************
4533 *******************************************************************************/
4535 static void loader_compute_class_values(classinfo *c)
4539 c->vftbl->baseval = ++classvalue;
4543 loader_compute_class_values(subs);
4544 subs = subs->nextsub;
4547 c->vftbl->diffval = classvalue - c->vftbl->baseval;
4551 /******************** Function: loader_close ***********************************
4555 *******************************************************************************/
4562 for (slot = 0; slot < class_hash.size; slot++) {
4563 c = class_hash.ptr[slot];
4574 * These are local overrides for various environment variables in Emacs.
4575 * Please do not remove this and leave it at the end of the file, where
4576 * Emacs will automagically detect them.
4577 * ---------------------------------------------------------------------
4580 * indent-tabs-mode: t