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