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