1 /* vm/loader.c - class loader functions
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5 M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6 P. Tomsich, J. Wenninger
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Reinhard Grafl
29 Changes: Andreas Krall
35 $Id: loader.c 1621 2004-11-30 13:06:55Z 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"
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 */
493 filenamelen = utf_strlen(c->name) + 7; /* 7 = ".class\0" */
494 filename = MNEW(char, filenamelen);
496 utf_sprint(filename, c->name);
497 strcat(filename, ".class");
499 /* walk through all classpath entries */
501 for (cpi = classpath_entries; cpi != NULL && cb == NULL; cpi = cpi->filepath.next) {
502 #if defined(USE_ZLIB)
503 if (cpi->filepath.type == CLASSPATH_ARCHIVE) {
504 if (cacao_locate(cpi->archive.uf, c->name) == UNZ_OK) {
505 unz_file_info file_info;
507 if (unzGetCurrentFileInfo(cpi->archive.uf, &file_info, filename,
508 sizeof(filename), NULL, 0, NULL, 0) == UNZ_OK) {
509 if (unzOpenCurrentFile(cpi->archive.uf) == UNZ_OK) {
510 cb = NEW(classbuffer);
512 cb->size = file_info.uncompressed_size;
513 cb->data = MNEW(u1, cb->size);
514 cb->pos = cb->data - 1;
516 len = unzReadCurrentFile(cpi->archive.uf, cb->data, cb->size);
518 if (len != cb->size) {
520 log_text("Error while unzipping");
524 log_text("Error while opening file in archive");
528 log_text("Error while retrieving fileinfo");
531 unzCloseCurrentFile(cpi->archive.uf);
534 #endif /* USE_ZLIB */
536 path = MNEW(char, cpi->filepath.pathlen + filenamelen + 1);
537 strcpy(path, cpi->filepath.path);
538 strcat(path, filename);
540 classfile = fopen(path, "r");
542 if (classfile) { /* file exists */
543 /* determine size of classfile */
544 err = stat(path, &buffer);
546 if (!err) { /* read classfile data */
547 cb = NEW(classbuffer);
549 cb->size = buffer.st_size;
550 cb->data = MNEW(u1, cb->size);
551 cb->pos = cb->data - 1;
553 /* read class data */
554 len = fread(cb->data, 1, cb->size, classfile);
556 if (len != buffer.st_size) {
558 /* if (ferror(classfile)) { */
564 MFREE(path, char, cpi->filepath.pathlen + filenamelen + 1);
565 #if defined(USE_ZLIB)
572 dolog("Warning: Can not open class file '%s'", filename);
575 MFREE(filename, char, filenamelen);
581 /************************** function suck_stop *********************************
583 frees memory for buffer with classfile data.
584 Caution: this function may only be called if buffer has been allocated
585 by suck_start with reading a file
587 *******************************************************************************/
589 void suck_stop(classbuffer *cb)
593 MFREE(cb->data, u1, cb->size);
594 FREE(cb, classbuffer);
598 /******************************************************************************/
599 /******************* Some support functions ***********************************/
600 /******************************************************************************/
602 void fprintflags (FILE *fp, u2 f)
604 if ( f & ACC_PUBLIC ) fprintf (fp," PUBLIC");
605 if ( f & ACC_PRIVATE ) fprintf (fp," PRIVATE");
606 if ( f & ACC_PROTECTED ) fprintf (fp," PROTECTED");
607 if ( f & ACC_STATIC ) fprintf (fp," STATIC");
608 if ( f & ACC_FINAL ) fprintf (fp," FINAL");
609 if ( f & ACC_SYNCHRONIZED ) fprintf (fp," SYNCHRONIZED");
610 if ( f & ACC_VOLATILE ) fprintf (fp," VOLATILE");
611 if ( f & ACC_TRANSIENT ) fprintf (fp," TRANSIENT");
612 if ( f & ACC_NATIVE ) fprintf (fp," NATIVE");
613 if ( f & ACC_INTERFACE ) fprintf (fp," INTERFACE");
614 if ( f & ACC_ABSTRACT ) fprintf (fp," ABSTRACT");
618 /********** internal function: printflags (only for debugging) ***************/
620 void printflags(u2 f)
622 if ( f & ACC_PUBLIC ) printf (" PUBLIC");
623 if ( f & ACC_PRIVATE ) printf (" PRIVATE");
624 if ( f & ACC_PROTECTED ) printf (" PROTECTED");
625 if ( f & ACC_STATIC ) printf (" STATIC");
626 if ( f & ACC_FINAL ) printf (" FINAL");
627 if ( f & ACC_SYNCHRONIZED ) printf (" SYNCHRONIZED");
628 if ( f & ACC_VOLATILE ) printf (" VOLATILE");
629 if ( f & ACC_TRANSIENT ) printf (" TRANSIENT");
630 if ( f & ACC_NATIVE ) printf (" NATIVE");
631 if ( f & ACC_INTERFACE ) printf (" INTERFACE");
632 if ( f & ACC_ABSTRACT ) printf (" ABSTRACT");
636 /********************** Function: skipattributebody ****************************
638 skips an attribute after the 16 bit reference to attribute_name has already
641 *******************************************************************************/
643 static bool skipattributebody(classbuffer *cb)
647 if (!check_classbuffer_size(cb, 4))
652 if (!check_classbuffer_size(cb, len))
655 skip_nbytes(cb, len);
661 /************************* Function: skipattributes ****************************
663 skips num attribute structures
665 *******************************************************************************/
667 static bool skipattributes(classbuffer *cb, u4 num)
672 for (i = 0; i < num; i++) {
673 if (!check_classbuffer_size(cb, 2 + 4))
679 if (!check_classbuffer_size(cb, len))
682 skip_nbytes(cb, len);
689 /******************** function:: class_getconstant *****************************
691 retrieves the value at position 'pos' of the constantpool of a class
692 if the type of the value is other than 'ctype' the system is stopped
694 *******************************************************************************/
696 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
698 /* check index and type of constantpool entry */
699 /* (pos == 0 is caught by type comparison) */
700 if (pos >= c->cpcount || c->cptags[pos] != ctype) {
701 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
705 return c->cpinfos[pos];
709 /******************** function: innerclass_getconstant ************************
711 like class_getconstant, but if cptags is ZERO null is returned
713 *******************************************************************************/
715 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
717 /* invalid position in constantpool */
718 if (pos >= c->cpcount) {
719 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
723 /* constantpool entry of type 0 */
727 /* check type of constantpool entry */
728 if (c->cptags[pos] != ctype) {
729 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
733 return c->cpinfos[pos];
737 /********************* Function: class_constanttype ****************************
739 Determines the type of a class entry in the ConstantPool
741 *******************************************************************************/
743 u4 class_constanttype(classinfo *c, u4 pos)
745 if (pos <= 0 || pos >= c->cpcount) {
746 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
750 return c->cptags[pos];
754 /************************ function: attribute_load ****************************
756 read attributes from classfile
758 *******************************************************************************/
760 static bool attribute_load(classbuffer *cb, classinfo *c, u4 num)
765 for (i = 0; i < num; i++) {
766 /* retrieve attribute name */
767 if (!check_classbuffer_size(cb, 2))
770 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
773 if (aname == utf_innerclasses) {
774 /* innerclasses attribute */
777 new_classformaterror(c, "Multiple InnerClasses attributes");
781 if (!check_classbuffer_size(cb, 4 + 2))
784 /* skip attribute length */
787 /* number of records */
788 c->innerclasscount = suck_u2(cb);
790 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
793 /* allocate memory for innerclass structure */
794 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
796 for (j = 0; j < c->innerclasscount; j++) {
797 /* The innerclass structure contains a class with an encoded
798 name, its defining scope, its simple name and a bitmask of
799 the access flags. If an inner class is not a member, its
800 outer_class is NULL, if a class is anonymous, its name is
803 innerclassinfo *info = c->innerclass + j;
806 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
808 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
810 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
811 info->flags = suck_u2(cb);
814 } else if (aname == utf_sourcefile) {
815 if (!check_classbuffer_size(cb, 4 + 2))
818 if (suck_u4(cb) != 2) {
820 new_classformaterror(c, "Wrong size for VALUE attribute");
826 new_classformaterror(c, "Multiple SourceFile attributes");
830 if (!(c->sourcefile = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
834 /* unknown attribute */
835 if (!skipattributebody(cb))
844 /******************* function: checkfielddescriptor ****************************
846 checks whether a field-descriptor is valid and aborts otherwise
847 all referenced classes are inserted into the list of unloaded classes
849 *******************************************************************************/
851 static void checkfielddescriptor (char *utf_ptr, char *end_pos)
853 class_from_descriptor(utf_ptr,end_pos,NULL,
855 | CLASSLOAD_NULLPRIMITIVE
857 | CLASSLOAD_CHECKEND);
859 /* XXX use the following if -noverify */
861 char *tstart; /* pointer to start of classname */
863 char *start = utf_ptr;
865 switch (*utf_ptr++) {
879 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
880 panic ("Ill formed descriptor");
884 panic ("Ill formed descriptor");
887 /* exceeding characters */
888 if (utf_ptr!=end_pos) panic ("descriptor has exceeding chars");
893 /******************* function checkmethoddescriptor ****************************
895 checks whether a method-descriptor is valid and aborts otherwise.
896 All referenced classes are inserted into the list of unloaded classes.
898 The number of arguments is returned. A long or double argument is counted
901 *******************************************************************************/
903 static int checkmethoddescriptor(classinfo *c, utf *descriptor)
905 char *utf_ptr; /* current position in utf text */
906 char *end_pos; /* points behind utf string */
907 s4 argcount = 0; /* number of arguments */
909 utf_ptr = descriptor->text;
910 end_pos = utf_end(descriptor);
912 /* method descriptor must start with parenthesis */
913 if (utf_ptr == end_pos || *utf_ptr++ != '(')
914 panic ("Missing '(' in method descriptor");
916 /* check arguments */
917 while (utf_ptr != end_pos && *utf_ptr != ')') {
918 /* We cannot count the this argument here because
919 * we don't know if the method is static. */
920 if (*utf_ptr == 'J' || *utf_ptr == 'D')
924 class_from_descriptor(utf_ptr,end_pos,&utf_ptr,
926 | CLASSLOAD_NULLPRIMITIVE
930 if (utf_ptr == end_pos)
931 panic("Missing ')' in method descriptor");
933 utf_ptr++; /* skip ')' */
935 class_from_descriptor(utf_ptr,
939 CLASSLOAD_NULLPRIMITIVE |
942 if (argcount > 255) {
944 new_classformaterror(c, "Too many arguments in signature");
951 /* XXX use the following if -noverify */
953 /* check arguments */
954 while ((c = *utf_ptr++) != ')') {
971 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
972 panic ("Ill formed method descriptor");
976 panic ("Ill formed methodtype-descriptor");
980 /* check returntype */
982 /* returntype void */
983 if ((utf_ptr+1) != end_pos) panic ("Method-descriptor has exceeding chars");
986 /* treat as field-descriptor */
987 checkfielddescriptor (utf_ptr,end_pos);
992 /***************** Function: print_arraydescriptor ****************************
994 Debugging helper for displaying an arraydescriptor
996 *******************************************************************************/
998 void print_arraydescriptor(FILE *file, arraydescriptor *desc)
1001 fprintf(file, "<NULL>");
1006 if (desc->componentvftbl) {
1007 if (desc->componentvftbl->class)
1008 utf_fprint(file, desc->componentvftbl->class->name);
1010 fprintf(file, "<no classinfo>");
1016 if (desc->elementvftbl) {
1017 if (desc->elementvftbl->class)
1018 utf_fprint(file, desc->elementvftbl->class->name);
1020 fprintf(file, "<no classinfo>");
1024 fprintf(file, ",%d,%d,%d,%d}", desc->arraytype, desc->dimension,
1025 desc->dataoffset, desc->componentsize);
1029 /******************************************************************************/
1030 /************************** Functions for fields ****************************/
1031 /******************************************************************************/
1034 /* field_load ******************************************************************
1036 Load everything about a class field from the class file and fill a
1037 'fieldinfo' structure. For static fields, space in the data segment is
1040 *******************************************************************************/
1042 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
1044 static bool field_load(classbuffer *cb, classinfo *c, fieldinfo *f)
1048 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
1051 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1054 f->flags = suck_u2(cb);
1056 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1060 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1066 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<')
1067 panic("Field with invalid name");
1069 /* check flag consistency */
1070 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
1072 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
1073 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
1075 new_classformaterror(c,
1076 "Illegal field modifiers: 0x%X",
1081 if (c->flags & ACC_INTERFACE) {
1082 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
1083 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
1084 f->flags & ACC_TRANSIENT) {
1086 new_classformaterror(c,
1087 "Illegal field modifiers: 0x%X",
1093 /* check descriptor */
1094 checkfielddescriptor(f->descriptor->text, utf_end(f->descriptor));
1097 f->type = jtype = desc_to_type(f->descriptor); /* data type */
1098 f->offset = 0; /* offset from start of object */
1103 case TYPE_INT: f->value.i = 0; break;
1104 case TYPE_FLOAT: f->value.f = 0.0; break;
1105 case TYPE_DOUBLE: f->value.d = 0.0; break;
1106 case TYPE_ADDRESS: f->value.a = NULL; break;
1109 f->value.l = 0; break;
1111 f->value.l.low = 0; f->value.l.high = 0; break;
1115 /* read attributes */
1116 if (!check_classbuffer_size(cb, 2))
1119 attrnum = suck_u2(cb);
1120 for (i = 0; i < attrnum; i++) {
1121 if (!check_classbuffer_size(cb, 2))
1124 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1127 if (u == utf_constantvalue) {
1128 if (!check_classbuffer_size(cb, 4 + 2))
1131 /* check attribute length */
1132 if (suck_u4(cb) != 2) {
1134 new_classformaterror(c, "Wrong size for VALUE attribute");
1138 /* constant value attribute */
1139 if (pindex != field_load_NOVALUE) {
1141 new_classformaterror(c,
1142 "Multiple ConstantValue attributes");
1146 /* index of value in constantpool */
1147 pindex = suck_u2(cb);
1149 /* initialize field with value from constantpool */
1152 constant_integer *ci;
1154 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
1157 f->value.i = ci->value;
1164 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
1167 f->value.l = cl->value;
1174 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
1177 f->value.f = cf->value;
1182 constant_double *cd;
1184 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
1187 f->value.d = cd->value;
1192 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
1195 /* create javastring from compressed utf8-string */
1196 f->value.a = literalstring_new(u);
1200 log_text("Invalid Constant - Type");
1204 /* unknown attribute */
1205 if (!skipattributebody(cb))
1210 /* everything was ok */
1216 /********************** function: field_free **********************************/
1218 static void field_free(fieldinfo *f)
1224 /**************** Function: field_display (debugging only) ********************/
1226 void field_display(fieldinfo *f)
1229 printflags(f->flags);
1231 utf_display(f->name);
1233 utf_display(f->descriptor);
1234 printf(" offset: %ld\n", (long int) (f->offset));
1238 /******************************************************************************/
1239 /************************* Functions for methods ******************************/
1240 /******************************************************************************/
1243 /* method_load *****************************************************************
1245 Loads a method from the class file and fills an existing 'methodinfo'
1246 structure. For native methods, the function pointer field is set to the
1247 real function pointer, for JavaVM methods a pointer to the compiler is used
1250 *******************************************************************************/
1252 static bool method_load(classbuffer *cb, classinfo *c, methodinfo *m)
1260 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1261 initObjectLock(&m->header);
1266 count_all_methods++;
1269 m->thrownexceptionscount = 0;
1270 m->linenumbercount = 0;
1273 m->nativelyoverloaded = false;
1275 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1278 m->flags = suck_u2(cb);
1280 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1284 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1289 if (!is_valid_name_utf(m->name))
1290 panic("Method with invalid name");
1292 if (m->name->text[0] == '<'
1293 && m->name != utf_init && m->name != utf_clinit)
1294 panic("Method with invalid special name");
1297 argcount = checkmethoddescriptor(c, m->descriptor);
1299 if (!(m->flags & ACC_STATIC))
1300 argcount++; /* count the 'this' argument */
1303 if (argcount > 255) {
1305 new_classformaterror(c, "Too many arguments in signature");
1309 /* check flag consistency */
1310 if (m->name != utf_clinit) {
1311 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1313 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1315 new_classformaterror(c,
1316 "Illegal method modifiers: 0x%X",
1321 if (m->flags & ACC_ABSTRACT) {
1322 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1323 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1325 new_classformaterror(c,
1326 "Illegal method modifiers: 0x%X",
1332 if (c->flags & ACC_INTERFACE) {
1333 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1335 new_classformaterror(c,
1336 "Illegal method modifiers: 0x%X",
1342 if (m->name == utf_init) {
1343 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1344 ACC_NATIVE | ACC_ABSTRACT))
1345 panic("Instance initialization method has invalid flags set");
1351 m->basicblockcount = 0;
1352 m->basicblocks = NULL;
1353 m->basicblockindex = NULL;
1354 m->instructioncount = 0;
1355 m->instructions = NULL;
1358 m->exceptiontable = NULL;
1359 m->stubroutine = NULL;
1361 m->entrypoint = NULL;
1362 m->methodUsed = NOTUSED;
1365 m->subRedefsUsed = 0;
1369 if (!(m->flags & ACC_NATIVE)) {
1370 m->stubroutine = createcompilerstub(m);
1373 /*if (useinlining) {
1374 log_text("creating native stub:");
1377 functionptr f = native_findfunction(c->name, m->name, m->descriptor,
1378 (m->flags & ACC_STATIC) != 0);
1379 #ifdef STATIC_CLASSPATH
1383 m->stubroutine = createnativestub(f, m);
1387 if (!check_classbuffer_size(cb, 2))
1390 attrnum = suck_u2(cb);
1391 for (i = 0; i < attrnum; i++) {
1394 if (!check_classbuffer_size(cb, 2))
1397 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1400 if (aname == utf_code) {
1401 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1403 new_classformaterror(c,
1404 "Code attribute in native or abstract methods");
1411 new_classformaterror(c, "Multiple Code attributes");
1416 if (!check_classbuffer_size(cb, 4 + 2 + 2))
1420 m->maxstack = suck_u2(cb);
1421 m->maxlocals = suck_u2(cb);
1423 if (m->maxlocals < argcount) {
1425 new_classformaterror(c, "Arguments can't fit into locals");
1430 if (!check_classbuffer_size(cb, 4))
1433 m->jcodelength = suck_u4(cb);
1435 if (m->jcodelength == 0) {
1437 new_classformaterror(c, "Code of a method has length 0");
1442 if (m->jcodelength > 65535) {
1444 new_classformaterror(c,
1445 "Code of a method longer than 65535 bytes");
1450 if (!check_classbuffer_size(cb, m->jcodelength))
1453 m->jcode = MNEW(u1, m->jcodelength);
1454 suck_nbytes(m->jcode, cb, m->jcodelength);
1456 if (!check_classbuffer_size(cb, 2))
1459 m->exceptiontablelength = suck_u2(cb);
1460 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->exceptiontablelength))
1463 m->exceptiontable = MNEW(exceptiontable, m->exceptiontablelength);
1465 #if defined(STATISTICS)
1467 count_vmcode_len += m->jcodelength + 18;
1468 count_extable_len += 8 * m->exceptiontablelength;
1472 for (j = 0; j < m->exceptiontablelength; j++) {
1474 m->exceptiontable[j].startpc = suck_u2(cb);
1475 m->exceptiontable[j].endpc = suck_u2(cb);
1476 m->exceptiontable[j].handlerpc = suck_u2(cb);
1480 m->exceptiontable[j].catchtype = NULL;
1483 if (!(m->exceptiontable[j].catchtype =
1484 class_getconstant(c, idx, CONSTANT_Class)))
1489 if (!check_classbuffer_size(cb, 2))
1492 codeattrnum = suck_u2(cb);
1494 for (; codeattrnum > 0; codeattrnum--) {
1497 if (!check_classbuffer_size(cb, 2))
1500 if (!(caname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1503 if (caname == utf_linenumbertable) {
1506 if (!check_classbuffer_size(cb, 4 + 2))
1510 m->linenumbercount = suck_u2(cb);
1512 if (!check_classbuffer_size(cb,
1513 (2 + 2) * m->linenumbercount))
1516 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1518 for (lncid = 0; lncid < m->linenumbercount; lncid++) {
1519 m->linenumbers[lncid].start_pc = suck_u2(cb);
1520 m->linenumbers[lncid].line_number = suck_u2(cb);
1524 if (!skipattributes(cb, codeattrnum))
1530 if (!skipattributebody(cb))
1535 } else if (aname == utf_exceptions) {
1538 if (m->thrownexceptions) {
1540 new_classformaterror(c, "Multiple Exceptions attributes");
1544 if (!check_classbuffer_size(cb, 4 + 2))
1547 suck_u4(cb); /* length */
1548 m->thrownexceptionscount = suck_u2(cb);
1550 if (!check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1553 m->thrownexceptions = MNEW(classinfo*, m->thrownexceptionscount);
1555 for (j = 0; j < m->thrownexceptionscount; j++) {
1556 if (!((m->thrownexceptions)[j] =
1557 class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1562 if (!skipattributebody(cb))
1567 if (!m->jcode && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1568 *exceptionptr = new_classformaterror(c, "Missing Code attribute");
1573 /* everything was ok */
1574 /* utf_display(m->name);
1575 printf("\nexceptiontablelength:%ld\n",m->exceptiontablelength);*/
1581 /********************* Function: method_free ***********************************
1583 frees all memory that was allocated for this method
1585 *******************************************************************************/
1587 static void method_free(methodinfo *m)
1590 MFREE(m->jcode, u1, m->jcodelength);
1592 if (m->exceptiontable)
1593 MFREE(m->exceptiontable, exceptiontable, m->exceptiontablelength);
1596 CFREE(m->mcode, m->mcodelength);
1598 if (m->stubroutine) {
1599 if (m->flags & ACC_NATIVE) {
1600 removenativestub(m->stubroutine);
1603 removecompilerstub(m->stubroutine);
1609 /************** Function: method_display (debugging only) **************/
1611 void method_display(methodinfo *m)
1614 printflags(m->flags);
1616 utf_display(m->name);
1618 utf_display(m->descriptor);
1622 /************** Function: method_display_w_class (debugging only) **************/
1624 void method_display_w_class(methodinfo *m)
1626 printflags(m->class->flags);
1627 printf(" "); fflush(stdout);
1628 utf_display(m->class->name);
1629 printf(".");fflush(stdout);
1632 printflags(m->flags);
1633 printf(" "); fflush(stdout);
1634 utf_display(m->name);
1635 printf(" "); fflush(stdout);
1636 utf_display(m->descriptor);
1637 printf("\n"); fflush(stdout);
1640 /************** Function: method_display_flags_last (debugging only) **************/
1642 void method_display_flags_last(methodinfo *m)
1645 utf_display(m->name);
1647 utf_display(m->descriptor);
1649 printflags(m->flags);
1654 /******************** Function: method_canoverwrite ****************************
1656 Check if m and old are identical with respect to type and name. This means
1657 that old can be overwritten with m.
1659 *******************************************************************************/
1661 static bool method_canoverwrite(methodinfo *m, methodinfo *old)
1663 if (m->name != old->name) return false;
1664 if (m->descriptor != old->descriptor) return false;
1665 if (m->flags & ACC_STATIC) return false;
1670 /******************** function: class_loadcpool ********************************
1672 loads the constantpool of a class,
1673 the entries are transformed into a simpler format
1674 by resolving references
1675 (a detailed overview of the compact structures can be found in global.h)
1677 *******************************************************************************/
1679 static bool class_loadcpool(classbuffer *cb, classinfo *c)
1682 /* The following structures are used to save information which cannot be
1683 processed during the first pass. After the complete constantpool has
1684 been traversed the references can be resolved.
1685 (only in specific order) */
1687 /* CONSTANT_Class entries */
1688 typedef struct forward_class {
1689 struct forward_class *next;
1694 /* CONSTANT_String */
1695 typedef struct forward_string {
1696 struct forward_string *next;
1701 /* CONSTANT_NameAndType */
1702 typedef struct forward_nameandtype {
1703 struct forward_nameandtype *next;
1707 } forward_nameandtype;
1709 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
1710 typedef struct forward_fieldmethint {
1711 struct forward_fieldmethint *next;
1715 u2 nameandtype_index;
1716 } forward_fieldmethint;
1721 forward_class *forward_classes = NULL;
1722 forward_string *forward_strings = NULL;
1723 forward_nameandtype *forward_nameandtypes = NULL;
1724 forward_fieldmethint *forward_fieldmethints = NULL;
1727 forward_string *nfs;
1728 forward_nameandtype *nfn;
1729 forward_fieldmethint *nff;
1735 /* number of entries in the constant_pool table plus one */
1736 if (!check_classbuffer_size(cb, 2))
1739 cpcount = c->cpcount = suck_u2(cb);
1741 /* allocate memory */
1742 cptags = c->cptags = MNEW(u1, cpcount);
1743 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
1746 *exceptionptr = new_classformaterror(c, "Illegal constant pool size");
1750 #if defined(STATISTICS)
1752 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
1755 /* initialize constantpool */
1756 for (idx = 0; idx < cpcount; idx++) {
1757 cptags[idx] = CONSTANT_UNUSED;
1758 cpinfos[idx] = NULL;
1762 /******* first pass *******/
1763 /* entries which cannot be resolved now are written into
1764 temporary structures and traversed again later */
1767 while (idx < cpcount) {
1770 /* get constant type */
1771 if (!check_classbuffer_size(cb, 1))
1777 case CONSTANT_Class:
1778 nfc = NEW(forward_class);
1780 nfc->next = forward_classes;
1781 forward_classes = nfc;
1783 nfc->thisindex = idx;
1784 /* reference to CONSTANT_NameAndType */
1785 if (!check_classbuffer_size(cb, 2))
1788 nfc->name_index = suck_u2(cb);
1793 case CONSTANT_String:
1794 nfs = NEW(forward_string);
1796 nfs->next = forward_strings;
1797 forward_strings = nfs;
1799 nfs->thisindex = idx;
1801 /* reference to CONSTANT_Utf8_info with string characters */
1802 if (!check_classbuffer_size(cb, 2))
1805 nfs->string_index = suck_u2(cb);
1810 case CONSTANT_NameAndType:
1811 nfn = NEW(forward_nameandtype);
1813 nfn->next = forward_nameandtypes;
1814 forward_nameandtypes = nfn;
1816 nfn->thisindex = idx;
1818 if (!check_classbuffer_size(cb, 2 + 2))
1821 /* reference to CONSTANT_Utf8_info containing simple name */
1822 nfn->name_index = suck_u2(cb);
1824 /* reference to CONSTANT_Utf8_info containing field or method
1826 nfn->sig_index = suck_u2(cb);
1831 case CONSTANT_Fieldref:
1832 case CONSTANT_Methodref:
1833 case CONSTANT_InterfaceMethodref:
1834 nff = NEW(forward_fieldmethint);
1836 nff->next = forward_fieldmethints;
1837 forward_fieldmethints = nff;
1839 nff->thisindex = idx;
1843 if (!check_classbuffer_size(cb, 2 + 2))
1846 /* class or interface type that contains the declaration of the
1848 nff->class_index = suck_u2(cb);
1850 /* name and descriptor of the field or method */
1851 nff->nameandtype_index = suck_u2(cb);
1856 case CONSTANT_Integer: {
1857 constant_integer *ci = NEW(constant_integer);
1859 #if defined(STATISTICS)
1861 count_const_pool_len += sizeof(constant_integer);
1864 if (!check_classbuffer_size(cb, 4))
1867 ci->value = suck_s4(cb);
1868 cptags[idx] = CONSTANT_Integer;
1875 case CONSTANT_Float: {
1876 constant_float *cf = NEW(constant_float);
1878 #if defined(STATISTICS)
1880 count_const_pool_len += sizeof(constant_float);
1883 if (!check_classbuffer_size(cb, 4))
1886 cf->value = suck_float(cb);
1887 cptags[idx] = CONSTANT_Float;
1894 case CONSTANT_Long: {
1895 constant_long *cl = NEW(constant_long);
1897 #if defined(STATISTICS)
1899 count_const_pool_len += sizeof(constant_long);
1902 if (!check_classbuffer_size(cb, 8))
1905 cl->value = suck_s8(cb);
1906 cptags[idx] = CONSTANT_Long;
1909 if (idx > cpcount) {
1911 new_classformaterror(c, "Invalid constant pool entry");
1917 case CONSTANT_Double: {
1918 constant_double *cd = NEW(constant_double);
1920 #if defined(STATISTICS)
1922 count_const_pool_len += sizeof(constant_double);
1925 if (!check_classbuffer_size(cb, 8))
1928 cd->value = suck_double(cb);
1929 cptags[idx] = CONSTANT_Double;
1932 if (idx > cpcount) {
1934 new_classformaterror(c, "Invalid constant pool entry");
1940 case CONSTANT_Utf8: {
1943 /* number of bytes in the bytes array (not string-length) */
1944 if (!check_classbuffer_size(cb, 2))
1947 length = suck_u2(cb);
1948 cptags[idx] = CONSTANT_Utf8;
1950 /* validate the string */
1951 if (!check_classbuffer_size(cb, length))
1955 !is_valid_utf((char *) (cb->pos + 1),
1956 (char *) (cb->pos + 1 + length))) {
1957 dolog("Invalid UTF-8 string (constant pool index %d)",idx);
1958 panic("Invalid UTF-8 string");
1960 /* insert utf-string into the utf-symboltable */
1961 cpinfos[idx] = utf_new_intern((char *) (cb->pos + 1), length);
1963 /* skip bytes of the string (buffer size check above) */
1964 skip_nbytes(cb, length);
1971 new_classformaterror(c, "Illegal constant pool type");
1977 /* resolve entries in temporary structures */
1979 while (forward_classes) {
1981 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
1983 if (opt_verify && !is_valid_name_utf(name))
1984 panic("Class reference with invalid name");
1986 cptags[forward_classes->thisindex] = CONSTANT_Class;
1987 /* retrieve class from class-table */
1990 tc = class_new_intern(name);
1992 if (!class_load(tc))
1995 /* link the class later, because we cannot link the class currently
1997 list_addfirst(&unlinkedclasses, tc);
1999 cpinfos[forward_classes->thisindex] = tc;
2002 cpinfos[forward_classes->thisindex] = class_new(name);
2005 nfc = forward_classes;
2006 forward_classes = forward_classes->next;
2007 FREE(nfc, forward_class);
2010 while (forward_strings) {
2012 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
2014 /* resolve utf-string */
2015 cptags[forward_strings->thisindex] = CONSTANT_String;
2016 cpinfos[forward_strings->thisindex] = text;
2018 nfs = forward_strings;
2019 forward_strings = forward_strings->next;
2020 FREE(nfs, forward_string);
2023 while (forward_nameandtypes) {
2024 constant_nameandtype *cn = NEW(constant_nameandtype);
2026 #if defined(STATISTICS)
2028 count_const_pool_len += sizeof(constant_nameandtype);
2031 /* resolve simple name and descriptor */
2032 cn->name = class_getconstant(c,
2033 forward_nameandtypes->name_index,
2036 cn->descriptor = class_getconstant(c,
2037 forward_nameandtypes->sig_index,
2042 if (!is_valid_name_utf(cn->name))
2043 panic("NameAndType with invalid name");
2044 /* disallow referencing <clinit> among others */
2045 if (cn->name->text[0] == '<' && cn->name != utf_init)
2046 panic("NameAndType with invalid special name");
2049 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
2050 cpinfos[forward_nameandtypes->thisindex] = cn;
2052 nfn = forward_nameandtypes;
2053 forward_nameandtypes = forward_nameandtypes->next;
2054 FREE(nfn, forward_nameandtype);
2057 while (forward_fieldmethints) {
2058 constant_nameandtype *nat;
2059 constant_FMIref *fmi = NEW(constant_FMIref);
2061 #if defined(STATISTICS)
2063 count_const_pool_len += sizeof(constant_FMIref);
2065 /* resolve simple name and descriptor */
2066 nat = class_getconstant(c,
2067 forward_fieldmethints->nameandtype_index,
2068 CONSTANT_NameAndType);
2070 fmi->class = class_getconstant(c,
2071 forward_fieldmethints->class_index,
2073 fmi->name = nat->name;
2074 fmi->descriptor = nat->descriptor;
2076 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
2077 cpinfos[forward_fieldmethints->thisindex] = fmi;
2079 switch (forward_fieldmethints->tag) {
2080 case CONSTANT_Fieldref: /* check validity of descriptor */
2081 checkfielddescriptor(fmi->descriptor->text,
2082 utf_end(fmi->descriptor));
2084 case CONSTANT_InterfaceMethodref:
2085 case CONSTANT_Methodref: /* check validity of descriptor */
2086 checkmethoddescriptor(c, fmi->descriptor);
2090 nff = forward_fieldmethints;
2091 forward_fieldmethints = forward_fieldmethints->next;
2092 FREE(nff, forward_fieldmethint);
2095 /* everything was ok */
2101 /********************** Function: class_load ***********************************
2103 Loads everything interesting about a class from the class file. The
2104 'classinfo' structure must have been allocated previously.
2106 The super class and the interfaces implemented by this class need not be
2107 loaded. The link is set later by the function 'class_link'.
2109 The loaded class is removed from the list 'unloadedclasses' and added to
2110 the list 'unlinkedclasses'.
2112 *******************************************************************************/
2114 classinfo *class_load_intern(classbuffer *cb);
2116 classinfo *class_load(classinfo *c)
2121 /* enter a monitor on the class */
2123 builtin_monitorenter((java_objectheader *) c);
2125 /* maybe the class is already loaded */
2127 builtin_monitorexit((java_objectheader *) c);
2134 if (getcompilingtime)
2135 compilingtime_stop();
2138 loadingtime_start();
2140 /* load classdata, throw exception on error */
2142 if ((cb = suck_start(c)) == NULL) {
2143 /* this means, the classpath was not set properly */
2144 if (c->name == utf_java_lang_Object)
2145 throw_cacao_exception_exit(string_java_lang_NoClassDefFoundError,
2146 "java/lang/Object");
2149 new_exception_utfmessage(string_java_lang_NoClassDefFoundError,
2152 builtin_monitorexit((java_objectheader *) c);
2157 /* call the internal function */
2158 r = class_load_intern(cb);
2160 /* if return value is NULL, we had a problem and the class is not loaded */
2164 /* now free the allocated memory, otherwise we could ran into a DOS */
2176 if (getcompilingtime)
2177 compilingtime_start();
2179 /* leave the monitor */
2181 builtin_monitorexit((java_objectheader *) c);
2187 classinfo *class_load_intern(classbuffer *cb)
2193 char msg[MAXLOGTEXT]; /* maybe we get an exception */
2195 /* get the classbuffer's class */
2198 /* maybe the class is already loaded */
2202 #if defined(STATISTICS)
2204 count_class_loads++;
2207 /* output for debugging purposes */
2209 log_message_class("Loading class: ", c);
2211 /* class is somewhat loaded */
2214 if (!check_classbuffer_size(cb, 4 + 2 + 2))
2217 /* check signature */
2218 if (suck_u4(cb) != MAGIC) {
2219 *exceptionptr = new_classformaterror(c, "Bad magic number");
2228 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
2230 new_unsupportedclassversionerror(c,
2231 "Unsupported major.minor version %d.%d",
2237 /* load the constant pool */
2238 if (!class_loadcpool(cb, c))
2242 c->erroneous_state = 0;
2243 c->initializing_thread = 0;
2245 c->classUsed = NOTUSED; /* not used initially CO-RT */
2249 if (!check_classbuffer_size(cb, 2))
2252 c->flags = suck_u2(cb);
2253 /*if (!(c->flags & ACC_PUBLIC)) { log_text("CLASS NOT PUBLIC"); } JOWENN*/
2255 /* check ACC flags consistency */
2256 if (c->flags & ACC_INTERFACE) {
2257 if (!(c->flags & ACC_ABSTRACT)) {
2258 /* We work around this because interfaces in JDK 1.1 are
2259 * not declared abstract. */
2261 c->flags |= ACC_ABSTRACT;
2262 /* panic("Interface class not declared abstract"); */
2265 if (c->flags & ACC_FINAL) {
2267 new_classformaterror(c,
2268 "Illegal class modifiers: 0x%X", c->flags);
2273 if (c->flags & ACC_SUPER) {
2274 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
2278 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
2280 new_classformaterror(c, "Illegal class modifiers: 0x%X", c->flags);
2285 if (!check_classbuffer_size(cb, 2 + 2))
2290 if (!(tc = class_getconstant(c, i, CONSTANT_Class)))
2294 utf_sprint(msg, c->name);
2295 sprintf(msg + strlen(msg), " (wrong name: ");
2296 utf_sprint(msg + strlen(msg), tc->name);
2297 sprintf(msg + strlen(msg), ")");
2300 new_exception_message(string_java_lang_NoClassDefFoundError, msg);
2305 /* retrieve superclass */
2306 if ((i = suck_u2(cb))) {
2307 if (!(c->super = class_getconstant(c, i, CONSTANT_Class)))
2310 /* java.lang.Object may not have a super class. */
2311 if (c->name == utf_java_lang_Object) {
2313 new_exception_message(string_java_lang_ClassFormatError,
2314 "java.lang.Object with superclass");
2319 /* Interfaces must have java.lang.Object as super class. */
2320 if ((c->flags & ACC_INTERFACE) &&
2321 c->super->name != utf_java_lang_Object) {
2323 new_exception_message(string_java_lang_ClassFormatError,
2324 "Interfaces must have java.lang.Object as superclass");
2332 /* This is only allowed for java.lang.Object. */
2333 if (c->name != utf_java_lang_Object) {
2334 *exceptionptr = new_classformaterror(c, "Bad superclass index");
2340 /* retrieve interfaces */
2341 if (!check_classbuffer_size(cb, 2))
2344 c->interfacescount = suck_u2(cb);
2346 if (!check_classbuffer_size(cb, 2 * c->interfacescount))
2349 c->interfaces = MNEW(classinfo*, c->interfacescount);
2350 for (i = 0; i < c->interfacescount; i++) {
2351 if (!(c->interfaces[i] = class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2356 if (!check_classbuffer_size(cb, 2))
2359 c->fieldscount = suck_u2(cb);
2360 c->fields = GCNEW(fieldinfo, c->fieldscount);
2361 /* c->fields = MNEW(fieldinfo, c->fieldscount); */
2362 for (i = 0; i < c->fieldscount; i++) {
2363 if (!field_load(cb, c, &(c->fields[i])))
2368 if (!check_classbuffer_size(cb, 2))
2371 c->methodscount = suck_u2(cb);
2372 c->methods = GCNEW(methodinfo, c->methodscount);
2373 /* c->methods = MNEW(methodinfo, c->methodscount); */
2374 for (i = 0; i < c->methodscount; i++) {
2375 if (!method_load(cb, c, &(c->methods[i])))
2379 /* Check if all fields and methods can be uniquely
2380 * identified by (name,descriptor). */
2382 /* We use a hash table here to avoid making the
2383 * average case quadratic in # of methods, fields.
2385 static int shift = 0;
2387 u2 *next; /* for chaining colliding hash entries */
2393 /* Allocate hashtable */
2394 len = c->methodscount;
2395 if (len < c->fieldscount) len = c->fieldscount;
2397 hashtab = MNEW(u2,(hashlen + len));
2398 next = hashtab + hashlen;
2400 /* Determine bitshift (to get good hash values) */
2410 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2412 for (i = 0; i < c->fieldscount; ++i) {
2413 fieldinfo *fi = c->fields + i;
2415 /* It's ok if we lose bits here */
2416 index = ((((size_t) fi->name) +
2417 ((size_t) fi->descriptor)) >> shift) % hashlen;
2419 if ((old = hashtab[index])) {
2423 if (c->fields[old].name == fi->name &&
2424 c->fields[old].descriptor == fi->descriptor) {
2426 new_classformaterror(c,
2427 "Repetitive field name/signature");
2431 } while ((old = next[old]));
2433 hashtab[index] = i + 1;
2437 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2439 for (i = 0; i < c->methodscount; ++i) {
2440 methodinfo *mi = c->methods + i;
2442 /* It's ok if we lose bits here */
2443 index = ((((size_t) mi->name) +
2444 ((size_t) mi->descriptor)) >> shift) % hashlen;
2448 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2449 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2453 if ((old = hashtab[index])) {
2457 if (c->methods[old].name == mi->name &&
2458 c->methods[old].descriptor == mi->descriptor) {
2460 new_classformaterror(c,
2461 "Repetitive method name/signature");
2465 } while ((old = next[old]));
2467 hashtab[index] = i + 1;
2470 MFREE(hashtab, u2, (hashlen + len));
2473 #if defined(STATISTICS)
2475 count_class_infos += sizeof(classinfo*) * c->interfacescount;
2476 count_class_infos += sizeof(fieldinfo) * c->fieldscount;
2477 count_class_infos += sizeof(methodinfo) * c->methodscount;
2481 /* load attribute structures */
2482 if (!check_classbuffer_size(cb, 2))
2485 if (!attribute_load(cb, c, suck_u2(cb)))
2489 /* Pre java 1.5 version don't check this. This implementation is like
2490 java 1.5 do it: for class file version 45.3 we don't check it, older
2491 versions are checked.
2493 if ((ma == 45 && mi > 3) || ma > 45) {
2494 /* check if all data has been read */
2495 s4 classdata_left = ((cb->data + cb->size) - cb->pos - 1);
2497 if (classdata_left > 0) {
2499 new_classformaterror(c, "Extra bytes at the end of class file");
2506 log_message_class("Loading done class: ", c);
2513 /************** internal Function: class_highestinterface **********************
2515 Used by the function class_link to determine the amount of memory needed
2516 for the interface table.
2518 *******************************************************************************/
2520 static s4 class_highestinterface(classinfo *c)
2525 /* check for ACC_INTERFACE bit already done in class_link_intern */
2528 for (i = 0; i < c->interfacescount; i++) {
2529 s4 h2 = class_highestinterface(c->interfaces[i]);
2537 /* class_addinterface **********************************************************
2539 Is needed by class_link for adding a VTBL to a class. All interfaces
2540 implemented by ic are added as well.
2542 *******************************************************************************/
2544 static void class_addinterface(classinfo *c, classinfo *ic)
2548 vftbl_t *v = c->vftbl;
2550 if (i >= v->interfacetablelength)
2551 panic ("Inernal error: interfacetable overflow");
2553 if (v->interfacetable[-i])
2556 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
2557 v->interfacevftbllength[i] = 1;
2558 v->interfacetable[-i] = MNEW(methodptr, 1);
2559 v->interfacetable[-i][0] = NULL;
2562 v->interfacevftbllength[i] = ic->methodscount;
2563 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
2565 #if defined(STATISTICS)
2567 count_vftbl_len += sizeof(methodptr) *
2568 (ic->methodscount + (ic->methodscount == 0));
2571 for (j = 0; j < ic->methodscount; j++) {
2574 for (m = 0; m < sc->methodscount; m++) {
2575 methodinfo *mi = &(sc->methods[m]);
2576 if (method_canoverwrite(mi, &(ic->methods[j]))) {
2577 v->interfacetable[-i][j] = v->table[mi->vftblindex];
2588 for (j = 0; j < ic->interfacescount; j++)
2589 class_addinterface(c, ic->interfaces[j]);
2593 /******************* Function: class_new_array *********************************
2595 This function is called by class_new to setup an array class.
2597 *******************************************************************************/
2599 void class_new_array(classinfo *c)
2601 classinfo *comp = NULL;
2605 /* Check array class name */
2606 namelen = c->name->blength;
2607 if (namelen < 2 || c->name->text[0] != '[')
2608 panic("Invalid array class name");
2610 /* Check the component type */
2611 switch (c->name->text[1]) {
2613 /* c is an array of arrays. We have to create the component class. */
2615 comp = class_new_intern(utf_new_intern(c->name->text + 1,
2618 list_addfirst(&unlinkedclasses, comp);
2621 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2626 /* c is an array of objects. */
2627 if (namelen < 4 || c->name->text[namelen - 1] != ';')
2628 panic("Invalid array class name");
2631 comp = class_new_intern(utf_new_intern(c->name->text + 2,
2634 list_addfirst(&unlinkedclasses, comp);
2637 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2642 /* Setup the array class */
2643 c->super = class_java_lang_Object;
2644 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2646 c->interfacescount = 2;
2647 c->interfaces = MNEW(classinfo*, 2);
2652 tc = class_new_intern(utf_new_char("java/lang/Cloneable"));
2654 list_addfirst(&unlinkedclasses, tc);
2655 c->interfaces[0] = tc;
2657 tc = class_new_intern(utf_new_char("java/io/Serializable"));
2659 list_addfirst(&unlinkedclasses, tc);
2660 c->interfaces[1] = tc;
2663 c->interfaces[0] = class_new(utf_new_char("java/lang/Cloneable"));
2664 c->interfaces[1] = class_new(utf_new_char("java/io/Serializable"));
2667 c->methodscount = 1;
2668 c->methods = MNEW(methodinfo, c->methodscount);
2671 memset(clone, 0, sizeof(methodinfo));
2672 clone->flags = ACC_PUBLIC;
2673 clone->name = utf_new_char("clone");
2674 clone->descriptor = utf_new_char("()Ljava/lang/Object;");
2676 clone->stubroutine = createnativestub((functionptr) &builtin_clone_array, clone);
2677 clone->monoPoly = MONO;
2679 /* XXX: field: length? */
2681 /* array classes are not loaded from class files */
2686 /****************** Function: class_link_array *********************************
2688 This function is called by class_link to create the
2689 arraydescriptor for an array class.
2691 This function returns NULL if the array cannot be linked because
2692 the component type has not been linked yet.
2694 *******************************************************************************/
2696 static arraydescriptor *class_link_array(classinfo *c)
2698 classinfo *comp = NULL;
2699 s4 namelen = c->name->blength;
2700 arraydescriptor *desc;
2703 /* Check the component type */
2704 switch (c->name->text[1]) {
2706 /* c is an array of arrays. */
2707 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2709 panic("Could not find component array class.");
2713 /* c is an array of objects. */
2714 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2716 panic("Could not find component class.");
2720 /* If the component type has not been linked, link it now */
2721 if (comp && !comp->linked) {
2723 if (!class_load(comp))
2726 if (!class_link(comp))
2730 /* Allocate the arraydescriptor */
2731 desc = NEW(arraydescriptor);
2734 /* c is an array of references */
2735 desc->arraytype = ARRAYTYPE_OBJECT;
2736 desc->componentsize = sizeof(void*);
2737 desc->dataoffset = OFFSET(java_objectarray, data);
2739 compvftbl = comp->vftbl;
2741 panic("Component class has no vftbl");
2742 desc->componentvftbl = compvftbl;
2744 if (compvftbl->arraydesc) {
2745 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
2746 if (compvftbl->arraydesc->dimension >= 255)
2747 panic("Creating array of dimension >255");
2748 desc->dimension = compvftbl->arraydesc->dimension + 1;
2749 desc->elementtype = compvftbl->arraydesc->elementtype;
2752 desc->elementvftbl = compvftbl;
2753 desc->dimension = 1;
2754 desc->elementtype = ARRAYTYPE_OBJECT;
2758 /* c is an array of a primitive type */
2759 switch (c->name->text[1]) {
2761 desc->arraytype = ARRAYTYPE_BOOLEAN;
2762 desc->dataoffset = OFFSET(java_booleanarray,data);
2763 desc->componentsize = sizeof(u1);
2767 desc->arraytype = ARRAYTYPE_BYTE;
2768 desc->dataoffset = OFFSET(java_bytearray,data);
2769 desc->componentsize = sizeof(u1);
2773 desc->arraytype = ARRAYTYPE_CHAR;
2774 desc->dataoffset = OFFSET(java_chararray,data);
2775 desc->componentsize = sizeof(u2);
2779 desc->arraytype = ARRAYTYPE_DOUBLE;
2780 desc->dataoffset = OFFSET(java_doublearray,data);
2781 desc->componentsize = sizeof(double);
2785 desc->arraytype = ARRAYTYPE_FLOAT;
2786 desc->dataoffset = OFFSET(java_floatarray,data);
2787 desc->componentsize = sizeof(float);
2791 desc->arraytype = ARRAYTYPE_INT;
2792 desc->dataoffset = OFFSET(java_intarray,data);
2793 desc->componentsize = sizeof(s4);
2797 desc->arraytype = ARRAYTYPE_LONG;
2798 desc->dataoffset = OFFSET(java_longarray,data);
2799 desc->componentsize = sizeof(s8);
2803 desc->arraytype = ARRAYTYPE_SHORT;
2804 desc->dataoffset = OFFSET(java_shortarray,data);
2805 desc->componentsize = sizeof(s2);
2809 panic("Invalid array class name");
2812 desc->componentvftbl = NULL;
2813 desc->elementvftbl = NULL;
2814 desc->dimension = 1;
2815 desc->elementtype = desc->arraytype;
2822 /********************** Function: class_link ***********************************
2824 Tries to link a class. The function calculates the length in bytes that
2825 an instance of this class requires as well as the VTBL for methods and
2828 *******************************************************************************/
2830 static classinfo *class_link_intern(classinfo *c);
2832 classinfo *class_link(classinfo *c)
2836 /* enter a monitor on the class */
2838 builtin_monitorenter((java_objectheader *) c);
2840 /* maybe the class is already linked */
2842 builtin_monitorexit((java_objectheader *) c);
2849 if (getcompilingtime)
2850 compilingtime_stop();
2853 loadingtime_start();
2855 /* call the internal function */
2856 r = class_link_intern(c);
2858 /* if return value is NULL, we had a problem and the class is not linked */
2867 if (getcompilingtime)
2868 compilingtime_start();
2870 /* leave the monitor */
2872 builtin_monitorexit((java_objectheader *) c);
2878 static classinfo *class_link_intern(classinfo *c)
2880 s4 supervftbllength; /* vftbllegnth of super class */
2881 s4 vftbllength; /* vftbllength of current class */
2882 s4 interfacetablelength; /* interface table length */
2883 classinfo *super; /* super class */
2884 classinfo *tc; /* temporary class variable */
2885 vftbl_t *v; /* vftbl of current class */
2886 s4 i; /* interface/method/field counter */
2887 arraydescriptor *arraydesc; /* descriptor for array classes */
2889 /* maybe the class is already linked */
2893 /* maybe the class is not loaded */
2899 log_message_class("Linking class: ", c);
2901 /* ok, this class is somewhat linked */
2906 /* check interfaces */
2908 for (i = 0; i < c->interfacescount; i++) {
2909 tc = c->interfaces[i];
2911 /* detect circularity */
2914 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2920 if (!class_load(tc))
2923 if (!(tc->flags & ACC_INTERFACE)) {
2925 new_exception_message(string_java_lang_IncompatibleClassChangeError,
2926 "Implementing class");
2931 if (!class_link(tc))
2935 /* check super class */
2939 if (super == NULL) { /* class java.lang.Object */
2941 c->classUsed = USED; /* Object class is always used CO-RT*/
2943 c->instancesize = sizeof(java_objectheader);
2945 vftbllength = supervftbllength = 0;
2947 c->finalizer = NULL;
2950 /* detect circularity */
2953 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2959 if (!class_load(super))
2962 if (super->flags & ACC_INTERFACE) {
2963 /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
2964 panic("Interface specified as super class");
2967 /* Don't allow extending final classes */
2968 if (super->flags & ACC_FINAL) {
2970 new_exception_message(string_java_lang_VerifyError,
2971 "Cannot inherit from final class");
2976 if (!class_link(super))
2979 /* handle array classes */
2980 if (c->name->text[0] == '[')
2981 if (!(arraydesc = class_link_array(c)))
2984 if (c->flags & ACC_INTERFACE)
2985 c->index = interfaceindex++;
2987 c->index = super->index + 1;
2989 c->instancesize = super->instancesize;
2991 vftbllength = supervftbllength = super->vftbl->vftbllength;
2993 c->finalizer = super->finalizer;
2996 /* compute vftbl length */
2998 for (i = 0; i < c->methodscount; i++) {
2999 methodinfo *m = &(c->methods[i]);
3001 if (!(m->flags & ACC_STATIC)) { /* is instance method */
3006 for (j = 0; j < tc->methodscount; j++) {
3007 if (method_canoverwrite(m, &(tc->methods[j]))) {
3008 if (tc->methods[j].flags & ACC_PRIVATE)
3009 goto notfoundvftblindex;
3011 if (tc->methods[j].flags & ACC_FINAL) {
3012 /* class a overrides final method . */
3014 new_exception(string_java_lang_VerifyError);
3017 m->vftblindex = tc->methods[j].vftblindex;
3018 goto foundvftblindex;
3024 m->vftblindex = (vftbllength++);
3030 #if defined(STATISTICS)
3033 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
3036 /* compute interfacetable length */
3038 interfacetablelength = 0;
3041 for (i = 0; i < tc->interfacescount; i++) {
3042 s4 h = class_highestinterface(tc->interfaces[i]) + 1;
3043 if (h > interfacetablelength)
3044 interfacetablelength = h;
3049 /* allocate virtual function table */
3051 v = (vftbl_t*) mem_alloc(sizeof(vftbl_t) + sizeof(methodptr) *
3052 (vftbllength - 1) + sizeof(methodptr*) *
3053 (interfacetablelength - (interfacetablelength > 0)));
3054 v = (vftbl_t*) (((methodptr*) v) + (interfacetablelength - 1) *
3055 (interfacetablelength > 1));
3056 c->header.vftbl = c->vftbl = v;
3058 v->vftbllength = vftbllength;
3059 v->interfacetablelength = interfacetablelength;
3060 v->arraydesc = arraydesc;
3062 /* store interface index in vftbl */
3063 if (c->flags & ACC_INTERFACE)
3064 v->baseval = -(c->index);
3066 /* copy virtual function table of super class */
3068 for (i = 0; i < supervftbllength; i++)
3069 v->table[i] = super->vftbl->table[i];
3071 /* add method stubs into virtual function table */
3073 for (i = 0; i < c->methodscount; i++) {
3074 methodinfo *m = &(c->methods[i]);
3075 if (!(m->flags & ACC_STATIC)) {
3076 v->table[m->vftblindex] = m->stubroutine;
3080 /* compute instance size and offset of each field */
3082 for (i = 0; i < c->fieldscount; i++) {
3084 fieldinfo *f = &(c->fields[i]);
3086 if (!(f->flags & ACC_STATIC)) {
3087 dsize = desc_typesize(f->descriptor);
3088 c->instancesize = ALIGN(c->instancesize, dsize);
3089 f->offset = c->instancesize;
3090 c->instancesize += dsize;
3094 /* initialize interfacetable and interfacevftbllength */
3096 v->interfacevftbllength = MNEW(s4, interfacetablelength);
3098 #if defined(STATISTICS)
3100 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
3103 for (i = 0; i < interfacetablelength; i++) {
3104 v->interfacevftbllength[i] = 0;
3105 v->interfacetable[-i] = NULL;
3108 /* add interfaces */
3110 for (tc = c; tc != NULL; tc = tc->super) {
3111 for (i = 0; i < tc->interfacescount; i++) {
3112 class_addinterface(c, tc->interfaces[i]);
3116 /* add finalizer method (not for java.lang.Object) */
3121 fi = class_findmethod(c, utf_finalize, utf_fidesc);
3124 if (!(fi->flags & ACC_STATIC)) {
3132 loader_compute_subclasses(c);
3135 log_message_class("Linking done class: ", c);
3137 /* just return c to show that we didn't had a problem */
3143 /******************* Function: class_freepool **********************************
3145 Frees all resources used by this classes Constant Pool.
3147 *******************************************************************************/
3149 static void class_freecpool(classinfo *c)
3155 if (c->cptags && c->cpinfos) {
3156 for (idx = 0; idx < c->cpcount; idx++) {
3157 tag = c->cptags[idx];
3158 info = c->cpinfos[idx];
3162 case CONSTANT_Fieldref:
3163 case CONSTANT_Methodref:
3164 case CONSTANT_InterfaceMethodref:
3165 FREE(info, constant_FMIref);
3167 case CONSTANT_Integer:
3168 FREE(info, constant_integer);
3170 case CONSTANT_Float:
3171 FREE(info, constant_float);
3174 FREE(info, constant_long);
3176 case CONSTANT_Double:
3177 FREE(info, constant_double);
3179 case CONSTANT_NameAndType:
3180 FREE(info, constant_nameandtype);
3188 MFREE(c->cptags, u1, c->cpcount);
3191 MFREE(c->cpinfos, voidptr, c->cpcount);
3195 /*********************** Function: class_free **********************************
3197 Frees all resources used by the class.
3199 *******************************************************************************/
3201 void class_free(classinfo *c)
3209 MFREE(c->interfaces, classinfo*, c->interfacescount);
3212 for (i = 0; i < c->fieldscount; i++)
3213 field_free(&(c->fields[i]));
3214 /* MFREE(c->fields, fieldinfo, c->fieldscount); */
3218 for (i = 0; i < c->methodscount; i++)
3219 method_free(&(c->methods[i]));
3220 /* MFREE(c->methods, methodinfo, c->methodscount); */
3223 if ((v = c->vftbl) != NULL) {
3225 mem_free(v->arraydesc,sizeof(arraydescriptor));
3227 for (i = 0; i < v->interfacetablelength; i++) {
3228 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
3230 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
3232 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
3233 sizeof(methodptr*) * (v->interfacetablelength -
3234 (v->interfacetablelength > 0));
3235 v = (vftbl_t*) (((methodptr*) v) - (v->interfacetablelength - 1) *
3236 (v->interfacetablelength > 1));
3241 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
3243 /* if (c->classvftbl)
3244 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
3250 /************************* Function: class_findfield ***************************
3252 Searches a 'classinfo' structure for a field having the given name and
3255 *******************************************************************************/
3257 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
3261 for (i = 0; i < c->fieldscount; i++) {
3262 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
3263 return &(c->fields[i]);
3266 panic("Can not find field given in CONSTANT_Fieldref");
3268 /* keep compiler happy */
3273 /****************** Function: class_resolvefield_int ***************************
3275 This is an internally used helper function. Do not use this directly.
3277 Tries to resolve a field having the given name and type.
3278 If the field cannot be resolved, NULL is returned.
3280 *******************************************************************************/
3282 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
3287 /* search for field in class c */
3288 for (i = 0; i < c->fieldscount; i++) {
3289 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
3290 return &(c->fields[i]);
3294 /* try superinterfaces recursively */
3295 for (i = 0; i < c->interfacescount; ++i) {
3296 fi = class_resolvefield_int(c->interfaces[i], name, desc);
3301 /* try superclass */
3303 return class_resolvefield_int(c->super, name, desc);
3310 /********************* Function: class_resolvefield ***************************
3312 Resolves a reference from REFERER to a field with NAME and DESC in class C.
3314 If the field cannot be resolved the return value is NULL. If EXCEPT is
3315 true *exceptionptr is set, too.
3317 *******************************************************************************/
3319 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
3320 classinfo *referer, bool except)
3324 /* XXX resolve class c */
3325 /* XXX check access from REFERER to C */
3327 fi = class_resolvefield_int(c, name, desc);
3332 new_exception_utfmessage(string_java_lang_NoSuchFieldError,
3338 /* XXX check access rights */
3344 /************************* Function: class_findmethod **************************
3346 Searches a 'classinfo' structure for a method having the given name and
3347 type and returns the index in the class info structure.
3348 If type is NULL, it is ignored.
3350 *******************************************************************************/
3352 s4 class_findmethodIndex(classinfo *c, utf *name, utf *desc)
3356 for (i = 0; i < c->methodscount; i++) {
3358 /* utf_display_classname(c->name);printf("."); */
3359 /* utf_display(c->methods[i].name);printf("."); */
3360 /* utf_display(c->methods[i].descriptor); */
3363 if ((c->methods[i].name == name) && ((desc == NULL) ||
3364 (c->methods[i].descriptor == desc))) {
3373 /************************* Function: class_findmethod **************************
3375 Searches a 'classinfo' structure for a method having the given name and
3377 If type is NULL, it is ignored.
3379 *******************************************************************************/
3381 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
3383 s4 idx = class_findmethodIndex(c, name, desc);
3388 return &(c->methods[idx]);
3392 /*********************** Function: class_fetchmethod **************************
3394 like class_findmethod, but aborts with an error if the method is not found
3396 *******************************************************************************/
3398 methodinfo *class_fetchmethod(classinfo *c, utf *name, utf *desc)
3402 mi = class_findmethod(c, name, desc);
3405 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3406 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3407 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3408 panic("Method not found");
3415 /*********************** Function: class_findmethod_w**************************
3417 like class_findmethod, but logs a warning if the method is not found
3419 *******************************************************************************/
3421 methodinfo *class_findmethod_w(classinfo *c, utf *name, utf *desc, char *from)
3424 mi = class_findmethod(c, name, desc);
3427 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3428 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3429 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3431 if ( c->flags & ACC_PUBLIC ) log_plain(" PUBLIC ");
3432 if ( c->flags & ACC_PRIVATE ) log_plain(" PRIVATE ");
3433 if ( c->flags & ACC_PROTECTED ) log_plain(" PROTECTED ");
3434 if ( c->flags & ACC_STATIC ) log_plain(" STATIC ");
3435 if ( c->flags & ACC_FINAL ) log_plain(" FINAL ");
3436 if ( c->flags & ACC_SYNCHRONIZED ) log_plain(" SYNCHRONIZED ");
3437 if ( c->flags & ACC_VOLATILE ) log_plain(" VOLATILE ");
3438 if ( c->flags & ACC_TRANSIENT ) log_plain(" TRANSIENT ");
3439 if ( c->flags & ACC_NATIVE ) log_plain(" NATIVE ");
3440 if ( c->flags & ACC_INTERFACE ) log_plain(" INTERFACE ");
3441 if ( c->flags & ACC_ABSTRACT ) log_plain(" ABSTRACT ");
3444 log_plain(" : WARNING: Method not found");log_nl( );
3451 /************************* Function: class_findmethod_approx ******************
3453 like class_findmethod but ignores the return value when comparing the
3456 *******************************************************************************/
3458 methodinfo *class_findmethod_approx(classinfo *c, utf *name, utf *desc)
3462 for (i = 0; i < c->methodscount; i++) {
3463 if (c->methods[i].name == name) {
3464 utf *meth_descr = c->methods[i].descriptor;
3468 return &(c->methods[i]);
3470 if (desc->blength <= meth_descr->blength) {
3471 /* current position in utf text */
3472 char *desc_utf_ptr = desc->text;
3473 char *meth_utf_ptr = meth_descr->text;
3474 /* points behind utf strings */
3475 char *desc_end = utf_end(desc);
3476 char *meth_end = utf_end(meth_descr);
3479 /* compare argument types */
3480 while (desc_utf_ptr < desc_end && meth_utf_ptr < meth_end) {
3482 if ((ch = *desc_utf_ptr++) != (*meth_utf_ptr++))
3483 break; /* no match */
3486 return &(c->methods[i]); /* all parameter types equal */
3496 /***************** Function: class_resolvemethod_approx ***********************
3498 Searches a class and every super class for a method (without paying
3499 attention to the return value)
3501 *******************************************************************************/
3503 methodinfo *class_resolvemethod_approx(classinfo *c, utf *name, utf *desc)
3506 /* search for method (ignore returntype) */
3507 methodinfo *m = class_findmethod_approx(c, name, desc);
3510 /* search superclass */
3518 /************************* Function: class_resolvemethod ***********************
3520 Searches a class and every super class for a method.
3522 *******************************************************************************/
3524 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
3526 /*log_text("Trying to resolve a method");
3527 utf_display(c->name);
3529 utf_display(desc);*/
3532 /*log_text("Looking in:");
3533 utf_display(c->name);*/
3534 methodinfo *m = class_findmethod(c, name, desc);
3536 /* search superclass */
3539 /*log_text("method not found:");*/
3545 /****************** Function: class_resolveinterfacemethod_int ****************
3547 Internally used helper function. Do not use this directly.
3549 *******************************************************************************/
3552 methodinfo *class_resolveinterfacemethod_int(classinfo *c, utf *name, utf *desc)
3557 mi = class_findmethod(c,name,desc);
3561 /* try the superinterfaces */
3562 for (i=0; i<c->interfacescount; ++i) {
3563 mi = class_resolveinterfacemethod_int(c->interfaces[i],name,desc);
3571 /******************** Function: class_resolveinterfacemethod ******************
3573 Resolves a reference from REFERER to a method with NAME and DESC in
3576 If the method cannot be resolved the return value is NULL. If EXCEPT is
3577 true *exceptionptr is set, too.
3579 *******************************************************************************/
3581 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
3582 classinfo *referer, bool except)
3586 /* XXX resolve class c */
3587 /* XXX check access from REFERER to C */
3589 if (!(c->flags & ACC_INTERFACE)) {
3592 new_exception(string_java_lang_IncompatibleClassChangeError);
3597 mi = class_resolveinterfacemethod_int(c, name, desc);
3602 /* try class java.lang.Object */
3603 mi = class_findmethod(class_java_lang_Object, name, desc);
3610 new_exception_utfmessage(string_java_lang_NoSuchMethodError, name);
3616 /********************* Function: class_resolveclassmethod *********************
3618 Resolves a reference from REFERER to a method with NAME and DESC in
3621 If the method cannot be resolved the return value is NULL. If EXCEPT is
3622 true *exceptionptr is set, too.
3624 *******************************************************************************/
3626 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
3627 classinfo *referer, bool except)
3632 char msg[MAXLOGTEXT];
3634 /* XXX resolve class c */
3635 /* XXX check access from REFERER to C */
3637 /* if (c->flags & ACC_INTERFACE) { */
3639 /* *exceptionptr = */
3640 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
3644 /* try class c and its superclasses */
3647 mi = class_findmethod(cls, name, desc);
3650 } while ((cls = cls->super) != NULL); /* try the superclass */
3652 /* try the superinterfaces */
3653 for (i = 0; i < c->interfacescount; ++i) {
3654 mi = class_resolveinterfacemethod_int(c->interfaces[i], name, desc);
3660 utf_sprint(msg, c->name);
3661 sprintf(msg + strlen(msg), ".");
3662 utf_sprint(msg + strlen(msg), name);
3663 utf_sprint(msg + strlen(msg), desc);
3666 new_exception_message(string_java_lang_NoSuchMethodError, msg);
3672 if ((mi->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
3674 *exceptionptr = new_exception(string_java_lang_AbstractMethodError);
3679 /* XXX check access rights */
3685 /************************* Function: class_issubclass **************************
3687 Checks if sub is a descendant of super.
3689 *******************************************************************************/
3691 bool class_issubclass(classinfo *sub, classinfo *super)
3694 if (!sub) return false;
3695 if (sub == super) return true;
3701 /****************** Initialization function for classes ******************
3703 In Java, every class can have a static initialization function. This
3704 function has to be called BEFORE calling other methods or accessing static
3707 *******************************************************************************/
3709 static classinfo *class_init_intern(classinfo *c);
3711 classinfo *class_init(classinfo *c)
3715 if (!makeinitializations)
3718 /* enter a monitor on the class */
3720 builtin_monitorenter((java_objectheader *) c);
3722 /* maybe the class is already initalized or the current thread, which can
3723 pass the monitor, is currently initalizing this class */
3725 if (c->initialized || c->initializing) {
3726 builtin_monitorexit((java_objectheader *) c);
3731 /* this initalizing run begins NOW */
3732 c->initializing = true;
3734 /* call the internal function */
3735 r = class_init_intern(c);
3737 /* if return value is not NULL everything was ok and the class is
3740 c->initialized = true;
3742 /* this initalizing run is done */
3743 c->initializing = false;
3745 /* leave the monitor */
3747 builtin_monitorexit((java_objectheader *) c);
3753 /* this function MUST NOT be called directly, because of thread <clinit>
3756 static classinfo *class_init_intern(classinfo *c)
3760 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3764 /* maybe the class is not already loaded */
3769 /* maybe the class is not already linked */
3774 #if defined(STATISTICS)
3776 count_class_inits++;
3779 /* initialize super class */
3782 if (!c->super->initialized) {
3784 char logtext[MAXLOGTEXT];
3785 sprintf(logtext, "Initialize super class ");
3786 utf_sprint_classname(logtext + strlen(logtext), c->super->name);
3787 sprintf(logtext + strlen(logtext), " from ");
3788 utf_sprint_classname(logtext + strlen(logtext), c->name);
3792 if (!class_init(c->super))
3797 /* initialize interface classes */
3799 for (i = 0; i < c->interfacescount; i++) {
3800 if (!c->interfaces[i]->initialized) {
3802 char logtext[MAXLOGTEXT];
3803 sprintf(logtext, "Initialize interface class ");
3804 utf_sprint_classname(logtext + strlen(logtext), c->interfaces[i]->name);
3805 sprintf(logtext + strlen(logtext), " from ");
3806 utf_sprint_classname(logtext + strlen(logtext), c->name);
3810 if (!class_init(c->interfaces[i]))
3815 m = class_findmethod(c, utf_clinit, utf_fidesc);
3819 char logtext[MAXLOGTEXT];
3820 sprintf(logtext, "Class ");
3821 utf_sprint_classname(logtext + strlen(logtext), c->name);
3822 sprintf(logtext + strlen(logtext), " has no static class initializer");
3829 /* Sun's and IBM's JVM don't care about the static flag */
3830 /* if (!(m->flags & ACC_STATIC)) { */
3831 /* panic("Class initializer is not static!"); */
3834 log_message_class("Starting static class initializer for class: ", c);
3836 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3841 /* now call the initializer */
3842 asm_calljavafunction(m, NULL, NULL, NULL, NULL);
3844 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3845 assert(blockInts == 0);
3849 /* we have an exception or error */
3850 if (*exceptionptr) {
3851 /* class is NOT initialized */
3852 c->initialized = false;
3854 /* is this an exception, than wrap it */
3855 if (builtin_instanceof(*exceptionptr, class_java_lang_Exception)) {
3856 java_objectheader *xptr;
3857 java_objectheader *cause;
3860 cause = *exceptionptr;
3862 /* clear exception, because we are calling jit code again */
3863 *exceptionptr = NULL;
3865 /* wrap the exception */
3867 new_exception_throwable(string_java_lang_ExceptionInInitializerError,
3868 (java_lang_Throwable *) cause);
3870 /* XXX should we exit here? */
3874 /* set new exception */
3875 *exceptionptr = xptr;
3882 log_message_class("Finished static class initializer for class: ", c);
3888 /********* Function: find_class_method_constant *********/
3890 int find_class_method_constant (classinfo *c, utf * c1, utf* m1, utf* d1)
3895 for (i=0; i<c->cpcount; i++) {
3897 e = c -> cpinfos [i];
3900 switch (c -> cptags [i]) {
3901 case CONSTANT_Methodref:
3903 constant_FMIref *fmi = e;
3904 if ( (fmi->class->name == c1)
3905 && (fmi->name == m1)
3906 && (fmi->descriptor == d1)) {
3913 case CONSTANT_InterfaceMethodref:
3915 constant_FMIref *fmi = e;
3916 if ( (fmi->class->name == c1)
3917 && (fmi->name == m1)
3918 && (fmi->descriptor == d1)) {
3932 void class_showconstanti(classinfo *c, int ii)
3938 printf ("#%d: ", (int) i);
3940 switch (c->cptags [i]) {
3941 case CONSTANT_Class:
3942 printf("Classreference -> ");
3943 utf_display(((classinfo*)e)->name);
3946 case CONSTANT_Fieldref:
3947 printf("Fieldref -> "); goto displayFMIi;
3948 case CONSTANT_Methodref:
3949 printf("Methodref -> "); goto displayFMIi;
3950 case CONSTANT_InterfaceMethodref:
3951 printf("InterfaceMethod -> "); goto displayFMIi;
3954 constant_FMIref *fmi = e;
3955 utf_display(fmi->class->name);
3957 utf_display(fmi->name);
3959 utf_display(fmi->descriptor);
3963 case CONSTANT_String:
3964 printf("String -> ");
3967 case CONSTANT_Integer:
3968 printf("Integer -> %d", (int) (((constant_integer*)e)->value));
3970 case CONSTANT_Float:
3971 printf("Float -> %f", ((constant_float*)e)->value);
3973 case CONSTANT_Double:
3974 printf("Double -> %f", ((constant_double*)e)->value);
3978 u8 v = ((constant_long*)e)->value;
3980 printf("Long -> %ld", (long int) v);
3982 printf("Long -> HI: %ld, LO: %ld\n",
3983 (long int) v.high, (long int) v.low);
3987 case CONSTANT_NameAndType:
3989 constant_nameandtype *cnt = e;
3990 printf("NameAndType: ");
3991 utf_display(cnt->name);
3993 utf_display(cnt->descriptor);
4001 panic("Invalid type of ConstantPool-Entry");
4008 void class_showconstantpool (classinfo *c)
4013 printf ("---- dump of constant pool ----\n");
4015 for (i=0; i<c->cpcount; i++) {
4016 printf ("#%d: ", (int) i);
4018 e = c -> cpinfos [i];
4021 switch (c -> cptags [i]) {
4022 case CONSTANT_Class:
4023 printf ("Classreference -> ");
4024 utf_display ( ((classinfo*)e) -> name );
4027 case CONSTANT_Fieldref:
4028 printf ("Fieldref -> "); goto displayFMI;
4029 case CONSTANT_Methodref:
4030 printf ("Methodref -> "); goto displayFMI;
4031 case CONSTANT_InterfaceMethodref:
4032 printf ("InterfaceMethod -> "); goto displayFMI;
4035 constant_FMIref *fmi = e;
4036 utf_display ( fmi->class->name );
4038 utf_display ( fmi->name);
4040 utf_display ( fmi->descriptor );
4044 case CONSTANT_String:
4045 printf ("String -> ");
4048 case CONSTANT_Integer:
4049 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
4051 case CONSTANT_Float:
4052 printf ("Float -> %f", ((constant_float*)e) -> value);
4054 case CONSTANT_Double:
4055 printf ("Double -> %f", ((constant_double*)e) -> value);
4059 u8 v = ((constant_long*)e) -> value;
4061 printf ("Long -> %ld", (long int) v);
4063 printf ("Long -> HI: %ld, LO: %ld\n",
4064 (long int) v.high, (long int) v.low);
4068 case CONSTANT_NameAndType:
4070 constant_nameandtype *cnt = e;
4071 printf ("NameAndType: ");
4072 utf_display (cnt->name);
4074 utf_display (cnt->descriptor);
4078 printf ("Utf8 -> ");
4082 panic ("Invalid type of ConstantPool-Entry");
4092 /********** Function: class_showmethods (debugging only) *************/
4094 void class_showmethods (classinfo *c)
4098 printf ("--------- Fields and Methods ----------------\n");
4099 printf ("Flags: "); printflags (c->flags); printf ("\n");
4101 printf ("This: "); utf_display (c->name); printf ("\n");
4103 printf ("Super: "); utf_display (c->super->name); printf ("\n");
4105 printf ("Index: %d\n", c->index);
4107 printf ("interfaces:\n");
4108 for (i=0; i < c-> interfacescount; i++) {
4110 utf_display (c -> interfaces[i] -> name);
4111 printf (" (%d)\n", c->interfaces[i] -> index);
4114 printf ("fields:\n");
4115 for (i=0; i < c -> fieldscount; i++) {
4116 field_display (&(c -> fields[i]));
4119 printf ("methods:\n");
4120 for (i=0; i < c -> methodscount; i++) {
4121 methodinfo *m = &(c->methods[i]);
4122 if ( !(m->flags & ACC_STATIC))
4123 printf ("vftblindex: %d ", m->vftblindex);
4125 method_display ( m );
4129 printf ("Virtual function table:\n");
4130 for (i=0; i<c->vftbl->vftbllength; i++) {
4131 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]) );
4137 /******************************************************************************/
4138 /******************* General functions for the class loader *******************/
4139 /******************************************************************************/
4141 /**************** function: create_primitive_classes ***************************
4143 create classes representing primitive types
4145 *******************************************************************************/
4147 static bool create_primitive_classes()
4151 for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
4152 /* create primitive class */
4154 class_new_intern(utf_new_char(primitivetype_table[i].name));
4155 c->classUsed = NOTUSED; /* not used initially CO-RT */
4158 /* prevent loader from loading primitive class */
4163 primitivetype_table[i].class_primitive = c;
4165 /* create class for wrapping the primitive type */
4166 c = class_new_intern(utf_new_char(primitivetype_table[i].wrapname));
4167 primitivetype_table[i].class_wrap = c;
4168 primitivetype_table[i].class_wrap->classUsed = NOTUSED; /* not used initially CO-RT */
4169 primitivetype_table[i].class_wrap->impldBy = NULL;
4171 /* create the primitive array class */
4172 if (primitivetype_table[i].arrayname) {
4173 c = class_new_intern(utf_new_char(primitivetype_table[i].arrayname));
4174 primitivetype_table[i].arrayclass = c;
4179 primitivetype_table[i].arrayvftbl = c->vftbl;
4187 /**************** function: class_primitive_from_sig ***************************
4189 return the primitive class indicated by the given signature character
4191 If the descriptor does not indicate a valid primitive type the
4192 return value is NULL.
4194 ********************************************************************************/
4196 classinfo *class_primitive_from_sig(char sig)
4199 case 'I': return primitivetype_table[PRIMITIVETYPE_INT].class_primitive;
4200 case 'J': return primitivetype_table[PRIMITIVETYPE_LONG].class_primitive;
4201 case 'F': return primitivetype_table[PRIMITIVETYPE_FLOAT].class_primitive;
4202 case 'D': return primitivetype_table[PRIMITIVETYPE_DOUBLE].class_primitive;
4203 case 'B': return primitivetype_table[PRIMITIVETYPE_BYTE].class_primitive;
4204 case 'C': return primitivetype_table[PRIMITIVETYPE_CHAR].class_primitive;
4205 case 'S': return primitivetype_table[PRIMITIVETYPE_SHORT].class_primitive;
4206 case 'Z': return primitivetype_table[PRIMITIVETYPE_BOOLEAN].class_primitive;
4207 case 'V': return primitivetype_table[PRIMITIVETYPE_VOID].class_primitive;
4212 /****************** function: class_from_descriptor ****************************
4214 return the class indicated by the given descriptor
4216 utf_ptr....first character of descriptor
4217 end_ptr....first character after the end of the string
4218 next.......if non-NULL, *next is set to the first character after
4219 the descriptor. (Undefined if an error occurs.)
4221 mode.......a combination (binary or) of the following flags:
4223 (Flags marked with * are the default settings.)
4225 What to do if a reference type descriptor is parsed successfully:
4227 CLASSLOAD_SKIP...skip it and return something != NULL
4228 * CLASSLOAD_NEW....get classinfo * via class_new
4229 CLASSLOAD_LOAD...get classinfo * via loader_load
4231 How to handle primitive types:
4233 * CLASSLOAD_PRIMITIVE.......return primitive class (eg. "int")
4234 CLASSLOAD_NULLPRIMITIVE...return NULL for primitive types
4236 How to handle "V" descriptors:
4238 * CLASSLOAD_VOID.....handle it like other primitive types
4239 CLASSLOAD_NOVOID...treat it as an error
4241 How to deal with extra characters after the end of the
4244 * CLASSLOAD_NOCHECKEND...ignore (useful for parameter lists)
4245 CLASSLOAD_CHECKEND.....treat them as an error
4247 How to deal with errors:
4249 * CLASSLOAD_PANIC....abort execution with an error message
4250 CLASSLOAD_NOPANIC..return NULL on error
4252 *******************************************************************************/
4254 classinfo *class_from_descriptor(char *utf_ptr, char *end_ptr,
4255 char **next, int mode)
4257 char *start = utf_ptr;
4261 SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr, end_ptr, error);
4263 if (mode & CLASSLOAD_CHECKEND)
4264 error |= (utf_ptr != end_ptr);
4267 if (next) *next = utf_ptr;
4271 if (mode & CLASSLOAD_NOVOID)
4282 return (mode & CLASSLOAD_NULLPRIMITIVE)
4284 : class_primitive_from_sig(*start);
4291 if (mode & CLASSLOAD_SKIP) return class_java_lang_Object;
4292 name = utf_new(start, utf_ptr - start);
4296 tc = class_new_intern(name);
4298 list_addfirst(&unlinkedclasses, tc);
4303 return (mode & CLASSLOAD_LOAD)
4304 ? class_load(class_new(name)) : class_new(name); /* XXX handle errors */
4309 /* An error occurred */
4310 if (mode & CLASSLOAD_NOPANIC)
4313 log_plain("Invalid descriptor at beginning of '");
4314 log_plain_utf(utf_new(start, end_ptr - start));
4318 panic("Invalid descriptor");
4320 /* keep compiler happy */
4325 /******************* function: type_from_descriptor ****************************
4327 return the basic type indicated by the given descriptor
4329 This function parses a descriptor and returns its basic type as
4330 TYPE_INT, TYPE_LONG, TYPE_FLOAT, TYPE_DOUBLE, TYPE_ADDRESS or TYPE_VOID.
4332 cls...if non-NULL the referenced variable is set to the classinfo *
4333 returned by class_from_descriptor.
4335 For documentation of the arguments utf_ptr, end_ptr, next and mode
4336 see class_from_descriptor. The only difference is that
4337 type_from_descriptor always uses CLASSLOAD_PANIC.
4339 ********************************************************************************/
4341 int type_from_descriptor(classinfo **cls, char *utf_ptr, char *end_ptr,
4342 char **next, int mode)
4345 if (!cls) cls = &mycls;
4346 *cls = class_from_descriptor(utf_ptr, end_ptr, next, mode & (~CLASSLOAD_NOPANIC));
4363 return TYPE_ADDRESS;
4367 /*************** function: create_pseudo_classes *******************************
4369 create pseudo classes used by the typechecker
4371 ********************************************************************************/
4373 static void create_pseudo_classes()
4375 /* pseudo class for Arraystubs (extends java.lang.Object) */
4377 pseudo_class_Arraystub = class_new_intern(utf_new_char("$ARRAYSTUB$"));
4378 pseudo_class_Arraystub->loaded = true;
4379 pseudo_class_Arraystub->super = class_java_lang_Object;
4380 pseudo_class_Arraystub->interfacescount = 2;
4381 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
4382 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
4383 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
4385 class_link(pseudo_class_Arraystub);
4387 pseudo_class_Arraystub_vftbl = pseudo_class_Arraystub->vftbl;
4389 /* pseudo class representing the null type */
4391 pseudo_class_Null = class_new_intern(utf_new_char("$NULL$"));
4392 pseudo_class_Null->loaded = true;
4393 pseudo_class_Null->super = class_java_lang_Object;
4394 class_link(pseudo_class_Null);
4396 /* pseudo class representing new uninitialized objects */
4398 pseudo_class_New = class_new_intern(utf_new_char("$NEW$"));
4399 pseudo_class_New->loaded = true;
4400 pseudo_class_New->linked = true;
4401 pseudo_class_New->super = class_java_lang_Object;
4402 /* class_link(pseudo_class_New); */
4406 /********************** Function: loader_init **********************************
4408 Initializes all lists and loads all classes required for the system or the
4411 *******************************************************************************/
4413 void loader_init(u1 *stackbottom)
4417 /* create utf-symbols for pointer comparison of frequently used strings */
4418 utf_innerclasses = utf_new_char("InnerClasses");
4419 utf_constantvalue = utf_new_char("ConstantValue");
4420 utf_code = utf_new_char("Code");
4421 utf_exceptions = utf_new_char("Exceptions");
4422 utf_linenumbertable = utf_new_char("LineNumberTable");
4423 utf_sourcefile = utf_new_char("SourceFile");
4424 utf_finalize = utf_new_char("finalize");
4425 utf_fidesc = utf_new_char("()V");
4426 utf_init = utf_new_char("<init>");
4427 utf_clinit = utf_new_char("<clinit>");
4428 utf_initsystemclass = utf_new_char("initializeSystemClass");
4429 utf_systemclass = utf_new_char("java/lang/System");
4430 utf_vmclassloader = utf_new_char("java/lang/VMClassLoader");
4431 utf_initialize = utf_new_char("initialize");
4432 utf_initializedesc = utf_new_char("(I)V");
4433 utf_vmclass = utf_new_char("java/lang/VMClass");
4434 utf_java_lang_Object= utf_new_char("java/lang/Object");
4435 array_packagename = utf_new_char("<the array package>");
4436 utf_fillInStackTrace_name = utf_new_char("fillInStackTrace");
4437 utf_fillInStackTrace_desc = utf_new_char("()Ljava/lang/Throwable;");
4439 /* create some important classes */
4440 /* These classes have to be created now because the classinfo
4441 * pointers are used in the loading code.
4443 class_java_lang_Object = class_new_intern(utf_java_lang_Object);
4444 class_load(class_java_lang_Object);
4445 class_link(class_java_lang_Object);
4447 class_java_lang_String = class_new(utf_new_char("java/lang/String"));
4448 class_load(class_java_lang_String);
4449 class_link(class_java_lang_String);
4451 class_java_lang_Cloneable = class_new(utf_new_char("java/lang/Cloneable"));
4452 class_load(class_java_lang_Cloneable);
4453 class_link(class_java_lang_Cloneable);
4455 class_java_io_Serializable =
4456 class_new(utf_new_char("java/io/Serializable"));
4457 class_load(class_java_io_Serializable);
4458 class_link(class_java_io_Serializable);
4460 /* create classes representing primitive types */
4461 create_primitive_classes();
4463 /* create classes used by the typechecker */
4464 create_pseudo_classes();
4466 /* correct vftbl-entries (retarded loading of class java/lang/String) */
4467 stringtable_update();
4469 #if defined(USE_THREADS)
4470 if (stackbottom != 0)
4476 /* loader_compute_subclasses ***************************************************
4480 *******************************************************************************/
4482 static void loader_compute_class_values(classinfo *c);
4484 void loader_compute_subclasses(classinfo *c)
4486 #if defined(USE_THREADS)
4487 #if defined(NATIVE_THREADS)
4494 if (!(c->flags & ACC_INTERFACE)) {
4499 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
4500 c->nextsub = c->super->sub;
4506 /* this is the java.lang.Object special case */
4508 if (!class_java_lang_Object) {
4509 loader_compute_class_values(c);
4512 loader_compute_class_values(class_java_lang_Object);
4515 #if defined(USE_THREADS)
4516 #if defined(NATIVE_THREADS)
4525 /* loader_compute_class_values *************************************************
4529 *******************************************************************************/
4531 static void loader_compute_class_values(classinfo *c)
4535 c->vftbl->baseval = ++classvalue;
4539 loader_compute_class_values(subs);
4540 subs = subs->nextsub;
4543 c->vftbl->diffval = classvalue - c->vftbl->baseval;
4547 /******************** Function: loader_close ***********************************
4551 *******************************************************************************/
4558 for (slot = 0; slot < class_hash.size; slot++) {
4559 c = class_hash.ptr[slot];
4570 * These are local overrides for various environment variables in Emacs.
4571 * Please do not remove this and leave it at the end of the file, where
4572 * Emacs will automagically detect them.
4573 * ---------------------------------------------------------------------
4576 * indent-tabs-mode: t