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