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