Get rid of asm_javacallmethod
[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 771 2003-12-13 23:11:08Z stefan $
34
35 */
36
37
38 #include <string.h>
39 #include <assert.h>
40 #include <sys/stat.h>
41 #include "global.h"
42 #include "loader.h"
43 #include "main.h"
44 #include "native.h"
45 #include "tables.h"
46 #include "builtin.h"
47 #include "jit.h"
48 #include "asmpart.h"
49 #include "toolbox/memory.h"
50 #include "toolbox/loging.h"
51 #include "threads/thread.h"
52 #include "threads/locks.h"
53 #include <sys/stat.h>
54
55 #ifdef USE_ZLIB
56 #include "unzip.h"
57 #endif
58
59 #undef JOWENN_DEBUG
60 #undef JOWENN_DEBUG1
61 #undef JOWENN_DEBUG2
62
63 /* global variables ***********************************************************/
64
65 int count_class_infos = 0;      /* variables for measurements                 */
66 int count_const_pool_len = 0;
67 int count_vftbl_len = 0;
68 int count_all_methods = 0;
69 int count_vmcode_len = 0;
70 int count_extable_len = 0;
71 int count_class_loads = 0;
72 int count_class_inits = 0;
73
74 static s4 interfaceindex;       /* sequential numbering of interfaces         */ 
75
76 list unloadedclasses;       /* list of all referenced but not loaded classes  */
77 list unlinkedclasses;       /* list of all loaded but not linked classes      */
78 list linkedclasses;         /* list of all completely linked classes          */
79
80
81 /* utf-symbols for pointer comparison of frequently used strings */
82
83 static utf *utf_innerclasses;           /* InnerClasses            */
84 static utf *utf_constantvalue;          /* ConstantValue           */
85 static utf *utf_code;                       /* Code                    */
86 static utf *utf_finalize;                   /* finalize                */
87 static utf *utf_fidesc;                     /* ()V changed             */
88 static utf *utf_clinit;                     /* <clinit>                */
89 static utf *utf_initsystemclass;        /* initializeSystemClass   */
90 static utf *utf_systemclass;            /* java/lang/System        */
91 static utf *utf_vmclassloader;      /* java/lang/VMClassLoader */
92 static utf *utf_vmclass;            /* java/lang/VMClassLoader */
93 static utf *utf_initialize;
94 static utf *utf_initializedesc;
95
96
97 #ifdef USE_ZLIB
98 static unzFile uf = 0;
99 #endif
100
101
102 utf* clinit_desc(){
103         return utf_fidesc;
104 }
105 utf* clinit_name(){
106         return utf_clinit;
107 }
108
109
110 /* important system classes ***************************************************/
111
112 classinfo *class_java_lang_Object;
113 classinfo *class_java_lang_String;
114
115 classinfo *class_java_lang_Throwable;
116 classinfo *class_java_lang_Cloneable;
117 classinfo *class_java_io_Serializable;
118
119 /* Pseudo classes for the typechecker */
120 classinfo *pseudo_class_Arraystub = NULL;
121 classinfo *pseudo_class_Null = NULL;
122 classinfo *pseudo_class_New = NULL;
123 vftbl *pseudo_class_Arraystub_vftbl = NULL;
124
125 /* stefan */
126 /* These are made static so they cannot be used for throwing in native */
127 /* functions.                                                          */
128 static classinfo *class_java_lang_ClassCastException;
129 static classinfo *class_java_lang_NullPointerException;
130 static classinfo *class_java_lang_ArrayIndexOutOfBoundsException;
131 static classinfo *class_java_lang_NegativeArraySizeException;
132 static classinfo *class_java_lang_OutOfMemoryError;
133 static classinfo *class_java_lang_ArithmeticException;
134 static classinfo *class_java_lang_ArrayStoreException;
135 static classinfo *class_java_lang_ThreadDeath;
136
137 static methodinfo method_clone_array;
138
139 static int loader_inited = 0;
140
141
142 /******************************************************************************
143
144    structure for primitive classes: contains the class for wrapping the 
145    primitive type, the primitive class, the name of the class for wrapping, 
146    the one character type signature and the name of the primitive class
147  
148  ******************************************************************************/
149
150 /* CAUTION: Don't change the order of the types. This table is indexed
151  * by the ARRAYTYPE_ constants (expcept ARRAYTYPE_OBJECT).
152  */
153 primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = { 
154                 { NULL, NULL, "java/lang/Integer",   'I', "int"     , "[I", NULL, NULL },
155                 { NULL, NULL, "java/lang/Long",      'J', "long"    , "[J", NULL, NULL },
156                 { NULL, NULL, "java/lang/Float",     'F', "float"   , "[F", NULL, NULL },
157                 { NULL, NULL, "java/lang/Double",    'D', "double"  , "[D", NULL, NULL },
158                 { NULL, NULL, "java/lang/Byte",      'B', "byte"    , "[B", NULL, NULL },
159                 { NULL, NULL, "java/lang/Character", 'C', "char"    , "[C", NULL, NULL },
160                 { NULL, NULL, "java/lang/Short",     'S', "short"   , "[S", NULL, NULL },
161                 { NULL, NULL, "java/lang/Boolean",   'Z', "boolean" , "[Z", NULL, NULL },
162                 { NULL, NULL, "java/lang/Void",      'V', "void"    , NULL, NULL, NULL }};
163
164 /* instances of important system classes **************************************/
165
166 java_objectheader *proto_java_lang_ClassCastException;
167 java_objectheader *proto_java_lang_NullPointerException;
168 java_objectheader *proto_java_lang_ArrayIndexOutOfBoundsException;
169 java_objectheader *proto_java_lang_NegativeArraySizeException;
170 java_objectheader *proto_java_lang_OutOfMemoryError;
171 java_objectheader *proto_java_lang_ArithmeticException;
172 java_objectheader *proto_java_lang_ArrayStoreException;
173 java_objectheader *proto_java_lang_ThreadDeath;
174
175 /************* functions for reading classdata *********************************
176
177     getting classdata in blocks of variable size
178     (8,16,32,64-bit integer or float)
179
180 *******************************************************************************/
181
182 static char *classpath    = "";     /* searchpath for classfiles              */
183 static u1 *classbuffer    = NULL;   /* pointer to buffer with classfile-data  */
184 static u1 *classbuf_pos;            /* current position in classfile buffer   */
185 static int classbuffer_size;        /* size of classfile-data                 */
186
187 /* assert that at least <len> bytes are left to read */
188 /* <len> is limited to the range of non-negative s4 values */
189 #define ASSERT_LEFT(len)                                                                                                \
190         do {if ( ((s4)(len)) < 0                                                                                        \
191                          || ((classbuffer + classbuffer_size) - classbuf_pos - 1) < (len)) \
192                         panic("Unexpected end of classfile"); } while(0)
193
194 /* transfer block of classfile data into a buffer */
195
196 #define suck_nbytes(buffer,len)                                         \
197         do {ASSERT_LEFT(len);                                                   \
198                 memcpy(buffer,classbuf_pos+1,len);                      \
199                 classbuf_pos+=len;} while (0)
200
201 /* skip block of classfile data */
202
203 #define skip_nbytes(len)                                                \
204         do {ASSERT_LEFT(len);                                           \
205                 classbuf_pos+=len;} while(0)
206
207 inline u1 suck_u1()
208 {
209         ASSERT_LEFT(1);
210         return *++classbuf_pos;
211 }
212 inline u2 suck_u2()
213 {
214         u1 a=suck_u1(), b=suck_u1();
215         return ((u2)a<<8)+(u2)b;
216 }
217 inline u4 suck_u4()
218 {
219         u1 a=suck_u1(), b=suck_u1(), c=suck_u1(), d=suck_u1();
220         return ((u4)a<<24)+((u4)b<<16)+((u4)c<<8)+(u4)d;
221 }
222 #define suck_s8() (s8) suck_u8()
223 #define suck_s2() (s2) suck_u2()
224 #define suck_s4() (s4) suck_u4()
225 #define suck_s1() (s1) suck_u1()
226
227
228 /* get u8 from classfile data */
229 static u8 suck_u8()
230 {
231 #if U8_AVAILABLE
232         u8 lo, hi;
233         hi = suck_u4();
234         lo = suck_u4();
235         return (hi << 32) + lo;
236 #else
237         u8 v;
238         v.high = suck_u4();
239         v.low = suck_u4();
240         return v;
241 #endif
242 }
243
244
245 /* get float from classfile data */
246 static float suck_float()
247 {
248         float f;
249
250 #if !WORDS_BIGENDIAN 
251                 u1 buffer[4];
252                 u2 i;
253                 for (i = 0; i < 4; i++) buffer[3 - i] = suck_u1();
254                 memcpy((u1*) (&f), buffer, 4);
255 #else 
256                 suck_nbytes((u1*) (&f), 4);
257 #endif
258
259         PANICIF (sizeof(float) != 4, "Incompatible float-format");
260         
261         return f;
262 }
263
264
265 /* get double from classfile data */
266 static double suck_double()
267 {
268         double d;
269
270 #if !WORDS_BIGENDIAN 
271                 u1 buffer[8];
272                 u2 i;   
273                 for (i = 0; i < 8; i++) buffer[7 - i] = suck_u1 ();
274                 memcpy((u1*) (&d), buffer, 8);
275 #else 
276                 suck_nbytes((u1*) (&d), 8);
277 #endif
278
279         PANICIF (sizeof(double) != 8, "Incompatible double-format" );
280         
281         return d;
282 }
283
284
285 /************************** function suck_init *********************************
286
287         called once at startup, sets the searchpath for the classfiles
288
289 *******************************************************************************/
290
291 void suck_init(char *cpath)
292 {
293         classpath   = cpath;
294         classbuffer = NULL;
295 }
296
297
298 /************************** function suck_start ********************************
299
300         returns true if classbuffer is already loaded or a file for the
301         specified class has succussfully been read in. All directories of
302         the searchpath are used to find the classfile (<classname>.class).
303         Returns false if no classfile is found and writes an error message. 
304         
305 *******************************************************************************/
306
307 bool suck_start(utf *classname)
308 {
309
310 #define MAXFILENAME 1000                /* maximum length of a filename           */
311         
312         char filename[MAXFILENAME+10];  /* room for '.class'                      */    
313         char *pathpos;                  /* position in searchpath                 */
314         char c, *utf_ptr;               /* pointer to the next utf8-character     */
315         FILE *classfile;
316         int  filenamelen, err;
317         struct stat buffer;
318         int isZip;
319
320         if (classbuffer)                /* classbuffer is already valid */
321                 return true;
322
323         pathpos = classpath;
324         
325         while (*pathpos) {
326
327                 /* skip path separator */
328
329                 while (*pathpos == ':')
330                         pathpos++;
331  
332                 /* extract directory from searchpath */
333
334                 filenamelen = 0;
335                 while ((*pathpos) && (*pathpos != ':')) {
336                     PANICIF (filenamelen >= MAXFILENAME, "Filename too long");
337                         filename[filenamelen++] = *(pathpos++);
338                         }
339
340                 isZip = 0;
341                 if (filenamelen > 4) {
342                         if ( ((filename[filenamelen - 1] == 'p') || (filename[filenamelen - 1] == 'P')) &
343                              ((filename[filenamelen - 2] == 'i') || (filename[filenamelen - 2] == 'I')) &
344                                  ((filename[filenamelen - 3] == 'z') || (filename[filenamelen - 3] == 'Z')) ) {
345                                 isZip = 1;
346                         }
347                 }
348
349                 if (isZip) {
350 #ifdef USE_ZLIB
351                         filename[filenamelen++] = '\0';
352                         if (uf == 0) uf = unzOpen(filename);
353                         if (uf != 0) {
354                                 utf_ptr = classname->text;
355                                 filenamelen = 0;
356                                 while (utf_ptr < utf_end(classname)) {
357                                         PANICIF (filenamelen >= MAXFILENAME, "Filename too long");
358                                         c = *utf_ptr++;
359                                         if ((c <= ' ' || c > 'z') && (c != '/'))     /* invalid character */ 
360                                                 c = '?'; 
361                                         filename[filenamelen++] = c;    
362                                 }
363                                 strcpy(filename + filenamelen, ".class");
364                                 if (cacao_locate(uf,classname) == UNZ_OK) {
365                                         unz_file_info file_info;
366                                         log_text("Class found in zip file");
367                                         if (unzGetCurrentFileInfo(uf, &file_info, filename,
368                                                                                                   sizeof(filename), NULL, 0, NULL, 0) == UNZ_OK) {
369                                                 if (unzOpenCurrentFile(uf) == UNZ_OK) {
370                                                         classbuffer_size = file_info.uncompressed_size;                         
371                                                         classbuffer      = MNEW(u1, classbuffer_size);
372                                                         classbuf_pos     = classbuffer - 1;
373                                                         /*printf("classfile size: %d\n",file_info.uncompressed_size);*/
374                                                         if (unzReadCurrentFile(uf, classbuffer, classbuffer_size) == classbuffer_size) {
375                                                                 unzCloseCurrentFile(uf);
376                                                                 return true;
377                                                         } else {
378                                                                 MFREE(classbuffer, u1, classbuffer_size);
379                                                                 log_text("Error while unzipping");
380                                                         }
381                                                 } else log_text("Error while opening file in archive");
382                                         } else log_text("Error while retrieving fileinfo");
383                                 }
384                                 unzCloseCurrentFile(uf);
385
386                         }
387 #endif                  
388                 } else {
389                         filename[filenamelen++] = '/';  
390    
391                         /* add classname to filename */
392
393                         utf_ptr = classname->text;
394                         while (utf_ptr < utf_end(classname)) {
395                                 PANICIF (filenamelen >= MAXFILENAME, "Filename too long");
396                                 c = *utf_ptr++;
397                                 if ((c <= ' ' || c > 'z') && (c != '/'))     /* invalid character */ 
398                                         c = '?'; 
399                                 filename[filenamelen++] = c;    
400                         }
401         
402                         /* add suffix */
403
404                         strcpy(filename + filenamelen, ".class");
405
406                         classfile = fopen(filename, "r");
407                         if (classfile) {                                       /* file exists */
408
409                                 /* determine size of classfile */
410
411                                 /* dolog("File: %s",filename); */
412
413                                 err = stat(filename, &buffer);
414
415                                 if (!err) {                                /* read classfile data */                            
416                                         classbuffer_size = buffer.st_size;                              
417                                         classbuffer      = MNEW(u1, classbuffer_size);
418                                         classbuf_pos     = classbuffer - 1;
419                                         fread(classbuffer, 1, classbuffer_size, classfile);
420                                         fclose(classfile);
421                                         return true;
422                                 }
423                         }
424                 }
425         }
426         if (verbose) {
427                 dolog("Warning: Can not open class file '%s'", filename);
428         }
429
430         return false;
431 }
432
433
434 /************************** function suck_stop *********************************
435
436         frees memory for buffer with classfile data.
437         Caution: this function may only be called if buffer has been allocated
438                  by suck_start with reading a file
439         
440 *******************************************************************************/
441
442 void suck_stop()
443 {
444         /* determine amount of classdata not retrieved by suck-operations         */
445
446         int classdata_left = ((classbuffer + classbuffer_size) - classbuf_pos - 1);
447
448         if (classdata_left > 0) {
449                 /* surplus */           
450                 dolog("There are %d access bytes at end of classfile",
451                                 classdata_left);
452                 /* XXX panic? */
453         }
454
455         /* free memory */
456
457         MFREE(classbuffer, u1, classbuffer_size);
458         classbuffer = NULL;
459 }
460
461
462 /******************************************************************************/
463 /******************* Some support functions ***********************************/
464 /******************************************************************************/
465
466
467
468 void fprintflags (FILE *fp, u2 f)
469 {
470    if ( f & ACC_PUBLIC )       fprintf (fp," PUBLIC");
471    if ( f & ACC_PRIVATE )      fprintf (fp," PRIVATE");
472    if ( f & ACC_PROTECTED )    fprintf (fp," PROTECTED");
473    if ( f & ACC_STATIC )       fprintf (fp," STATIC");
474    if ( f & ACC_FINAL )        fprintf (fp," FINAL");
475    if ( f & ACC_SYNCHRONIZED ) fprintf (fp," SYNCHRONIZED");
476    if ( f & ACC_VOLATILE )     fprintf (fp," VOLATILE");
477    if ( f & ACC_TRANSIENT )    fprintf (fp," TRANSIENT");
478    if ( f & ACC_NATIVE )       fprintf (fp," NATIVE");
479    if ( f & ACC_INTERFACE )    fprintf (fp," INTERFACE");
480    if ( f & ACC_ABSTRACT )     fprintf (fp," ABSTRACT");
481 }
482
483 /********** internal function: printflags  (only for debugging) ***************/
484 void printflags (u2 f)
485 {
486    if ( f & ACC_PUBLIC )       printf (" PUBLIC");
487    if ( f & ACC_PRIVATE )      printf (" PRIVATE");
488    if ( f & ACC_PROTECTED )    printf (" PROTECTED");
489    if ( f & ACC_STATIC )       printf (" STATIC");
490    if ( f & ACC_FINAL )        printf (" FINAL");
491    if ( f & ACC_SYNCHRONIZED ) printf (" SYNCHRONIZED");
492    if ( f & ACC_VOLATILE )     printf (" VOLATILE");
493    if ( f & ACC_TRANSIENT )    printf (" TRANSIENT");
494    if ( f & ACC_NATIVE )       printf (" NATIVE");
495    if ( f & ACC_INTERFACE )    printf (" INTERFACE");
496    if ( f & ACC_ABSTRACT )     printf (" ABSTRACT");
497 }
498
499
500 /************************* Function: skipattribute *****************************
501
502         skips a (1) 'attribute' structure in the class file
503
504 *******************************************************************************/
505
506 static void skipattribute ()
507 {
508         u4 len;
509         suck_u2 ();
510         len = suck_u4();
511         skip_nbytes(len);       
512 }
513
514 /********************** Function: skipattributebody ****************************
515
516         skips an attribute after the 16 bit reference to attribute_name has already
517         been read
518         
519 *******************************************************************************/
520
521 static void skipattributebody ()
522 {
523         u4 len;
524         len = suck_u4();
525         skip_nbytes(len);
526 }
527
528 /************************* Function: skipattributes ****************************
529
530         skips num attribute structures
531         
532 *******************************************************************************/
533
534 static void skipattributes (u4 num)
535 {
536         u4 i;
537         for (i = 0; i < num; i++)
538                 skipattribute();
539 }
540
541 /******************** function: innerclass_getconstant ************************
542
543     like class_getconstant, but if cptags is ZERO null is returned                                       
544         
545 *******************************************************************************/
546
547 voidptr innerclass_getconstant (classinfo *c, u4 pos, u4 ctype) 
548 {
549         /* invalid position in constantpool */
550         if (pos >= c->cpcount) 
551                 panic ("Attempt to access constant outside range");
552
553         /* constantpool entry of type 0 */      
554         if (!c->cptags[pos])
555                 return NULL;
556
557         /* check type of constantpool entry */
558         if (c->cptags[pos] != ctype) {
559                 error ("Type mismatch on constant: %d requested, %d here (innerclass_getconstant)",
560                  (int) ctype, (int) c->cptags[pos] );
561                 }
562                 
563         return c->cpinfos[pos];
564 }
565
566 /************************ function: attribute_load ****************************
567
568     read attributes from classfile
569         
570 *******************************************************************************/
571
572 static void attribute_load (u4 num, classinfo *c)
573 {
574         u4 i,j;
575
576         for (i = 0; i < num; i++) {
577                 /* retrieve attribute name */   
578                 utf *aname = class_getconstant (c, suck_u2(), CONSTANT_Utf8);
579
580                 if ( aname == utf_innerclasses)  {                      
581                         /* innerclasses attribute */
582                                 
583                         /* skip attribute length */                                             
584                         suck_u4(); 
585                         /* number of records */
586                         c->innerclasscount = suck_u2();
587                         /* allocate memory for innerclass structure */
588                         c->innerclass = MNEW (innerclassinfo, c->innerclasscount);
589
590                         for (j=0;j<c->innerclasscount;j++) {
591                                 
592                                 /*  The innerclass structure contains a class with an encoded name, 
593                                     its defining scope, its simple name  and a bitmask of the access flags. 
594                                     If an inner class is not a member, its outer_class is NULL, 
595                                     if a class is anonymous, its name is NULL.                              */
596                                                                 
597                                 innerclassinfo *info = c->innerclass + j;
598
599                                 info->inner_class = innerclass_getconstant(c, suck_u2(), CONSTANT_Class); /* CONSTANT_Class_info index */
600                                 info->outer_class = innerclass_getconstant(c, suck_u2(), CONSTANT_Class); /* CONSTANT_Class_info index */
601                                 info->name  = innerclass_getconstant(c, suck_u2(), CONSTANT_Utf8);        /* CONSTANT_Utf8_info index  */
602                                 info->flags = suck_u2 ();                                                 /* access_flags bitmask      */
603                         }
604                 } else {
605                         /* unknown attribute */
606                         skipattributebody ();
607                 }
608         }
609 }
610
611 /******************* function: checkfielddescriptor ****************************
612
613         checks whether a field-descriptor is valid and aborts otherwise
614         all referenced classes are inserted into the list of unloaded classes
615         
616 *******************************************************************************/
617
618 static void checkfielddescriptor (char *utf_ptr, char *end_pos)
619 {
620         class_from_descriptor(utf_ptr,end_pos,NULL,
621                                                   CLASSLOAD_NEW
622                                                   | CLASSLOAD_NULLPRIMITIVE
623                                                   | CLASSLOAD_NOVOID
624                                                   | CLASSLOAD_CHECKEND);
625 #if 0
626         char *tstart;  /* pointer to start of classname */
627         char ch;
628         char *start = utf_ptr;
629
630         switch (*utf_ptr++) {
631           case 'B':
632           case 'C':
633           case 'I':
634           case 'S':
635           case 'Z':  
636           case 'J':  
637           case 'F':  
638           case 'D':
639                   /* primitive type */  
640                   break;
641                   
642           case '[':
643           case 'L':
644                   if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
645                           panic ("Ill formed descriptor");
646                   break;
647                   
648           default:   
649                   panic ("Ill formed descriptor");
650         }                       
651         
652         /* exceeding characters */              
653         if (utf_ptr!=end_pos) panic ("descriptor has exceeding chars");
654 #endif
655 }
656
657
658 /******************* function checkmethoddescriptor ****************************
659
660     checks whether a method-descriptor is valid and aborts otherwise.
661     All referenced classes are inserted into the list of unloaded classes.
662         
663 *******************************************************************************/
664
665 static void checkmethoddescriptor (utf *d)
666 {
667         char *utf_ptr = d->text;     /* current position in utf text   */
668         char *end_pos = utf_end(d);  /* points behind utf string       */
669
670         /* method descriptor must start with parenthesis */
671         if (utf_ptr == end_pos || *utf_ptr++ != '(') panic ("Missing '(' in method descriptor");
672
673     /* check arguments */
674     while (utf_ptr != end_pos && *utf_ptr != ')') {
675                 class_from_descriptor(utf_ptr,end_pos,&utf_ptr,
676                                                           CLASSLOAD_NEW
677                                                           | CLASSLOAD_NULLPRIMITIVE
678                                                           | CLASSLOAD_NOVOID);
679         }
680
681         if (utf_ptr == end_pos) panic("Missing return type in method descriptor");
682     utf_ptr++; /* skip ')' */
683
684         class_from_descriptor(utf_ptr,end_pos,NULL,
685                                                   CLASSLOAD_NEW
686                                                   | CLASSLOAD_NULLPRIMITIVE
687                                                   | CLASSLOAD_CHECKEND);
688         
689 #if 0
690         /* XXX check length */
691         /* check arguments */
692         while ((c = *utf_ptr++) != ')') {
693                 start = utf_ptr-1;
694                 
695                 switch (c) {
696                 case 'B':
697                 case 'C':
698                 case 'I':
699                 case 'S':
700                 case 'Z':  
701                 case 'J':  
702                 case 'F':  
703                 case 'D':
704                         /* primitive type */  
705                         break;
706
707                 case '[':
708                 case 'L':
709                         if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
710                                 panic ("Ill formed method descriptor");
711                         break;
712                         
713                 default:   
714                         panic ("Ill formed methodtype-descriptor");
715                 }
716         }
717
718         /* check returntype */
719         if (*utf_ptr=='V') {
720                 /* returntype void */
721                 if ((utf_ptr+1) != end_pos) panic ("Method-descriptor has exceeding chars");
722         }
723         else
724                 /* treat as field-descriptor */
725                 checkfielddescriptor (utf_ptr,end_pos);
726 #endif
727 }
728
729
730 /***************** Function: print_arraydescriptor ****************************
731
732         Debugging helper for displaying an arraydescriptor
733         
734 *******************************************************************************/
735
736 void print_arraydescriptor(FILE *file, arraydescriptor *desc)
737 {
738         if (!desc) {
739                 fprintf(file, "<NULL>");
740                 return;
741         }
742
743         fprintf(file, "{");
744         if (desc->componentvftbl) {
745                 if (desc->componentvftbl->class)
746                         utf_fprint(file, desc->componentvftbl->class->name);
747                 else
748                         fprintf(file, "<no classinfo>");
749         }
750         else
751                 fprintf(file, "0");
752                 
753         fprintf(file, ",");
754         if (desc->elementvftbl) {
755                 if (desc->elementvftbl->class)
756                         utf_fprint(file, desc->elementvftbl->class->name);
757                 else
758                         fprintf(file, "<no classinfo>");
759         }
760         else
761                 fprintf(file, "0");
762         fprintf(file, ",%d,%d,%d,%d}", desc->arraytype, desc->dimension,
763                         desc->dataoffset, desc->componentsize);
764 }
765
766
767 /******************************************************************************/
768 /**************************  Functions for fields  ****************************/
769 /******************************************************************************/
770
771
772 /************************ Function: field_load *********************************
773
774         Load everything about a class field from the class file and fill a
775         'fieldinfo' structure. For static fields, space in the data segment is
776         allocated.
777
778 *******************************************************************************/
779
780 static void field_load (fieldinfo *f, classinfo *c)
781 {
782         u4 attrnum,i;
783         u4 jtype;
784
785         f -> flags = suck_u2 ();                                           /* ACC flags                   */
786         f -> name = class_getconstant (c, suck_u2(), CONSTANT_Utf8);       /* name of field               */
787         f -> descriptor = class_getconstant (c, suck_u2(), CONSTANT_Utf8); /* JavaVM descriptor           */
788         f -> type = jtype = desc_to_type (f->descriptor);                  /* data type                   */
789         f -> offset = 0;                                                   /* offset from start of object */
790         f -> class = c;
791         f->xta = NULL;
792         
793         switch (f->type) {
794         case TYPE_INT:        f->value.i = 0; break;
795         case TYPE_FLOAT:      f->value.f = 0.0; break;
796         case TYPE_DOUBLE:     f->value.d = 0.0; break;
797         case TYPE_ADDRESS:    f->value.a = NULL;                              
798 /*                            heap_addreference (&(f->value.a));           /* make global reference (GC)  */
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(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         if (exceptionptr) {
2496                 printf("#### Initializer of ");
2497                 utf_display(c->name);
2498                 printf(" has thrown: ");
2499                 utf_display(exceptionptr->vftbl->class->name);
2500                 printf("\n");
2501                 fflush(stdout);
2502         }
2503
2504         if (initverbose) {
2505                 char logtext[MAXLOGTEXT];
2506                 sprintf(logtext, "Finished initializer for class: ");
2507                 utf_sprint(logtext + strlen(logtext), c->name);
2508                 log_text(logtext);
2509         }
2510         if (c->name == utf_systemclass) {
2511                 /* class java.lang.System requires explicit initialization */
2512
2513                 if (initverbose)
2514                         printf("#### Initializing class System");
2515
2516                 /* find initializing method */
2517                 m = class_findmethod(c,
2518                                                          utf_initsystemclass,
2519                                                          utf_fidesc);
2520
2521                 if (!m) {
2522                         /* no method found */
2523                         /* printf("initializeSystemClass failed"); */
2524                         return;
2525                 }
2526
2527 #ifdef USE_THREADS
2528                 b = blockInts;
2529                 blockInts = 0;
2530 #endif
2531
2532                 asm_calljavafunction(m, NULL, NULL, NULL, NULL);
2533
2534 #ifdef USE_THREADS
2535                 assert(blockInts == 0);
2536                 blockInts = b;
2537 #endif
2538
2539                 if (exceptionptr) {
2540                         printf("#### initializeSystemClass has thrown: ");
2541                         utf_display(exceptionptr->vftbl->class->name);
2542                         printf("\n");
2543                         fflush(stdout);
2544                 }
2545         }
2546 }
2547
2548
2549 /********* Function: find_class_method_constant *********/
2550
2551 int find_class_method_constant (classinfo *c, utf * c1, utf* m1, utf* d1)  
2552 {
2553         u4 i;
2554         voidptr e;
2555
2556         for (i=0; i<c->cpcount; i++) {
2557                 
2558                 e = c -> cpinfos [i];
2559                 if (e) {
2560                         
2561                         switch (c -> cptags [i]) {
2562                         case CONSTANT_Methodref:
2563                                 {
2564                                         constant_FMIref *fmi = e;
2565                                         if (       (fmi->class->name == c1)  
2566                                                            && (fmi->name == m1)
2567                                                            && (fmi->descriptor == d1)) {
2568                                         
2569                                                 return i;
2570                                         }
2571                                 }
2572                                 break;
2573
2574                         case CONSTANT_InterfaceMethodref:
2575                                 {
2576                                         constant_FMIref *fmi = e;
2577                                         if (       (fmi->class->name == c1)  
2578                                                            && (fmi->name == m1)
2579                                                            && (fmi->descriptor == d1)) {
2580
2581                                                 return i;
2582                                         }
2583                                 }
2584                                 break;
2585                         }
2586                 }
2587         }
2588
2589         return -1;
2590 }
2591
2592
2593 void class_showconstanti(classinfo *c, int ii) 
2594 {
2595         u4 i = ii;
2596         voidptr e;
2597                 
2598         e = c->cpinfos [i];
2599         printf ("#%d:  ", (int) i);
2600         if (e) {
2601                 switch (c->cptags [i]) {
2602                 case CONSTANT_Class:
2603                         printf("Classreference -> ");
2604                         utf_display(((classinfo*)e)->name);
2605                         break;
2606                                 
2607                 case CONSTANT_Fieldref:
2608                         printf("Fieldref -> "); goto displayFMIi;
2609                 case CONSTANT_Methodref:
2610                         printf("Methodref -> "); goto displayFMIi;
2611                 case CONSTANT_InterfaceMethodref:
2612                         printf("InterfaceMethod -> "); goto displayFMIi;
2613                 displayFMIi:
2614                         {
2615                                 constant_FMIref *fmi = e;
2616                                 utf_display(fmi->class->name);
2617                                 printf(".");
2618                                 utf_display(fmi->name);
2619                                 printf(" ");
2620                                 utf_display(fmi->descriptor);
2621                         }
2622                         break;
2623
2624                 case CONSTANT_String:
2625                         printf("String -> ");
2626                         utf_display(e);
2627                         break;
2628                 case CONSTANT_Integer:
2629                         printf("Integer -> %d", (int) (((constant_integer*)e)->value));
2630                         break;
2631                 case CONSTANT_Float:
2632                         printf("Float -> %f", ((constant_float*)e)->value);
2633                         break;
2634                 case CONSTANT_Double:
2635                         printf("Double -> %f", ((constant_double*)e)->value);
2636                         break;
2637                 case CONSTANT_Long:
2638                         {
2639                                 u8 v = ((constant_long*)e)->value;
2640 #if U8_AVAILABLE
2641                                 printf("Long -> %ld", (long int) v);
2642 #else
2643                                 printf("Long -> HI: %ld, LO: %ld\n", 
2644                                             (long int) v.high, (long int) v.low);
2645 #endif 
2646                         }
2647                         break;
2648                 case CONSTANT_NameAndType:
2649                         { 
2650                                 constant_nameandtype *cnt = e;
2651                                 printf("NameAndType: ");
2652                                 utf_display(cnt->name);
2653                                 printf(" ");
2654                                 utf_display(cnt->descriptor);
2655                         }
2656                         break;
2657                 case CONSTANT_Utf8:
2658                         printf("Utf8 -> ");
2659                         utf_display(e);
2660                         break;
2661                 default: 
2662                         panic("Invalid type of ConstantPool-Entry");
2663                 }
2664         }
2665         printf("\n");
2666 }
2667
2668
2669 void class_showconstantpool (classinfo *c) 
2670 {
2671         u4 i;
2672         voidptr e;
2673
2674         printf ("---- dump of constant pool ----\n");
2675
2676         for (i=0; i<c->cpcount; i++) {
2677                 printf ("#%d:  ", (int) i);
2678                 
2679                 e = c -> cpinfos [i];
2680                 if (e) {
2681                         
2682                         switch (c -> cptags [i]) {
2683                         case CONSTANT_Class:
2684                                 printf ("Classreference -> ");
2685                                 utf_display ( ((classinfo*)e) -> name );
2686                                 break;
2687                                 
2688                         case CONSTANT_Fieldref:
2689                                 printf ("Fieldref -> "); goto displayFMI;
2690                         case CONSTANT_Methodref:
2691                                 printf ("Methodref -> "); goto displayFMI;
2692                         case CONSTANT_InterfaceMethodref:
2693                                 printf ("InterfaceMethod -> "); goto displayFMI;
2694                         displayFMI:
2695                                 {
2696                                         constant_FMIref *fmi = e;
2697                                         utf_display ( fmi->class->name );
2698                                         printf (".");
2699                                         utf_display ( fmi->name);
2700                                         printf (" ");
2701                                         utf_display ( fmi->descriptor );
2702                                 }
2703                                 break;
2704
2705                         case CONSTANT_String:
2706                                 printf ("String -> ");
2707                                 utf_display (e);
2708                                 break;
2709                         case CONSTANT_Integer:
2710                                 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
2711                                 break;
2712                         case CONSTANT_Float:
2713                                 printf ("Float -> %f", ((constant_float*)e) -> value);
2714                                 break;
2715                         case CONSTANT_Double:
2716                                 printf ("Double -> %f", ((constant_double*)e) -> value);
2717                                 break;
2718                         case CONSTANT_Long:
2719                                 {
2720                                         u8 v = ((constant_long*)e) -> value;
2721 #if U8_AVAILABLE
2722                                         printf ("Long -> %ld", (long int) v);
2723 #else
2724                                         printf ("Long -> HI: %ld, LO: %ld\n", 
2725                                                         (long int) v.high, (long int) v.low);
2726 #endif 
2727                                 }
2728                                 break;
2729                         case CONSTANT_NameAndType:
2730                                 {
2731                                         constant_nameandtype *cnt = e;
2732                                         printf ("NameAndType: ");
2733                                         utf_display (cnt->name);
2734                                         printf (" ");
2735                                         utf_display (cnt->descriptor);
2736                                 }
2737                                 break;
2738                         case CONSTANT_Utf8:
2739                                 printf ("Utf8 -> ");
2740                                 utf_display (e);
2741                                 break;
2742                         default: 
2743                                 panic ("Invalid type of ConstantPool-Entry");
2744                         }
2745                 }
2746
2747                 printf ("\n");
2748         }
2749 }
2750
2751
2752
2753 /********** Function: class_showmethods   (debugging only) *************/
2754
2755 void class_showmethods (classinfo *c)
2756 {
2757         s4 i;
2758         
2759         printf ("--------- Fields and Methods ----------------\n");
2760         printf ("Flags: ");     printflags (c->flags);  printf ("\n");
2761
2762         printf ("This: "); utf_display (c->name); printf ("\n");
2763         if (c->super) {
2764                 printf ("Super: "); utf_display (c->super->name); printf ("\n");
2765                 }
2766         printf ("Index: %d\n", c->index);
2767         
2768         printf ("interfaces:\n");       
2769         for (i=0; i < c-> interfacescount; i++) {
2770                 printf ("   ");
2771                 utf_display (c -> interfaces[i] -> name);
2772                 printf (" (%d)\n", c->interfaces[i] -> index);
2773                 }
2774
2775         printf ("fields:\n");           
2776         for (i=0; i < c -> fieldscount; i++) {
2777                 field_display (&(c -> fields[i]));
2778                 }
2779
2780         printf ("methods:\n");
2781         for (i=0; i < c -> methodscount; i++) {
2782                 methodinfo *m = &(c->methods[i]);
2783                 if ( !(m->flags & ACC_STATIC)) 
2784                         printf ("vftblindex: %d   ", m->vftblindex);
2785
2786                 method_display ( m );
2787
2788                 }
2789
2790         printf ("Virtual function table:\n");
2791         for (i=0; i<c->vftbl->vftbllength; i++) {
2792                 printf ("entry: %d,  %ld\n", i, (long int) (c->vftbl->table[i]) );
2793                 }
2794
2795 }
2796
2797
2798
2799 /******************************************************************************/
2800 /******************* General functions for the class loader *******************/
2801 /******************************************************************************/
2802
2803 /********************* Function: loader_load ***********************************
2804
2805         Loads and links the class desired class and each class and interface
2806         referenced by it.
2807         Returns: a pointer to this class
2808
2809 *******************************************************************************/
2810
2811 static int loader_load_running = 0;
2812
2813 classinfo *loader_load(utf *topname)
2814 {
2815         classinfo *top;
2816         classinfo *c;
2817         s8 starttime = 0;
2818         s8 stoptime = 0;
2819         classinfo *notlinkable;
2820         
2821 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
2822         pthread_mutex_lock(&compiler_mutex);
2823 #endif
2824
2825         /* avoid recursive calls */
2826         if (loader_load_running)
2827                 return class_new(topname);
2828
2829         loader_load_running++;
2830         
2831         intsDisable();
2832
2833         if (getloadingtime)
2834                 starttime = getcputime();
2835
2836         top = class_new(topname);
2837
2838         /* load classes */
2839         while ((c = list_first(&unloadedclasses))) {
2840                 if (!class_load(c)) {
2841                         if (linkverbose)
2842                                 dolog("Failed to load class");
2843                         list_remove(&unloadedclasses, c);
2844                         top = NULL;
2845                 }
2846         }
2847
2848         /* link classes */
2849         if (linkverbose)
2850                 dolog("Linking...");
2851
2852         /* XXX added a hack to break infinite linking loops. A better
2853          * linking algorithm would be nice. -Edwin */
2854         notlinkable = NULL;
2855         while ((c = list_first(&unlinkedclasses))) {
2856                 class_link(c);
2857                 if (!c->linked) {
2858                         if (!notlinkable)
2859                                 notlinkable = c;
2860                         else if (notlinkable == c) {
2861                                 /* We tried to link this class for the second time and
2862                                  * no other classes were linked in between, so we are
2863                                  * caught in a loop.
2864                                  */
2865                                 if (linkverbose)
2866                                         dolog("Cannot resolve linking dependencies");
2867                                 top = NULL;
2868                                 if (!exceptionptr)
2869                                         throw_linkageerror_message(c->name);
2870                                 break;
2871                         }
2872
2873                 } else
2874                         notlinkable = NULL;
2875         }
2876         if (linkverbose)
2877                 dolog("Linking done.");
2878
2879         if (loader_inited)
2880                 loader_compute_subclasses();
2881
2882         /* measure time */
2883         if (getloadingtime) {
2884                 stoptime = getcputime();
2885                 loadingtime += (stoptime - starttime);
2886         }
2887
2888
2889         loader_load_running--;
2890         
2891         /* check if a former loader_load call tried to load/link the class and 
2892            failed. This is needed because the class didn't appear in the 
2893            undloadclasses or unlinkedclasses list during this class. */
2894         if (top) {
2895                 if (!top->loaded) {
2896                         if (linkverbose) dolog("Failed to load class (former call)");
2897                         throw_noclassdeffounderror_message(top->name);
2898                         top = NULL;
2899                         
2900                 } else if (!top->linked) {
2901                         if (linkverbose)
2902                                 dolog("Failed to link class (former call)");
2903                         throw_linkageerror_message(top->name);
2904                         top = NULL;
2905                 }
2906         }
2907
2908         intsRestore();
2909         
2910 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
2911         pthread_mutex_unlock(&compiler_mutex);
2912 #endif
2913
2914         /* XXX DEBUG */ if (linkverbose && !top) dolog("returning NULL from loader_load");
2915         
2916         return top; 
2917 }
2918
2919 /****************** Function: loader_load_sysclass ****************************
2920
2921         Loads and links the class desired class and each class and interface
2922         referenced by it.
2923
2924     The pointer to the classinfo is stored in *top if top != NULL.
2925     The pointer is also returned.
2926
2927     If the class could not be loaded the function aborts with an error.
2928
2929 *******************************************************************************/
2930
2931 classinfo *loader_load_sysclass(classinfo **top,utf *topname)
2932 {
2933         classinfo *cls;
2934
2935         if ((cls = loader_load(topname)) == NULL) {
2936                 log_plain("Could not important system class: ");
2937                 log_plain_utf(topname);
2938                 log_nl();
2939                 panic("Could not load important system class");
2940         }
2941
2942         if (top) *top = cls;
2943
2944         return cls;
2945 }
2946
2947 /**************** function: create_primitive_classes ***************************
2948
2949         create classes representing primitive types 
2950
2951 ********************************************************************************/
2952
2953
2954 void create_primitive_classes()
2955 {  
2956         int i;
2957
2958         for (i=0;i<PRIMITIVETYPE_COUNT;i++) {
2959                 /* create primitive class */
2960                 classinfo *c = class_new ( utf_new_char(primitivetype_table[i].name) );
2961                 c -> classUsed = NOTUSED; /* not used initially CO-RT */                
2962                 c -> impldBy = NULL;
2963                 
2964                 /* prevent loader from loading primitive class */
2965                 list_remove (&unloadedclasses, c);
2966                 c->loaded=true;
2967                 /* add to unlinked classes */
2968                 list_addlast (&unlinkedclasses, c);             
2969 /*JOWENN primitive types don't have objects as super class              c -> super = class_java_lang_Object; */
2970                 class_link (c);
2971
2972                 primitivetype_table[i].class_primitive = c;
2973
2974                 /* create class for wrapping the primitive type */
2975                 primitivetype_table[i].class_wrap =
2976                         class_new( utf_new_char(primitivetype_table[i].wrapname) );
2977                 primitivetype_table[i].class_wrap -> classUsed = NOTUSED; /* not used initially CO-RT */
2978                 primitivetype_table[i].class_wrap  -> impldBy = NULL;
2979
2980                 /* create the primitive array class */
2981                 if (primitivetype_table[i].arrayname) {
2982                         c = class_new( utf_new_char(primitivetype_table[i].arrayname) );
2983                         primitivetype_table[i].arrayclass = c;
2984                         c->loaded=true;
2985                         if (!c->linked) class_link(c);
2986                         primitivetype_table[i].arrayvftbl = c->vftbl;
2987                 }
2988         }
2989 }
2990
2991 /**************** function: class_primitive_from_sig ***************************
2992
2993         return the primitive class indicated by the given signature character
2994
2995     If the descriptor does not indicate a valid primitive type the
2996     return value is NULL.
2997
2998 ********************************************************************************/
2999
3000 classinfo *class_primitive_from_sig(char sig)
3001 {
3002         switch (sig) {
3003           case 'I': return primitivetype_table[PRIMITIVETYPE_INT].class_primitive;
3004           case 'J': return primitivetype_table[PRIMITIVETYPE_LONG].class_primitive;
3005           case 'F': return primitivetype_table[PRIMITIVETYPE_FLOAT].class_primitive;
3006           case 'D': return primitivetype_table[PRIMITIVETYPE_DOUBLE].class_primitive;
3007           case 'B': return primitivetype_table[PRIMITIVETYPE_BYTE].class_primitive;
3008           case 'C': return primitivetype_table[PRIMITIVETYPE_CHAR].class_primitive;
3009           case 'S': return primitivetype_table[PRIMITIVETYPE_SHORT].class_primitive;
3010           case 'Z': return primitivetype_table[PRIMITIVETYPE_BOOLEAN].class_primitive;
3011           case 'V': return primitivetype_table[PRIMITIVETYPE_VOID].class_primitive;
3012         }
3013         return NULL;
3014 }
3015
3016 /****************** function: class_from_descriptor ****************************
3017
3018     return the class indicated by the given descriptor
3019
3020     utf_ptr....first character of descriptor
3021     end_ptr....first character after the end of the string
3022     next.......if non-NULL, *next is set to the first character after
3023                the descriptor. (Undefined if an error occurs.)
3024
3025     mode.......a combination (binary or) of the following flags:
3026
3027                (Flags marked with * are the default settings.)
3028
3029                What to do if a reference type descriptor is parsed successfully:
3030
3031                    CLASSLOAD_SKIP...skip it and return something != NULL
3032                                  * CLASSLOAD_NEW....get classinfo * via class_new
3033                    CLASSLOAD_LOAD...get classinfo * via loader_load
3034
3035                How to handle primitive types:
3036
3037                              * CLASSLOAD_PRIMITIVE.......return primitive class (eg. "int")
3038                    CLASSLOAD_NULLPRIMITIVE...return NULL for primitive types
3039
3040                How to handle "V" descriptors:
3041
3042                              * CLASSLOAD_VOID.....handle it like other primitive types
3043                    CLASSLOAD_NOVOID...treat it as an error
3044
3045                How to deal with extra characters after the end of the
3046                descriptor:
3047
3048                              * CLASSLOAD_NOCHECKEND...ignore (useful for parameter lists)
3049                    CLASSLOAD_CHECKEND.....treat them as an error
3050
3051                How to deal with errors:
3052
3053                              * CLASSLOAD_PANIC....abort execution with an error message
3054                    CLASSLOAD_NOPANIC..return NULL on error
3055
3056 ********************************************************************************/
3057
3058 classinfo *class_from_descriptor(char *utf_ptr, char *end_ptr,
3059                                                                  char **next, int mode)
3060 {
3061         char *start = utf_ptr;
3062         bool error = false;
3063         utf *name;
3064
3065         SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr,end_ptr,error);
3066
3067         if (mode & CLASSLOAD_CHECKEND)
3068                 error |= (utf_ptr != end_ptr);
3069         
3070         if (!error) {
3071                 if (next) *next = utf_ptr;
3072                 
3073                 switch (*start) {
3074                   case 'V':
3075                           if (mode & CLASSLOAD_NOVOID)
3076                                   break;
3077                           /* FALLTHROUGH! */
3078                   case 'I':
3079                   case 'J':
3080                   case 'F':
3081                   case 'D':
3082                   case 'B':
3083                   case 'C':
3084                   case 'S':
3085                   case 'Z':
3086                           return (mode & CLASSLOAD_NULLPRIMITIVE)
3087                                   ? NULL
3088                                   : class_primitive_from_sig(*start);
3089                           
3090                   case 'L':
3091                           start++;
3092                           utf_ptr--;
3093                           /* FALLTHROUGH! */
3094                   case '[':
3095                           if (mode & CLASSLOAD_SKIP) return class_java_lang_Object;
3096                           name = utf_new(start,utf_ptr-start);
3097                           return (mode & CLASSLOAD_LOAD)
3098                                   ? loader_load(name) : class_new(name); /* XXX */
3099                 }
3100         }
3101
3102         /* An error occurred */
3103         if (mode & CLASSLOAD_NOPANIC)
3104                 return NULL;
3105
3106         log_plain("Invalid descriptor at beginning of '");
3107         log_plain_utf(utf_new(start, end_ptr-start));
3108         log_plain("'");
3109         log_nl();
3110                                                   
3111         panic("Invalid descriptor");
3112
3113         /* keep compiler happy */
3114         return NULL;
3115 }
3116
3117
3118 /******************* function: type_from_descriptor ****************************
3119
3120     return the basic type indicated by the given descriptor
3121
3122     This function parses a descriptor and returns its basic type as
3123     TYPE_INT, TYPE_LONG, TYPE_FLOAT, TYPE_DOUBLE, TYPE_ADDRESS or TYPE_VOID.
3124
3125     cls...if non-NULL the referenced variable is set to the classinfo *
3126           returned by class_from_descriptor.
3127
3128     For documentation of the arguments utf_ptr, end_ptr, next and mode
3129     see class_from_descriptor. The only difference is that
3130     type_from_descriptor always uses CLASSLOAD_PANIC.
3131
3132 ********************************************************************************/
3133
3134 int type_from_descriptor(classinfo **cls, char *utf_ptr, char *end_ptr,
3135                                                  char **next, int mode)
3136 {
3137         classinfo *mycls;
3138         if (!cls) cls = &mycls;
3139         *cls = class_from_descriptor(utf_ptr, end_ptr, next, mode & (~CLASSLOAD_NOPANIC));
3140         switch (*utf_ptr) {
3141           case 'B': 
3142           case 'C':
3143           case 'I':
3144           case 'S':  
3145           case 'Z':
3146                   return TYPE_INT;
3147           case 'D':
3148                   return TYPE_DOUBLE;
3149           case 'F':
3150                   return TYPE_FLOAT;
3151           case 'J':
3152                   return TYPE_LONG;
3153           case 'V':
3154                   return TYPE_VOID;
3155         }
3156         return TYPE_ADDRESS;
3157 }
3158
3159
3160 /*************** function: create_pseudo_classes *******************************
3161
3162         create pseudo classes used by the typechecker
3163
3164 ********************************************************************************/
3165
3166 static void create_pseudo_classes()
3167 {
3168     /* pseudo class for Arraystubs (extends java.lang.Object) */
3169     
3170     pseudo_class_Arraystub = class_new(utf_new_char("$ARRAYSTUB$"));
3171     list_remove(&unloadedclasses, pseudo_class_Arraystub);
3172
3173     pseudo_class_Arraystub->super = class_java_lang_Object;
3174     pseudo_class_Arraystub->interfacescount = 2;
3175     pseudo_class_Arraystub->interfaces = MNEW(classinfo*, 2);
3176     pseudo_class_Arraystub->interfaces[0] = class_java_lang_Cloneable;
3177     pseudo_class_Arraystub->interfaces[1] = class_java_io_Serializable;
3178
3179     list_addlast(&unlinkedclasses, pseudo_class_Arraystub);
3180     class_link(pseudo_class_Arraystub);
3181
3182         pseudo_class_Arraystub_vftbl = pseudo_class_Arraystub->vftbl;
3183
3184     /* pseudo class representing the null type */
3185     
3186     pseudo_class_Null = class_new(utf_new_char("$NULL$"));
3187     list_remove(&unloadedclasses, pseudo_class_Null);
3188
3189     pseudo_class_Null->super = class_java_lang_Object;
3190
3191     list_addlast(&unlinkedclasses, pseudo_class_Null);
3192     class_link(pseudo_class_Null);      
3193
3194     /* pseudo class representing new uninitialized objects */
3195     
3196     pseudo_class_New = class_new( utf_new_char("$NEW$") );
3197     list_remove(&unloadedclasses,pseudo_class_New);
3198
3199     pseudo_class_New->super = class_java_lang_Object;
3200
3201     list_addlast(&unlinkedclasses,pseudo_class_New);
3202     class_link(pseudo_class_New);       
3203 }
3204
3205
3206 /********************** Function: loader_init **********************************
3207
3208         Initializes all lists and loads all classes required for the system or the
3209         compiler.
3210
3211 *******************************************************************************/
3212  
3213 void loader_init(u1 * stackbottom)
3214 {
3215         interfaceindex = 0;
3216         
3217         log_text("Entering loader_init");
3218         
3219         list_init (&unloadedclasses, OFFSET(classinfo, listnode) );
3220         list_init (&unlinkedclasses, OFFSET(classinfo, listnode) );
3221         list_init (&linkedclasses, OFFSET(classinfo, listnode) );
3222
3223         /* create utf-symbols for pointer comparison of frequently used strings */
3224         utf_innerclasses    = utf_new_char("InnerClasses");
3225         utf_constantvalue   = utf_new_char("ConstantValue");
3226         utf_code                = utf_new_char("Code");
3227         utf_finalize        = utf_new_char("finalize");
3228         utf_fidesc              = utf_new_char("()V");
3229         utf_clinit              = utf_new_char("<clinit>");
3230         utf_initsystemclass = utf_new_char("initializeSystemClass");
3231         utf_systemclass     = utf_new_char("java/lang/System");
3232         utf_vmclassloader   = utf_new_char("java/lang/VMClassLoader");
3233         utf_initialize      = utf_new_char("initialize");
3234         utf_initializedesc  = utf_new_char("(I)V");
3235
3236         utf_vmclass         = utf_new_char("java/lang/VMClass");
3237
3238         /* create some important classes */
3239         /* These classes have to be created now because the classinfo
3240          * pointers are used in the loading code.
3241          */
3242         class_java_lang_Object = class_new(utf_new_char("java/lang/Object"));
3243         class_java_lang_String = class_new(utf_new_char("java/lang/String"));
3244         class_java_lang_Cloneable = class_new(utf_new_char("java/lang/Cloneable"));
3245         class_java_io_Serializable = class_new(utf_new_char("java/io/Serializable"));
3246
3247         log_text("loader_init: java/lang/Object");
3248         /* load the classes which were created above */
3249         loader_load_sysclass(NULL, class_java_lang_Object->name);
3250
3251         loader_inited = 1; /*JOWENN*/
3252
3253         loader_load_sysclass(&class_java_lang_Throwable,
3254                                                  utf_new_char("java/lang/Throwable"));
3255
3256         log_text("loader_init:  loader_load: java/lang/ClassCastException");
3257         loader_load_sysclass(&class_java_lang_ClassCastException,
3258                                                  utf_new_char ("java/lang/ClassCastException"));
3259         loader_load_sysclass(&class_java_lang_NullPointerException,
3260                                                  utf_new_char ("java/lang/NullPointerException"));
3261         loader_load_sysclass(&class_java_lang_ArrayIndexOutOfBoundsException,
3262                                                  utf_new_char ("java/lang/ArrayIndexOutOfBoundsException"));
3263         loader_load_sysclass(&class_java_lang_NegativeArraySizeException,
3264                                                  utf_new_char ("java/lang/NegativeArraySizeException"));
3265         loader_load_sysclass(&class_java_lang_OutOfMemoryError,
3266                                                  utf_new_char ("java/lang/OutOfMemoryError"));
3267         loader_load_sysclass(&class_java_lang_ArrayStoreException,
3268                                                  utf_new_char ("java/lang/ArrayStoreException"));
3269         loader_load_sysclass(&class_java_lang_ArithmeticException,
3270                                                  utf_new_char ("java/lang/ArithmeticException"));
3271         loader_load_sysclass(&class_java_lang_ThreadDeath,
3272                                                  utf_new_char ("java/lang/ThreadDeath"));
3273                 
3274         /* create classes representing primitive types */
3275         create_primitive_classes();
3276
3277         /* create classes used by the typechecker */
3278         create_pseudo_classes();
3279
3280         /* correct vftbl-entries (retarded loading of class java/lang/String) */
3281         stringtable_update();
3282
3283 #ifdef USE_THREADS
3284         if (stackbottom!=0)
3285                 initLocks();
3286 #endif
3287
3288         log_text("loader_init: creating global proto_java_lang_ClassCastException");
3289         proto_java_lang_ClassCastException =
3290                 builtin_new(class_java_lang_ClassCastException);
3291 /*      heap_addreference((void**) &proto_java_lang_ClassCastException); */
3292
3293         log_text("loader_init: proto_java_lang_ClassCastException has been initialized");
3294
3295         proto_java_lang_NullPointerException =
3296                 builtin_new(class_java_lang_NullPointerException);
3297 /*      heap_addreference((void**) &proto_java_lang_NullPointerException); */
3298         log_text("loader_init: proto_java_lang_NullPointerException has been initialized");
3299
3300         proto_java_lang_ArrayIndexOutOfBoundsException =
3301                 builtin_new(class_java_lang_ArrayIndexOutOfBoundsException);
3302 /*      heap_addreference((void**) &proto_java_lang_ArrayIndexOutOfBoundsException); */
3303
3304         proto_java_lang_NegativeArraySizeException =
3305                 builtin_new(class_java_lang_NegativeArraySizeException);
3306 /*      heap_addreference((void**) &proto_java_lang_NegativeArraySizeException); */
3307
3308         proto_java_lang_OutOfMemoryError =
3309                 builtin_new(class_java_lang_OutOfMemoryError);
3310 /*      heap_addreference((void**) &proto_java_lang_OutOfMemoryError); */
3311
3312         proto_java_lang_ArithmeticException =
3313                 builtin_new(class_java_lang_ArithmeticException);
3314 /*      heap_addreference((void**) &proto_java_lang_ArithmeticException); */
3315
3316         proto_java_lang_ArrayStoreException =
3317                 builtin_new(class_java_lang_ArrayStoreException);
3318 /*      heap_addreference((void**) &proto_java_lang_ArrayStoreException); */
3319
3320         proto_java_lang_ThreadDeath =                             /* schani */
3321                 builtin_new(class_java_lang_ThreadDeath);
3322 /*      heap_addreference((void**) &proto_java_lang_ThreadDeath); */
3323
3324         loader_inited = 1;
3325 }
3326
3327
3328 /********************* Function: loader_initclasses ****************************
3329
3330         Initializes all loaded but uninitialized classes
3331
3332 *******************************************************************************/
3333
3334 void loader_initclasses ()
3335 {
3336         classinfo *c;
3337         
3338 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3339         pthread_mutex_lock(&compiler_mutex);
3340 #endif
3341
3342         intsDisable();                     /* schani */
3343
3344         if (makeinitializations) {
3345                 c = list_first (&linkedclasses);
3346                 while (c) {
3347                         class_init (c);
3348                         c = list_next (&linkedclasses, c);
3349                         }
3350                 }
3351
3352         intsRestore();                      /* schani */
3353         
3354 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3355         pthread_mutex_unlock(&compiler_mutex);
3356 #endif
3357 }
3358
3359 static s4 classvalue;
3360
3361 static void loader_compute_class_values(classinfo *c)
3362 {
3363         classinfo *subs;
3364
3365         c->vftbl->baseval = ++classvalue;
3366
3367         subs = c->sub;
3368         while (subs != NULL) {
3369                 loader_compute_class_values(subs);
3370                 subs = subs->nextsub;
3371         }
3372         c->vftbl->diffval = classvalue - c->vftbl->baseval;
3373         
3374         /*
3375         {
3376         int i;
3377         for (i = 0; i < c->index; i++)
3378                 printf(" ");
3379         printf("%3d  %3d  ", (int) c->vftbl->baseval, c->vftbl->diffval);
3380         utf_display(c->name);
3381         printf("\n");
3382         }
3383         */
3384 }
3385
3386
3387 void loader_compute_subclasses()
3388 {
3389         classinfo *c;
3390         
3391         intsDisable();                     /* schani */
3392
3393         c = list_first(&linkedclasses);
3394         while (c) {
3395                 if (!(c->flags & ACC_INTERFACE)) {
3396                         c->nextsub = 0;
3397                         c->sub = 0;
3398                 }
3399                 c = list_next (&linkedclasses, c);
3400         }
3401
3402         c = list_first (&linkedclasses);
3403         while (c) {
3404                 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
3405                         c->nextsub = c->super->sub;
3406                         c->super->sub = c;
3407                 }
3408                 c = list_next (&linkedclasses, c);
3409         }
3410
3411         classvalue = 0;
3412 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3413         cast_lock();
3414 #endif
3415         loader_compute_class_values(class_java_lang_Object);
3416 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3417         cast_unlock();
3418 #endif
3419
3420         intsRestore();                      /* schani */
3421 }
3422
3423
3424 /******************** function classloader_buffer ******************************
3425  
3426     sets buffer for reading classdata
3427
3428 *******************************************************************************/
3429
3430 void classload_buffer(u1 *buf, int len)
3431 {
3432         classbuffer      = buf;
3433         classbuffer_size = len;
3434         classbuf_pos     = buf - 1;
3435 }
3436
3437
3438 /******************** Function: loader_close ***********************************
3439
3440         Frees all resources
3441         
3442 *******************************************************************************/
3443
3444 void loader_close()
3445 {
3446         classinfo *c;
3447
3448         while ((c = list_first(&unloadedclasses))) {
3449                 list_remove(&unloadedclasses, c);
3450                 class_free(c);
3451         }
3452         while ((c = list_first(&unlinkedclasses))) {
3453                 list_remove(&unlinkedclasses, c);
3454                 class_free(c);
3455         }
3456         while ((c = list_first(&linkedclasses))) {
3457                 list_remove(&linkedclasses, c);
3458                 class_free(c);
3459         }
3460 }
3461
3462
3463 /*
3464  * These are local overrides for various environment variables in Emacs.
3465  * Please do not remove this and leave it at the end of the file, where
3466  * Emacs will automagically detect them.
3467  * ---------------------------------------------------------------------
3468  * Local variables:
3469  * mode: c
3470  * indent-tabs-mode: t
3471  * c-basic-offset: 4
3472  * tab-width: 4
3473  * End:
3474  */