1 /* loader.c - class loader functions
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5 M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6 P. Tomsich, J. Wenninger
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Reinhard Grafl
28 Changes: Andreas Krall
33 $Id: loader.c 1173 2004-06-16 14:56:18Z jowenn $
50 #include "toolbox/memory.h"
51 #include "toolbox/logging.h"
52 #include "threads/thread.h"
53 #include "threads/locks.h"
54 #include "nat/java_lang_Throwable.h"
64 /* global variables ***********************************************************/
66 int count_class_infos = 0; /* variables for measurements */
67 int count_const_pool_len = 0;
68 int count_vftbl_len = 0;
69 int count_all_methods = 0;
70 int count_vmcode_len = 0;
71 int count_extable_len = 0;
72 int count_class_loads = 0;
73 int count_class_inits = 0;
75 static s4 interfaceindex; /* sequential numbering of interfaces */
79 /* utf-symbols for pointer comparison of frequently used strings */
81 static utf *utf_innerclasses; /* InnerClasses */
82 static utf *utf_constantvalue; /* ConstantValue */
83 static utf *utf_code; /* Code */
84 static utf *utf_exceptions; /* Exceptions */
85 static utf *utf_linenumbertable; /* LineNumberTable */
86 static utf *utf_sourcefile; /* SourceFile */
87 static utf *utf_finalize; /* finalize */
88 static utf *utf_fidesc; /* ()V changed */
89 static utf *utf_init; /* <init> */
90 static utf *utf_clinit; /* <clinit> */
91 static utf *utf_initsystemclass; /* initializeSystemClass */
92 static utf *utf_systemclass; /* java/lang/System */
93 static utf *utf_vmclassloader; /* java/lang/VMClassLoader */
94 static utf *utf_vmclass; /* java/lang/VMClassLoader */
95 static utf *utf_initialize;
96 static utf *utf_initializedesc;
97 static utf *utf_java_lang_Object; /* java/lang/Object */
99 utf *utf_fillInStackTrace_name;
100 utf *utf_fillInStackTrace_desc;
110 /* important system classes ***************************************************/
112 classinfo *class_java_lang_Object;
113 classinfo *class_java_lang_String;
114 classinfo *class_java_lang_Cloneable;
115 classinfo *class_java_io_Serializable;
117 /* Pseudo classes for the typechecker */
118 classinfo *pseudo_class_Arraystub = NULL;
119 classinfo *pseudo_class_Null = NULL;
120 classinfo *pseudo_class_New = NULL;
121 vftbl *pseudo_class_Arraystub_vftbl = NULL;
123 utf *array_packagename = NULL;
126 /********************************************************************
127 list of classpath entries (either filesystem directories or
129 ********************************************************************/
130 static classpath_info *classpath_entries=0;
133 /******************************************************************************
135 structure for primitive classes: contains the class for wrapping the
136 primitive type, the primitive class, the name of the class for wrapping,
137 the one character type signature and the name of the primitive class
139 ******************************************************************************/
141 /* CAUTION: Don't change the order of the types. This table is indexed
142 * by the ARRAYTYPE_ constants (expcept ARRAYTYPE_OBJECT).
144 primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = {
145 { NULL, NULL, "java/lang/Integer", 'I', "int" , "[I", NULL, NULL },
146 { NULL, NULL, "java/lang/Long", 'J', "long" , "[J", NULL, NULL },
147 { NULL, NULL, "java/lang/Float", 'F', "float" , "[F", NULL, NULL },
148 { NULL, NULL, "java/lang/Double", 'D', "double" , "[D", NULL, NULL },
149 { NULL, NULL, "java/lang/Byte", 'B', "byte" , "[B", NULL, NULL },
150 { NULL, NULL, "java/lang/Character", 'C', "char" , "[C", NULL, NULL },
151 { NULL, NULL, "java/lang/Short", 'S', "short" , "[S", NULL, NULL },
152 { NULL, NULL, "java/lang/Boolean", 'Z', "boolean" , "[Z", NULL, NULL },
153 { NULL, NULL, "java/lang/Void", 'V', "void" , NULL, NULL, NULL }
157 /* instances of important system classes **************************************/
159 java_objectheader *proto_java_lang_NullPointerException;
162 /************* functions for reading classdata *********************************
164 getting classdata in blocks of variable size
165 (8,16,32,64-bit integer or float)
167 *******************************************************************************/
169 static char *classpath = ""; /* searchpath for classfiles */
172 /* assert that at least <len> bytes are left to read */
173 /* <len> is limited to the range of non-negative s4 values */
175 #define ASSERT_LEFT(cb, len) \
177 if (((s4) (len)) < 0 || \
178 (((cb)->data + (cb)->size) - (cb)->pos - 1) < (len)) { \
179 char message[MAXLOGTEXT]; \
180 utf_sprint_classname(message, (cb)->class->name); \
181 sprintf(message + strlen(message), " (Truncated class file)"); \
183 new_exception_message(string_java_lang_ClassFormatError, \
185 throw_exception_exit(); \
190 /* transfer block of classfile data into a buffer */
192 #define suck_nbytes(buffer, cb, len) \
194 ASSERT_LEFT((cb), (len)); \
195 memcpy((buffer), (cb)->pos + 1, (len)); \
196 (cb)->pos += (len); \
200 /* skip block of classfile data */
202 #define skip_nbytes(cb, len) \
204 ASSERT_LEFT((cb), (len)); \
205 (cb)->pos += (len); \
209 inline u1 suck_u1(classbuffer *cb)
216 inline u2 suck_u2(classbuffer *cb)
220 return ((u2) a << 8) + (u2) b;
224 inline u4 suck_u4(classbuffer *cb)
230 return ((u4) a << 24) + ((u4) b << 16) + ((u4) c << 8) + (u4) d;
233 #define suck_s8(a) (s8) suck_u8((a))
234 #define suck_s2(a) (s2) suck_u2((a))
235 #define suck_s4(a) (s4) suck_u4((a))
236 #define suck_s1(a) (s1) suck_u1((a))
239 /* get u8 from classfile data */
240 static u8 suck_u8(classbuffer *cb)
246 return (hi << 32) + lo;
249 v.high = suck_u4(cb);
256 /* get float from classfile data */
257 static float suck_float(classbuffer *cb)
265 for (i = 0; i < 4; i++)
266 buffer[3 - i] = suck_u1(cb);
268 memcpy((u1*) (&f), buffer, 4);
270 suck_nbytes((u1*) (&f), cb, 4);
273 if (sizeof(float) != 4) {
275 new_exception_message(string_java_lang_InternalError,
276 "Incompatible float-format");
278 /* XXX should we exit in such a case? */
279 throw_exception_exit();
286 /* get double from classfile data */
287 static double suck_double(classbuffer *cb)
295 for (i = 0; i < 8; i++)
296 buffer[7 - i] = suck_u1(cb);
298 memcpy((u1*) (&d), buffer, 8);
300 suck_nbytes((u1*) (&d), cb, 8);
303 if (sizeof(double) != 8) {
305 new_exception_message(string_java_lang_InternalError,
306 "Incompatible double-format");
308 /* XXX should we exit in such a case? */
309 throw_exception_exit();
316 /************************** function suck_init *********************************
318 called once at startup, sets the searchpath for the classfiles
320 *******************************************************************************/
322 void suck_init(char *cpath)
329 union classpath_info *tmp;
330 union classpath_info *insertAfter=0;
337 if (classpath_entries)
338 panic("suck_init should be called only once");
340 for (start = classpath; (*start) != '\0';) {
341 for (end = start; ((*end) != '\0') && ((*end) != ':'); end++);
345 filenamelen = end - start;
348 if (strncasecmp(end - 3, "zip", 3) == 0 ||
349 strncasecmp(end - 3, "jar", 3) == 0) {
354 if (filenamelen >= (CLASSPATH_MAXFILENAME - 1))
355 panic("path length >= MAXFILENAME in suck_init");
358 filename = MNEW(char, CLASSPATH_MAXFILENAME);
360 strncpy(filename, start, filenamelen);
361 filename[filenamelen + 1] = '\0';
366 unzFile uf = unzOpen(filename);
369 tmp = (union classpath_info *) NEW(classpath_info);
370 tmp->archive.type = CLASSPATH_ARCHIVE;
371 tmp->archive.uf = uf;
372 tmp->archive.next = 0;
376 panic("Zip/JAR not supported");
380 tmp = (union classpath_info *) NEW(classpath_info);
381 tmp->filepath.type = CLASSPATH_PATH;
382 tmp->filepath.next = 0;
384 if (filename[filenamelen - 1] != '/') {/*PERHAPS THIS SHOULD BE READ FROM A GLOBAL CONFIGURATION */
385 filename[filenamelen] = '/';
386 filename[filenamelen + 1] = '\0';
390 tmp->filepath.filename = filename;
391 tmp->filepath.pathlen = filenamelen;
397 insertAfter->filepath.next = tmp;
400 classpath_entries = tmp;
412 MFREE(filename, char, CLASSPATH_MAXFILENAME);
419 void create_all_classes()
423 for (cpi = classpath_entries; cpi != 0; cpi = cpi->filepath.next) {
424 #if defined(USE_ZLIB)
425 if (cpi->filepath.type == CLASSPATH_ARCHIVE) {
429 s = (unz_s *) cpi->archive.uf;
430 ce = s->cacao_dir_list;
433 (void) class_new(ce->name);
439 #if defined(USE_ZLIB)
446 /************************** function suck_start ********************************
448 returns true if classbuffer is already loaded or a file for the
449 specified class has succussfully been read in. All directories of
450 the searchpath are used to find the classfile (<classname>.class).
451 Returns false if no classfile is found and writes an error message.
453 *******************************************************************************/
455 classbuffer *suck_start(classinfo *c)
457 classpath_info *currPos;
460 char filename[CLASSPATH_MAXFILENAME+10]; /* room for '.class' */
467 utf_ptr = c->name->text;
469 while (utf_ptr < utf_end(c->name)) {
470 if (filenamelen >= CLASSPATH_MAXFILENAME) {
472 new_exception_message(string_java_lang_InternalError,
473 "Filename too long");
475 /* XXX should we exit in such a case? */
476 throw_exception_exit();
480 if ((ch <= ' ' || ch > 'z') && (ch != '/')) /* invalid character */
482 filename[filenamelen++] = ch;
485 strcpy(filename + filenamelen, ".class");
488 for (currPos = classpath_entries; currPos != 0; currPos = currPos->filepath.next) {
490 if (currPos->filepath.type == CLASSPATH_ARCHIVE) {
491 if (cacao_locate(currPos->archive.uf, c->name) == UNZ_OK) {
492 unz_file_info file_info;
493 /*log_text("Class found in zip file");*/
494 if (unzGetCurrentFileInfo(currPos->archive.uf, &file_info, filename,
495 sizeof(filename), NULL, 0, NULL, 0) == UNZ_OK) {
496 if (unzOpenCurrentFile(currPos->archive.uf) == UNZ_OK) {
497 cb = NEW(classbuffer);
499 cb->size = file_info.uncompressed_size;
500 cb->data = MNEW(u1, cb->size);
501 cb->pos = cb->data - 1;
502 /*printf("classfile size: %d\n",file_info.uncompressed_size);*/
503 if (unzReadCurrentFile(currPos->archive.uf, cb->data, cb->size) == cb->size) {
504 unzCloseCurrentFile(currPos->archive.uf);
508 MFREE(cb->data, u1, cb->size);
509 FREE(cb, classbuffer);
510 log_text("Error while unzipping");
512 } else log_text("Error while opening file in archive");
513 } else log_text("Error while retrieving fileinfo");
515 unzCloseCurrentFile(currPos->archive.uf);
519 if ((currPos->filepath.pathlen + filenamelen) >= CLASSPATH_MAXFILENAME) continue;
520 strcpy(currPos->filepath.filename + currPos->filepath.pathlen, filename);
521 classfile = fopen(currPos->filepath.filename, "r");
522 if (classfile) { /* file exists */
524 /* determine size of classfile */
526 /* dolog("File: %s",filename); */
527 err = stat(currPos->filepath.filename, &buffer);
529 if (!err) { /* read classfile data */
530 cb = NEW(classbuffer);
532 cb->size = buffer.st_size;
533 cb->data = MNEW(u1, cb->size);
534 cb->pos = cb->data - 1;
535 fread(cb->data, 1, cb->size, classfile);
547 dolog("Warning: Can not open class file '%s'", filename);
554 /************************** function suck_stop *********************************
556 frees memory for buffer with classfile data.
557 Caution: this function may only be called if buffer has been allocated
558 by suck_start with reading a file
560 *******************************************************************************/
562 void suck_stop(classbuffer *cb)
566 MFREE(cb->data, u1, cb->size);
567 FREE(cb, classbuffer);
571 /******************************************************************************/
572 /******************* Some support functions ***********************************/
573 /******************************************************************************/
575 void fprintflags (FILE *fp, u2 f)
577 if ( f & ACC_PUBLIC ) fprintf (fp," PUBLIC");
578 if ( f & ACC_PRIVATE ) fprintf (fp," PRIVATE");
579 if ( f & ACC_PROTECTED ) fprintf (fp," PROTECTED");
580 if ( f & ACC_STATIC ) fprintf (fp," STATIC");
581 if ( f & ACC_FINAL ) fprintf (fp," FINAL");
582 if ( f & ACC_SYNCHRONIZED ) fprintf (fp," SYNCHRONIZED");
583 if ( f & ACC_VOLATILE ) fprintf (fp," VOLATILE");
584 if ( f & ACC_TRANSIENT ) fprintf (fp," TRANSIENT");
585 if ( f & ACC_NATIVE ) fprintf (fp," NATIVE");
586 if ( f & ACC_INTERFACE ) fprintf (fp," INTERFACE");
587 if ( f & ACC_ABSTRACT ) fprintf (fp," ABSTRACT");
591 /********** internal function: printflags (only for debugging) ***************/
593 void printflags(u2 f)
595 if ( f & ACC_PUBLIC ) printf (" PUBLIC");
596 if ( f & ACC_PRIVATE ) printf (" PRIVATE");
597 if ( f & ACC_PROTECTED ) printf (" PROTECTED");
598 if ( f & ACC_STATIC ) printf (" STATIC");
599 if ( f & ACC_FINAL ) printf (" FINAL");
600 if ( f & ACC_SYNCHRONIZED ) printf (" SYNCHRONIZED");
601 if ( f & ACC_VOLATILE ) printf (" VOLATILE");
602 if ( f & ACC_TRANSIENT ) printf (" TRANSIENT");
603 if ( f & ACC_NATIVE ) printf (" NATIVE");
604 if ( f & ACC_INTERFACE ) printf (" INTERFACE");
605 if ( f & ACC_ABSTRACT ) printf (" ABSTRACT");
609 /************************* Function: skipattribute *****************************
611 skips a (1) 'attribute' structure in the class file
613 *******************************************************************************/
615 static void skipattribute(classbuffer *cb)
620 skip_nbytes(cb, len);
624 /********************** Function: skipattributebody ****************************
626 skips an attribute after the 16 bit reference to attribute_name has already
629 *******************************************************************************/
631 static void skipattributebody(classbuffer *cb)
635 skip_nbytes(cb, len);
639 /************************* Function: skipattributes ****************************
641 skips num attribute structures
643 *******************************************************************************/
645 static void skipattributes(classbuffer *cb, u4 num)
648 for (i = 0; i < num; i++)
653 /******************** function: innerclass_getconstant ************************
655 like class_getconstant, but if cptags is ZERO null is returned
657 *******************************************************************************/
659 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype)
661 /* invalid position in constantpool */
662 if (pos >= c->cpcount)
663 panic("Attempt to access constant outside range");
665 /* constantpool entry of type 0 */
669 /* check type of constantpool entry */
670 if (c->cptags[pos] != ctype) {
671 error("Type mismatch on constant: %d requested, %d here (innerclass_getconstant)",
672 (int) ctype, (int) c->cptags[pos] );
675 return c->cpinfos[pos];
679 /************************ function: attribute_load ****************************
681 read attributes from classfile
683 *******************************************************************************/
685 static void attribute_load(classbuffer *cb, classinfo *c, u4 num)
689 for (i = 0; i < num; i++) {
690 /* retrieve attribute name */
691 utf *aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
693 if (aname == utf_innerclasses) {
694 /* innerclasses attribute */
696 if (c->innerclass != NULL)
697 panic("Class has more than one InnerClasses attribute");
699 /* skip attribute length */
701 /* number of records */
702 c->innerclasscount = suck_u2(cb);
703 /* allocate memory for innerclass structure */
704 c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
706 for (j = 0; j < c->innerclasscount; j++) {
707 /* The innerclass structure contains a class with an encoded name,
708 its defining scope, its simple name and a bitmask of the access flags.
709 If an inner class is not a member, its outer_class is NULL,
710 if a class is anonymous, its name is NULL. */
712 innerclassinfo *info = c->innerclass + j;
714 info->inner_class = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class); /* CONSTANT_Class_info index */
715 info->outer_class = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class); /* CONSTANT_Class_info index */
716 info->name = innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8); /* CONSTANT_Utf8_info index */
717 info->flags = suck_u2(cb); /* access_flags bitmask */
719 } else if (aname==utf_sourcefile) {
721 /*log_text("source file attribute found");*/
722 c->sourcefile = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
724 /* unknown attribute */
725 skipattributebody(cb);
731 /******************* function: checkfielddescriptor ****************************
733 checks whether a field-descriptor is valid and aborts otherwise
734 all referenced classes are inserted into the list of unloaded classes
736 *******************************************************************************/
738 static void checkfielddescriptor (char *utf_ptr, char *end_pos)
740 class_from_descriptor(utf_ptr,end_pos,NULL,
742 | CLASSLOAD_NULLPRIMITIVE
744 | CLASSLOAD_CHECKEND);
746 /* XXX use the following if -noverify */
748 char *tstart; /* pointer to start of classname */
750 char *start = utf_ptr;
752 switch (*utf_ptr++) {
766 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
767 panic ("Ill formed descriptor");
771 panic ("Ill formed descriptor");
774 /* exceeding characters */
775 if (utf_ptr!=end_pos) panic ("descriptor has exceeding chars");
780 /******************* function checkmethoddescriptor ****************************
782 checks whether a method-descriptor is valid and aborts otherwise.
783 All referenced classes are inserted into the list of unloaded classes.
785 The number of arguments is returned. A long or double argument is counted
788 *******************************************************************************/
790 static int checkmethoddescriptor (utf *d)
792 char *utf_ptr = d->text; /* current position in utf text */
793 char *end_pos = utf_end(d); /* points behind utf string */
794 int argcount = 0; /* number of arguments */
796 /* method descriptor must start with parenthesis */
797 if (utf_ptr == end_pos || *utf_ptr++ != '(') panic ("Missing '(' in method descriptor");
799 /* check arguments */
800 while (utf_ptr != end_pos && *utf_ptr != ')') {
801 /* We cannot count the this argument here because
802 * we don't know if the method is static. */
803 if (*utf_ptr == 'J' || *utf_ptr == 'D')
807 class_from_descriptor(utf_ptr,end_pos,&utf_ptr,
809 | CLASSLOAD_NULLPRIMITIVE
813 if (utf_ptr == end_pos) panic("Missing ')' in method descriptor");
814 utf_ptr++; /* skip ')' */
816 class_from_descriptor(utf_ptr,end_pos,NULL,
818 | CLASSLOAD_NULLPRIMITIVE
819 | CLASSLOAD_CHECKEND);
822 panic("Invalid method descriptor: too many arguments");
826 /* XXX use the following if -noverify */
828 /* check arguments */
829 while ((c = *utf_ptr++) != ')') {
846 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
847 panic ("Ill formed method descriptor");
851 panic ("Ill formed methodtype-descriptor");
855 /* check returntype */
857 /* returntype void */
858 if ((utf_ptr+1) != end_pos) panic ("Method-descriptor has exceeding chars");
861 /* treat as field-descriptor */
862 checkfielddescriptor (utf_ptr,end_pos);
867 /***************** Function: print_arraydescriptor ****************************
869 Debugging helper for displaying an arraydescriptor
871 *******************************************************************************/
873 void print_arraydescriptor(FILE *file, arraydescriptor *desc)
876 fprintf(file, "<NULL>");
881 if (desc->componentvftbl) {
882 if (desc->componentvftbl->class)
883 utf_fprint(file, desc->componentvftbl->class->name);
885 fprintf(file, "<no classinfo>");
891 if (desc->elementvftbl) {
892 if (desc->elementvftbl->class)
893 utf_fprint(file, desc->elementvftbl->class->name);
895 fprintf(file, "<no classinfo>");
899 fprintf(file, ",%d,%d,%d,%d}", desc->arraytype, desc->dimension,
900 desc->dataoffset, desc->componentsize);
904 /******************************************************************************/
905 /************************** Functions for fields ****************************/
906 /******************************************************************************/
909 /************************ Function: field_load *********************************
911 Load everything about a class field from the class file and fill a
912 'fieldinfo' structure. For static fields, space in the data segment is
915 *******************************************************************************/
917 #define field_load_NOVALUE 0xffffffff /* must be bigger than any u2 value! */
919 static fieldinfo *field_load(classbuffer *cb, classinfo *c, fieldinfo *f)
923 u4 pindex = field_load_NOVALUE; /* constantvalue_index */
925 f->flags = suck_u2(cb); /* ACC flags */
926 f->name = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8); /* name of field */
927 f->descriptor = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8); /* JavaVM descriptor */
931 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<')
932 panic("Field with invalid name");
934 /* check flag consistency */
935 i = (f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
936 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED)
937 panic("Field has invalid access flags");
938 if ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))
939 panic("Field is declared final and volatile");
940 if ((c->flags & ACC_INTERFACE) != 0) {
941 if ((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
942 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
943 panic("Interface field is not declared static final public");
944 if ((f->flags & ACC_TRANSIENT) != 0)
945 panic("Interface field declared transient");
948 /* check descriptor */
949 checkfielddescriptor(f->descriptor->text,utf_end(f->descriptor));
952 f->type = jtype = desc_to_type(f->descriptor); /* data type */
953 f->offset = 0; /* offset from start of object */
958 case TYPE_INT: f->value.i = 0; break;
959 case TYPE_FLOAT: f->value.f = 0.0; break;
960 case TYPE_DOUBLE: f->value.d = 0.0; break;
961 case TYPE_ADDRESS: f->value.a = NULL; break;
964 f->value.l = 0; break;
966 f->value.l.low = 0; f->value.l.high = 0; break;
970 /* read attributes */
971 attrnum = suck_u2(cb);
972 for (i = 0; i < attrnum; i++) {
975 aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
977 if (aname != utf_constantvalue) {
978 /* unknown attribute */
979 skipattributebody(cb);
982 /* constant value attribute */
984 if (pindex != field_load_NOVALUE)
985 panic("Field has more than one ConstantValue attribute");
987 /* check attribute length */
988 if (suck_u4(cb) != 2)
989 panic("ConstantValue attribute has invalid length");
991 /* index of value in constantpool */
992 pindex = suck_u2(cb);
994 /* initialize field with value from constantpool */
997 constant_integer *ci =
998 class_getconstant(c, pindex, CONSTANT_Integer);
999 f->value.i = ci->value;
1005 class_getconstant(c, pindex, CONSTANT_Long);
1006 f->value.l = cl->value;
1011 constant_float *cf =
1012 class_getconstant(c, pindex, CONSTANT_Float);
1013 f->value.f = cf->value;
1018 constant_double *cd =
1019 class_getconstant(c, pindex, CONSTANT_Double);
1020 f->value.d = cd->value;
1024 case TYPE_ADDRESS: {
1025 utf *u = class_getconstant(c, pindex, CONSTANT_String);
1026 /* create javastring from compressed utf8-string */
1027 f->value.a = literalstring_new(u);
1032 log_text ("Invalid Constant - Type");
1037 /* just return fieldinfo* to signal everything was ok */
1043 /********************** function: field_free **********************************/
1045 static void field_free(fieldinfo *f)
1051 /**************** Function: field_display (debugging only) ********************/
1053 void field_display(fieldinfo *f)
1056 printflags(f->flags);
1058 utf_display(f->name);
1060 utf_display(f->descriptor);
1061 printf(" offset: %ld\n", (long int) (f->offset));
1065 /******************************************************************************/
1066 /************************* Functions for methods ******************************/
1067 /******************************************************************************/
1070 /*********************** Function: method_load *********************************
1072 Loads a method from the class file and fills an existing 'methodinfo'
1073 structure. For native methods, the function pointer field is set to the
1074 real function pointer, for JavaVM methods a pointer to the compiler is used
1077 *******************************************************************************/
1079 static methodinfo *method_load(classbuffer *cb, classinfo *c, methodinfo *m)
1083 char msg[MAXLOGTEXT]; /* maybe we get an exception */
1087 count_all_methods++;
1090 m->thrownexceptionscount = 0;
1091 m->linenumbercount = 0;
1094 m->nativelyoverloaded=false;
1095 m->flags = suck_u2(cb);
1096 m->name = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1099 if (!is_valid_name_utf(m->name))
1100 panic("Method with invalid name");
1101 if (m->name->text[0] == '<'
1102 && m->name != utf_init && m->name != utf_clinit)
1103 panic("Method with invalid special name");
1106 m->descriptor = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1107 argcount = checkmethoddescriptor(m->descriptor);
1108 if (!(m->flags & ACC_STATIC))
1109 argcount++; /* count the 'this' argument */
1113 panic("Too many arguments in signature");
1115 /* check flag consistency */
1116 if (m->name != utf_clinit) {
1117 i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1118 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED)
1119 panic("Method has invalid access flags");
1121 if ((m->flags & ACC_ABSTRACT) != 0) {
1122 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1123 ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1124 utf_sprint(msg, c->name);
1125 sprintf(msg + strlen(msg), " (Illegal method modifiers: 0x%x)", m->flags);
1128 new_exception_message(string_java_lang_ClassFormatError,
1135 if ((c->flags & ACC_INTERFACE) != 0) {
1136 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC))
1137 != (ACC_ABSTRACT | ACC_PUBLIC))
1138 panic("Interface method is not declared abstract and public");
1141 if (m->name == utf_init) {
1142 if ((m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED
1143 | ACC_NATIVE | ACC_ABSTRACT)) != 0)
1144 panic("Instance initialization method has invalid flags set");
1150 m->exceptiontable = NULL;
1151 m->entrypoint = NULL;
1153 m->stubroutine = NULL;
1154 m->methodUsed = NOTUSED;
1157 m->subRedefsUsed = 0;
1161 if (!(m->flags & ACC_NATIVE)) {
1162 m->stubroutine = createcompilerstub(m);
1165 functionptr f = native_findfunction(c->name, m->name, m->descriptor,
1166 (m->flags & ACC_STATIC) != 0);
1168 m->stubroutine = createnativestub(f, m);
1173 attrnum = suck_u2(cb);
1174 for (i = 0; i < attrnum; i++) {
1177 aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1179 if (aname != utf_code) {
1180 if (aname == utf_exceptions) {
1183 suck_u4(cb); /*length*/
1184 exceptionCount=suck_u2(cb);
1185 m->thrownexceptionscount=exceptionCount;
1186 m->thrownexceptions=MNEW(classinfo*,exceptionCount);
1187 for (exceptionID=0;exceptionID<exceptionCount;exceptionID++) {
1188 (m->thrownexceptions)[exceptionID]=class_getconstant(c,suck_u2(cb),CONSTANT_Class);
1192 skipattributebody(cb);
1196 if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1197 utf_sprint(msg, c->name);
1198 sprintf(msg + strlen(msg),
1199 " (Code attribute in native or abstract methods)");
1202 new_exception_message(string_java_lang_ClassFormatError,
1209 utf_sprint(msg, c->name);
1210 sprintf(msg + strlen(msg), " (Multiple Code attributes)");
1213 new_exception_message(string_java_lang_ClassFormatError,
1220 m->maxstack = suck_u2(cb);
1221 m->maxlocals = suck_u2(cb);
1222 if (m->maxlocals < argcount) {
1223 utf_sprint(msg, c->name);
1224 sprintf(msg + strlen(msg),
1225 " (Arguments can't fit into locals)");
1228 new_exception_message(string_java_lang_ClassFormatError,
1234 codelen = suck_u4(cb);
1237 panic("bytecode has zero length");
1239 if (codelen > 65535) {
1240 utf_sprint(msg, c->name);
1241 sprintf(msg + strlen(msg),
1242 " (Code of a method longer than 65535 bytes)");
1245 new_exception_message(string_java_lang_ClassFormatError,
1251 m->jcodelength = codelen;
1252 m->jcode = MNEW(u1, m->jcodelength);
1253 suck_nbytes(m->jcode, cb, m->jcodelength);
1255 m->exceptiontablelength = suck_u2(cb);
1256 m->exceptiontable = MNEW(exceptiontable, m->exceptiontablelength);
1260 count_vmcode_len += m->jcodelength + 18;
1261 count_extable_len += 8 * m->exceptiontablelength;
1265 for (e = 0; e < m->exceptiontablelength; e++) {
1267 m->exceptiontable[e].startpc = suck_u2(cb);
1268 m->exceptiontable[e].endpc = suck_u2(cb);
1269 m->exceptiontable[e].handlerpc = suck_u2(cb);
1273 m->exceptiontable[e].catchtype = NULL;
1276 m->exceptiontable[e].catchtype =
1277 class_getconstant(c, idx, CONSTANT_Class);
1282 for (codeattrnum=suck_u2(cb);codeattrnum>0;codeattrnum--) {
1283 utf * caname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1284 if (caname==utf_linenumbertable) {
1286 /*log_text("LineNumberTable found");*/
1288 m->linenumbercount=suck_u2(cb);
1289 /*printf("length:%d\n",m->linenumbercount);*/
1290 m->linenumbers=MNEW(lineinfo,m->linenumbercount);
1291 for (lncid=0;lncid<m->linenumbercount;lncid++) {
1292 m->linenumbers[lncid].start_pc=suck_u2(cb);
1293 m->linenumbers[lncid].line_number=suck_u2(cb);
1296 skipattributes(cb, codeattrnum);
1298 } else skipattributebody(cb);
1305 if (!m->jcode && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1306 utf_sprint(msg, c->name);
1307 sprintf(msg + strlen(msg), " (Missing Code attribute)");
1310 new_exception_message(string_java_lang_ClassFormatError, msg);
1315 /* just return methodinfo* to signal everything was ok */
1321 /********************* Function: method_free ***********************************
1323 frees all memory that was allocated for this method
1325 *******************************************************************************/
1327 static void method_free(methodinfo *m)
1330 MFREE(m->jcode, u1, m->jcodelength);
1332 if (m->exceptiontable)
1333 MFREE(m->exceptiontable, exceptiontable, m->exceptiontablelength);
1336 CFREE(m->mcode, m->mcodelength);
1338 if (m->stubroutine) {
1339 if (m->flags & ACC_NATIVE) {
1340 removenativestub(m->stubroutine);
1343 removecompilerstub(m->stubroutine);
1349 /************** Function: method_display (debugging only) **************/
1351 void method_display(methodinfo *m)
1354 printflags(m->flags);
1356 utf_display(m->name);
1358 utf_display(m->descriptor);
1362 /************** Function: method_display_flags_last (debugging only) **************/
1364 void method_display_flags_last(methodinfo *m)
1367 utf_display(m->name);
1369 utf_display(m->descriptor);
1371 printflags(m->flags);
1376 /******************** Function: method_canoverwrite ****************************
1378 Check if m and old are identical with respect to type and name. This means
1379 that old can be overwritten with m.
1381 *******************************************************************************/
1383 static bool method_canoverwrite(methodinfo *m, methodinfo *old)
1385 if (m->name != old->name) return false;
1386 if (m->descriptor != old->descriptor) return false;
1387 if (m->flags & ACC_STATIC) return false;
1392 /******************************************************************************/
1393 /************************ Functions for class *********************************/
1394 /******************************************************************************/
1397 /******************** function:: class_getconstant *****************************
1399 retrieves the value at position 'pos' of the constantpool of a class
1400 if the type of the value is other than 'ctype' the system is stopped
1402 *******************************************************************************/
1404 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
1406 /* invalid position in constantpool */
1407 /* (pos == 0 is caught by type comparison) */
1408 if (pos >= c->cpcount)
1409 panic("Attempt to access constant outside range");
1411 /* check type of constantpool entry */
1413 if (c->cptags[pos] != ctype) {
1414 class_showconstantpool(c);
1415 error("Type mismatch on constant: %d requested, %d here (class_getconstant)",
1416 (int) ctype, (int) c->cptags[pos]);
1419 return c->cpinfos[pos];
1423 /********************* Function: class_constanttype ****************************
1425 Determines the type of a class entry in the ConstantPool
1427 *******************************************************************************/
1429 u4 class_constanttype(classinfo *c, u4 pos)
1431 if (pos >= c->cpcount)
1432 panic("Attempt to access constant outside range");
1434 return c->cptags[pos];
1438 /******************** function: class_loadcpool ********************************
1440 loads the constantpool of a class,
1441 the entries are transformed into a simpler format
1442 by resolving references
1443 (a detailed overview of the compact structures can be found in global.h)
1445 *******************************************************************************/
1447 static void class_loadcpool(classbuffer *cb, classinfo *c)
1450 /* The following structures are used to save information which cannot be
1451 processed during the first pass. After the complete constantpool has
1452 been traversed the references can be resolved.
1453 (only in specific order) */
1455 /* CONSTANT_Class_info entries */
1456 typedef struct forward_class {
1457 struct forward_class *next;
1462 /* CONSTANT_String */
1463 typedef struct forward_string {
1464 struct forward_string *next;
1469 /* CONSTANT_NameAndType */
1470 typedef struct forward_nameandtype {
1471 struct forward_nameandtype *next;
1475 } forward_nameandtype;
1477 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
1478 typedef struct forward_fieldmethint {
1479 struct forward_fieldmethint *next;
1483 u2 nameandtype_index;
1484 } forward_fieldmethint;
1488 long int dumpsize = dump_size ();
1490 forward_class *forward_classes = NULL;
1491 forward_string *forward_strings = NULL;
1492 forward_nameandtype *forward_nameandtypes = NULL;
1493 forward_fieldmethint *forward_fieldmethints = NULL;
1495 /* number of entries in the constant_pool table plus one */
1496 u4 cpcount = c->cpcount = suck_u2(cb);
1498 /* allocate memory */
1499 u1 *cptags = c->cptags = MNEW(u1, cpcount);
1500 voidptr *cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
1503 panic("Invalid constant_pool_count (0)");
1506 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
1509 /* initialize constantpool */
1510 for (idx = 0; idx < cpcount; idx++) {
1511 cptags[idx] = CONSTANT_UNUSED;
1512 cpinfos[idx] = NULL;
1516 /******* first pass *******/
1517 /* entries which cannot be resolved now are written into
1518 temporary structures and traversed again later */
1521 while (idx < cpcount) {
1522 /* get constant type */
1526 case CONSTANT_Class: {
1527 forward_class *nfc = DNEW(forward_class);
1529 nfc->next = forward_classes;
1530 forward_classes = nfc;
1532 nfc->thisindex = idx;
1533 /* reference to CONSTANT_NameAndType */
1534 nfc->name_index = suck_u2(cb);
1540 case CONSTANT_Fieldref:
1541 case CONSTANT_Methodref:
1542 case CONSTANT_InterfaceMethodref: {
1543 forward_fieldmethint *nff = DNEW(forward_fieldmethint);
1545 nff->next = forward_fieldmethints;
1546 forward_fieldmethints = nff;
1548 nff->thisindex = idx;
1551 /* class or interface type that contains the declaration of the
1553 nff->class_index = suck_u2(cb);
1554 /* name and descriptor of the field or method */
1555 nff->nameandtype_index = suck_u2(cb);
1561 case CONSTANT_String: {
1562 forward_string *nfs = DNEW(forward_string);
1564 nfs->next = forward_strings;
1565 forward_strings = nfs;
1567 nfs->thisindex = idx;
1568 /* reference to CONSTANT_Utf8_info with string characters */
1569 nfs->string_index = suck_u2(cb);
1575 case CONSTANT_NameAndType: {
1576 forward_nameandtype *nfn = DNEW(forward_nameandtype);
1578 nfn->next = forward_nameandtypes;
1579 forward_nameandtypes = nfn;
1581 nfn->thisindex = idx;
1582 /* reference to CONSTANT_Utf8_info containing simple name */
1583 nfn->name_index = suck_u2(cb);
1584 /* reference to CONSTANT_Utf8_info containing field or method
1586 nfn->sig_index = suck_u2(cb);
1592 case CONSTANT_Integer: {
1593 constant_integer *ci = NEW(constant_integer);
1596 count_const_pool_len += sizeof(constant_integer);
1599 ci->value = suck_s4(cb);
1600 cptags[idx] = CONSTANT_Integer;
1607 case CONSTANT_Float: {
1608 constant_float *cf = NEW(constant_float);
1611 count_const_pool_len += sizeof(constant_float);
1614 cf->value = suck_float(cb);
1615 cptags[idx] = CONSTANT_Float;
1622 case CONSTANT_Long: {
1623 constant_long *cl = NEW(constant_long);
1626 count_const_pool_len += sizeof(constant_long);
1629 cl->value = suck_s8(cb);
1630 cptags[idx] = CONSTANT_Long;
1634 panic("Long constant exceeds constant pool");
1638 case CONSTANT_Double: {
1639 constant_double *cd = NEW(constant_double);
1642 count_const_pool_len += sizeof(constant_double);
1645 cd->value = suck_double(cb);
1646 cptags[idx] = CONSTANT_Double;
1650 panic("Double constant exceeds constant pool");
1654 case CONSTANT_Utf8: {
1655 /* number of bytes in the bytes array (not string-length) */
1656 u4 length = suck_u2(cb);
1657 cptags[idx] = CONSTANT_Utf8;
1658 /* validate the string */
1659 ASSERT_LEFT(cb, length);
1661 !is_valid_utf(cb->pos + 1, cb->pos + 1 + length)) {
1662 dolog("Invalid UTF-8 string (constant pool index %d)",idx);
1663 panic("Invalid UTF-8 string");
1665 /* insert utf-string into the utf-symboltable */
1666 cpinfos[idx] = utf_new_int(cb->pos + 1, length);
1668 /* skip bytes of the string */
1669 skip_nbytes(cb, length);
1675 error("Unkown constant type: %d",(int) t);
1680 /* resolve entries in temporary structures */
1682 while (forward_classes) {
1684 class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
1686 if (opt_verify && !is_valid_name_utf(name))
1687 panic("Class reference with invalid name");
1689 cptags[forward_classes->thisindex] = CONSTANT_Class;
1690 /* retrieve class from class-table */
1691 cpinfos[forward_classes->thisindex] = class_new(name);
1693 forward_classes = forward_classes->next;
1696 while (forward_strings) {
1698 class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
1700 /* resolve utf-string */
1701 cptags[forward_strings->thisindex] = CONSTANT_String;
1702 cpinfos[forward_strings->thisindex] = text;
1704 forward_strings = forward_strings->next;
1707 while (forward_nameandtypes) {
1708 constant_nameandtype *cn = NEW(constant_nameandtype);
1711 count_const_pool_len += sizeof(constant_nameandtype);
1714 /* resolve simple name and descriptor */
1715 cn->name = class_getconstant(c,
1716 forward_nameandtypes->name_index,
1719 cn->descriptor = class_getconstant(c,
1720 forward_nameandtypes->sig_index,
1725 if (!is_valid_name_utf(cn->name))
1726 panic("NameAndType with invalid name");
1727 /* disallow referencing <clinit> among others */
1728 if (cn->name->text[0] == '<' && cn->name != utf_init)
1729 panic("NameAndType with invalid special name");
1732 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
1733 cpinfos[forward_nameandtypes->thisindex] = cn;
1735 forward_nameandtypes = forward_nameandtypes->next;
1738 while (forward_fieldmethints) {
1739 constant_nameandtype *nat;
1740 constant_FMIref *fmi = NEW(constant_FMIref);
1743 count_const_pool_len += sizeof(constant_FMIref);
1745 /* resolve simple name and descriptor */
1746 nat = class_getconstant(c,
1747 forward_fieldmethints->nameandtype_index,
1748 CONSTANT_NameAndType);
1750 fmi->class = class_getconstant(c,
1751 forward_fieldmethints->class_index,
1753 fmi->name = nat->name;
1754 fmi->descriptor = nat->descriptor;
1756 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
1757 cpinfos[forward_fieldmethints->thisindex] = fmi;
1759 switch (forward_fieldmethints->tag) {
1760 case CONSTANT_Fieldref: /* check validity of descriptor */
1761 checkfielddescriptor(fmi->descriptor->text,
1762 utf_end(fmi->descriptor));
1764 case CONSTANT_InterfaceMethodref:
1765 case CONSTANT_Methodref: /* check validity of descriptor */
1766 checkmethoddescriptor(fmi->descriptor);
1770 forward_fieldmethints = forward_fieldmethints->next;
1773 dump_release(dumpsize);
1777 /********************** Function: class_load ***********************************
1779 Loads everything interesting about a class from the class file. The
1780 'classinfo' structure must have been allocated previously.
1782 The super class and the interfaces implemented by this class need not be
1783 loaded. The link is set later by the function 'class_link'.
1785 The loaded class is removed from the list 'unloadedclasses' and added to
1786 the list 'unlinkedclasses'.
1788 *******************************************************************************/
1790 classinfo *class_load_intern(classbuffer *cb);
1792 classinfo *class_load(classinfo *c)
1799 #if defined(USE_THREADS)
1800 #if defined(NATIVE_THREADS)
1808 /* maybe the class is already loaded */
1810 #if defined(USE_THREADS)
1811 #if defined(NATIVE_THREADS)
1824 starttime = getcputime();
1826 /* load classdata, throw exception on error */
1828 if ((cb = suck_start(c)) == NULL) {
1829 /* this means, the classpath was not set properly */
1830 if (c->name == utf_java_lang_Object)
1831 throw_cacao_exception_exit(string_java_lang_NoClassDefFoundError,
1832 "java/lang/Object");
1835 new_exception_utfmessage(string_java_lang_NoClassDefFoundError,
1837 /* log_text("Leaving class_load with NoClassDefFoundError");*/
1838 #if defined(USE_THREADS)
1839 #if defined(NATIVE_THREADS)
1850 /* call the internal function */
1851 r = class_load_intern(cb);
1853 /* if return value is NULL, we had a problem and the class is not loaded */
1861 if (getloadingtime) {
1862 stoptime = getcputime();
1863 loadingtime += (stoptime - starttime);
1866 #if defined(USE_THREADS)
1867 #if defined(NATIVE_THREADS)
1879 classinfo *class_load_intern(classbuffer *cb)
1884 /* s4 classdata_left; */
1885 char msg[MAXLOGTEXT]; /* maybe we get an exception */
1887 /* get the classbuffer's class */
1890 /* maybe the class is already loaded */
1895 count_class_loads++;
1898 /* output for debugging purposes */
1900 log_message_class("Loading class: ", c);
1902 /* class is somewhat loaded */
1905 /* check signature */
1906 if (suck_u4(cb) != MAGIC) {
1907 utf_sprint_classname(msg, c->name);
1908 sprintf(msg + strlen(msg), " (Bad magic number)");
1911 new_exception_message(string_java_lang_ClassFormatError, msg);
1920 /* if (ma != MAJOR_VERSION && (ma != MAJOR_VERSION + 1 || mi != 0)) { */
1921 if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1922 utf_sprint_classname(msg, c->name);
1923 sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
1927 new_exception_message(string_java_lang_ClassFormatError,
1933 class_loadcpool(cb, c);
1935 c->erroneous_state = 0;
1936 c->initializing_thread = 0;
1938 c->classUsed = NOTUSED; /* not used initially CO-RT */
1942 c->flags = suck_u2(cb);
1943 /*if (!(c->flags & ACC_PUBLIC)) { log_text("CLASS NOT PUBLIC"); } JOWENN*/
1945 /* check ACC flags consistency */
1946 if (c->flags & ACC_INTERFACE) {
1947 if (!(c->flags & ACC_ABSTRACT)) {
1948 /* We work around this because interfaces in JDK 1.1 are
1949 * not declared abstract. */
1951 c->flags |= ACC_ABSTRACT;
1952 /* panic("Interface class not declared abstract"); */
1955 if (c->flags & ACC_FINAL) {
1956 utf_sprint(msg, c->name);
1957 sprintf(msg + strlen(msg),
1958 " (Illegal class modifiers: 0x%x)", c->flags);
1961 new_exception_message(string_java_lang_ClassFormatError, msg);
1966 if (c->flags & ACC_SUPER) {
1967 c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1971 if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1972 utf_sprint(msg, c->name);
1973 sprintf(msg + strlen(msg),
1974 " (Illegal class modifiers: 0x%x)", c->flags);
1977 new_exception_message(string_java_lang_ClassFormatError, msg);
1984 if (class_getconstant(c, i, CONSTANT_Class) != c) {
1985 utf_sprint(msg, c->name);
1986 sprintf(msg + strlen(msg), " (wrong name: ");
1987 utf_sprint(msg + strlen(msg),
1988 ((classinfo *) class_getconstant(c, i, CONSTANT_Class))->name);
1989 sprintf(msg + strlen(msg), ")");
1992 new_exception_message(string_java_lang_NoClassDefFoundError, msg);
1997 /* retrieve superclass */
1998 if ((i = suck_u2(cb))) {
1999 c->super = class_getconstant(c, i, CONSTANT_Class);
2001 /* java.lang.Object may not have a super class. */
2002 if (c->name == utf_java_lang_Object) {
2004 new_exception_message(string_java_lang_ClassFormatError,
2005 "java.lang.Object with superclass");
2010 /* Interfaces must have java.lang.Object as super class. */
2011 if ((c->flags & ACC_INTERFACE) &&
2012 c->super->name != utf_java_lang_Object) {
2014 new_exception_message(string_java_lang_ClassFormatError,
2015 "Interfaces must have java.lang.Object as superclass");
2023 /* This is only allowed for java.lang.Object. */
2024 if (c->name != utf_java_lang_Object) {
2025 utf_sprint(msg, c->name);
2026 sprintf(msg + strlen(msg), " (Bad superclass index)");
2029 new_exception_message(string_java_lang_ClassFormatError, msg);
2036 /* retrieve interfaces */
2037 c->interfacescount = suck_u2(cb);
2038 c->interfaces = MNEW(classinfo*, c->interfacescount);
2039 for (i = 0; i < c->interfacescount; i++) {
2040 c->interfaces[i] = class_getconstant(c, suck_u2(cb), CONSTANT_Class);
2044 c->fieldscount = suck_u2(cb);
2045 c->fields = GCNEW(fieldinfo, c->fieldscount);
2046 /* c->fields = MNEW(fieldinfo, c->fieldscount); */
2047 for (i = 0; i < c->fieldscount; i++) {
2048 if (!field_load(cb, c, &(c->fields[i])))
2053 c->methodscount = suck_u2(cb);
2054 c->methods = GCNEW(methodinfo, c->methodscount);
2055 /* c->methods = MNEW(methodinfo, c->methodscount); */
2056 for (i = 0; i < c->methodscount; i++) {
2057 if (!method_load(cb, c, &(c->methods[i])))
2061 /* Check if all fields and methods can be uniquely
2062 * identified by (name,descriptor). */
2064 /* We use a hash table here to avoid making the
2065 * average case quadratic in # of methods, fields.
2067 static int shift = 0;
2069 u2 *next; /* for chaining colliding hash entries */
2075 /* Allocate hashtable */
2076 len = c->methodscount;
2077 if (len < c->fieldscount) len = c->fieldscount;
2079 hashtab = MNEW(u2,(hashlen + len));
2080 next = hashtab + hashlen;
2082 /* Determine bitshift (to get good hash values) */
2092 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2093 for (i = 0; i < c->fieldscount; ++i) {
2094 fieldinfo *fi = c->fields + i;
2095 /* It's ok if we lose bits here */
2096 index = ((((size_t) fi->name) +
2097 ((size_t) fi->descriptor)) >> shift) % hashlen;
2098 if ((old = hashtab[index])) {
2102 if (c->fields[old].name == fi->name &&
2103 c->fields[old].descriptor == fi->descriptor) {
2104 utf_sprint(msg, c->name);
2105 sprintf(msg + strlen(msg), " (Repetitive field name/signature)");
2108 new_exception_message(string_java_lang_ClassFormatError,
2113 } while ((old = next[old]));
2115 hashtab[index] = i + 1;
2119 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2120 for (i = 0; i < c->methodscount; ++i) {
2121 methodinfo *mi = c->methods + i;
2122 /* It's ok if we lose bits here */
2123 index = ((((size_t) mi->name) +
2124 ((size_t) mi->descriptor)) >> shift) % hashlen;
2125 if ((old = hashtab[index])) {
2129 if (c->methods[old].name == mi->name &&
2130 c->methods[old].descriptor == mi->descriptor) {
2131 utf_sprint(msg, c->name);
2132 sprintf(msg + strlen(msg), " (Repetitive method name/signature)");
2135 new_exception_message(string_java_lang_ClassFormatError,
2140 } while ((old = next[old]));
2142 hashtab[index] = i + 1;
2145 MFREE(hashtab, u2, (hashlen + len));
2150 count_class_infos += sizeof(classinfo*) * c->interfacescount;
2151 count_class_infos += sizeof(fieldinfo) * c->fieldscount;
2152 count_class_infos += sizeof(methodinfo) * c->methodscount;
2156 /* load variable-length attribute structures */
2157 attribute_load(cb, c, suck_u2(cb));
2160 /* XXX TWISTI is this still in the JVM spec? SUN and IBM don't complain about it */
2162 /* check if all data has been read */
2163 classdata_left = ((cb->data + cb->size) - cb->pos - 1);
2165 if (classdata_left > 0) {
2167 dolog("There are %d extra bytes at end of classfile", classdata_left);
2168 /* The JVM spec disallows extra bytes. */
2169 panic("Extra bytes at end of classfile");
2174 log_message_class("Loading done class: ", c);
2181 /************** internal Function: class_highestinterface **********************
2183 Used by the function class_link to determine the amount of memory needed
2184 for the interface table.
2186 *******************************************************************************/
2188 static s4 class_highestinterface(classinfo *c)
2193 if (!(c->flags & ACC_INTERFACE)) {
2194 char logtext[MAXLOGTEXT];
2195 sprintf(logtext, "Interface-methods count requested for non-interface: ");
2196 utf_sprint(logtext + strlen(logtext), c->name);
2197 error("%s",logtext);
2201 for (i = 0; i < c->interfacescount; i++) {
2202 s4 h2 = class_highestinterface(c->interfaces[i]);
2210 /* class_addinterface **********************************************************
2212 Is needed by class_link for adding a VTBL to a class. All interfaces
2213 implemented by ic are added as well.
2215 *******************************************************************************/
2217 static void class_addinterface(classinfo *c, classinfo *ic)
2221 vftbl *vftbl = c->vftbl;
2223 if (i >= vftbl->interfacetablelength)
2224 panic ("Inernal error: interfacetable overflow");
2226 if (vftbl->interfacetable[-i])
2229 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
2230 vftbl->interfacevftbllength[i] = 1;
2231 vftbl->interfacetable[-i] = MNEW(methodptr, 1);
2232 vftbl->interfacetable[-i][0] = NULL;
2235 vftbl->interfacevftbllength[i] = ic->methodscount;
2236 vftbl->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
2240 count_vftbl_len += sizeof(methodptr) *
2241 (ic->methodscount + (ic->methodscount == 0));
2244 for (j = 0; j < ic->methodscount; j++) {
2247 for (m = 0; m < sc->methodscount; m++) {
2248 methodinfo *mi = &(sc->methods[m]);
2249 if (method_canoverwrite(mi, &(ic->methods[j]))) {
2250 vftbl->interfacetable[-i][j] =
2251 vftbl->table[mi->vftblindex];
2262 for (j = 0; j < ic->interfacescount; j++)
2263 class_addinterface(c, ic->interfaces[j]);
2267 /******************* Function: class_new_array *********************************
2269 This function is called by class_new to setup an array class.
2271 *******************************************************************************/
2273 void class_new_array(classinfo *c)
2275 classinfo *comp = NULL;
2279 /* Check array class name */
2280 namelen = c->name->blength;
2281 if (namelen < 2 || c->name->text[0] != '[')
2282 panic("Invalid array class name");
2284 /* Check the component type */
2285 switch (c->name->text[1]) {
2287 /* c is an array of arrays. We have to create the component class. */
2288 comp = class_new(utf_new_int(c->name->text + 1, namelen - 1));
2292 /* c is an array of objects. */
2293 if (namelen < 4 || c->name->text[namelen - 1] != ';')
2294 panic("Invalid array class name");
2295 comp = class_new(utf_new_int(c->name->text + 2, namelen - 3));
2299 /* Setup the array class */
2300 c->super = class_java_lang_Object;
2301 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2303 c->interfacescount = 2;
2304 c->interfaces = MNEW(classinfo*, 2);
2305 c->interfaces[0] = class_new(utf_new_char("java/lang/Cloneable"));
2306 c->interfaces[1] = class_new(utf_new_char("java/io/Serializable"));
2308 c->methodscount = 1;
2309 c->methods = MNEW(methodinfo, c->methodscount);
2312 memset(clone, 0, sizeof(methodinfo));
2313 clone->flags = ACC_PUBLIC;
2314 clone->name = utf_new_char("clone");
2315 clone->descriptor = utf_new_char("()Ljava/lang/Object;");
2317 clone->stubroutine = createnativestub((functionptr) &builtin_clone_array, clone);
2318 clone->monoPoly = MONO;
2320 /* XXX: field: length? */
2322 /* array classes are not loaded from class files */
2327 /****************** Function: class_link_array *********************************
2329 This function is called by class_link to create the
2330 arraydescriptor for an array class.
2332 This function returns NULL if the array cannot be linked because
2333 the component type has not been linked yet.
2335 *******************************************************************************/
2337 static arraydescriptor *class_link_array(classinfo *c)
2339 classinfo *comp = NULL;
2340 s4 namelen = c->name->blength;
2341 arraydescriptor *desc;
2344 /* Check the component type */
2345 switch (c->name->text[1]) {
2347 /* c is an array of arrays. */
2348 /* comp = class_get(utf_new_int(c->name->text + 1, namelen - 1)); */
2349 comp = class_new(utf_new_int(c->name->text + 1, namelen - 1));
2351 panic("Could not find component array class.");
2355 /* c is an array of objects. */
2356 /* comp = class_get(utf_new_int(c->name->text + 2, namelen - 3)); */
2357 comp = class_new(utf_new_int(c->name->text + 2, namelen - 3));
2359 panic("Could not find component class.");
2363 /* If the component type has not been linked, link it now */
2364 if (comp && !comp->linked) {
2370 /* Allocate the arraydescriptor */
2371 desc = NEW(arraydescriptor);
2374 /* c is an array of references */
2375 desc->arraytype = ARRAYTYPE_OBJECT;
2376 desc->componentsize = sizeof(void*);
2377 desc->dataoffset = OFFSET(java_objectarray, data);
2379 compvftbl = comp->vftbl;
2381 panic("Component class has no vftbl");
2382 desc->componentvftbl = compvftbl;
2384 if (compvftbl->arraydesc) {
2385 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
2386 if (compvftbl->arraydesc->dimension >= 255)
2387 panic("Creating array of dimension >255");
2388 desc->dimension = compvftbl->arraydesc->dimension + 1;
2389 desc->elementtype = compvftbl->arraydesc->elementtype;
2392 desc->elementvftbl = compvftbl;
2393 desc->dimension = 1;
2394 desc->elementtype = ARRAYTYPE_OBJECT;
2398 /* c is an array of a primitive type */
2399 switch (c->name->text[1]) {
2401 desc->arraytype = ARRAYTYPE_BOOLEAN;
2402 desc->dataoffset = OFFSET(java_booleanarray,data);
2403 desc->componentsize = sizeof(u1);
2407 desc->arraytype = ARRAYTYPE_BYTE;
2408 desc->dataoffset = OFFSET(java_bytearray,data);
2409 desc->componentsize = sizeof(u1);
2413 desc->arraytype = ARRAYTYPE_CHAR;
2414 desc->dataoffset = OFFSET(java_chararray,data);
2415 desc->componentsize = sizeof(u2);
2419 desc->arraytype = ARRAYTYPE_DOUBLE;
2420 desc->dataoffset = OFFSET(java_doublearray,data);
2421 desc->componentsize = sizeof(double);
2425 desc->arraytype = ARRAYTYPE_FLOAT;
2426 desc->dataoffset = OFFSET(java_floatarray,data);
2427 desc->componentsize = sizeof(float);
2431 desc->arraytype = ARRAYTYPE_INT;
2432 desc->dataoffset = OFFSET(java_intarray,data);
2433 desc->componentsize = sizeof(s4);
2437 desc->arraytype = ARRAYTYPE_LONG;
2438 desc->dataoffset = OFFSET(java_longarray,data);
2439 desc->componentsize = sizeof(s8);
2443 desc->arraytype = ARRAYTYPE_SHORT;
2444 desc->dataoffset = OFFSET(java_shortarray,data);
2445 desc->componentsize = sizeof(s2);
2449 panic("Invalid array class name");
2452 desc->componentvftbl = NULL;
2453 desc->elementvftbl = NULL;
2454 desc->dimension = 1;
2455 desc->elementtype = desc->arraytype;
2462 /********************** Function: class_link ***********************************
2464 Tries to link a class. The function calculates the length in bytes that
2465 an instance of this class requires as well as the VTBL for methods and
2468 *******************************************************************************/
2470 static classinfo *class_link_intern(classinfo *c);
2472 classinfo *class_link(classinfo *c)
2478 #if defined(USE_THREADS)
2479 #if defined(NATIVE_THREADS)
2487 /* maybe the class is already linked */
2489 #if defined(USE_THREADS)
2490 #if defined(NATIVE_THREADS)
2503 starttime = getcputime();
2505 /* call the internal function */
2506 r = class_link_intern(c);
2508 /* if return value is NULL, we had a problem and the class is not linked */
2513 if (getloadingtime) {
2514 stoptime = getcputime();
2515 loadingtime += (stoptime - starttime);
2518 #if defined(USE_THREADS)
2519 #if defined(NATIVE_THREADS)
2526 if (c->linked) return c; else return 0;
2530 static classinfo *class_link_intern(classinfo *c)
2532 s4 supervftbllength; /* vftbllegnth of super class */
2533 s4 vftbllength; /* vftbllength of current class */
2534 s4 interfacetablelength; /* interface table length */
2535 classinfo *super = c->super; /* super class */
2536 classinfo *ic, *c2; /* intermediate class variables */
2537 vftbl *v; /* vftbl of current class */
2538 s4 i; /* interface/method/field counter */
2539 arraydescriptor *arraydesc = NULL; /* descriptor for array classes */
2541 /* maybe the class is already linked */
2546 log_message_class("Linking class: ", c);
2548 /* ok, this class is somewhat linked */
2551 /* check interfaces */
2553 for (i = 0; i < c->interfacescount; i++) {
2554 ic = c->interfaces[i];
2556 /* detect circularity */
2559 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2571 if (!(ic->flags & ACC_INTERFACE)) {
2572 dolog("Specified interface is not declared as interface:");
2576 panic("Specified interface is not declared as interface");
2580 /* check super class */
2582 if (super == NULL) { /* class java.lang.Object */
2584 c->classUsed = USED; /* Object class is always used CO-RT*/
2586 c->instancesize = sizeof(java_objectheader);
2588 vftbllength = supervftbllength = 0;
2590 c->finalizer = NULL;
2593 /* detect circularity */
2596 new_exception_utfmessage(string_java_lang_ClassCircularityError,
2608 if (super->flags & ACC_INTERFACE)
2609 panic("Interface specified as super class");
2611 /* handle array classes */
2612 /* The component class must have been linked already. */
2613 if (c->name->text[0] == '[') {
2614 if ((arraydesc = class_link_array(c)) == NULL) {
2615 panic("class_link: class_link_array");
2619 /* Don't allow extending final classes */
2620 if (super->flags & ACC_FINAL)
2621 panic("Trying to extend final class");
2623 if (c->flags & ACC_INTERFACE)
2624 c->index = interfaceindex++;
2626 c->index = super->index + 1;
2628 c->instancesize = super->instancesize;
2630 vftbllength = supervftbllength = super->vftbl->vftbllength;
2632 c->finalizer = super->finalizer;
2635 /* compute vftbl length */
2637 for (i = 0; i < c->methodscount; i++) {
2638 methodinfo *m = &(c->methods[i]);
2640 if (!(m->flags & ACC_STATIC)) { /* is instance method */
2641 classinfo *sc = super;
2644 for (j = 0; j < sc->methodscount; j++) {
2645 if (method_canoverwrite(m, &(sc->methods[j]))) {
2646 if ((sc->methods[j].flags & ACC_PRIVATE) != 0)
2647 goto notfoundvftblindex;
2649 if ((sc->methods[j].flags & ACC_FINAL) != 0) {
2652 log_utf(sc->methods[j].name);
2653 log_utf(sc->methods[j].descriptor);
2654 panic("Trying to overwrite final method");
2656 m->vftblindex = sc->methods[j].vftblindex;
2657 goto foundvftblindex;
2663 m->vftblindex = (vftbllength++);
2672 sizeof(vftbl) + (sizeof(methodptr) * (vftbllength - 1));
2675 /* compute interfacetable length */
2677 interfacetablelength = 0;
2680 for (i = 0; i < c2->interfacescount; i++) {
2681 s4 h = class_highestinterface(c2->interfaces[i]) + 1;
2682 if (h > interfacetablelength)
2683 interfacetablelength = h;
2688 /* allocate virtual function table */
2690 v = (vftbl*) mem_alloc(sizeof(vftbl) + sizeof(methodptr) *
2691 (vftbllength - 1) + sizeof(methodptr*) *
2692 (interfacetablelength - (interfacetablelength > 0)));
2693 v = (vftbl*) (((methodptr*) v) + (interfacetablelength - 1) *
2694 (interfacetablelength > 1));
2695 c->header.vftbl = c->vftbl = v;
2696 /* utf_display_classname(c->name);printf(", c->header.vftbl=%p\n", c->header.vftbl); */
2698 v->vftbllength = vftbllength;
2699 v->interfacetablelength = interfacetablelength;
2700 v->arraydesc = arraydesc;
2702 /* store interface index in vftbl */
2703 if (c->flags & ACC_INTERFACE)
2704 v->baseval = -(c->index);
2706 /* copy virtual function table of super class */
2708 for (i = 0; i < supervftbllength; i++)
2709 v->table[i] = super->vftbl->table[i];
2711 /* add method stubs into virtual function table */
2713 for (i = 0; i < c->methodscount; i++) {
2714 methodinfo *m = &(c->methods[i]);
2715 if (!(m->flags & ACC_STATIC)) {
2716 v->table[m->vftblindex] = m->stubroutine;
2720 /* compute instance size and offset of each field */
2722 for (i = 0; i < c->fieldscount; i++) {
2724 fieldinfo *f = &(c->fields[i]);
2726 if (!(f->flags & ACC_STATIC)) {
2727 dsize = desc_typesize(f->descriptor);
2728 c->instancesize = ALIGN(c->instancesize, dsize);
2729 f->offset = c->instancesize;
2730 c->instancesize += dsize;
2734 /* initialize interfacetable and interfacevftbllength */
2736 v->interfacevftbllength = MNEW(s4, interfacetablelength);
2740 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
2743 for (i = 0; i < interfacetablelength; i++) {
2744 v->interfacevftbllength[i] = 0;
2745 v->interfacetable[-i] = NULL;
2748 /* add interfaces */
2750 for (c2 = c; c2 != NULL; c2 = c2->super)
2751 for (i = 0; i < c2->interfacescount; i++) {
2752 class_addinterface(c, c2->interfaces[i]);
2755 /* add finalizer method (not for java.lang.Object) */
2757 if (super != NULL) {
2759 static utf *finame = NULL;
2760 static utf *fidesc = NULL;
2763 finame = utf_finalize;
2765 fidesc = utf_fidesc;
2767 fi = class_findmethod(c, finame, fidesc);
2769 if (!(fi->flags & ACC_STATIC)) {
2777 loader_compute_subclasses(c);
2780 log_message_class("Linking done class: ", c);
2782 /* just return c to show that we didn't had a problem */
2788 /******************* Function: class_freepool **********************************
2790 Frees all resources used by this classes Constant Pool.
2792 *******************************************************************************/
2794 static void class_freecpool(classinfo *c)
2800 for (idx=0; idx < c->cpcount; idx++) {
2801 tag = c->cptags[idx];
2802 info = c->cpinfos[idx];
2806 case CONSTANT_Fieldref:
2807 case CONSTANT_Methodref:
2808 case CONSTANT_InterfaceMethodref:
2809 FREE(info, constant_FMIref);
2811 case CONSTANT_Integer:
2812 FREE(info, constant_integer);
2814 case CONSTANT_Float:
2815 FREE(info, constant_float);
2818 FREE(info, constant_long);
2820 case CONSTANT_Double:
2821 FREE(info, constant_double);
2823 case CONSTANT_NameAndType:
2824 FREE(info, constant_nameandtype);
2830 MFREE(c->cptags, u1, c->cpcount);
2831 MFREE(c->cpinfos, voidptr, c->cpcount);
2835 /*********************** Function: class_free **********************************
2837 Frees all resources used by the class.
2839 *******************************************************************************/
2841 static void class_free(classinfo *c)
2848 MFREE(c->interfaces, classinfo*, c->interfacescount);
2850 for (i = 0; i < c->fieldscount; i++)
2851 field_free(&(c->fields[i]));
2852 /* MFREE(c->fields, fieldinfo, c->fieldscount); */
2854 for (i = 0; i < c->methodscount; i++)
2855 method_free(&(c->methods[i]));
2856 /* MFREE(c->methods, methodinfo, c->methodscount); */
2858 if ((v = c->vftbl) != NULL) {
2860 mem_free(v->arraydesc,sizeof(arraydescriptor));
2862 for (i = 0; i < v->interfacetablelength; i++) {
2863 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
2865 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
2867 i = sizeof(vftbl) + sizeof(methodptr) * (v->vftbllength - 1) +
2868 sizeof(methodptr*) * (v->interfacetablelength -
2869 (v->interfacetablelength > 0));
2870 v = (vftbl*) (((methodptr*) v) - (v->interfacetablelength - 1) *
2871 (v->interfacetablelength > 1));
2875 if (c->innerclasscount)
2876 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
2878 /* if (c->classvftbl)
2879 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
2885 /************************* Function: class_findfield ***************************
2887 Searches a 'classinfo' structure for a field having the given name and
2890 *******************************************************************************/
2892 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
2896 for (i = 0; i < c->fieldscount; i++) {
2897 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
2898 return &(c->fields[i]);
2901 panic("Can not find field given in CONSTANT_Fieldref");
2903 /* keep compiler happy */
2908 /****************** Function: class_resolvefield_int ***************************
2910 This is an internally used helper function. Do not use this directly.
2912 Tries to resolve a field having the given name and type.
2913 If the field cannot be resolved, NULL is returned.
2915 *******************************************************************************/
2917 static fieldinfo *class_resolvefield_int(classinfo *c, utf *name, utf *desc)
2922 /* search for field in class c */
2923 for (i = 0; i < c->fieldscount; i++) {
2924 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) {
2925 return &(c->fields[i]);
2929 /* try superinterfaces recursively */
2930 for (i = 0; i < c->interfacescount; ++i) {
2931 fi = class_resolvefield_int(c->interfaces[i], name, desc);
2936 /* try superclass */
2938 return class_resolvefield_int(c->super, name, desc);
2945 /********************* Function: class_resolvefield ***************************
2947 Resolves a reference from REFERER to a field with NAME and DESC in class C.
2949 If the field cannot be resolved the return value is NULL. If EXCEPT is
2950 true *exceptionptr is set, too.
2952 *******************************************************************************/
2954 fieldinfo *class_resolvefield(classinfo *c, utf *name, utf *desc,
2955 classinfo *referer, bool except)
2959 /* XXX resolve class c */
2960 /* XXX check access from REFERER to C */
2962 fi = class_resolvefield_int(c, name, desc);
2967 new_exception_utfmessage(string_java_lang_NoSuchFieldError,
2973 /* XXX check access rights */
2979 /************************* Function: class_findmethod **************************
2981 Searches a 'classinfo' structure for a method having the given name and
2982 type and returns the index in the class info structure.
2983 If type is NULL, it is ignored.
2985 *******************************************************************************/
2987 s4 class_findmethodIndex(classinfo *c, utf *name, utf *desc)
2991 for (i = 0; i < c->methodscount; i++) {
2993 /* utf_display_classname(c->name);printf("."); */
2994 /* utf_display(c->methods[i].name);printf("."); */
2995 /* utf_display(c->methods[i].descriptor); */
2998 if ((c->methods[i].name == name) && ((desc == NULL) ||
2999 (c->methods[i].descriptor == desc))) {
3008 /************************* Function: class_findmethod **************************
3010 Searches a 'classinfo' structure for a method having the given name and
3012 If type is NULL, it is ignored.
3014 *******************************************************************************/
3016 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
3018 s4 idx = class_findmethodIndex(c, name, desc);
3023 return &(c->methods[idx]);
3027 /*********************** Function: class_fetchmethod **************************
3029 like class_findmethod, but aborts with an error if the method is not found
3031 *******************************************************************************/
3033 methodinfo *class_fetchmethod(classinfo *c, utf *name, utf *desc)
3037 mi = class_findmethod(c, name, desc);
3040 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3041 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3042 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3043 panic("Method not found");
3050 /*********************** Function: class_findmethod_w**************************
3052 like class_findmethod, but logs a warning if the method is not found
3054 *******************************************************************************/
3056 methodinfo *class_findmethod_w(classinfo *c, utf *name, utf *desc, char *from)
3059 mi = class_findmethod(c, name, desc);
3062 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
3063 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
3064 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
3066 if ( c->flags & ACC_PUBLIC ) log_plain(" PUBLIC ");
3067 if ( c->flags & ACC_PRIVATE ) log_plain(" PRIVATE ");
3068 if ( c->flags & ACC_PROTECTED ) log_plain(" PROTECTED ");
3069 if ( c->flags & ACC_STATIC ) log_plain(" STATIC ");
3070 if ( c->flags & ACC_FINAL ) log_plain(" FINAL ");
3071 if ( c->flags & ACC_SYNCHRONIZED ) log_plain(" SYNCHRONIZED ");
3072 if ( c->flags & ACC_VOLATILE ) log_plain(" VOLATILE ");
3073 if ( c->flags & ACC_TRANSIENT ) log_plain(" TRANSIENT ");
3074 if ( c->flags & ACC_NATIVE ) log_plain(" NATIVE ");
3075 if ( c->flags & ACC_INTERFACE ) log_plain(" INTERFACE ");
3076 if ( c->flags & ACC_ABSTRACT ) log_plain(" ABSTRACT ");
3079 log_plain(" : WARNING: Method not found");log_nl( );
3086 /************************* Function: class_findmethod_approx ******************
3088 like class_findmethod but ignores the return value when comparing the
3091 *******************************************************************************/
3093 methodinfo *class_findmethod_approx(classinfo *c, utf *name, utf *desc)
3097 for (i = 0; i < c->methodscount; i++) {
3098 if (c->methods[i].name == name) {
3099 utf *meth_descr = c->methods[i].descriptor;
3103 return &(c->methods[i]);
3105 if (desc->blength <= meth_descr->blength) {
3106 /* current position in utf text */
3107 char *desc_utf_ptr = desc->text;
3108 char *meth_utf_ptr = meth_descr->text;
3109 /* points behind utf strings */
3110 char *desc_end = utf_end(desc);
3111 char *meth_end = utf_end(meth_descr);
3114 /* compare argument types */
3115 while (desc_utf_ptr < desc_end && meth_utf_ptr < meth_end) {
3117 if ((ch = *desc_utf_ptr++) != (*meth_utf_ptr++))
3118 break; /* no match */
3121 return &(c->methods[i]); /* all parameter types equal */
3131 /***************** Function: class_resolvemethod_approx ***********************
3133 Searches a class and every super class for a method (without paying
3134 attention to the return value)
3136 *******************************************************************************/
3138 methodinfo *class_resolvemethod_approx(classinfo *c, utf *name, utf *desc)
3141 /* search for method (ignore returntype) */
3142 methodinfo *m = class_findmethod_approx(c, name, desc);
3145 /* search superclass */
3153 /************************* Function: class_resolvemethod ***********************
3155 Searches a class and every super class for a method.
3157 *******************************************************************************/
3159 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
3161 /*log_text("Trying to resolve a method");
3162 utf_display(c->name);
3164 utf_display(desc);*/
3167 /*log_text("Looking in:");
3168 utf_display(c->name);*/
3169 methodinfo *m = class_findmethod(c, name, desc);
3171 /* search superclass */
3174 /*log_text("method not found:");*/
3180 /****************** Function: class_resolveinterfacemethod_int ****************
3182 Internally used helper function. Do not use this directly.
3184 *******************************************************************************/
3187 methodinfo *class_resolveinterfacemethod_int(classinfo *c, utf *name, utf *desc)
3192 mi = class_findmethod(c,name,desc);
3196 /* try the superinterfaces */
3197 for (i=0; i<c->interfacescount; ++i) {
3198 mi = class_resolveinterfacemethod_int(c->interfaces[i],name,desc);
3206 /******************** Function: class_resolveinterfacemethod ******************
3208 Resolves a reference from REFERER to a method with NAME and DESC in
3211 If the method cannot be resolved the return value is NULL. If EXCEPT is
3212 true *exceptionptr is set, too.
3214 *******************************************************************************/
3216 methodinfo *class_resolveinterfacemethod(classinfo *c, utf *name, utf *desc,
3217 classinfo *referer, bool except)
3221 /* XXX resolve class c */
3222 /* XXX check access from REFERER to C */
3224 if (!(c->flags & ACC_INTERFACE)) {
3227 new_exception(string_java_lang_IncompatibleClassChangeError);
3232 mi = class_resolveinterfacemethod_int(c, name, desc);
3237 /* try class java.lang.Object */
3238 mi = class_findmethod(class_java_lang_Object, name, desc);
3245 new_exception_utfmessage(string_java_lang_NoSuchMethodError, name);
3251 /********************* Function: class_resolveclassmethod *********************
3253 Resolves a reference from REFERER to a method with NAME and DESC in
3256 If the method cannot be resolved the return value is NULL. If EXCEPT is
3257 true *exceptionptr is set, too.
3259 *******************************************************************************/
3261 methodinfo *class_resolveclassmethod(classinfo *c, utf *name, utf *desc,
3262 classinfo *referer, bool except)
3267 char msg[MAXLOGTEXT];
3269 /* XXX resolve class c */
3270 /* XXX check access from REFERER to C */
3272 /* if (c->flags & ACC_INTERFACE) { */
3274 /* *exceptionptr = */
3275 /* new_exception(string_java_lang_IncompatibleClassChangeError); */
3279 /* try class c and its superclasses */
3282 mi = class_findmethod(cls, name, desc);
3285 } while ((cls = cls->super) != NULL); /* try the superclass */
3287 /* try the superinterfaces */
3288 for (i = 0; i < c->interfacescount; ++i) {
3289 mi = class_resolveinterfacemethod_int(c->interfaces[i], name, desc);
3295 utf_sprint(msg, c->name);
3296 sprintf(msg + strlen(msg), ".");
3297 utf_sprint(msg + strlen(msg), name);
3298 utf_sprint(msg + strlen(msg), desc);
3301 new_exception_message(string_java_lang_NoSuchMethodError, msg);
3307 if ((mi->flags & ACC_ABSTRACT) && !(c->flags & ACC_ABSTRACT)) {
3309 *exceptionptr = new_exception(string_java_lang_AbstractMethodError);
3314 /* XXX check access rights */
3320 /************************* Function: class_issubclass **************************
3322 Checks if sub is a descendant of super.
3324 *******************************************************************************/
3326 bool class_issubclass(classinfo *sub, classinfo *super)
3329 if (!sub) return false;
3330 if (sub == super) return true;
3336 /****************** Initialization function for classes ******************
3338 In Java, every class can have a static initialization function. This
3339 function has to be called BEFORE calling other methods or accessing static
3342 *******************************************************************************/
3344 classinfo *class_init(classinfo *c)
3348 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3352 if (!makeinitializations)
3358 /* class is somewhat initialized */
3359 c->initialized = true;
3369 #if defined(STATISTICS)
3371 count_class_inits++;
3374 /* initialize super class */
3376 if (!c->super->loaded)
3377 if (!class_load(c->super))
3380 if (!c->super->linked)
3381 if (!class_link(c->super))
3384 if (!c->super->initialized) {
3386 char logtext[MAXLOGTEXT];
3387 sprintf(logtext, "Initialize super class ");
3388 utf_sprint_classname(logtext + strlen(logtext), c->super->name);
3389 sprintf(logtext + strlen(logtext), " from ");
3390 utf_sprint_classname(logtext + strlen(logtext), c->name);
3394 if (!class_init(c->super))
3399 /* initialize interface classes */
3400 for (i = 0; i < c->interfacescount; i++) {
3401 if (!c->interfaces[i]->loaded)
3402 if (!class_load(c->interfaces[i]))
3405 if (!c->interfaces[i]->linked)
3406 if (!class_link(c->interfaces[i]))
3409 if (!c->interfaces[i]->initialized) {
3411 char logtext[MAXLOGTEXT];
3412 sprintf(logtext, "Initialize interface class ");
3413 utf_sprint_classname(logtext + strlen(logtext), c->interfaces[i]->name);
3414 sprintf(logtext + strlen(logtext), " from ");
3415 utf_sprint_classname(logtext + strlen(logtext), c->name);
3419 if (!class_init(c->interfaces[i]))
3424 m = class_findmethod(c, utf_clinit, utf_fidesc);
3428 char logtext[MAXLOGTEXT];
3429 sprintf(logtext, "Class ");
3430 utf_sprint_classname(logtext + strlen(logtext), c->name);
3431 sprintf(logtext + strlen(logtext), " has no static class initializer");
3438 if (!(m->flags & ACC_STATIC))
3439 panic("Class initializer is not static!");
3442 log_message_class("Starting static class initializer for class: ", c);
3444 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3449 /* now call the initializer */
3450 asm_calljavafunction(m, NULL, NULL, NULL, NULL);
3452 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
3453 assert(blockInts == 0);
3457 /* we have an exception */
3458 if (*exceptionptr) {
3459 java_objectheader *xptr;
3460 java_objectheader *cause;
3462 /* class is NOT initialized */
3463 c->initialized = false;
3466 cause = *exceptionptr;
3468 /* clear exception, because we are calling jit code again */
3469 *exceptionptr = NULL;
3471 /* wrap the exception */
3473 new_exception_throwable(string_java_lang_ExceptionInInitializerError,
3474 (java_lang_Throwable *) cause);
3476 if (*exceptionptr) {
3480 /* set new exception */
3481 *exceptionptr = xptr;
3487 log_message_class("Finished static class initializer for class: ", c);
3493 /********* Function: find_class_method_constant *********/
3495 int find_class_method_constant (classinfo *c, utf * c1, utf* m1, utf* d1)
3500 for (i=0; i<c->cpcount; i++) {
3502 e = c -> cpinfos [i];
3505 switch (c -> cptags [i]) {
3506 case CONSTANT_Methodref:
3508 constant_FMIref *fmi = e;
3509 if ( (fmi->class->name == c1)
3510 && (fmi->name == m1)
3511 && (fmi->descriptor == d1)) {
3518 case CONSTANT_InterfaceMethodref:
3520 constant_FMIref *fmi = e;
3521 if ( (fmi->class->name == c1)
3522 && (fmi->name == m1)
3523 && (fmi->descriptor == d1)) {
3537 void class_showconstanti(classinfo *c, int ii)
3543 printf ("#%d: ", (int) i);
3545 switch (c->cptags [i]) {
3546 case CONSTANT_Class:
3547 printf("Classreference -> ");
3548 utf_display(((classinfo*)e)->name);
3551 case CONSTANT_Fieldref:
3552 printf("Fieldref -> "); goto displayFMIi;
3553 case CONSTANT_Methodref:
3554 printf("Methodref -> "); goto displayFMIi;
3555 case CONSTANT_InterfaceMethodref:
3556 printf("InterfaceMethod -> "); goto displayFMIi;
3559 constant_FMIref *fmi = e;
3560 utf_display(fmi->class->name);
3562 utf_display(fmi->name);
3564 utf_display(fmi->descriptor);
3568 case CONSTANT_String:
3569 printf("String -> ");
3572 case CONSTANT_Integer:
3573 printf("Integer -> %d", (int) (((constant_integer*)e)->value));
3575 case CONSTANT_Float:
3576 printf("Float -> %f", ((constant_float*)e)->value);
3578 case CONSTANT_Double:
3579 printf("Double -> %f", ((constant_double*)e)->value);
3583 u8 v = ((constant_long*)e)->value;
3585 printf("Long -> %ld", (long int) v);
3587 printf("Long -> HI: %ld, LO: %ld\n",
3588 (long int) v.high, (long int) v.low);
3592 case CONSTANT_NameAndType:
3594 constant_nameandtype *cnt = e;
3595 printf("NameAndType: ");
3596 utf_display(cnt->name);
3598 utf_display(cnt->descriptor);
3606 panic("Invalid type of ConstantPool-Entry");
3613 void class_showconstantpool (classinfo *c)
3618 printf ("---- dump of constant pool ----\n");
3620 for (i=0; i<c->cpcount; i++) {
3621 printf ("#%d: ", (int) i);
3623 e = c -> cpinfos [i];
3626 switch (c -> cptags [i]) {
3627 case CONSTANT_Class:
3628 printf ("Classreference -> ");
3629 utf_display ( ((classinfo*)e) -> name );
3632 case CONSTANT_Fieldref:
3633 printf ("Fieldref -> "); goto displayFMI;
3634 case CONSTANT_Methodref:
3635 printf ("Methodref -> "); goto displayFMI;
3636 case CONSTANT_InterfaceMethodref:
3637 printf ("InterfaceMethod -> "); goto displayFMI;
3640 constant_FMIref *fmi = e;
3641 utf_display ( fmi->class->name );
3643 utf_display ( fmi->name);
3645 utf_display ( fmi->descriptor );
3649 case CONSTANT_String:
3650 printf ("String -> ");
3653 case CONSTANT_Integer:
3654 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
3656 case CONSTANT_Float:
3657 printf ("Float -> %f", ((constant_float*)e) -> value);
3659 case CONSTANT_Double:
3660 printf ("Double -> %f", ((constant_double*)e) -> value);
3664 u8 v = ((constant_long*)e) -> value;
3666 printf ("Long -> %ld", (long int) v);
3668 printf ("Long -> HI: %ld, LO: %ld\n",
3669 (long int) v.high, (long int) v.low);
3673 case CONSTANT_NameAndType:
3675 constant_nameandtype *cnt = e;
3676 printf ("NameAndType: ");
3677 utf_display (cnt->name);
3679 utf_display (cnt->descriptor);
3683 printf ("Utf8 -> ");
3687 panic ("Invalid type of ConstantPool-Entry");
3697 /********** Function: class_showmethods (debugging only) *************/
3699 void class_showmethods (classinfo *c)
3703 printf ("--------- Fields and Methods ----------------\n");
3704 printf ("Flags: "); printflags (c->flags); printf ("\n");
3706 printf ("This: "); utf_display (c->name); printf ("\n");
3708 printf ("Super: "); utf_display (c->super->name); printf ("\n");
3710 printf ("Index: %d\n", c->index);
3712 printf ("interfaces:\n");
3713 for (i=0; i < c-> interfacescount; i++) {
3715 utf_display (c -> interfaces[i] -> name);
3716 printf (" (%d)\n", c->interfaces[i] -> index);
3719 printf ("fields:\n");
3720 for (i=0; i < c -> fieldscount; i++) {
3721 field_display (&(c -> fields[i]));
3724 printf ("methods:\n");
3725 for (i=0; i < c -> methodscount; i++) {
3726 methodinfo *m = &(c->methods[i]);
3727 if ( !(m->flags & ACC_STATIC))
3728 printf ("vftblindex: %d ", m->vftblindex);
3730 method_display ( m );
3734 printf ("Virtual function table:\n");
3735 for (i=0; i<c->vftbl->vftbllength; i++) {
3736 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]) );
3742 /******************************************************************************/
3743 /******************* General functions for the class loader *******************/
3744 /******************************************************************************/
3746 /**************** function: create_primitive_classes ***************************
3748 create classes representing primitive types
3750 *******************************************************************************/
3752 void create_primitive_classes()
3756 for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
3757 /* create primitive class */
3758 classinfo *c = class_new_int(utf_new_char(primitivetype_table[i].name));
3759 c->classUsed = NOTUSED; /* not used initially CO-RT */
3762 /* prevent loader from loading primitive class */
3766 primitivetype_table[i].class_primitive = c;
3768 /* create class for wrapping the primitive type */
3769 c = class_new_int(utf_new_char(primitivetype_table[i].wrapname));
3770 primitivetype_table[i].class_wrap = c;
3771 primitivetype_table[i].class_wrap->classUsed = NOTUSED; /* not used initially CO-RT */
3772 primitivetype_table[i].class_wrap->impldBy = NULL;
3774 /* create the primitive array class */
3775 if (primitivetype_table[i].arrayname) {
3776 c = class_new_int(utf_new_char(primitivetype_table[i].arrayname));
3777 primitivetype_table[i].arrayclass = c;
3781 primitivetype_table[i].arrayvftbl = c->vftbl;
3787 /**************** function: class_primitive_from_sig ***************************
3789 return the primitive class indicated by the given signature character
3791 If the descriptor does not indicate a valid primitive type the
3792 return value is NULL.
3794 ********************************************************************************/
3796 classinfo *class_primitive_from_sig(char sig)
3799 case 'I': return primitivetype_table[PRIMITIVETYPE_INT].class_primitive;
3800 case 'J': return primitivetype_table[PRIMITIVETYPE_LONG].class_primitive;
3801 case 'F': return primitivetype_table[PRIMITIVETYPE_FLOAT].class_primitive;
3802 case 'D': return primitivetype_table[PRIMITIVETYPE_DOUBLE].class_primitive;
3803 case 'B': return primitivetype_table[PRIMITIVETYPE_BYTE].class_primitive;
3804 case 'C': return primitivetype_table[PRIMITIVETYPE_CHAR].class_primitive;
3805 case 'S': return primitivetype_table[PRIMITIVETYPE_SHORT].class_primitive;
3806 case 'Z': return primitivetype_table[PRIMITIVETYPE_BOOLEAN].class_primitive;
3807 case 'V': return primitivetype_table[PRIMITIVETYPE_VOID].class_primitive;
3812 /****************** function: class_from_descriptor ****************************
3814 return the class indicated by the given descriptor
3816 utf_ptr....first character of descriptor
3817 end_ptr....first character after the end of the string
3818 next.......if non-NULL, *next is set to the first character after
3819 the descriptor. (Undefined if an error occurs.)
3821 mode.......a combination (binary or) of the following flags:
3823 (Flags marked with * are the default settings.)
3825 What to do if a reference type descriptor is parsed successfully:
3827 CLASSLOAD_SKIP...skip it and return something != NULL
3828 * CLASSLOAD_NEW....get classinfo * via class_new
3829 CLASSLOAD_LOAD...get classinfo * via loader_load
3831 How to handle primitive types:
3833 * CLASSLOAD_PRIMITIVE.......return primitive class (eg. "int")
3834 CLASSLOAD_NULLPRIMITIVE...return NULL for primitive types
3836 How to handle "V" descriptors:
3838 * CLASSLOAD_VOID.....handle it like other primitive types
3839 CLASSLOAD_NOVOID...treat it as an error
3841 How to deal with extra characters after the end of the
3844 * CLASSLOAD_NOCHECKEND...ignore (useful for parameter lists)
3845 CLASSLOAD_CHECKEND.....treat them as an error
3847 How to deal with errors:
3849 * CLASSLOAD_PANIC....abort execution with an error message
3850 CLASSLOAD_NOPANIC..return NULL on error
3852 ********************************************************************************/
3854 classinfo *class_from_descriptor(char *utf_ptr, char *end_ptr,
3855 char **next, int mode)
3857 char *start = utf_ptr;
3861 SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr, end_ptr, error);
3863 if (mode & CLASSLOAD_CHECKEND)
3864 error |= (utf_ptr != end_ptr);
3867 if (next) *next = utf_ptr;
3871 if (mode & CLASSLOAD_NOVOID)
3882 return (mode & CLASSLOAD_NULLPRIMITIVE)
3884 : class_primitive_from_sig(*start);
3891 if (mode & CLASSLOAD_SKIP) return class_java_lang_Object;
3892 name = utf_new(start, utf_ptr - start);
3893 return (mode & CLASSLOAD_LOAD)
3894 ? class_load(class_new(name)) : class_new(name); /* XXX handle errors */
3898 /* An error occurred */
3899 if (mode & CLASSLOAD_NOPANIC)
3902 log_plain("Invalid descriptor at beginning of '");
3903 log_plain_utf(utf_new(start, end_ptr - start));
3907 panic("Invalid descriptor");
3909 /* keep compiler happy */
3914 /******************* function: type_from_descriptor ****************************
3916 return the basic type indicated by the given descriptor
3918 This function parses a descriptor and returns its basic type as
3919 TYPE_INT, TYPE_LONG, TYPE_FLOAT, TYPE_DOUBLE, TYPE_ADDRESS or TYPE_VOID.
3921 cls...if non-NULL the referenced variable is set to the classinfo *
3922 returned by class_from_descriptor.
3924 For documentation of the arguments utf_ptr, end_ptr, next and mode
3925 see class_from_descriptor. The only difference is that
3926 type_from_descriptor always uses CLASSLOAD_PANIC.
3928 ********************************************************************************/
3930 int type_from_descriptor(classinfo **cls, char *utf_ptr, char *end_ptr,
3931 char **next, int mode)
3934 if (!cls) cls = &mycls;
3935 *cls = class_from_descriptor(utf_ptr, end_ptr, next, mode & (~CLASSLOAD_NOPANIC));
3952 return TYPE_ADDRESS;
3956 /*************** function: create_pseudo_classes *******************************
3958 create pseudo classes used by the typechecker
3960 ********************************************************************************/
3962 static void create_pseudo_classes()
3964 /* pseudo class for Arraystubs (extends java.lang.Object) */
3966 pseudo_class_Arraystub = class_new_int(utf_new_char("$ARRAYSTUB$"));
3967 pseudo_class_Arraystub->loaded = true;
3968 pseudo_class_Arraystub->super = class_java_lang_Object;
3969 pseudo_class_Arraystub->interfacescount = 2;
3970 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
3971 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
3972 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
3974 class_link(pseudo_class_Arraystub);
3976 pseudo_class_Arraystub_vftbl = pseudo_class_Arraystub->vftbl;
3978 /* pseudo class representing the null type */
3980 pseudo_class_Null = class_new_int(utf_new_char("$NULL$"));
3981 pseudo_class_Null->loaded = true;
3982 pseudo_class_Null->super = class_java_lang_Object;
3983 class_link(pseudo_class_Null);
3985 /* pseudo class representing new uninitialized objects */
3987 pseudo_class_New = class_new_int(utf_new_char("$NEW$"));
3988 pseudo_class_New->loaded = true;
3989 pseudo_class_New->linked = true;
3990 pseudo_class_New->super = class_java_lang_Object;
3991 /* class_link(pseudo_class_New); */
3995 /********************** Function: loader_init **********************************
3997 Initializes all lists and loads all classes required for the system or the
4000 *******************************************************************************/
4002 void loader_init(u1 *stackbottom)
4006 /* create utf-symbols for pointer comparison of frequently used strings */
4007 utf_innerclasses = utf_new_char("InnerClasses");
4008 utf_constantvalue = utf_new_char("ConstantValue");
4009 utf_code = utf_new_char("Code");
4010 utf_exceptions = utf_new_char("Exceptions");
4011 utf_linenumbertable = utf_new_char("LineNumberTable");
4012 utf_sourcefile = utf_new_char("SourceFile");
4013 utf_finalize = utf_new_char("finalize");
4014 utf_fidesc = utf_new_char("()V");
4015 utf_init = utf_new_char("<init>");
4016 utf_clinit = utf_new_char("<clinit>");
4017 utf_initsystemclass = utf_new_char("initializeSystemClass");
4018 utf_systemclass = utf_new_char("java/lang/System");
4019 utf_vmclassloader = utf_new_char("java/lang/VMClassLoader");
4020 utf_initialize = utf_new_char("initialize");
4021 utf_initializedesc = utf_new_char("(I)V");
4022 utf_vmclass = utf_new_char("java/lang/VMClass");
4023 utf_java_lang_Object= utf_new_char("java/lang/Object");
4024 array_packagename = utf_new_char("<the array package>");
4025 utf_fillInStackTrace_name = utf_new_char("fillInStackTrace");
4026 utf_fillInStackTrace_desc = utf_new_char("()Ljava/lang/Throwable;");
4028 /* create some important classes */
4029 /* These classes have to be created now because the classinfo
4030 * pointers are used in the loading code.
4032 class_java_lang_Object =
4033 class_new_int(utf_java_lang_Object);
4034 class_load(class_java_lang_Object);
4035 class_link(class_java_lang_Object);
4037 class_java_lang_String =
4038 class_new_int(utf_new_char("java/lang/String"));
4039 class_load(class_java_lang_String);
4040 class_link(class_java_lang_String);
4042 class_java_lang_Cloneable =
4043 class_new_int(utf_new_char("java/lang/Cloneable"));
4044 class_load(class_java_lang_Cloneable);
4045 class_link(class_java_lang_Cloneable);
4047 class_java_io_Serializable =
4048 class_new_int(utf_new_char("java/io/Serializable"));
4049 class_load(class_java_io_Serializable);
4050 class_link(class_java_io_Serializable);
4052 /* create classes representing primitive types */
4053 create_primitive_classes();
4055 /* create classes used by the typechecker */
4056 create_pseudo_classes();
4058 /* correct vftbl-entries (retarded loading of class java/lang/String) */
4059 stringtable_update();
4061 #if defined(USE_THREADS)
4062 if (stackbottom != 0)
4068 static void loader_compute_class_values(classinfo *c)
4072 c->vftbl->baseval = ++classvalue;
4075 while (subs != NULL) {
4076 loader_compute_class_values(subs);
4077 subs = subs->nextsub;
4080 c->vftbl->diffval = classvalue - c->vftbl->baseval;
4084 void loader_compute_subclasses(classinfo *c)
4086 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
4090 if (!(c->flags & ACC_INTERFACE)) {
4095 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
4096 c->nextsub = c->super->sub;
4102 /* this is the java.lang.Object special case */
4103 if (!class_java_lang_Object) {
4104 loader_compute_class_values(c);
4107 loader_compute_class_values(class_java_lang_Object);
4110 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
4116 /******************** Function: loader_close ***********************************
4120 *******************************************************************************/
4127 for (slot = 0; slot < class_hash.size; slot++) {
4128 c = class_hash.ptr[slot];
4139 * These are local overrides for various environment variables in Emacs.
4140 * Please do not remove this and leave it at the end of the file, where
4141 * Emacs will automagically detect them.
4142 * ---------------------------------------------------------------------
4145 * indent-tabs-mode: t