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