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