Added check for field/method uniqueness
[cacao.git] / loader.c
1 /* loader.c - class loader functions
2
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
7
8    This file is part of CACAO.
9
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.
14
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.
19
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
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Reinhard Grafl
28    Changes: Andreas Krall
29             Roman Obermaiser
30             Mark Probst
31                         Edwin Steiner
32
33    $Id: loader.c 880 2004-01-13 17:17:12Z edwin $
34
35 */
36
37
38 #include <stdlib.h>
39 #include <string.h>
40 #include <assert.h>
41 #include <sys/stat.h>
42 #include "global.h"
43 #include "loader.h"
44 #include "main.h"
45 #include "native.h"
46 #include "tables.h"
47 #include "builtin.h"
48 #include "jit.h"
49 #include "asmpart.h"
50 #include "toolbox/memory.h"
51 #include "toolbox/loging.h"
52 #include "threads/thread.h"
53 #include "threads/locks.h"
54 #include <sys/stat.h>
55
56 #ifdef USE_ZLIB
57 #include "unzip.h"
58 #endif
59
60 #undef JOWENN_DEBUG
61 #undef JOWENN_DEBUG1
62 #undef JOWENN_DEBUG2
63
64 /* global variables ***********************************************************/
65
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;
74
75 static s4 interfaceindex;       /* sequential numbering of interfaces         */
76 static s4 classvalue;
77
78 list unloadedclasses;       /* list of all referenced but not loaded classes  */
79 list unlinkedclasses;       /* list of all loaded but not linked classes      */
80 list linkedclasses;         /* list of all completely linked classes          */
81
82
83 /* utf-symbols for pointer comparison of frequently used strings */
84
85 static utf *utf_innerclasses;           /* InnerClasses            */
86 static utf *utf_constantvalue;          /* ConstantValue           */
87 static utf *utf_code;                       /* Code                    */
88 static utf *utf_finalize;                   /* finalize                */
89 static utf *utf_fidesc;                     /* ()V changed             */
90 static utf *utf_init;                   /* <init>                  */
91 static utf *utf_clinit;                     /* <clinit>                */
92 static utf *utf_initsystemclass;        /* initializeSystemClass   */
93 static utf *utf_systemclass;            /* java/lang/System        */
94 static utf *utf_vmclassloader;      /* java/lang/VMClassLoader */
95 static utf *utf_vmclass;            /* java/lang/VMClassLoader */
96 static utf *utf_initialize;
97 static utf *utf_initializedesc;
98 static utf *utf_java_lang_Object;   /* java/lang/Object        */
99
100
101
102
103 utf* clinit_desc(){
104         return utf_fidesc;
105 }
106 utf* clinit_name(){
107         return utf_clinit;
108 }
109
110
111 /* important system classes ***************************************************/
112
113 classinfo *class_java_lang_Object;
114 classinfo *class_java_lang_String;
115
116 classinfo *class_java_lang_Throwable;
117 classinfo *class_java_lang_Cloneable;
118 classinfo *class_java_io_Serializable;
119
120 /* Pseudo classes for the typechecker */
121 classinfo *pseudo_class_Arraystub = NULL;
122 classinfo *pseudo_class_Null = NULL;
123 classinfo *pseudo_class_New = NULL;
124 vftbl *pseudo_class_Arraystub_vftbl = NULL;
125
126 /* stefan */
127 /* These are made static so they cannot be used for throwing in native */
128 /* functions.                                                          */
129 static classinfo *class_java_lang_ClassCastException;
130 static classinfo *class_java_lang_NullPointerException;
131 static classinfo *class_java_lang_ArrayIndexOutOfBoundsException;
132 static classinfo *class_java_lang_NegativeArraySizeException;
133 static classinfo *class_java_lang_OutOfMemoryError;
134 static classinfo *class_java_lang_ArithmeticException;
135 static classinfo *class_java_lang_ArrayStoreException;
136 static classinfo *class_java_lang_ThreadDeath;
137
138 utf *array_packagename = NULL;
139
140 static int loader_inited = 0;
141
142
143 /********************************************************************
144    list of classpath entries (either filesystem directories or 
145    ZIP/JAR archives
146 ********************************************************************/
147 static classpath_info *classpath_entries=0;
148
149
150 /******************************************************************************
151
152    structure for primitive classes: contains the class for wrapping the 
153    primitive type, the primitive class, the name of the class for wrapping, 
154    the one character type signature and the name of the primitive class
155  
156  ******************************************************************************/
157
158 /* CAUTION: Don't change the order of the types. This table is indexed
159  * by the ARRAYTYPE_ constants (expcept ARRAYTYPE_OBJECT).
160  */
161 primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = { 
162         { NULL, NULL, "java/lang/Integer",   'I', "int"     , "[I", NULL, NULL },
163         { NULL, NULL, "java/lang/Long",      'J', "long"    , "[J", NULL, NULL },
164         { NULL, NULL, "java/lang/Float",     'F', "float"   , "[F", NULL, NULL },
165         { NULL, NULL, "java/lang/Double",    'D', "double"  , "[D", NULL, NULL },
166         { NULL, NULL, "java/lang/Byte",      'B', "byte"    , "[B", NULL, NULL },
167         { NULL, NULL, "java/lang/Character", 'C', "char"    , "[C", NULL, NULL },
168         { NULL, NULL, "java/lang/Short",     'S', "short"   , "[S", NULL, NULL },
169         { NULL, NULL, "java/lang/Boolean",   'Z', "boolean" , "[Z", NULL, NULL },
170         { NULL, NULL, "java/lang/Void",      'V', "void"    , NULL, NULL, NULL }
171 };
172
173
174 /* instances of important system classes **************************************/
175
176 java_objectheader *proto_java_lang_ClassCastException;
177 java_objectheader *proto_java_lang_NullPointerException;
178 java_objectheader *proto_java_lang_ArrayIndexOutOfBoundsException;
179 java_objectheader *proto_java_lang_NegativeArraySizeException;
180 java_objectheader *proto_java_lang_OutOfMemoryError;
181 java_objectheader *proto_java_lang_ArithmeticException;
182 java_objectheader *proto_java_lang_ArrayStoreException;
183 java_objectheader *proto_java_lang_ThreadDeath;
184
185 /************* functions for reading classdata *********************************
186
187     getting classdata in blocks of variable size
188     (8,16,32,64-bit integer or float)
189
190 *******************************************************************************/
191
192 static char *classpath    = "";     /* searchpath for classfiles              */
193 static u1 *classbuffer    = NULL;   /* pointer to buffer with classfile-data  */
194 static u1 *classbuf_pos;            /* current position in classfile buffer   */
195 static int classbuffer_size;        /* size of classfile-data                 */
196
197 /* assert that at least <len> bytes are left to read */
198 /* <len> is limited to the range of non-negative s4 values */
199 #define ASSERT_LEFT(len)                                                                                                \
200         do {if ( ((s4)(len)) < 0                                                                                        \
201                          || ((classbuffer + classbuffer_size) - classbuf_pos - 1) < (len)) \
202                         panic("Unexpected end of classfile"); } while(0)
203
204 /* transfer block of classfile data into a buffer */
205
206 #define suck_nbytes(buffer,len)                                         \
207         do {ASSERT_LEFT(len);                                                   \
208                 memcpy(buffer,classbuf_pos+1,len);                      \
209                 classbuf_pos+=len;} while (0)
210
211 /* skip block of classfile data */
212
213 #define skip_nbytes(len)                                                \
214         do {ASSERT_LEFT(len);                                           \
215                 classbuf_pos+=len;} while(0)
216
217 inline u1 suck_u1()
218 {
219         ASSERT_LEFT(1);
220         return *++classbuf_pos;
221 }
222 inline u2 suck_u2()
223 {
224         u1 a=suck_u1(), b=suck_u1();
225         return ((u2)a<<8)+(u2)b;
226 }
227 inline u4 suck_u4()
228 {
229         u1 a=suck_u1(), b=suck_u1(), c=suck_u1(), d=suck_u1();
230         return ((u4)a<<24)+((u4)b<<16)+((u4)c<<8)+(u4)d;
231 }
232 #define suck_s8() (s8) suck_u8()
233 #define suck_s2() (s2) suck_u2()
234 #define suck_s4() (s4) suck_u4()
235 #define suck_s1() (s1) suck_u1()
236
237
238 /* get u8 from classfile data */
239 static u8 suck_u8()
240 {
241 #if U8_AVAILABLE
242         u8 lo, hi;
243         hi = suck_u4();
244         lo = suck_u4();
245         return (hi << 32) + lo;
246 #else
247         u8 v;
248         v.high = suck_u4();
249         v.low = suck_u4();
250         return v;
251 #endif
252 }
253
254
255 /* get float from classfile data */
256 static float suck_float()
257 {
258         float f;
259
260 #if !WORDS_BIGENDIAN 
261                 u1 buffer[4];
262                 u2 i;
263                 for (i = 0; i < 4; i++) buffer[3 - i] = suck_u1();
264                 memcpy((u1*) (&f), buffer, 4);
265 #else 
266                 suck_nbytes((u1*) (&f), 4);
267 #endif
268
269         PANICIF (sizeof(float) != 4, "Incompatible float-format");
270         
271         return f;
272 }
273
274
275 /* get double from classfile data */
276 static double suck_double()
277 {
278         double d;
279
280 #if !WORDS_BIGENDIAN 
281                 u1 buffer[8];
282                 u2 i;   
283                 for (i = 0; i < 8; i++) buffer[7 - i] = suck_u1 ();
284                 memcpy((u1*) (&d), buffer, 8);
285 #else 
286                 suck_nbytes((u1*) (&d), 8);
287 #endif
288
289         PANICIF (sizeof(double) != 8, "Incompatible double-format" );
290         
291         return d;
292 }
293
294
295 /************************** function suck_init *********************************
296
297         called once at startup, sets the searchpath for the classfiles
298
299 *******************************************************************************/
300
301 void suck_init(char *cpath)
302 {
303         char *filename=0;
304         char *start;
305         char *end;
306         int isZip;
307         int filenamelen;
308         union classpath_info *tmp;
309         union classpath_info *insertAfter=0;
310         if (!cpath) return;
311         classpath   = cpath;
312         classbuffer = NULL;
313         
314         if (classpath_entries) panic("suck_init should be called only once");
315         for(start=classpath;(*start)!='\0';) {
316                 for (end=start; ((*end)!='\0') && ((*end)!=':') ; end++);
317                 if (start!=end) {
318                         isZip=0;
319                         filenamelen=(end-start);
320                         if  (filenamelen>3) {
321                                 if ( 
322                                         (
323                                                 (
324                                                         ((*(end-1))=='p') ||
325                                                         ((*(end-1))=='P')
326                                                 ) &&
327                                                 (
328                                                         ((*(end-2))=='i') ||
329                                                         ((*(end-2))=='I')
330                                                 ) &&
331                                                 (
332                                                         ((*(end-3))=='z') ||
333                                                         ((*(end-3))=='Z')
334                                                 )
335                                         ) ||
336                                         (
337                                                 (
338                                                         ((*(end-1))=='r') ||
339                                                         ((*(end-1))=='R')
340                                                 ) &&
341                                                 (
342                                                         ((*(end-2))=='a') ||
343                                                         ((*(end-2))=='A')
344                                                 ) &&
345                                                 (
346                                                         ((*(end-3))=='j') ||
347                                                         ((*(end-3))=='J')
348                                                 )
349                                         )
350                                 ) isZip=1;
351 #if 0
352                                 if ( 
353                                         (  (  (*(end - 1)) == 'p') || ( (*(end - 1))  == 'P')) &&
354                                      (((*(end - 2)) == 'i') || ( (*(end - 2)) == 'I'))) &&
355                                          (( (*(end - 3)) == 'z') || ((*(end - 3)) == 'Z'))) 
356                                 ) {
357                                         isZip=1;
358                                 } else  if ( (( (*(end - 1)) == 'r') || ( (*(end - 1))  == 'R')) &&
359                                      ((*(end - 2)) == 'a') || ( (*(end - 2)) == 'A')) &&
360                                          (( (*(end - 3)) == 'j') || ((*(end - 3)) == 'J')) ) {
361                                         isZip=1;
362                                 }
363 #endif
364                         }
365                         if (filenamelen>=(CLASSPATH_MAXFILENAME-1)) panic("path length >= MAXFILENAME in suck_init"); 
366                         if (!filename)
367                                 filename=(char*)malloc(CLASSPATH_MAXFILENAME);
368                         strncpy(filename,start,filenamelen);
369                         filename[filenamelen+1]='\0';
370                         tmp=0;
371
372                         if (isZip) {
373 #ifdef USE_ZLIB
374                                 unzFile uf=unzOpen(filename);
375                                 if (uf) {
376                                         tmp=(union classpath_info*)malloc(sizeof(classpath_info));
377                                         tmp->archive.type=CLASSPATH_ARCHIVE;
378                                         tmp->archive.uf=uf;
379                                         tmp->archive.next=0;
380                                         filename=0;
381                                 }
382 #else
383                                 panic("Zip/JAR not supported");
384 #endif
385                                 
386                         } else {
387                                 tmp=(union classpath_info*)malloc(sizeof(classpath_info));
388                                 tmp->filepath.type=CLASSPATH_PATH;
389                                 tmp->filepath.next=0;
390                                 if (filename[filenamelen-1]!='/') {/*PERHAPS THIS SHOULD BE READ FROM A GLOBAL CONFIGURATION */
391                                         filename[filenamelen]='/';
392                                         filename[filenamelen+1]='\0';
393                                         filenamelen++;
394                                 }
395                         
396                                 tmp->filepath.filename=filename;
397                                 tmp->filepath.pathlen=filenamelen;                              
398                                 filename=0;
399                         }
400
401                 if (tmp) {
402                         if (insertAfter) {
403                                 insertAfter->filepath.next=tmp;
404                         } else {
405                                 classpath_entries=tmp;  
406                         }
407                         insertAfter=tmp;
408                 }
409         }
410                 if ((*end)==':') start=end+1; else start=end;
411         
412         
413         if (filename!=0) free(filename);
414 }
415
416 }
417
418 /************************** function suck_start ********************************
419
420         returns true if classbuffer is already loaded or a file for the
421         specified class has succussfully been read in. All directories of
422         the searchpath are used to find the classfile (<classname>.class).
423         Returns false if no classfile is found and writes an error message. 
424         
425 *******************************************************************************/
426
427 bool suck_start(utf *classname)
428 {
429         classpath_info *currPos;
430         char *utf_ptr;
431         char c;
432         char filename[CLASSPATH_MAXFILENAME+10];  /* room for '.class'                      */  
433         int  filenamelen=0;
434         FILE *classfile;
435         int  err;
436         struct stat buffer;
437
438         if (classbuffer) return true; /* classbuffer is already valid */
439
440         utf_ptr = classname->text;
441         while (utf_ptr < utf_end(classname)) {
442                 PANICIF (filenamelen >= CLASSPATH_MAXFILENAME, "Filename too long");
443                 c = *utf_ptr++;
444                 if ((c <= ' ' || c > 'z') && (c != '/'))     /* invalid character */
445                         c = '?';
446                 filename[filenamelen++] = c;
447         }
448         strcpy(filename + filenamelen, ".class");
449         filenamelen+=6;
450         for (currPos=classpath_entries;currPos!=0;currPos=currPos->filepath.next) {
451 #ifdef USE_ZLIB
452                 if (currPos->filepath.type==CLASSPATH_ARCHIVE) {
453                         if (cacao_locate(currPos->archive.uf,classname) == UNZ_OK) {
454                                 unz_file_info file_info;
455                                 /*log_text("Class found in zip file");*/
456                                 if (unzGetCurrentFileInfo(currPos->archive.uf, &file_info, filename,
457                                                 sizeof(filename), NULL, 0, NULL, 0) == UNZ_OK) {
458                                         if (unzOpenCurrentFile(currPos->archive.uf) == UNZ_OK) {
459                                                 classbuffer_size = file_info.uncompressed_size;                         
460                                                 classbuffer      = MNEW(u1, classbuffer_size);
461                                                 classbuf_pos     = classbuffer - 1;
462                                                 /*printf("classfile size: %d\n",file_info.uncompressed_size);*/
463                                                 if (unzReadCurrentFile(currPos->archive.uf, classbuffer, classbuffer_size) == classbuffer_size) {
464                                                         unzCloseCurrentFile(currPos->archive.uf);
465                                                         return true;
466                                                 } else {
467                                                         MFREE(classbuffer, u1, classbuffer_size);
468                                                         log_text("Error while unzipping");
469                                                 }
470                                         } else log_text("Error while opening file in archive");
471                                 } else log_text("Error while retrieving fileinfo");
472                         }
473                         unzCloseCurrentFile(currPos->archive.uf);
474
475                 } else {
476 #endif
477                         if ((currPos->filepath.pathlen+filenamelen)>=CLASSPATH_MAXFILENAME) continue;
478                         strcpy(currPos->filepath.filename+currPos->filepath.pathlen,filename);
479                         classfile = fopen(currPos->filepath.filename, "r");
480                         if (classfile) {                                       /* file exists */
481
482                                 /* determine size of classfile */
483
484                                 /* dolog("File: %s",filename); */
485
486                                 err = stat(currPos->filepath.filename, &buffer);
487
488                                 if (!err) {                                /* read classfile data */                            
489                                         classbuffer_size = buffer.st_size;                              
490                                         classbuffer      = MNEW(u1, classbuffer_size);
491                                         classbuf_pos     = classbuffer - 1;
492                                         fread(classbuffer, 1, classbuffer_size, classfile);
493                                         fclose(classfile);
494                                         return true;
495                                 }
496                         }
497 #ifdef USE_ZLIB
498                 }
499 #endif
500         }
501
502         if (verbose) {
503                 dolog("Warning: Can not open class file '%s'", filename);
504         }
505
506         return false;
507
508 }
509
510 /************************** function suck_stop *********************************
511
512         frees memory for buffer with classfile data.
513         Caution: this function may only be called if buffer has been allocated
514                  by suck_start with reading a file
515         
516 *******************************************************************************/
517
518 void suck_stop()
519 {
520         /* determine amount of classdata not retrieved by suck-operations         */
521
522         int classdata_left = ((classbuffer + classbuffer_size) - classbuf_pos - 1);
523
524         if (classdata_left > 0) {
525                 /* surplus */           
526                 dolog("There are %d extra bytes at end of classfile",
527                                 classdata_left);
528                 /* The JVM spec disallows extra bytes. */
529                 panic("Extra bytes at end of classfile");
530         }
531
532         /* free memory */
533
534         MFREE(classbuffer, u1, classbuffer_size);
535         classbuffer = NULL;
536 }
537
538
539 /******************************************************************************/
540 /******************* Some support functions ***********************************/
541 /******************************************************************************/
542
543 void fprintflags (FILE *fp, u2 f)
544 {
545    if ( f & ACC_PUBLIC )       fprintf (fp," PUBLIC");
546    if ( f & ACC_PRIVATE )      fprintf (fp," PRIVATE");
547    if ( f & ACC_PROTECTED )    fprintf (fp," PROTECTED");
548    if ( f & ACC_STATIC )       fprintf (fp," STATIC");
549    if ( f & ACC_FINAL )        fprintf (fp," FINAL");
550    if ( f & ACC_SYNCHRONIZED ) fprintf (fp," SYNCHRONIZED");
551    if ( f & ACC_VOLATILE )     fprintf (fp," VOLATILE");
552    if ( f & ACC_TRANSIENT )    fprintf (fp," TRANSIENT");
553    if ( f & ACC_NATIVE )       fprintf (fp," NATIVE");
554    if ( f & ACC_INTERFACE )    fprintf (fp," INTERFACE");
555    if ( f & ACC_ABSTRACT )     fprintf (fp," ABSTRACT");
556 }
557
558
559 /********** internal function: printflags  (only for debugging) ***************/
560
561 void printflags(u2 f)
562 {
563    if ( f & ACC_PUBLIC )       printf (" PUBLIC");
564    if ( f & ACC_PRIVATE )      printf (" PRIVATE");
565    if ( f & ACC_PROTECTED )    printf (" PROTECTED");
566    if ( f & ACC_STATIC )       printf (" STATIC");
567    if ( f & ACC_FINAL )        printf (" FINAL");
568    if ( f & ACC_SYNCHRONIZED ) printf (" SYNCHRONIZED");
569    if ( f & ACC_VOLATILE )     printf (" VOLATILE");
570    if ( f & ACC_TRANSIENT )    printf (" TRANSIENT");
571    if ( f & ACC_NATIVE )       printf (" NATIVE");
572    if ( f & ACC_INTERFACE )    printf (" INTERFACE");
573    if ( f & ACC_ABSTRACT )     printf (" ABSTRACT");
574 }
575
576
577 /************************* Function: skipattribute *****************************
578
579         skips a (1) 'attribute' structure in the class file
580
581 *******************************************************************************/
582
583 static void skipattribute()
584 {
585         u4 len;
586         suck_u2 ();
587         len = suck_u4();
588         skip_nbytes(len);       
589 }
590
591
592 /********************** Function: skipattributebody ****************************
593
594         skips an attribute after the 16 bit reference to attribute_name has already
595         been read
596         
597 *******************************************************************************/
598
599 static void skipattributebody()
600 {
601         u4 len;
602         len = suck_u4();
603         skip_nbytes(len);
604 }
605
606
607 /************************* Function: skipattributes ****************************
608
609         skips num attribute structures
610         
611 *******************************************************************************/
612
613 static void skipattributes(u4 num)
614 {
615         u4 i;
616         for (i = 0; i < num; i++)
617                 skipattribute();
618 }
619
620
621 /******************** function: innerclass_getconstant ************************
622
623     like class_getconstant, but if cptags is ZERO null is returned                                       
624         
625 *******************************************************************************/
626
627 voidptr innerclass_getconstant(classinfo *c, u4 pos, u4 ctype) 
628 {
629         /* invalid position in constantpool */
630         if (pos >= c->cpcount)
631                 panic("Attempt to access constant outside range");
632
633         /* constantpool entry of type 0 */      
634         if (!c->cptags[pos])
635                 return NULL;
636
637         /* check type of constantpool entry */
638         if (c->cptags[pos] != ctype) {
639                 error("Type mismatch on constant: %d requested, %d here (innerclass_getconstant)",
640                           (int) ctype, (int) c->cptags[pos] );
641         }
642                 
643         return c->cpinfos[pos];
644 }
645
646
647 /************************ function: attribute_load ****************************
648
649     read attributes from classfile
650         
651 *******************************************************************************/
652
653 static void attribute_load(u4 num, classinfo *c)
654 {
655         u4 i, j;
656
657         for (i = 0; i < num; i++) {
658                 /* retrieve attribute name */
659                 utf *aname = class_getconstant(c, suck_u2(), CONSTANT_Utf8);
660
661                 if (aname == utf_innerclasses) {
662                         /* innerclasses attribute */
663
664                         if (c->innerclass != NULL)
665                                 panic("Class has more than one InnerClasses attribute");
666                                 
667                         /* skip attribute length */                                             
668                         suck_u4(); 
669                         /* number of records */
670                         c->innerclasscount = suck_u2();
671                         /* allocate memory for innerclass structure */
672                         c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
673
674                         for (j = 0; j < c->innerclasscount; j++) {
675                                 /*  The innerclass structure contains a class with an encoded name, 
676                                     its defining scope, its simple name  and a bitmask of the access flags. 
677                                     If an inner class is not a member, its outer_class is NULL, 
678                                     if a class is anonymous, its name is NULL.                              */
679                                                                 
680                                 innerclassinfo *info = c->innerclass + j;
681
682                                 info->inner_class = innerclass_getconstant(c, suck_u2(), CONSTANT_Class); /* CONSTANT_Class_info index */
683                                 info->outer_class = innerclass_getconstant(c, suck_u2(), CONSTANT_Class); /* CONSTANT_Class_info index */
684                                 info->name  = innerclass_getconstant(c, suck_u2(), CONSTANT_Utf8);        /* CONSTANT_Utf8_info index  */
685                                 info->flags = suck_u2();                                                  /* access_flags bitmask      */
686                         }
687
688                 } else {
689                         /* unknown attribute */
690                         skipattributebody();
691                 }
692         }
693 }
694
695
696 /******************* function: checkfielddescriptor ****************************
697
698         checks whether a field-descriptor is valid and aborts otherwise
699         all referenced classes are inserted into the list of unloaded classes
700         
701 *******************************************************************************/
702
703 static void checkfielddescriptor (char *utf_ptr, char *end_pos)
704 {
705         class_from_descriptor(utf_ptr,end_pos,NULL,
706                                                   CLASSLOAD_NEW
707                                                   | CLASSLOAD_NULLPRIMITIVE
708                                                   | CLASSLOAD_NOVOID
709                                                   | CLASSLOAD_CHECKEND);
710         
711         /* XXX use the following if -noverify */
712 #if 0
713         char *tstart;  /* pointer to start of classname */
714         char ch;
715         char *start = utf_ptr;
716
717         switch (*utf_ptr++) {
718           case 'B':
719           case 'C':
720           case 'I':
721           case 'S':
722           case 'Z':  
723           case 'J':  
724           case 'F':  
725           case 'D':
726                   /* primitive type */  
727                   break;
728                   
729           case '[':
730           case 'L':
731                   if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
732                           panic ("Ill formed descriptor");
733                   break;
734                   
735           default:   
736                   panic ("Ill formed descriptor");
737         }                       
738         
739         /* exceeding characters */              
740         if (utf_ptr!=end_pos) panic ("descriptor has exceeding chars");
741 #endif
742 }
743
744
745 /******************* function checkmethoddescriptor ****************************
746
747     checks whether a method-descriptor is valid and aborts otherwise.
748     All referenced classes are inserted into the list of unloaded classes.
749
750     The number of arguments is returned. A long or double argument is counted
751     as two arguments.
752         
753 *******************************************************************************/
754
755 static int checkmethoddescriptor (utf *d)
756 {
757         char *utf_ptr = d->text;     /* current position in utf text   */
758         char *end_pos = utf_end(d);  /* points behind utf string       */
759         int argcount = 0;            /* number of arguments            */
760
761         /* method descriptor must start with parenthesis */
762         if (utf_ptr == end_pos || *utf_ptr++ != '(') panic ("Missing '(' in method descriptor");
763
764     /* check arguments */
765     while (utf_ptr != end_pos && *utf_ptr != ')') {
766                 /* XXX we cannot count the this argument here because
767                  * we don't know if the method is static. */
768                 if (*utf_ptr == 'J' || *utf_ptr == 'D')
769                         argcount+=2;
770                 else
771                         argcount++;
772                 class_from_descriptor(utf_ptr,end_pos,&utf_ptr,
773                                                           CLASSLOAD_NEW
774                                                           | CLASSLOAD_NULLPRIMITIVE
775                                                           | CLASSLOAD_NOVOID);
776         }
777
778         if (utf_ptr == end_pos) panic("Missing ')' in method descriptor");
779     utf_ptr++; /* skip ')' */
780
781         class_from_descriptor(utf_ptr,end_pos,NULL,
782                                                   CLASSLOAD_NEW
783                                                   | CLASSLOAD_NULLPRIMITIVE
784                                                   | CLASSLOAD_CHECKEND);
785
786         if (argcount > 255)
787                 panic("Invalid method descriptor: too many arguments");
788
789         return argcount;
790
791         /* XXX use the following if -noverify */
792 #if 0
793         /* XXX check length */
794         /* check arguments */
795         while ((c = *utf_ptr++) != ')') {
796                 start = utf_ptr-1;
797                 
798                 switch (c) {
799                 case 'B':
800                 case 'C':
801                 case 'I':
802                 case 'S':
803                 case 'Z':  
804                 case 'J':  
805                 case 'F':  
806                 case 'D':
807                         /* primitive type */  
808                         break;
809
810                 case '[':
811                 case 'L':
812                         if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
813                                 panic ("Ill formed method descriptor");
814                         break;
815                         
816                 default:   
817                         panic ("Ill formed methodtype-descriptor");
818                 }
819         }
820
821         /* check returntype */
822         if (*utf_ptr=='V') {
823                 /* returntype void */
824                 if ((utf_ptr+1) != end_pos) panic ("Method-descriptor has exceeding chars");
825         }
826         else
827                 /* treat as field-descriptor */
828                 checkfielddescriptor (utf_ptr,end_pos);
829 #endif
830 }
831
832
833 /***************** Function: print_arraydescriptor ****************************
834
835         Debugging helper for displaying an arraydescriptor
836         
837 *******************************************************************************/
838
839 void print_arraydescriptor(FILE *file, arraydescriptor *desc)
840 {
841         if (!desc) {
842                 fprintf(file, "<NULL>");
843                 return;
844         }
845
846         fprintf(file, "{");
847         if (desc->componentvftbl) {
848                 if (desc->componentvftbl->class)
849                         utf_fprint(file, desc->componentvftbl->class->name);
850                 else
851                         fprintf(file, "<no classinfo>");
852         }
853         else
854                 fprintf(file, "0");
855                 
856         fprintf(file, ",");
857         if (desc->elementvftbl) {
858                 if (desc->elementvftbl->class)
859                         utf_fprint(file, desc->elementvftbl->class->name);
860                 else
861                         fprintf(file, "<no classinfo>");
862         }
863         else
864                 fprintf(file, "0");
865         fprintf(file, ",%d,%d,%d,%d}", desc->arraytype, desc->dimension,
866                         desc->dataoffset, desc->componentsize);
867 }
868
869
870 /******************************************************************************/
871 /**************************  Functions for fields  ****************************/
872 /******************************************************************************/
873
874
875 /************************ Function: field_load *********************************
876
877         Load everything about a class field from the class file and fill a
878         'fieldinfo' structure. For static fields, space in the data segment is
879         allocated.
880
881 *******************************************************************************/
882
883 #define field_load_NOVALUE  0xffffffff /* must be bigger than any u2 value! */
884
885 static void field_load(fieldinfo *f, classinfo *c)
886 {
887         u4 attrnum,i;
888         u4 jtype;
889         u4 pindex = field_load_NOVALUE;                               /* constantvalue_index */
890
891         f->flags = suck_u2();                                           /* ACC flags         */
892         f->name = class_getconstant(c, suck_u2(), CONSTANT_Utf8);       /* name of field     */
893         f->descriptor = class_getconstant(c, suck_u2(), CONSTANT_Utf8); /* JavaVM descriptor */
894         f->type = jtype = desc_to_type(f->descriptor);                      /* data type         */
895         f->offset = 0;                                                            /* offset from start of object */
896         f->class = c;
897         f->xta = NULL;
898         
899         /* check flag consistency */
900         if (opt_verify) {
901                 i = (f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
902                 if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED)
903                         panic("Field has invalid access flags");
904                 if ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))
905                         panic("Field is declared final and volatile");
906                 if ((c->flags & ACC_INTERFACE) != 0) {
907                         if ((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
908                                 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
909                                 panic("Interface field is not declared static final public");
910                         if ((f->flags & ACC_TRANSIENT) != 0)
911                                 panic("Interface field declared transient");
912                 }
913         }
914                 
915         switch (f->type) {
916         case TYPE_INT:        f->value.i = 0; break;
917         case TYPE_FLOAT:      f->value.f = 0.0; break;
918         case TYPE_DOUBLE:     f->value.d = 0.0; break;
919         case TYPE_ADDRESS:    f->value.a = NULL; break;
920         case TYPE_LONG:
921 #if U8_AVAILABLE
922                 f->value.l = 0; break;
923 #else
924                 f->value.l.low = 0; f->value.l.high = 0; break;
925 #endif
926         }
927
928         /* read attributes */
929         attrnum = suck_u2();
930         for (i = 0; i < attrnum; i++) {
931                 utf *aname;
932
933                 aname = class_getconstant(c, suck_u2(), CONSTANT_Utf8);
934                 
935                 if (aname != utf_constantvalue) {
936                         /* unknown attribute */
937                         skipattributebody();
938
939                 } else {
940                         /* constant value attribute */
941
942                         if (pindex != field_load_NOVALUE)
943                                 panic("Field has more than one ConstantValue attribute");
944                         
945                         /* check attribute length */
946                         if (suck_u4() != 2)
947                                 panic("ConstantValue attribute has invalid length");
948                         
949                         /* index of value in constantpool */            
950                         pindex = suck_u2();
951                 
952                         /* initialize field with value from constantpool */             
953                         switch (jtype) {
954                         case TYPE_INT: {
955                                 constant_integer *ci = 
956                                         class_getconstant(c, pindex, CONSTANT_Integer);
957                                 f->value.i = ci->value;
958                         }
959                         break;
960                                         
961                         case TYPE_LONG: {
962                                 constant_long *cl = 
963                                         class_getconstant(c, pindex, CONSTANT_Long);
964                                 f->value.l = cl->value;
965                         }
966                         break;
967
968                         case TYPE_FLOAT: {
969                                 constant_float *cf = 
970                                         class_getconstant(c, pindex, CONSTANT_Float);
971                                 f->value.f = cf->value;
972                         }
973                         break;
974                                                                                         
975                         case TYPE_DOUBLE: {
976                                 constant_double *cd = 
977                                         class_getconstant(c, pindex, CONSTANT_Double);
978                                 f->value.d = cd->value;
979                         }
980                         break;
981                                                 
982                         case TYPE_ADDRESS: { 
983                                 utf *u = class_getconstant(c, pindex, CONSTANT_String);
984                                 /* create javastring from compressed utf8-string */                                     
985                                 f->value.a = literalstring_new(u);
986                         }
987                         break;
988         
989                         default: 
990                                 log_text ("Invalid Constant - Type");
991                         }
992                 }
993         }
994 }
995
996
997 /********************** function: field_free **********************************/
998
999 static void field_free (fieldinfo *f)
1000 {
1001         /* empty */
1002 }
1003
1004
1005 /**************** Function: field_display (debugging only) ********************/
1006
1007 void field_display(fieldinfo *f)
1008 {
1009         printf("   ");
1010         printflags(f->flags);
1011         printf(" ");
1012         utf_display(f->name);
1013         printf(" ");
1014         utf_display(f->descriptor);     
1015         printf(" offset: %ld\n", (long int) (f->offset));
1016 }
1017
1018
1019 /******************************************************************************/
1020 /************************* Functions for methods ******************************/ 
1021 /******************************************************************************/
1022
1023
1024 /*********************** Function: method_load *********************************
1025
1026         Loads a method from the class file and fills an existing 'methodinfo'
1027         structure. For native methods, the function pointer field is set to the
1028         real function pointer, for JavaVM methods a pointer to the compiler is used
1029         preliminarily.
1030         
1031 *******************************************************************************/
1032
1033 static void method_load(methodinfo *m, classinfo *c)
1034 {
1035         u4 attrnum, i, e;
1036         int argcount;
1037         
1038 #ifdef STATISTICS
1039         count_all_methods++;
1040 #endif
1041
1042         m->class = c;
1043         
1044         m->flags = suck_u2();
1045         m->name = class_getconstant(c, suck_u2(), CONSTANT_Utf8);
1046         m->descriptor = class_getconstant(c, suck_u2(), CONSTANT_Utf8);
1047         argcount = checkmethoddescriptor(m->descriptor);
1048         if ((m->flags & ACC_STATIC) == 0)
1049                 argcount++; /* count the 'this' argument */
1050
1051         if (opt_verify) {
1052                 if (argcount > 255)
1053                         panic("Method has more than 255 arguments");
1054
1055                 /* check flag consistency */
1056                 /* XXX could check if <clinit> is STATIC */
1057                 if (m->name != utf_clinit) {
1058                         i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1059                         if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED)
1060                                 panic("Method has invalid access flags");
1061                         if ((m->flags & ACC_ABSTRACT) != 0) {
1062                                 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE | ACC_STATIC
1063                                                                  | ACC_STRICT | ACC_SYNCHRONIZED)) != 0)
1064                                         panic("Abstract method has invalid flags set");
1065                         }
1066                         if ((c->flags & ACC_INTERFACE) != 0) {
1067                                 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC))
1068                                         != (ACC_ABSTRACT | ACC_PUBLIC))
1069                                         panic("Interface method is not declared abstract and public");
1070                         }
1071                         if (m->name == utf_init) {
1072                                 if ((m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED
1073                                                                  | ACC_NATIVE | ACC_ABSTRACT)) != 0)
1074                                         panic("Instance initialization method has invalid flags set");
1075                         }
1076                 }
1077         }
1078                 
1079         m->jcode = NULL;
1080         m->exceptiontable = NULL;
1081         m->entrypoint = NULL;
1082         m->mcode = NULL;
1083         m->stubroutine = NULL;
1084         m->methodUsed = NOTUSED;    
1085         m->monoPoly = MONO;    
1086         m->subRedefs = 0;
1087         m->subRedefsUsed = 0;
1088
1089         m->xta = NULL;
1090         
1091         if (!(m->flags & ACC_NATIVE)) {
1092                 m->stubroutine = createcompilerstub(m);
1093
1094         } else {
1095                 functionptr f = native_findfunction(c->name, m->name, m->descriptor, 
1096                                                                                         (m->flags & ACC_STATIC) != 0);
1097                 if (f) {
1098                         m->stubroutine = createnativestub(f, m);
1099                 }
1100         }
1101         
1102         
1103         attrnum = suck_u2();
1104         for (i = 0; i < attrnum; i++) {
1105                 utf *aname;
1106
1107                 aname = class_getconstant(c, suck_u2(), CONSTANT_Utf8);
1108
1109                 if (aname != utf_code) {
1110                         skipattributebody();
1111
1112                 } else {
1113                         u4 codelen;
1114                         if ((m->flags & (ACC_ABSTRACT | ACC_NATIVE)) != 0)
1115                                 panic("Code attribute for native or abstract method");
1116                         
1117                         if (m->jcode)
1118                                 panic("Method has more than one Code attribute");
1119
1120                         suck_u4();
1121                         m->maxstack = suck_u2();
1122                         m->maxlocals = suck_u2();
1123                         if (m->maxlocals < argcount)
1124                                 panic("max_locals is smaller than the number of arguments");
1125                         
1126                         codelen = suck_u4();
1127                         if (codelen == 0)
1128                                 panic("bytecode has zero length");
1129                         if (codelen > 65536)
1130                                 panic("bytecode too long");
1131                         m->jcodelength = codelen;
1132                         m->jcode = MNEW(u1, m->jcodelength);
1133                         suck_nbytes(m->jcode, m->jcodelength);
1134                         m->exceptiontablelength = suck_u2();
1135                         m->exceptiontable = 
1136                                 MNEW(exceptiontable, m->exceptiontablelength);
1137
1138 #ifdef STATISTICS
1139                         count_vmcode_len += m->jcodelength + 18;
1140                         count_extable_len += 8 * m->exceptiontablelength;
1141 #endif
1142
1143                         for (e = 0; e < m->exceptiontablelength; e++) {
1144                                 u4 idx;
1145                                 m->exceptiontable[e].startpc = suck_u2();
1146                                 m->exceptiontable[e].endpc = suck_u2();
1147                                 m->exceptiontable[e].handlerpc = suck_u2();
1148
1149                                 idx = suck_u2();
1150                                 if (!idx) {
1151                                         m->exceptiontable[e].catchtype = NULL;
1152
1153                                 } else {
1154                                         m->exceptiontable[e].catchtype = 
1155                                       class_getconstant(c, idx, CONSTANT_Class);
1156                                 }
1157                         }                       
1158
1159                         skipattributes(suck_u2());
1160                 }
1161         }
1162
1163         if (!m->jcode && (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) == 0)
1164                 panic("Method missing Code attribute");
1165 }
1166
1167
1168 /********************* Function: method_free ***********************************
1169
1170         frees all memory that was allocated for this method
1171
1172 *******************************************************************************/
1173
1174 static void method_free(methodinfo *m)
1175 {
1176         if (m->jcode)
1177                 MFREE(m->jcode, u1, m->jcodelength);
1178
1179         if (m->exceptiontable)
1180                 MFREE(m->exceptiontable, exceptiontable, m->exceptiontablelength);
1181
1182         if (m->mcode)
1183                 CFREE(m->mcode, m->mcodelength);
1184
1185         if (m->stubroutine) {
1186                 if (m->flags & ACC_NATIVE) {
1187                         removenativestub(m->stubroutine);
1188
1189                 } else {
1190                         removecompilerstub(m->stubroutine);
1191                 }
1192         }
1193 }
1194
1195
1196 /************** Function: method_display  (debugging only) **************/
1197
1198 void method_display(methodinfo *m)
1199 {
1200         printf("   ");
1201         printflags(m->flags);
1202         printf(" ");
1203         utf_display(m->name);
1204         printf(" "); 
1205         utf_display(m->descriptor);
1206         printf("\n");
1207 }
1208
1209
1210 /******************** Function: method_canoverwrite ****************************
1211
1212         Check if m and old are identical with respect to type and name. This means
1213         that old can be overwritten with m.
1214         
1215 *******************************************************************************/  
1216
1217 static bool method_canoverwrite (methodinfo *m, methodinfo *old)
1218 {
1219         if (m->name != old->name) return false;
1220         if (m->descriptor != old->descriptor) return false;
1221         if (m->flags & ACC_STATIC) return false;
1222         return true;
1223 }
1224
1225
1226
1227
1228 /******************************************************************************/
1229 /************************ Functions for class *********************************/
1230 /******************************************************************************/
1231
1232
1233 /******************** function:: class_getconstant ******************************
1234
1235         retrieves the value at position 'pos' of the constantpool of a class
1236         if the type of the value is other than 'ctype' the system is stopped
1237
1238 *******************************************************************************/
1239
1240 voidptr class_getconstant(classinfo *c, u4 pos, u4 ctype)
1241 {
1242         /* invalid position in constantpool */
1243         /* (pos == 0 is caught by type comparison) */
1244         if (pos >= c->cpcount)
1245                 panic("Attempt to access constant outside range");
1246
1247         /* check type of constantpool entry */
1248
1249         if (c->cptags[pos] != ctype) {
1250                 class_showconstantpool(c);
1251                 error("Type mismatch on constant: %d requested, %d here (class_getconstant)",
1252                           (int) ctype, (int) c->cptags[pos]);
1253         }
1254                 
1255         return c->cpinfos[pos];
1256 }
1257
1258
1259 /********************* Function: class_constanttype ****************************
1260
1261         Determines the type of a class entry in the ConstantPool
1262         
1263 *******************************************************************************/
1264
1265 u4 class_constanttype(classinfo *c, u4 pos)
1266 {
1267         if (pos >= c->cpcount)
1268                 panic("Attempt to access constant outside range");
1269
1270         return c->cptags[pos];
1271 }
1272
1273
1274 /******************** function: class_loadcpool ********************************
1275
1276         loads the constantpool of a class, 
1277         the entries are transformed into a simpler format 
1278         by resolving references
1279         (a detailed overview of the compact structures can be found in global.h)        
1280
1281 *******************************************************************************/
1282
1283 static void class_loadcpool(classinfo *c)
1284 {
1285
1286         /* The following structures are used to save information which cannot be 
1287            processed during the first pass. After the complete constantpool has 
1288            been traversed the references can be resolved. 
1289            (only in specific order)                                                */
1290         
1291         /* CONSTANT_Class_info entries */
1292         typedef struct forward_class {      
1293                 struct forward_class *next; 
1294                 u2 thisindex;               
1295                 u2 name_index;              
1296         } forward_class;                    
1297                                         
1298         /* CONSTANT_String */                                      
1299         typedef struct forward_string { 
1300                 struct forward_string *next; 
1301                 u2 thisindex;                
1302                 u2 string_index;
1303         } forward_string;
1304
1305         /* CONSTANT_NameAndType */
1306         typedef struct forward_nameandtype {
1307                 struct forward_nameandtype *next;
1308                 u2 thisindex;
1309                 u2 name_index;
1310                 u2 sig_index;
1311         } forward_nameandtype;
1312
1313         /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
1314         typedef struct forward_fieldmethint {   
1315                 struct forward_fieldmethint *next;
1316                 u2 thisindex;
1317                 u1 tag;
1318                 u2 class_index;
1319                 u2 nameandtype_index;
1320         } forward_fieldmethint;
1321
1322
1323         u4 idx;
1324         long int dumpsize = dump_size ();
1325
1326         forward_class *forward_classes = NULL;
1327         forward_string *forward_strings = NULL;
1328         forward_nameandtype *forward_nameandtypes = NULL;
1329         forward_fieldmethint *forward_fieldmethints = NULL;
1330
1331         /* number of entries in the constant_pool table plus one */
1332         u4 cpcount       = c -> cpcount = suck_u2();
1333         /* allocate memory */
1334         u1 *cptags       = c -> cptags  = MNEW (u1, cpcount);
1335         voidptr *cpinfos = c -> cpinfos = MNEW (voidptr, cpcount);
1336
1337         if (!cpcount)
1338                 panic("Invalid constant_pool_count (0)");
1339         
1340 #ifdef STATISTICS
1341         count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
1342 #endif
1343         
1344         /* initialize constantpool */
1345         for (idx=0; idx<cpcount; idx++) {
1346                 cptags[idx] = CONSTANT_UNUSED;
1347                 cpinfos[idx] = NULL;
1348                 }
1349
1350                         
1351                 /******* first pass *******/
1352                 /* entries which cannot be resolved now are written into 
1353                    temporary structures and traversed again later        */
1354                    
1355         idx = 1;
1356         while (idx < cpcount) {
1357                 /* get constant type */
1358                 u4 t = suck_u1 (); 
1359                 switch ( t ) {
1360
1361                         case CONSTANT_Class: { 
1362                                 forward_class *nfc = DNEW(forward_class);
1363
1364                                 nfc -> next = forward_classes;                                                                                  
1365                                 forward_classes = nfc;
1366
1367                                 nfc -> thisindex = idx;
1368                                 /* reference to CONSTANT_NameAndType */
1369                                 nfc -> name_index = suck_u2 (); 
1370
1371                                 idx++;
1372                                 break;
1373                                 }
1374                         
1375                         case CONSTANT_Fieldref:
1376                         case CONSTANT_Methodref:
1377                         case CONSTANT_InterfaceMethodref: { 
1378                                 forward_fieldmethint *nff = DNEW (forward_fieldmethint);
1379                                 
1380                                 nff -> next = forward_fieldmethints;
1381                                 forward_fieldmethints = nff;
1382
1383                                 nff -> thisindex = idx;
1384                                 /* constant type */
1385                                 nff -> tag = t;
1386                                 /* class or interface type that contains the declaration of the field or method */
1387                                 nff -> class_index = suck_u2 (); 
1388                                 /* name and descriptor of the field or method */
1389                                 nff -> nameandtype_index = suck_u2 ();
1390
1391                                 idx ++;
1392                                 break;
1393                                 }
1394                                 
1395                         case CONSTANT_String: {
1396                                 forward_string *nfs = DNEW (forward_string);
1397                                 
1398                                 nfs -> next = forward_strings;
1399                                 forward_strings = nfs;
1400                                 
1401                                 nfs -> thisindex = idx;
1402                                 /* reference to CONSTANT_Utf8_info with string characters */
1403                                 nfs -> string_index = suck_u2 ();
1404                                 
1405                                 idx ++;
1406                                 break;
1407                                 }
1408
1409                         case CONSTANT_NameAndType: {
1410                                 forward_nameandtype *nfn = DNEW (forward_nameandtype);
1411                                 
1412                                 nfn -> next = forward_nameandtypes;
1413                                 forward_nameandtypes = nfn;
1414                                 
1415                                 nfn -> thisindex = idx;
1416                                 /* reference to CONSTANT_Utf8_info containing simple name */
1417                                 nfn -> name_index = suck_u2 ();
1418                                 /* reference to CONSTANT_Utf8_info containing field or method descriptor */
1419                                 nfn -> sig_index = suck_u2 ();
1420                                 
1421                                 idx ++;
1422                                 break;
1423                                 }
1424
1425                         case CONSTANT_Integer: {
1426                                 constant_integer *ci = NEW (constant_integer);
1427
1428 #ifdef STATISTICS
1429         count_const_pool_len += sizeof(constant_integer);
1430 #endif
1431
1432                                 ci -> value = suck_s4 ();
1433                                 cptags [idx] = CONSTANT_Integer;
1434                                 cpinfos [idx] = ci;
1435                                 idx ++;
1436                                 
1437                                 break;
1438                                 }
1439                                 
1440                         case CONSTANT_Float: {
1441                                 constant_float *cf = NEW (constant_float);
1442
1443 #ifdef STATISTICS
1444         count_const_pool_len += sizeof(constant_float);
1445 #endif
1446
1447                                 cf -> value = suck_float ();
1448                                 cptags [idx] = CONSTANT_Float;
1449                                 cpinfos[idx] = cf;
1450                                 idx ++;
1451                                 break;
1452                                 }
1453                                 
1454                         case CONSTANT_Long: {
1455                                 constant_long *cl = NEW(constant_long);
1456                                         
1457 #ifdef STATISTICS
1458         count_const_pool_len += sizeof(constant_long);
1459 #endif
1460
1461                                 cl -> value = suck_s8 ();
1462                                 cptags [idx] = CONSTANT_Long;
1463                                 cpinfos [idx] = cl;
1464                                 idx += 2;
1465                                 if (idx > cpcount)
1466                                         panic("Long constant exceeds constant pool");
1467                                 break;
1468                                 }
1469                         
1470                         case CONSTANT_Double: {
1471                                 constant_double *cd = NEW(constant_double);
1472                                 
1473 #ifdef STATISTICS
1474         count_const_pool_len += sizeof(constant_double);
1475 #endif
1476
1477                                 cd -> value = suck_double ();
1478                                 cptags [idx] = CONSTANT_Double;
1479                                 cpinfos [idx] = cd;
1480                                 idx += 2;
1481                                 if (idx > cpcount)
1482                                         panic("Double constant exceeds constant pool");
1483                                 break;
1484                                 }
1485                                 
1486                         case CONSTANT_Utf8: { 
1487
1488                                 /* number of bytes in the bytes array (not string-length) */
1489                                 u4 length = suck_u2();
1490                                 cptags [idx]  = CONSTANT_Utf8;
1491                                 /* validate the string */
1492                                 ASSERT_LEFT(length);
1493                                 if (opt_verify &&
1494                                         !is_valid_utf(classbuf_pos+1, classbuf_pos+1+length))
1495                                 {
1496                                         dolog("Invalid UTF-8 string (constant pool index %d)",idx);
1497                                         panic("Invalid UTF-8 string");
1498                                 }
1499                                 /* insert utf-string into the utf-symboltable */
1500                                 cpinfos [idx] = utf_new(classbuf_pos+1, length);
1501                                 /* skip bytes of the string */
1502                                 skip_nbytes(length);
1503                                 idx++;
1504                                 break;
1505                                 }
1506                                                                                 
1507                         default:
1508                                 error ("Unkown constant type: %d",(int) t);
1509                 
1510                         }  /* end switch */
1511                         
1512                 } /* end while */
1513                 
1514
1515
1516            /* resolve entries in temporary structures */
1517
1518         while (forward_classes) {
1519                 utf *name =
1520                   class_getconstant (c, forward_classes -> name_index, CONSTANT_Utf8);
1521
1522                 cptags  [forward_classes -> thisindex] = CONSTANT_Class;
1523                 /* retrieve class from class-table */
1524                 cpinfos [forward_classes -> thisindex] = class_new (name);
1525
1526                 forward_classes = forward_classes -> next;
1527                 
1528                 }
1529
1530         while (forward_strings) {
1531                 utf *text = 
1532                   class_getconstant (c, forward_strings -> string_index, CONSTANT_Utf8);
1533 /*
1534                 log_text("forward_string:");
1535                 printf( "classpoolid: %d\n",forward_strings -> thisindex);
1536                 utf_display(text);
1537                 log_text("\n------------------"); */
1538                 /* resolve utf-string */                
1539                 cptags   [forward_strings -> thisindex] = CONSTANT_String;
1540                 cpinfos  [forward_strings -> thisindex] = text;
1541                 
1542                 forward_strings = forward_strings -> next;
1543                 }       
1544
1545         while (forward_nameandtypes) {
1546                 constant_nameandtype *cn = NEW (constant_nameandtype);  
1547
1548 #ifdef STATISTICS
1549                 count_const_pool_len += sizeof(constant_nameandtype);
1550 #endif
1551
1552                 /* resolve simple name and descriptor */
1553                 cn -> name = class_getconstant 
1554                    (c, forward_nameandtypes -> name_index, CONSTANT_Utf8);
1555                 cn -> descriptor = class_getconstant
1556                    (c, forward_nameandtypes -> sig_index, CONSTANT_Utf8);
1557                  
1558                 cptags   [forward_nameandtypes -> thisindex] = CONSTANT_NameAndType;
1559                 cpinfos  [forward_nameandtypes -> thisindex] = cn;
1560                 
1561                 forward_nameandtypes = forward_nameandtypes -> next;
1562                 }
1563
1564
1565         while (forward_fieldmethints)  {
1566                 constant_nameandtype *nat;
1567                 constant_FMIref *fmi = NEW (constant_FMIref);
1568
1569 #ifdef STATISTICS
1570                 count_const_pool_len += sizeof(constant_FMIref);
1571 #endif
1572                 /* resolve simple name and descriptor */
1573                 nat = class_getconstant
1574                         (c, forward_fieldmethints -> nameandtype_index, CONSTANT_NameAndType);
1575
1576 #ifdef JOWENN_DEBUG
1577                 log_text("trying to resolve:");
1578                 log_text(nat->name->text);
1579                 switch(forward_fieldmethints ->tag) {
1580                 case CONSTANT_Fieldref: 
1581                                 log_text("CONSTANT_Fieldref");
1582                                 break;
1583                 case CONSTANT_InterfaceMethodref: 
1584                                 log_text("CONSTANT_InterfaceMethodref");
1585                                 break;
1586                 case CONSTANT_Methodref: 
1587                                 log_text("CONSTANT_Methodref");
1588                                 break;
1589                 }
1590 #endif
1591                 fmi -> class = class_getconstant 
1592                         (c, forward_fieldmethints -> class_index, CONSTANT_Class);
1593                 fmi -> name = nat -> name;
1594                 fmi -> descriptor = nat -> descriptor;
1595
1596                 cptags [forward_fieldmethints -> thisindex] = forward_fieldmethints -> tag;
1597                 cpinfos [forward_fieldmethints -> thisindex] = fmi;
1598         
1599                 switch (forward_fieldmethints -> tag) {
1600                 case CONSTANT_Fieldref:  /* check validity of descriptor */
1601                                          checkfielddescriptor (fmi->descriptor->text,utf_end(fmi->descriptor));
1602                                          break;
1603                 case CONSTANT_InterfaceMethodref: 
1604                 case CONSTANT_Methodref: /* check validity of descriptor */
1605                         /* XXX check special names (<init>) */
1606                                          checkmethoddescriptor (fmi->descriptor);
1607                                          break;
1608                 }               
1609         
1610                 forward_fieldmethints = forward_fieldmethints -> next;
1611
1612                 }
1613
1614 /*      class_showconstantpool(c); */
1615
1616         dump_release (dumpsize);
1617 }
1618
1619
1620 /********************** Function: class_load ***********************************
1621         
1622         Loads everything interesting about a class from the class file. The
1623         'classinfo' structure must have been allocated previously.
1624
1625         The super class and the interfaces implemented by this class need not be
1626         loaded. The link is set later by the function 'class_link'.
1627
1628         The loaded class is removed from the list 'unloadedclasses' and added to
1629         the list 'unlinkedclasses'.
1630         
1631 *******************************************************************************/
1632
1633 static int class_load(classinfo *c)
1634 {
1635         u4 i;
1636         u4 mi,ma;
1637
1638 #ifdef STATISTICS
1639         count_class_loads++;
1640 #endif
1641
1642         /* output for debugging purposes */
1643         if (loadverbose) {              
1644                 char logtext[MAXLOGTEXT];
1645                 sprintf(logtext, "Loading class: ");
1646                 utf_sprint(logtext + strlen(logtext), c->name);
1647                 log_text(logtext);
1648         }
1649         
1650         /* load classdata, throw exception on error */
1651
1652         if (!suck_start(c->name)) {
1653                 throw_noclassdeffounderror_message(c->name);
1654                 return false;
1655         }
1656         
1657         /* check signature */           
1658         if (suck_u4() != MAGIC) panic("Can not find class-file signature");     
1659         /* check version */
1660         mi = suck_u2(); 
1661         ma = suck_u2();
1662         if (ma != MAJOR_VERSION && (ma != MAJOR_VERSION+1 || mi != 0)) {
1663                 error("File version %d.%d is not supported", (int) ma, (int) mi);
1664         }
1665
1666         class_loadcpool(c);
1667         /*JOWENN*/
1668         c->erroneous_state = 0;
1669         c->initializing_thread = 0;     
1670         /*JOWENN*/
1671         c->classUsed = NOTUSED; /* not used initially CO-RT */
1672         c->impldBy = NULL;
1673
1674         /* ACC flags */
1675         c->flags = suck_u2(); 
1676         /*if (!(c->flags & ACC_PUBLIC)) { log_text("CLASS NOT PUBLIC"); } JOWENN*/
1677
1678         /* check ACC flags consistency */
1679         if ((c->flags & ACC_INTERFACE) != 0) {
1680                 if ((c->flags & ACC_ABSTRACT) == 0) {
1681                         /* XXX We work around this because interfaces in JDK 1.1 are
1682                          * not declared abstract. */
1683
1684                         c->flags |= ACC_ABSTRACT;
1685                         /* panic("Interface class not declared abstract"); */
1686                 }
1687                 if ((c->flags & (ACC_FINAL | ACC_SUPER)) != 0)
1688                         panic("Interface class has invalid flags");
1689         }
1690         if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL))
1691                 panic("Class is declared both abstract and final");
1692
1693         /* this class */
1694         i = suck_u2();
1695         if (class_getconstant(c, i, CONSTANT_Class) != c)
1696                 panic("Invalid this_class in class file");
1697         
1698         /* retrieve superclass */
1699         if ((i = suck_u2())) {
1700                 c->super = class_getconstant(c, i, CONSTANT_Class);
1701
1702                 /* java.lang.Object may not have a super class. */
1703                 if (c->name == utf_java_lang_Object)
1704                         panic("java.lang.Object with super class");
1705
1706                 /* Interfaces must have j.l.O as super class. */
1707                 if ((c->flags & ACC_INTERFACE) != 0
1708                         && c->super->name != utf_java_lang_Object)
1709                 {
1710                         panic("Interface with super class other than java.lang.Object");
1711                 }
1712         } else {
1713                 c->super = NULL;
1714
1715                 /* This is only allowed for java.lang.Object. */
1716                 if (c->name != utf_java_lang_Object)
1717                         panic("Class (not java.lang.Object) without super class");
1718         }
1719                          
1720         /* retrieve interfaces */
1721         c->interfacescount = suck_u2();
1722         c->interfaces = MNEW(classinfo*, c->interfacescount);
1723         for (i = 0; i < c->interfacescount; i++) {
1724                 c->interfaces [i] = 
1725                         class_getconstant(c, suck_u2(), CONSTANT_Class);
1726         }
1727
1728         /* load fields */
1729         c->fieldscount = suck_u2();
1730 /*      utf_display(c->name);
1731         printf(" ,Fieldscount: %d\n",c->fieldscount);*/
1732
1733         c->fields = GCNEW(fieldinfo, c->fieldscount);
1734         for (i = 0; i < c->fieldscount; i++) {
1735                 field_load(&(c->fields[i]), c);
1736         }
1737
1738         /* load methods */
1739         c->methodscount = suck_u2();
1740         c->methods = MNEW(methodinfo, c->methodscount);
1741         for (i = 0; i < c->methodscount; i++) {
1742                 method_load(&(c->methods[i]), c);
1743         }
1744
1745         /* Check if all fields and methods can be uniquely
1746          * identified by (name,descriptor). */
1747         if (opt_verify) {
1748                 /* We use a hash table here to avoid making the
1749                  * average case quadratic in # of methods, fields.
1750                  */
1751                 static int shift = 0;
1752                 u2 *hashtab;
1753                 u2 *next; /* for chaining colliding hash entries */
1754                 size_t len;
1755                 size_t hashlen;
1756                 u2 index;
1757                 u2 old;
1758
1759                 /* Allocate hashtable */
1760                 len = c->methodscount;
1761                 if (len < c->fieldscount) len = c->fieldscount;
1762                 hashlen = 5 * len;
1763                 hashtab = MNEW(u2,(hashlen + len));
1764                 next = hashtab + hashlen;
1765
1766                 /* Determine bitshift (to get good hash values) */
1767                 if (!shift) {
1768                         len = sizeof(utf);
1769                         while (len) {
1770                                 len >>= 1;
1771                                 shift++;
1772                         }
1773                 }
1774
1775                 /* Check fields */
1776                 memset(hashtab,0,sizeof(u2) * (hashlen + len));
1777                 for (i = 0; i<c->fieldscount; ++i) {
1778                         fieldinfo *fi = c->fields + i;
1779                         /* It's ok if we lose bits here */
1780                         index = ((((size_t)fi->name) + ((size_t)fi->descriptor)) >> shift)
1781                                   % hashlen;
1782                         if ((old = hashtab[index]) != 0) {
1783                                 old--;
1784                                 /* dolog("HASHHIT %d --> %d",index,old); */
1785                                 next[i] = old;
1786                                 do {
1787                                         /* dolog("HASHCHECK %d",old); */
1788                                         if (c->fields[old].name == fi->name
1789                                                 && c->fields[old].descriptor == fi->descriptor)
1790                                         {
1791                                                 dolog("Duplicate field (%d,%d):",i,old);
1792                                                 log_utf(fi->name); log_utf(fi->descriptor);
1793                                                 panic("Fields with same name and descriptor");
1794                                         }
1795                                 } while ((old = next[old]) != 0);
1796                         }
1797                         /* else dolog("HASHLUCKY"); */
1798                         hashtab[index] = i+1;
1799                 }
1800                 
1801                 /* Check methods */
1802                 memset(hashtab,0,sizeof(u2) * (hashlen + len));
1803                 for (i = 0; i<c->methodscount; ++i) {
1804                         methodinfo *mi = c->methods + i;
1805                         /* It's ok if we lose bits here */
1806                         index = ((((size_t)mi->name) + ((size_t)mi->descriptor)) >> shift)
1807                                   % hashlen;
1808                         if ((old = hashtab[index]) != 0) {
1809                                 old--;
1810                                 /* dolog("HASHHIT %d --> %d",index,old); */
1811                                 next[i] = old;
1812                                 do {
1813                                         /* dolog("HASHCHECK %d",old); */
1814                                         if (c->methods[old].name == mi->name
1815                                                 && c->methods[old].descriptor == mi->descriptor)
1816                                         {
1817                                                 dolog("Duplicate method (%d,%d):",i,old);
1818                                                 log_utf(mi->name); log_utf(mi->descriptor);
1819                                                 panic("Methods with same name and descriptor");
1820                                         }
1821                                 } while ((old = next[old]) != 0);
1822                         }
1823                         /* else dolog("HASHLUCKY"); */
1824                         hashtab[index] = i+1;
1825                 }
1826                 
1827                 MFREE(hashtab,u2,(hashlen + len));
1828         }
1829
1830 #ifdef STATISTICS
1831         count_class_infos += sizeof(classinfo*) * c->interfacescount;
1832         count_class_infos += sizeof(fieldinfo) * c->fieldscount;
1833         count_class_infos += sizeof(methodinfo) * c->methodscount;
1834 #endif
1835
1836         /* load variable-length attribute structures */ 
1837         attribute_load(suck_u2(), c);
1838
1839         /* free memory */
1840         suck_stop();
1841
1842         /* remove class from list of unloaded classes and 
1843            add to list of unlinked classes                */
1844         list_remove(&unloadedclasses, c);
1845         list_addlast(&unlinkedclasses, c);
1846
1847         c->loaded = true;
1848
1849         return true;
1850 }
1851
1852
1853
1854 /************** internal Function: class_highestinterface ***********************
1855
1856         Used by the function class_link to determine the amount of memory needed
1857         for the interface table.
1858
1859 *******************************************************************************/
1860
1861 static s4 class_highestinterface(classinfo *c) 
1862 {
1863         s4 h;
1864         s4 i;
1865         
1866         if (!(c->flags & ACC_INTERFACE)) {
1867                 char logtext[MAXLOGTEXT];
1868                 sprintf(logtext, "Interface-methods count requested for non-interface:  ");
1869         utf_sprint(logtext + strlen(logtext), c->name);
1870         error("%s",logtext);
1871         }
1872     
1873     h = c->index;
1874         for (i = 0; i < c->interfacescount; i++) {
1875                 s4 h2 = class_highestinterface(c->interfaces[i]);
1876                 if (h2 > h) h = h2;
1877         }
1878
1879         return h;
1880 }
1881
1882
1883 /* class_addinterface **********************************************************
1884
1885         Is needed by class_link for adding a VTBL to a class. All interfaces
1886         implemented by ic are added as well.
1887
1888 *******************************************************************************/        
1889
1890 static void class_addinterface (classinfo *c, classinfo *ic)
1891 {
1892         s4     j, m;
1893         s4     i     = ic->index;
1894         vftbl *vftbl = c->vftbl;
1895         
1896         if (i >= vftbl->interfacetablelength)
1897                 panic ("Inernal error: interfacetable overflow");
1898         if (vftbl->interfacetable[-i])
1899                 return;
1900
1901         if (ic->methodscount == 0) {  /* fake entry needed for subtype test */
1902                 vftbl->interfacevftbllength[i] = 1;
1903                 vftbl->interfacetable[-i] = MNEW(methodptr, 1);
1904                 vftbl->interfacetable[-i][0] = NULL;
1905                 }
1906         else {
1907                 vftbl->interfacevftbllength[i] = ic->methodscount;
1908                 vftbl->interfacetable[-i] = MNEW(methodptr, ic->methodscount); 
1909
1910 #ifdef STATISTICS
1911         count_vftbl_len += sizeof(methodptr) *
1912                                  (ic->methodscount + (ic->methodscount == 0));
1913 #endif
1914
1915                 for (j=0; j<ic->methodscount; j++) {
1916                         classinfo *sc = c;
1917                         while (sc) {
1918                                 for (m = 0; m < sc->methodscount; m++) {
1919                                         methodinfo *mi = &(sc->methods[m]);
1920                                         if (method_canoverwrite(mi, &(ic->methods[j]))) {
1921                                                 vftbl->interfacetable[-i][j] = 
1922                                                                           vftbl->table[mi->vftblindex];
1923                                                 goto foundmethod;
1924                                                 }
1925                                         }
1926                                 sc = sc->super;
1927                                 }
1928                          foundmethod: ;
1929                         }
1930                 }
1931
1932         for (j = 0; j < ic->interfacescount; j++) 
1933                 class_addinterface(c, ic->interfaces[j]);
1934 }
1935
1936
1937 /******************* Function: class_new_array *********************************
1938
1939     This function is called by class_new to setup an array class.
1940
1941 *******************************************************************************/
1942
1943 void class_new_array(classinfo *c)
1944 {
1945         classinfo *comp = NULL;
1946         methodinfo *clone;
1947         int namelen;
1948
1949         /* XXX remove */ /* dolog("class_new_array: %s",c->name->text); */
1950
1951         /* Array classes are not loaded from classfiles. */
1952         list_remove(&unloadedclasses, c);
1953
1954         /* Check array class name */
1955         namelen = c->name->blength;
1956         if (namelen < 2 || c->name->text[0] != '[')
1957                 panic("Invalid array class name");
1958
1959         /* Check the component type */
1960         switch (c->name->text[1]) {
1961           case '[':
1962                   /* c is an array of arrays. We have to create the component class. */
1963                   comp = class_new(utf_new(c->name->text + 1,namelen - 1));
1964                   break;
1965
1966           case 'L':
1967                   /* c is an array of objects. */
1968                   if (namelen < 4 || c->name->text[namelen - 1] != ';')
1969                           panic("Invalid array class name");
1970                   comp = class_new(utf_new(c->name->text + 2,namelen - 3));
1971                   break;
1972         }
1973
1974         /* Setup the array class */
1975         c->super = class_java_lang_Object;
1976         c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
1977
1978     c->interfacescount = 2;
1979     c->interfaces = MNEW(classinfo*,2); /* XXX use GC? */
1980     c->interfaces[0] = class_java_lang_Cloneable;
1981     c->interfaces[1] = class_java_io_Serializable;
1982
1983         c->methodscount = 1;
1984         c->methods = MNEW (methodinfo, c->methodscount); /* XXX use GC? */
1985
1986         clone = c->methods;
1987         memset(clone, 0, sizeof(methodinfo));
1988         clone->flags = ACC_PUBLIC; /* XXX protected? */
1989         clone->name = utf_new_char("clone");
1990         clone->descriptor = utf_new_char("()Ljava/lang/Object;");
1991         clone->class = c;
1992         clone->stubroutine = createnativestub((functionptr) &builtin_clone_array, clone);
1993         clone->monoPoly = MONO; /* XXX should be poly? */
1994
1995         /* XXX: field: length? */
1996
1997         /* The array class has to be linked */
1998         list_addlast(&unlinkedclasses,c);
1999         
2000         /*
2001      * Array classes which are created after the other classes have been
2002      * loaded and linked are linked explicitely.
2003      */
2004         c->loaded=true;
2005      
2006         if (loader_inited)
2007                 loader_load(c->name); /* XXX handle errors */
2008 }
2009
2010
2011 /****************** Function: class_link_array *********************************
2012
2013     This function is called by class_link to create the
2014     arraydescriptor for an array class.
2015
2016     This function returns NULL if the array cannot be linked because
2017     the component type has not been linked yet.
2018
2019 *******************************************************************************/
2020
2021 static arraydescriptor *class_link_array(classinfo *c)
2022 {
2023         classinfo *comp = NULL;
2024         int namelen = c->name->blength;
2025         arraydescriptor *desc;
2026         vftbl *compvftbl;
2027
2028         /* Check the component type */
2029         switch (c->name->text[1]) {
2030           case '[':
2031                   /* c is an array of arrays. */
2032                   comp = class_get(utf_new(c->name->text + 1,namelen - 1));
2033                   if (!comp) panic("Could not find component array class.");
2034                   break;
2035
2036           case 'L':
2037                   /* c is an array of objects. */
2038                   comp = class_get(utf_new(c->name->text + 2,namelen - 3));
2039                   if (!comp) panic("Could not find component class.");
2040                   break;
2041         }
2042
2043         /* If the component type has not been linked return NULL */
2044         if (comp && !comp->linked)
2045                 return NULL;
2046
2047         /* Allocate the arraydescriptor */
2048         desc = NEW(arraydescriptor);
2049
2050         if (comp) {
2051                 /* c is an array of references */
2052                 desc->arraytype = ARRAYTYPE_OBJECT;
2053                 desc->componentsize = sizeof(void*);
2054                 desc->dataoffset = OFFSET(java_objectarray,data);
2055                 
2056                 compvftbl = comp->vftbl;
2057                 if (!compvftbl)
2058                         panic("Component class has no vftbl");
2059                 desc->componentvftbl = compvftbl;
2060                 
2061                 if (compvftbl->arraydesc) {
2062                         desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
2063                         if (compvftbl->arraydesc->dimension >= 255)
2064                                 panic("Creating array of dimension >255");
2065                         desc->dimension = compvftbl->arraydesc->dimension + 1;
2066                         desc->elementtype = compvftbl->arraydesc->elementtype;
2067                 }
2068                 else {
2069                         desc->elementvftbl = compvftbl;
2070                         desc->dimension = 1;
2071                         desc->elementtype = ARRAYTYPE_OBJECT;
2072                 }
2073
2074         } else {
2075                 /* c is an array of a primitive type */
2076                 switch (c->name->text[1]) {
2077                 case 'Z': desc->arraytype = ARRAYTYPE_BOOLEAN;
2078                         desc->dataoffset = OFFSET(java_booleanarray,data);
2079                         desc->componentsize = sizeof(u1);
2080                         break;
2081
2082                 case 'B': desc->arraytype = ARRAYTYPE_BYTE;
2083                         desc->dataoffset = OFFSET(java_bytearray,data);
2084                         desc->componentsize = sizeof(u1);
2085                         break;
2086
2087                 case 'C': desc->arraytype = ARRAYTYPE_CHAR;
2088                         desc->dataoffset = OFFSET(java_chararray,data);
2089                         desc->componentsize = sizeof(u2);
2090                         break;
2091
2092                 case 'D': desc->arraytype = ARRAYTYPE_DOUBLE;
2093                         desc->dataoffset = OFFSET(java_doublearray,data);
2094                         desc->componentsize = sizeof(double);
2095                         break;
2096
2097                 case 'F': desc->arraytype = ARRAYTYPE_FLOAT;
2098                         desc->dataoffset = OFFSET(java_floatarray,data);
2099                         desc->componentsize = sizeof(float);
2100                         break;
2101
2102                 case 'I': desc->arraytype = ARRAYTYPE_INT;
2103                         desc->dataoffset = OFFSET(java_intarray,data);
2104                         desc->componentsize = sizeof(s4);
2105                         break;
2106
2107                 case 'J': desc->arraytype = ARRAYTYPE_LONG;
2108                         desc->dataoffset = OFFSET(java_longarray,data);
2109                         desc->componentsize = sizeof(s8);
2110                         break;
2111
2112                 case 'S': desc->arraytype = ARRAYTYPE_SHORT;
2113                         desc->dataoffset = OFFSET(java_shortarray,data);
2114                         desc->componentsize = sizeof(s2);
2115                         break;
2116
2117                 default:
2118                         panic("Invalid array class name");
2119                 }
2120                 
2121                 desc->componentvftbl = NULL;
2122                 desc->elementvftbl = NULL;
2123                 desc->dimension = 1;
2124                 desc->elementtype = desc->arraytype;
2125         }
2126
2127         return desc;
2128 }
2129
2130
2131 /********************** Function: class_link ***********************************
2132
2133         Tries to link a class. The super class and every implemented interface must
2134         already have been linked. The function calculates the length in bytes that
2135         an instance of this class requires as well as the VTBL for methods and
2136         interface methods.
2137         
2138         If the class can be linked, it is removed from the list 'unlinkedclasses'
2139         and added to 'linkedclasses'. Otherwise, it is moved to the end of
2140         'unlinkedclasses'.
2141
2142         Attention: If cyclical class definitions are encountered, the program gets
2143         into an infinite loop (we'll have to work that out)
2144
2145 *******************************************************************************/
2146
2147 void class_link(classinfo *c)
2148 {
2149         s4 supervftbllength;          /* vftbllegnth of super class               */
2150         s4 vftbllength;               /* vftbllength of current class             */
2151         s4 interfacetablelength;      /* interface table length                   */
2152         classinfo *super = c->super;  /* super class                              */
2153         classinfo *ic, *c2;           /* intermediate class variables             */
2154         vftbl *v;                     /* vftbl of current class                   */
2155         s4 i;                         /* interface/method/field counter           */
2156         arraydescriptor *arraydesc = NULL;  /* descriptor for array classes       */
2157
2158
2159         /*  check if all superclasses are already linked, if not put c at end of
2160             unlinked list and return. Additionally initialize class fields.       */
2161
2162         /*  check interfaces */
2163
2164         for (i = 0; i < c->interfacescount; i++) {
2165                 ic = c->interfaces[i];
2166                 if (!ic->linked) {
2167                         list_remove(&unlinkedclasses, c);
2168                         list_addlast(&unlinkedclasses, c);
2169                         return; 
2170                 }
2171                 if ((ic->flags & ACC_INTERFACE) == 0) {
2172                         dolog("Specified interface is not declared as interface:");
2173                         log_utf(ic->name);
2174                         dolog("in");
2175                         log_utf(c->name);
2176                         panic("Specified interface is not declared as interface");
2177                 }
2178         }
2179         
2180         /*  check super class */
2181
2182         if (super == NULL) {          /* class java.long.Object */
2183                 c->index = 0;
2184         c->classUsed = USED;     /* Object class is always used CO-RT*/
2185                 c->impldBy = NULL;
2186                 c->instancesize = sizeof(java_objectheader);
2187                 
2188                 vftbllength = supervftbllength = 0;
2189
2190                 c->finalizer = NULL;
2191
2192         } else {
2193                 if (!super->linked) {
2194                         list_remove(&unlinkedclasses, c);
2195                         list_addlast(&unlinkedclasses, c);
2196                         return; 
2197                 }
2198
2199                 if ((super->flags & ACC_INTERFACE) != 0)
2200                         panic("Interface specified as super class");
2201
2202                 /* handle array classes */
2203                 /* The component class must have been linked already. */
2204                 if (c->name->text[0] == '[')
2205                         if ((arraydesc = class_link_array(c)) == NULL) {
2206                                 list_remove(&unlinkedclasses, c);
2207                                 list_addlast(&unlinkedclasses, c);
2208                                 return; 
2209                         }
2210
2211                 /* Don't allow extending final classes */
2212                 if ((super->flags & ACC_FINAL) != 0)
2213                         panic("Trying to extend final class");
2214                 
2215                 if (c->flags & ACC_INTERFACE)
2216                         c->index = interfaceindex++;
2217                 else
2218                         c->index = super->index + 1;
2219                 
2220                 c->instancesize = super->instancesize;
2221                 
2222                 vftbllength = supervftbllength = super->vftbl->vftbllength;
2223                 
2224                 c->finalizer = super->finalizer;
2225         }
2226
2227
2228         if (linkverbose) {
2229                 char logtext[MAXLOGTEXT];
2230                 sprintf(logtext, "Linking Class: ");
2231                 utf_sprint(logtext + strlen(logtext), c->name );
2232                 log_text(logtext);
2233         }
2234
2235         /* compute vftbl length */
2236
2237         for (i = 0; i < c->methodscount; i++) {
2238                 methodinfo *m = &(c->methods[i]);
2239                         
2240                 if (!(m->flags & ACC_STATIC)) { /* is instance method */
2241                         classinfo *sc = super;
2242                         while (sc) {
2243                                 int j;
2244                                 for (j = 0; j < sc->methodscount; j++) {
2245                                         if (method_canoverwrite(m, &(sc->methods[j]))) {
2246                                                 if ((sc->methods[j].flags & ACC_FINAL) != 0)
2247                                                         panic("Trying to overwrite final method");
2248                                                 m->vftblindex = sc->methods[j].vftblindex;
2249                                                 goto foundvftblindex;
2250                                         }
2251                                 }
2252                                 sc = sc->super;
2253                         }
2254                         m->vftblindex = (vftbllength++);
2255                 foundvftblindex: ;
2256                 }
2257         }       
2258         
2259 #ifdef STATISTICS
2260         count_vftbl_len += sizeof(vftbl) + (sizeof(methodptr) * (vftbllength - 1));
2261 #endif
2262
2263         /* compute interfacetable length */
2264
2265         interfacetablelength = 0;
2266         c2 = c;
2267         while (c2) {
2268                 for (i = 0; i < c2->interfacescount; i++) {
2269                         s4 h = class_highestinterface (c2->interfaces[i]) + 1;
2270                         if (h > interfacetablelength)
2271                                 interfacetablelength = h;
2272                 }
2273                 c2 = c2->super;
2274         }
2275
2276         /* allocate virtual function table */
2277
2278         v = (vftbl*) mem_alloc(sizeof(vftbl) + sizeof(methodptr) *
2279                                                    (vftbllength - 1) + sizeof(methodptr*) *
2280                                                    (interfacetablelength - (interfacetablelength > 0)));
2281         v = (vftbl*) (((methodptr*) v) + (interfacetablelength - 1) *
2282                                   (interfacetablelength > 1));
2283         c->header.vftbl = c->vftbl = v;
2284         v->class = c;
2285         v->vftbllength = vftbllength;
2286         v->interfacetablelength = interfacetablelength;
2287         v->arraydesc = arraydesc;
2288
2289         /* store interface index in vftbl */
2290         if (c->flags & ACC_INTERFACE)
2291                 v->baseval = -(c->index);
2292
2293         /* copy virtual function table of super class */
2294
2295         for (i = 0; i < supervftbllength; i++) 
2296                 v->table[i] = super->vftbl->table[i];
2297         
2298         /* add method stubs into virtual function table */
2299
2300         for (i = 0; i < c->methodscount; i++) {
2301                 methodinfo *m = &(c->methods[i]);
2302                 if (!(m->flags & ACC_STATIC)) {
2303                         v->table[m->vftblindex] = m->stubroutine;
2304                 }
2305         }
2306
2307         /* compute instance size and offset of each field */
2308         
2309         for (i = 0; i < c->fieldscount; i++) {
2310                 s4 dsize;
2311                 fieldinfo *f = &(c->fields[i]);
2312                 
2313                 if (!(f->flags & ACC_STATIC) ) {
2314                         dsize = desc_typesize(f->descriptor);
2315                         c->instancesize = ALIGN(c->instancesize, dsize);
2316                         f->offset = c->instancesize;
2317                         c->instancesize += dsize;
2318                 }
2319         }
2320
2321         /* initialize interfacetable and interfacevftbllength */
2322         
2323         v->interfacevftbllength = MNEW(s4, interfacetablelength);
2324
2325 #ifdef STATISTICS
2326         count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
2327 #endif
2328
2329         for (i = 0; i < interfacetablelength; i++) {
2330                 v->interfacevftbllength[i] = 0;
2331                 v->interfacetable[-i] = NULL;
2332         }
2333         
2334         /* add interfaces */
2335         
2336         for (c2 = c; c2 != NULL; c2 = c2->super)
2337                 for (i = 0; i < c2->interfacescount; i++) {
2338                         class_addinterface(c, c2->interfaces[i]);
2339                 }
2340
2341         /* add finalizer method (not for java.lang.Object) */
2342
2343         if (super != NULL) {
2344                 methodinfo *fi;
2345                 static utf *finame = NULL;
2346                 static utf *fidesc = NULL;
2347
2348                 if (finame == NULL)
2349                         finame = utf_finalize;
2350                 if (fidesc == NULL)
2351                         fidesc = utf_fidesc;
2352
2353                 fi = class_findmethod(c, finame, fidesc);
2354                 if (fi != NULL) {
2355                         if (!(fi->flags & ACC_STATIC)) {
2356                                 c->finalizer = fi;
2357                         }
2358                 }
2359         }
2360
2361         /* final tasks */
2362
2363         c->linked = true;       
2364
2365         list_remove(&unlinkedclasses, c);
2366         list_addlast(&linkedclasses, c);
2367 }
2368
2369
2370 /******************* Function: class_freepool **********************************
2371
2372         Frees all resources used by this classes Constant Pool.
2373
2374 *******************************************************************************/
2375
2376 static void class_freecpool (classinfo *c)
2377 {
2378         u4 idx;
2379         u4 tag;
2380         voidptr info;
2381         
2382         for (idx=0; idx < c->cpcount; idx++) {
2383                 tag = c->cptags[idx];
2384                 info = c->cpinfos[idx];
2385                 
2386                 if (info != NULL) {
2387                         switch (tag) {
2388                         case CONSTANT_Fieldref:
2389                         case CONSTANT_Methodref:
2390                         case CONSTANT_InterfaceMethodref:
2391                                 FREE (info, constant_FMIref);
2392                                 break;
2393                         case CONSTANT_Integer:
2394                                 FREE (info, constant_integer);
2395                                 break;
2396                         case CONSTANT_Float:
2397                                 FREE (info, constant_float);
2398                                 break;
2399                         case CONSTANT_Long:
2400                                 FREE (info, constant_long);
2401                                 break;
2402                         case CONSTANT_Double:
2403                                 FREE (info, constant_double);
2404                                 break;
2405                         case CONSTANT_NameAndType:
2406                                 FREE (info, constant_nameandtype);
2407                                 break;
2408                         }
2409                         }
2410                 }
2411
2412         MFREE (c -> cptags,  u1, c -> cpcount);
2413         MFREE (c -> cpinfos, voidptr, c -> cpcount);
2414 }
2415
2416
2417 /*********************** Function: class_free **********************************
2418
2419         Frees all resources used by the class.
2420
2421 *******************************************************************************/
2422
2423 static void class_free(classinfo *c)
2424 {
2425         s4 i;
2426         vftbl *v;
2427                 
2428         class_freecpool(c);
2429
2430         MFREE(c->interfaces, classinfo*, c->interfacescount);
2431
2432         for (i = 0; i < c->fieldscount; i++)
2433                 field_free(&(c->fields[i]));
2434         
2435         for (i = 0; i < c->methodscount; i++)
2436                 method_free(&(c->methods[i]));
2437         MFREE(c->methods, methodinfo, c->methodscount);
2438
2439         if ((v = c->vftbl) != NULL) {
2440                 if (v->arraydesc)
2441                         mem_free(v->arraydesc,sizeof(arraydescriptor));
2442                 
2443                 for (i = 0; i < v->interfacetablelength; i++) {
2444                         MFREE(v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
2445                 }
2446                 MFREE(v->interfacevftbllength, s4, v->interfacetablelength);
2447
2448                 i = sizeof(vftbl) + sizeof(methodptr) * (v->vftbllength - 1) +
2449                     sizeof(methodptr*) * (v->interfacetablelength -
2450                                          (v->interfacetablelength > 0));
2451                 v = (vftbl*) (((methodptr*) v) - (v->interfacetablelength - 1) *
2452                                              (v->interfacetablelength > 1));
2453                 mem_free(v, i);
2454         }
2455
2456         if (c->innerclasscount)
2457                 MFREE(c->innerclass, innerclassinfo, c->innerclasscount);
2458
2459         /*      if (c->classvftbl)
2460                 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
2461         
2462         GCFREE(c);
2463 }
2464
2465
2466 /************************* Function: class_findfield ***************************
2467         
2468         Searches a 'classinfo' structure for a field having the given name and
2469         type.
2470
2471 *******************************************************************************/
2472
2473 fieldinfo *class_findfield(classinfo *c, utf *name, utf *desc)
2474 {
2475         s4 i;
2476         
2477         for (i = 0; i < c->fieldscount; i++) { 
2478                 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) 
2479                         return &(c->fields[i]);                                                         
2480     }
2481
2482         panic("Can not find field given in CONSTANT_Fieldref");
2483
2484         /* keep compiler happy */
2485         return NULL;
2486 }
2487
2488
2489 /************************* Function: class_findmethod **************************
2490         
2491         Searches a 'classinfo' structure for a method having the given name and
2492         type and returns the index in the class info structure.
2493         If type is NULL, it is ignored.
2494
2495 *******************************************************************************/
2496
2497 s4 class_findmethodIndex(classinfo *c, utf *name, utf *desc)
2498 {
2499         s4 i;
2500 #if defined(JOWENN_DEBUG1) || defined(JOWENN_DEBUG2)
2501         char *buffer;                   
2502         int buffer_len, pos;
2503 #endif
2504 #ifdef JOWENN_DEBUG1
2505
2506         buffer_len = 
2507                 utf_strlen(name) + utf_strlen(desc) + utf_strlen(c->name) + 64;
2508         
2509         buffer = MNEW(char, buffer_len);
2510
2511         strcpy(buffer, "class_findmethod: method:");
2512         utf_sprint(buffer + strlen(buffer), name);
2513         strcpy(buffer + strlen(buffer), ", desc: ");
2514         utf_sprint(buffer + strlen(buffer), desc);
2515         strcpy(buffer + strlen(buffer), ", classname: ");
2516         utf_sprint(buffer + strlen(buffer), c->name);
2517         
2518         log_text(buffer);       
2519
2520         MFREE(buffer, char, buffer_len);
2521 #endif  
2522         for (i = 0; i < c->methodscount; i++) {
2523 #ifdef JOWENN_DEBUG2
2524                 buffer_len = 
2525                         utf_strlen(c->methods[i].name) + utf_strlen(c->methods[i].descriptor)+ 64;
2526         
2527                 buffer = MNEW(char, buffer_len);
2528
2529                 strcpy(buffer, "class_findmethod: comparing to method:");
2530                 utf_sprint(buffer + strlen(buffer), c->methods[i].name);
2531                 strcpy(buffer + strlen(buffer), ", desc: ");
2532                 utf_sprint(buffer + strlen(buffer), c->methods[i].descriptor);
2533         
2534                 log_text(buffer);       
2535
2536                 MFREE(buffer, char, buffer_len);
2537 #endif  
2538                 
2539                 
2540                 if ((c->methods[i].name == name) && ((desc == NULL) ||
2541                                                                                          (c->methods[i].descriptor == desc))) {
2542                         return i;
2543                 }
2544         }
2545
2546 #ifdef JOWENN_DEBUG2    
2547         class_showconstantpool(c);
2548         log_text("class_findmethod: returning NULL");
2549 #endif
2550
2551         return -1;
2552 }
2553
2554
2555 /************************* Function: class_findmethod **************************
2556         
2557         Searches a 'classinfo' structure for a method having the given name and
2558         type.
2559         If type is NULL, it is ignored.
2560
2561 *******************************************************************************/
2562
2563 methodinfo *class_findmethod(classinfo *c, utf *name, utf *desc)
2564 {
2565 #if 0
2566         s4 i;
2567 #if defined(JOWENN_DEBUG1) || defined(JOWENN_DEBUG2)
2568         char *buffer;                   
2569         int buffer_len, pos;
2570 #endif
2571 #ifdef JOWENN_DEBUG1
2572
2573         buffer_len = 
2574                 utf_strlen(name) + utf_strlen(desc) + utf_strlen(c->name) + 64;
2575         
2576         buffer = MNEW(char, buffer_len);
2577
2578         strcpy(buffer, "class_findmethod: method:");
2579         utf_sprint(buffer + strlen(buffer), name);
2580         strcpy(buffer + strlen(buffer), ", desc: ");
2581         utf_sprint(buffer + strlen(buffer), desc);
2582         strcpy(buffer + strlen(buffer), ", classname: ");
2583         utf_sprint(buffer + strlen(buffer), c->name);
2584         
2585         log_text(buffer);       
2586
2587         MFREE(buffer, char, buffer_len);
2588 #endif  
2589         for (i = 0; i < c->methodscount; i++) {
2590 #ifdef JOWENN_DEBUG2
2591                 buffer_len = 
2592                         utf_strlen(c->methods[i].name) + utf_strlen(c->methods[i].descriptor)+ 64;
2593         
2594                 buffer = MNEW(char, buffer_len);
2595
2596                 strcpy(buffer, "class_findmethod: comparing to method:");
2597                 utf_sprint(buffer + strlen(buffer), c->methods[i].name);
2598                 strcpy(buffer + strlen(buffer), ", desc: ");
2599                 utf_sprint(buffer + strlen(buffer), c->methods[i].descriptor);
2600         
2601                 log_text(buffer);       
2602
2603                 MFREE(buffer, char, buffer_len);
2604 #endif  
2605                 
2606                 if ((c->methods[i].name == name) && ((desc == NULL) ||
2607                                                                                          (c->methods[i].descriptor == desc))) {
2608                         return &(c->methods[i]);
2609                 }
2610         }
2611 #ifdef JOWENN_DEBUG2    
2612         class_showconstantpool(c);
2613         log_text("class_findmethod: returning NULL");
2614 #endif
2615         return NULL;
2616 #endif
2617
2618         s4 idx=class_findmethodIndex(c, name, desc);
2619 /*      if (idx==-1) log_text("class_findmethod: method not found");*/
2620         if (idx == -1) return NULL;
2621
2622         return &(c->methods[idx]);
2623 }
2624
2625
2626 /*********************** Function: class_fetchmethod **************************
2627         
2628     like class_findmethod, but aborts with an error if the method is not found
2629
2630 *******************************************************************************/
2631
2632 methodinfo *class_fetchmethod(classinfo *c, utf *name, utf *desc)
2633 {
2634         methodinfo *mi;
2635         mi = class_findmethod(c, name, desc);
2636
2637         if (!mi) {
2638                 log_plain("Class: "); if (c) log_plain_utf(c->name); log_nl();
2639                 log_plain("Method: "); if (name) log_plain_utf(name); log_nl();
2640                 log_plain("Descriptor: "); if (desc) log_plain_utf(desc); log_nl();
2641                 panic("Method not found");
2642         }
2643
2644         return mi;
2645 }
2646
2647
2648 /************************* Function: class_findmethod_approx ******************
2649         
2650         like class_findmethod but ignores the return value when comparing the
2651         descriptor.
2652
2653 *******************************************************************************/
2654
2655 methodinfo *class_findmethod_approx(classinfo *c, utf *name, utf *desc)
2656 {
2657         s4 i;
2658
2659         for (i = 0; i < c->methodscount; i++) {
2660                 if (c->methods[i].name == name) {
2661                         utf *meth_descr = c->methods[i].descriptor;
2662                         
2663                         if (desc == NULL) 
2664                                 /* ignore type */
2665                                 return &(c->methods[i]);
2666
2667                         if (desc->blength <= meth_descr->blength) {
2668                                 /* current position in utf text   */
2669                                 char *desc_utf_ptr = desc->text;      
2670                                 char *meth_utf_ptr = meth_descr->text;                                    
2671                                 /* points behind utf strings */
2672                                 char *desc_end = utf_end(desc);         
2673                                 char *meth_end = utf_end(meth_descr);   
2674                                 char ch;
2675
2676                                 /* compare argument types */
2677                                 while (desc_utf_ptr < desc_end && meth_utf_ptr < meth_end) {
2678
2679                                         if ((ch = *desc_utf_ptr++) != (*meth_utf_ptr++))
2680                                                 break; /* no match */
2681
2682                                         if (ch == ')')
2683                                                 return &(c->methods[i]);   /* all parameter types equal */
2684                                 }
2685                         }
2686                 }
2687         }
2688
2689         return NULL;
2690 }
2691
2692
2693 /***************** Function: class_resolvemethod_approx ***********************
2694         
2695         Searches a class and every super class for a method (without paying
2696         attention to the return value)
2697
2698 *******************************************************************************/
2699
2700 methodinfo *class_resolvemethod_approx(classinfo *c, utf *name, utf *desc)
2701 {
2702         while (c) {
2703                 /* search for method (ignore returntype) */
2704                 methodinfo *m = class_findmethod_approx(c, name, desc);
2705                 /* method found */
2706                 if (m) return m;
2707                 /* search superclass */
2708                 c = c->super;
2709         }
2710
2711         return NULL;
2712 }
2713
2714
2715 /************************* Function: class_resolvemethod ***********************
2716         
2717         Searches a class and every super class for a method.
2718
2719 *******************************************************************************/
2720
2721 methodinfo *class_resolvemethod(classinfo *c, utf *name, utf *desc)
2722 {
2723         while (c) {
2724                 methodinfo *m = class_findmethod(c, name, desc);
2725                 if (m) return m;
2726                 /* search superclass */
2727                 c = c->super;
2728         }
2729
2730         return NULL;
2731 }
2732
2733
2734 /************************* Function: class_issubclass **************************
2735
2736         Checks if sub is a descendant of super.
2737         
2738 *******************************************************************************/
2739
2740 bool class_issubclass(classinfo *sub, classinfo *super)
2741 {
2742         for (;;) {
2743                 if (!sub) return false;
2744                 if (sub == super) return true;
2745                 sub = sub->super;
2746         }
2747 }
2748
2749
2750 /****************** Initialization function for classes ******************
2751
2752         In Java, every class can have a static initialization function. This
2753         function has to be called BEFORE calling other methods or accessing static
2754         variables.
2755
2756 *******************************************************************************/
2757
2758 void class_init(classinfo *c)
2759 {
2760         methodinfo *m;
2761         s4 i;
2762 #ifdef USE_THREADS
2763         int b;
2764 #endif
2765
2766         if (!makeinitializations)
2767                 return;
2768         if (c->initialized)
2769                 return;
2770
2771         c->initialized = true;
2772
2773 #ifdef STATISTICS
2774         count_class_inits++;
2775 #endif
2776
2777         /* initialize super class */
2778         if (c->super) {
2779                 if (initverbose) {
2780                         char logtext[MAXLOGTEXT];
2781                         sprintf(logtext, "Initialize super class ");
2782                         utf_sprint(logtext + strlen(logtext), c->super->name);
2783                         sprintf(logtext + strlen(logtext), " from ");
2784                         utf_sprint(logtext + strlen(logtext), c->name);
2785                         log_text(logtext);
2786                 }
2787                 class_init(c->super);
2788         }
2789
2790         /* initialize interface classes */
2791         for (i = 0; i < c->interfacescount; i++) {
2792                 if (initverbose) {
2793                         char logtext[MAXLOGTEXT];
2794                         sprintf(logtext, "Initialize interface class ");
2795                         utf_sprint(logtext + strlen(logtext), c->interfaces[i]->name);
2796                         sprintf(logtext + strlen(logtext), " from ");
2797                         utf_sprint(logtext + strlen(logtext), c->name);
2798                         log_text(logtext);
2799                 }
2800                 class_init(c->interfaces[i]);  /* real */
2801         }
2802
2803         m = class_findmethod(c, utf_clinit, utf_fidesc);
2804         if (!m) {
2805                 if (initverbose) {
2806                         char logtext[MAXLOGTEXT];
2807                         sprintf(logtext, "Class ");
2808                         utf_sprint(logtext + strlen(logtext), c->name);
2809                         sprintf(logtext + strlen(logtext), " has no initializer");
2810                         log_text(logtext);
2811                 }
2812                 /*              goto callinitialize;*/
2813                 return;
2814         }
2815
2816         if (!(m->flags & ACC_STATIC))
2817                 panic("Class initializer is not static!");
2818
2819         if (initverbose) {
2820                 char logtext[MAXLOGTEXT];
2821                 sprintf(logtext, "Starting initializer for class: ");
2822                 utf_sprint(logtext + strlen(logtext), c->name);
2823                 log_text(logtext);
2824         }
2825
2826 #ifdef USE_THREADS
2827         b = blockInts;
2828         blockInts = 0;
2829 #endif
2830
2831         /* now call the initializer */
2832         asm_calljavafunction(m, NULL, NULL, NULL, NULL);
2833
2834 #ifdef USE_THREADS
2835         assert(blockInts == 0);
2836         blockInts = b;
2837 #endif
2838
2839         /* we have to throw an exception */
2840         if (*exceptionptr) {
2841                 printf("Exception in thread \"main\" java.lang.ExceptionInInitializerError\n");
2842                 printf("Caused by: ");
2843                 utf_display((*exceptionptr)->vftbl->class->name);
2844                 printf("\n");
2845                 fflush(stdout);
2846                 exit(1);
2847         }
2848
2849         if (initverbose) {
2850                 char logtext[MAXLOGTEXT];
2851                 sprintf(logtext, "Finished initializer for class: ");
2852                 utf_sprint(logtext + strlen(logtext), c->name);
2853                 log_text(logtext);
2854         }
2855
2856         if (c->name == utf_systemclass) {
2857                 /* class java.lang.System requires explicit initialization */
2858
2859                 if (initverbose)
2860                         printf("#### Initializing class System");
2861
2862                 /* find initializing method */
2863                 m = class_findmethod(c,
2864                                                          utf_initsystemclass,
2865                                                          utf_fidesc);
2866
2867                 if (!m) {
2868                         /* no method found */
2869                         /* printf("initializeSystemClass failed"); */
2870                         return;
2871                 }
2872
2873 #ifdef USE_THREADS
2874                 b = blockInts;
2875                 blockInts = 0;
2876 #endif
2877
2878                 asm_calljavafunction(m, NULL, NULL, NULL, NULL);
2879
2880 #ifdef USE_THREADS
2881                 assert(blockInts == 0);
2882                 blockInts = b;
2883 #endif
2884
2885                 if (*exceptionptr) {
2886                         printf("#### initializeSystemClass has thrown: ");
2887                         utf_display((*exceptionptr)->vftbl->class->name);
2888                         printf("\n");
2889                         fflush(stdout);
2890                 }
2891         }
2892 }
2893
2894
2895 /********* Function: find_class_method_constant *********/
2896
2897 int find_class_method_constant (classinfo *c, utf * c1, utf* m1, utf* d1)  
2898 {
2899         u4 i;
2900         voidptr e;
2901
2902         for (i=0; i<c->cpcount; i++) {
2903                 
2904                 e = c -> cpinfos [i];
2905                 if (e) {
2906                         
2907                         switch (c -> cptags [i]) {
2908                         case CONSTANT_Methodref:
2909                                 {
2910                                         constant_FMIref *fmi = e;
2911                                         if (       (fmi->class->name == c1)  
2912                                                            && (fmi->name == m1)
2913                                                            && (fmi->descriptor == d1)) {
2914                                         
2915                                                 return i;
2916                                         }
2917                                 }
2918                                 break;
2919
2920                         case CONSTANT_InterfaceMethodref:
2921                                 {
2922                                         constant_FMIref *fmi = e;
2923                                         if (       (fmi->class->name == c1)  
2924                                                            && (fmi->name == m1)
2925                                                            && (fmi->descriptor == d1)) {
2926
2927                                                 return i;
2928                                         }
2929                                 }
2930                                 break;
2931                         }
2932                 }
2933         }
2934
2935         return -1;
2936 }
2937
2938
2939 void class_showconstanti(classinfo *c, int ii) 
2940 {
2941         u4 i = ii;
2942         voidptr e;
2943                 
2944         e = c->cpinfos [i];
2945         printf ("#%d:  ", (int) i);
2946         if (e) {
2947                 switch (c->cptags [i]) {
2948                 case CONSTANT_Class:
2949                         printf("Classreference -> ");
2950                         utf_display(((classinfo*)e)->name);
2951                         break;
2952                                 
2953                 case CONSTANT_Fieldref:
2954                         printf("Fieldref -> "); goto displayFMIi;
2955                 case CONSTANT_Methodref:
2956                         printf("Methodref -> "); goto displayFMIi;
2957                 case CONSTANT_InterfaceMethodref:
2958                         printf("InterfaceMethod -> "); goto displayFMIi;
2959                 displayFMIi:
2960                         {
2961                                 constant_FMIref *fmi = e;
2962                                 utf_display(fmi->class->name);
2963                                 printf(".");
2964                                 utf_display(fmi->name);
2965                                 printf(" ");
2966                                 utf_display(fmi->descriptor);
2967                         }
2968                         break;
2969
2970                 case CONSTANT_String:
2971                         printf("String -> ");
2972                         utf_display(e);
2973                         break;
2974                 case CONSTANT_Integer:
2975                         printf("Integer -> %d", (int) (((constant_integer*)e)->value));
2976                         break;
2977                 case CONSTANT_Float:
2978                         printf("Float -> %f", ((constant_float*)e)->value);
2979                         break;
2980                 case CONSTANT_Double:
2981                         printf("Double -> %f", ((constant_double*)e)->value);
2982                         break;
2983                 case CONSTANT_Long:
2984                         {
2985                                 u8 v = ((constant_long*)e)->value;
2986 #if U8_AVAILABLE
2987                                 printf("Long -> %ld", (long int) v);
2988 #else
2989                                 printf("Long -> HI: %ld, LO: %ld\n", 
2990                                             (long int) v.high, (long int) v.low);
2991 #endif 
2992                         }
2993                         break;
2994                 case CONSTANT_NameAndType:
2995                         { 
2996                                 constant_nameandtype *cnt = e;
2997                                 printf("NameAndType: ");
2998                                 utf_display(cnt->name);
2999                                 printf(" ");
3000                                 utf_display(cnt->descriptor);
3001                         }
3002                         break;
3003                 case CONSTANT_Utf8:
3004                         printf("Utf8 -> ");
3005                         utf_display(e);
3006                         break;
3007                 default: 
3008                         panic("Invalid type of ConstantPool-Entry");
3009                 }
3010         }
3011         printf("\n");
3012 }
3013
3014
3015 void class_showconstantpool (classinfo *c) 
3016 {
3017         u4 i;
3018         voidptr e;
3019
3020         printf ("---- dump of constant pool ----\n");
3021
3022         for (i=0; i<c->cpcount; i++) {
3023                 printf ("#%d:  ", (int) i);
3024                 
3025                 e = c -> cpinfos [i];
3026                 if (e) {
3027                         
3028                         switch (c -> cptags [i]) {
3029                         case CONSTANT_Class:
3030                                 printf ("Classreference -> ");
3031                                 utf_display ( ((classinfo*)e) -> name );
3032                                 break;
3033                                 
3034                         case CONSTANT_Fieldref:
3035                                 printf ("Fieldref -> "); goto displayFMI;
3036                         case CONSTANT_Methodref:
3037                                 printf ("Methodref -> "); goto displayFMI;
3038                         case CONSTANT_InterfaceMethodref:
3039                                 printf ("InterfaceMethod -> "); goto displayFMI;
3040                         displayFMI:
3041                                 {
3042                                         constant_FMIref *fmi = e;
3043                                         utf_display ( fmi->class->name );
3044                                         printf (".");
3045                                         utf_display ( fmi->name);
3046                                         printf (" ");
3047                                         utf_display ( fmi->descriptor );
3048                                 }
3049                                 break;
3050
3051                         case CONSTANT_String:
3052                                 printf ("String -> ");
3053                                 utf_display (e);
3054                                 break;
3055                         case CONSTANT_Integer:
3056                                 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
3057                                 break;
3058                         case CONSTANT_Float:
3059                                 printf ("Float -> %f", ((constant_float*)e) -> value);
3060                                 break;
3061                         case CONSTANT_Double:
3062                                 printf ("Double -> %f", ((constant_double*)e) -> value);
3063                                 break;
3064                         case CONSTANT_Long:
3065                                 {
3066                                         u8 v = ((constant_long*)e) -> value;
3067 #if U8_AVAILABLE
3068                                         printf ("Long -> %ld", (long int) v);
3069 #else
3070                                         printf ("Long -> HI: %ld, LO: %ld\n", 
3071                                                         (long int) v.high, (long int) v.low);
3072 #endif 
3073                                 }
3074                                 break;
3075                         case CONSTANT_NameAndType:
3076                                 {
3077                                         constant_nameandtype *cnt = e;
3078                                         printf ("NameAndType: ");
3079                                         utf_display (cnt->name);
3080                                         printf (" ");
3081                                         utf_display (cnt->descriptor);
3082                                 }
3083                                 break;
3084                         case CONSTANT_Utf8:
3085                                 printf ("Utf8 -> ");
3086                                 utf_display (e);
3087                                 break;
3088                         default: 
3089                                 panic ("Invalid type of ConstantPool-Entry");
3090                         }
3091                 }
3092
3093                 printf ("\n");
3094         }
3095 }
3096
3097
3098
3099 /********** Function: class_showmethods   (debugging only) *************/
3100
3101 void class_showmethods (classinfo *c)
3102 {
3103         s4 i;
3104         
3105         printf ("--------- Fields and Methods ----------------\n");
3106         printf ("Flags: ");     printflags (c->flags);  printf ("\n");
3107
3108         printf ("This: "); utf_display (c->name); printf ("\n");
3109         if (c->super) {
3110                 printf ("Super: "); utf_display (c->super->name); printf ("\n");
3111                 }
3112         printf ("Index: %d\n", c->index);
3113         
3114         printf ("interfaces:\n");       
3115         for (i=0; i < c-> interfacescount; i++) {
3116                 printf ("   ");
3117                 utf_display (c -> interfaces[i] -> name);
3118                 printf (" (%d)\n", c->interfaces[i] -> index);
3119                 }
3120
3121         printf ("fields:\n");           
3122         for (i=0; i < c -> fieldscount; i++) {
3123                 field_display (&(c -> fields[i]));
3124                 }
3125
3126         printf ("methods:\n");
3127         for (i=0; i < c -> methodscount; i++) {
3128                 methodinfo *m = &(c->methods[i]);
3129                 if ( !(m->flags & ACC_STATIC)) 
3130                         printf ("vftblindex: %d   ", m->vftblindex);
3131
3132                 method_display ( m );
3133
3134                 }
3135
3136         printf ("Virtual function table:\n");
3137         for (i=0; i<c->vftbl->vftbllength; i++) {
3138                 printf ("entry: %d,  %ld\n", i, (long int) (c->vftbl->table[i]) );
3139                 }
3140
3141 }
3142
3143
3144
3145 /******************************************************************************/
3146 /******************* General functions for the class loader *******************/
3147 /******************************************************************************/
3148
3149 /********************* Function: loader_load ***********************************
3150
3151         Loads and links the class desired class and each class and interface
3152         referenced by it.
3153         Returns: a pointer to this class
3154
3155 *******************************************************************************/
3156
3157 static int loader_load_running = 0;
3158
3159 classinfo *loader_load(utf *topname)
3160 {
3161         classinfo *top;
3162         classinfo *c;
3163         s8 starttime = 0;
3164         s8 stoptime = 0;
3165         classinfo *notlinkable;
3166
3167 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3168         pthread_mutex_lock(&compiler_mutex);
3169 #endif
3170
3171         /* avoid recursive calls */
3172         if (loader_load_running)
3173                 return class_new(topname);
3174
3175         loader_load_running++;
3176         
3177         intsDisable();
3178
3179         if (getloadingtime)
3180                 starttime = getcputime();
3181
3182         top = class_new(topname);
3183
3184         /* load classes */
3185         while ((c = list_first(&unloadedclasses))) {
3186                 if (!class_load(c)) {
3187                         if (linkverbose)
3188                                 dolog("Failed to load class");
3189                         list_remove(&unloadedclasses, c);
3190                         top = NULL;
3191                 }
3192         }
3193
3194         /* link classes */
3195         if (linkverbose)
3196                 dolog("Linking...");
3197
3198         /* XXX added a hack to break infinite linking loops. A better
3199          * linking algorithm would be nice. -Edwin */
3200         notlinkable = NULL;
3201         while ((c = list_first(&unlinkedclasses))) {
3202                 class_link(c);
3203                 if (!c->linked) {
3204                         if (!notlinkable)
3205                                 notlinkable = c;
3206                         else if (notlinkable == c) {
3207                                 /* We tried to link this class for the second time and
3208                                  * no other classes were linked in between, so we are
3209                                  * caught in a loop.
3210                                  */
3211                                 if (linkverbose)
3212                                         dolog("Cannot resolve linking dependencies");
3213                                 top = NULL;
3214                                 if (!*exceptionptr)
3215                                         throw_linkageerror_message(c->name);
3216                                 break;
3217                         }
3218
3219                 } else
3220                         notlinkable = NULL;
3221         }
3222         if (linkverbose)
3223                 dolog("Linking done.");
3224
3225         if (loader_inited)
3226                 loader_compute_subclasses();
3227
3228         /* measure time */
3229         if (getloadingtime) {
3230                 stoptime = getcputime();
3231                 loadingtime += (stoptime - starttime);
3232         }
3233
3234
3235         loader_load_running--;
3236         
3237         /* check if a former loader_load call tried to load/link the class and 
3238            failed. This is needed because the class didn't appear in the 
3239            undloadclasses or unlinkedclasses list during this class. */
3240         if (top) {
3241                 if (!top->loaded) {
3242                         if (linkverbose) dolog("Failed to load class (former call)");
3243                         throw_noclassdeffounderror_message(top->name);
3244                         top = NULL;
3245                         
3246                 } else if (!top->linked) {
3247                         if (linkverbose)
3248                                 dolog("Failed to link class (former call)");
3249                         throw_linkageerror_message(top->name);
3250                         top = NULL;
3251                 }
3252         }
3253
3254         intsRestore();
3255         
3256 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3257         pthread_mutex_unlock(&compiler_mutex);
3258 #endif
3259
3260         /* XXX DEBUG */ if (linkverbose && !top) dolog("returning NULL from loader_load");
3261         
3262         return top; 
3263 }
3264
3265
3266 /****************** Function: loader_load_sysclass ****************************
3267
3268         Loads and links the class desired class and each class and interface
3269         referenced by it.
3270
3271     The pointer to the classinfo is stored in *top if top != NULL.
3272     The pointer is also returned.
3273
3274     If the class could not be loaded the function aborts with an error.
3275
3276 *******************************************************************************/
3277
3278 classinfo *loader_load_sysclass(classinfo **top, utf *topname)
3279 {
3280         classinfo *cls;
3281
3282         if ((cls = loader_load(topname)) == NULL) {
3283                 log_plain("Could not load important system class: ");
3284                 log_plain_utf(topname);
3285                 log_nl();
3286                 panic("Could not load important system class");
3287         }
3288
3289         if (top) *top = cls;
3290
3291         return cls;
3292 }
3293
3294
3295 /**************** function: create_primitive_classes ***************************
3296
3297         create classes representing primitive types 
3298
3299 ********************************************************************************/
3300
3301
3302 void create_primitive_classes()
3303 {  
3304         int i;
3305
3306         for (i=0;i<PRIMITIVETYPE_COUNT;i++) {
3307                 /* create primitive class */
3308                 classinfo *c = class_new ( utf_new_char(primitivetype_table[i].name) );
3309                 c -> classUsed = NOTUSED; /* not used initially CO-RT */                
3310                 c -> impldBy = NULL;
3311                 
3312                 /* prevent loader from loading primitive class */
3313                 list_remove (&unloadedclasses, c);
3314                 c->loaded=true;
3315                 /* add to unlinked classes */
3316                 list_addlast (&unlinkedclasses, c);             
3317 /*JOWENN primitive types don't have objects as super class              c -> super = class_java_lang_Object; */
3318                 class_link (c);
3319
3320                 primitivetype_table[i].class_primitive = c;
3321
3322                 /* create class for wrapping the primitive type */
3323                 primitivetype_table[i].class_wrap =
3324                         class_new( utf_new_char(primitivetype_table[i].wrapname) );
3325                 primitivetype_table[i].class_wrap -> classUsed = NOTUSED; /* not used initially CO-RT */
3326                 primitivetype_table[i].class_wrap  -> impldBy = NULL;
3327
3328                 /* create the primitive array class */
3329                 if (primitivetype_table[i].arrayname) {
3330                         c = class_new( utf_new_char(primitivetype_table[i].arrayname) );
3331                         primitivetype_table[i].arrayclass = c;
3332                         c->loaded=true;
3333                         if (!c->linked) class_link(c);
3334                         primitivetype_table[i].arrayvftbl = c->vftbl;
3335                 }
3336         }
3337 }
3338
3339 /**************** function: class_primitive_from_sig ***************************
3340
3341         return the primitive class indicated by the given signature character
3342
3343     If the descriptor does not indicate a valid primitive type the
3344     return value is NULL.
3345
3346 ********************************************************************************/
3347
3348 classinfo *class_primitive_from_sig(char sig)
3349 {
3350         switch (sig) {
3351           case 'I': return primitivetype_table[PRIMITIVETYPE_INT].class_primitive;
3352           case 'J': return primitivetype_table[PRIMITIVETYPE_LONG].class_primitive;
3353           case 'F': return primitivetype_table[PRIMITIVETYPE_FLOAT].class_primitive;
3354           case 'D': return primitivetype_table[PRIMITIVETYPE_DOUBLE].class_primitive;
3355           case 'B': return primitivetype_table[PRIMITIVETYPE_BYTE].class_primitive;
3356           case 'C': return primitivetype_table[PRIMITIVETYPE_CHAR].class_primitive;
3357           case 'S': return primitivetype_table[PRIMITIVETYPE_SHORT].class_primitive;
3358           case 'Z': return primitivetype_table[PRIMITIVETYPE_BOOLEAN].class_primitive;
3359           case 'V': return primitivetype_table[PRIMITIVETYPE_VOID].class_primitive;
3360         }
3361         return NULL;
3362 }
3363
3364 /****************** function: class_from_descriptor ****************************
3365
3366     return the class indicated by the given descriptor
3367
3368     utf_ptr....first character of descriptor
3369     end_ptr....first character after the end of the string
3370     next.......if non-NULL, *next is set to the first character after
3371                the descriptor. (Undefined if an error occurs.)
3372
3373     mode.......a combination (binary or) of the following flags:
3374
3375                (Flags marked with * are the default settings.)
3376
3377                What to do if a reference type descriptor is parsed successfully:
3378
3379                    CLASSLOAD_SKIP...skip it and return something != NULL
3380                                  * CLASSLOAD_NEW....get classinfo * via class_new
3381                    CLASSLOAD_LOAD...get classinfo * via loader_load
3382
3383                How to handle primitive types:
3384
3385                              * CLASSLOAD_PRIMITIVE.......return primitive class (eg. "int")
3386                    CLASSLOAD_NULLPRIMITIVE...return NULL for primitive types
3387
3388                How to handle "V" descriptors:
3389
3390                              * CLASSLOAD_VOID.....handle it like other primitive types
3391                    CLASSLOAD_NOVOID...treat it as an error
3392
3393                How to deal with extra characters after the end of the
3394                descriptor:
3395
3396                              * CLASSLOAD_NOCHECKEND...ignore (useful for parameter lists)
3397                    CLASSLOAD_CHECKEND.....treat them as an error
3398
3399                How to deal with errors:
3400
3401                              * CLASSLOAD_PANIC....abort execution with an error message
3402                    CLASSLOAD_NOPANIC..return NULL on error
3403
3404 ********************************************************************************/
3405
3406 classinfo *class_from_descriptor(char *utf_ptr, char *end_ptr,
3407                                                                  char **next, int mode)
3408 {
3409         char *start = utf_ptr;
3410         bool error = false;
3411         utf *name;
3412
3413         SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr,end_ptr,error);
3414
3415         if (mode & CLASSLOAD_CHECKEND)
3416                 error |= (utf_ptr != end_ptr);
3417         
3418         if (!error) {
3419                 if (next) *next = utf_ptr;
3420                 
3421                 switch (*start) {
3422                   case 'V':
3423                           if (mode & CLASSLOAD_NOVOID)
3424                                   break;
3425                           /* FALLTHROUGH! */
3426                   case 'I':
3427                   case 'J':
3428                   case 'F':
3429                   case 'D':
3430                   case 'B':
3431                   case 'C':
3432                   case 'S':
3433                   case 'Z':
3434                           return (mode & CLASSLOAD_NULLPRIMITIVE)
3435                                   ? NULL
3436                                   : class_primitive_from_sig(*start);
3437                           
3438                   case 'L':
3439                           start++;
3440                           utf_ptr--;
3441                           /* FALLTHROUGH! */
3442                   case '[':
3443                           if (mode & CLASSLOAD_SKIP) return class_java_lang_Object;
3444                           name = utf_new(start,utf_ptr-start);
3445                           return (mode & CLASSLOAD_LOAD)
3446                                   ? loader_load(name) : class_new(name); /* XXX */
3447                 }
3448         }
3449
3450         /* An error occurred */
3451         if (mode & CLASSLOAD_NOPANIC)
3452                 return NULL;
3453
3454         log_plain("Invalid descriptor at beginning of '");
3455         log_plain_utf(utf_new(start, end_ptr-start));
3456         log_plain("'");
3457         log_nl();
3458                                                   
3459         panic("Invalid descriptor");
3460
3461         /* keep compiler happy */
3462         return NULL;
3463 }
3464
3465
3466 /******************* function: type_from_descriptor ****************************
3467
3468     return the basic type indicated by the given descriptor
3469
3470     This function parses a descriptor and returns its basic type as
3471     TYPE_INT, TYPE_LONG, TYPE_FLOAT, TYPE_DOUBLE, TYPE_ADDRESS or TYPE_VOID.
3472
3473     cls...if non-NULL the referenced variable is set to the classinfo *
3474           returned by class_from_descriptor.
3475
3476     For documentation of the arguments utf_ptr, end_ptr, next and mode
3477     see class_from_descriptor. The only difference is that
3478     type_from_descriptor always uses CLASSLOAD_PANIC.
3479
3480 ********************************************************************************/
3481
3482 int type_from_descriptor(classinfo **cls, char *utf_ptr, char *end_ptr,
3483                                                  char **next, int mode)
3484 {
3485         classinfo *mycls;
3486         if (!cls) cls = &mycls;
3487         *cls = class_from_descriptor(utf_ptr, end_ptr, next, mode & (~CLASSLOAD_NOPANIC));
3488         switch (*utf_ptr) {
3489           case 'B': 
3490           case 'C':
3491           case 'I':
3492           case 'S':  
3493           case 'Z':
3494                   return TYPE_INT;
3495           case 'D':
3496                   return TYPE_DOUBLE;
3497           case 'F':
3498                   return TYPE_FLOAT;
3499           case 'J':
3500                   return TYPE_LONG;
3501           case 'V':
3502                   return TYPE_VOID;
3503         }
3504         return TYPE_ADDRESS;
3505 }
3506
3507
3508 /*************** function: create_pseudo_classes *******************************
3509
3510         create pseudo classes used by the typechecker
3511
3512 ********************************************************************************/
3513
3514 static void create_pseudo_classes()
3515 {
3516     /* pseudo class for Arraystubs (extends java.lang.Object) */
3517     
3518     pseudo_class_Arraystub = class_new(utf_new_char("$ARRAYSTUB$"));
3519     list_remove(&unloadedclasses, pseudo_class_Arraystub);
3520
3521     pseudo_class_Arraystub->super = class_java_lang_Object;
3522     pseudo_class_Arraystub->interfacescount = 2;
3523     pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
3524     pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
3525     pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
3526
3527     list_addlast(&unlinkedclasses, pseudo_class_Arraystub);
3528     class_link(pseudo_class_Arraystub);
3529
3530         pseudo_class_Arraystub_vftbl = pseudo_class_Arraystub->vftbl;
3531
3532     /* pseudo class representing the null type */
3533     
3534     pseudo_class_Null = class_new(utf_new_char("$NULL$"));
3535     list_remove(&unloadedclasses, pseudo_class_Null);
3536
3537     pseudo_class_Null->super = class_java_lang_Object;
3538
3539     list_addlast(&unlinkedclasses, pseudo_class_Null);
3540     class_link(pseudo_class_Null);      
3541
3542     /* pseudo class representing new uninitialized objects */
3543     
3544     pseudo_class_New = class_new(utf_new_char("$NEW$"));
3545     list_remove(&unloadedclasses, pseudo_class_New);
3546
3547     pseudo_class_New->super = class_java_lang_Object;
3548
3549     list_addlast(&unlinkedclasses, pseudo_class_New);
3550     class_link(pseudo_class_New);       
3551 }
3552
3553
3554 /********************** Function: loader_init **********************************
3555
3556         Initializes all lists and loads all classes required for the system or the
3557         compiler.
3558
3559 *******************************************************************************/
3560  
3561 void loader_init(u1 *stackbottom)
3562 {
3563         interfaceindex = 0;
3564         
3565         list_init(&unloadedclasses, OFFSET(classinfo, listnode));
3566         list_init(&unlinkedclasses, OFFSET(classinfo, listnode));
3567         list_init(&linkedclasses, OFFSET(classinfo, listnode));
3568
3569         /* create utf-symbols for pointer comparison of frequently used strings */
3570         utf_innerclasses    = utf_new_char("InnerClasses");
3571         utf_constantvalue   = utf_new_char("ConstantValue");
3572         utf_code                = utf_new_char("Code");
3573         utf_finalize        = utf_new_char("finalize");
3574         utf_fidesc              = utf_new_char("()V");
3575         utf_init                = utf_new_char("<init>");
3576         utf_clinit              = utf_new_char("<clinit>");
3577         utf_initsystemclass = utf_new_char("initializeSystemClass");
3578         utf_systemclass     = utf_new_char("java/lang/System");
3579         utf_vmclassloader   = utf_new_char("java/lang/VMClassLoader");
3580         utf_initialize      = utf_new_char("initialize");
3581         utf_initializedesc  = utf_new_char("(I)V");
3582
3583         utf_vmclass         = utf_new_char("java/lang/VMClass");
3584         utf_java_lang_Object= utf_new_char("java/lang/Object");
3585
3586         array_packagename   = utf_new_char("<the array package>");
3587
3588         /* create some important classes */
3589         /* These classes have to be created now because the classinfo
3590          * pointers are used in the loading code.
3591          */
3592         class_java_lang_Object = class_new(utf_new_char("java/lang/Object"));
3593         class_java_lang_String = class_new(utf_new_char("java/lang/String"));
3594         class_java_lang_Cloneable = class_new(utf_new_char("java/lang/Cloneable"));
3595         class_java_io_Serializable = class_new(utf_new_char("java/io/Serializable"));
3596
3597         if (verbose) log_text("loader_init: java/lang/Object");
3598         /* load the classes which were created above */
3599         loader_load_sysclass(NULL, class_java_lang_Object->name);
3600
3601         loader_inited = 1; /*JOWENN*/
3602
3603         loader_load_sysclass(&class_java_lang_Throwable,
3604                                                  utf_new_char("java/lang/Throwable"));
3605
3606         if (verbose) log_text("loader_init:  loader_load: java/lang/ClassCastException");
3607         loader_load_sysclass(&class_java_lang_ClassCastException,
3608                                                  utf_new_char ("java/lang/ClassCastException"));
3609         loader_load_sysclass(&class_java_lang_NullPointerException,
3610                                                  utf_new_char ("java/lang/NullPointerException"));
3611         loader_load_sysclass(&class_java_lang_ArrayIndexOutOfBoundsException,
3612                                                  utf_new_char ("java/lang/ArrayIndexOutOfBoundsException"));
3613         loader_load_sysclass(&class_java_lang_NegativeArraySizeException,
3614                                                  utf_new_char ("java/lang/NegativeArraySizeException"));
3615         loader_load_sysclass(&class_java_lang_OutOfMemoryError,
3616                                                  utf_new_char ("java/lang/OutOfMemoryError"));
3617         loader_load_sysclass(&class_java_lang_ArrayStoreException,
3618                                                  utf_new_char ("java/lang/ArrayStoreException"));
3619         loader_load_sysclass(&class_java_lang_ArithmeticException,
3620                                                  utf_new_char ("java/lang/ArithmeticException"));
3621         loader_load_sysclass(&class_java_lang_ThreadDeath,
3622                                                  utf_new_char ("java/lang/ThreadDeath"));
3623                 
3624         /* create classes representing primitive types */
3625         create_primitive_classes();
3626
3627         /* create classes used by the typechecker */
3628         create_pseudo_classes();
3629
3630         /* correct vftbl-entries (retarded loading of class java/lang/String) */
3631         stringtable_update();
3632
3633 #ifdef USE_THREADS
3634         if (stackbottom!=0)
3635                 initLocks();
3636 #endif
3637
3638         if (verbose) log_text("loader_init: creating global proto_java_lang_ClassCastException");
3639         proto_java_lang_ClassCastException =
3640                 builtin_new(class_java_lang_ClassCastException);
3641
3642         if (verbose) log_text("loader_init: proto_java_lang_ClassCastException has been initialized");
3643
3644         proto_java_lang_NullPointerException =
3645                 builtin_new(class_java_lang_NullPointerException);
3646         if (verbose) log_text("loader_init: proto_java_lang_NullPointerException has been initialized");
3647
3648         proto_java_lang_ArrayIndexOutOfBoundsException =
3649                 builtin_new(class_java_lang_ArrayIndexOutOfBoundsException);
3650
3651         proto_java_lang_NegativeArraySizeException =
3652                 builtin_new(class_java_lang_NegativeArraySizeException);
3653
3654         proto_java_lang_OutOfMemoryError =
3655                 builtin_new(class_java_lang_OutOfMemoryError);
3656
3657         proto_java_lang_ArithmeticException =
3658                 builtin_new(class_java_lang_ArithmeticException);
3659
3660         proto_java_lang_ArrayStoreException =
3661                 builtin_new(class_java_lang_ArrayStoreException);
3662
3663         proto_java_lang_ThreadDeath =
3664                 builtin_new(class_java_lang_ThreadDeath);
3665
3666         loader_inited = 1;
3667 }
3668
3669
3670 /********************* Function: loader_initclasses ****************************
3671
3672         Initializes all loaded but uninitialized classes
3673
3674 *******************************************************************************/
3675
3676 #if 0
3677 /* XXX TWISTI: i think we do not need this */
3678 void loader_initclasses ()
3679 {
3680         classinfo *c;
3681         
3682 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3683         pthread_mutex_lock(&compiler_mutex);
3684 #endif
3685
3686         intsDisable();                     /* schani */
3687
3688         if (makeinitializations) {
3689                 c = list_first(&linkedclasses);
3690                 while (c) {
3691                         class_init(c);
3692                         c = list_next(&linkedclasses, c);
3693                 }
3694         }
3695
3696         intsRestore();                      /* schani */
3697         
3698 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3699         pthread_mutex_unlock(&compiler_mutex);
3700 #endif
3701 }
3702 #endif
3703
3704
3705 static void loader_compute_class_values(classinfo *c)
3706 {
3707         classinfo *subs;
3708
3709         c->vftbl->baseval = ++classvalue;
3710
3711         subs = c->sub;
3712         while (subs != NULL) {
3713                 loader_compute_class_values(subs);
3714                 subs = subs->nextsub;
3715         }
3716         c->vftbl->diffval = classvalue - c->vftbl->baseval;
3717         
3718         /*
3719         {
3720         int i;
3721         for (i = 0; i < c->index; i++)
3722                 printf(" ");
3723         printf("%3d  %3d  ", (int) c->vftbl->baseval, c->vftbl->diffval);
3724         utf_display(c->name);
3725         printf("\n");
3726         }
3727         */
3728 }
3729
3730
3731 void loader_compute_subclasses()
3732 {
3733         classinfo *c;
3734         
3735         intsDisable();                     /* schani */
3736
3737         c = list_first(&linkedclasses);
3738         while (c) {
3739                 if (!(c->flags & ACC_INTERFACE)) {
3740                         c->nextsub = 0;
3741                         c->sub = 0;
3742                 }
3743                 c = list_next(&linkedclasses, c);
3744         }
3745
3746         c = list_first(&linkedclasses);
3747         while (c) {
3748                 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
3749                         c->nextsub = c->super->sub;
3750                         c->super->sub = c;
3751                 }
3752                 c = list_next(&linkedclasses, c);
3753         }
3754
3755         classvalue = 0;
3756 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3757         cast_lock();
3758 #endif
3759         loader_compute_class_values(class_java_lang_Object);
3760 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3761         cast_unlock();
3762 #endif
3763
3764         intsRestore();                      /* schani */
3765 }
3766
3767
3768 /******************** function classloader_buffer ******************************
3769  
3770     sets buffer for reading classdata
3771
3772 *******************************************************************************/
3773
3774 void classload_buffer(u1 *buf, int len)
3775 {
3776         classbuffer      = buf;
3777         classbuffer_size = len;
3778         classbuf_pos     = buf - 1;
3779 }
3780
3781
3782 /******************** Function: loader_close ***********************************
3783
3784         Frees all resources
3785         
3786 *******************************************************************************/
3787
3788 void loader_close()
3789 {
3790         classinfo *c;
3791
3792         while ((c = list_first(&unloadedclasses))) {
3793                 list_remove(&unloadedclasses, c);
3794                 class_free(c);
3795         }
3796         while ((c = list_first(&unlinkedclasses))) {
3797                 list_remove(&unlinkedclasses, c);
3798                 class_free(c);
3799         }
3800         while ((c = list_first(&linkedclasses))) {
3801                 list_remove(&linkedclasses, c);
3802                 class_free(c);
3803         }
3804 }
3805
3806
3807 /*
3808  * These are local overrides for various environment variables in Emacs.
3809  * Please do not remove this and leave it at the end of the file, where
3810  * Emacs will automagically detect them.
3811  * ---------------------------------------------------------------------
3812  * Local variables:
3813  * mode: c
3814  * indent-tabs-mode: t
3815  * c-basic-offset: 4
3816  * tab-width: 4
3817  * End:
3818  */