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