1 /* vm/loader.c - class loader functions
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Reinhard Grafl
29 Changes: Andreas Krall
35 $Id: loader.c 1898 2005-02-07 17:21:30Z twisti $
45 #include "mm/memory.h"
46 #include "native/native.h"
47 #include "native/include/java_lang_Throwable.h"
49 #if defined(USE_THREADS)
50 # if defined(NATIVE_THREADS)
51 # include "threads/native/threads.h"
53 # include "threads/green/threads.h"
54 # include "threads/green/locks.h"
58 #include "toolbox/logging.h"
59 #include "vm/exceptions.h"
60 #include "vm/builtin.h"
61 #include "vm/global.h"
62 #include "vm/loader.h"
63 #include "vm/options.h"
64 #include "vm/statistics.h"
65 #include "vm/tables.h"
68 # include "vm/unzip.h"
71 #include "vm/jit/asmpart.h"
72 #include "vm/jit/jit.h"
79 /* global variables ***********************************************************/
81 static s4 interfaceindex; /* sequential numbering of interfaces */
85 /* utf-symbols for pointer comparison of frequently used strings */
87 static utf *utf_innerclasses; /* InnerClasses */
88 static utf *utf_constantvalue; /* ConstantValue */
89 static utf *utf_code; /* Code */
90 static utf *utf_exceptions; /* Exceptions */
91 static utf *utf_linenumbertable; /* LineNumberTable */
92 static utf *utf_sourcefile; /* SourceFile */
93 static utf *utf_finalize; /* finalize */
94 static utf *utf_fidesc; /* ()V changed */
95 static utf *utf_init; /* <init> */
96 static utf *utf_clinit; /* <clinit> */
97 static utf *utf_initsystemclass; /* initializeSystemClass */
98 static utf *utf_systemclass; /* java/lang/System */
99 static utf *utf_vmclassloader; /* java/lang/VMClassLoader */
100 static utf *utf_vmclass; /* java/lang/VMClassLoader */
101 static utf *utf_initialize;
102 static utf *utf_initializedesc;
103 static utf *utf_java_lang_Object; /* java/lang/Object */
105 utf *utf_fillInStackTrace_name;
106 utf *utf_fillInStackTrace_desc;
116 /* important system classes ***************************************************/
118 classinfo *class_java_lang_Object;
119 classinfo *class_java_lang_String;
120 classinfo *class_java_lang_Cloneable;
121 classinfo *class_java_io_Serializable;
123 /* Pseudo classes for the typechecker */
124 classinfo *pseudo_class_Arraystub = NULL;
125 classinfo *pseudo_class_Null = NULL;
126 classinfo *pseudo_class_New = NULL;
127 vftbl_t *pseudo_class_Arraystub_vftbl = NULL;
129 utf *array_packagename = NULL;
132 /********************************************************************
133 list of classpath entries (either filesystem directories or
135 ********************************************************************/
137 static classpath_info *classpath_entries = NULL;
140 /******************************************************************************
142 structure for primitive classes: contains the class for wrapping the
143 primitive type, the primitive class, the name of the class for wrapping,
144 the one character type signature and the name of the primitive class
146 ******************************************************************************/
148 /* CAUTION: Don't change the order of the types. This table is indexed
149 * by the ARRAYTYPE_ constants (expcept ARRAYTYPE_OBJECT).
151 primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = {
152 { NULL, NULL, "java/lang/Integer", 'I', "int" , "[I", NULL, NULL },
153 { NULL, NULL, "java/lang/Long", 'J', "long" , "[J", NULL, NULL },
154 { NULL, NULL, "java/lang/Float", 'F', "float" , "[F", NULL, NULL },
155 { NULL, NULL, "java/lang/Double", 'D', "double" , "[D", NULL, NULL },
156 { NULL, NULL, "java/lang/Byte", 'B', "byte" , "[B", NULL, NULL },
157 { NULL, NULL, "java/lang/Character", 'C', "char" , "[C", NULL, NULL },
158 { NULL, NULL, "java/lang/Short", 'S', "short" , "[S", NULL, NULL },
159 { NULL, NULL, "java/lang/Boolean", 'Z', "boolean" , "[Z", NULL, NULL },
160 { NULL, NULL, "java/lang/Void", 'V', "void" , NULL, NULL, NULL }
164 /************* functions for reading classdata *********************************
166 getting classdata in blocks of variable size
167 (8,16,32,64-bit integer or float)
169 *******************************************************************************/
171 /* check_classbuffer_size ******************************************************
173 assert that at least <len> bytes are left to read
174 <len> is limited to the range of non-negative s4 values
176 *******************************************************************************/
178 static inline bool check_classbuffer_size(classbuffer *cb, s4 len)
180 if (len < 0 || ((cb->data + cb->size) - cb->pos - 1) < len) {
182 new_classformaterror((cb)->class, "Truncated class file");
191 /* suck_nbytes *****************************************************************
193 transfer block of classfile data into a buffer
195 *******************************************************************************/
197 inline void suck_nbytes(u1 *buffer, classbuffer *cb, s4 len)
199 memcpy(buffer, cb->pos + 1, len);
204 /* skip_nbytes ****************************************************************
206 skip block of classfile data
208 *******************************************************************************/
210 inline void skip_nbytes(classbuffer *cb, s4 len)
216 inline u1 suck_u1(classbuffer *cb)
222 inline u2 suck_u2(classbuffer *cb)
226 return ((u2) a << 8) + (u2) b;
230 inline u4 suck_u4(classbuffer *cb)
236 return ((u4) a << 24) + ((u4) b << 16) + ((u4) c << 8) + (u4) d;
240 /* get u8 from classfile data */
241 static u8 suck_u8(classbuffer *cb)
247 return (hi << 32) + lo;
250 v.high = suck_u4(cb);
257 #define suck_s8(a) (s8) suck_u8((a))
258 #define suck_s2(a) (s2) suck_u2((a))
259 #define suck_s4(a) (s4) suck_u4((a))
260 #define suck_s1(a) (s1) suck_u1((a))
263 /* get float from classfile data */
264 static float suck_float(classbuffer *cb)
272 for (i = 0; i < 4; i++)
273 buffer[3 - i] = suck_u1(cb);
275 memcpy((u1*) (&f), buffer, 4);
277 suck_nbytes((u1*) (&f), cb, 4);
280 if (sizeof(float) != 4) {
281 *exceptionptr = new_exception_message(string_java_lang_InternalError,
282 "Incompatible float-format");
284 /* XXX should we exit in such a case? */
285 throw_exception_exit();
292 /* get double from classfile data */
293 static double suck_double(classbuffer *cb)
301 for (i = 0; i < 8; i++)
302 buffer[7 - i] = suck_u1(cb);
304 memcpy((u1*) (&d), buffer, 8);
306 suck_nbytes((u1*) (&d), cb, 8);
309 if (sizeof(double) != 8) {
310 *exceptionptr = new_exception_message(string_java_lang_InternalError,
311 "Incompatible double-format");
313 /* XXX should we exit in such a case? */
314 throw_exception_exit();
321 /************************** function suck_init *********************************
323 called once at startup, sets the searchpath for the classfiles
325 *******************************************************************************/
327 void suck_init(char *classpath)
335 classpath_info *lastcpi;
337 /* search for last classpath entry (only if there already some) */
339 if ((lastcpi = classpath_entries)) {
340 while (lastcpi->next)
341 lastcpi = lastcpi->next;
344 for (start = classpath; (*start) != '\0';) {
346 /* search for ':' delimiter to get the end of the current entry */
347 for (end = start; ((*end) != '\0') && ((*end) != ':'); end++);
351 filenamelen = end - start;
353 if (filenamelen > 3) {
354 if (strncasecmp(end - 3, "zip", 3) == 0 ||
355 strncasecmp(end - 3, "jar", 3) == 0) {
360 /* allocate memory for filename and fill it */
362 filename = MNEW(char, filenamelen + 2); /* 2 = "/\0" */
363 strncpy(filename, start, filenamelen);
364 filename[filenamelen + 1] = '\0';
368 #if defined(USE_ZLIB)
369 unzFile uf = unzOpen(filename);
372 cpi = NEW(classpath_info);
373 cpi->type = CLASSPATH_ARCHIVE;
376 cpi->pd = NULL; /* ProtectionDomain not set yet */
377 cpi->path = filename;
381 throw_cacao_exception_exit(string_java_lang_InternalError,
382 "zip/jar files not supported");
386 cpi = NEW(classpath_info);
387 cpi->type = CLASSPATH_PATH;
389 cpi->pd = NULL; /* ProtectionDomain not set yet */
391 if (filename[filenamelen - 1] != '/') {/*PERHAPS THIS SHOULD BE READ FROM A GLOBAL CONFIGURATION */
392 filename[filenamelen] = '/';
393 filename[filenamelen + 1] = '\0';
397 cpi->path = filename;
398 cpi->pathlen = filenamelen;
401 /* attach current classpath entry */
404 if (!classpath_entries)
405 classpath_entries = cpi;
413 /* goto next classpath entry, skip ':' delimiter */
425 void create_all_classes()
429 for (cpi = classpath_entries; cpi != 0; cpi = cpi->next) {
430 #if defined(USE_ZLIB)
431 if (cpi->type == CLASSPATH_ARCHIVE) {
435 s = (unz_s *) cpi->uf;
436 ce = s->cacao_dir_list;
439 (void) class_new(ce->name);
445 #if defined(USE_ZLIB)
452 /************************** function suck_start ********************************
454 returns true if classbuffer is already loaded or a file for the
455 specified class has succussfully been read in. All directories of
456 the searchpath are used to find the classfile (<classname>.class).
457 Returns false if no classfile is found and writes an error message.
459 *******************************************************************************/
461 classbuffer *suck_start(classinfo *c)
475 /* initialize return value */
480 filenamelen = utf_strlen(c->name) + 7; /* 7 = ".class\0" */
481 filename = MNEW(char, filenamelen);
483 utf_sprint(filename, c->name);
484 strcat(filename, ".class");
486 /* walk through all classpath entries */
488 for (cpi = classpath_entries; cpi != NULL && cb == NULL; cpi = cpi->next) {
489 #if defined(USE_ZLIB)
490 if (cpi->type == CLASSPATH_ARCHIVE) {
492 #if defined(USE_THREADS)
493 /* enter a monitor on zip/jar archives */
495 builtin_monitorenter((java_objectheader *) cpi);
498 if (cacao_locate(cpi->uf, c->name) == UNZ_OK) {
499 unz_file_info file_info;
501 if (unzGetCurrentFileInfo(cpi->uf, &file_info, filename,
502 sizeof(filename), NULL, 0, NULL, 0) == UNZ_OK) {
503 if (unzOpenCurrentFile(cpi->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;
509 /* We need this later in use_class_as_object to set a */
510 /* correct ProtectionDomain and CodeSource. */
511 c->pd = (struct java_security_ProtectionDomain *) cpi;
513 len = unzReadCurrentFile(cpi->uf, cb->data, cb->size);
515 if (len != cb->size) {
517 log_text("Error while unzipping");
524 log_text("Error while opening file in archive");
528 log_text("Error while retrieving fileinfo");
531 unzCloseCurrentFile(cpi->uf);
533 #if defined(USE_THREADS)
534 /* leave the monitor */
536 builtin_monitorexit((java_objectheader *) cpi);
540 #endif /* USE_ZLIB */
542 path = MNEW(char, cpi->pathlen + filenamelen + 1);
543 strcpy(path, cpi->path);
544 strcat(path, filename);
546 classfile = fopen(path, "r");
548 if (classfile) { /* file exists */
549 if (!stat(path, &buffer)) { /* read classfile data */
550 cb = NEW(classbuffer);
552 cb->size = buffer.st_size;
553 cb->data = MNEW(u1, cb->size);
554 cb->pos = cb->data - 1;
555 /* We need this later in use_class_as_object to set a */
556 /* correct ProtectionDomain and CodeSource. */
557 c->pd = (struct java_security_ProtectionDomain *) cpi;
559 /* read class data */
560 len = fread(cb->data, 1, cb->size, classfile);
562 if (len != buffer.st_size) {
564 /* if (ferror(classfile)) { */
573 MFREE(path, char, cpi->pathlen + filenamelen + 1);
574 #if defined(USE_ZLIB)
581 dolog("Warning: Can not open class file '%s'", filename);
584 MFREE(filename, char, filenamelen);
590 /************************** function suck_stop *********************************
592 frees memory for buffer with classfile data.
593 Caution: this function may only be called if buffer has been allocated
594 by suck_start with reading a file
596 *******************************************************************************/
598 void suck_stop(classbuffer *cb)
602 MFREE(cb->data, u1, cb->size);
603 FREE(cb, classbuffer);
607 /******************************************************************************/
608 /******************* Some support functions ***********************************/
609 /******************************************************************************/
611 void fprintflags (FILE *fp, u2 f)
613 if ( f & ACC_PUBLIC ) fprintf (fp," PUBLIC");
614 if ( f & ACC_PRIVATE ) fprintf (fp," PRIVATE");
615 if ( f & ACC_PROTECTED ) fprintf (fp," PROTECTED");
616 if ( f & ACC_STATIC ) fprintf (fp," STATIC");
617 if ( f & ACC_FINAL ) fprintf (fp," FINAL");
618 if ( f & ACC_SYNCHRONIZED ) fprintf (fp," SYNCHRONIZED");
619 if ( f & ACC_VOLATILE ) fprintf (fp," VOLATILE");
620 if ( f & ACC_TRANSIENT ) fprintf (fp," TRANSIENT");
621 if ( f & ACC_NATIVE ) fprintf (fp," NATIVE");
622 if ( f & ACC_INTERFACE ) fprintf (fp," INTERFACE");
623 if ( f & ACC_ABSTRACT ) fprintf (fp," ABSTRACT");
627 /********** internal function: printflags (only for debugging) ***************/
629 void printflags(u2 f)
631 if ( f & ACC_PUBLIC ) printf (" PUBLIC");
632 if ( f & ACC_PRIVATE ) printf (" PRIVATE");
633 if ( f & ACC_PROTECTED ) printf (" PROTECTED");
634 if ( f & ACC_STATIC ) printf (" STATIC");
635 if ( f & ACC_FINAL ) printf (" FINAL");
636 if ( f & ACC_SYNCHRONIZED ) printf (" SYNCHRONIZED");
637 if ( f & ACC_VOLATILE ) printf (" VOLATILE");
638 if ( f & ACC_TRANSIENT ) printf (" TRANSIENT");
639 if ( f & ACC_NATIVE ) printf (" NATIVE");
640 if ( f & ACC_INTERFACE ) printf (" INTERFACE");
641 if ( f & ACC_ABSTRACT ) printf (" ABSTRACT");
645 /********************** Function: skipattributebody ****************************
647 skips an attribute after the 16 bit reference to attribute_name has already
650 *******************************************************************************/
652 static bool skipattributebody(classbuffer *cb)
656 if (!check_classbuffer_size(cb, 4))
661 if (!check_classbuffer_size(cb, len))
664 skip_nbytes(cb, len);
670 /************************* Function: skipattributes ****************************
672 skips num attribute structures
674 *******************************************************************************/
676 static bool skipattributes(classbuffer *cb, u4 num)
681 for (i = 0; i < num; i++) {
682 if (!check_classbuffer_size(cb, 2 + 4))
688 if (!check_classbuffer_size(cb, len))
691 skip_nbytes(cb, len);
698 /******************** function:: class_getconstant *****************************
700 retrieves the value at position 'pos' of the constantpool of a class
701 if the type of the value is other than 'ctype' the system is stopped
703 *******************************************************************************/
705 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
707 /* check index and type of constantpool entry */
708 /* (pos == 0 is caught by type comparison) */
709 if (pos >= c->cpcount || c->cptags[pos] != ctype) {
710 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
714 return c->cpinfos[pos];
718 /******************** function: innerclass_getconstant ************************
720 like class_getconstant, but if cptags is ZERO null is returned
722 *******************************************************************************/
724 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
726 /* invalid position in constantpool */
727 if (pos >= c->cpcount) {
728 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
732 /* constantpool entry of type 0 */
736 /* check type of constantpool entry */
737 if (c->cptags[pos] != ctype) {
738 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
742 return c->cpinfos[pos];
746 /********************* Function: class_constanttype ****************************
748 Determines the type of a class entry in the ConstantPool
750 *******************************************************************************/
752 u4 class_constanttype(classinfo *c, u4 pos)
754 if (pos <= 0 || pos >= c->cpcount) {
755 *exceptionptr = new_classformaterror(c, "Illegal constant pool index");
759 return c->cptags[pos];
763 /************************ function: attribute_load ****************************
765 read attributes from classfile
767 *******************************************************************************/
769 static bool attribute_load(classbuffer *cb, classinfo *c, u4 num)
774 for (i = 0; i < num; i++) {
775 /* retrieve attribute name */
776 if (!check_classbuffer_size(cb, 2))
779 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
782 if (aname == utf_innerclasses) {
783 /* innerclasses attribute */
786 new_classformaterror(c, "Multiple InnerClasses attributes");
790 if (!check_classbuffer_size(cb, 4 + 2))
793 /* skip attribute length */
796 /* number of records */
797 c->innerclasscount = suck_u2(cb);
799 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
802 /* allocate memory for innerclass structure */
803 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
805 for (j = 0; j < c->innerclasscount; j++) {
806 /* The innerclass structure contains a class with an encoded
807 name, its defining scope, its simple name and a bitmask of
808 the access flags. If an inner class is not a member, its
809 outer_class is NULL, if a class is anonymous, its name is
812 innerclassinfo *info = c->innerclass + j;
815 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
817 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
819 innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
820 info->flags = suck_u2(cb);
823 } else if (aname == utf_sourcefile) {
824 if (!check_classbuffer_size(cb, 4 + 2))
827 if (suck_u4(cb) != 2) {
829 new_classformaterror(c, "Wrong size for VALUE attribute");
835 new_classformaterror(c, "Multiple SourceFile attributes");
839 if (!(c->sourcefile = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
843 /* unknown attribute */
844 if (!skipattributebody(cb))
853 /******************* function: checkfielddescriptor ****************************
855 checks whether a field-descriptor is valid and aborts otherwise
856 all referenced classes are inserted into the list of unloaded classes
858 *******************************************************************************/
860 static void checkfielddescriptor (char *utf_ptr, char *end_pos)
862 class_from_descriptor(utf_ptr,end_pos,NULL,
864 | CLASSLOAD_NULLPRIMITIVE
866 | CLASSLOAD_CHECKEND);
868 /* XXX use the following if -noverify */
870 char *tstart; /* pointer to start of classname */
872 char *start = utf_ptr;
874 switch (*utf_ptr++) {
888 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
889 panic ("Ill formed descriptor");
893 panic ("Ill formed descriptor");
896 /* exceeding characters */
897 if (utf_ptr!=end_pos) panic ("descriptor has exceeding chars");
902 /******************* function checkmethoddescriptor ****************************
904 checks whether a method-descriptor is valid and aborts otherwise.
905 All referenced classes are inserted into the list of unloaded classes.
907 The number of arguments is returned. A long or double argument is counted
910 *******************************************************************************/
912 static int checkmethoddescriptor(classinfo *c, utf *descriptor)
914 char *utf_ptr; /* current position in utf text */
915 char *end_pos; /* points behind utf string */
916 s4 argcount = 0; /* number of arguments */
918 utf_ptr = descriptor->text;
919 end_pos = utf_end(descriptor);
921 /* method descriptor must start with parenthesis */
922 if (utf_ptr == end_pos || *utf_ptr++ != '(')
923 panic ("Missing '(' in method descriptor");
925 /* check arguments */
926 while (utf_ptr != end_pos && *utf_ptr != ')') {
927 /* We cannot count the this argument here because
928 * we don't know if the method is static. */
929 if (*utf_ptr == 'J' || *utf_ptr == 'D')
933 class_from_descriptor(utf_ptr,end_pos,&utf_ptr,
935 | CLASSLOAD_NULLPRIMITIVE
939 if (utf_ptr == end_pos)
940 panic("Missing ')' in method descriptor");
942 utf_ptr++; /* skip ')' */
944 class_from_descriptor(utf_ptr,
948 CLASSLOAD_NULLPRIMITIVE |
951 if (argcount > 255) {
953 new_classformaterror(c, "Too many arguments in signature");
960 /* XXX use the following if -noverify */
962 /* check arguments */
963 while ((c = *utf_ptr++) != ')') {
980 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
981 panic ("Ill formed method descriptor");
985 panic ("Ill formed methodtype-descriptor");
989 /* check returntype */
991 /* returntype void */
992 if ((utf_ptr+1) != end_pos) panic ("Method-descriptor has exceeding chars");
995 /* treat as field-descriptor */
996 checkfielddescriptor (utf_ptr,end_pos);
1001 /***************** Function: print_arraydescriptor ****************************
1003 Debugging helper for displaying an arraydescriptor
1005 *******************************************************************************/
1007 void print_arraydescriptor(FILE *file, arraydescriptor *desc)
1010 fprintf(file, "<NULL>");
1015 if (desc->componentvftbl) {
1016 if (desc->componentvftbl->class)
1017 utf_fprint(file, desc->componentvftbl->class->name);
1019 fprintf(file, "<no classinfo>");
1025 if (desc->elementvftbl) {
1026 if (desc->elementvftbl->class)
1027 utf_fprint(file, desc->elementvftbl->class->name);
1029 fprintf(file, "<no classinfo>");
1033 fprintf(file, ",%d,%d,%d,%d}", desc->arraytype, desc->dimension,
1034 desc->dataoffset, desc->componentsize);
1038 /******************************************************************************/
1039 /************************** Functions for fields ****************************/
1040 /******************************************************************************/
1043 /* field_load ******************************************************************
1045 Load everything about a class field from the class file and fill a
1046 'fieldinfo' structure. For static fields, space in the data segment is
1049 *******************************************************************************/
1051 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
1053 static bool field_load(classbuffer *cb, classinfo *c, fieldinfo *f)
1057 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
1060 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1063 f->flags = suck_u2(cb);
1065 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1069 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1075 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<')
1076 panic("Field with invalid name");
1078 /* check flag consistency */
1079 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
1081 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
1082 ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
1084 new_classformaterror(c,
1085 "Illegal field modifiers: 0x%X",
1090 if (c->flags & ACC_INTERFACE) {
1091 if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
1092 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
1093 f->flags & ACC_TRANSIENT) {
1095 new_classformaterror(c,
1096 "Illegal field modifiers: 0x%X",
1102 /* check descriptor */
1103 checkfielddescriptor(f->descriptor->text, utf_end(f->descriptor));
1106 f->type = jtype = desc_to_type(f->descriptor); /* data type */
1107 f->offset = 0; /* offset from start of object */
1112 case TYPE_INT: f->value.i = 0; break;
1113 case TYPE_FLOAT: f->value.f = 0.0; break;
1114 case TYPE_DOUBLE: f->value.d = 0.0; break;
1115 case TYPE_ADDRESS: f->value.a = NULL; break;
1118 f->value.l = 0; break;
1120 f->value.l.low = 0; f->value.l.high = 0; break;
1124 /* read attributes */
1125 if (!check_classbuffer_size(cb, 2))
1128 attrnum = suck_u2(cb);
1129 for (i = 0; i < attrnum; i++) {
1130 if (!check_classbuffer_size(cb, 2))
1133 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1136 if (u == utf_constantvalue) {
1137 if (!check_classbuffer_size(cb, 4 + 2))
1140 /* check attribute length */
1141 if (suck_u4(cb) != 2) {
1143 new_classformaterror(c, "Wrong size for VALUE attribute");
1147 /* constant value attribute */
1148 if (pindex != field_load_NOVALUE) {
1150 new_classformaterror(c,
1151 "Multiple ConstantValue attributes");
1155 /* index of value in constantpool */
1156 pindex = suck_u2(cb);
1158 /* initialize field with value from constantpool */
1161 constant_integer *ci;
1163 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
1166 f->value.i = ci->value;
1173 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
1176 f->value.l = cl->value;
1183 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
1186 f->value.f = cf->value;
1191 constant_double *cd;
1193 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
1196 f->value.d = cd->value;
1201 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
1204 /* create javastring from compressed utf8-string */
1205 f->value.a = literalstring_new(u);
1209 log_text("Invalid Constant - Type");
1213 /* unknown attribute */
1214 if (!skipattributebody(cb))
1219 /* everything was ok */
1225 /********************** function: field_free **********************************/
1227 static void field_free(fieldinfo *f)
1233 /**************** Function: field_display (debugging only) ********************/
1235 void field_display(fieldinfo *f)
1238 printflags(f->flags);
1240 utf_display(f->name);
1242 utf_display(f->descriptor);
1243 printf(" offset: %ld\n", (long int) (f->offset));
1247 /******************************************************************************/
1248 /************************* Functions for methods ******************************/
1249 /******************************************************************************/
1252 /* method_load *****************************************************************
1254 Loads a method from the class file and fills an existing 'methodinfo'
1255 structure. For native methods, the function pointer field is set to the
1256 real function pointer, for JavaVM methods a pointer to the compiler is used
1259 *******************************************************************************/
1261 static bool method_load(classbuffer *cb, classinfo *c, methodinfo *m)
1269 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1270 initObjectLock(&m->header);
1275 count_all_methods++;
1278 m->thrownexceptionscount = 0;
1279 m->linenumbercount = 0;
1282 m->nativelyoverloaded = false;
1284 if (!check_classbuffer_size(cb, 2 + 2 + 2))
1287 m->flags = suck_u2(cb);
1289 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1293 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1298 if (!is_valid_name_utf(m->name))
1299 panic("Method with invalid name");
1301 if (m->name->text[0] == '<'
1302 && m->name != utf_init && m->name != utf_clinit)
1303 panic("Method with invalid special name");
1306 argcount = checkmethoddescriptor(c, m->descriptor);
1308 if (!(m->flags & ACC_STATIC))
1309 argcount++; /* count the 'this' argument */
1312 if (argcount > 255) {
1314 new_classformaterror(c, "Too many arguments in signature");
1318 /* check flag consistency */
1319 if (m->name != utf_clinit) {
1320 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1322 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1324 new_classformaterror(c,
1325 "Illegal method modifiers: 0x%X",
1330 if (m->flags & ACC_ABSTRACT) {
1331 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1332 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1334 new_classformaterror(c,
1335 "Illegal method modifiers: 0x%X",
1341 if (c->flags & ACC_INTERFACE) {
1342 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1344 new_classformaterror(c,
1345 "Illegal method modifiers: 0x%X",
1351 if (m->name == utf_init) {
1352 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1353 ACC_NATIVE | ACC_ABSTRACT))
1354 panic("Instance initialization method has invalid flags set");
1360 m->basicblockcount = 0;
1361 m->basicblocks = NULL;
1362 m->basicblockindex = NULL;
1363 m->instructioncount = 0;
1364 m->instructions = NULL;
1367 m->exceptiontable = NULL;
1368 m->stubroutine = NULL;
1370 m->entrypoint = NULL;
1371 m->methodUsed = NOTUSED;
1374 m->subRedefsUsed = 0;
1378 if (!(m->flags & ACC_NATIVE)) {
1379 m->stubroutine = createcompilerstub(m);
1382 /*if (useinlining) {
1383 log_text("creating native stub:");
1386 functionptr f = native_findfunction(c->name, m->name, m->descriptor,
1387 (m->flags & ACC_STATIC) != 0);
1388 #ifdef STATIC_CLASSPATH
1392 m->stubroutine = createnativestub(f, m);
1396 if (!check_classbuffer_size(cb, 2))
1399 attrnum = suck_u2(cb);
1400 for (i = 0; i < attrnum; i++) {
1403 if (!check_classbuffer_size(cb, 2))
1406 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1409 if (aname == utf_code) {
1410 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1412 new_classformaterror(c,
1413 "Code attribute in native or abstract methods");
1420 new_classformaterror(c, "Multiple Code attributes");
1425 if (!check_classbuffer_size(cb, 4 + 2 + 2))
1429 m->maxstack = suck_u2(cb);
1430 m->maxlocals = suck_u2(cb);
1432 if (m->maxlocals < argcount) {
1434 new_classformaterror(c, "Arguments can't fit into locals");
1439 if (!check_classbuffer_size(cb, 4))
1442 m->jcodelength = suck_u4(cb);
1444 if (m->jcodelength == 0) {
1446 new_classformaterror(c, "Code of a method has length 0");
1451 if (m->jcodelength > 65535) {
1453 new_classformaterror(c,
1454 "Code of a method longer than 65535 bytes");
1459 if (!check_classbuffer_size(cb, m->jcodelength))
1462 m->jcode = MNEW(u1, m->jcodelength);
1463 suck_nbytes(m->jcode, cb, m->jcodelength);
1465 if (!check_classbuffer_size(cb, 2))
1468 m->exceptiontablelength = suck_u2(cb);
1469 if (!check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->exceptiontablelength))
1472 m->exceptiontable = MNEW(exceptiontable, m->exceptiontablelength);
1474 #if defined(STATISTICS)
1476 count_vmcode_len += m->jcodelength + 18;
1477 count_extable_len += 8 * m->exceptiontablelength;
1481 for (j = 0; j < m->exceptiontablelength; j++) {
1483 m->exceptiontable[j].startpc = suck_u2(cb);
1484 m->exceptiontable[j].endpc = suck_u2(cb);
1485 m->exceptiontable[j].handlerpc = suck_u2(cb);
1489 m->exceptiontable[j].catchtype = NULL;
1492 if (!(m->exceptiontable[j].catchtype =
1493 class_getconstant(c, idx, CONSTANT_Class)))
1498 if (!check_classbuffer_size(cb, 2))
1501 codeattrnum = suck_u2(cb);
1503 for (; codeattrnum > 0; codeattrnum--) {
1506 if (!check_classbuffer_size(cb, 2))
1509 if (!(caname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1512 if (caname == utf_linenumbertable) {
1515 if (!check_classbuffer_size(cb, 4 + 2))
1519 m->linenumbercount = suck_u2(cb);
1521 if (!check_classbuffer_size(cb,
1522 (2 + 2) * m->linenumbercount))
1525 m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1527 for (lncid = 0; lncid < m->linenumbercount; lncid++) {
1528 m->linenumbers[lncid].start_pc = suck_u2(cb);
1529 m->linenumbers[lncid].line_number = suck_u2(cb);
1533 if (!skipattributes(cb, codeattrnum))
1539 if (!skipattributebody(cb))
1544 } else if (aname == utf_exceptions) {
1547 if (m->thrownexceptions) {
1549 new_classformaterror(c, "Multiple Exceptions attributes");
1553 if (!check_classbuffer_size(cb, 4 + 2))
1556 suck_u4(cb); /* length */
1557 m->thrownexceptionscount = suck_u2(cb);
1559 if (!check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1562 m->thrownexceptions = MNEW(classinfo*, m->thrownexceptionscount);
1564 for (j = 0; j < m->thrownexceptionscount; j++) {
1565 if (!((m->thrownexceptions)[j] =
1566 class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1571 if (!skipattributebody(cb))
1576 if (!m->jcode && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1577 *exceptionptr = new_classformaterror(c, "Missing Code attribute");
1582 /* everything was ok */
1583 /* utf_display(m->name);
1584 printf("\nexceptiontablelength:%ld\n",m->exceptiontablelength);*/
1590 /********************* Function: method_free ***********************************
1592 frees all memory that was allocated for this method
1594 *******************************************************************************/
1596 static void method_free(methodinfo *m)
1599 MFREE(m->jcode, u1, m->jcodelength);
1601 if (m->exceptiontable)
1602 MFREE(m->exceptiontable, exceptiontable, m->exceptiontablelength);
1605 CFREE(m->mcode, m->mcodelength);
1607 if (m->stubroutine) {
1608 if (m->flags & ACC_NATIVE) {
1609 removenativestub(m->stubroutine);
1612 removecompilerstub(m->stubroutine);
1618 /************** Function: method_display (debugging only) **************/
1620 void method_display(methodinfo *m)
1623 printflags(m->flags);
1625 utf_display(m->name);
1627 utf_display(m->descriptor);
1631 /************** Function: method_display_w_class (debugging only) **************/
1633 void method_display_w_class(methodinfo *m)
1635 printflags(m->class->flags);
1636 printf(" "); fflush(stdout);
1637 utf_display(m->class->name);
1638 printf(".");fflush(stdout);
1641 printflags(m->flags);
1642 printf(" "); fflush(stdout);
1643 utf_display(m->name);
1644 printf(" "); fflush(stdout);
1645 utf_display(m->descriptor);
1646 printf("\n"); fflush(stdout);
1649 /************** Function: method_display_flags_last (debugging only) **************/
1651 void method_display_flags_last(methodinfo *m)
1654 utf_display(m->name);
1656 utf_display(m->descriptor);
1658 printflags(m->flags);
1663 /******************** Function: method_canoverwrite ****************************
1665 Check if m and old are identical with respect to type and name. This means
1666 that old can be overwritten with m.
1668 *******************************************************************************/
1670 static bool method_canoverwrite(methodinfo *m, methodinfo *old)
1672 if (m->name != old->name) return false;
1673 if (m->descriptor != old->descriptor) return false;
1674 if (m->flags & ACC_STATIC) return false;
1679 /******************** function: class_loadcpool ********************************
1681 loads the constantpool of a class,
1682 the entries are transformed into a simpler format
1683 by resolving references
1684 (a detailed overview of the compact structures can be found in global.h)
1686 *******************************************************************************/
1688 static bool class_loadcpool(classbuffer *cb, classinfo *c)
1691 /* The following structures are used to save information which cannot be
1692 processed during the first pass. After the complete constantpool has
1693 been traversed the references can be resolved.
1694 (only in specific order) */
1696 /* CONSTANT_Class entries */
1697 typedef struct forward_class {
1698 struct forward_class *next;
1703 /* CONSTANT_String */
1704 typedef struct forward_string {
1705 struct forward_string *next;
1710 /* CONSTANT_NameAndType */
1711 typedef struct forward_nameandtype {
1712 struct forward_nameandtype *next;
1716 } forward_nameandtype;
1718 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
1719 typedef struct forward_fieldmethint {
1720 struct forward_fieldmethint *next;
1724 u2 nameandtype_index;
1725 } forward_fieldmethint;
1730 forward_class *forward_classes = NULL;
1731 forward_string *forward_strings = NULL;
1732 forward_nameandtype *forward_nameandtypes = NULL;
1733 forward_fieldmethint *forward_fieldmethints = NULL;
1736 forward_string *nfs;
1737 forward_nameandtype *nfn;
1738 forward_fieldmethint *nff;
1744 /* number of entries in the constant_pool table plus one */
1745 if (!check_classbuffer_size(cb, 2))
1748 cpcount = c->cpcount = suck_u2(cb);
1750 /* allocate memory */
1751 cptags = c->cptags = MNEW(u1, cpcount);
1752 cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
1755 *exceptionptr = new_classformaterror(c, "Illegal constant pool size");
1759 #if defined(STATISTICS)
1761 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
1764 /* initialize constantpool */
1765 for (idx = 0; idx < cpcount; idx++) {
1766 cptags[idx] = CONSTANT_UNUSED;
1767 cpinfos[idx] = NULL;
1771 /******* first pass *******/
1772 /* entries which cannot be resolved now are written into
1773 temporary structures and traversed again later */
1776 while (idx < cpcount) {
1779 /* get constant type */
1780 if (!check_classbuffer_size(cb, 1))
1786 case CONSTANT_Class:
1787 nfc = NEW(forward_class);
1789 nfc->next = forward_classes;
1790 forward_classes = nfc;
1792 nfc->thisindex = idx;
1793 /* reference to CONSTANT_NameAndType */
1794 if (!check_classbuffer_size(cb, 2))
1797 nfc->name_index = suck_u2(cb);
1802 case CONSTANT_String:
1803 nfs = NEW(forward_string);
1805 nfs->next = forward_strings;
1806 forward_strings = nfs;
1808 nfs->thisindex = idx;
1810 /* reference to CONSTANT_Utf8_info with string characters */
1811 if (!check_classbuffer_size(cb, 2))
1814 nfs->string_index = suck_u2(cb);
1819 case CONSTANT_NameAndType:
1820 nfn = NEW(forward_nameandtype);
1822 nfn->next = forward_nameandtypes;
1823 forward_nameandtypes = nfn;
1825 nfn->thisindex = idx;
1827 if (!check_classbuffer_size(cb, 2 + 2))
1830 /* reference to CONSTANT_Utf8_info containing simple name */
1831 nfn->name_index = suck_u2(cb);
1833 /* reference to CONSTANT_Utf8_info containing field or method
1835 nfn->sig_index = suck_u2(cb);
1840 case CONSTANT_Fieldref:
1841 case CONSTANT_Methodref:
1842 case CONSTANT_InterfaceMethodref:
1843 nff = NEW(forward_fieldmethint);
1845 nff->next = forward_fieldmethints;
1846 forward_fieldmethints = nff;
1848 nff->thisindex = idx;
1852 if (!check_classbuffer_size(cb, 2 + 2))
1855 /* class or interface type that contains the declaration of the
1857 nff->class_index = suck_u2(cb);
1859 /* name and descriptor of the field or method */
1860 nff->nameandtype_index = suck_u2(cb);
1865 case CONSTANT_Integer: {
1866 constant_integer *ci = NEW(constant_integer);
1868 #if defined(STATISTICS)
1870 count_const_pool_len += sizeof(constant_integer);
1873 if (!check_classbuffer_size(cb, 4))
1876 ci->value = suck_s4(cb);
1877 cptags[idx] = CONSTANT_Integer;
1884 case CONSTANT_Float: {
1885 constant_float *cf = NEW(constant_float);
1887 #if defined(STATISTICS)
1889 count_const_pool_len += sizeof(constant_float);
1892 if (!check_classbuffer_size(cb, 4))
1895 cf->value = suck_float(cb);
1896 cptags[idx] = CONSTANT_Float;
1903 case CONSTANT_Long: {
1904 constant_long *cl = NEW(constant_long);
1906 #if defined(STATISTICS)
1908 count_const_pool_len += sizeof(constant_long);
1911 if (!check_classbuffer_size(cb, 8))
1914 cl->value = suck_s8(cb);
1915 cptags[idx] = CONSTANT_Long;
1918 if (idx > cpcount) {
1920 new_classformaterror(c, "Invalid constant pool entry");
1926 case CONSTANT_Double: {
1927 constant_double *cd = NEW(constant_double);
1929 #if defined(STATISTICS)
1931 count_const_pool_len += sizeof(constant_double);
1934 if (!check_classbuffer_size(cb, 8))
1937 cd->value = suck_double(cb);
1938 cptags[idx] = CONSTANT_Double;
1941 if (idx > cpcount) {
1943 new_classformaterror(c, "Invalid constant pool entry");
1949 case CONSTANT_Utf8: {
1952 /* number of bytes in the bytes array (not string-length) */
1953 if (!check_classbuffer_size(cb, 2))
1956 length = suck_u2(cb);
1957 cptags[idx] = CONSTANT_Utf8;
1959 /* validate the string */
1960 if (!check_classbuffer_size(cb, length))
1964 !is_valid_utf((char *) (cb->pos + 1),
1965 (char *) (cb->pos + 1 + length))) {
1966 dolog("Invalid UTF-8 string (constant pool index %d)",idx);
1967 panic("Invalid UTF-8 string");
1969 /* insert utf-string into the utf-symboltable */
1970 cpinfos[idx] = utf_new_intern((char *) (cb->pos + 1), length);
1972 /* skip bytes of the string (buffer size check above) */
1973 skip_nbytes(cb, length);
1980 new_classformaterror(c, "Illegal constant pool type");
1986 /* resolve entries in temporary structures */
1988 while (forward_classes) {
1990 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
1992 if (opt_verify && !is_valid_name_utf(name))
1993 panic("Class reference with invalid name");
1995 cptags[forward_classes->thisindex] = CONSTANT_Class;
1996 /* retrieve class from class-table */
1999 tc = class_new_intern(name);
2001 if (!class_load(tc))
2004 /* link the class later, because we cannot link the class currently
2006 list_addfirst(&unlinkedclasses, tc);
2008 cpinfos[forward_classes->thisindex] = tc;
2011 cpinfos[forward_classes->thisindex] = class_new(name);
2014 nfc = forward_classes;
2015 forward_classes = forward_classes->next;
2016 FREE(nfc, forward_class);
2019 while (forward_strings) {
2021 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
2023 /* resolve utf-string */
2024 cptags[forward_strings->thisindex] = CONSTANT_String;
2025 cpinfos[forward_strings->thisindex] = text;
2027 nfs = forward_strings;
2028 forward_strings = forward_strings->next;
2029 FREE(nfs, forward_string);
2032 while (forward_nameandtypes) {
2033 constant_nameandtype *cn = NEW(constant_nameandtype);
2035 #if defined(STATISTICS)
2037 count_const_pool_len += sizeof(constant_nameandtype);
2040 /* resolve simple name and descriptor */
2041 cn->name = class_getconstant(c,
2042 forward_nameandtypes->name_index,
2045 cn->descriptor = class_getconstant(c,
2046 forward_nameandtypes->sig_index,
2051 if (!is_valid_name_utf(cn->name))
2052 panic("NameAndType with invalid name");
2053 /* disallow referencing <clinit> among others */
2054 if (cn->name->text[0] == '<' && cn->name != utf_init)
2055 panic("NameAndType with invalid special name");
2058 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
2059 cpinfos[forward_nameandtypes->thisindex] = cn;
2061 nfn = forward_nameandtypes;
2062 forward_nameandtypes = forward_nameandtypes->next;
2063 FREE(nfn, forward_nameandtype);
2066 while (forward_fieldmethints) {
2067 constant_nameandtype *nat;
2068 constant_FMIref *fmi = NEW(constant_FMIref);
2070 #if defined(STATISTICS)
2072 count_const_pool_len += sizeof(constant_FMIref);
2074 /* resolve simple name and descriptor */
2075 nat = class_getconstant(c,
2076 forward_fieldmethints->nameandtype_index,
2077 CONSTANT_NameAndType);
2079 fmi->class = class_getconstant(c,
2080 forward_fieldmethints->class_index,
2082 fmi->name = nat->name;
2083 fmi->descriptor = nat->descriptor;
2085 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
2086 cpinfos[forward_fieldmethints->thisindex] = fmi;
2088 switch (forward_fieldmethints->tag) {
2089 case CONSTANT_Fieldref: /* check validity of descriptor */
2090 checkfielddescriptor(fmi->descriptor->text,
2091 utf_end(fmi->descriptor));
2093 case CONSTANT_InterfaceMethodref:
2094 case CONSTANT_Methodref: /* check validity of descriptor */
2095 checkmethoddescriptor(c, fmi->descriptor);
2099 nff = forward_fieldmethints;
2100 forward_fieldmethints = forward_fieldmethints->next;
2101 FREE(nff, forward_fieldmethint);
2104 /* everything was ok */
2110 /********************** Function: class_load ***********************************
2112 Loads everything interesting about a class from the class file. The
2113 'classinfo' structure must have been allocated previously.
2115 The super class and the interfaces implemented by this class need not be
2116 loaded. The link is set later by the function 'class_link'.
2118 The loaded class is removed from the list 'unloadedclasses' and added to
2119 the list 'unlinkedclasses'.
2121 *******************************************************************************/
2123 classinfo *class_load_intern(classbuffer *cb);
2125 classinfo *class_load(classinfo *c)
2130 #if defined(USE_THREADS)
2131 /* enter a monitor on the class */
2133 builtin_monitorenter((java_objectheader *) c);
2136 /* maybe the class is already loaded */
2138 #if defined(USE_THREADS)
2139 builtin_monitorexit((java_objectheader *) c);
2147 if (getcompilingtime)
2148 compilingtime_stop();
2151 loadingtime_start();
2153 /* load classdata, throw exception on error */
2155 if ((cb = suck_start(c)) == NULL) {
2156 /* this means, the classpath was not set properly */
2157 if (c->name == utf_java_lang_Object)
2158 throw_cacao_exception_exit(string_java_lang_NoClassDefFoundError,
2159 "java/lang/Object");
2162 new_exception_utfmessage(string_java_lang_NoClassDefFoundError,
2165 #if defined(USE_THREADS)
2166 builtin_monitorexit((java_objectheader *) c);
2172 /* call the internal function */
2173 r = class_load_intern(cb);
2175 /* if return value is NULL, we had a problem and the class is not loaded */
2179 /* now free the allocated memory, otherwise we could ran into a DOS */
2191 if (getcompilingtime)
2192 compilingtime_start();
2194 #if defined(USE_THREADS)
2195 /* leave the monitor */
2197 builtin_monitorexit((java_objectheader *) c);
2204 classinfo *class_load_intern(classbuffer *cb)
2210 char msg[MAXLOGTEXT]; /* maybe we get an exception */
2212 /* get the classbuffer's class */
2215 /* maybe the class is already loaded */
2219 #if defined(STATISTICS)
2221 count_class_loads++;
2224 /* output for debugging purposes */
2226 log_message_class("Loading class: ", c);
2228 /* class is somewhat loaded */
2231 if (!check_classbuffer_size(cb, 4 + 2 + 2))
2234 /* check signature */
2235 if (suck_u4(cb) != MAGIC) {
2236 *exceptionptr = new_classformaterror(c, "Bad magic number");
2245 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
2247 new_unsupportedclassversionerror(c,
2248 "Unsupported major.minor version %d.%d",
2254 /* load the constant pool */
2255 if (!class_loadcpool(cb, c))
2259 c->erroneous_state = 0;
2260 c->initializing_thread = 0;
2262 c->classUsed = NOTUSED; /* not used initially CO-RT */
2266 if (!check_classbuffer_size(cb, 2))
2269 c->flags = suck_u2(cb);
2270 /*if (!(c->flags & ACC_PUBLIC)) { log_text("CLASS NOT PUBLIC"); } JOWENN*/
2272 /* check ACC flags consistency */
2273 if (c->flags & ACC_INTERFACE) {
2274 if (!(c->flags & ACC_ABSTRACT)) {
2275 /* We work around this because interfaces in JDK 1.1 are
2276 * not declared abstract. */
2278 c->flags |= ACC_ABSTRACT;
2279 /* panic("Interface class not declared abstract"); */
2282 if (c->flags & ACC_FINAL) {
2284 new_classformaterror(c,
2285 "Illegal class modifiers: 0x%X", c->flags);
2290 if (c->flags & ACC_SUPER) {
2291 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
2295 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
2297 new_classformaterror(c, "Illegal class modifiers: 0x%X", c->flags);
2302 if (!check_classbuffer_size(cb, 2 + 2))
2307 if (!(tc = class_getconstant(c, i, CONSTANT_Class)))
2311 utf_sprint(msg, c->name);
2312 sprintf(msg + strlen(msg), " (wrong name: ");
2313 utf_sprint(msg + strlen(msg), tc->name);
2314 sprintf(msg + strlen(msg), ")");
2317 new_exception_message(string_java_lang_NoClassDefFoundError, msg);
2322 /* retrieve superclass */
2323 if ((i = suck_u2(cb))) {
2324 if (!(c->super = class_getconstant(c, i, CONSTANT_Class)))
2327 /* java.lang.Object may not have a super class. */
2328 if (c->name == utf_java_lang_Object) {
2330 new_exception_message(string_java_lang_ClassFormatError,
2331 "java.lang.Object with superclass");
2336 /* Interfaces must have java.lang.Object as super class. */
2337 if ((c->flags & ACC_INTERFACE) &&
2338 c->super->name != utf_java_lang_Object) {
2340 new_exception_message(string_java_lang_ClassFormatError,
2341 "Interfaces must have java.lang.Object as superclass");
2349 /* This is only allowed for java.lang.Object. */
2350 if (c->name != utf_java_lang_Object) {
2351 *exceptionptr = new_classformaterror(c, "Bad superclass index");
2357 /* retrieve interfaces */
2358 if (!check_classbuffer_size(cb, 2))
2361 c->interfacescount = suck_u2(cb);
2363 if (!check_classbuffer_size(cb, 2 * c->interfacescount))
2366 c->interfaces = MNEW(classinfo*, c->interfacescount);
2367 for (i = 0; i < c->interfacescount; i++) {
2368 if (!(c->interfaces[i] = class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2373 if (!check_classbuffer_size(cb, 2))
2376 c->fieldscount = suck_u2(cb);
2377 c->fields = GCNEW(fieldinfo, c->fieldscount);
2378 /* c->fields = MNEW(fieldinfo, c->fieldscount); */
2379 for (i = 0; i < c->fieldscount; i++) {
2380 if (!field_load(cb, c, &(c->fields[i])))
2385 if (!check_classbuffer_size(cb, 2))
2388 c->methodscount = suck_u2(cb);
2389 c->methods = GCNEW(methodinfo, c->methodscount);
2390 /* c->methods = MNEW(methodinfo, c->methodscount); */
2391 for (i = 0; i < c->methodscount; i++) {
2392 if (!method_load(cb, c, &(c->methods[i])))
2396 /* Check if all fields and methods can be uniquely
2397 * identified by (name,descriptor). */
2399 /* We use a hash table here to avoid making the
2400 * average case quadratic in # of methods, fields.
2402 static int shift = 0;
2404 u2 *next; /* for chaining colliding hash entries */
2410 /* Allocate hashtable */
2411 len = c->methodscount;
2412 if (len < c->fieldscount) len = c->fieldscount;
2414 hashtab = MNEW(u2,(hashlen + len));
2415 next = hashtab + hashlen;
2417 /* Determine bitshift (to get good hash values) */
2427 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2429 for (i = 0; i < c->fieldscount; ++i) {
2430 fieldinfo *fi = c->fields + i;
2432 /* It's ok if we lose bits here */
2433 index = ((((size_t) fi->name) +
2434 ((size_t) fi->descriptor)) >> shift) % hashlen;
2436 if ((old = hashtab[index])) {
2440 if (c->fields[old].name == fi->name &&
2441 c->fields[old].descriptor == fi->descriptor) {
2443 new_classformaterror(c,
2444 "Repetitive field name/signature");
2448 } while ((old = next[old]));
2450 hashtab[index] = i + 1;
2454 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2456 for (i = 0; i < c->methodscount; ++i) {
2457 methodinfo *mi = c->methods + i;
2459 /* It's ok if we lose bits here */
2460 index = ((((size_t) mi->name) +
2461 ((size_t) mi->descriptor)) >> shift) % hashlen;
2465 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2466 printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2470 if ((old = hashtab[index])) {
2474 if (c->methods[old].name == mi->name &&
2475 c->methods[old].descriptor == mi->descriptor) {
2477 new_classformaterror(c,
2478 "Repetitive method name/signature");
2482 } while ((old = next[old]));
2484 hashtab[index] = i + 1;
2487 MFREE(hashtab, u2, (hashlen + len));
2490 #if defined(STATISTICS)
2492 count_class_infos += sizeof(classinfo*) * c->interfacescount;
2493 count_class_infos += sizeof(fieldinfo) * c->fieldscount;
2494 count_class_infos += sizeof(methodinfo) * c->methodscount;
2498 /* load attribute structures */
2499 if (!check_classbuffer_size(cb, 2))
2502 if (!attribute_load(cb, c, suck_u2(cb)))
2506 /* Pre java 1.5 version don't check this. This implementation is like
2507 java 1.5 do it: for class file version 45.3 we don't check it, older
2508 versions are checked.
2510 if ((ma == 45 && mi > 3) || ma > 45) {
2511 /* check if all data has been read */
2512 s4 classdata_left = ((cb->data + cb->size) - cb->pos - 1);
2514 if (classdata_left > 0) {
2516 new_classformaterror(c, "Extra bytes at the end of class file");
2523 log_message_class("Loading done class: ", c);
2530 /************** internal Function: class_highestinterface **********************
2532 Used by the function class_link to determine the amount of memory needed
2533 for the interface table.
2535 *******************************************************************************/
2537 static s4 class_highestinterface(classinfo *c)
2542 /* check for ACC_INTERFACE bit already done in class_link_intern */
2545 for (i = 0; i < c->interfacescount; i++) {
2546 s4 h2 = class_highestinterface(c->interfaces[i]);
2554 /* class_addinterface **********************************************************
2556 Is needed by class_link for adding a VTBL to a class. All interfaces
2557 implemented by ic are added as well.
2559 *******************************************************************************/
2561 static void class_addinterface(classinfo *c, classinfo *ic)
2565 vftbl_t *v = c->vftbl;
2567 if (i >= v->interfacetablelength)
2568 panic ("Inernal error: interfacetable overflow");
2570 if (v->interfacetable[-i])
2573 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
2574 v->interfacevftbllength[i] = 1;
2575 v->interfacetable[-i] = MNEW(methodptr, 1);
2576 v->interfacetable[-i][0] = NULL;
2579 v->interfacevftbllength[i] = ic->methodscount;
2580 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
2582 #if defined(STATISTICS)
2584 count_vftbl_len += sizeof(methodptr) *
2585 (ic->methodscount + (ic->methodscount == 0));
2588 for (j = 0; j < ic->methodscount; j++) {
2591 for (m = 0; m < sc->methodscount; m++) {
2592 methodinfo *mi = &(sc->methods[m]);
2593 if (method_canoverwrite(mi, &(ic->methods[j]))) {
2594 v->interfacetable[-i][j] = v->table[mi->vftblindex];
2605 for (j = 0; j < ic->interfacescount; j++)
2606 class_addinterface(c, ic->interfaces[j]);
2610 /******************* Function: class_new_array *********************************
2612 This function is called by class_new to setup an array class.
2614 *******************************************************************************/
2616 void class_new_array(classinfo *c)
2618 classinfo *comp = NULL;
2622 /* Check array class name */
2623 namelen = c->name->blength;
2624 if (namelen < 2 || c->name->text[0] != '[')
2625 panic("Invalid array class name");
2627 /* Check the component type */
2628 switch (c->name->text[1]) {
2630 /* c is an array of arrays. We have to create the component class. */
2632 comp = class_new_intern(utf_new_intern(c->name->text + 1,
2635 list_addfirst(&unlinkedclasses, comp);
2638 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2643 /* c is an array of objects. */
2644 if (namelen < 4 || c->name->text[namelen - 1] != ';')
2645 panic("Invalid array class name");
2648 comp = class_new_intern(utf_new_intern(c->name->text + 2,
2651 list_addfirst(&unlinkedclasses, comp);
2654 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2659 /* Setup the array class */
2660 c->super = class_java_lang_Object;
2661 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2663 c->interfacescount = 2;
2664 c->interfaces = MNEW(classinfo*, 2);
2669 tc = class_new_intern(utf_new_char("java/lang/Cloneable"));
2671 list_addfirst(&unlinkedclasses, tc);
2672 c->interfaces[0] = tc;
2674 tc = class_new_intern(utf_new_char("java/io/Serializable"));
2676 list_addfirst(&unlinkedclasses, tc);
2677 c->interfaces[1] = tc;
2680 c->interfaces[0] = class_new(utf_new_char("java/lang/Cloneable"));
2681 c->interfaces[1] = class_new(utf_new_char("java/io/Serializable"));
2684 c->methodscount = 1;
2685 c->methods = MNEW(methodinfo, c->methodscount);
2688 memset(clone, 0, sizeof(methodinfo));
2689 clone->flags = ACC_PUBLIC;
2690 clone->name = utf_new_char("clone");
2691 clone->descriptor = utf_new_char("()Ljava/lang/Object;");
2693 clone->stubroutine = createnativestub((functionptr) &builtin_clone_array, clone);
2694 clone->monoPoly = MONO;
2696 /* XXX: field: length? */
2698 /* array classes are not loaded from class files */
2703 /****************** Function: class_link_array *********************************
2705 This function is called by class_link to create the
2706 arraydescriptor for an array class.
2708 This function returns NULL if the array cannot be linked because
2709 the component type has not been linked yet.
2711 *******************************************************************************/
2713 static arraydescriptor *class_link_array(classinfo *c)
2715 classinfo *comp = NULL;
2716 s4 namelen = c->name->blength;
2717 arraydescriptor *desc;
2720 /* Check the component type */
2721 switch (c->name->text[1]) {
2723 /* c is an array of arrays. */
2724 comp = class_new(utf_new_intern(c->name->text + 1, namelen - 1));
2726 panic("Could not find component array class.");
2730 /* c is an array of objects. */
2731 comp = class_new(utf_new_intern(c->name->text + 2, namelen - 3));
2733 panic("Could not find component class.");
2737 /* If the component type has not been linked, link it now */
2738 if (comp && !comp->linked) {
2740 if (!class_load(comp))
2743 if (!class_link(comp))
2747 /* Allocate the arraydescriptor */
2748 desc = NEW(arraydescriptor);
2751 /* c is an array of references */
2752 desc->arraytype = ARRAYTYPE_OBJECT;
2753 desc->componentsize = sizeof(void*);
2754 desc->dataoffset = OFFSET(java_objectarray, data);
2756 compvftbl = comp->vftbl;
2758 panic("Component class has no vftbl");
2759 desc->componentvftbl = compvftbl;
2761 if (compvftbl->arraydesc) {
2762 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
2763 if (compvftbl->arraydesc->dimension >= 255)
2764 panic("Creating array of dimension >255");
2765 desc->dimension = compvftbl->arraydesc->dimension + 1;
2766 desc->elementtype = compvftbl->arraydesc->elementtype;
2769 desc->elementvftbl = compvftbl;
2770 desc->dimension = 1;
2771 desc->elementtype = ARRAYTYPE_OBJECT;
2775 /* c is an array of a primitive type */
2776 switch (c->name->text[1]) {
2778 desc->arraytype = ARRAYTYPE_BOOLEAN;
2779 desc->dataoffset = OFFSET(java_booleanarray,data);
2780 desc->componentsize = sizeof(u1);
2784 desc->arraytype = ARRAYTYPE_BYTE;
2785 desc->dataoffset = OFFSET(java_bytearray,data);
2786 desc->componentsize = sizeof(u1);
2790 desc->arraytype = ARRAYTYPE_CHAR;
2791 desc->dataoffset = OFFSET(java_chararray,data);
2792 desc->componentsize = sizeof(u2);
2796 desc->arraytype = ARRAYTYPE_DOUBLE;
2797 desc->dataoffset = OFFSET(java_doublearray,data);
2798 desc->componentsize = sizeof(double);
2802 desc->arraytype = ARRAYTYPE_FLOAT;
2803 desc->dataoffset = OFFSET(java_floatarray,data);
2804 desc->componentsize = sizeof(float);
2808 desc->arraytype = ARRAYTYPE_INT;
2809 desc->dataoffset = OFFSET(java_intarray,data);
2810 desc->componentsize = sizeof(s4);
2814 desc->arraytype = ARRAYTYPE_LONG;
2815 desc->dataoffset = OFFSET(java_longarray,data);
2816 desc->componentsize = sizeof(s8);
2820 desc->arraytype = ARRAYTYPE_SHORT;
2821 desc->dataoffset = OFFSET(java_shortarray,data);
2822 desc->componentsize = sizeof(s2);
2826 panic("Invalid array class name");
2829 desc->componentvftbl = NULL;
2830 desc->elementvftbl = NULL;
2831 desc->dimension = 1;
2832 desc->elementtype = desc->arraytype;
2839 /********************** Function: class_link ***********************************
2841 Tries to link a class. The function calculates the length in bytes that
2842 an instance of this class requires as well as the VTBL for methods and
2845 *******************************************************************************/
2847 static classinfo *class_link_intern(classinfo *c);
2849 classinfo *class_link(classinfo *c)
2853 #if defined(USE_THREADS)
2854 /* enter a monitor on the class */
2856 builtin_monitorenter((java_objectheader *) c);
2859 /* maybe the class is already linked */
2861 #if defined(USE_THREADS)
2862 builtin_monitorexit((java_objectheader *) c);
2870 if (getcompilingtime)
2871 compilingtime_stop();
2874 loadingtime_start();
2876 /* call the internal function */
2877 r = class_link_intern(c);
2879 /* if return value is NULL, we had a problem and the class is not linked */
2888 if (getcompilingtime)
2889 compilingtime_start();
2891 #if defined(USE_THREADS)
2892 /* leave the monitor */
2894 builtin_monitorexit((java_objectheader *) c);
2901 static classinfo *class_link_intern(classinfo *c)
2903 s4 supervftbllength; /* vftbllegnth of super class */
2904 s4 vftbllength; /* vftbllength of current class */
2905 s4 interfacetablelength; /* interface table length */
2906 classinfo *super; /* super class */
2907 classinfo *tc; /* temporary class variable */
2908 vftbl_t *v; /* vftbl of current class */
2909 s4 i; /* interface/method/field counter */
2910 arraydescriptor *arraydesc; /* descriptor for array classes */
2912 /* maybe the class is already linked */
2916 /* maybe the class is not loaded */
2922 log_message_class("Linking class: ", c);
2924 /* ok, this class is somewhat linked */
2929 /* check interfaces */
2931 for (i = 0; i < c->interfacescount; i++) {
2932 tc = c->interfaces[i];
2934 /* detect circularity */
2937 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2943 if (!class_load(tc))
2946 if (!(tc->flags & ACC_INTERFACE)) {
2948 new_exception_message(string_java_lang_IncompatibleClassChangeError,
2949 "Implementing class");
2954 if (!class_link(tc))
2958 /* check super class */
2962 if (super == NULL) { /* class java.lang.Object */
2964 c->classUsed = USED; /* Object class is always used CO-RT*/
2966 c->instancesize = sizeof(java_objectheader);
2968 vftbllength = supervftbllength = 0;
2970 c->finalizer = NULL;
2973 /* detect circularity */
2976 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2982 if (!class_load(super))
2985 if (super->flags & ACC_INTERFACE) {
2986 /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
2987 panic("Interface specified as super class");
2990 /* Don't allow extending final classes */
2991 if (super->flags & ACC_FINAL) {
2993 new_exception_message(string_java_lang_VerifyError,
2994 "Cannot inherit from final class");
2999 if (!class_link(super))
3002 /* handle array classes */
3003 if (c->name->text[0] == '[')
3004 if (!(arraydesc = class_link_array(c)))
3007 if (c->flags & ACC_INTERFACE)
3008 c->index = interfaceindex++;
3010 c->index = super->index + 1;
3012 c->instancesize = super->instancesize;
3014 vftbllength = supervftbllength = super->vftbl->vftbllength;
3016 c->finalizer = super->finalizer;
3019 /* compute vftbl length */
3021 for (i = 0; i < c->methodscount; i++) {
3022 methodinfo *m = &(c->methods[i]);
3024 if (!(m->flags & ACC_STATIC)) { /* is instance method */
3029 for (j = 0; j < tc->methodscount; j++) {
3030 if (method_canoverwrite(m, &(tc->methods[j]))) {
3031 if (tc->methods[j].flags & ACC_PRIVATE)
3032 goto notfoundvftblindex;
3034 if (tc->methods[j].flags & ACC_FINAL) {
3035 /* class a overrides final method . */
3037 new_exception(string_java_lang_VerifyError);
3040 m->vftblindex = tc->methods[j].vftblindex;
3041 goto foundvftblindex;
3047 m->vftblindex = (vftbllength++);
3053 #if defined(STATISTICS)
3056 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
3059 /* compute interfacetable length */
3061 interfacetablelength = 0;
3064 for (i = 0; i < tc->interfacescount; i++) {
3065 s4 h = class_highestinterface(tc->interfaces[i]) + 1;
3066 if (h > interfacetablelength)
3067 interfacetablelength = h;
3072 /* allocate virtual function table */
3074 v = (vftbl_t*) mem_alloc(sizeof(vftbl_t) + sizeof(methodptr) *
3075 (vftbllength - 1) + sizeof(methodptr*) *
3076 (interfacetablelength - (interfacetablelength > 0)));
3077 v = (vftbl_t*) (((methodptr*) v) + (interfacetablelength - 1) *
3078 (interfacetablelength > 1));
3079 c->header.vftbl = c->vftbl = v;
3081 v->vftbllength = vftbllength;
3082 v->interfacetablelength = interfacetablelength;
3083 v->arraydesc = arraydesc;
3085 /* store interface index in vftbl */
3086 if (c->flags & ACC_INTERFACE)
3087 v->baseval = -(c->index);
3089 /* copy virtual function table of super class */
3091 for (i = 0; i < supervftbllength; i++)
3092 v->table[i] = super->vftbl->table[i];
3094 /* add method stubs into virtual function table */
3096 for (i = 0; i < c->methodscount; i++) {
3097 methodinfo *m = &(c->methods[i]);
3098 if (!(m->flags & ACC_STATIC)) {
3099 v->table[m->vftblindex] = m->stubroutine;
3103 /* compute instance size and offset of each field */
3105 for (i = 0; i < c->fieldscount; i++) {
3107 fieldinfo *f = &(c->fields[i]);
3109 if (!(f->flags & ACC_STATIC)) {
3110 dsize = desc_typesize(f->descriptor);
3111 c->instancesize = ALIGN(c->instancesize, dsize);
3112 f->offset = c->instancesize;
3113 c->instancesize += dsize;
3117 /* initialize interfacetable and interfacevftbllength */
3119 v->interfacevftbllength = MNEW(s4, interfacetablelength);
3121 #if defined(STATISTICS)
3123 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
3126 for (i = 0; i < interfacetablelength; i++) {
3127 v->interfacevftbllength[i] = 0;
3128 v->interfacetable[-i] = NULL;
3131 /* add interfaces */
3133 for (tc = c; tc != NULL; tc = tc->super) {
3134 for (i = 0; i < tc->interfacescount; i++) {
3135 class_addinterface(c, tc->interfaces[i]);
3139 /* add finalizer method (not for java.lang.Object) */
3144 fi = class_findmethod(c, utf_finalize, utf_fidesc);
3147 if (!(fi->flags & ACC_STATIC)) {
3155 loader_compute_subclasses(c);
3158 log_message_class("Linking done class: ", c);
3160 /* just return c to show that we didn't had a problem */
3166 /******************* Function: class_freepool **********************************
3168 Frees all resources used by this classes Constant Pool.
3170 *******************************************************************************/
3172 static void class_freecpool(classinfo *c)
3178 if (c->cptags && c->cpinfos) {
3179 for (idx = 0; idx < c->cpcount; idx++) {
3180 tag = c->cptags[idx];
3181 info = c->cpinfos[idx];
3185 case CONSTANT_Fieldref:
3186 case CONSTANT_Methodref:
3187 case CONSTANT_InterfaceMethodref:
3188 FREE(info, constant_FMIref);
3190 case CONSTANT_Integer:
3191 FREE(info, constant_integer);
3193 case CONSTANT_Float:
3194 FREE(info, constant_float);
3197 FREE(info, constant_long);
3199 case CONSTANT_Double:
3200 FREE(info, constant_double);
3202 case CONSTANT_NameAndType:
3203 FREE(info, constant_nameandtype);
3211 MFREE(c->cptags, u1, c->cpcount);
3214 MFREE(c->cpinfos, voidptr, c->cpcount);
3218 /*********************** Function: class_free **********************************
3220 Frees all resources used by the class.
3222 *******************************************************************************/
3224 void class_free(classinfo *c)
3232 MFREE(c->interfaces, classinfo*, c->interfacescount);
3235 for (i = 0; i < c->fieldscount; i++)
3236 field_free(&(c->fields[i]));
3237 /* MFREE(c->fields, fieldinfo, c->fieldscount); */
3241 for (i = 0; i < c->methodscount; i++)
3242 method_free(&(c->methods[i]));
3243 /* MFREE(c->methods, methodinfo, c->methodscount); */
3246 if ((v = c->vftbl) != NULL) {
3248 mem_free(v->arraydesc,sizeof(arraydescriptor));
3250 for (i = 0; i < v->interfacetablelength; i++) {
3251 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
3253 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
3255 i = sizeof(vftbl_t) + sizeof(methodptr) * (v->vftbllength - 1) +
3256 sizeof(methodptr*) * (v->interfacetablelength -
3257 (v->interfacetablelength > 0));
3258 v = (vftbl_t*) (((methodptr*) v) - (v->interfacetablelength - 1) *
3259 (v->interfacetablelength > 1));
3264 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
3266 /* if (c->classvftbl)
3267 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
3273 /************************* Function: class_findfield ***************************
3275 Searches a 'classinfo' structure for a field having the given name and
3278 *******************************************************************************/
3280 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
3284 for (i = 0; i < c->fieldscount; i++) {
3285 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
3286 return &(c->fields[i]);
3289 panic("Can not find field given in CONSTANT_Fieldref");
3291 /* keep compiler happy */
3296 /****************** Function: class_resolvefield_int ***************************
3298 This is an internally used helper function. Do not use this directly.
3300 Tries to resolve a field having the given name and type.
3301 If the field cannot be resolved, NULL is returned.
3303 *******************************************************************************/
3305 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
3310 /* search for field in class c */
3311 for (i = 0; i < c->fieldscount; i++) {
3312 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
3313 return &(c->fields[i]);
3317 /* try superinterfaces recursively */
3318 for (i = 0; i < c->interfacescount; ++i) {
3319 fi = class_resolvefield_int(c->interfaces[i], name, desc);
3324 /* try superclass */
3326 return class_resolvefield_int(c->super, name, desc);
3333 /********************* Function: class_resolvefield ***************************
3335 Resolves a reference from REFERER to a field with NAME and DESC in class C.
3337 If the field cannot be resolved the return value is NULL. If EXCEPT is
3338 true *exceptionptr is set, too.
3340 *******************************************************************************/
3342 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
3343 classinfo *referer, bool except)
3347 /* XXX resolve class c */
3348 /* XXX check access from REFERER to C */
3350 fi = class_resolvefield_int(c, name, desc);
3355 new_exception_utfmessage(string_java_lang_NoSuchFieldError,
3361 /* XXX check access rights */
3367 /************************* Function: class_findmethod **************************
3369 Searches a 'classinfo' structure for a method having the given name and
3370 type and returns the index in the class info structure.
3371 If type is NULL, it is ignored.
3373 *******************************************************************************/
3375 s4 class_findmethodIndex(classinfo *c, utf *name, utf *desc)
3379 for (i = 0; i < c->methodscount; i++) {
3381 /* utf_display_classname(c->name);printf("."); */
3382 /* utf_display(c->methods[i].name);printf("."); */
3383 /* utf_display(c->methods[i].descriptor); */
3386 if ((c->methods[i].name == name) && ((desc == NULL) ||
3387 (c->methods[i].descriptor == desc))) {
3396 /************************* Function: class_findmethod **************************
3398 Searches a 'classinfo' structure for a method having the given name and
3400 If type is NULL, it is ignored.
3402 *******************************************************************************/
3404 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
3406 s4 idx = class_findmethodIndex(c, name, desc);
3411 return &(c->methods[idx]);
3415 /*********************** Function: class_fetchmethod **************************
3417 like class_findmethod, but aborts with an error if the method is not found
3419 *******************************************************************************/
3421 methodinfo *class_fetchmethod(classinfo *c, utf *name, utf *desc)
3425 mi = class_findmethod(c, name, desc);
3428 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3429 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3430 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3431 panic("Method not found");
3438 /*********************** Function: class_findmethod_w**************************
3440 like class_findmethod, but logs a warning if the method is not found
3442 *******************************************************************************/
3444 methodinfo *class_findmethod_w(classinfo *c, utf *name, utf *desc, char *from)
3447 mi = class_findmethod(c, name, desc);
3450 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3451 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3452 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3454 if ( c->flags & ACC_PUBLIC ) log_plain(" PUBLIC ");
3455 if ( c->flags & ACC_PRIVATE ) log_plain(" PRIVATE ");
3456 if ( c->flags & ACC_PROTECTED ) log_plain(" PROTECTED ");
3457 if ( c->flags & ACC_STATIC ) log_plain(" STATIC ");
3458 if ( c->flags & ACC_FINAL ) log_plain(" FINAL ");
3459 if ( c->flags & ACC_SYNCHRONIZED ) log_plain(" SYNCHRONIZED ");
3460 if ( c->flags & ACC_VOLATILE ) log_plain(" VOLATILE ");
3461 if ( c->flags & ACC_TRANSIENT ) log_plain(" TRANSIENT ");
3462 if ( c->flags & ACC_NATIVE ) log_plain(" NATIVE ");
3463 if ( c->flags & ACC_INTERFACE ) log_plain(" INTERFACE ");
3464 if ( c->flags & ACC_ABSTRACT ) log_plain(" ABSTRACT ");
3467 log_plain(" : WARNING: Method not found");log_nl( );
3474 /************************* Function: class_findmethod_approx ******************
3476 like class_findmethod but ignores the return value when comparing the
3479 *******************************************************************************/
3481 methodinfo *class_findmethod_approx(classinfo *c, utf *name, utf *desc)
3485 for (i = 0; i < c->methodscount; i++) {
3486 if (c->methods[i].name == name) {
3487 utf *meth_descr = c->methods[i].descriptor;
3491 return &(c->methods[i]);
3493 if (desc->blength <= meth_descr->blength) {
3494 /* current position in utf text */
3495 char *desc_utf_ptr = desc->text;
3496 char *meth_utf_ptr = meth_descr->text;
3497 /* points behind utf strings */
3498 char *desc_end = utf_end(desc);
3499 char *meth_end = utf_end(meth_descr);
3502 /* compare argument types */
3503 while (desc_utf_ptr < desc_end && meth_utf_ptr < meth_end) {
3505 if ((ch = *desc_utf_ptr++) != (*meth_utf_ptr++))
3506 break; /* no match */
3509 return &(c->methods[i]); /* all parameter types equal */
3519 /***************** Function: class_resolvemethod_approx ***********************
3521 Searches a class and every super class for a method (without paying
3522 attention to the return value)
3524 *******************************************************************************/
3526 methodinfo *class_resolvemethod_approx(classinfo *c, utf *name, utf *desc)
3529 /* search for method (ignore returntype) */
3530 methodinfo *m = class_findmethod_approx(c, name, desc);
3533 /* search superclass */
3541 /************************* Function: class_resolvemethod ***********************
3543 Searches a class and every super class for a method.
3545 *******************************************************************************/
3547 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
3549 /*log_text("Trying to resolve a method");
3550 utf_display(c->name);
3552 utf_display(desc);*/
3555 /*log_text("Looking in:");
3556 utf_display(c->name);*/
3557 methodinfo *m = class_findmethod(c, name, desc);
3559 /* search superclass */
3562 /*log_text("method not found:");*/
3568 /****************** Function: class_resolveinterfacemethod_int ****************
3570 Internally used helper function. Do not use this directly.
3572 *******************************************************************************/
3575 methodinfo *class_resolveinterfacemethod_int(classinfo *c, utf *name, utf *desc)
3580 mi = class_findmethod(c,name,desc);
3584 /* try the superinterfaces */
3585 for (i=0; i<c->interfacescount; ++i) {
3586 mi = class_resolveinterfacemethod_int(c->interfaces[i],name,desc);
3594 /******************** Function: class_resolveinterfacemethod ******************
3596 Resolves a reference from REFERER to a method with NAME and DESC in
3599 If the method cannot be resolved the return value is NULL. If EXCEPT is
3600 true *exceptionptr is set, too.
3602 *******************************************************************************/
3604 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
3605 classinfo *referer, bool except)
3609 /* XXX resolve class c */
3610 /* XXX check access from REFERER to C */
3612 if (!(c->flags & ACC_INTERFACE)) {
3615 new_exception(string_java_lang_IncompatibleClassChangeError);
3620 mi = class_resolveinterfacemethod_int(c, name, desc);
3625 /* try class java.lang.Object */
3626 mi = class_findmethod(class_java_lang_Object, name, desc);
3633 new_exception_utfmessage(string_java_lang_NoSuchMethodError, name);
3639 /********************* Function: class_resolveclassmethod *********************
3641 Resolves a reference from REFERER to a method with NAME and DESC in
3644 If the method cannot be resolved the return value is NULL. If EXCEPT is
3645 true *exceptionptr is set, too.
3647 *******************************************************************************/
3649 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
3650 classinfo *referer, bool except)
3655 char msg[MAXLOGTEXT];
3657 /* XXX resolve class c */
3658 /* XXX check access from REFERER to C */
3660 /* if (c->flags & ACC_INTERFACE) { */
3662 /* *exceptionptr = */
3663 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
3667 /* try class c and its superclasses */
3670 mi = class_findmethod(cls, name, desc);
3673 } while ((cls = cls->super) != NULL); /* try the superclass */
3675 /* try the superinterfaces */
3676 for (i = 0; i < c->interfacescount; ++i) {
3677 mi = class_resolveinterfacemethod_int(c->interfaces[i], name, desc);
3683 utf_sprint(msg, c->name);
3684 sprintf(msg + strlen(msg), ".");
3685 utf_sprint(msg + strlen(msg), name);
3686 utf_sprint(msg + strlen(msg), desc);
3689 new_exception_message(string_java_lang_NoSuchMethodError, msg);
3695 if ((mi->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
3697 *exceptionptr = new_exception(string_java_lang_AbstractMethodError);
3702 /* XXX check access rights */
3708 /************************* Function: class_issubclass **************************
3710 Checks if sub is a descendant of super.
3712 *******************************************************************************/
3714 bool class_issubclass(classinfo *sub, classinfo *super)
3717 if (!sub) return false;
3718 if (sub == super) return true;
3724 /****************** Initialization function for classes ******************
3726 In Java, every class can have a static initialization function. This
3727 function has to be called BEFORE calling other methods or accessing static
3730 *******************************************************************************/
3732 static classinfo *class_init_intern(classinfo *c);
3734 classinfo *class_init(classinfo *c)
3738 if (!makeinitializations)
3741 #if defined(USE_THREADS)
3742 /* enter a monitor on the class */
3744 builtin_monitorenter((java_objectheader *) c);
3747 /* maybe the class is already initalized or the current thread, which can
3748 pass the monitor, is currently initalizing this class */
3750 /* JOWENN: In future we need an additinal flag: initializationfailed,
3751 since further access to the class should cause a NoClassDefFound,
3752 if the static initializer failed once
3755 if (c->initialized || c->initializing) {
3756 #if defined(USE_THREADS)
3757 builtin_monitorexit((java_objectheader *) c);
3763 /* this initalizing run begins NOW */
3764 c->initializing = true;
3766 /* call the internal function */
3767 r = class_init_intern(c);
3769 /* if return value is not NULL everything was ok and the class is
3772 c->initialized = true;
3774 /* this initalizing run is done */
3775 c->initializing = false;
3777 #if defined(USE_THREADS)
3778 /* leave the monitor */
3780 builtin_monitorexit((java_objectheader *) c);
3787 /* this function MUST NOT be called directly, because of thread <clinit>
3790 static classinfo *class_init_intern(classinfo *c)
3794 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3798 /* maybe the class is not already loaded */
3803 /* maybe the class is not already linked */
3808 #if defined(STATISTICS)
3810 count_class_inits++;
3813 /* initialize super class */
3816 if (!c->super->initialized) {
3818 char logtext[MAXLOGTEXT];
3819 sprintf(logtext, "Initialize super class ");
3820 utf_sprint_classname(logtext + strlen(logtext), c->super->name);
3821 sprintf(logtext + strlen(logtext), " from ");
3822 utf_sprint_classname(logtext + strlen(logtext), c->name);
3826 if (!class_init(c->super))
3831 /* initialize interface classes */
3833 for (i = 0; i < c->interfacescount; i++) {
3834 if (!c->interfaces[i]->initialized) {
3836 char logtext[MAXLOGTEXT];
3837 sprintf(logtext, "Initialize interface class ");
3838 utf_sprint_classname(logtext + strlen(logtext), c->interfaces[i]->name);
3839 sprintf(logtext + strlen(logtext), " from ");
3840 utf_sprint_classname(logtext + strlen(logtext), c->name);
3844 if (!class_init(c->interfaces[i]))
3849 m = class_findmethod(c, utf_clinit, utf_fidesc);
3853 char logtext[MAXLOGTEXT];
3854 sprintf(logtext, "Class ");
3855 utf_sprint_classname(logtext + strlen(logtext), c->name);
3856 sprintf(logtext + strlen(logtext), " has no static class initializer");
3863 /* Sun's and IBM's JVM don't care about the static flag */
3864 /* if (!(m->flags & ACC_STATIC)) { */
3865 /* panic("Class initializer is not static!"); */
3868 log_message_class("Starting static class initializer for class: ", c);
3870 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3875 /* now call the initializer */
3876 asm_calljavafunction(m, NULL, NULL, NULL, NULL);
3878 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3879 assert(blockInts == 0);
3883 /* we have an exception or error */
3884 if (*exceptionptr) {
3885 /* class is NOT initialized */
3886 c->initialized = false;
3888 /* is this an exception, than wrap it */
3889 if (builtin_instanceof(*exceptionptr, class_java_lang_Exception)) {
3890 java_objectheader *xptr;
3891 java_objectheader *cause;
3894 cause = *exceptionptr;
3896 /* clear exception, because we are calling jit code again */
3897 *exceptionptr = NULL;
3899 /* wrap the exception */
3901 new_exception_throwable(string_java_lang_ExceptionInInitializerError,
3902 (java_lang_Throwable *) cause);
3904 /* XXX should we exit here? */
3908 /* set new exception */
3909 *exceptionptr = xptr;
3916 log_message_class("Finished static class initializer for class: ", c);
3922 /********* Function: find_class_method_constant *********/
3924 int find_class_method_constant (classinfo *c, utf * c1, utf* m1, utf* d1)
3929 for (i=0; i<c->cpcount; i++) {
3931 e = c -> cpinfos [i];
3934 switch (c -> cptags [i]) {
3935 case CONSTANT_Methodref:
3937 constant_FMIref *fmi = e;
3938 if ( (fmi->class->name == c1)
3939 && (fmi->name == m1)
3940 && (fmi->descriptor == d1)) {
3947 case CONSTANT_InterfaceMethodref:
3949 constant_FMIref *fmi = e;
3950 if ( (fmi->class->name == c1)
3951 && (fmi->name == m1)
3952 && (fmi->descriptor == d1)) {
3966 void class_showconstanti(classinfo *c, int ii)
3972 printf ("#%d: ", (int) i);
3974 switch (c->cptags [i]) {
3975 case CONSTANT_Class:
3976 printf("Classreference -> ");
3977 utf_display(((classinfo*)e)->name);
3980 case CONSTANT_Fieldref:
3981 printf("Fieldref -> "); goto displayFMIi;
3982 case CONSTANT_Methodref:
3983 printf("Methodref -> "); goto displayFMIi;
3984 case CONSTANT_InterfaceMethodref:
3985 printf("InterfaceMethod -> "); goto displayFMIi;
3988 constant_FMIref *fmi = e;
3989 utf_display(fmi->class->name);
3991 utf_display(fmi->name);
3993 utf_display(fmi->descriptor);
3997 case CONSTANT_String:
3998 printf("String -> ");
4001 case CONSTANT_Integer:
4002 printf("Integer -> %d", (int) (((constant_integer*)e)->value));
4004 case CONSTANT_Float:
4005 printf("Float -> %f", ((constant_float*)e)->value);
4007 case CONSTANT_Double:
4008 printf("Double -> %f", ((constant_double*)e)->value);
4012 u8 v = ((constant_long*)e)->value;
4014 printf("Long -> %ld", (long int) v);
4016 printf("Long -> HI: %ld, LO: %ld\n",
4017 (long int) v.high, (long int) v.low);
4021 case CONSTANT_NameAndType:
4023 constant_nameandtype *cnt = e;
4024 printf("NameAndType: ");
4025 utf_display(cnt->name);
4027 utf_display(cnt->descriptor);
4035 panic("Invalid type of ConstantPool-Entry");
4042 void class_showconstantpool (classinfo *c)
4047 printf ("---- dump of constant pool ----\n");
4049 for (i=0; i<c->cpcount; i++) {
4050 printf ("#%d: ", (int) i);
4052 e = c -> cpinfos [i];
4055 switch (c -> cptags [i]) {
4056 case CONSTANT_Class:
4057 printf ("Classreference -> ");
4058 utf_display ( ((classinfo*)e) -> name );
4061 case CONSTANT_Fieldref:
4062 printf ("Fieldref -> "); goto displayFMI;
4063 case CONSTANT_Methodref:
4064 printf ("Methodref -> "); goto displayFMI;
4065 case CONSTANT_InterfaceMethodref:
4066 printf ("InterfaceMethod -> "); goto displayFMI;
4069 constant_FMIref *fmi = e;
4070 utf_display ( fmi->class->name );
4072 utf_display ( fmi->name);
4074 utf_display ( fmi->descriptor );
4078 case CONSTANT_String:
4079 printf ("String -> ");
4082 case CONSTANT_Integer:
4083 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
4085 case CONSTANT_Float:
4086 printf ("Float -> %f", ((constant_float*)e) -> value);
4088 case CONSTANT_Double:
4089 printf ("Double -> %f", ((constant_double*)e) -> value);
4093 u8 v = ((constant_long*)e) -> value;
4095 printf ("Long -> %ld", (long int) v);
4097 printf ("Long -> HI: %ld, LO: %ld\n",
4098 (long int) v.high, (long int) v.low);
4102 case CONSTANT_NameAndType:
4104 constant_nameandtype *cnt = e;
4105 printf ("NameAndType: ");
4106 utf_display (cnt->name);
4108 utf_display (cnt->descriptor);
4112 printf ("Utf8 -> ");
4116 panic ("Invalid type of ConstantPool-Entry");
4126 /********** Function: class_showmethods (debugging only) *************/
4128 void class_showmethods (classinfo *c)
4132 printf ("--------- Fields and Methods ----------------\n");
4133 printf ("Flags: "); printflags (c->flags); printf ("\n");
4135 printf ("This: "); utf_display (c->name); printf ("\n");
4137 printf ("Super: "); utf_display (c->super->name); printf ("\n");
4139 printf ("Index: %d\n", c->index);
4141 printf ("interfaces:\n");
4142 for (i=0; i < c-> interfacescount; i++) {
4144 utf_display (c -> interfaces[i] -> name);
4145 printf (" (%d)\n", c->interfaces[i] -> index);
4148 printf ("fields:\n");
4149 for (i=0; i < c -> fieldscount; i++) {
4150 field_display (&(c -> fields[i]));
4153 printf ("methods:\n");
4154 for (i=0; i < c -> methodscount; i++) {
4155 methodinfo *m = &(c->methods[i]);
4156 if ( !(m->flags & ACC_STATIC))
4157 printf ("vftblindex: %d ", m->vftblindex);
4159 method_display ( m );
4163 printf ("Virtual function table:\n");
4164 for (i=0; i<c->vftbl->vftbllength; i++) {
4165 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]) );
4171 /******************************************************************************/
4172 /******************* General functions for the class loader *******************/
4173 /******************************************************************************/
4175 /**************** function: create_primitive_classes ***************************
4177 create classes representing primitive types
4179 *******************************************************************************/
4181 static bool create_primitive_classes()
4185 for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
4186 /* create primitive class */
4188 class_new_intern(utf_new_char(primitivetype_table[i].name));
4189 c->classUsed = NOTUSED; /* not used initially CO-RT */
4192 /* prevent loader from loading primitive class */
4197 primitivetype_table[i].class_primitive = c;
4199 /* create class for wrapping the primitive type */
4200 c = class_new_intern(utf_new_char(primitivetype_table[i].wrapname));
4201 primitivetype_table[i].class_wrap = c;
4202 primitivetype_table[i].class_wrap->classUsed = NOTUSED; /* not used initially CO-RT */
4203 primitivetype_table[i].class_wrap->impldBy = NULL;
4205 /* create the primitive array class */
4206 if (primitivetype_table[i].arrayname) {
4207 c = class_new_intern(utf_new_char(primitivetype_table[i].arrayname));
4208 primitivetype_table[i].arrayclass = c;
4213 primitivetype_table[i].arrayvftbl = c->vftbl;
4221 /**************** function: class_primitive_from_sig ***************************
4223 return the primitive class indicated by the given signature character
4225 If the descriptor does not indicate a valid primitive type the
4226 return value is NULL.
4228 ********************************************************************************/
4230 classinfo *class_primitive_from_sig(char sig)
4233 case 'I': return primitivetype_table[PRIMITIVETYPE_INT].class_primitive;
4234 case 'J': return primitivetype_table[PRIMITIVETYPE_LONG].class_primitive;
4235 case 'F': return primitivetype_table[PRIMITIVETYPE_FLOAT].class_primitive;
4236 case 'D': return primitivetype_table[PRIMITIVETYPE_DOUBLE].class_primitive;
4237 case 'B': return primitivetype_table[PRIMITIVETYPE_BYTE].class_primitive;
4238 case 'C': return primitivetype_table[PRIMITIVETYPE_CHAR].class_primitive;
4239 case 'S': return primitivetype_table[PRIMITIVETYPE_SHORT].class_primitive;
4240 case 'Z': return primitivetype_table[PRIMITIVETYPE_BOOLEAN].class_primitive;
4241 case 'V': return primitivetype_table[PRIMITIVETYPE_VOID].class_primitive;
4246 /****************** function: class_from_descriptor ****************************
4248 return the class indicated by the given descriptor
4250 utf_ptr....first character of descriptor
4251 end_ptr....first character after the end of the string
4252 next.......if non-NULL, *next is set to the first character after
4253 the descriptor. (Undefined if an error occurs.)
4255 mode.......a combination (binary or) of the following flags:
4257 (Flags marked with * are the default settings.)
4259 What to do if a reference type descriptor is parsed successfully:
4261 CLASSLOAD_SKIP...skip it and return something != NULL
4262 * CLASSLOAD_NEW....get classinfo * via class_new
4263 CLASSLOAD_LOAD...get classinfo * via loader_load
4265 How to handle primitive types:
4267 * CLASSLOAD_PRIMITIVE.......return primitive class (eg. "int")
4268 CLASSLOAD_NULLPRIMITIVE...return NULL for primitive types
4270 How to handle "V" descriptors:
4272 * CLASSLOAD_VOID.....handle it like other primitive types
4273 CLASSLOAD_NOVOID...treat it as an error
4275 How to deal with extra characters after the end of the
4278 * CLASSLOAD_NOCHECKEND...ignore (useful for parameter lists)
4279 CLASSLOAD_CHECKEND.....treat them as an error
4281 How to deal with errors:
4283 * CLASSLOAD_PANIC....abort execution with an error message
4284 CLASSLOAD_NOPANIC..return NULL on error
4286 *******************************************************************************/
4288 classinfo *class_from_descriptor(char *utf_ptr, char *end_ptr,
4289 char **next, int mode)
4291 char *start = utf_ptr;
4295 SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr, end_ptr, error);
4297 if (mode & CLASSLOAD_CHECKEND)
4298 error |= (utf_ptr != end_ptr);
4301 if (next) *next = utf_ptr;
4305 if (mode & CLASSLOAD_NOVOID)
4316 return (mode & CLASSLOAD_NULLPRIMITIVE)
4318 : class_primitive_from_sig(*start);
4325 if (mode & CLASSLOAD_SKIP) return class_java_lang_Object;
4326 name = utf_new(start, utf_ptr - start);
4330 tc = class_new_intern(name);
4332 list_addfirst(&unlinkedclasses, tc);
4337 return (mode & CLASSLOAD_LOAD)
4338 ? class_load(class_new(name)) : class_new(name); /* XXX handle errors */
4343 /* An error occurred */
4344 if (mode & CLASSLOAD_NOPANIC)
4347 log_plain("Invalid descriptor at beginning of '");
4348 log_plain_utf(utf_new(start, end_ptr - start));
4352 panic("Invalid descriptor");
4354 /* keep compiler happy */
4359 /******************* function: type_from_descriptor ****************************
4361 return the basic type indicated by the given descriptor
4363 This function parses a descriptor and returns its basic type as
4364 TYPE_INT, TYPE_LONG, TYPE_FLOAT, TYPE_DOUBLE, TYPE_ADDRESS or TYPE_VOID.
4366 cls...if non-NULL the referenced variable is set to the classinfo *
4367 returned by class_from_descriptor.
4369 For documentation of the arguments utf_ptr, end_ptr, next and mode
4370 see class_from_descriptor. The only difference is that
4371 type_from_descriptor always uses CLASSLOAD_PANIC.
4373 ********************************************************************************/
4375 int type_from_descriptor(classinfo **cls, char *utf_ptr, char *end_ptr,
4376 char **next, int mode)
4379 if (!cls) cls = &mycls;
4380 *cls = class_from_descriptor(utf_ptr, end_ptr, next, mode & (~CLASSLOAD_NOPANIC));
4397 return TYPE_ADDRESS;
4401 /*************** function: create_pseudo_classes *******************************
4403 create pseudo classes used by the typechecker
4405 ********************************************************************************/
4407 static void create_pseudo_classes()
4409 /* pseudo class for Arraystubs (extends java.lang.Object) */
4411 pseudo_class_Arraystub = class_new_intern(utf_new_char("$ARRAYSTUB$"));
4412 pseudo_class_Arraystub->loaded = true;
4413 pseudo_class_Arraystub->super = class_java_lang_Object;
4414 pseudo_class_Arraystub->interfacescount = 2;
4415 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
4416 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
4417 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
4419 class_link(pseudo_class_Arraystub);
4421 pseudo_class_Arraystub_vftbl = pseudo_class_Arraystub->vftbl;
4423 /* pseudo class representing the null type */
4425 pseudo_class_Null = class_new_intern(utf_new_char("$NULL$"));
4426 pseudo_class_Null->loaded = true;
4427 pseudo_class_Null->super = class_java_lang_Object;
4428 class_link(pseudo_class_Null);
4430 /* pseudo class representing new uninitialized objects */
4432 pseudo_class_New = class_new_intern(utf_new_char("$NEW$"));
4433 pseudo_class_New->loaded = true;
4434 pseudo_class_New->linked = true;
4435 pseudo_class_New->super = class_java_lang_Object;
4436 /* class_link(pseudo_class_New); */
4440 /********************** Function: loader_init **********************************
4442 Initializes all lists and loads all classes required for the system or the
4445 *******************************************************************************/
4447 void loader_init(u1 *stackbottom)
4449 classpath_info *cpi;
4452 /* create utf-symbols for pointer comparison of frequently used strings */
4453 utf_innerclasses = utf_new_char("InnerClasses");
4454 utf_constantvalue = utf_new_char("ConstantValue");
4455 utf_code = utf_new_char("Code");
4456 utf_exceptions = utf_new_char("Exceptions");
4457 utf_linenumbertable = utf_new_char("LineNumberTable");
4458 utf_sourcefile = utf_new_char("SourceFile");
4459 utf_finalize = utf_new_char("finalize");
4460 utf_fidesc = utf_new_char("()V");
4461 utf_init = utf_new_char("<init>");
4462 utf_clinit = utf_new_char("<clinit>");
4463 utf_initsystemclass = utf_new_char("initializeSystemClass");
4464 utf_systemclass = utf_new_char("java/lang/System");
4465 utf_vmclassloader = utf_new_char("java/lang/VMClassLoader");
4466 utf_initialize = utf_new_char("initialize");
4467 utf_initializedesc = utf_new_char("(I)V");
4468 utf_vmclass = utf_new_char("java/lang/VMClass");
4469 utf_java_lang_Object= utf_new_char("java/lang/Object");
4470 array_packagename = utf_new_char("<the array package>");
4471 utf_fillInStackTrace_name = utf_new_char("fillInStackTrace");
4472 utf_fillInStackTrace_desc = utf_new_char("()Ljava/lang/Throwable;");
4475 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4476 /* Initialize the monitor pointer for zip/jar file locking. */
4478 for (cpi = classpath_entries; cpi != NULL; cpi = cpi->next) {
4479 if (cpi->type == CLASSPATH_ARCHIVE)
4480 initObjectLock(&cpi->header);
4484 /* Create some important classes. These classes have to be created now */
4485 /* because the classinfo pointers are used in the loading code. */
4487 class_java_lang_Object = class_new_intern(utf_java_lang_Object);
4488 class_load(class_java_lang_Object);
4489 class_link(class_java_lang_Object);
4491 class_java_lang_String = class_new(utf_new_char("java/lang/String"));
4492 class_load(class_java_lang_String);
4493 class_link(class_java_lang_String);
4495 class_java_lang_Cloneable = class_new(utf_new_char("java/lang/Cloneable"));
4496 class_load(class_java_lang_Cloneable);
4497 class_link(class_java_lang_Cloneable);
4499 class_java_io_Serializable =
4500 class_new(utf_new_char("java/io/Serializable"));
4501 class_load(class_java_io_Serializable);
4502 class_link(class_java_io_Serializable);
4504 /* create classes representing primitive types */
4505 create_primitive_classes();
4507 /* create classes used by the typechecker */
4508 create_pseudo_classes();
4510 /* correct vftbl-entries (retarded loading of class java/lang/String) */
4511 stringtable_update();
4513 #if defined(USE_THREADS)
4514 if (stackbottom != 0)
4520 /* loader_compute_subclasses ***************************************************
4524 *******************************************************************************/
4526 static void loader_compute_class_values(classinfo *c);
4528 void loader_compute_subclasses(classinfo *c)
4530 #if defined(USE_THREADS)
4531 #if defined(NATIVE_THREADS)
4538 if (!(c->flags & ACC_INTERFACE)) {
4543 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
4544 c->nextsub = c->super->sub;
4550 /* this is the java.lang.Object special case */
4552 if (!class_java_lang_Object) {
4553 loader_compute_class_values(c);
4556 loader_compute_class_values(class_java_lang_Object);
4559 #if defined(USE_THREADS)
4560 #if defined(NATIVE_THREADS)
4569 /* loader_compute_class_values *************************************************
4573 *******************************************************************************/
4575 static void loader_compute_class_values(classinfo *c)
4579 c->vftbl->baseval = ++classvalue;
4583 loader_compute_class_values(subs);
4584 subs = subs->nextsub;
4587 c->vftbl->diffval = classvalue - c->vftbl->baseval;
4591 /******************** Function: loader_close ***********************************
4595 *******************************************************************************/
4602 for (slot = 0; slot < class_hash.size; slot++) {
4603 c = class_hash.ptr[slot];
4614 * These are local overrides for various environment variables in Emacs.
4615 * Please do not remove this and leave it at the end of the file, where
4616 * Emacs will automagically detect them.
4617 * ---------------------------------------------------------------------
4620 * indent-tabs-mode: t