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