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