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