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