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