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