1 /* loader.c - class loader functions
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5 M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6 P. Tomsich, J. Wenninger
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Reinhard Grafl
29 Changes: Andreas Krall
35 $Id: loader.c 1544 2004-11-18 12:21:44Z twisti $
44 #include "exceptions.h"
53 #include "statistics.h"
54 #include "toolbox/memory.h"
55 #include "toolbox/logging.h"
56 #include "threads/thread.h"
57 #include "threads/locks.h"
58 #include "nat/java_lang_Throwable.h"
68 /* global variables ***********************************************************/
70 static s4 interfaceindex; /* sequential numbering of interfaces */
74 /* utf-symbols for pointer comparison of frequently used strings */
76 static utf *utf_innerclasses; /* InnerClasses */
77 static utf *utf_constantvalue; /* ConstantValue */
78 static utf *utf_code; /* Code */
79 static utf *utf_exceptions; /* Exceptions */
80 static utf *utf_linenumbertable; /* LineNumberTable */
81 static utf *utf_sourcefile; /* SourceFile */
82 static utf *utf_finalize; /* finalize */
83 static utf *utf_fidesc; /* ()V changed */
84 static utf *utf_init; /* <init> */
85 static utf *utf_clinit; /* <clinit> */
86 static utf *utf_initsystemclass; /* initializeSystemClass */
87 static utf *utf_systemclass; /* java/lang/System */
88 static utf *utf_vmclassloader; /* java/lang/VMClassLoader */
89 static utf *utf_vmclass; /* java/lang/VMClassLoader */
90 static utf *utf_initialize;
91 static utf *utf_initializedesc;
92 static utf *utf_java_lang_Object; /* java/lang/Object */
94 utf *utf_fillInStackTrace_name;
95 utf *utf_fillInStackTrace_desc;
105 /* important system classes ***************************************************/
107 classinfo *class_java_lang_Object;
108 classinfo *class_java_lang_String;
109 classinfo *class_java_lang_Cloneable;
110 classinfo *class_java_io_Serializable;
112 /* Pseudo classes for the typechecker */
113 classinfo *pseudo_class_Arraystub = NULL;
114 classinfo *pseudo_class_Null = NULL;
115 classinfo *pseudo_class_New = NULL;
116 vftbl_t *pseudo_class_Arraystub_vftbl = NULL;
118 utf *array_packagename = NULL;
121 /********************************************************************
122 list of classpath entries (either filesystem directories or
124 ********************************************************************/
126 static classpath_info *classpath_entries = NULL;
129 /******************************************************************************
131 structure for primitive classes: contains the class for wrapping the
132 primitive type, the primitive class, the name of the class for wrapping,
133 the one character type signature and the name of the primitive class
135 ******************************************************************************/
137 /* CAUTION: Don't change the order of the types. This table is indexed
138 * by the ARRAYTYPE_ constants (expcept ARRAYTYPE_OBJECT).
140 primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = {
141 { NULL, NULL, "java/lang/Integer", 'I', "int" , "[I", NULL, NULL },
142 { NULL, NULL, "java/lang/Long", 'J', "long" , "[J", NULL, NULL },
143 { NULL, NULL, "java/lang/Float", 'F', "float" , "[F", NULL, NULL },
144 { NULL, NULL, "java/lang/Double", 'D', "double" , "[D", NULL, NULL },
145 { NULL, NULL, "java/lang/Byte", 'B', "byte" , "[B", NULL, NULL },
146 { NULL, NULL, "java/lang/Character", 'C', "char" , "[C", NULL, NULL },
147 { NULL, NULL, "java/lang/Short", 'S', "short" , "[S", NULL, NULL },
148 { NULL, NULL, "java/lang/Boolean", 'Z', "boolean" , "[Z", NULL, NULL },
149 { NULL, NULL, "java/lang/Void", 'V', "void" , NULL, NULL, NULL }
153 /************* functions for reading classdata *********************************
155 getting classdata in blocks of variable size
156 (8,16,32,64-bit integer or float)
158 *******************************************************************************/
160 /* check_classbuffer_size ******************************************************
162 assert that at least <len> bytes are left to read
163 <len> is limited to the range of non-negative s4 values
165 *******************************************************************************/
167 static inline bool check_classbuffer_size(classbuffer *cb, s4 len)
169 if (len < 0 || ((cb->data + cb->size) - cb->pos - 1) < len) {
171 new_classformaterror((cb)->class, "Truncated class file");
180 /* suck_nbytes *****************************************************************
182 transfer block of classfile data into a buffer
184 *******************************************************************************/
186 inline void suck_nbytes(u1 *buffer, classbuffer *cb, s4 len)
188 memcpy(buffer, cb->pos + 1, len);
193 /* skip_nbytes ****************************************************************
195 skip block of classfile data
197 *******************************************************************************/
199 inline void skip_nbytes(classbuffer *cb, s4 len)
205 inline u1 suck_u1(classbuffer *cb)
211 inline u2 suck_u2(classbuffer *cb)
215 return ((u2) a << 8) + (u2) b;
219 inline u4 suck_u4(classbuffer *cb)
225 return ((u4) a << 24) + ((u4) b << 16) + ((u4) c << 8) + (u4) d;
229 /* get u8 from classfile data */
230 static u8 suck_u8(classbuffer *cb)
236 return (hi << 32) + lo;
239 v.high = suck_u4(cb);
246 #define suck_s8(a) (s8) suck_u8((a))
247 #define suck_s2(a) (s2) suck_u2((a))
248 #define suck_s4(a) (s4) suck_u4((a))
249 #define suck_s1(a) (s1) suck_u1((a))
252 /* get float from classfile data */
253 static float suck_float(classbuffer *cb)
261 for (i = 0; i < 4; i++)
262 buffer[3 - i] = suck_u1(cb);
264 memcpy((u1*) (&f), buffer, 4);
266 suck_nbytes((u1*) (&f), cb, 4);
269 if (sizeof(float) != 4) {
270 *exceptionptr = new_exception_message(string_java_lang_InternalError,
271 "Incompatible float-format");
273 /* XXX should we exit in such a case? */
274 throw_exception_exit();
281 /* get double from classfile data */
282 static double suck_double(classbuffer *cb)
290 for (i = 0; i < 8; i++)
291 buffer[7 - i] = suck_u1(cb);
293 memcpy((u1*) (&d), buffer, 8);
295 suck_nbytes((u1*) (&d), cb, 8);
298 if (sizeof(double) != 8) {
299 *exceptionptr = new_exception_message(string_java_lang_InternalError,
300 "Incompatible double-format");
302 /* XXX should we exit in such a case? */
303 throw_exception_exit();
310 /************************** function suck_init *********************************
312 called once at startup, sets the searchpath for the classfiles
314 *******************************************************************************/
316 void suck_init(char *classpath)
324 classpath_info *lastcpi;
329 for (start = classpath; (*start) != '\0';) {
331 /* search for ':' delimiter to get the end of the current entry */
332 for (end = start; ((*end) != '\0') && ((*end) != ':'); end++);
336 filenamelen = end - start;
338 if (filenamelen > 3) {
339 if (strncasecmp(end - 3, "zip", 3) == 0 ||
340 strncasecmp(end - 3, "jar", 3) == 0) {
345 /* allocate memory for filename and fill it */
347 filename = MNEW(char, filenamelen + 1);
348 strncpy(filename, start, filenamelen);
349 filename[filenamelen + 1] = '\0';
353 #if defined(USE_ZLIB)
354 unzFile uf = unzOpen(filename);
357 cpi = (union classpath_info *) NEW(classpath_info);
358 cpi->archive.type = CLASSPATH_ARCHIVE;
359 cpi->archive.uf = uf;
360 cpi->archive.next = NULL;
363 throw_cacao_exception_exit(string_java_lang_InternalError,
364 "zip/jar files not supported");
368 cpi = (union classpath_info *) NEW(classpath_info);
369 cpi->filepath.type = CLASSPATH_PATH;
370 cpi->filepath.next = NULL;
373 if (filename[filenamelen - 1] != '/') {/*PERHAPS THIS SHOULD BE READ FROM A GLOBAL CONFIGURATION */
374 filename[filenamelen] = '/';
375 filename[filenamelen + 1] = '\0';
379 cpi->filepath.path = filename;
380 cpi->filepath.pathlen = filenamelen;
383 /* free allocated memory */
385 MFREE(filename, char, filenamelen);
387 /* attach current classpath entry */
390 if (!classpath_entries) {
391 classpath_entries = cpi;
394 lastcpi->filepath.next = cpi;
401 /* goto next classpath entry, skip ':' delimiter */
413 void create_all_classes()
417 for (cpi = classpath_entries; cpi != 0; cpi = cpi->filepath.next) {
418 #if defined(USE_ZLIB)
419 if (cpi->filepath.type == CLASSPATH_ARCHIVE) {
423 s = (unz_s *) cpi->archive.uf;
424 ce = s->cacao_dir_list;
427 (void) class_new(ce->name);
433 #if defined(USE_ZLIB)
440 /************************** function suck_start ********************************
442 returns true if classbuffer is already loaded or a file for the
443 specified class has succussfully been read in. All directories of
444 the searchpath are used to find the classfile (<classname>.class).
445 Returns false if no classfile is found and writes an error message.
447 *******************************************************************************/
449 classbuffer *suck_start(classinfo *c)
464 utf_ptr = c->name->text;
466 while (utf_ptr < utf_end(c->name)) {
467 if (filenamelen >= CLASSPATH_MAXFILENAME) {
469 new_exception_message(string_java_lang_InternalError,
470 "Filename too long");
472 /* XXX should we exit in such a case? */
473 throw_exception_exit();
477 if ((ch <= ' ' || ch > 'z') && (ch != '/')) /* invalid character */
479 filename[filenamelen++] = ch;
483 /* initialize return value */
487 filenamelen = utf_strlen(c->name) + 7; /* 7 = ".class\0" */
488 filename = MNEW(char, filenamelen);
490 utf_sprint(filename, c->name);
491 strcat(filename, ".class");
493 /* walk through all classpath entries */
495 for (cpi = classpath_entries; !cb && cpi; cpi = cpi->filepath.next) {
496 #if defined(USE_ZLIB)
497 if (cpi->filepath.type == CLASSPATH_ARCHIVE) {
498 if (cacao_locate(cpi->archive.uf, c->name) == UNZ_OK) {
499 unz_file_info file_info;
501 if (unzGetCurrentFileInfo(cpi->archive.uf, &file_info, filename,
502 sizeof(filename), NULL, 0, NULL, 0) == UNZ_OK) {
503 if (unzOpenCurrentFile(cpi->archive.uf) == UNZ_OK) {
504 cb = NEW(classbuffer);
506 cb->size = file_info.uncompressed_size;
507 cb->data = MNEW(u1, cb->size);
508 cb->pos = cb->data - 1;
510 len = unzReadCurrentFile(cpi->archive.uf, cb->data, cb->size);
512 if (len != cb->size) {
513 MFREE(cb->data, u1, cb->size);
514 FREE(cb, classbuffer);
515 log_text("Error while unzipping");
519 log_text("Error while opening file in archive");
523 log_text("Error while retrieving fileinfo");
526 unzCloseCurrentFile(cpi->archive.uf);
529 #endif /* USE_ZLIB */
531 path = MNEW(char, cpi->filepath.pathlen + filenamelen + 1);
532 strcpy(path, cpi->filepath.path);
533 strcat(path, filename);
535 classfile = fopen(path, "r");
537 if (classfile) { /* file exists */
538 /* determine size of classfile */
539 err = stat(path, &buffer);
541 if (!err) { /* read classfile data */
542 cb = NEW(classbuffer);
544 cb->size = buffer.st_size;
545 cb->data = MNEW(u1, cb->size);
546 cb->pos = cb->data - 1;
548 /* read class data */
549 len = fread(cb->data, 1, cb->size, classfile);
551 /* if (len != buffer.st_size) { */
552 /* if (ferror(classfile)) { */
558 MFREE(path, char, cpi->filepath.pathlen + filenamelen + 1);
559 #if defined(USE_ZLIB)
566 dolog("Warning: Can not open class file '%s'", filename);
569 MFREE(filename, char, filenamelen);
575 /************************** function suck_stop *********************************
577 frees memory for buffer with classfile data.
578 Caution: this function may only be called if buffer has been allocated
579 by suck_start with reading a file
581 *******************************************************************************/
583 void suck_stop(classbuffer *cb)
587 MFREE(cb->data, u1, cb->size);
588 FREE(cb, classbuffer);
592 /******************************************************************************/
593 /******************* Some support functions ***********************************/
594 /******************************************************************************/
596 void fprintflags (FILE *fp, u2 f)
598 if ( f & ACC_PUBLIC ) fprintf (fp," PUBLIC");
599 if ( f & ACC_PRIVATE ) fprintf (fp," PRIVATE");
600 if ( f & ACC_PROTECTED ) fprintf (fp," PROTECTED");
601 if ( f & ACC_STATIC ) fprintf (fp," STATIC");
602 if ( f & ACC_FINAL ) fprintf (fp," FINAL");
603 if ( f & ACC_SYNCHRONIZED ) fprintf (fp," SYNCHRONIZED");
604 if ( f & ACC_VOLATILE ) fprintf (fp," VOLATILE");
605 if ( f & ACC_TRANSIENT ) fprintf (fp," TRANSIENT");
606 if ( f & ACC_NATIVE ) fprintf (fp," NATIVE");
607 if ( f & ACC_INTERFACE ) fprintf (fp," INTERFACE");
608 if ( f & ACC_ABSTRACT ) fprintf (fp," ABSTRACT");
612 /********** internal function: printflags (only for debugging) ***************/
614 void printflags(u2 f)
616 if ( f & ACC_PUBLIC ) printf (" PUBLIC");
617 if ( f & ACC_PRIVATE ) printf (" PRIVATE");
618 if ( f & ACC_PROTECTED ) printf (" PROTECTED");
619 if ( f & ACC_STATIC ) printf (" STATIC");
620 if ( f & ACC_FINAL ) printf (" FINAL");
621 if ( f & ACC_SYNCHRONIZED ) printf (" SYNCHRONIZED");
622 if ( f & ACC_VOLATILE ) printf (" VOLATILE");
623 if ( f & ACC_TRANSIENT ) printf (" TRANSIENT");
624 if ( f & ACC_NATIVE ) printf (" NATIVE");
625 if ( f & ACC_INTERFACE ) printf (" INTERFACE");
626 if ( f & ACC_ABSTRACT ) printf (" ABSTRACT");
630 /********************** Function: skipattributebody ****************************
632 skips an attribute after the 16 bit reference to attribute_name has already
635 *******************************************************************************/
637 static bool skipattributebody(classbuffer *cb)
641 if (!check_classbuffer_size(cb, 4))
646 if (!check_classbuffer_size(cb, len))
649 skip_nbytes(cb, len);
655 /************************* Function: skipattributes ****************************
657 skips num attribute structures
659 *******************************************************************************/
661 static bool skipattributes(classbuffer *cb, u4 num)
666 for (i = 0; i < num; i++) {
667 if (!check_classbuffer_size(cb, 2 + 4))
673 if (!check_classbuffer_size(cb, len))
676 skip_nbytes(cb, len);
683 /******************** function:: class_getconstant *****************************
685 retrieves the value at position 'pos' of the constantpool of a class
686 if the type of the value is other than 'ctype' the system is stopped
688 *******************************************************************************/
690 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
692 /* check index and type of constantpool entry */
693 /* (pos == 0 is caught by type comparison) */
694 if (pos >= c->cpcount || c->cptags[pos] != ctype) {
695 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
699 return c->cpinfos[pos];
703 /******************** function: innerclass_getconstant ************************
705 like class_getconstant, but if cptags is ZERO null is returned
707 *******************************************************************************/
709 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
711 /* invalid position in constantpool */
712 if (pos >= c->cpcount) {
713 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
717 /* constantpool entry of type 0 */
721 /* check type of constantpool entry */
722 if (c->cptags[pos] != ctype) {
723 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
727 return c->cpinfos[pos];
731 /********************* Function: class_constanttype ****************************
733 Determines the type of a class entry in the ConstantPool
735 *******************************************************************************/
737 u4 class_constanttype(classinfo *c, u4 pos)
739 if (pos <= 0 || pos >= c->cpcount) {
740 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
744 return c->cptags[pos];
748 /************************ function: attribute_load ****************************
750 read attributes from classfile
752 *******************************************************************************/
754 static bool attribute_load(classbuffer *cb, classinfo *c, u4 num)
759 for (i = 0; i < num; i++) {
760 /* retrieve attribute name */
761 if (!check_classbuffer_size(cb, 2))
764 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
767 if (aname == utf_innerclasses) {
768 /* innerclasses attribute */
771 new_classformaterror(c, "Multiple InnerClasses attributes");
775 if (!check_classbuffer_size(cb, 4 + 2))
778 /* skip attribute length */
781 /* number of records */
782 c->innerclasscount = suck_u2(cb);
784 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
787 /* allocate memory for innerclass structure */
788 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
790 for (j = 0; j < c->innerclasscount; j++) {
791 /* The innerclass structure contains a class with an encoded
792 name, its defining scope, its simple name and a bitmask of
793 the access flags. If an inner class is not a member, its
794 outer_class is NULL, if a class is anonymous, its name is
797 innerclassinfo *info = c->innerclass + j;
800 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
802 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
804 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
805 info->flags = suck_u2(cb);
808 } else if (aname == utf_sourcefile) {
809 if (!check_classbuffer_size(cb, 4 + 2))
812 if (suck_u4(cb) != 2) {
814 new_classformaterror(c, "Wrong size for VALUE attribute");
820 new_classformaterror(c, "Multiple SourceFile attributes");
824 if (!(c->sourcefile = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
828 /* unknown attribute */
829 if (!skipattributebody(cb))
838 /******************* function: checkfielddescriptor ****************************
840 checks whether a field-descriptor is valid and aborts otherwise
841 all referenced classes are inserted into the list of unloaded classes
843 *******************************************************************************/
845 static void checkfielddescriptor (char *utf_ptr, char *end_pos)
847 class_from_descriptor(utf_ptr,end_pos,NULL,
849 | CLASSLOAD_NULLPRIMITIVE
851 | CLASSLOAD_CHECKEND);
853 /* XXX use the following if -noverify */
855 char *tstart; /* pointer to start of classname */
857 char *start = utf_ptr;
859 switch (*utf_ptr++) {
873 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
874 panic ("Ill formed descriptor");
878 panic ("Ill formed descriptor");
881 /* exceeding characters */
882 if (utf_ptr!=end_pos) panic ("descriptor has exceeding chars");
887 /******************* function checkmethoddescriptor ****************************
889 checks whether a method-descriptor is valid and aborts otherwise.
890 All referenced classes are inserted into the list of unloaded classes.
892 The number of arguments is returned. A long or double argument is counted
895 *******************************************************************************/
897 static int checkmethoddescriptor(classinfo *c, utf *descriptor)
899 char *utf_ptr; /* current position in utf text */
900 char *end_pos; /* points behind utf string */
901 s4 argcount = 0; /* number of arguments */
903 utf_ptr = descriptor->text;
904 end_pos = utf_end(descriptor);
906 /* method descriptor must start with parenthesis */
907 if (utf_ptr == end_pos || *utf_ptr++ != '(')
908 panic ("Missing '(' in method descriptor");
910 /* check arguments */
911 while (utf_ptr != end_pos && *utf_ptr != ')') {
912 /* We cannot count the this argument here because
913 * we don't know if the method is static. */
914 if (*utf_ptr == 'J' || *utf_ptr == 'D')
918 class_from_descriptor(utf_ptr,end_pos,&utf_ptr,
920 | CLASSLOAD_NULLPRIMITIVE
924 if (utf_ptr == end_pos)
925 panic("Missing ')' in method descriptor");
927 utf_ptr++; /* skip ')' */
929 class_from_descriptor(utf_ptr,
933 CLASSLOAD_NULLPRIMITIVE |
936 if (argcount > 255) {
938 new_classformaterror(c, "Too many arguments in signature");
945 /* XXX use the following if -noverify */
947 /* check arguments */
948 while ((c = *utf_ptr++) != ')') {
965 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
966 panic ("Ill formed method descriptor");
970 panic ("Ill formed methodtype-descriptor");
974 /* check returntype */
976 /* returntype void */
977 if ((utf_ptr+1) != end_pos) panic ("Method-descriptor has exceeding chars");
980 /* treat as field-descriptor */
981 checkfielddescriptor (utf_ptr,end_pos);
986 /***************** Function: print_arraydescriptor ****************************
988 Debugging helper for displaying an arraydescriptor
990 *******************************************************************************/
992 void print_arraydescriptor(FILE *file, arraydescriptor *desc)
995 fprintf(file, "<NULL>");
1000 if (desc->componentvftbl) {
1001 if (desc->componentvftbl->class)
1002 utf_fprint(file, desc->componentvftbl->class->name);
1004 fprintf(file, "<no classinfo>");
1010 if (desc->elementvftbl) {
1011 if (desc->elementvftbl->class)
1012 utf_fprint(file, desc->elementvftbl->class->name);
1014 fprintf(file, "<no classinfo>");
1018 fprintf(file, ",%d,%d,%d,%d}", desc->arraytype, desc->dimension,
1019 desc->dataoffset, desc->componentsize);
1023 /******************************************************************************/
1024 /************************** Functions for fields ****************************/
1025 /******************************************************************************/
1028 /* field_load ******************************************************************
1030 Load everything about a class field from the class file and fill a
1031 'fieldinfo' structure. For static fields, space in the data segment is
1034 *******************************************************************************/
1036 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
1038 static bool field_load(classbuffer *cb, classinfo *c, fieldinfo *f)
1042 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
1045 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1048 f->flags = suck_u2(cb);
1050 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1054 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1060 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<')
1061 panic("Field with invalid name");
1063 /* check flag consistency */
1064 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
1066 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
1067 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
1069 new_classformaterror(c,
1070 "Illegal field modifiers: 0x%X",
1075 if (c->flags & ACC_INTERFACE) {
1076 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
1077 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
1078 f->flags & ACC_TRANSIENT) {
1080 new_classformaterror(c,
1081 "Illegal field modifiers: 0x%X",
1087 /* check descriptor */
1088 checkfielddescriptor(f->descriptor->text, utf_end(f->descriptor));
1091 f->type = jtype = desc_to_type(f->descriptor); /* data type */
1092 f->offset = 0; /* offset from start of object */
1097 case TYPE_INT: f->value.i = 0; break;
1098 case TYPE_FLOAT: f->value.f = 0.0; break;
1099 case TYPE_DOUBLE: f->value.d = 0.0; break;
1100 case TYPE_ADDRESS: f->value.a = NULL; break;
1103 f->value.l = 0; break;
1105 f->value.l.low = 0; f->value.l.high = 0; break;
1109 /* read attributes */
1110 if (!check_classbuffer_size(cb, 2))
1113 attrnum = suck_u2(cb);
1114 for (i = 0; i < attrnum; i++) {
1115 if (!check_classbuffer_size(cb, 2))
1118 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1121 if (u == utf_constantvalue) {
1122 if (!check_classbuffer_size(cb, 4 + 2))
1125 /* check attribute length */
1126 if (suck_u4(cb) != 2) {
1128 new_classformaterror(c, "Wrong size for VALUE attribute");
1132 /* constant value attribute */
1133 if (pindex != field_load_NOVALUE) {
1135 new_classformaterror(c,
1136 "Multiple ConstantValue attributes");
1140 /* index of value in constantpool */
1141 pindex = suck_u2(cb);
1143 /* initialize field with value from constantpool */
1146 constant_integer *ci;
1148 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
1151 f->value.i = ci->value;
1158 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
1161 f->value.l = cl->value;
1168 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
1171 f->value.f = cf->value;
1176 constant_double *cd;
1178 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
1181 f->value.d = cd->value;
1186 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
1189 /* create javastring from compressed utf8-string */
1190 f->value.a = literalstring_new(u);
1194 log_text("Invalid Constant - Type");
1198 /* unknown attribute */
1199 if (!skipattributebody(cb))
1204 /* everything was ok */
1210 /********************** function: field_free **********************************/
1212 static void field_free(fieldinfo *f)
1218 /**************** Function: field_display (debugging only) ********************/
1220 void field_display(fieldinfo *f)
1223 printflags(f->flags);
1225 utf_display(f->name);
1227 utf_display(f->descriptor);
1228 printf(" offset: %ld\n", (long int) (f->offset));
1232 /******************************************************************************/
1233 /************************* Functions for methods ******************************/
1234 /******************************************************************************/
1237 /* method_load *****************************************************************
1239 Loads a method from the class file and fills an existing 'methodinfo'
1240 structure. For native methods, the function pointer field is set to the
1241 real function pointer, for JavaVM methods a pointer to the compiler is used
1244 *******************************************************************************/
1246 static bool method_load(classbuffer *cb, classinfo *c, methodinfo *m)
1254 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1255 initObjectLock(&m->header);
1260 count_all_methods++;
1263 m->thrownexceptionscount = 0;
1264 m->linenumbercount = 0;
1267 m->nativelyoverloaded = false;
1269 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1272 m->flags = suck_u2(cb);
1274 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1278 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1283 if (!is_valid_name_utf(m->name))
1284 panic("Method with invalid name");
1286 if (m->name->text[0] == '<'
1287 && m->name != utf_init && m->name != utf_clinit)
1288 panic("Method with invalid special name");
1291 argcount = checkmethoddescriptor(c, m->descriptor);
1293 if (!(m->flags & ACC_STATIC))
1294 argcount++; /* count the 'this' argument */
1297 if (argcount > 255) {
1299 new_classformaterror(c, "Too many arguments in signature");
1303 /* check flag consistency */
1304 if (m->name != utf_clinit) {
1305 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1307 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1309 new_classformaterror(c,
1310 "Illegal method modifiers: 0x%X",
1315 if (m->flags & ACC_ABSTRACT) {
1316 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1317 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1319 new_classformaterror(c,
1320 "Illegal method modifiers: 0x%X",
1326 if (c->flags & ACC_INTERFACE) {
1327 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1329 new_classformaterror(c,
1330 "Illegal method modifiers: 0x%X",
1336 if (m->name == utf_init) {
1337 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1338 ACC_NATIVE | ACC_ABSTRACT))
1339 panic("Instance initialization method has invalid flags set");
1345 m->basicblockcount = 0;
1346 m->basicblocks = NULL;
1347 m->basicblockindex = NULL;
1348 m->instructioncount = 0;
1349 m->instructions = NULL;
1352 m->exceptiontable = NULL;
1353 m->stubroutine = NULL;
1355 m->entrypoint = NULL;
1356 m->methodUsed = NOTUSED;
1359 m->subRedefsUsed = 0;
1363 if (!(m->flags & ACC_NATIVE)) {
1364 m->stubroutine = createcompilerstub(m);
1367 /*if (useinlining) {
1368 log_text("creating native stub:");
1371 functionptr f = native_findfunction(c->name, m->name, m->descriptor,
1372 (m->flags & ACC_STATIC) != 0);
1373 #ifdef STATIC_CLASSPATH
1377 m->stubroutine = createnativestub(f, m);
1381 if (!check_classbuffer_size(cb, 2))
1384 attrnum = suck_u2(cb);
1385 for (i = 0; i < attrnum; i++) {
1388 if (!check_classbuffer_size(cb, 2))
1391 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1394 if (aname == utf_code) {
1395 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1397 new_classformaterror(c,
1398 "Code attribute in native or abstract methods");
1405 new_classformaterror(c, "Multiple Code attributes");
1410 if (!check_classbuffer_size(cb, 4 + 2 + 2))
1414 m->maxstack = suck_u2(cb);
1415 m->maxlocals = suck_u2(cb);
1417 if (m->maxlocals < argcount) {
1419 new_classformaterror(c, "Arguments can't fit into locals");
1424 if (!check_classbuffer_size(cb, 4))
1427 m->jcodelength = suck_u4(cb);
1429 if (m->jcodelength == 0) {
1431 new_classformaterror(c, "Code of a method has length 0");
1436 if (m->jcodelength > 65535) {
1438 new_classformaterror(c,
1439 "Code of a method longer than 65535 bytes");
1444 if (!check_classbuffer_size(cb, m->jcodelength))
1447 m->jcode = MNEW(u1, m->jcodelength);
1448 suck_nbytes(m->jcode, cb, m->jcodelength);
1450 if (!check_classbuffer_size(cb, 2))
1453 m->exceptiontablelength = suck_u2(cb);
1454 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->exceptiontablelength))
1457 m->exceptiontable = MNEW(exceptiontable, m->exceptiontablelength);
1459 #if defined(STATISTICS)
1461 count_vmcode_len += m->jcodelength + 18;
1462 count_extable_len += 8 * m->exceptiontablelength;
1466 for (j = 0; j < m->exceptiontablelength; j++) {
1468 m->exceptiontable[j].startpc = suck_u2(cb);
1469 m->exceptiontable[j].endpc = suck_u2(cb);
1470 m->exceptiontable[j].handlerpc = suck_u2(cb);
1474 m->exceptiontable[j].catchtype = NULL;
1477 if (!(m->exceptiontable[j].catchtype =
1478 class_getconstant(c, idx, CONSTANT_Class)))
1483 if (!check_classbuffer_size(cb, 2))
1486 codeattrnum = suck_u2(cb);
1488 for (; codeattrnum > 0; codeattrnum--) {
1491 if (!check_classbuffer_size(cb, 2))
1494 if (!(caname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1497 if (caname == utf_linenumbertable) {
1500 if (!check_classbuffer_size(cb, 4 + 2))
1504 m->linenumbercount = suck_u2(cb);
1506 if (!check_classbuffer_size(cb,
1507 (2 + 2) * m->linenumbercount))
1510 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1512 for (lncid = 0; lncid < m->linenumbercount; lncid++) {
1513 m->linenumbers[lncid].start_pc = suck_u2(cb);
1514 m->linenumbers[lncid].line_number = suck_u2(cb);
1518 if (!skipattributes(cb, codeattrnum))
1524 if (!skipattributebody(cb))
1529 } else if (aname == utf_exceptions) {
1532 if (m->thrownexceptions) {
1534 new_classformaterror(c, "Multiple Exceptions attributes");
1538 if (!check_classbuffer_size(cb, 4 + 2))
1541 suck_u4(cb); /* length */
1542 m->thrownexceptionscount = suck_u2(cb);
1544 if (!check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1547 m->thrownexceptions = MNEW(classinfo*, m->thrownexceptionscount);
1549 for (j = 0; j < m->thrownexceptionscount; j++) {
1550 if (!((m->thrownexceptions)[j] =
1551 class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1556 if (!skipattributebody(cb))
1561 if (!m->jcode && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1562 *exceptionptr = new_classformaterror(c, "Missing Code attribute");
1567 /* everything was ok */
1568 /* utf_display(m->name);
1569 printf("\nexceptiontablelength:%ld\n",m->exceptiontablelength);*/
1575 /********************* Function: method_free ***********************************
1577 frees all memory that was allocated for this method
1579 *******************************************************************************/
1581 static void method_free(methodinfo *m)
1584 MFREE(m->jcode, u1, m->jcodelength);
1586 if (m->exceptiontable)
1587 MFREE(m->exceptiontable, exceptiontable, m->exceptiontablelength);
1590 CFREE(m->mcode, m->mcodelength);
1592 if (m->stubroutine) {
1593 if (m->flags & ACC_NATIVE) {
1594 removenativestub(m->stubroutine);
1597 removecompilerstub(m->stubroutine);
1603 /************** Function: method_display (debugging only) **************/
1605 void method_display(methodinfo *m)
1608 printflags(m->flags);
1610 utf_display(m->name);
1612 utf_display(m->descriptor);
1616 /************** Function: method_display_flags_last (debugging only) **************/
1618 void method_display_flags_last(methodinfo *m)
1621 utf_display(m->name);
1623 utf_display(m->descriptor);
1625 printflags(m->flags);
1630 /******************** Function: method_canoverwrite ****************************
1632 Check if m and old are identical with respect to type and name. This means
1633 that old can be overwritten with m.
1635 *******************************************************************************/
1637 static bool method_canoverwrite(methodinfo *m, methodinfo *old)
1639 if (m->name != old->name) return false;
1640 if (m->descriptor != old->descriptor) return false;
1641 if (m->flags & ACC_STATIC) return false;
1646 /******************** function: class_loadcpool ********************************
1648 loads the constantpool of a class,
1649 the entries are transformed into a simpler format
1650 by resolving references
1651 (a detailed overview of the compact structures can be found in global.h)
1653 *******************************************************************************/
1655 static bool class_loadcpool(classbuffer *cb, classinfo *c)
1658 /* The following structures are used to save information which cannot be
1659 processed during the first pass. After the complete constantpool has
1660 been traversed the references can be resolved.
1661 (only in specific order) */
1663 /* CONSTANT_Class entries */
1664 typedef struct forward_class {
1665 struct forward_class *next;
1670 /* CONSTANT_String */
1671 typedef struct forward_string {
1672 struct forward_string *next;
1677 /* CONSTANT_NameAndType */
1678 typedef struct forward_nameandtype {
1679 struct forward_nameandtype *next;
1683 } forward_nameandtype;
1685 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
1686 typedef struct forward_fieldmethint {
1687 struct forward_fieldmethint *next;
1691 u2 nameandtype_index;
1692 } forward_fieldmethint;
1697 forward_class *forward_classes = NULL;
1698 forward_string *forward_strings = NULL;
1699 forward_nameandtype *forward_nameandtypes = NULL;
1700 forward_fieldmethint *forward_fieldmethints = NULL;
1703 forward_string *nfs;
1704 forward_nameandtype *nfn;
1705 forward_fieldmethint *nff;
1711 /* number of entries in the constant_pool table plus one */
1712 if (!check_classbuffer_size(cb, 2))
1715 cpcount = c->cpcount = suck_u2(cb);
1717 /* allocate memory */
1718 cptags = c->cptags = MNEW(u1, cpcount);
1719 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
1722 *exceptionptr = new_classformaterror(c, "Illegal constant pool size");
1726 #if defined(STATISTICS)
1728 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
1731 /* initialize constantpool */
1732 for (idx = 0; idx < cpcount; idx++) {
1733 cptags[idx] = CONSTANT_UNUSED;
1734 cpinfos[idx] = NULL;
1738 /******* first pass *******/
1739 /* entries which cannot be resolved now are written into
1740 temporary structures and traversed again later */
1743 while (idx < cpcount) {
1746 /* get constant type */
1747 if (!check_classbuffer_size(cb, 1))
1753 case CONSTANT_Class:
1754 nfc = NEW(forward_class);
1756 nfc->next = forward_classes;
1757 forward_classes = nfc;
1759 nfc->thisindex = idx;
1760 /* reference to CONSTANT_NameAndType */
1761 if (!check_classbuffer_size(cb, 2))
1764 nfc->name_index = suck_u2(cb);
1769 case CONSTANT_String:
1770 nfs = NEW(forward_string);
1772 nfs->next = forward_strings;
1773 forward_strings = nfs;
1775 nfs->thisindex = idx;
1777 /* reference to CONSTANT_Utf8_info with string characters */
1778 if (!check_classbuffer_size(cb, 2))
1781 nfs->string_index = suck_u2(cb);
1786 case CONSTANT_NameAndType:
1787 nfn = NEW(forward_nameandtype);
1789 nfn->next = forward_nameandtypes;
1790 forward_nameandtypes = nfn;
1792 nfn->thisindex = idx;
1794 if (!check_classbuffer_size(cb, 2 + 2))
1797 /* reference to CONSTANT_Utf8_info containing simple name */
1798 nfn->name_index = suck_u2(cb);
1800 /* reference to CONSTANT_Utf8_info containing field or method
1802 nfn->sig_index = suck_u2(cb);
1807 case CONSTANT_Fieldref:
1808 case CONSTANT_Methodref:
1809 case CONSTANT_InterfaceMethodref:
1810 nff = NEW(forward_fieldmethint);
1812 nff->next = forward_fieldmethints;
1813 forward_fieldmethints = nff;
1815 nff->thisindex = idx;
1819 if (!check_classbuffer_size(cb, 2 + 2))
1822 /* class or interface type that contains the declaration of the
1824 nff->class_index = suck_u2(cb);
1826 /* name and descriptor of the field or method */
1827 nff->nameandtype_index = suck_u2(cb);
1832 case CONSTANT_Integer: {
1833 constant_integer *ci = NEW(constant_integer);
1835 #if defined(STATISTICS)
1837 count_const_pool_len += sizeof(constant_integer);
1840 if (!check_classbuffer_size(cb, 4))
1843 ci->value = suck_s4(cb);
1844 cptags[idx] = CONSTANT_Integer;
1851 case CONSTANT_Float: {
1852 constant_float *cf = NEW(constant_float);
1854 #if defined(STATISTICS)
1856 count_const_pool_len += sizeof(constant_float);
1859 if (!check_classbuffer_size(cb, 4))
1862 cf->value = suck_float(cb);
1863 cptags[idx] = CONSTANT_Float;
1870 case CONSTANT_Long: {
1871 constant_long *cl = NEW(constant_long);
1873 #if defined(STATISTICS)
1875 count_const_pool_len += sizeof(constant_long);
1878 if (!check_classbuffer_size(cb, 8))
1881 cl->value = suck_s8(cb);
1882 cptags[idx] = CONSTANT_Long;
1885 if (idx > cpcount) {
1887 new_classformaterror(c, "Invalid constant pool entry");
1893 case CONSTANT_Double: {
1894 constant_double *cd = NEW(constant_double);
1896 #if defined(STATISTICS)
1898 count_const_pool_len += sizeof(constant_double);
1901 if (!check_classbuffer_size(cb, 8))
1904 cd->value = suck_double(cb);
1905 cptags[idx] = CONSTANT_Double;
1908 if (idx > cpcount) {
1910 new_classformaterror(c, "Invalid constant pool entry");
1916 case CONSTANT_Utf8: {
1919 /* number of bytes in the bytes array (not string-length) */
1920 if (!check_classbuffer_size(cb, 2))
1923 length = suck_u2(cb);
1924 cptags[idx] = CONSTANT_Utf8;
1926 /* validate the string */
1927 if (!check_classbuffer_size(cb, length))
1931 !is_valid_utf((char *) (cb->pos + 1),
1932 (char *) (cb->pos + 1 + length))) {
1933 dolog("Invalid UTF-8 string (constant pool index %d)",idx);
1934 panic("Invalid UTF-8 string");
1936 /* insert utf-string into the utf-symboltable */
1937 cpinfos[idx] = utf_new_intern((char *) (cb->pos + 1), length);
1939 /* skip bytes of the string (buffer size check above) */
1940 skip_nbytes(cb, length);
1947 new_classformaterror(c, "Illegal constant pool type");
1953 /* resolve entries in temporary structures */
1955 while (forward_classes) {
1957 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
1959 if (opt_verify && !is_valid_name_utf(name))
1960 panic("Class reference with invalid name");
1962 cptags[forward_classes->thisindex] = CONSTANT_Class;
1963 /* retrieve class from class-table */
1966 tc = class_new_intern(name);
1968 if (!class_load(tc))
1971 /* link the class later, because we cannot link the class currently
1973 list_addfirst(&unlinkedclasses, tc);
1975 cpinfos[forward_classes->thisindex] = tc;
1978 cpinfos[forward_classes->thisindex] = class_new(name);
1981 nfc = forward_classes;
1982 forward_classes = forward_classes->next;
1983 FREE(nfc, forward_class);
1986 while (forward_strings) {
1988 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
1990 /* resolve utf-string */
1991 cptags[forward_strings->thisindex] = CONSTANT_String;
1992 cpinfos[forward_strings->thisindex] = text;
1994 nfs = forward_strings;
1995 forward_strings = forward_strings->next;
1996 FREE(nfs, forward_string);
1999 while (forward_nameandtypes) {
2000 constant_nameandtype *cn = NEW(constant_nameandtype);
2002 #if defined(STATISTICS)
2004 count_const_pool_len += sizeof(constant_nameandtype);
2007 /* resolve simple name and descriptor */
2008 cn->name = class_getconstant(c,
2009 forward_nameandtypes->name_index,
2012 cn->descriptor = class_getconstant(c,
2013 forward_nameandtypes->sig_index,
2018 if (!is_valid_name_utf(cn->name))
2019 panic("NameAndType with invalid name");
2020 /* disallow referencing <clinit> among others */
2021 if (cn->name->text[0] == '<' && cn->name != utf_init)
2022 panic("NameAndType with invalid special name");
2025 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
2026 cpinfos[forward_nameandtypes->thisindex] = cn;
2028 nfn = forward_nameandtypes;
2029 forward_nameandtypes = forward_nameandtypes->next;
2030 FREE(nfn, forward_nameandtype);
2033 while (forward_fieldmethints) {
2034 constant_nameandtype *nat;
2035 constant_FMIref *fmi = NEW(constant_FMIref);
2037 #if defined(STATISTICS)
2039 count_const_pool_len += sizeof(constant_FMIref);
2041 /* resolve simple name and descriptor */
2042 nat = class_getconstant(c,
2043 forward_fieldmethints->nameandtype_index,
2044 CONSTANT_NameAndType);
2046 fmi->class = class_getconstant(c,
2047 forward_fieldmethints->class_index,
2049 fmi->name = nat->name;
2050 fmi->descriptor = nat->descriptor;
2052 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
2053 cpinfos[forward_fieldmethints->thisindex] = fmi;
2055 switch (forward_fieldmethints->tag) {
2056 case CONSTANT_Fieldref: /* check validity of descriptor */
2057 checkfielddescriptor(fmi->descriptor->text,
2058 utf_end(fmi->descriptor));
2060 case CONSTANT_InterfaceMethodref:
2061 case CONSTANT_Methodref: /* check validity of descriptor */
2062 checkmethoddescriptor(c, fmi->descriptor);
2066 nff = forward_fieldmethints;
2067 forward_fieldmethints = forward_fieldmethints->next;
2068 FREE(nff, forward_fieldmethint);
2071 /* everything was ok */
2077 /********************** Function: class_load ***********************************
2079 Loads everything interesting about a class from the class file. The
2080 'classinfo' structure must have been allocated previously.
2082 The super class and the interfaces implemented by this class need not be
2083 loaded. The link is set later by the function 'class_link'.
2085 The loaded class is removed from the list 'unloadedclasses' and added to
2086 the list 'unlinkedclasses'.
2088 *******************************************************************************/
2090 classinfo *class_load_intern(classbuffer *cb);
2092 classinfo *class_load(classinfo *c)
2097 /* enter a monitor on the class */
2099 builtin_monitorenter((java_objectheader *) c);
2101 /* maybe the class is already loaded */
2103 builtin_monitorexit((java_objectheader *) c);
2110 if (getcompilingtime)
2111 compilingtime_stop();
2114 loadingtime_start();
2116 /* load classdata, throw exception on error */
2118 if ((cb = suck_start(c)) == NULL) {
2119 /* this means, the classpath was not set properly */
2120 if (c->name == utf_java_lang_Object)
2121 throw_cacao_exception_exit(string_java_lang_NoClassDefFoundError,
2122 "java/lang/Object");
2125 new_exception_utfmessage(string_java_lang_NoClassDefFoundError,
2128 builtin_monitorexit((java_objectheader *) c);
2133 /* call the internal function */
2134 r = class_load_intern(cb);
2136 /* if return value is NULL, we had a problem and the class is not loaded */
2140 /* now free the allocated memory, otherwise we could ran into a DOS */
2152 if (getcompilingtime)
2153 compilingtime_start();
2155 /* leave the monitor */
2157 builtin_monitorexit((java_objectheader *) c);
2163 classinfo *class_load_intern(classbuffer *cb)
2169 char msg[MAXLOGTEXT]; /* maybe we get an exception */
2171 /* get the classbuffer's class */
2174 /* maybe the class is already loaded */
2178 #if defined(STATISTICS)
2180 count_class_loads++;
2183 /* output for debugging purposes */
2185 log_message_class("Loading class: ", c);
2187 /* class is somewhat loaded */
2190 if (!check_classbuffer_size(cb, 4 + 2 + 2))
2193 /* check signature */
2194 if (suck_u4(cb) != MAGIC) {
2195 *exceptionptr = new_classformaterror(c, "Bad magic number");
2204 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
2206 new_unsupportedclassversionerror(c,
2207 "Unsupported major.minor version %d.%d",
2213 /* load the constant pool */
2214 if (!class_loadcpool(cb, c))
2218 c->erroneous_state = 0;
2219 c->initializing_thread = 0;
2221 c->classUsed = NOTUSED; /* not used initially CO-RT */
2225 if (!check_classbuffer_size(cb, 2))
2228 c->flags = suck_u2(cb);
2229 /*if (!(c->flags & ACC_PUBLIC)) { log_text("CLASS NOT PUBLIC"); } JOWENN*/
2231 /* check ACC flags consistency */
2232 if (c->flags & ACC_INTERFACE) {
2233 if (!(c->flags & ACC_ABSTRACT)) {
2234 /* We work around this because interfaces in JDK 1.1 are
2235 * not declared abstract. */
2237 c->flags |= ACC_ABSTRACT;
2238 /* panic("Interface class not declared abstract"); */
2241 if (c->flags & ACC_FINAL) {
2243 new_classformaterror(c,
2244 "Illegal class modifiers: 0x%X", c->flags);
2249 if (c->flags & ACC_SUPER) {
2250 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
2254 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
2256 new_classformaterror(c, "Illegal class modifiers: 0x%X", c->flags);
2261 if (!check_classbuffer_size(cb, 2 + 2))
2266 if (!(tc = class_getconstant(c, i, CONSTANT_Class)))
2270 utf_sprint(msg, c->name);
2271 sprintf(msg + strlen(msg), " (wrong name: ");
2272 utf_sprint(msg + strlen(msg), tc->name);
2273 sprintf(msg + strlen(msg), ")");
2276 new_exception_message(string_java_lang_NoClassDefFoundError, msg);
2281 /* retrieve superclass */
2282 if ((i = suck_u2(cb))) {
2283 if (!(c->super = class_getconstant(c, i, CONSTANT_Class)))
2286 /* java.lang.Object may not have a super class. */
2287 if (c->name == utf_java_lang_Object) {
2289 new_exception_message(string_java_lang_ClassFormatError,
2290 "java.lang.Object with superclass");
2295 /* Interfaces must have java.lang.Object as super class. */
2296 if ((c->flags & ACC_INTERFACE) &&
2297 c->super->name != utf_java_lang_Object) {
2299 new_exception_message(string_java_lang_ClassFormatError,
2300 "Interfaces must have java.lang.Object as superclass");
2308 /* This is only allowed for java.lang.Object. */
2309 if (c->name != utf_java_lang_Object) {
2310 *exceptionptr = new_classformaterror(c, "Bad superclass index");
2316 /* retrieve interfaces */
2317 if (!check_classbuffer_size(cb, 2))
2320 c->interfacescount = suck_u2(cb);
2322 if (!check_classbuffer_size(cb, 2 * c->interfacescount))
2325 c->interfaces = MNEW(classinfo*, c->interfacescount);
2326 for (i = 0; i < c->interfacescount; i++) {
2327 if (!(c->interfaces[i] = class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2332 if (!check_classbuffer_size(cb, 2))
2335 c->fieldscount = suck_u2(cb);
2336 c->fields = GCNEW(fieldinfo, c->fieldscount);
2337 /* c->fields = MNEW(fieldinfo, c->fieldscount); */
2338 for (i = 0; i < c->fieldscount; i++) {
2339 if (!field_load(cb, c, &(c->fields[i])))
2344 if (!check_classbuffer_size(cb, 2))
2347 c->methodscount = suck_u2(cb);
2348 c->methods = GCNEW(methodinfo, c->methodscount);
2349 /* c->methods = MNEW(methodinfo, c->methodscount); */
2350 for (i = 0; i < c->methodscount; i++) {
2351 if (!method_load(cb, c, &(c->methods[i])))
2355 /* Check if all fields and methods can be uniquely
2356 * identified by (name,descriptor). */
2358 /* We use a hash table here to avoid making the
2359 * average case quadratic in # of methods, fields.
2361 static int shift = 0;
2363 u2 *next; /* for chaining colliding hash entries */
2369 /* Allocate hashtable */
2370 len = c->methodscount;
2371 if (len < c->fieldscount) len = c->fieldscount;
2373 hashtab = MNEW(u2,(hashlen + len));
2374 next = hashtab + hashlen;
2376 /* Determine bitshift (to get good hash values) */
2386 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2388 for (i = 0; i < c->fieldscount; ++i) {
2389 fieldinfo *fi = c->fields + i;
2391 /* It's ok if we lose bits here */
2392 index = ((((size_t) fi->name) +
2393 ((size_t) fi->descriptor)) >> shift) % hashlen;
2395 if ((old = hashtab[index])) {
2399 if (c->fields[old].name == fi->name &&
2400 c->fields[old].descriptor == fi->descriptor) {
2402 new_classformaterror(c,
2403 "Repetitive field name/signature");
2407 } while ((old = next[old]));
2409 hashtab[index] = i + 1;
2413 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2415 for (i = 0; i < c->methodscount; ++i) {
2416 methodinfo *mi = c->methods + i;
2418 /* It's ok if we lose bits here */
2419 index = ((((size_t) mi->name) +
2420 ((size_t) mi->descriptor)) >> shift) % hashlen;
2424 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2425 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2429 if ((old = hashtab[index])) {
2433 if (c->methods[old].name == mi->name &&
2434 c->methods[old].descriptor == mi->descriptor) {
2436 new_classformaterror(c,
2437 "Repetitive method name/signature");
2441 } while ((old = next[old]));
2443 hashtab[index] = i + 1;
2446 MFREE(hashtab, u2, (hashlen + len));
2449 #if defined(STATISTICS)
2451 count_class_infos += sizeof(classinfo*) * c->interfacescount;
2452 count_class_infos += sizeof(fieldinfo) * c->fieldscount;
2453 count_class_infos += sizeof(methodinfo) * c->methodscount;
2457 /* load attribute structures */
2458 if (!check_classbuffer_size(cb, 2))
2461 if (!attribute_load(cb, c, suck_u2(cb)))
2465 /* Pre java 1.5 version don't check this. This implementation is like
2466 java 1.5 do it: for class file version 45.3 we don't check it, older
2467 versions are checked.
2469 if ((ma == 45 && mi > 3) || ma > 45) {
2470 /* check if all data has been read */
2471 s4 classdata_left = ((cb->data + cb->size) - cb->pos - 1);
2473 if (classdata_left > 0) {
2475 new_classformaterror(c, "Extra bytes at the end of class file");
2482 log_message_class("Loading done class: ", c);
2489 /************** internal Function: class_highestinterface **********************
2491 Used by the function class_link to determine the amount of memory needed
2492 for the interface table.
2494 *******************************************************************************/
2496 static s4 class_highestinterface(classinfo *c)
2501 /* check for ACC_INTERFACE bit already done in class_link_intern */
2504 for (i = 0; i < c->interfacescount; i++) {
2505 s4 h2 = class_highestinterface(c->interfaces[i]);
2513 /* class_addinterface **********************************************************
2515 Is needed by class_link for adding a VTBL to a class. All interfaces
2516 implemented by ic are added as well.
2518 *******************************************************************************/
2520 static void class_addinterface(classinfo *c, classinfo *ic)
2524 vftbl_t *v = c->vftbl;
2526 if (i >= v->interfacetablelength)
2527 panic ("Inernal error: interfacetable overflow");
2529 if (v->interfacetable[-i])
2532 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
2533 v->interfacevftbllength[i] = 1;
2534 v->interfacetable[-i] = MNEW(methodptr, 1);
2535 v->interfacetable[-i][0] = NULL;
2538 v->interfacevftbllength[i] = ic->methodscount;
2539 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
2541 #if defined(STATISTICS)
2543 count_vftbl_len += sizeof(methodptr) *
2544 (ic->methodscount + (ic->methodscount == 0));
2547 for (j = 0; j < ic->methodscount; j++) {
2550 for (m = 0; m < sc->methodscount; m++) {
2551 methodinfo *mi = &(sc->methods[m]);
2552 if (method_canoverwrite(mi, &(ic->methods[j]))) {
2553 v->interfacetable[-i][j] = v->table[mi->vftblindex];
2564 for (j = 0; j < ic->interfacescount; j++)
2565 class_addinterface(c, ic->interfaces[j]);
2569 /******************* Function: class_new_array *********************************
2571 This function is called by class_new to setup an array class.
2573 *******************************************************************************/
2575 void class_new_array(classinfo *c)
2577 classinfo *comp = NULL;
2581 /* Check array class name */
2582 namelen = c->name->blength;
2583 if (namelen < 2 || c->name->text[0] != '[')
2584 panic("Invalid array class name");
2586 /* Check the component type */
2587 switch (c->name->text[1]) {
2589 /* c is an array of arrays. We have to create the component class. */
2591 comp = class_new_intern(utf_new_intern(c->name->text + 1,
2594 list_addfirst(&unlinkedclasses, comp);
2597 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2602 /* c is an array of objects. */
2603 if (namelen < 4 || c->name->text[namelen - 1] != ';')
2604 panic("Invalid array class name");
2607 comp = class_new_intern(utf_new_intern(c->name->text + 2,
2610 list_addfirst(&unlinkedclasses, comp);
2613 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2618 /* Setup the array class */
2619 c->super = class_java_lang_Object;
2620 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2622 c->interfacescount = 2;
2623 c->interfaces = MNEW(classinfo*, 2);
2628 tc = class_new_intern(utf_new_char("java/lang/Cloneable"));
2630 list_addfirst(&unlinkedclasses, tc);
2631 c->interfaces[0] = tc;
2633 tc = class_new_intern(utf_new_char("java/io/Serializable"));
2635 list_addfirst(&unlinkedclasses, tc);
2636 c->interfaces[1] = tc;
2639 c->interfaces[0] = class_new(utf_new_char("java/lang/Cloneable"));
2640 c->interfaces[1] = class_new(utf_new_char("java/io/Serializable"));
2643 c->methodscount = 1;
2644 c->methods = MNEW(methodinfo, c->methodscount);
2647 memset(clone, 0, sizeof(methodinfo));
2648 clone->flags = ACC_PUBLIC;
2649 clone->name = utf_new_char("clone");
2650 clone->descriptor = utf_new_char("()Ljava/lang/Object;");
2652 clone->stubroutine = createnativestub((functionptr) &builtin_clone_array, clone);
2653 clone->monoPoly = MONO;
2655 /* XXX: field: length? */
2657 /* array classes are not loaded from class files */
2662 /****************** Function: class_link_array *********************************
2664 This function is called by class_link to create the
2665 arraydescriptor for an array class.
2667 This function returns NULL if the array cannot be linked because
2668 the component type has not been linked yet.
2670 *******************************************************************************/
2672 static arraydescriptor *class_link_array(classinfo *c)
2674 classinfo *comp = NULL;
2675 s4 namelen = c->name->blength;
2676 arraydescriptor *desc;
2679 /* Check the component type */
2680 switch (c->name->text[1]) {
2682 /* c is an array of arrays. */
2683 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2685 panic("Could not find component array class.");
2689 /* c is an array of objects. */
2690 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2692 panic("Could not find component class.");
2696 /* If the component type has not been linked, link it now */
2697 if (comp && !comp->linked) {
2699 if (!class_load(comp))
2702 if (!class_link(comp))
2706 /* Allocate the arraydescriptor */
2707 desc = NEW(arraydescriptor);
2710 /* c is an array of references */
2711 desc->arraytype = ARRAYTYPE_OBJECT;
2712 desc->componentsize = sizeof(void*);
2713 desc->dataoffset = OFFSET(java_objectarray, data);
2715 compvftbl = comp->vftbl;
2717 panic("Component class has no vftbl");
2718 desc->componentvftbl = compvftbl;
2720 if (compvftbl->arraydesc) {
2721 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
2722 if (compvftbl->arraydesc->dimension >= 255)
2723 panic("Creating array of dimension >255");
2724 desc->dimension = compvftbl->arraydesc->dimension + 1;
2725 desc->elementtype = compvftbl->arraydesc->elementtype;
2728 desc->elementvftbl = compvftbl;
2729 desc->dimension = 1;
2730 desc->elementtype = ARRAYTYPE_OBJECT;
2734 /* c is an array of a primitive type */
2735 switch (c->name->text[1]) {
2737 desc->arraytype = ARRAYTYPE_BOOLEAN;
2738 desc->dataoffset = OFFSET(java_booleanarray,data);
2739 desc->componentsize = sizeof(u1);
2743 desc->arraytype = ARRAYTYPE_BYTE;
2744 desc->dataoffset = OFFSET(java_bytearray,data);
2745 desc->componentsize = sizeof(u1);
2749 desc->arraytype = ARRAYTYPE_CHAR;
2750 desc->dataoffset = OFFSET(java_chararray,data);
2751 desc->componentsize = sizeof(u2);
2755 desc->arraytype = ARRAYTYPE_DOUBLE;
2756 desc->dataoffset = OFFSET(java_doublearray,data);
2757 desc->componentsize = sizeof(double);
2761 desc->arraytype = ARRAYTYPE_FLOAT;
2762 desc->dataoffset = OFFSET(java_floatarray,data);
2763 desc->componentsize = sizeof(float);
2767 desc->arraytype = ARRAYTYPE_INT;
2768 desc->dataoffset = OFFSET(java_intarray,data);
2769 desc->componentsize = sizeof(s4);
2773 desc->arraytype = ARRAYTYPE_LONG;
2774 desc->dataoffset = OFFSET(java_longarray,data);
2775 desc->componentsize = sizeof(s8);
2779 desc->arraytype = ARRAYTYPE_SHORT;
2780 desc->dataoffset = OFFSET(java_shortarray,data);
2781 desc->componentsize = sizeof(s2);
2785 panic("Invalid array class name");
2788 desc->componentvftbl = NULL;
2789 desc->elementvftbl = NULL;
2790 desc->dimension = 1;
2791 desc->elementtype = desc->arraytype;
2798 /********************** Function: class_link ***********************************
2800 Tries to link a class. The function calculates the length in bytes that
2801 an instance of this class requires as well as the VTBL for methods and
2804 *******************************************************************************/
2806 static classinfo *class_link_intern(classinfo *c);
2808 classinfo *class_link(classinfo *c)
2812 /* enter a monitor on the class */
2814 builtin_monitorenter((java_objectheader *) c);
2816 /* maybe the class is already linked */
2818 builtin_monitorexit((java_objectheader *) c);
2825 if (getcompilingtime)
2826 compilingtime_stop();
2829 loadingtime_start();
2831 /* call the internal function */
2832 r = class_link_intern(c);
2834 /* if return value is NULL, we had a problem and the class is not linked */
2843 if (getcompilingtime)
2844 compilingtime_start();
2846 /* leave the monitor */
2848 builtin_monitorexit((java_objectheader *) c);
2854 static classinfo *class_link_intern(classinfo *c)
2856 s4 supervftbllength; /* vftbllegnth of super class */
2857 s4 vftbllength; /* vftbllength of current class */
2858 s4 interfacetablelength; /* interface table length */
2859 classinfo *super; /* super class */
2860 classinfo *tc; /* temporary class variable */
2861 vftbl_t *v; /* vftbl of current class */
2862 s4 i; /* interface/method/field counter */
2863 arraydescriptor *arraydesc; /* descriptor for array classes */
2865 /* maybe the class is already linked */
2869 /* maybe the class is not loaded */
2875 log_message_class("Linking class: ", c);
2877 /* ok, this class is somewhat linked */
2882 /* check interfaces */
2884 for (i = 0; i < c->interfacescount; i++) {
2885 tc = c->interfaces[i];
2887 /* detect circularity */
2890 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2896 if (!class_load(tc))
2899 if (!(tc->flags & ACC_INTERFACE)) {
2901 new_exception_message(string_java_lang_IncompatibleClassChangeError,
2902 "Implementing class");
2907 if (!class_link(tc))
2911 /* check super class */
2915 if (super == NULL) { /* class java.lang.Object */
2917 c->classUsed = USED; /* Object class is always used CO-RT*/
2919 c->instancesize = sizeof(java_objectheader);
2921 vftbllength = supervftbllength = 0;
2923 c->finalizer = NULL;
2926 /* detect circularity */
2929 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2935 if (!class_load(super))
2938 if (super->flags & ACC_INTERFACE) {
2939 /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
2940 panic("Interface specified as super class");
2943 /* Don't allow extending final classes */
2944 if (super->flags & ACC_FINAL) {
2946 new_exception_message(string_java_lang_VerifyError,
2947 "Cannot inherit from final class");
2952 if (!class_link(super))
2955 /* handle array classes */
2956 if (c->name->text[0] == '[')
2957 if (!(arraydesc = class_link_array(c)))
2960 if (c->flags & ACC_INTERFACE)
2961 c->index = interfaceindex++;
2963 c->index = super->index + 1;
2965 c->instancesize = super->instancesize;
2967 vftbllength = supervftbllength = super->vftbl->vftbllength;
2969 c->finalizer = super->finalizer;
2972 /* compute vftbl length */
2974 for (i = 0; i < c->methodscount; i++) {
2975 methodinfo *m = &(c->methods[i]);
2977 if (!(m->flags & ACC_STATIC)) { /* is instance method */
2982 for (j = 0; j < tc->methodscount; j++) {
2983 if (method_canoverwrite(m, &(tc->methods[j]))) {
2984 if (tc->methods[j].flags & ACC_PRIVATE)
2985 goto notfoundvftblindex;
2987 if (tc->methods[j].flags & ACC_FINAL) {
2988 /* class a overrides final method . */
2990 new_exception(string_java_lang_VerifyError);
2993 m->vftblindex = tc->methods[j].vftblindex;
2994 goto foundvftblindex;
3000 m->vftblindex = (vftbllength++);
3006 #if defined(STATISTICS)
3009 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
3012 /* compute interfacetable length */
3014 interfacetablelength = 0;
3017 for (i = 0; i < tc->interfacescount; i++) {
3018 s4 h = class_highestinterface(tc->interfaces[i]) + 1;
3019 if (h > interfacetablelength)
3020 interfacetablelength = h;
3025 /* allocate virtual function table */
3027 v = (vftbl_t*) mem_alloc(sizeof(vftbl_t) + sizeof(methodptr) *
3028 (vftbllength - 1) + sizeof(methodptr*) *
3029 (interfacetablelength - (interfacetablelength > 0)));
3030 v = (vftbl_t*) (((methodptr*) v) + (interfacetablelength - 1) *
3031 (interfacetablelength > 1));
3032 c->header.vftbl = c->vftbl = v;
3034 v->vftbllength = vftbllength;
3035 v->interfacetablelength = interfacetablelength;
3036 v->arraydesc = arraydesc;
3038 /* store interface index in vftbl */
3039 if (c->flags & ACC_INTERFACE)
3040 v->baseval = -(c->index);
3042 /* copy virtual function table of super class */
3044 for (i = 0; i < supervftbllength; i++)
3045 v->table[i] = super->vftbl->table[i];
3047 /* add method stubs into virtual function table */
3049 for (i = 0; i < c->methodscount; i++) {
3050 methodinfo *m = &(c->methods[i]);
3051 if (!(m->flags & ACC_STATIC)) {
3052 v->table[m->vftblindex] = m->stubroutine;
3056 /* compute instance size and offset of each field */
3058 for (i = 0; i < c->fieldscount; i++) {
3060 fieldinfo *f = &(c->fields[i]);
3062 if (!(f->flags & ACC_STATIC)) {
3063 dsize = desc_typesize(f->descriptor);
3064 c->instancesize = ALIGN(c->instancesize, dsize);
3065 f->offset = c->instancesize;
3066 c->instancesize += dsize;
3070 /* initialize interfacetable and interfacevftbllength */
3072 v->interfacevftbllength = MNEW(s4, interfacetablelength);
3074 #if defined(STATISTICS)
3076 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
3079 for (i = 0; i < interfacetablelength; i++) {
3080 v->interfacevftbllength[i] = 0;
3081 v->interfacetable[-i] = NULL;
3084 /* add interfaces */
3086 for (tc = c; tc != NULL; tc = tc->super) {
3087 for (i = 0; i < tc->interfacescount; i++) {
3088 class_addinterface(c, tc->interfaces[i]);
3092 /* add finalizer method (not for java.lang.Object) */
3097 fi = class_findmethod(c, utf_finalize, utf_fidesc);
3100 if (!(fi->flags & ACC_STATIC)) {
3108 loader_compute_subclasses(c);
3111 log_message_class("Linking done class: ", c);
3113 /* just return c to show that we didn't had a problem */
3119 /******************* Function: class_freepool **********************************
3121 Frees all resources used by this classes Constant Pool.
3123 *******************************************************************************/
3125 static void class_freecpool(classinfo *c)
3131 if (c->cptags && c->cpinfos) {
3132 for (idx = 0; idx < c->cpcount; idx++) {
3133 tag = c->cptags[idx];
3134 info = c->cpinfos[idx];
3138 case CONSTANT_Fieldref:
3139 case CONSTANT_Methodref:
3140 case CONSTANT_InterfaceMethodref:
3141 FREE(info, constant_FMIref);
3143 case CONSTANT_Integer:
3144 FREE(info, constant_integer);
3146 case CONSTANT_Float:
3147 FREE(info, constant_float);
3150 FREE(info, constant_long);
3152 case CONSTANT_Double:
3153 FREE(info, constant_double);
3155 case CONSTANT_NameAndType:
3156 FREE(info, constant_nameandtype);
3164 MFREE(c->cptags, u1, c->cpcount);
3167 MFREE(c->cpinfos, voidptr, c->cpcount);
3171 /*********************** Function: class_free **********************************
3173 Frees all resources used by the class.
3175 *******************************************************************************/
3177 void class_free(classinfo *c)
3185 MFREE(c->interfaces, classinfo*, c->interfacescount);
3188 for (i = 0; i < c->fieldscount; i++)
3189 field_free(&(c->fields[i]));
3190 /* MFREE(c->fields, fieldinfo, c->fieldscount); */
3194 for (i = 0; i < c->methodscount; i++)
3195 method_free(&(c->methods[i]));
3196 /* MFREE(c->methods, methodinfo, c->methodscount); */
3199 if ((v = c->vftbl) != NULL) {
3201 mem_free(v->arraydesc,sizeof(arraydescriptor));
3203 for (i = 0; i < v->interfacetablelength; i++) {
3204 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
3206 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
3208 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
3209 sizeof(methodptr*) * (v->interfacetablelength -
3210 (v->interfacetablelength > 0));
3211 v = (vftbl_t*) (((methodptr*) v) - (v->interfacetablelength - 1) *
3212 (v->interfacetablelength > 1));
3217 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
3219 /* if (c->classvftbl)
3220 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
3226 /************************* Function: class_findfield ***************************
3228 Searches a 'classinfo' structure for a field having the given name and
3231 *******************************************************************************/
3233 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
3237 for (i = 0; i < c->fieldscount; i++) {
3238 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
3239 return &(c->fields[i]);
3242 panic("Can not find field given in CONSTANT_Fieldref");
3244 /* keep compiler happy */
3249 /****************** Function: class_resolvefield_int ***************************
3251 This is an internally used helper function. Do not use this directly.
3253 Tries to resolve a field having the given name and type.
3254 If the field cannot be resolved, NULL is returned.
3256 *******************************************************************************/
3258 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
3263 /* search for field in class c */
3264 for (i = 0; i < c->fieldscount; i++) {
3265 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
3266 return &(c->fields[i]);
3270 /* try superinterfaces recursively */
3271 for (i = 0; i < c->interfacescount; ++i) {
3272 fi = class_resolvefield_int(c->interfaces[i], name, desc);
3277 /* try superclass */
3279 return class_resolvefield_int(c->super, name, desc);
3286 /********************* Function: class_resolvefield ***************************
3288 Resolves a reference from REFERER to a field with NAME and DESC in class C.
3290 If the field cannot be resolved the return value is NULL. If EXCEPT is
3291 true *exceptionptr is set, too.
3293 *******************************************************************************/
3295 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
3296 classinfo *referer, bool except)
3300 /* XXX resolve class c */
3301 /* XXX check access from REFERER to C */
3303 fi = class_resolvefield_int(c, name, desc);
3308 new_exception_utfmessage(string_java_lang_NoSuchFieldError,
3314 /* XXX check access rights */
3320 /************************* Function: class_findmethod **************************
3322 Searches a 'classinfo' structure for a method having the given name and
3323 type and returns the index in the class info structure.
3324 If type is NULL, it is ignored.
3326 *******************************************************************************/
3328 s4 class_findmethodIndex(classinfo *c, utf *name, utf *desc)
3332 for (i = 0; i < c->methodscount; i++) {
3334 /* utf_display_classname(c->name);printf("."); */
3335 /* utf_display(c->methods[i].name);printf("."); */
3336 /* utf_display(c->methods[i].descriptor); */
3339 if ((c->methods[i].name == name) && ((desc == NULL) ||
3340 (c->methods[i].descriptor == desc))) {
3349 /************************* Function: class_findmethod **************************
3351 Searches a 'classinfo' structure for a method having the given name and
3353 If type is NULL, it is ignored.
3355 *******************************************************************************/
3357 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
3359 s4 idx = class_findmethodIndex(c, name, desc);
3364 return &(c->methods[idx]);
3368 /*********************** Function: class_fetchmethod **************************
3370 like class_findmethod, but aborts with an error if the method is not found
3372 *******************************************************************************/
3374 methodinfo *class_fetchmethod(classinfo *c, utf *name, utf *desc)
3378 mi = class_findmethod(c, name, desc);
3381 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3382 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3383 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3384 panic("Method not found");
3391 /*********************** Function: class_findmethod_w**************************
3393 like class_findmethod, but logs a warning if the method is not found
3395 *******************************************************************************/
3397 methodinfo *class_findmethod_w(classinfo *c, utf *name, utf *desc, char *from)
3400 mi = class_findmethod(c, name, desc);
3403 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3404 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3405 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3407 if ( c->flags & ACC_PUBLIC ) log_plain(" PUBLIC ");
3408 if ( c->flags & ACC_PRIVATE ) log_plain(" PRIVATE ");
3409 if ( c->flags & ACC_PROTECTED ) log_plain(" PROTECTED ");
3410 if ( c->flags & ACC_STATIC ) log_plain(" STATIC ");
3411 if ( c->flags & ACC_FINAL ) log_plain(" FINAL ");
3412 if ( c->flags & ACC_SYNCHRONIZED ) log_plain(" SYNCHRONIZED ");
3413 if ( c->flags & ACC_VOLATILE ) log_plain(" VOLATILE ");
3414 if ( c->flags & ACC_TRANSIENT ) log_plain(" TRANSIENT ");
3415 if ( c->flags & ACC_NATIVE ) log_plain(" NATIVE ");
3416 if ( c->flags & ACC_INTERFACE ) log_plain(" INTERFACE ");
3417 if ( c->flags & ACC_ABSTRACT ) log_plain(" ABSTRACT ");
3420 log_plain(" : WARNING: Method not found");log_nl( );
3427 /************************* Function: class_findmethod_approx ******************
3429 like class_findmethod but ignores the return value when comparing the
3432 *******************************************************************************/
3434 methodinfo *class_findmethod_approx(classinfo *c, utf *name, utf *desc)
3438 for (i = 0; i < c->methodscount; i++) {
3439 if (c->methods[i].name == name) {
3440 utf *meth_descr = c->methods[i].descriptor;
3444 return &(c->methods[i]);
3446 if (desc->blength <= meth_descr->blength) {
3447 /* current position in utf text */
3448 char *desc_utf_ptr = desc->text;
3449 char *meth_utf_ptr = meth_descr->text;
3450 /* points behind utf strings */
3451 char *desc_end = utf_end(desc);
3452 char *meth_end = utf_end(meth_descr);
3455 /* compare argument types */
3456 while (desc_utf_ptr < desc_end && meth_utf_ptr < meth_end) {
3458 if ((ch = *desc_utf_ptr++) != (*meth_utf_ptr++))
3459 break; /* no match */
3462 return &(c->methods[i]); /* all parameter types equal */
3472 /***************** Function: class_resolvemethod_approx ***********************
3474 Searches a class and every super class for a method (without paying
3475 attention to the return value)
3477 *******************************************************************************/
3479 methodinfo *class_resolvemethod_approx(classinfo *c, utf *name, utf *desc)
3482 /* search for method (ignore returntype) */
3483 methodinfo *m = class_findmethod_approx(c, name, desc);
3486 /* search superclass */
3494 /************************* Function: class_resolvemethod ***********************
3496 Searches a class and every super class for a method.
3498 *******************************************************************************/
3500 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
3502 /*log_text("Trying to resolve a method");
3503 utf_display(c->name);
3505 utf_display(desc);*/
3508 /*log_text("Looking in:");
3509 utf_display(c->name);*/
3510 methodinfo *m = class_findmethod(c, name, desc);
3512 /* search superclass */
3515 /*log_text("method not found:");*/
3521 /****************** Function: class_resolveinterfacemethod_int ****************
3523 Internally used helper function. Do not use this directly.
3525 *******************************************************************************/
3528 methodinfo *class_resolveinterfacemethod_int(classinfo *c, utf *name, utf *desc)
3533 mi = class_findmethod(c,name,desc);
3537 /* try the superinterfaces */
3538 for (i=0; i<c->interfacescount; ++i) {
3539 mi = class_resolveinterfacemethod_int(c->interfaces[i],name,desc);
3547 /******************** Function: class_resolveinterfacemethod ******************
3549 Resolves a reference from REFERER to a method with NAME and DESC in
3552 If the method cannot be resolved the return value is NULL. If EXCEPT is
3553 true *exceptionptr is set, too.
3555 *******************************************************************************/
3557 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
3558 classinfo *referer, bool except)
3562 /* XXX resolve class c */
3563 /* XXX check access from REFERER to C */
3565 if (!(c->flags & ACC_INTERFACE)) {
3568 new_exception(string_java_lang_IncompatibleClassChangeError);
3573 mi = class_resolveinterfacemethod_int(c, name, desc);
3578 /* try class java.lang.Object */
3579 mi = class_findmethod(class_java_lang_Object, name, desc);
3586 new_exception_utfmessage(string_java_lang_NoSuchMethodError, name);
3592 /********************* Function: class_resolveclassmethod *********************
3594 Resolves a reference from REFERER to a method with NAME and DESC in
3597 If the method cannot be resolved the return value is NULL. If EXCEPT is
3598 true *exceptionptr is set, too.
3600 *******************************************************************************/
3602 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
3603 classinfo *referer, bool except)
3608 char msg[MAXLOGTEXT];
3610 /* XXX resolve class c */
3611 /* XXX check access from REFERER to C */
3613 /* if (c->flags & ACC_INTERFACE) { */
3615 /* *exceptionptr = */
3616 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
3620 /* try class c and its superclasses */
3623 mi = class_findmethod(cls, name, desc);
3626 } while ((cls = cls->super) != NULL); /* try the superclass */
3628 /* try the superinterfaces */
3629 for (i = 0; i < c->interfacescount; ++i) {
3630 mi = class_resolveinterfacemethod_int(c->interfaces[i], name, desc);
3636 utf_sprint(msg, c->name);
3637 sprintf(msg + strlen(msg), ".");
3638 utf_sprint(msg + strlen(msg), name);
3639 utf_sprint(msg + strlen(msg), desc);
3642 new_exception_message(string_java_lang_NoSuchMethodError, msg);
3648 if ((mi->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
3650 *exceptionptr = new_exception(string_java_lang_AbstractMethodError);
3655 /* XXX check access rights */
3661 /************************* Function: class_issubclass **************************
3663 Checks if sub is a descendant of super.
3665 *******************************************************************************/
3667 bool class_issubclass(classinfo *sub, classinfo *super)
3670 if (!sub) return false;
3671 if (sub == super) return true;
3677 /****************** Initialization function for classes ******************
3679 In Java, every class can have a static initialization function. This
3680 function has to be called BEFORE calling other methods or accessing static
3683 *******************************************************************************/
3685 static classinfo *class_init_intern(classinfo *c);
3687 classinfo *class_init(classinfo *c)
3691 if (!makeinitializations)
3694 /* enter a monitor on the class */
3696 builtin_monitorenter((java_objectheader *) c);
3698 /* maybe the class is already initalized or the current thread, which can
3699 pass the monitor, is currently initalizing this class */
3701 if (c->initialized || c->initializing) {
3702 builtin_monitorexit((java_objectheader *) c);
3707 /* this initalizing run begins NOW */
3708 c->initializing = true;
3710 /* call the internal function */
3711 r = class_init_intern(c);
3713 /* if return value is not NULL everything was ok and the class is
3716 c->initialized = true;
3718 /* this initalizing run is done */
3719 c->initializing = false;
3721 /* leave the monitor */
3723 builtin_monitorexit((java_objectheader *) c);
3729 /* this function MUST NOT be called directly, because of thread <clinit>
3732 static classinfo *class_init_intern(classinfo *c)
3736 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3740 /* maybe the class is not already loaded */
3745 /* maybe the class is not already linked */
3750 #if defined(STATISTICS)
3752 count_class_inits++;
3755 /* initialize super class */
3758 if (!c->super->initialized) {
3760 char logtext[MAXLOGTEXT];
3761 sprintf(logtext, "Initialize super class ");
3762 utf_sprint_classname(logtext + strlen(logtext), c->super->name);
3763 sprintf(logtext + strlen(logtext), " from ");
3764 utf_sprint_classname(logtext + strlen(logtext), c->name);
3768 if (!class_init(c->super))
3773 /* initialize interface classes */
3775 for (i = 0; i < c->interfacescount; i++) {
3776 if (!c->interfaces[i]->initialized) {
3778 char logtext[MAXLOGTEXT];
3779 sprintf(logtext, "Initialize interface class ");
3780 utf_sprint_classname(logtext + strlen(logtext), c->interfaces[i]->name);
3781 sprintf(logtext + strlen(logtext), " from ");
3782 utf_sprint_classname(logtext + strlen(logtext), c->name);
3786 if (!class_init(c->interfaces[i]))
3791 m = class_findmethod(c, utf_clinit, utf_fidesc);
3795 char logtext[MAXLOGTEXT];
3796 sprintf(logtext, "Class ");
3797 utf_sprint_classname(logtext + strlen(logtext), c->name);
3798 sprintf(logtext + strlen(logtext), " has no static class initializer");
3805 /* Sun's and IBM's JVM don't care about the static flag */
3806 /* if (!(m->flags & ACC_STATIC)) { */
3807 /* panic("Class initializer is not static!"); */
3810 log_message_class("Starting static class initializer for class: ", c);
3812 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3817 /* now call the initializer */
3818 asm_calljavafunction(m, NULL, NULL, NULL, NULL);
3820 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3821 assert(blockInts == 0);
3825 /* we have an exception or error */
3826 if (*exceptionptr) {
3827 /* class is NOT initialized */
3828 c->initialized = false;
3830 /* is this an exception, than wrap it */
3831 if (builtin_instanceof(*exceptionptr, class_java_lang_Exception)) {
3832 java_objectheader *xptr;
3833 java_objectheader *cause;
3836 cause = *exceptionptr;
3838 /* clear exception, because we are calling jit code again */
3839 *exceptionptr = NULL;
3841 /* wrap the exception */
3843 new_exception_throwable(string_java_lang_ExceptionInInitializerError,
3844 (java_lang_Throwable *) cause);
3846 /* XXX should we exit here? */
3850 /* set new exception */
3851 *exceptionptr = xptr;
3858 log_message_class("Finished static class initializer for class: ", c);
3864 /********* Function: find_class_method_constant *********/
3866 int find_class_method_constant (classinfo *c, utf * c1, utf* m1, utf* d1)
3871 for (i=0; i<c->cpcount; i++) {
3873 e = c -> cpinfos [i];
3876 switch (c -> cptags [i]) {
3877 case CONSTANT_Methodref:
3879 constant_FMIref *fmi = e;
3880 if ( (fmi->class->name == c1)
3881 && (fmi->name == m1)
3882 && (fmi->descriptor == d1)) {
3889 case CONSTANT_InterfaceMethodref:
3891 constant_FMIref *fmi = e;
3892 if ( (fmi->class->name == c1)
3893 && (fmi->name == m1)
3894 && (fmi->descriptor == d1)) {
3908 void class_showconstanti(classinfo *c, int ii)
3914 printf ("#%d: ", (int) i);
3916 switch (c->cptags [i]) {
3917 case CONSTANT_Class:
3918 printf("Classreference -> ");
3919 utf_display(((classinfo*)e)->name);
3922 case CONSTANT_Fieldref:
3923 printf("Fieldref -> "); goto displayFMIi;
3924 case CONSTANT_Methodref:
3925 printf("Methodref -> "); goto displayFMIi;
3926 case CONSTANT_InterfaceMethodref:
3927 printf("InterfaceMethod -> "); goto displayFMIi;
3930 constant_FMIref *fmi = e;
3931 utf_display(fmi->class->name);
3933 utf_display(fmi->name);
3935 utf_display(fmi->descriptor);
3939 case CONSTANT_String:
3940 printf("String -> ");
3943 case CONSTANT_Integer:
3944 printf("Integer -> %d", (int) (((constant_integer*)e)->value));
3946 case CONSTANT_Float:
3947 printf("Float -> %f", ((constant_float*)e)->value);
3949 case CONSTANT_Double:
3950 printf("Double -> %f", ((constant_double*)e)->value);
3954 u8 v = ((constant_long*)e)->value;
3956 printf("Long -> %ld", (long int) v);
3958 printf("Long -> HI: %ld, LO: %ld\n",
3959 (long int) v.high, (long int) v.low);
3963 case CONSTANT_NameAndType:
3965 constant_nameandtype *cnt = e;
3966 printf("NameAndType: ");
3967 utf_display(cnt->name);
3969 utf_display(cnt->descriptor);
3977 panic("Invalid type of ConstantPool-Entry");
3984 void class_showconstantpool (classinfo *c)
3989 printf ("---- dump of constant pool ----\n");
3991 for (i=0; i<c->cpcount; i++) {
3992 printf ("#%d: ", (int) i);
3994 e = c -> cpinfos [i];
3997 switch (c -> cptags [i]) {
3998 case CONSTANT_Class:
3999 printf ("Classreference -> ");
4000 utf_display ( ((classinfo*)e) -> name );
4003 case CONSTANT_Fieldref:
4004 printf ("Fieldref -> "); goto displayFMI;
4005 case CONSTANT_Methodref:
4006 printf ("Methodref -> "); goto displayFMI;
4007 case CONSTANT_InterfaceMethodref:
4008 printf ("InterfaceMethod -> "); goto displayFMI;
4011 constant_FMIref *fmi = e;
4012 utf_display ( fmi->class->name );
4014 utf_display ( fmi->name);
4016 utf_display ( fmi->descriptor );
4020 case CONSTANT_String:
4021 printf ("String -> ");
4024 case CONSTANT_Integer:
4025 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
4027 case CONSTANT_Float:
4028 printf ("Float -> %f", ((constant_float*)e) -> value);
4030 case CONSTANT_Double:
4031 printf ("Double -> %f", ((constant_double*)e) -> value);
4035 u8 v = ((constant_long*)e) -> value;
4037 printf ("Long -> %ld", (long int) v);
4039 printf ("Long -> HI: %ld, LO: %ld\n",
4040 (long int) v.high, (long int) v.low);
4044 case CONSTANT_NameAndType:
4046 constant_nameandtype *cnt = e;
4047 printf ("NameAndType: ");
4048 utf_display (cnt->name);
4050 utf_display (cnt->descriptor);
4054 printf ("Utf8 -> ");
4058 panic ("Invalid type of ConstantPool-Entry");
4068 /********** Function: class_showmethods (debugging only) *************/
4070 void class_showmethods (classinfo *c)
4074 printf ("--------- Fields and Methods ----------------\n");
4075 printf ("Flags: "); printflags (c->flags); printf ("\n");
4077 printf ("This: "); utf_display (c->name); printf ("\n");
4079 printf ("Super: "); utf_display (c->super->name); printf ("\n");
4081 printf ("Index: %d\n", c->index);
4083 printf ("interfaces:\n");
4084 for (i=0; i < c-> interfacescount; i++) {
4086 utf_display (c -> interfaces[i] -> name);
4087 printf (" (%d)\n", c->interfaces[i] -> index);
4090 printf ("fields:\n");
4091 for (i=0; i < c -> fieldscount; i++) {
4092 field_display (&(c -> fields[i]));
4095 printf ("methods:\n");
4096 for (i=0; i < c -> methodscount; i++) {
4097 methodinfo *m = &(c->methods[i]);
4098 if ( !(m->flags & ACC_STATIC))
4099 printf ("vftblindex: %d ", m->vftblindex);
4101 method_display ( m );
4105 printf ("Virtual function table:\n");
4106 for (i=0; i<c->vftbl->vftbllength; i++) {
4107 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]) );
4113 /******************************************************************************/
4114 /******************* General functions for the class loader *******************/
4115 /******************************************************************************/
4117 /**************** function: create_primitive_classes ***************************
4119 create classes representing primitive types
4121 *******************************************************************************/
4123 static bool create_primitive_classes()
4127 for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
4128 /* create primitive class */
4130 class_new_intern(utf_new_char(primitivetype_table[i].name));
4131 c->classUsed = NOTUSED; /* not used initially CO-RT */
4134 /* prevent loader from loading primitive class */
4139 primitivetype_table[i].class_primitive = c;
4141 /* create class for wrapping the primitive type */
4142 c = class_new_intern(utf_new_char(primitivetype_table[i].wrapname));
4143 primitivetype_table[i].class_wrap = c;
4144 primitivetype_table[i].class_wrap->classUsed = NOTUSED; /* not used initially CO-RT */
4145 primitivetype_table[i].class_wrap->impldBy = NULL;
4147 /* create the primitive array class */
4148 if (primitivetype_table[i].arrayname) {
4149 c = class_new_intern(utf_new_char(primitivetype_table[i].arrayname));
4150 primitivetype_table[i].arrayclass = c;
4155 primitivetype_table[i].arrayvftbl = c->vftbl;
4163 /**************** function: class_primitive_from_sig ***************************
4165 return the primitive class indicated by the given signature character
4167 If the descriptor does not indicate a valid primitive type the
4168 return value is NULL.
4170 ********************************************************************************/
4172 classinfo *class_primitive_from_sig(char sig)
4175 case 'I': return primitivetype_table[PRIMITIVETYPE_INT].class_primitive;
4176 case 'J': return primitivetype_table[PRIMITIVETYPE_LONG].class_primitive;
4177 case 'F': return primitivetype_table[PRIMITIVETYPE_FLOAT].class_primitive;
4178 case 'D': return primitivetype_table[PRIMITIVETYPE_DOUBLE].class_primitive;
4179 case 'B': return primitivetype_table[PRIMITIVETYPE_BYTE].class_primitive;
4180 case 'C': return primitivetype_table[PRIMITIVETYPE_CHAR].class_primitive;
4181 case 'S': return primitivetype_table[PRIMITIVETYPE_SHORT].class_primitive;
4182 case 'Z': return primitivetype_table[PRIMITIVETYPE_BOOLEAN].class_primitive;
4183 case 'V': return primitivetype_table[PRIMITIVETYPE_VOID].class_primitive;
4188 /****************** function: class_from_descriptor ****************************
4190 return the class indicated by the given descriptor
4192 utf_ptr....first character of descriptor
4193 end_ptr....first character after the end of the string
4194 next.......if non-NULL, *next is set to the first character after
4195 the descriptor. (Undefined if an error occurs.)
4197 mode.......a combination (binary or) of the following flags:
4199 (Flags marked with * are the default settings.)
4201 What to do if a reference type descriptor is parsed successfully:
4203 CLASSLOAD_SKIP...skip it and return something != NULL
4204 * CLASSLOAD_NEW....get classinfo * via class_new
4205 CLASSLOAD_LOAD...get classinfo * via loader_load
4207 How to handle primitive types:
4209 * CLASSLOAD_PRIMITIVE.......return primitive class (eg. "int")
4210 CLASSLOAD_NULLPRIMITIVE...return NULL for primitive types
4212 How to handle "V" descriptors:
4214 * CLASSLOAD_VOID.....handle it like other primitive types
4215 CLASSLOAD_NOVOID...treat it as an error
4217 How to deal with extra characters after the end of the
4220 * CLASSLOAD_NOCHECKEND...ignore (useful for parameter lists)
4221 CLASSLOAD_CHECKEND.....treat them as an error
4223 How to deal with errors:
4225 * CLASSLOAD_PANIC....abort execution with an error message
4226 CLASSLOAD_NOPANIC..return NULL on error
4228 *******************************************************************************/
4230 classinfo *class_from_descriptor(char *utf_ptr, char *end_ptr,
4231 char **next, int mode)
4233 char *start = utf_ptr;
4237 SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr, end_ptr, error);
4239 if (mode & CLASSLOAD_CHECKEND)
4240 error |= (utf_ptr != end_ptr);
4243 if (next) *next = utf_ptr;
4247 if (mode & CLASSLOAD_NOVOID)
4258 return (mode & CLASSLOAD_NULLPRIMITIVE)
4260 : class_primitive_from_sig(*start);
4267 if (mode & CLASSLOAD_SKIP) return class_java_lang_Object;
4268 name = utf_new(start, utf_ptr - start);
4272 tc = class_new_intern(name);
4274 list_addfirst(&unlinkedclasses, tc);
4279 return (mode & CLASSLOAD_LOAD)
4280 ? class_load(class_new(name)) : class_new(name); /* XXX handle errors */
4285 /* An error occurred */
4286 if (mode & CLASSLOAD_NOPANIC)
4289 log_plain("Invalid descriptor at beginning of '");
4290 log_plain_utf(utf_new(start, end_ptr - start));
4294 panic("Invalid descriptor");
4296 /* keep compiler happy */
4301 /******************* function: type_from_descriptor ****************************
4303 return the basic type indicated by the given descriptor
4305 This function parses a descriptor and returns its basic type as
4306 TYPE_INT, TYPE_LONG, TYPE_FLOAT, TYPE_DOUBLE, TYPE_ADDRESS or TYPE_VOID.
4308 cls...if non-NULL the referenced variable is set to the classinfo *
4309 returned by class_from_descriptor.
4311 For documentation of the arguments utf_ptr, end_ptr, next and mode
4312 see class_from_descriptor. The only difference is that
4313 type_from_descriptor always uses CLASSLOAD_PANIC.
4315 ********************************************************************************/
4317 int type_from_descriptor(classinfo **cls, char *utf_ptr, char *end_ptr,
4318 char **next, int mode)
4321 if (!cls) cls = &mycls;
4322 *cls = class_from_descriptor(utf_ptr, end_ptr, next, mode & (~CLASSLOAD_NOPANIC));
4339 return TYPE_ADDRESS;
4343 /*************** function: create_pseudo_classes *******************************
4345 create pseudo classes used by the typechecker
4347 ********************************************************************************/
4349 static void create_pseudo_classes()
4351 /* pseudo class for Arraystubs (extends java.lang.Object) */
4353 pseudo_class_Arraystub = class_new_intern(utf_new_char("$ARRAYSTUB$"));
4354 pseudo_class_Arraystub->loaded = true;
4355 pseudo_class_Arraystub->super = class_java_lang_Object;
4356 pseudo_class_Arraystub->interfacescount = 2;
4357 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
4358 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
4359 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
4361 class_link(pseudo_class_Arraystub);
4363 pseudo_class_Arraystub_vftbl = pseudo_class_Arraystub->vftbl;
4365 /* pseudo class representing the null type */
4367 pseudo_class_Null = class_new_intern(utf_new_char("$NULL$"));
4368 pseudo_class_Null->loaded = true;
4369 pseudo_class_Null->super = class_java_lang_Object;
4370 class_link(pseudo_class_Null);
4372 /* pseudo class representing new uninitialized objects */
4374 pseudo_class_New = class_new_intern(utf_new_char("$NEW$"));
4375 pseudo_class_New->loaded = true;
4376 pseudo_class_New->linked = true;
4377 pseudo_class_New->super = class_java_lang_Object;
4378 /* class_link(pseudo_class_New); */
4382 /********************** Function: loader_init **********************************
4384 Initializes all lists and loads all classes required for the system or the
4387 *******************************************************************************/
4389 void loader_init(u1 *stackbottom)
4393 /* create utf-symbols for pointer comparison of frequently used strings */
4394 utf_innerclasses = utf_new_char("InnerClasses");
4395 utf_constantvalue = utf_new_char("ConstantValue");
4396 utf_code = utf_new_char("Code");
4397 utf_exceptions = utf_new_char("Exceptions");
4398 utf_linenumbertable = utf_new_char("LineNumberTable");
4399 utf_sourcefile = utf_new_char("SourceFile");
4400 utf_finalize = utf_new_char("finalize");
4401 utf_fidesc = utf_new_char("()V");
4402 utf_init = utf_new_char("<init>");
4403 utf_clinit = utf_new_char("<clinit>");
4404 utf_initsystemclass = utf_new_char("initializeSystemClass");
4405 utf_systemclass = utf_new_char("java/lang/System");
4406 utf_vmclassloader = utf_new_char("java/lang/VMClassLoader");
4407 utf_initialize = utf_new_char("initialize");
4408 utf_initializedesc = utf_new_char("(I)V");
4409 utf_vmclass = utf_new_char("java/lang/VMClass");
4410 utf_java_lang_Object= utf_new_char("java/lang/Object");
4411 array_packagename = utf_new_char("<the array package>");
4412 utf_fillInStackTrace_name = utf_new_char("fillInStackTrace");
4413 utf_fillInStackTrace_desc = utf_new_char("()Ljava/lang/Throwable;");
4415 /* create some important classes */
4416 /* These classes have to be created now because the classinfo
4417 * pointers are used in the loading code.
4419 class_java_lang_Object = class_new_intern(utf_java_lang_Object);
4420 class_load(class_java_lang_Object);
4421 class_link(class_java_lang_Object);
4423 class_java_lang_String = class_new(utf_new_char("java/lang/String"));
4424 class_load(class_java_lang_String);
4425 class_link(class_java_lang_String);
4427 class_java_lang_Cloneable = class_new(utf_new_char("java/lang/Cloneable"));
4428 class_load(class_java_lang_Cloneable);
4429 class_link(class_java_lang_Cloneable);
4431 class_java_io_Serializable =
4432 class_new(utf_new_char("java/io/Serializable"));
4433 class_load(class_java_io_Serializable);
4434 class_link(class_java_io_Serializable);
4436 /* create classes representing primitive types */
4437 create_primitive_classes();
4439 /* create classes used by the typechecker */
4440 create_pseudo_classes();
4442 /* correct vftbl-entries (retarded loading of class java/lang/String) */
4443 stringtable_update();
4445 #if defined(USE_THREADS)
4446 if (stackbottom != 0)
4452 /* loader_compute_subclasses ***************************************************
4456 *******************************************************************************/
4458 static void loader_compute_class_values(classinfo *c);
4460 void loader_compute_subclasses(classinfo *c)
4462 #if defined(USE_THREADS)
4463 #if defined(NATIVE_THREADS)
4470 if (!(c->flags & ACC_INTERFACE)) {
4475 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
4476 c->nextsub = c->super->sub;
4482 /* this is the java.lang.Object special case */
4484 if (!class_java_lang_Object) {
4485 loader_compute_class_values(c);
4488 loader_compute_class_values(class_java_lang_Object);
4491 #if defined(USE_THREADS)
4492 #if defined(NATIVE_THREADS)
4501 /* loader_compute_class_values *************************************************
4505 *******************************************************************************/
4507 static void loader_compute_class_values(classinfo *c)
4511 c->vftbl->baseval = ++classvalue;
4515 loader_compute_class_values(subs);
4516 subs = subs->nextsub;
4519 c->vftbl->diffval = classvalue - c->vftbl->baseval;
4523 /******************** Function: loader_close ***********************************
4527 *******************************************************************************/
4534 for (slot = 0; slot < class_hash.size; slot++) {
4535 c = class_hash.ptr[slot];
4546 * These are local overrides for various environment variables in Emacs.
4547 * Please do not remove this and leave it at the end of the file, where
4548 * Emacs will automagically detect them.
4549 * ---------------------------------------------------------------------
4552 * indent-tabs-mode: t