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