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