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