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