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