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 771 2003-12-13 23:11:08Z stefan $
49 #include "toolbox/memory.h"
50 #include "toolbox/loging.h"
51 #include "threads/thread.h"
52 #include "threads/locks.h"
63 /* global variables ***********************************************************/
65 int count_class_infos = 0; /* variables for measurements */
66 int count_const_pool_len = 0;
67 int count_vftbl_len = 0;
68 int count_all_methods = 0;
69 int count_vmcode_len = 0;
70 int count_extable_len = 0;
71 int count_class_loads = 0;
72 int count_class_inits = 0;
74 static s4 interfaceindex; /* sequential numbering of interfaces */
76 list unloadedclasses; /* list of all referenced but not loaded classes */
77 list unlinkedclasses; /* list of all loaded but not linked classes */
78 list linkedclasses; /* list of all completely linked classes */
81 /* utf-symbols for pointer comparison of frequently used strings */
83 static utf *utf_innerclasses; /* InnerClasses */
84 static utf *utf_constantvalue; /* ConstantValue */
85 static utf *utf_code; /* Code */
86 static utf *utf_finalize; /* finalize */
87 static utf *utf_fidesc; /* ()V changed */
88 static utf *utf_clinit; /* <clinit> */
89 static utf *utf_initsystemclass; /* initializeSystemClass */
90 static utf *utf_systemclass; /* java/lang/System */
91 static utf *utf_vmclassloader; /* java/lang/VMClassLoader */
92 static utf *utf_vmclass; /* java/lang/VMClassLoader */
93 static utf *utf_initialize;
94 static utf *utf_initializedesc;
98 static unzFile uf = 0;
110 /* important system classes ***************************************************/
112 classinfo *class_java_lang_Object;
113 classinfo *class_java_lang_String;
115 classinfo *class_java_lang_Throwable;
116 classinfo *class_java_lang_Cloneable;
117 classinfo *class_java_io_Serializable;
119 /* Pseudo classes for the typechecker */
120 classinfo *pseudo_class_Arraystub = NULL;
121 classinfo *pseudo_class_Null = NULL;
122 classinfo *pseudo_class_New = NULL;
123 vftbl *pseudo_class_Arraystub_vftbl = NULL;
126 /* These are made static so they cannot be used for throwing in native */
128 static classinfo *class_java_lang_ClassCastException;
129 static classinfo *class_java_lang_NullPointerException;
130 static classinfo *class_java_lang_ArrayIndexOutOfBoundsException;
131 static classinfo *class_java_lang_NegativeArraySizeException;
132 static classinfo *class_java_lang_OutOfMemoryError;
133 static classinfo *class_java_lang_ArithmeticException;
134 static classinfo *class_java_lang_ArrayStoreException;
135 static classinfo *class_java_lang_ThreadDeath;
137 static methodinfo method_clone_array;
139 static int loader_inited = 0;
142 /******************************************************************************
144 structure for primitive classes: contains the class for wrapping the
145 primitive type, the primitive class, the name of the class for wrapping,
146 the one character type signature and the name of the primitive class
148 ******************************************************************************/
150 /* CAUTION: Don't change the order of the types. This table is indexed
151 * by the ARRAYTYPE_ constants (expcept ARRAYTYPE_OBJECT).
153 primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = {
154 { NULL, NULL, "java/lang/Integer", 'I', "int" , "[I", NULL, NULL },
155 { NULL, NULL, "java/lang/Long", 'J', "long" , "[J", NULL, NULL },
156 { NULL, NULL, "java/lang/Float", 'F', "float" , "[F", NULL, NULL },
157 { NULL, NULL, "java/lang/Double", 'D', "double" , "[D", NULL, NULL },
158 { NULL, NULL, "java/lang/Byte", 'B', "byte" , "[B", NULL, NULL },
159 { NULL, NULL, "java/lang/Character", 'C', "char" , "[C", NULL, NULL },
160 { NULL, NULL, "java/lang/Short", 'S', "short" , "[S", NULL, NULL },
161 { NULL, NULL, "java/lang/Boolean", 'Z', "boolean" , "[Z", NULL, NULL },
162 { NULL, NULL, "java/lang/Void", 'V', "void" , NULL, NULL, NULL }};
164 /* instances of important system classes **************************************/
166 java_objectheader *proto_java_lang_ClassCastException;
167 java_objectheader *proto_java_lang_NullPointerException;
168 java_objectheader *proto_java_lang_ArrayIndexOutOfBoundsException;
169 java_objectheader *proto_java_lang_NegativeArraySizeException;
170 java_objectheader *proto_java_lang_OutOfMemoryError;
171 java_objectheader *proto_java_lang_ArithmeticException;
172 java_objectheader *proto_java_lang_ArrayStoreException;
173 java_objectheader *proto_java_lang_ThreadDeath;
175 /************* functions for reading classdata *********************************
177 getting classdata in blocks of variable size
178 (8,16,32,64-bit integer or float)
180 *******************************************************************************/
182 static char *classpath = ""; /* searchpath for classfiles */
183 static u1 *classbuffer = NULL; /* pointer to buffer with classfile-data */
184 static u1 *classbuf_pos; /* current position in classfile buffer */
185 static int classbuffer_size; /* size of classfile-data */
187 /* assert that at least <len> bytes are left to read */
188 /* <len> is limited to the range of non-negative s4 values */
189 #define ASSERT_LEFT(len) \
190 do {if ( ((s4)(len)) < 0 \
191 || ((classbuffer + classbuffer_size) - classbuf_pos - 1) < (len)) \
192 panic("Unexpected end of classfile"); } while(0)
194 /* transfer block of classfile data into a buffer */
196 #define suck_nbytes(buffer,len) \
197 do {ASSERT_LEFT(len); \
198 memcpy(buffer,classbuf_pos+1,len); \
199 classbuf_pos+=len;} while (0)
201 /* skip block of classfile data */
203 #define skip_nbytes(len) \
204 do {ASSERT_LEFT(len); \
205 classbuf_pos+=len;} while(0)
210 return *++classbuf_pos;
214 u1 a=suck_u1(), b=suck_u1();
215 return ((u2)a<<8)+(u2)b;
219 u1 a=suck_u1(), b=suck_u1(), c=suck_u1(), d=suck_u1();
220 return ((u4)a<<24)+((u4)b<<16)+((u4)c<<8)+(u4)d;
222 #define suck_s8() (s8) suck_u8()
223 #define suck_s2() (s2) suck_u2()
224 #define suck_s4() (s4) suck_u4()
225 #define suck_s1() (s1) suck_u1()
228 /* get u8 from classfile data */
235 return (hi << 32) + lo;
245 /* get float from classfile data */
246 static float suck_float()
253 for (i = 0; i < 4; i++) buffer[3 - i] = suck_u1();
254 memcpy((u1*) (&f), buffer, 4);
256 suck_nbytes((u1*) (&f), 4);
259 PANICIF (sizeof(float) != 4, "Incompatible float-format");
265 /* get double from classfile data */
266 static double suck_double()
273 for (i = 0; i < 8; i++) buffer[7 - i] = suck_u1 ();
274 memcpy((u1*) (&d), buffer, 8);
276 suck_nbytes((u1*) (&d), 8);
279 PANICIF (sizeof(double) != 8, "Incompatible double-format" );
285 /************************** function suck_init *********************************
287 called once at startup, sets the searchpath for the classfiles
289 *******************************************************************************/
291 void suck_init(char *cpath)
298 /************************** function suck_start ********************************
300 returns true if classbuffer is already loaded or a file for the
301 specified class has succussfully been read in. All directories of
302 the searchpath are used to find the classfile (<classname>.class).
303 Returns false if no classfile is found and writes an error message.
305 *******************************************************************************/
307 bool suck_start(utf *classname)
310 #define MAXFILENAME 1000 /* maximum length of a filename */
312 char filename[MAXFILENAME+10]; /* room for '.class' */
313 char *pathpos; /* position in searchpath */
314 char c, *utf_ptr; /* pointer to the next utf8-character */
316 int filenamelen, err;
320 if (classbuffer) /* classbuffer is already valid */
327 /* skip path separator */
329 while (*pathpos == ':')
332 /* extract directory from searchpath */
335 while ((*pathpos) && (*pathpos != ':')) {
336 PANICIF (filenamelen >= MAXFILENAME, "Filename too long");
337 filename[filenamelen++] = *(pathpos++);
341 if (filenamelen > 4) {
342 if ( ((filename[filenamelen - 1] == 'p') || (filename[filenamelen - 1] == 'P')) &
343 ((filename[filenamelen - 2] == 'i') || (filename[filenamelen - 2] == 'I')) &
344 ((filename[filenamelen - 3] == 'z') || (filename[filenamelen - 3] == 'Z')) ) {
351 filename[filenamelen++] = '\0';
352 if (uf == 0) uf = unzOpen(filename);
354 utf_ptr = classname->text;
356 while (utf_ptr < utf_end(classname)) {
357 PANICIF (filenamelen >= MAXFILENAME, "Filename too long");
359 if ((c <= ' ' || c > 'z') && (c != '/')) /* invalid character */
361 filename[filenamelen++] = c;
363 strcpy(filename + filenamelen, ".class");
364 if (cacao_locate(uf,classname) == UNZ_OK) {
365 unz_file_info file_info;
366 log_text("Class found in zip file");
367 if (unzGetCurrentFileInfo(uf, &file_info, filename,
368 sizeof(filename), NULL, 0, NULL, 0) == UNZ_OK) {
369 if (unzOpenCurrentFile(uf) == UNZ_OK) {
370 classbuffer_size = file_info.uncompressed_size;
371 classbuffer = MNEW(u1, classbuffer_size);
372 classbuf_pos = classbuffer - 1;
373 /*printf("classfile size: %d\n",file_info.uncompressed_size);*/
374 if (unzReadCurrentFile(uf, classbuffer, classbuffer_size) == classbuffer_size) {
375 unzCloseCurrentFile(uf);
378 MFREE(classbuffer, u1, classbuffer_size);
379 log_text("Error while unzipping");
381 } else log_text("Error while opening file in archive");
382 } else log_text("Error while retrieving fileinfo");
384 unzCloseCurrentFile(uf);
389 filename[filenamelen++] = '/';
391 /* add classname to filename */
393 utf_ptr = classname->text;
394 while (utf_ptr < utf_end(classname)) {
395 PANICIF (filenamelen >= MAXFILENAME, "Filename too long");
397 if ((c <= ' ' || c > 'z') && (c != '/')) /* invalid character */
399 filename[filenamelen++] = c;
404 strcpy(filename + filenamelen, ".class");
406 classfile = fopen(filename, "r");
407 if (classfile) { /* file exists */
409 /* determine size of classfile */
411 /* dolog("File: %s",filename); */
413 err = stat(filename, &buffer);
415 if (!err) { /* read classfile data */
416 classbuffer_size = buffer.st_size;
417 classbuffer = MNEW(u1, classbuffer_size);
418 classbuf_pos = classbuffer - 1;
419 fread(classbuffer, 1, classbuffer_size, classfile);
427 dolog("Warning: Can not open class file '%s'", filename);
434 /************************** function suck_stop *********************************
436 frees memory for buffer with classfile data.
437 Caution: this function may only be called if buffer has been allocated
438 by suck_start with reading a file
440 *******************************************************************************/
444 /* determine amount of classdata not retrieved by suck-operations */
446 int classdata_left = ((classbuffer + classbuffer_size) - classbuf_pos - 1);
448 if (classdata_left > 0) {
450 dolog("There are %d access bytes at end of classfile",
457 MFREE(classbuffer, u1, classbuffer_size);
462 /******************************************************************************/
463 /******************* Some support functions ***********************************/
464 /******************************************************************************/
468 void fprintflags (FILE *fp, u2 f)
470 if ( f & ACC_PUBLIC ) fprintf (fp," PUBLIC");
471 if ( f & ACC_PRIVATE ) fprintf (fp," PRIVATE");
472 if ( f & ACC_PROTECTED ) fprintf (fp," PROTECTED");
473 if ( f & ACC_STATIC ) fprintf (fp," STATIC");
474 if ( f & ACC_FINAL ) fprintf (fp," FINAL");
475 if ( f & ACC_SYNCHRONIZED ) fprintf (fp," SYNCHRONIZED");
476 if ( f & ACC_VOLATILE ) fprintf (fp," VOLATILE");
477 if ( f & ACC_TRANSIENT ) fprintf (fp," TRANSIENT");
478 if ( f & ACC_NATIVE ) fprintf (fp," NATIVE");
479 if ( f & ACC_INTERFACE ) fprintf (fp," INTERFACE");
480 if ( f & ACC_ABSTRACT ) fprintf (fp," ABSTRACT");
483 /********** internal function: printflags (only for debugging) ***************/
484 void printflags (u2 f)
486 if ( f & ACC_PUBLIC ) printf (" PUBLIC");
487 if ( f & ACC_PRIVATE ) printf (" PRIVATE");
488 if ( f & ACC_PROTECTED ) printf (" PROTECTED");
489 if ( f & ACC_STATIC ) printf (" STATIC");
490 if ( f & ACC_FINAL ) printf (" FINAL");
491 if ( f & ACC_SYNCHRONIZED ) printf (" SYNCHRONIZED");
492 if ( f & ACC_VOLATILE ) printf (" VOLATILE");
493 if ( f & ACC_TRANSIENT ) printf (" TRANSIENT");
494 if ( f & ACC_NATIVE ) printf (" NATIVE");
495 if ( f & ACC_INTERFACE ) printf (" INTERFACE");
496 if ( f & ACC_ABSTRACT ) printf (" ABSTRACT");
500 /************************* Function: skipattribute *****************************
502 skips a (1) 'attribute' structure in the class file
504 *******************************************************************************/
506 static void skipattribute ()
514 /********************** Function: skipattributebody ****************************
516 skips an attribute after the 16 bit reference to attribute_name has already
519 *******************************************************************************/
521 static void skipattributebody ()
528 /************************* Function: skipattributes ****************************
530 skips num attribute structures
532 *******************************************************************************/
534 static void skipattributes (u4 num)
537 for (i = 0; i < num; i++)
541 /******************** function: innerclass_getconstant ************************
543 like class_getconstant, but if cptags is ZERO null is returned
545 *******************************************************************************/
547 voidptr innerclass_getconstant (classinfo *c, u4 pos, u4 ctype)
549 /* invalid position in constantpool */
550 if (pos >= c->cpcount)
551 panic ("Attempt to access constant outside range");
553 /* constantpool entry of type 0 */
557 /* check type of constantpool entry */
558 if (c->cptags[pos] != ctype) {
559 error ("Type mismatch on constant: %d requested, %d here (innerclass_getconstant)",
560 (int) ctype, (int) c->cptags[pos] );
563 return c->cpinfos[pos];
566 /************************ function: attribute_load ****************************
568 read attributes from classfile
570 *******************************************************************************/
572 static void attribute_load (u4 num, classinfo *c)
576 for (i = 0; i < num; i++) {
577 /* retrieve attribute name */
578 utf *aname = class_getconstant (c, suck_u2(), CONSTANT_Utf8);
580 if ( aname == utf_innerclasses) {
581 /* innerclasses attribute */
583 /* skip attribute length */
585 /* number of records */
586 c->innerclasscount = suck_u2();
587 /* allocate memory for innerclass structure */
588 c->innerclass = MNEW (innerclassinfo, c->innerclasscount);
590 for (j=0;j<c->innerclasscount;j++) {
592 /* The innerclass structure contains a class with an encoded name,
593 its defining scope, its simple name and a bitmask of the access flags.
594 If an inner class is not a member, its outer_class is NULL,
595 if a class is anonymous, its name is NULL. */
597 innerclassinfo *info = c->innerclass + j;
599 info->inner_class = innerclass_getconstant(c, suck_u2(), CONSTANT_Class); /* CONSTANT_Class_info index */
600 info->outer_class = innerclass_getconstant(c, suck_u2(), CONSTANT_Class); /* CONSTANT_Class_info index */
601 info->name = innerclass_getconstant(c, suck_u2(), CONSTANT_Utf8); /* CONSTANT_Utf8_info index */
602 info->flags = suck_u2 (); /* access_flags bitmask */
605 /* unknown attribute */
606 skipattributebody ();
611 /******************* function: checkfielddescriptor ****************************
613 checks whether a field-descriptor is valid and aborts otherwise
614 all referenced classes are inserted into the list of unloaded classes
616 *******************************************************************************/
618 static void checkfielddescriptor (char *utf_ptr, char *end_pos)
620 class_from_descriptor(utf_ptr,end_pos,NULL,
622 | CLASSLOAD_NULLPRIMITIVE
624 | CLASSLOAD_CHECKEND);
626 char *tstart; /* pointer to start of classname */
628 char *start = utf_ptr;
630 switch (*utf_ptr++) {
644 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
645 panic ("Ill formed descriptor");
649 panic ("Ill formed descriptor");
652 /* exceeding characters */
653 if (utf_ptr!=end_pos) panic ("descriptor has exceeding chars");
658 /******************* function checkmethoddescriptor ****************************
660 checks whether a method-descriptor is valid and aborts otherwise.
661 All referenced classes are inserted into the list of unloaded classes.
663 *******************************************************************************/
665 static void checkmethoddescriptor (utf *d)
667 char *utf_ptr = d->text; /* current position in utf text */
668 char *end_pos = utf_end(d); /* points behind utf string */
670 /* method descriptor must start with parenthesis */
671 if (utf_ptr == end_pos || *utf_ptr++ != '(') panic ("Missing '(' in method descriptor");
673 /* check arguments */
674 while (utf_ptr != end_pos && *utf_ptr != ')') {
675 class_from_descriptor(utf_ptr,end_pos,&utf_ptr,
677 | CLASSLOAD_NULLPRIMITIVE
681 if (utf_ptr == end_pos) panic("Missing return type in method descriptor");
682 utf_ptr++; /* skip ')' */
684 class_from_descriptor(utf_ptr,end_pos,NULL,
686 | CLASSLOAD_NULLPRIMITIVE
687 | CLASSLOAD_CHECKEND);
690 /* XXX check length */
691 /* check arguments */
692 while ((c = *utf_ptr++) != ')') {
709 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
710 panic ("Ill formed method descriptor");
714 panic ("Ill formed methodtype-descriptor");
718 /* check returntype */
720 /* returntype void */
721 if ((utf_ptr+1) != end_pos) panic ("Method-descriptor has exceeding chars");
724 /* treat as field-descriptor */
725 checkfielddescriptor (utf_ptr,end_pos);
730 /***************** Function: print_arraydescriptor ****************************
732 Debugging helper for displaying an arraydescriptor
734 *******************************************************************************/
736 void print_arraydescriptor(FILE *file, arraydescriptor *desc)
739 fprintf(file, "<NULL>");
744 if (desc->componentvftbl) {
745 if (desc->componentvftbl->class)
746 utf_fprint(file, desc->componentvftbl->class->name);
748 fprintf(file, "<no classinfo>");
754 if (desc->elementvftbl) {
755 if (desc->elementvftbl->class)
756 utf_fprint(file, desc->elementvftbl->class->name);
758 fprintf(file, "<no classinfo>");
762 fprintf(file, ",%d,%d,%d,%d}", desc->arraytype, desc->dimension,
763 desc->dataoffset, desc->componentsize);
767 /******************************************************************************/
768 /************************** Functions for fields ****************************/
769 /******************************************************************************/
772 /************************ Function: field_load *********************************
774 Load everything about a class field from the class file and fill a
775 'fieldinfo' structure. For static fields, space in the data segment is
778 *******************************************************************************/
780 static void field_load (fieldinfo *f, classinfo *c)
785 f -> flags = suck_u2 (); /* ACC flags */
786 f -> name = class_getconstant (c, suck_u2(), CONSTANT_Utf8); /* name of field */
787 f -> descriptor = class_getconstant (c, suck_u2(), CONSTANT_Utf8); /* JavaVM descriptor */
788 f -> type = jtype = desc_to_type (f->descriptor); /* data type */
789 f -> offset = 0; /* offset from start of object */
794 case TYPE_INT: f->value.i = 0; break;
795 case TYPE_FLOAT: f->value.f = 0.0; break;
796 case TYPE_DOUBLE: f->value.d = 0.0; break;
797 case TYPE_ADDRESS: f->value.a = NULL;
798 /* heap_addreference (&(f->value.a)); /* make global reference (GC) */
802 f->value.l = 0; break;
804 f->value.l.low = 0; f->value.l.high = 0; break;
808 /* read attributes */
810 for (i=0; i<attrnum; i++) {
814 aname = class_getconstant (c, suck_u2(), CONSTANT_Utf8);
816 if ( aname != utf_constantvalue ) {
817 /* unknown attribute */
818 skipattributebody ();
821 /* constant value attribute */
823 /* skip attribute length */
825 /* index of value in constantpool */
828 /* initialize field with value from constantpool */
831 constant_integer *ci =
832 class_getconstant(c, pindex, CONSTANT_Integer);
833 f->value.i = ci -> value;
839 class_getconstant(c, pindex, CONSTANT_Long);
841 f->value.l = cl -> value;
847 class_getconstant(c, pindex, CONSTANT_Float);
849 f->value.f = cf->value;
854 constant_double *cd =
855 class_getconstant(c, pindex, CONSTANT_Double);
857 f->value.d = cd->value;
862 utf *u = class_getconstant(c, pindex, CONSTANT_String);
863 /* create javastring from compressed utf8-string */
864 f->value.a = literalstring_new(u);
869 log_text ("Invalid Constant - Type");
878 /********************** function: field_free **********************************/
880 static void field_free (fieldinfo *f)
886 /**************** Function: field_display (debugging only) ********************/
888 void field_display(fieldinfo *f)
891 printflags(f->flags);
893 utf_display(f->name);
895 utf_display(f->descriptor);
896 printf(" offset: %ld\n", (long int) (f->offset));
900 /******************************************************************************/
901 /************************* Functions for methods ******************************/
902 /******************************************************************************/
905 /*********************** Function: method_load *********************************
907 Loads a method from the class file and fills an existing 'methodinfo'
908 structure. For native methods, the function pointer field is set to the
909 real function pointer, for JavaVM methods a pointer to the compiler is used
912 *******************************************************************************/
914 static void method_load(methodinfo *m, classinfo *c)
924 m->flags = suck_u2();
925 m->name = class_getconstant(c, suck_u2(), CONSTANT_Utf8);
926 m->descriptor = class_getconstant(c, suck_u2(), CONSTANT_Utf8);
927 checkmethoddescriptor(m->descriptor);
930 m->exceptiontable = NULL;
931 m->entrypoint = NULL;
933 m->stubroutine = NULL;
934 m->methodUsed = NOTUSED;
937 m->subRedefsUsed = 0;
941 if (!(m->flags & ACC_NATIVE)) {
942 m->stubroutine = createcompilerstub(m);
945 functionptr f = native_findfunction(c->name, m->name, m->descriptor,
946 (m->flags & ACC_STATIC) != 0);
948 m->stubroutine = createnativestub(f, m);
954 for (i = 0; i < attrnum; i++) {
957 aname = class_getconstant(c, suck_u2(), CONSTANT_Utf8);
959 if (aname != utf_code) {
965 panic("Two code-attributes for one method!");
968 m->maxstack = suck_u2();
969 m->maxlocals = suck_u2();
972 panic("bytecode has zero length");
974 panic("bytecode too long");
975 m->jcodelength = codelen;
976 m->jcode = MNEW(u1, m->jcodelength);
977 suck_nbytes(m->jcode, m->jcodelength);
978 m->exceptiontablelength = suck_u2();
980 MNEW(exceptiontable, m->exceptiontablelength);
983 count_vmcode_len += m->jcodelength + 18;
984 count_extable_len += 8 * m->exceptiontablelength;
987 for (e = 0; e < m->exceptiontablelength; e++) {
989 m->exceptiontable[e].startpc = suck_u2();
990 m->exceptiontable[e].endpc = suck_u2();
991 m->exceptiontable[e].handlerpc = suck_u2();
995 m->exceptiontable[e].catchtype = NULL;
998 m->exceptiontable[e].catchtype =
999 class_getconstant(c, idx, CONSTANT_Class);
1003 skipattributes(suck_u2());
1009 /********************* Function: method_free ***********************************
1011 frees all memory that was allocated for this method
1013 *******************************************************************************/
1015 static void method_free(methodinfo *m)
1018 MFREE(m->jcode, u1, m->jcodelength);
1020 if (m->exceptiontable)
1021 MFREE(m->exceptiontable, exceptiontable, m->exceptiontablelength);
1024 CFREE(m->mcode, m->mcodelength);
1026 if (m->stubroutine) {
1027 if (m->flags & ACC_NATIVE) {
1028 removenativestub(m->stubroutine);
1031 removecompilerstub(m->stubroutine);
1037 /************** Function: method_display (debugging only) **************/
1039 void method_display(methodinfo *m)
1042 printflags(m->flags);
1044 utf_display(m->name);
1046 utf_display(m->descriptor);
1051 /******************** Function: method_canoverwrite ****************************
1053 Check if m and old are identical with respect to type and name. This means
1054 that old can be overwritten with m.
1056 *******************************************************************************/
1058 static bool method_canoverwrite (methodinfo *m, methodinfo *old)
1060 if (m->name != old->name) return false;
1061 if (m->descriptor != old->descriptor) return false;
1062 if (m->flags & ACC_STATIC) return false;
1069 /******************************************************************************/
1070 /************************ Functions for class *********************************/
1071 /******************************************************************************/
1074 /******************** function:: class_getconstant ******************************
1076 retrieves the value at position 'pos' of the constantpool of a class
1077 if the type of the value is other than 'ctype' the system is stopped
1079 *******************************************************************************/
1081 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
1083 /* invalid position in constantpool */
1084 if (pos >= c->cpcount)
1085 panic("Attempt to access constant outside range");
1087 /* check type of constantpool entry */
1089 if (c->cptags[pos] != ctype) {
1090 class_showconstantpool(c);
1091 error("Type mismatch on constant: %d requested, %d here (class_getconstant)",
1092 (int) ctype, (int) c->cptags[pos]);
1095 return c->cpinfos[pos];
1099 /********************* Function: class_constanttype ****************************
1101 Determines the type of a class entry in the ConstantPool
1103 *******************************************************************************/
1105 u4 class_constanttype(classinfo *c, u4 pos)
1107 if (pos >= c->cpcount)
1108 panic("Attempt to access constant outside range");
1110 return c->cptags[pos];
1114 /******************** function: class_loadcpool ********************************
1116 loads the constantpool of a class,
1117 the entries are transformed into a simpler format
1118 by resolving references
1119 (a detailed overview of the compact structures can be found in global.h)
1121 *******************************************************************************/
1123 static void class_loadcpool(classinfo *c)
1126 /* The following structures are used to save information which cannot be
1127 processed during the first pass. After the complete constantpool has
1128 been traversed the references can be resolved.
1129 (only in specific order) */
1131 /* CONSTANT_Class_info entries */
1132 typedef struct forward_class {
1133 struct forward_class *next;
1138 /* CONSTANT_String */
1139 typedef struct forward_string {
1140 struct forward_string *next;
1145 /* CONSTANT_NameAndType */
1146 typedef struct forward_nameandtype {
1147 struct forward_nameandtype *next;
1151 } forward_nameandtype;
1153 /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
1154 typedef struct forward_fieldmethint {
1155 struct forward_fieldmethint *next;
1159 u2 nameandtype_index;
1160 } forward_fieldmethint;
1164 long int dumpsize = dump_size ();
1166 forward_class *forward_classes = NULL;
1167 forward_string *forward_strings = NULL;
1168 forward_nameandtype *forward_nameandtypes = NULL;
1169 forward_fieldmethint *forward_fieldmethints = NULL;
1171 /* number of entries in the constant_pool table */
1172 u4 cpcount = c -> cpcount = suck_u2();
1173 /* allocate memory */
1174 u1 *cptags = c -> cptags = MNEW (u1, cpcount);
1175 voidptr *cpinfos = c -> cpinfos = MNEW (voidptr, cpcount);
1178 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
1181 /* initialize constantpool */
1182 for (idx=0; idx<cpcount; idx++) {
1183 cptags[idx] = CONSTANT_UNUSED;
1184 cpinfos[idx] = NULL;
1188 /******* first pass *******/
1189 /* entries which cannot be resolved now are written into
1190 temporary structures and traversed again later */
1193 while (idx < cpcount) {
1194 /* get constant type */
1198 case CONSTANT_Class: {
1199 forward_class *nfc = DNEW(forward_class);
1201 nfc -> next = forward_classes;
1202 forward_classes = nfc;
1204 nfc -> thisindex = idx;
1205 /* reference to CONSTANT_NameAndType */
1206 nfc -> name_index = suck_u2 ();
1212 case CONSTANT_Fieldref:
1213 case CONSTANT_Methodref:
1214 case CONSTANT_InterfaceMethodref: {
1215 forward_fieldmethint *nff = DNEW (forward_fieldmethint);
1217 nff -> next = forward_fieldmethints;
1218 forward_fieldmethints = nff;
1220 nff -> thisindex = idx;
1223 /* class or interface type that contains the declaration of the field or method */
1224 nff -> class_index = suck_u2 ();
1225 /* name and descriptor of the field or method */
1226 nff -> nameandtype_index = suck_u2 ();
1232 case CONSTANT_String: {
1233 forward_string *nfs = DNEW (forward_string);
1235 nfs -> next = forward_strings;
1236 forward_strings = nfs;
1238 nfs -> thisindex = idx;
1239 /* reference to CONSTANT_Utf8_info with string characters */
1240 nfs -> string_index = suck_u2 ();
1246 case CONSTANT_NameAndType: {
1247 forward_nameandtype *nfn = DNEW (forward_nameandtype);
1249 nfn -> next = forward_nameandtypes;
1250 forward_nameandtypes = nfn;
1252 nfn -> thisindex = idx;
1253 /* reference to CONSTANT_Utf8_info containing simple name */
1254 nfn -> name_index = suck_u2 ();
1255 /* reference to CONSTANT_Utf8_info containing field or method descriptor */
1256 nfn -> sig_index = suck_u2 ();
1262 case CONSTANT_Integer: {
1263 constant_integer *ci = NEW (constant_integer);
1266 count_const_pool_len += sizeof(constant_integer);
1269 ci -> value = suck_s4 ();
1270 cptags [idx] = CONSTANT_Integer;
1277 case CONSTANT_Float: {
1278 constant_float *cf = NEW (constant_float);
1281 count_const_pool_len += sizeof(constant_float);
1284 cf -> value = suck_float ();
1285 cptags [idx] = CONSTANT_Float;
1291 case CONSTANT_Long: {
1292 constant_long *cl = NEW(constant_long);
1295 count_const_pool_len += sizeof(constant_long);
1298 cl -> value = suck_s8 ();
1299 cptags [idx] = CONSTANT_Long;
1305 case CONSTANT_Double: {
1306 constant_double *cd = NEW(constant_double);
1309 count_const_pool_len += sizeof(constant_double);
1312 cd -> value = suck_double ();
1313 cptags [idx] = CONSTANT_Double;
1319 case CONSTANT_Utf8: {
1321 /* number of bytes in the bytes array (not string-length) */
1322 u4 length = suck_u2();
1323 cptags [idx] = CONSTANT_Utf8;
1324 /* validate the string */
1325 ASSERT_LEFT(length);
1326 if (!is_valid_utf(classbuf_pos+1, classbuf_pos+1+length))
1327 panic("Invalid UTF-8 string");
1328 /* insert utf-string into the utf-symboltable */
1329 cpinfos [idx] = utf_new(classbuf_pos+1, length);
1330 /* skip bytes of the string */
1331 skip_nbytes(length);
1337 error ("Unkown constant type: %d",(int) t);
1345 /* resolve entries in temporary structures */
1347 while (forward_classes) {
1349 class_getconstant (c, forward_classes -> name_index, CONSTANT_Utf8);
1351 cptags [forward_classes -> thisindex] = CONSTANT_Class;
1352 /* retrieve class from class-table */
1353 cpinfos [forward_classes -> thisindex] = class_new (name);
1355 forward_classes = forward_classes -> next;
1359 while (forward_strings) {
1361 class_getconstant (c, forward_strings -> string_index, CONSTANT_Utf8);
1363 log_text("forward_string:");
1364 printf( "classpoolid: %d\n",forward_strings -> thisindex);
1366 log_text("\n------------------"); */
1367 /* resolve utf-string */
1368 cptags [forward_strings -> thisindex] = CONSTANT_String;
1369 cpinfos [forward_strings -> thisindex] = text;
1371 forward_strings = forward_strings -> next;
1374 while (forward_nameandtypes) {
1375 constant_nameandtype *cn = NEW (constant_nameandtype);
1378 count_const_pool_len += sizeof(constant_nameandtype);
1381 /* resolve simple name and descriptor */
1382 cn -> name = class_getconstant
1383 (c, forward_nameandtypes -> name_index, CONSTANT_Utf8);
1384 cn -> descriptor = class_getconstant
1385 (c, forward_nameandtypes -> sig_index, CONSTANT_Utf8);
1387 cptags [forward_nameandtypes -> thisindex] = CONSTANT_NameAndType;
1388 cpinfos [forward_nameandtypes -> thisindex] = cn;
1390 forward_nameandtypes = forward_nameandtypes -> next;
1394 while (forward_fieldmethints) {
1395 constant_nameandtype *nat;
1396 constant_FMIref *fmi = NEW (constant_FMIref);
1399 count_const_pool_len += sizeof(constant_FMIref);
1401 /* resolve simple name and descriptor */
1402 nat = class_getconstant
1403 (c, forward_fieldmethints -> nameandtype_index, CONSTANT_NameAndType);
1406 log_text("trying to resolve:");
1407 log_text(nat->name->text);
1408 switch(forward_fieldmethints ->tag) {
1409 case CONSTANT_Fieldref:
1410 log_text("CONSTANT_Fieldref");
1412 case CONSTANT_InterfaceMethodref:
1413 log_text("CONSTANT_InterfaceMethodref");
1415 case CONSTANT_Methodref:
1416 log_text("CONSTANT_Methodref");
1420 fmi -> class = class_getconstant
1421 (c, forward_fieldmethints -> class_index, CONSTANT_Class);
1422 fmi -> name = nat -> name;
1423 fmi -> descriptor = nat -> descriptor;
1425 cptags [forward_fieldmethints -> thisindex] = forward_fieldmethints -> tag;
1426 cpinfos [forward_fieldmethints -> thisindex] = fmi;
1428 switch (forward_fieldmethints -> tag) {
1429 case CONSTANT_Fieldref: /* check validity of descriptor */
1430 checkfielddescriptor (fmi->descriptor->text,utf_end(fmi->descriptor));
1432 case CONSTANT_InterfaceMethodref:
1433 case CONSTANT_Methodref: /* check validity of descriptor */
1434 /* XXX check special names (<init>) */
1435 checkmethoddescriptor (fmi->descriptor);
1439 forward_fieldmethints = forward_fieldmethints -> next;
1443 /* class_showconstantpool(c); */
1445 dump_release (dumpsize);
1449 /********************** Function: class_load ***********************************
1451 Loads everything interesting about a class from the class file. The
1452 'classinfo' structure must have been allocated previously.
1454 The super class and the interfaces implemented by this class need not be
1455 loaded. The link is set later by the function 'class_link'.
1457 The loaded class is removed from the list 'unloadedclasses' and added to
1458 the list 'unlinkedclasses'.
1460 *******************************************************************************/
1462 static int class_load(classinfo *c)
1468 count_class_loads++;
1471 /* output for debugging purposes */
1473 char logtext[MAXLOGTEXT];
1474 sprintf(logtext, "Loading class: ");
1475 utf_sprint(logtext + strlen(logtext), c->name);
1479 /* load classdata, throw exception on error */
1481 if (!suck_start(c->name)) {
1482 throw_noclassdeffounderror_message(c->name);
1486 /* check signature */
1487 if (suck_u4() != MAGIC) panic("Can not find class-file signature");
1491 if (ma != MAJOR_VERSION && (ma != MAJOR_VERSION+1 || mi != 0)) {
1492 error("File version %d.%d is not supported", (int) ma, (int) mi);
1497 c->erroneous_state = 0;
1498 c->initializing_thread = 0;
1500 c->classUsed = NOTUSED; /* not used initially CO-RT */
1504 c->flags = suck_u2();
1505 /*if (!(c->flags & ACC_PUBLIC)) { log_text("CLASS NOT PUBLIC"); } JOWENN*/
1510 /* retrieve superclass */
1511 if ((i = suck_u2())) {
1512 c->super = class_getconstant(c, i, CONSTANT_Class);
1518 /* retrieve interfaces */
1519 c->interfacescount = suck_u2();
1520 c->interfaces = MNEW(classinfo*, c->interfacescount);
1521 for (i = 0; i < c->interfacescount; i++) {
1523 class_getconstant(c, suck_u2(), CONSTANT_Class);
1527 c->fieldscount = suck_u2();
1528 /* utf_display(c->name);
1529 printf(" ,Fieldscount: %d\n",c->fieldscount);*/
1531 c->fields = GCNEW(fieldinfo, c->fieldscount);
1532 for (i = 0; i < c->fieldscount; i++) {
1533 field_load(&(c->fields[i]), c);
1537 c->methodscount = suck_u2();
1538 c->methods = MNEW(methodinfo, c->methodscount);
1539 for (i = 0; i < c->methodscount; i++) {
1540 method_load(&(c->methods[i]), c);
1544 count_class_infos += sizeof(classinfo*) * c->interfacescount;
1545 count_class_infos += sizeof(fieldinfo) * c->fieldscount;
1546 count_class_infos += sizeof(methodinfo) * c->methodscount;
1549 /* load variable-length attribute structures */
1550 attribute_load(suck_u2(), c);
1555 /* remove class from list of unloaded classes and
1556 add to list of unlinked classes */
1557 list_remove(&unloadedclasses, c);
1558 list_addlast(&unlinkedclasses, c);
1567 /************** internal Function: class_highestinterface ***********************
1569 Used by the function class_link to determine the amount of memory needed
1570 for the interface table.
1572 *******************************************************************************/
1574 static s4 class_highestinterface(classinfo *c)
1579 if (!(c->flags & ACC_INTERFACE)) {
1580 char logtext[MAXLOGTEXT];
1581 sprintf(logtext, "Interface-methods count requested for non-interface: ");
1582 utf_sprint(logtext + strlen(logtext), c->name);
1587 for (i = 0; i < c->interfacescount; i++) {
1588 s4 h2 = class_highestinterface(c->interfaces[i]);
1596 /* class_addinterface **********************************************************
1598 Is needed by class_link for adding a VTBL to a class. All interfaces
1599 implemented by ic are added as well.
1601 *******************************************************************************/
1603 static void class_addinterface (classinfo *c, classinfo *ic)
1607 vftbl *vftbl = c->vftbl;
1609 if (i >= vftbl->interfacetablelength)
1610 panic ("Inernal error: interfacetable overflow");
1611 if (vftbl->interfacetable[-i])
1614 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1615 vftbl->interfacevftbllength[i] = 1;
1616 vftbl->interfacetable[-i] = MNEW(methodptr, 1);
1617 vftbl->interfacetable[-i][0] = NULL;
1620 vftbl->interfacevftbllength[i] = ic->methodscount;
1621 vftbl->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1624 count_vftbl_len += sizeof(methodptr) *
1625 (ic->methodscount + (ic->methodscount == 0));
1628 for (j=0; j<ic->methodscount; j++) {
1631 for (m = 0; m < sc->methodscount; m++) {
1632 methodinfo *mi = &(sc->methods[m]);
1633 if (method_canoverwrite(mi, &(ic->methods[j]))) {
1634 vftbl->interfacetable[-i][j] =
1635 vftbl->table[mi->vftblindex];
1645 for (j = 0; j < ic->interfacescount; j++)
1646 class_addinterface(c, ic->interfaces[j]);
1650 /******************* Function: class_new_array *********************************
1652 This function is called by class_new to setup an array class.
1654 *******************************************************************************/
1656 void class_new_array(classinfo *c)
1658 classinfo *comp = NULL;
1662 /* XXX remove */ /* dolog("class_new_array: %s",c->name->text); */
1664 /* Array classes are not loaded from classfiles. */
1665 list_remove (&unloadedclasses, c);
1667 /* Check array class name */
1668 namelen = c->name->blength;
1669 if (namelen < 2 || c->name->text[0] != '[')
1670 panic("Invalid array class name");
1672 /* Check the component type */
1673 switch (c->name->text[1]) {
1675 /* c is an array of arrays. We have to create the component class. */
1676 comp = class_new(utf_new(c->name->text + 1,namelen - 1));
1680 /* c is an array of objects. */
1681 if (namelen < 4 || c->name->text[namelen-1] != ';')
1682 panic("Invalid array class name");
1683 comp = class_new(utf_new(c->name->text + 2,namelen - 3));
1687 /* Setup the array class */
1688 c->super = class_java_lang_Object;
1689 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
1691 c->interfacescount = 2;
1692 c->interfaces = MNEW(classinfo*,2); /* XXX use GC? */
1693 c->interfaces[0] = class_java_lang_Cloneable;
1694 c->interfaces[1] = class_java_io_Serializable;
1696 c->methodscount = 1;
1697 c->methods = MNEW (methodinfo, c->methodscount); /* XXX use GC? */
1700 memset(clone, 0, sizeof(methodinfo));
1701 clone->flags = ACC_PUBLIC; /* XXX protected? */
1702 clone->name = utf_new_char("clone");
1703 clone->descriptor = utf_new_char("()Ljava/lang/Object;");
1705 clone->stubroutine = createnativestub((functionptr) &builtin_clone_array, clone);
1706 clone->monoPoly = MONO; /* XXX should be poly? */
1708 /* XXX: field: length? */
1710 /* The array class has to be linked */
1711 list_addlast(&unlinkedclasses,c);
1714 * Array classes which are created after the other classes have been
1715 * loaded and linked are linked explicitely.
1720 loader_load(c->name); /* XXX handle errors */
1724 /****************** Function: class_link_array *********************************
1726 This function is called by class_link to create the
1727 arraydescriptor for an array class.
1729 This function returns NULL if the array cannot be linked because
1730 the component type has not been linked yet.
1732 *******************************************************************************/
1734 static arraydescriptor *class_link_array(classinfo *c)
1736 classinfo *comp = NULL;
1737 int namelen = c->name->blength;
1738 arraydescriptor *desc;
1741 /* Check the component type */
1742 switch (c->name->text[1]) {
1744 /* c is an array of arrays. */
1745 comp = class_get(utf_new(c->name->text + 1,namelen - 1));
1746 if (!comp) panic("Could not find component array class.");
1750 /* c is an array of objects. */
1751 comp = class_get(utf_new(c->name->text + 2,namelen - 3));
1752 if (!comp) panic("Could not find component class.");
1756 /* If the component type has not been linked return NULL */
1757 if (comp && !comp->linked)
1760 /* Allocate the arraydescriptor */
1761 desc = NEW(arraydescriptor);
1764 /* c is an array of references */
1765 desc->arraytype = ARRAYTYPE_OBJECT;
1766 desc->componentsize = sizeof(void*);
1767 desc->dataoffset = OFFSET(java_objectarray,data);
1769 compvftbl = comp->vftbl;
1771 panic("Component class has no vftbl.");
1772 desc->componentvftbl = compvftbl;
1774 if (compvftbl->arraydesc) {
1775 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
1776 desc->dimension = compvftbl->arraydesc->dimension + 1;
1777 desc->elementtype = compvftbl->arraydesc->elementtype;
1780 desc->elementvftbl = compvftbl;
1781 desc->dimension = 1;
1782 desc->elementtype = ARRAYTYPE_OBJECT;
1786 /* c is an array of a primitive type */
1787 switch (c->name->text[1]) {
1788 case 'Z': desc->arraytype = ARRAYTYPE_BOOLEAN;
1789 desc->dataoffset = OFFSET(java_booleanarray,data);
1790 desc->componentsize = sizeof(u1); break;
1791 case 'B': desc->arraytype = ARRAYTYPE_BYTE;
1792 desc->dataoffset = OFFSET(java_bytearray,data);
1793 desc->componentsize = sizeof(u1); break;
1794 case 'C': desc->arraytype = ARRAYTYPE_CHAR;
1795 desc->dataoffset = OFFSET(java_chararray,data);
1796 desc->componentsize = sizeof(u2); break;
1797 case 'D': desc->arraytype = ARRAYTYPE_DOUBLE;
1798 desc->dataoffset = OFFSET(java_doublearray,data);
1799 desc->componentsize = sizeof(double); break;
1800 case 'F': desc->arraytype = ARRAYTYPE_FLOAT;
1801 desc->dataoffset = OFFSET(java_floatarray,data);
1802 desc->componentsize = sizeof(float); break;
1803 case 'I': desc->arraytype = ARRAYTYPE_INT;
1804 desc->dataoffset = OFFSET(java_intarray,data);
1805 desc->componentsize = sizeof(s4); break;
1806 case 'J': desc->arraytype = ARRAYTYPE_LONG;
1807 desc->dataoffset = OFFSET(java_longarray,data);
1808 desc->componentsize = sizeof(s8); break;
1809 case 'S': desc->arraytype = ARRAYTYPE_SHORT;
1810 desc->dataoffset = OFFSET(java_shortarray,data);
1811 desc->componentsize = sizeof(s2); break;
1813 panic("Invalid array class name");
1816 desc->componentvftbl = NULL;
1817 desc->elementvftbl = NULL;
1818 desc->dimension = 1;
1819 desc->elementtype = desc->arraytype;
1826 /********************** Function: class_link ***********************************
1828 Tries to link a class. The super class and every implemented interface must
1829 already have been linked. The function calculates the length in bytes that
1830 an instance of this class requires as well as the VTBL for methods and
1833 If the class can be linked, it is removed from the list 'unlinkedclasses'
1834 and added to 'linkedclasses'. Otherwise, it is moved to the end of
1837 Attention: If cyclical class definitions are encountered, the program gets
1838 into an infinite loop (we'll have to work that out)
1840 *******************************************************************************/
1842 void class_link(classinfo *c)
1844 s4 supervftbllength; /* vftbllegnth of super class */
1845 s4 vftbllength; /* vftbllength of current class */
1846 s4 interfacetablelength; /* interface table length */
1847 classinfo *super = c->super; /* super class */
1848 classinfo *ic, *c2; /* intermediate class variables */
1849 vftbl *v; /* vftbl of current class */
1850 s4 i; /* interface/method/field counter */
1851 arraydescriptor *arraydesc = NULL; /* descriptor for array classes */
1854 /* check if all superclasses are already linked, if not put c at end of
1855 unlinked list and return. Additionally initialize class fields. */
1857 /* check interfaces */
1859 for (i = 0; i < c->interfacescount; i++) {
1860 ic = c->interfaces[i];
1862 list_remove(&unlinkedclasses, c);
1863 list_addlast(&unlinkedclasses, c);
1868 /* check super class */
1870 if (super == NULL) { /* class java.long.Object */
1872 c->classUsed = USED; /* Object class is always used CO-RT*/
1873 c -> impldBy = NULL;
1874 c->instancesize = sizeof(java_objectheader);
1876 vftbllength = supervftbllength = 0;
1878 c->finalizer = NULL;
1881 if (!super->linked) {
1882 list_remove(&unlinkedclasses, c);
1883 list_addlast(&unlinkedclasses, c);
1887 /* handle array classes */
1888 if (c->name->text[0] == '[')
1889 if ((arraydesc = class_link_array(c)) == NULL) {
1890 list_remove(&unlinkedclasses, c);
1891 list_addlast(&unlinkedclasses, c);
1895 if (c->flags & ACC_INTERFACE)
1896 c->index = interfaceindex++;
1898 c->index = super->index + 1;
1900 c->instancesize = super->instancesize;
1902 vftbllength = supervftbllength = super->vftbl->vftbllength;
1904 c->finalizer = super->finalizer;
1909 char logtext[MAXLOGTEXT];
1910 sprintf(logtext, "Linking Class: ");
1911 utf_sprint(logtext + strlen(logtext), c->name );
1915 /* compute vftbl length */
1917 for (i = 0; i < c->methodscount; i++) {
1918 methodinfo *m = &(c->methods[i]);
1920 if (!(m->flags & ACC_STATIC)) { /* is instance method */
1921 classinfo *sc = super;
1924 for (j = 0; j < sc->methodscount; j++) {
1925 if (method_canoverwrite(m, &(sc->methods[j]))) {
1926 m->vftblindex = sc->methods[j].vftblindex;
1927 goto foundvftblindex;
1932 m->vftblindex = (vftbllength++);
1938 count_vftbl_len += sizeof(vftbl) + (sizeof(methodptr) * (vftbllength - 1));
1941 /* compute interfacetable length */
1943 interfacetablelength = 0;
1946 for (i = 0; i < c2->interfacescount; i++) {
1947 s4 h = class_highestinterface (c2->interfaces[i]) + 1;
1948 if (h > interfacetablelength)
1949 interfacetablelength = h;
1954 /* allocate virtual function table */
1956 v = (vftbl*) mem_alloc(sizeof(vftbl) + sizeof(methodptr) *
1957 (vftbllength - 1) + sizeof(methodptr*) *
1958 (interfacetablelength - (interfacetablelength > 0)));
1959 v = (vftbl*) (((methodptr*) v) + (interfacetablelength - 1) *
1960 (interfacetablelength > 1));
1961 c->header.vftbl = c->vftbl = v;
1963 v->vftbllength = vftbllength;
1964 v->interfacetablelength = interfacetablelength;
1965 v->arraydesc = arraydesc;
1967 /* store interface index in vftbl */
1968 if (c->flags & ACC_INTERFACE)
1969 v->baseval = -(c->index);
1971 /* copy virtual function table of super class */
1973 for (i = 0; i < supervftbllength; i++)
1974 v->table[i] = super->vftbl->table[i];
1976 /* add method stubs into virtual function table */
1978 for (i = 0; i < c->methodscount; i++) {
1979 methodinfo *m = &(c->methods[i]);
1980 if (!(m->flags & ACC_STATIC)) {
1981 v->table[m->vftblindex] = m->stubroutine;
1985 /* compute instance size and offset of each field */
1987 for (i = 0; i < c->fieldscount; i++) {
1989 fieldinfo *f = &(c->fields[i]);
1991 if (!(f->flags & ACC_STATIC) ) {
1992 dsize = desc_typesize(f->descriptor);
1993 c->instancesize = ALIGN(c->instancesize, dsize);
1994 f->offset = c->instancesize;
1995 c->instancesize += dsize;
1999 /* initialize interfacetable and interfacevftbllength */
2001 v->interfacevftbllength = MNEW(s4, interfacetablelength);
2004 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
2007 for (i = 0; i < interfacetablelength; i++) {
2008 v->interfacevftbllength[i] = 0;
2009 v->interfacetable[-i] = NULL;
2012 /* add interfaces */
2014 for (c2 = c; c2 != NULL; c2 = c2->super)
2015 for (i = 0; i < c2->interfacescount; i++) {
2016 class_addinterface(c, c2->interfaces[i]);
2019 /* add finalizer method (not for java.lang.Object) */
2021 if (super != NULL) {
2023 static utf *finame = NULL;
2024 static utf *fidesc = NULL;
2027 finame = utf_finalize;
2029 fidesc = utf_fidesc;
2031 fi = class_findmethod(c, finame, fidesc);
2033 if (!(fi->flags & ACC_STATIC)) {
2043 list_remove(&unlinkedclasses, c);
2044 list_addlast(&linkedclasses, c);
2048 /******************* Function: class_freepool **********************************
2050 Frees all resources used by this classes Constant Pool.
2052 *******************************************************************************/
2054 static void class_freecpool (classinfo *c)
2060 for (idx=0; idx < c->cpcount; idx++) {
2061 tag = c->cptags[idx];
2062 info = c->cpinfos[idx];
2066 case CONSTANT_Fieldref:
2067 case CONSTANT_Methodref:
2068 case CONSTANT_InterfaceMethodref:
2069 FREE (info, constant_FMIref);
2071 case CONSTANT_Integer:
2072 FREE (info, constant_integer);
2074 case CONSTANT_Float:
2075 FREE (info, constant_float);
2078 FREE (info, constant_long);
2080 case CONSTANT_Double:
2081 FREE (info, constant_double);
2083 case CONSTANT_NameAndType:
2084 FREE (info, constant_nameandtype);
2090 MFREE (c -> cptags, u1, c -> cpcount);
2091 MFREE (c -> cpinfos, voidptr, c -> cpcount);
2095 /*********************** Function: class_free **********************************
2097 Frees all resources used by the class.
2099 *******************************************************************************/
2101 static void class_free(classinfo *c)
2108 MFREE(c->interfaces, classinfo*, c->interfacescount);
2110 for (i = 0; i < c->fieldscount; i++)
2111 field_free(&(c->fields[i]));
2113 for (i = 0; i < c->methodscount; i++)
2114 method_free(&(c->methods[i]));
2115 MFREE(c->methods, methodinfo, c->methodscount);
2117 if ((v = c->vftbl) != NULL) {
2119 mem_free(v->arraydesc,sizeof(arraydescriptor));
2121 for (i = 0; i < v->interfacetablelength; i++) {
2122 MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
2124 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
2126 i = sizeof(vftbl) + sizeof(methodptr) * (v->vftbllength - 1) +
2127 sizeof(methodptr*) * (v->interfacetablelength -
2128 (v->interfacetablelength > 0));
2129 v = (vftbl*) (((methodptr*) v) - (v->interfacetablelength - 1) *
2130 (v->interfacetablelength > 1));
2134 if (c->innerclasscount)
2135 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
2137 /* if (c->classvftbl)
2138 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
2144 /************************* Function: class_findfield ***************************
2146 Searches a 'classinfo' structure for a field having the given name and
2149 *******************************************************************************/
2151 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
2155 for (i = 0; i < c->fieldscount; i++) {
2156 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
2157 return &(c->fields[i]);
2160 panic("Can not find field given in CONSTANT_Fieldref");
2162 /* keep compiler happy */
2167 /************************* Function: class_findmethod **************************
2169 Searches a 'classinfo' structure for a method having the given name and
2170 type and returns the index in the class info structure.
2171 If type is NULL, it is ignored.
2173 *******************************************************************************/
2175 s4 class_findmethodIndex(classinfo *c, utf *name, utf *desc)
2178 #if defined(JOWENN_DEBUG1) || defined(JOWENN_DEBUG2)
2180 int buffer_len, pos;
2182 #ifdef JOWENN_DEBUG1
2185 utf_strlen(name) + utf_strlen(desc) + utf_strlen(c->name) + 64;
2187 buffer = MNEW(char, buffer_len);
2189 strcpy(buffer, "class_findmethod: method:");
2190 utf_sprint(buffer + strlen(buffer), name);
2191 strcpy(buffer + strlen(buffer), ", desc: ");
2192 utf_sprint(buffer + strlen(buffer), desc);
2193 strcpy(buffer + strlen(buffer), ", classname: ");
2194 utf_sprint(buffer + strlen(buffer), c->name);
2198 MFREE(buffer, char, buffer_len);
2200 for (i = 0; i < c->methodscount; i++) {
2201 #ifdef JOWENN_DEBUG2
2203 utf_strlen(c->methods[i].name) + utf_strlen(c->methods[i].descriptor)+ 64;
2205 buffer = MNEW(char, buffer_len);
2207 strcpy(buffer, "class_findmethod: comparing to method:");
2208 utf_sprint(buffer + strlen(buffer), c->methods[i].name);
2209 strcpy(buffer + strlen(buffer), ", desc: ");
2210 utf_sprint(buffer + strlen(buffer), c->methods[i].descriptor);
2214 MFREE(buffer, char, buffer_len);
2218 if ((c->methods[i].name == name) && ((desc == NULL) ||
2219 (c->methods[i].descriptor == desc))) {
2224 #ifdef JOWENN_DEBUG2
2225 class_showconstantpool(c);
2226 log_text("class_findmethod: returning NULL");
2233 /************************* Function: class_findmethod **************************
2235 Searches a 'classinfo' structure for a method having the given name and
2237 If type is NULL, it is ignored.
2239 *******************************************************************************/
2241 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
2245 #if defined(JOWENN_DEBUG1) || defined(JOWENN_DEBUG2)
2247 int buffer_len, pos;
2249 #ifdef JOWENN_DEBUG1
2252 utf_strlen(name) + utf_strlen(desc) + utf_strlen(c->name) + 64;
2254 buffer = MNEW(char, buffer_len);
2256 strcpy(buffer, "class_findmethod: method:");
2257 utf_sprint(buffer + strlen(buffer), name);
2258 strcpy(buffer + strlen(buffer), ", desc: ");
2259 utf_sprint(buffer + strlen(buffer), desc);
2260 strcpy(buffer + strlen(buffer), ", classname: ");
2261 utf_sprint(buffer + strlen(buffer), c->name);
2265 MFREE(buffer, char, buffer_len);
2267 for (i = 0; i < c->methodscount; i++) {
2268 #ifdef JOWENN_DEBUG2
2270 utf_strlen(c->methods[i].name) + utf_strlen(c->methods[i].descriptor)+ 64;
2272 buffer = MNEW(char, buffer_len);
2274 strcpy(buffer, "class_findmethod: comparing to method:");
2275 utf_sprint(buffer + strlen(buffer), c->methods[i].name);
2276 strcpy(buffer + strlen(buffer), ", desc: ");
2277 utf_sprint(buffer + strlen(buffer), c->methods[i].descriptor);
2281 MFREE(buffer, char, buffer_len);
2284 if ((c->methods[i].name == name) && ((desc == NULL) ||
2285 (c->methods[i].descriptor == desc))) {
2286 return &(c->methods[i]);
2289 #ifdef JOWENN_DEBUG2
2290 class_showconstantpool(c);
2291 log_text("class_findmethod: returning NULL");
2296 s4 idx=class_findmethodIndex(c, name, desc);
2297 /* if (idx==-1) log_text("class_findmethod: method not found");*/
2298 if (idx == -1) return NULL;
2300 return &(c->methods[idx]);
2304 /*********************** Function: class_fetchmethod **************************
2306 like class_findmethod, but aborts with an error if the method is not found
2308 *******************************************************************************/
2310 methodinfo *class_fetchmethod(classinfo *c, utf *name, utf *desc)
2313 mi = class_findmethod(c, name, desc);
2316 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
2317 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
2318 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
2319 panic("Method not found");
2326 /************************* Function: class_findmethod_approx ******************
2328 like class_findmethod but ignores the return value when comparing the
2331 *******************************************************************************/
2333 methodinfo *class_findmethod_approx(classinfo *c, utf *name, utf *desc)
2337 for (i = 0; i < c->methodscount; i++) {
2338 if (c->methods[i].name == name) {
2339 utf *meth_descr = c->methods[i].descriptor;
2343 return &(c->methods[i]);
2345 if (desc->blength <= meth_descr->blength) {
2346 /* current position in utf text */
2347 char *desc_utf_ptr = desc->text;
2348 char *meth_utf_ptr = meth_descr->text;
2349 /* points behind utf strings */
2350 char *desc_end = utf_end(desc);
2351 char *meth_end = utf_end(meth_descr);
2354 /* compare argument types */
2355 while (desc_utf_ptr < desc_end && meth_utf_ptr < meth_end) {
2357 if ((ch = *desc_utf_ptr++) != (*meth_utf_ptr++))
2358 break; /* no match */
2361 return &(c->methods[i]); /* all parameter types equal */
2371 /***************** Function: class_resolvemethod_approx ***********************
2373 Searches a class and every super class for a method (without paying
2374 attention to the return value)
2376 *******************************************************************************/
2378 methodinfo *class_resolvemethod_approx(classinfo *c, utf *name, utf *desc)
2381 /* search for method (ignore returntype) */
2382 methodinfo *m = class_findmethod_approx(c, name, desc);
2385 /* search superclass */
2393 /************************* Function: class_resolvemethod ***********************
2395 Searches a class and every super class for a method.
2397 *******************************************************************************/
2399 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
2402 methodinfo *m = class_findmethod(c, name, desc);
2404 /* search superclass */
2412 /************************* Function: class_issubclass **************************
2414 Checks if sub is a descendant of super.
2416 *******************************************************************************/
2418 bool class_issubclass(classinfo *sub, classinfo *super)
2421 if (!sub) return false;
2422 if (sub == super) return true;
2428 /****************** Initialization function for classes ******************
2430 In Java, every class can have a static initialization function. This
2431 function has to be called BEFORE calling other methods or accessing static
2434 *******************************************************************************/
2436 void class_init(classinfo *c)
2444 if (!makeinitializations)
2449 c->initialized = true;
2452 count_class_inits++;
2456 class_init (c->super);
2457 for (i = 0; i < c->interfacescount; i++)
2458 class_init(c->interfaces[i]); /* real */
2460 m = class_findmethod(c, utf_clinit, utf_fidesc);
2463 char logtext[MAXLOGTEXT];
2464 sprintf(logtext, "Class ");
2465 utf_sprint(logtext + strlen(logtext), c->name);
2466 sprintf(logtext + strlen(logtext), " has no initializer");
2469 /* goto callinitialize;*/
2473 if (!(m->flags & ACC_STATIC))
2474 panic("Class initializer is not static!");
2477 char logtext[MAXLOGTEXT];
2478 sprintf(logtext, "Starting initializer for class: ");
2479 utf_sprint(logtext + strlen(logtext), c->name);
2488 asm_calljavafunction(m, NULL, NULL, NULL, NULL);
2491 assert(blockInts == 0);
2496 printf("#### Initializer of ");
2497 utf_display(c->name);
2498 printf(" has thrown: ");
2499 utf_display(exceptionptr->vftbl->class->name);
2505 char logtext[MAXLOGTEXT];
2506 sprintf(logtext, "Finished initializer for class: ");
2507 utf_sprint(logtext + strlen(logtext), c->name);
2510 if (c->name == utf_systemclass) {
2511 /* class java.lang.System requires explicit initialization */
2514 printf("#### Initializing class System");
2516 /* find initializing method */
2517 m = class_findmethod(c,
2518 utf_initsystemclass,
2522 /* no method found */
2523 /* printf("initializeSystemClass failed"); */
2532 asm_calljavafunction(m, NULL, NULL, NULL, NULL);
2535 assert(blockInts == 0);
2540 printf("#### initializeSystemClass has thrown: ");
2541 utf_display(exceptionptr->vftbl->class->name);
2549 /********* Function: find_class_method_constant *********/
2551 int find_class_method_constant (classinfo *c, utf * c1, utf* m1, utf* d1)
2556 for (i=0; i<c->cpcount; i++) {
2558 e = c -> cpinfos [i];
2561 switch (c -> cptags [i]) {
2562 case CONSTANT_Methodref:
2564 constant_FMIref *fmi = e;
2565 if ( (fmi->class->name == c1)
2566 && (fmi->name == m1)
2567 && (fmi->descriptor == d1)) {
2574 case CONSTANT_InterfaceMethodref:
2576 constant_FMIref *fmi = e;
2577 if ( (fmi->class->name == c1)
2578 && (fmi->name == m1)
2579 && (fmi->descriptor == d1)) {
2593 void class_showconstanti(classinfo *c, int ii)
2599 printf ("#%d: ", (int) i);
2601 switch (c->cptags [i]) {
2602 case CONSTANT_Class:
2603 printf("Classreference -> ");
2604 utf_display(((classinfo*)e)->name);
2607 case CONSTANT_Fieldref:
2608 printf("Fieldref -> "); goto displayFMIi;
2609 case CONSTANT_Methodref:
2610 printf("Methodref -> "); goto displayFMIi;
2611 case CONSTANT_InterfaceMethodref:
2612 printf("InterfaceMethod -> "); goto displayFMIi;
2615 constant_FMIref *fmi = e;
2616 utf_display(fmi->class->name);
2618 utf_display(fmi->name);
2620 utf_display(fmi->descriptor);
2624 case CONSTANT_String:
2625 printf("String -> ");
2628 case CONSTANT_Integer:
2629 printf("Integer -> %d", (int) (((constant_integer*)e)->value));
2631 case CONSTANT_Float:
2632 printf("Float -> %f", ((constant_float*)e)->value);
2634 case CONSTANT_Double:
2635 printf("Double -> %f", ((constant_double*)e)->value);
2639 u8 v = ((constant_long*)e)->value;
2641 printf("Long -> %ld", (long int) v);
2643 printf("Long -> HI: %ld, LO: %ld\n",
2644 (long int) v.high, (long int) v.low);
2648 case CONSTANT_NameAndType:
2650 constant_nameandtype *cnt = e;
2651 printf("NameAndType: ");
2652 utf_display(cnt->name);
2654 utf_display(cnt->descriptor);
2662 panic("Invalid type of ConstantPool-Entry");
2669 void class_showconstantpool (classinfo *c)
2674 printf ("---- dump of constant pool ----\n");
2676 for (i=0; i<c->cpcount; i++) {
2677 printf ("#%d: ", (int) i);
2679 e = c -> cpinfos [i];
2682 switch (c -> cptags [i]) {
2683 case CONSTANT_Class:
2684 printf ("Classreference -> ");
2685 utf_display ( ((classinfo*)e) -> name );
2688 case CONSTANT_Fieldref:
2689 printf ("Fieldref -> "); goto displayFMI;
2690 case CONSTANT_Methodref:
2691 printf ("Methodref -> "); goto displayFMI;
2692 case CONSTANT_InterfaceMethodref:
2693 printf ("InterfaceMethod -> "); goto displayFMI;
2696 constant_FMIref *fmi = e;
2697 utf_display ( fmi->class->name );
2699 utf_display ( fmi->name);
2701 utf_display ( fmi->descriptor );
2705 case CONSTANT_String:
2706 printf ("String -> ");
2709 case CONSTANT_Integer:
2710 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
2712 case CONSTANT_Float:
2713 printf ("Float -> %f", ((constant_float*)e) -> value);
2715 case CONSTANT_Double:
2716 printf ("Double -> %f", ((constant_double*)e) -> value);
2720 u8 v = ((constant_long*)e) -> value;
2722 printf ("Long -> %ld", (long int) v);
2724 printf ("Long -> HI: %ld, LO: %ld\n",
2725 (long int) v.high, (long int) v.low);
2729 case CONSTANT_NameAndType:
2731 constant_nameandtype *cnt = e;
2732 printf ("NameAndType: ");
2733 utf_display (cnt->name);
2735 utf_display (cnt->descriptor);
2739 printf ("Utf8 -> ");
2743 panic ("Invalid type of ConstantPool-Entry");
2753 /********** Function: class_showmethods (debugging only) *************/
2755 void class_showmethods (classinfo *c)
2759 printf ("--------- Fields and Methods ----------------\n");
2760 printf ("Flags: "); printflags (c->flags); printf ("\n");
2762 printf ("This: "); utf_display (c->name); printf ("\n");
2764 printf ("Super: "); utf_display (c->super->name); printf ("\n");
2766 printf ("Index: %d\n", c->index);
2768 printf ("interfaces:\n");
2769 for (i=0; i < c-> interfacescount; i++) {
2771 utf_display (c -> interfaces[i] -> name);
2772 printf (" (%d)\n", c->interfaces[i] -> index);
2775 printf ("fields:\n");
2776 for (i=0; i < c -> fieldscount; i++) {
2777 field_display (&(c -> fields[i]));
2780 printf ("methods:\n");
2781 for (i=0; i < c -> methodscount; i++) {
2782 methodinfo *m = &(c->methods[i]);
2783 if ( !(m->flags & ACC_STATIC))
2784 printf ("vftblindex: %d ", m->vftblindex);
2786 method_display ( m );
2790 printf ("Virtual function table:\n");
2791 for (i=0; i<c->vftbl->vftbllength; i++) {
2792 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]) );
2799 /******************************************************************************/
2800 /******************* General functions for the class loader *******************/
2801 /******************************************************************************/
2803 /********************* Function: loader_load ***********************************
2805 Loads and links the class desired class and each class and interface
2807 Returns: a pointer to this class
2809 *******************************************************************************/
2811 static int loader_load_running = 0;
2813 classinfo *loader_load(utf *topname)
2819 classinfo *notlinkable;
2821 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
2822 pthread_mutex_lock(&compiler_mutex);
2825 /* avoid recursive calls */
2826 if (loader_load_running)
2827 return class_new(topname);
2829 loader_load_running++;
2834 starttime = getcputime();
2836 top = class_new(topname);
2839 while ((c = list_first(&unloadedclasses))) {
2840 if (!class_load(c)) {
2842 dolog("Failed to load class");
2843 list_remove(&unloadedclasses, c);
2850 dolog("Linking...");
2852 /* XXX added a hack to break infinite linking loops. A better
2853 * linking algorithm would be nice. -Edwin */
2855 while ((c = list_first(&unlinkedclasses))) {
2860 else if (notlinkable == c) {
2861 /* We tried to link this class for the second time and
2862 * no other classes were linked in between, so we are
2866 dolog("Cannot resolve linking dependencies");
2869 throw_linkageerror_message(c->name);
2877 dolog("Linking done.");
2880 loader_compute_subclasses();
2883 if (getloadingtime) {
2884 stoptime = getcputime();
2885 loadingtime += (stoptime - starttime);
2889 loader_load_running--;
2891 /* check if a former loader_load call tried to load/link the class and
2892 failed. This is needed because the class didn't appear in the
2893 undloadclasses or unlinkedclasses list during this class. */
2896 if (linkverbose) dolog("Failed to load class (former call)");
2897 throw_noclassdeffounderror_message(top->name);
2900 } else if (!top->linked) {
2902 dolog("Failed to link class (former call)");
2903 throw_linkageerror_message(top->name);
2910 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
2911 pthread_mutex_unlock(&compiler_mutex);
2914 /* XXX DEBUG */ if (linkverbose && !top) dolog("returning NULL from loader_load");
2919 /****************** Function: loader_load_sysclass ****************************
2921 Loads and links the class desired class and each class and interface
2924 The pointer to the classinfo is stored in *top if top != NULL.
2925 The pointer is also returned.
2927 If the class could not be loaded the function aborts with an error.
2929 *******************************************************************************/
2931 classinfo *loader_load_sysclass(classinfo **top,utf *topname)
2935 if ((cls = loader_load(topname)) == NULL) {
2936 log_plain("Could not important system class: ");
2937 log_plain_utf(topname);
2939 panic("Could not load important system class");
2942 if (top) *top = cls;
2947 /**************** function: create_primitive_classes ***************************
2949 create classes representing primitive types
2951 ********************************************************************************/
2954 void create_primitive_classes()
2958 for (i=0;i<PRIMITIVETYPE_COUNT;i++) {
2959 /* create primitive class */
2960 classinfo *c = class_new ( utf_new_char(primitivetype_table[i].name) );
2961 c -> classUsed = NOTUSED; /* not used initially CO-RT */
2962 c -> impldBy = NULL;
2964 /* prevent loader from loading primitive class */
2965 list_remove (&unloadedclasses, c);
2967 /* add to unlinked classes */
2968 list_addlast (&unlinkedclasses, c);
2969 /*JOWENN primitive types don't have objects as super class c -> super = class_java_lang_Object; */
2972 primitivetype_table[i].class_primitive = c;
2974 /* create class for wrapping the primitive type */
2975 primitivetype_table[i].class_wrap =
2976 class_new( utf_new_char(primitivetype_table[i].wrapname) );
2977 primitivetype_table[i].class_wrap -> classUsed = NOTUSED; /* not used initially CO-RT */
2978 primitivetype_table[i].class_wrap -> impldBy = NULL;
2980 /* create the primitive array class */
2981 if (primitivetype_table[i].arrayname) {
2982 c = class_new( utf_new_char(primitivetype_table[i].arrayname) );
2983 primitivetype_table[i].arrayclass = c;
2985 if (!c->linked) class_link(c);
2986 primitivetype_table[i].arrayvftbl = c->vftbl;
2991 /**************** function: class_primitive_from_sig ***************************
2993 return the primitive class indicated by the given signature character
2995 If the descriptor does not indicate a valid primitive type the
2996 return value is NULL.
2998 ********************************************************************************/
3000 classinfo *class_primitive_from_sig(char sig)
3003 case 'I': return primitivetype_table[PRIMITIVETYPE_INT].class_primitive;
3004 case 'J': return primitivetype_table[PRIMITIVETYPE_LONG].class_primitive;
3005 case 'F': return primitivetype_table[PRIMITIVETYPE_FLOAT].class_primitive;
3006 case 'D': return primitivetype_table[PRIMITIVETYPE_DOUBLE].class_primitive;
3007 case 'B': return primitivetype_table[PRIMITIVETYPE_BYTE].class_primitive;
3008 case 'C': return primitivetype_table[PRIMITIVETYPE_CHAR].class_primitive;
3009 case 'S': return primitivetype_table[PRIMITIVETYPE_SHORT].class_primitive;
3010 case 'Z': return primitivetype_table[PRIMITIVETYPE_BOOLEAN].class_primitive;
3011 case 'V': return primitivetype_table[PRIMITIVETYPE_VOID].class_primitive;
3016 /****************** function: class_from_descriptor ****************************
3018 return the class indicated by the given descriptor
3020 utf_ptr....first character of descriptor
3021 end_ptr....first character after the end of the string
3022 next.......if non-NULL, *next is set to the first character after
3023 the descriptor. (Undefined if an error occurs.)
3025 mode.......a combination (binary or) of the following flags:
3027 (Flags marked with * are the default settings.)
3029 What to do if a reference type descriptor is parsed successfully:
3031 CLASSLOAD_SKIP...skip it and return something != NULL
3032 * CLASSLOAD_NEW....get classinfo * via class_new
3033 CLASSLOAD_LOAD...get classinfo * via loader_load
3035 How to handle primitive types:
3037 * CLASSLOAD_PRIMITIVE.......return primitive class (eg. "int")
3038 CLASSLOAD_NULLPRIMITIVE...return NULL for primitive types
3040 How to handle "V" descriptors:
3042 * CLASSLOAD_VOID.....handle it like other primitive types
3043 CLASSLOAD_NOVOID...treat it as an error
3045 How to deal with extra characters after the end of the
3048 * CLASSLOAD_NOCHECKEND...ignore (useful for parameter lists)
3049 CLASSLOAD_CHECKEND.....treat them as an error
3051 How to deal with errors:
3053 * CLASSLOAD_PANIC....abort execution with an error message
3054 CLASSLOAD_NOPANIC..return NULL on error
3056 ********************************************************************************/
3058 classinfo *class_from_descriptor(char *utf_ptr, char *end_ptr,
3059 char **next, int mode)
3061 char *start = utf_ptr;
3065 SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr,end_ptr,error);
3067 if (mode & CLASSLOAD_CHECKEND)
3068 error |= (utf_ptr != end_ptr);
3071 if (next) *next = utf_ptr;
3075 if (mode & CLASSLOAD_NOVOID)
3086 return (mode & CLASSLOAD_NULLPRIMITIVE)
3088 : class_primitive_from_sig(*start);
3095 if (mode & CLASSLOAD_SKIP) return class_java_lang_Object;
3096 name = utf_new(start,utf_ptr-start);
3097 return (mode & CLASSLOAD_LOAD)
3098 ? loader_load(name) : class_new(name); /* XXX */
3102 /* An error occurred */
3103 if (mode & CLASSLOAD_NOPANIC)
3106 log_plain("Invalid descriptor at beginning of '");
3107 log_plain_utf(utf_new(start, end_ptr-start));
3111 panic("Invalid descriptor");
3113 /* keep compiler happy */
3118 /******************* function: type_from_descriptor ****************************
3120 return the basic type indicated by the given descriptor
3122 This function parses a descriptor and returns its basic type as
3123 TYPE_INT, TYPE_LONG, TYPE_FLOAT, TYPE_DOUBLE, TYPE_ADDRESS or TYPE_VOID.
3125 cls...if non-NULL the referenced variable is set to the classinfo *
3126 returned by class_from_descriptor.
3128 For documentation of the arguments utf_ptr, end_ptr, next and mode
3129 see class_from_descriptor. The only difference is that
3130 type_from_descriptor always uses CLASSLOAD_PANIC.
3132 ********************************************************************************/
3134 int type_from_descriptor(classinfo **cls, char *utf_ptr, char *end_ptr,
3135 char **next, int mode)
3138 if (!cls) cls = &mycls;
3139 *cls = class_from_descriptor(utf_ptr, end_ptr, next, mode & (~CLASSLOAD_NOPANIC));
3156 return TYPE_ADDRESS;
3160 /*************** function: create_pseudo_classes *******************************
3162 create pseudo classes used by the typechecker
3164 ********************************************************************************/
3166 static void create_pseudo_classes()
3168 /* pseudo class for Arraystubs (extends java.lang.Object) */
3170 pseudo_class_Arraystub = class_new(utf_new_char("$ARRAYSTUB$"));
3171 list_remove(&unloadedclasses, pseudo_class_Arraystub);
3173 pseudo_class_Arraystub->super = class_java_lang_Object;
3174 pseudo_class_Arraystub->interfacescount = 2;
3175 pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
3176 pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
3177 pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
3179 list_addlast(&unlinkedclasses, pseudo_class_Arraystub);
3180 class_link(pseudo_class_Arraystub);
3182 pseudo_class_Arraystub_vftbl = pseudo_class_Arraystub->vftbl;
3184 /* pseudo class representing the null type */
3186 pseudo_class_Null = class_new(utf_new_char("$NULL$"));
3187 list_remove(&unloadedclasses, pseudo_class_Null);
3189 pseudo_class_Null->super = class_java_lang_Object;
3191 list_addlast(&unlinkedclasses, pseudo_class_Null);
3192 class_link(pseudo_class_Null);
3194 /* pseudo class representing new uninitialized objects */
3196 pseudo_class_New = class_new( utf_new_char("$NEW$") );
3197 list_remove(&unloadedclasses,pseudo_class_New);
3199 pseudo_class_New->super = class_java_lang_Object;
3201 list_addlast(&unlinkedclasses,pseudo_class_New);
3202 class_link(pseudo_class_New);
3206 /********************** Function: loader_init **********************************
3208 Initializes all lists and loads all classes required for the system or the
3211 *******************************************************************************/
3213 void loader_init(u1 * stackbottom)
3217 log_text("Entering loader_init");
3219 list_init (&unloadedclasses, OFFSET(classinfo, listnode) );
3220 list_init (&unlinkedclasses, OFFSET(classinfo, listnode) );
3221 list_init (&linkedclasses, OFFSET(classinfo, listnode) );
3223 /* create utf-symbols for pointer comparison of frequently used strings */
3224 utf_innerclasses = utf_new_char("InnerClasses");
3225 utf_constantvalue = utf_new_char("ConstantValue");
3226 utf_code = utf_new_char("Code");
3227 utf_finalize = utf_new_char("finalize");
3228 utf_fidesc = utf_new_char("()V");
3229 utf_clinit = utf_new_char("<clinit>");
3230 utf_initsystemclass = utf_new_char("initializeSystemClass");
3231 utf_systemclass = utf_new_char("java/lang/System");
3232 utf_vmclassloader = utf_new_char("java/lang/VMClassLoader");
3233 utf_initialize = utf_new_char("initialize");
3234 utf_initializedesc = utf_new_char("(I)V");
3236 utf_vmclass = utf_new_char("java/lang/VMClass");
3238 /* create some important classes */
3239 /* These classes have to be created now because the classinfo
3240 * pointers are used in the loading code.
3242 class_java_lang_Object = class_new(utf_new_char("java/lang/Object"));
3243 class_java_lang_String = class_new(utf_new_char("java/lang/String"));
3244 class_java_lang_Cloneable = class_new(utf_new_char("java/lang/Cloneable"));
3245 class_java_io_Serializable = class_new(utf_new_char("java/io/Serializable"));
3247 log_text("loader_init: java/lang/Object");
3248 /* load the classes which were created above */
3249 loader_load_sysclass(NULL, class_java_lang_Object->name);
3251 loader_inited = 1; /*JOWENN*/
3253 loader_load_sysclass(&class_java_lang_Throwable,
3254 utf_new_char("java/lang/Throwable"));
3256 log_text("loader_init: loader_load: java/lang/ClassCastException");
3257 loader_load_sysclass(&class_java_lang_ClassCastException,
3258 utf_new_char ("java/lang/ClassCastException"));
3259 loader_load_sysclass(&class_java_lang_NullPointerException,
3260 utf_new_char ("java/lang/NullPointerException"));
3261 loader_load_sysclass(&class_java_lang_ArrayIndexOutOfBoundsException,
3262 utf_new_char ("java/lang/ArrayIndexOutOfBoundsException"));
3263 loader_load_sysclass(&class_java_lang_NegativeArraySizeException,
3264 utf_new_char ("java/lang/NegativeArraySizeException"));
3265 loader_load_sysclass(&class_java_lang_OutOfMemoryError,
3266 utf_new_char ("java/lang/OutOfMemoryError"));
3267 loader_load_sysclass(&class_java_lang_ArrayStoreException,
3268 utf_new_char ("java/lang/ArrayStoreException"));
3269 loader_load_sysclass(&class_java_lang_ArithmeticException,
3270 utf_new_char ("java/lang/ArithmeticException"));
3271 loader_load_sysclass(&class_java_lang_ThreadDeath,
3272 utf_new_char ("java/lang/ThreadDeath"));
3274 /* create classes representing primitive types */
3275 create_primitive_classes();
3277 /* create classes used by the typechecker */
3278 create_pseudo_classes();
3280 /* correct vftbl-entries (retarded loading of class java/lang/String) */
3281 stringtable_update();
3288 log_text("loader_init: creating global proto_java_lang_ClassCastException");
3289 proto_java_lang_ClassCastException =
3290 builtin_new(class_java_lang_ClassCastException);
3291 /* heap_addreference((void**) &proto_java_lang_ClassCastException); */
3293 log_text("loader_init: proto_java_lang_ClassCastException has been initialized");
3295 proto_java_lang_NullPointerException =
3296 builtin_new(class_java_lang_NullPointerException);
3297 /* heap_addreference((void**) &proto_java_lang_NullPointerException); */
3298 log_text("loader_init: proto_java_lang_NullPointerException has been initialized");
3300 proto_java_lang_ArrayIndexOutOfBoundsException =
3301 builtin_new(class_java_lang_ArrayIndexOutOfBoundsException);
3302 /* heap_addreference((void**) &proto_java_lang_ArrayIndexOutOfBoundsException); */
3304 proto_java_lang_NegativeArraySizeException =
3305 builtin_new(class_java_lang_NegativeArraySizeException);
3306 /* heap_addreference((void**) &proto_java_lang_NegativeArraySizeException); */
3308 proto_java_lang_OutOfMemoryError =
3309 builtin_new(class_java_lang_OutOfMemoryError);
3310 /* heap_addreference((void**) &proto_java_lang_OutOfMemoryError); */
3312 proto_java_lang_ArithmeticException =
3313 builtin_new(class_java_lang_ArithmeticException);
3314 /* heap_addreference((void**) &proto_java_lang_ArithmeticException); */
3316 proto_java_lang_ArrayStoreException =
3317 builtin_new(class_java_lang_ArrayStoreException);
3318 /* heap_addreference((void**) &proto_java_lang_ArrayStoreException); */
3320 proto_java_lang_ThreadDeath = /* schani */
3321 builtin_new(class_java_lang_ThreadDeath);
3322 /* heap_addreference((void**) &proto_java_lang_ThreadDeath); */
3328 /********************* Function: loader_initclasses ****************************
3330 Initializes all loaded but uninitialized classes
3332 *******************************************************************************/
3334 void loader_initclasses ()
3338 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3339 pthread_mutex_lock(&compiler_mutex);
3342 intsDisable(); /* schani */
3344 if (makeinitializations) {
3345 c = list_first (&linkedclasses);
3348 c = list_next (&linkedclasses, c);
3352 intsRestore(); /* schani */
3354 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3355 pthread_mutex_unlock(&compiler_mutex);
3359 static s4 classvalue;
3361 static void loader_compute_class_values(classinfo *c)
3365 c->vftbl->baseval = ++classvalue;
3368 while (subs != NULL) {
3369 loader_compute_class_values(subs);
3370 subs = subs->nextsub;
3372 c->vftbl->diffval = classvalue - c->vftbl->baseval;
3377 for (i = 0; i < c->index; i++)
3379 printf("%3d %3d ", (int) c->vftbl->baseval, c->vftbl->diffval);
3380 utf_display(c->name);
3387 void loader_compute_subclasses()
3391 intsDisable(); /* schani */
3393 c = list_first(&linkedclasses);
3395 if (!(c->flags & ACC_INTERFACE)) {
3399 c = list_next (&linkedclasses, c);
3402 c = list_first (&linkedclasses);
3404 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
3405 c->nextsub = c->super->sub;
3408 c = list_next (&linkedclasses, c);
3412 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3415 loader_compute_class_values(class_java_lang_Object);
3416 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3420 intsRestore(); /* schani */
3424 /******************** function classloader_buffer ******************************
3426 sets buffer for reading classdata
3428 *******************************************************************************/
3430 void classload_buffer(u1 *buf, int len)
3433 classbuffer_size = len;
3434 classbuf_pos = buf - 1;
3438 /******************** Function: loader_close ***********************************
3442 *******************************************************************************/
3448 while ((c = list_first(&unloadedclasses))) {
3449 list_remove(&unloadedclasses, c);
3452 while ((c = list_first(&unlinkedclasses))) {
3453 list_remove(&unlinkedclasses, c);
3456 while ((c = list_first(&linkedclasses))) {
3457 list_remove(&linkedclasses, c);
3464 * These are local overrides for various environment variables in Emacs.
3465 * Please do not remove this and leave it at the end of the file, where
3466 * Emacs will automagically detect them.
3467 * ---------------------------------------------------------------------
3470 * indent-tabs-mode: t