efba3cea6694850cad155fa91210fd7bd1584a95
[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
33    $Id: loader.c 593 2003-11-09 19:50:55Z twisti $
34
35 */
36
37
38 #include <string.h>
39 #include <assert.h>
40 #include <sys/stat.h>
41 #include "global.h"
42 #include "loader.h"
43 #include "native.h"
44 #include "tables.h"
45 #include "builtin.h"
46 #include "jit.h"
47 #include "asmpart.h"
48 #include "toolbox/memory.h"
49 #include "toolbox/loging.h"
50 #include "threads/thread.h"
51
52
53 /* global variables ***********************************************************/
54
55 bool opt_rt = false;            /* true if RTA parse should be used     RT-CO */
56 bool opt_xta = false;           /* true if XTA parse should be used    XTA-CO */
57 bool opt_vta = false;           /* true if VTA parse should be used    VTA-CO */
58
59 int count_class_infos = 0;      /* variables for measurements                 */
60 int count_const_pool_len = 0;
61 int count_vftbl_len = 0;
62 int count_all_methods = 0;
63 int count_vmcode_len = 0;
64 int count_extable_len = 0;
65 int count_class_loads = 0;
66 int count_class_inits = 0;
67
68 bool loadverbose = false;       /* switches for debug messages                */
69 bool linkverbose = false;
70 bool initverbose = false;
71
72 bool makeinitializations = true;
73
74 bool getloadingtime  = false;   /* to measure the runtime                     */
75 long int loadingtime = 0;
76
77 static s4 interfaceindex;       /* sequential numbering of interfaces         */ 
78
79 list unloadedclasses;       /* list of all referenced but not loaded classes  */
80 list unlinkedclasses;       /* list of all loaded but not linked classes      */
81 list linkedclasses;         /* list of all completely linked classes          */
82
83
84 /* utf-symbols for pointer comparison of frequently used strings */
85
86 static utf *utf_innerclasses;           /* InnerClasses                    */
87 static utf *utf_constantvalue;          /* ConstantValue                   */
88 static utf *utf_code;                       /* Code                            */
89 static utf *utf_finalize;                   /* finalize                            */
90 static utf *utf_fidesc;                     /* ()V                                     */
91 static utf *utf_clinit;                     /* <clinit>                            */
92 static utf *utf_initsystemclass;        /* initializeSystemClass   */
93 static utf *utf_systemclass;            /* java/lang/System        */
94
95
96 /* important system classes ***************************************************/
97
98 classinfo *class_java_lang_Object;
99 classinfo *class_java_lang_String;
100 classinfo *class_array = NULL;
101
102 /* stefan */
103 /* These are made static so they cannot be used for throwing in native */
104 /* functions.                                                          */
105 static classinfo *class_java_lang_ClassCastException;
106 static classinfo *class_java_lang_NullPointerException;
107 static classinfo *class_java_lang_ArrayIndexOutOfBoundsException;
108 static classinfo *class_java_lang_NegativeArraySizeException;
109 static classinfo *class_java_lang_OutOfMemoryError;
110 static classinfo *class_java_lang_ArithmeticException;
111 static classinfo *class_java_lang_ArrayStoreException;
112 static classinfo *class_java_lang_ThreadDeath;
113
114
115 /******************************************************************************
116
117    structure for primitive classes: contains the class for wrapping the 
118    primitive type, the primitive class, the name of the class for wrapping, 
119    the one character type signature and the name of the primitive class
120  
121  ******************************************************************************/
122  
123 primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = { 
124         { NULL, NULL, "java/lang/Integer",   'I', "int"     },
125         { NULL, NULL, "java/lang/Long",      'J', "long"    },
126         { NULL, NULL, "java/lang/Float",     'F', "float"   },
127         { NULL, NULL, "java/lang/Double",    'D', "double"  },
128         { NULL, NULL, "java/lang/Byte",      'B', "byte"    },
129         { NULL, NULL, "java/lang/Character", 'C', "char"    },
130         { NULL, NULL, "java/lang/Short",     'S', "short"   },
131         { NULL, NULL, "java/lang/Boolean",   'Z', "boolean" },
132         { NULL, NULL, "java/lang/Void",      'V', "void"    }
133 };
134
135
136 /* instances of important system classes **************************************/
137
138 java_objectheader *proto_java_lang_ClassCastException;
139 java_objectheader *proto_java_lang_NullPointerException;
140 java_objectheader *proto_java_lang_ArrayIndexOutOfBoundsException;
141 java_objectheader *proto_java_lang_NegativeArraySizeException;
142 java_objectheader *proto_java_lang_OutOfMemoryError;
143 java_objectheader *proto_java_lang_ArithmeticException;
144 java_objectheader *proto_java_lang_ArrayStoreException;
145 java_objectheader *proto_java_lang_ThreadDeath;
146
147
148 /************* functions for reading classdata *********************************
149
150     getting classdata in blocks of variable size
151     (8,16,32,64-bit integer or float)
152
153 *******************************************************************************/
154
155 static char *classpath    = "";     /* searchpath for classfiles              */
156 static u1 *classbuffer    = NULL;   /* pointer to buffer with classfile-data  */
157 static u1 *classbuf_pos;            /* current position in classfile buffer   */
158 static int classbuffer_size;        /* size of classfile-data                 */
159
160 /* transfer block of classfile data into a buffer */
161
162 #define suck_nbytes(buffer,len) memcpy(buffer,classbuf_pos+1,len); \
163                                 classbuf_pos+=len;
164
165 /* skip block of classfile data */
166
167 #define skip_nbytes(len) classbuf_pos+=len;
168
169 inline u1 suck_u1()
170 {
171         return *++classbuf_pos;
172 }
173 inline u2 suck_u2()
174 {
175         u1 a=suck_u1(), b=suck_u1();
176         return ((u2)a<<8)+(u2)b;
177 }
178 inline u4 suck_u4()
179 {
180         u1 a=suck_u1(), b=suck_u1(), c=suck_u1(), d=suck_u1();
181         return ((u4)a<<24)+((u4)b<<16)+((u4)c<<8)+(u4)d;
182 }
183 #define suck_s8() (s8) suck_u8()
184 #define suck_s2() (s2) suck_u2()
185 #define suck_s4() (s4) suck_u4()
186 #define suck_s1() (s1) suck_u1()
187
188
189 /* get u8 from classfile data */
190
191 static u8 suck_u8 ()
192 {
193 #if U8_AVAILABLE
194         u8 lo,hi;
195         hi = suck_u4();
196         lo = suck_u4();
197         return (hi<<32) + lo;
198 #else
199         u8 v;
200         v.high = suck_u4();
201         v.low = suck_u4();
202         return v;
203 #endif
204 }
205
206 /* get float from classfile data */
207
208 static float suck_float ()
209 {
210         float f;
211
212 #if !WORDS_BIGENDIAN 
213                 u1 buffer[4];
214                 u2 i;
215                 for (i=0; i<4; i++) buffer[3-i] = suck_u1 ();
216                 memcpy ( (u1*) (&f), buffer, 4);
217 #else 
218                 suck_nbytes ( (u1*) (&f), 4 );
219 #endif
220
221         PANICIF (sizeof(float) != 4, "Incompatible float-format");
222         
223         return f;
224 }
225
226 /* get double from classfile data */
227 static double suck_double ()
228 {
229         double d;
230
231 #if !WORDS_BIGENDIAN 
232                 u1 buffer[8];
233                 u2 i;   
234                 for (i=0; i<8; i++) buffer[7-i] = suck_u1 ();
235                 memcpy ( (u1*) (&d), buffer, 8);
236 #else 
237                 suck_nbytes ( (u1*) (&d), 8 );
238 #endif
239
240         PANICIF (sizeof(double) != 8, "Incompatible double-format" );
241         
242         return d;
243 }
244
245 /************************** function suck_init *********************************
246
247         called once at startup, sets the searchpath for the classfiles
248
249 *******************************************************************************/
250
251 void suck_init (char *cpath)
252 {
253         classpath   = cpath;
254         classbuffer = NULL;
255 }
256
257
258 /************************** function suck_start ********************************
259
260         returns true if classbuffer is already loaded or a file for the
261         specified class has succussfully been read in. All directories of
262         the searchpath are used to find the classfile (<classname>.class).
263         Returns false if no classfile is found and writes an error message. 
264         
265 *******************************************************************************/
266
267
268 bool suck_start (utf *classname) {
269
270 #define MAXFILENAME 1000                /* maximum length of a filename           */
271         
272         char filename[MAXFILENAME+10];  /* room for '.class'                      */    
273         char *pathpos;                  /* position in searchpath                 */
274         char c, *utf_ptr;               /* pointer to the next utf8-character     */
275         FILE *classfile;
276         int  filenamelen, err;
277         struct stat buffer;
278         
279         if (classbuffer)                /* classbuffer is already valid */
280                 return true;
281
282         pathpos = classpath;
283         
284         while (*pathpos) {
285
286                 /* skip path separator */
287
288                 while (*pathpos == ':')
289                         pathpos++;
290  
291                 /* extract directory from searchpath */
292
293                 filenamelen = 0;
294                 while ((*pathpos) && (*pathpos!=':')) {
295                     PANICIF (filenamelen >= MAXFILENAME, "Filename too long") ;
296                         filename[filenamelen++] = *(pathpos++);
297                         }
298
299                 filename[filenamelen++] = '/';  
300    
301                 /* add classname to filename */
302
303                 utf_ptr = classname->text;
304                 while (utf_ptr < utf_end(classname)) {
305                         PANICIF (filenamelen >= MAXFILENAME, "Filename too long");
306                         c = *utf_ptr++;
307                         if ((c <= ' ' || c > 'z') && (c != '/'))     /* invalid character */ 
308                                 c = '?'; 
309                         filename[filenamelen++] = c;    
310                         }
311       
312                 /* add suffix */
313
314                 strcpy (filename+filenamelen, ".class");
315
316                 classfile = fopen(filename, "r");
317                 if (classfile) {                                       /* file exists */
318                         
319                         /* determine size of classfile */
320
321                         err = stat (filename, &buffer);
322
323                         if (!err) {                                /* read classfile data */                            
324                                 classbuffer_size = buffer.st_size;                              
325                                 classbuffer      = MNEW(u1, classbuffer_size);
326                                 classbuf_pos     = classbuffer-1;
327                                 fread(classbuffer, 1, classbuffer_size, classfile);
328                                 fclose(classfile);
329                                 return true;
330                         }
331                 }
332         }
333
334         if (verbose) {
335                 sprintf (logtext, "Warning: Can not open class file '%s'", filename);
336                 dolog();
337         }
338
339         return false;
340 }
341
342
343 /************************** function suck_stop *********************************
344
345         frees memory for buffer with classfile data.
346         Caution: this function may only be called if buffer has been allocated
347                  by suck_start with reading a file
348         
349 *******************************************************************************/
350
351 void suck_stop () {
352
353         /* determine amount of classdata not retrieved by suck-operations         */
354
355         int classdata_left = ((classbuffer+classbuffer_size)-classbuf_pos-1);
356
357         if (classdata_left > 0) {               
358                 /* surplus */           
359                 sprintf (logtext,"There are %d access bytes at end of classfile",
360                          classdata_left);
361                 dolog();
362         }
363
364         /* free memory */
365
366         MFREE(classbuffer, u1, classbuffer_size);
367         classbuffer = NULL;
368 }
369
370 /******************************************************************************/
371 /******************* Some support functions ***********************************/
372 /******************************************************************************/
373
374
375
376 void fprintflags (FILE *fp, u2 f)
377 {
378    if ( f & ACC_PUBLIC )       fprintf (fp," PUBLIC");
379    if ( f & ACC_PRIVATE )      fprintf (fp," PRIVATE");
380    if ( f & ACC_PROTECTED )    fprintf (fp," PROTECTED");
381    if ( f & ACC_STATIC )       fprintf (fp," STATIC");
382    if ( f & ACC_FINAL )        fprintf (fp," FINAL");
383    if ( f & ACC_SYNCHRONIZED ) fprintf (fp," SYNCHRONIZED");
384    if ( f & ACC_VOLATILE )     fprintf (fp," VOLATILE");
385    if ( f & ACC_TRANSIENT )    fprintf (fp," TRANSIENT");
386    if ( f & ACC_NATIVE )       fprintf (fp," NATIVE");
387    if ( f & ACC_INTERFACE )    fprintf (fp," INTERFACE");
388    if ( f & ACC_ABSTRACT )     fprintf (fp," ABSTRACT");
389 }
390
391 /********** internal function: printflags  (only for debugging) ***************/
392 void printflags (u2 f)
393 {
394    if ( f & ACC_PUBLIC )       printf (" PUBLIC");
395    if ( f & ACC_PRIVATE )      printf (" PRIVATE");
396    if ( f & ACC_PROTECTED )    printf (" PROTECTED");
397    if ( f & ACC_STATIC )       printf (" STATIC");
398    if ( f & ACC_FINAL )        printf (" FINAL");
399    if ( f & ACC_SYNCHRONIZED ) printf (" SYNCHRONIZED");
400    if ( f & ACC_VOLATILE )     printf (" VOLATILE");
401    if ( f & ACC_TRANSIENT )    printf (" TRANSIENT");
402    if ( f & ACC_NATIVE )       printf (" NATIVE");
403    if ( f & ACC_INTERFACE )    printf (" INTERFACE");
404    if ( f & ACC_ABSTRACT )     printf (" ABSTRACT");
405 }
406
407
408 /************************* Function: skipattribute *****************************
409
410         skips a (1) 'attribute' structure in the class file
411
412 *******************************************************************************/
413
414 static void skipattribute ()
415 {
416         suck_u2 ();
417         skip_nbytes(suck_u4()); 
418 }
419
420 /********************** Function: skipattributebody ****************************
421
422         skips an attribute after the 16 bit reference to attribute_name has already
423         been read
424         
425 *******************************************************************************/
426
427 static void skipattributebody ()
428 {
429         skip_nbytes(suck_u4());
430 }
431
432 /************************* Function: skipattributes ****************************
433
434         skips num attribute structures
435         
436 *******************************************************************************/
437
438 static void skipattributes (u4 num)
439 {
440         u4 i;
441         for (i = 0; i < num; i++)
442                 skipattribute();
443 }
444
445 /******************** function: innerclass_getconstant ************************
446
447     like class_getconstant, but if cptags is ZERO null is returned                                       
448         
449 *******************************************************************************/
450
451 voidptr innerclass_getconstant (classinfo *c, u4 pos, u4 ctype) 
452 {
453         /* invalid position in constantpool */
454         if (pos >= c->cpcount) 
455                 panic ("Attempt to access constant outside range");
456
457         /* constantpool entry of type 0 */      
458         if (!c->cptags[pos])
459                 return NULL;
460
461         /* check type of constantpool entry */
462         if (c->cptags[pos] != ctype) {
463                 sprintf (logtext, "Type mismatch on constant: %d requested, %d here",
464                  (int) ctype, (int) c->cptags[pos] );
465                 error();
466                 }
467                 
468         return c->cpinfos[pos];
469 }
470
471 /************************ function: attribute_load ****************************
472
473     read attributes from classfile
474         
475 *******************************************************************************/
476
477 static void attribute_load (u4 num, classinfo *c)
478 {
479         u4 i,j;
480
481         for (i = 0; i < num; i++) {
482                 /* retrieve attribute name */   
483                 utf *aname = class_getconstant (c, suck_u2(), CONSTANT_Utf8);
484
485                 if ( aname == utf_innerclasses)  {                      
486                         /* innerclasses attribute */
487                                 
488                         /* skip attribute length */                                             
489                         suck_u4(); 
490                         /* number of records */
491                         c->innerclasscount = suck_u2();
492                         /* allocate memory for innerclass structure */
493                         c->innerclass = MNEW (innerclassinfo, c->innerclasscount);
494
495                         for (j=0;j<c->innerclasscount;j++) {
496                                 
497                                 /*  The innerclass structure contains a class with an encoded name, 
498                                     its defining scope, its simple name  and a bitmask of the access flags. 
499                                     If an inner class is not a member, its outer_class is NULL, 
500                                     if a class is anonymous, its name is NULL.                              */
501                                                                 
502                                 innerclassinfo *info = c->innerclass + j;
503
504                                 info->inner_class = innerclass_getconstant(c, suck_u2(), CONSTANT_Class); /* CONSTANT_Class_info index */
505                                 info->outer_class = innerclass_getconstant(c, suck_u2(), CONSTANT_Class); /* CONSTANT_Class_info index */
506                                 info->name  = innerclass_getconstant(c, suck_u2(), CONSTANT_Utf8);        /* CONSTANT_Utf8_info index  */
507                                 info->flags = suck_u2 ();                                                 /* access_flags bitmask      */
508                         }
509                 } else {
510                         /* unknown attribute */
511                         skipattributebody ();
512                 }
513         }
514 }
515
516 /******************* function: checkfielddescriptor ****************************
517
518         checks whether a field-descriptor is valid and aborts otherwise
519         all referenced classes are inserted into the list of unloaded classes
520         
521 *******************************************************************************/
522
523 static void checkfielddescriptor (char *utf_ptr, char *end_pos)
524 {
525         char *tstart;  /* pointer to start of classname */
526         char ch;
527         
528         switch (*utf_ptr++) {
529         case 'B':
530         case 'C':
531         case 'I':
532         case 'S':
533         case 'Z':  
534         case 'J':  
535         case 'F':  
536         case 'D':
537                 /* primitive type */  
538                 break;
539
540         case 'L':
541                 /* save start of classname */
542                 tstart = utf_ptr;  
543                 
544                 /* determine length of classname */
545                 while ( *utf_ptr++ != ';' )
546                         if (utf_ptr>=end_pos) 
547                                 panic ("Missing ';' in objecttype-descriptor");
548
549                 /* cause loading of referenced class */                 
550                 class_new ( utf_new(tstart, utf_ptr-tstart-1) );
551                 break;
552
553         case '[' : 
554                 /* array type */
555                 while ((ch = *utf_ptr++)=='[') 
556                         /* skip */ ;
557
558                 /* component type of array */
559                 switch (ch) {
560                 case 'B':
561                 case 'C':
562                 case 'I':
563                 case 'S':
564                 case 'Z':  
565                 case 'J':  
566                 case 'F':  
567                 case 'D':
568                         /* primitive type */  
569                         break;
570                         
571                 case 'L':
572                         /* save start of classname */
573                         tstart = utf_ptr;
574                         
575                         /* determine length of classname */
576                         while ( *utf_ptr++ != ';' )
577                                 if (utf_ptr>=end_pos) 
578                                         panic ("Missing ';' in objecttype-descriptor");
579
580                         /* cause loading of referenced class */                 
581                         class_new ( utf_new(tstart, utf_ptr-tstart-1) );
582                         break;
583
584                 default:   
585                         panic ("Ill formed methodtype-descriptor");
586                 }
587                 break;
588                         
589         default:   
590                 panic ("Ill formed methodtype-descriptor");
591         }                       
592
593         /* exceeding characters */              
594         if (utf_ptr!=end_pos) panic ("descriptor has exceeding chars");
595 }
596
597
598 /******************* function checkmethoddescriptor ****************************
599
600     checks whether a method-descriptor is valid and aborts otherwise.
601     All referenced classes are inserted into the list of unloaded classes.
602         
603 *******************************************************************************/
604
605 static void checkmethoddescriptor (utf *d)
606 {
607         char *utf_ptr = d->text;     /* current position in utf text   */
608         char *end_pos = utf_end(d);  /* points behind utf string       */
609         char *tstart;                /* pointer to start of classname  */
610         char c,ch;
611
612         /* method descriptor must start with parenthesis */
613         if (*utf_ptr++ != '(') panic ("Missing '(' in method descriptor");
614
615         /* check arguments */
616         while ((c = *utf_ptr++) != ')') {
617                 switch (c) {
618                 case 'B':
619                 case 'C':
620                 case 'I':
621                 case 'S':
622                 case 'Z':  
623                 case 'J':  
624                 case 'F':  
625                 case 'D':
626                         /* primitive type */  
627                         break;
628
629                 case 'L':
630                         /* save start of classname */ 
631                         tstart = utf_ptr;
632                         
633                         /* determine length of classname */
634                         while ( *utf_ptr++ != ';' )
635                                 if (utf_ptr>=end_pos) 
636                                         panic ("Missing ';' in objecttype-descriptor");
637                         
638                         /* cause loading of referenced class */
639                         class_new ( utf_new(tstart, utf_ptr-tstart-1) );
640                         break;
641            
642                 case '[' :
643                         /* array type */ 
644                         while ((ch = *utf_ptr++)=='[') 
645                                 /* skip */ ;
646
647                         /* component type of array */
648                         switch (ch) {
649                         case 'B':
650                         case 'C':
651                         case 'I':
652                         case 'S':
653                         case 'Z':  
654                         case 'J':  
655                         case 'F':  
656                         case 'D':
657                                 /* primitive type */  
658                                 break;
659
660                         case 'L':
661                                 /* save start of classname */
662                                 tstart = utf_ptr;
663                         
664                                 /* determine length of classname */     
665                                 while ( *utf_ptr++ != ';' )
666                                         if (utf_ptr>=end_pos) 
667                                                 panic ("Missing ';' in objecttype-descriptor");
668
669                                 /* cause loading of referenced class */
670                                 class_new ( utf_new(tstart, utf_ptr-tstart-1) );
671                                 break;
672
673                         default:   
674                                 panic ("Ill formed methodtype-descriptor");
675                         } 
676                         break;
677                         
678                 default:   
679                         panic ("Ill formed methodtype-descriptor");
680                 }                       
681         }
682
683         /* check returntype */
684         if (*utf_ptr=='V') {
685                 /* returntype void */
686                 if ((utf_ptr+1) != end_pos) panic ("Method-descriptor has exceeding chars");
687         }
688         else
689                 /* treat as field-descriptor */
690                 checkfielddescriptor (utf_ptr,end_pos);
691 }
692
693
694 /******************** Function: buildarraydescriptor ***************************
695
696         creates a constant_arraydescriptor structure for the array type named by an
697         utf string
698         
699 *******************************************************************************/
700
701 constant_arraydescriptor * buildarraydescriptor(char *utf_ptr, u4 namelen)
702 {
703         constant_arraydescriptor *d;
704         
705         if (*utf_ptr++ != '[') panic ("Attempt to build arraydescriptor for non-array");
706
707         d = NEW (constant_arraydescriptor);
708         d -> objectclass = NULL;
709         d -> elementdescriptor = NULL;
710
711 #ifdef STATISTICS
712         count_const_pool_len += sizeof(constant_arraydescriptor);
713 #endif
714
715         switch (*utf_ptr) {
716         case 'Z': d -> arraytype = ARRAYTYPE_BOOLEAN; break;
717         case 'B': d -> arraytype = ARRAYTYPE_BYTE; break;
718         case 'C': d -> arraytype = ARRAYTYPE_CHAR; break;
719         case 'D': d -> arraytype = ARRAYTYPE_DOUBLE; break;
720         case 'F': d -> arraytype = ARRAYTYPE_FLOAT; break;
721         case 'I': d -> arraytype = ARRAYTYPE_INT; break;
722         case 'J': d -> arraytype = ARRAYTYPE_LONG; break;
723         case 'S': d -> arraytype = ARRAYTYPE_SHORT; break;
724
725         case '[':
726                 d -> arraytype = ARRAYTYPE_ARRAY; 
727                 d -> elementdescriptor = buildarraydescriptor (utf_ptr, namelen-1);
728                 break;
729                 
730         case 'L':
731                 d -> arraytype = ARRAYTYPE_OBJECT;
732
733                 d -> objectclass = class_new ( utf_new(utf_ptr+1, namelen-3) );
734                 d -> objectclass  -> classUsed = NOTUSED; /* not used initially CO-RT */
735                 d -> objectclass  -> impldBy = NULL;
736                 break;
737         }
738         return d;
739 }
740
741
742 /******************* Function: freearraydescriptor *****************************
743
744         removes a structure created by buildarraydescriptor from memory
745         
746 *******************************************************************************/
747
748 static void freearraydescriptor (constant_arraydescriptor *d)
749 {
750         while (d) {
751                 constant_arraydescriptor *n = d->elementdescriptor;
752                 FREE (d, constant_arraydescriptor);
753                 d = n;
754                 }
755 }
756
757 /*********************** Function: displayarraydescriptor *********************/
758
759 static void displayarraydescriptor (constant_arraydescriptor *d)
760 {
761         switch (d->arraytype) {
762         case ARRAYTYPE_BOOLEAN: printf ("boolean[]"); break;
763         case ARRAYTYPE_BYTE: printf ("byte[]"); break;
764         case ARRAYTYPE_CHAR: printf ("char[]"); break;
765         case ARRAYTYPE_DOUBLE: printf ("double[]"); break;
766         case ARRAYTYPE_FLOAT: printf ("float[]"); break;
767         case ARRAYTYPE_INT: printf ("int[]"); break;
768         case ARRAYTYPE_LONG: printf ("long[]"); break;
769         case ARRAYTYPE_SHORT: printf ("short[]"); break;
770         case ARRAYTYPE_ARRAY: displayarraydescriptor(d->elementdescriptor); printf("[]"); break;
771         case ARRAYTYPE_OBJECT: utf_display(d->objectclass->name); printf("[]"); break;
772         }
773 }
774
775
776
777 /******************************************************************************/
778 /**************************  Functions for fields  ****************************/
779 /******************************************************************************/
780
781
782 /************************ Function: field_load *********************************
783
784         Load everything about a class field from the class file and fill a
785         'fieldinfo' structure. For static fields, space in the data segment is
786         allocated.
787
788 *******************************************************************************/
789
790 static void field_load (fieldinfo *f, classinfo *c)
791 {
792         u4 attrnum,i;
793         u4 jtype;
794
795         f -> flags = suck_u2 ();                                           /* ACC flags                   */
796         f -> name = class_getconstant (c, suck_u2(), CONSTANT_Utf8);       /* name of field               */
797         f -> descriptor = class_getconstant (c, suck_u2(), CONSTANT_Utf8); /* JavaVM descriptor           */
798         f -> type = jtype = desc_to_type (f->descriptor);                  /* data type                   */
799         f -> offset = 0;                                                   /* offset from start of object */
800         f->xta = NULL;
801         
802         switch (f->type) {
803         case TYPE_INT:        f->value.i = 0; break;
804         case TYPE_FLOAT:      f->value.f = 0.0; break;
805         case TYPE_DOUBLE:     f->value.d = 0.0; break;
806         case TYPE_ADDRESS:    f->value.a = NULL;                              
807                               heap_addreference (&(f->value.a));           /* make global reference (GC)  */    
808                               break;
809         case TYPE_LONG:
810 #if U8_AVAILABLE
811                 f->value.l = 0; break;
812 #else
813                 f->value.l.low = 0; f->value.l.high = 0; break;
814 #endif 
815         }
816
817         /* read attributes */
818         attrnum = suck_u2();
819         for (i=0; i<attrnum; i++) {
820                 u4 pindex;
821                 utf *aname;
822
823                 aname = class_getconstant (c, suck_u2(), CONSTANT_Utf8);
824                 
825                 if ( aname != utf_constantvalue ) {
826                         /* unknown attribute */
827                         skipattributebody ();
828                         }
829                 else {
830                         /* constant value attribute */
831                         
832                         /* skip attribute length */
833                         suck_u4();
834                         /* index of value in constantpool */            
835                         pindex = suck_u2();
836                 
837                         /* initialize field with value from constantpool */             
838                         switch (jtype) {
839                                 case TYPE_INT: {
840                                         constant_integer *ci = 
841                                                 class_getconstant(c, pindex, CONSTANT_Integer);
842                                         f->value.i = ci -> value;
843                                         }
844                                         break;
845                                         
846                                 case TYPE_LONG: {
847                                         constant_long *cl = 
848                                            class_getconstant(c, pindex, CONSTANT_Long);
849         
850                                         f->value.l = cl -> value;
851                                         }
852                                         break;
853
854                                 case TYPE_FLOAT: {
855                                         constant_float *cf = 
856                                             class_getconstant(c, pindex, CONSTANT_Float);
857         
858                                         f->value.f = cf->value;
859                                         }
860                                         break;
861                                                                                         
862                                 case TYPE_DOUBLE: {
863                                         constant_double *cd = 
864                                             class_getconstant(c, pindex, CONSTANT_Double);
865         
866                                         f->value.d = cd->value;
867                                         }
868                                         break;
869                                                 
870                                 case TYPE_ADDRESS: { 
871                                         utf *u = class_getconstant(c, pindex, CONSTANT_String);
872                                         /* create javastring from compressed utf8-string */                                     
873                                         f->value.a = literalstring_new(u);
874                                         }
875                                         break;
876         
877                                 default: 
878                                         log_text ("Invalid Constant - Type");
879
880                                 }
881
882                         }
883                 }
884 }
885
886
887 /********************** function: field_free **********************************/
888
889 static void field_free (fieldinfo *f)
890 {
891         /* empty */
892 }
893
894
895 /**************** Function: field_display (debugging only) ********************/
896
897 void field_display (fieldinfo *f)
898 {
899         printf ("   ");
900         printflags (f -> flags);
901         printf (" ");
902         utf_display (f -> name);
903         printf (" ");
904         utf_display (f -> descriptor);  
905         printf (" offset: %ld\n", (long int) (f -> offset) );
906 }
907
908
909 /******************************************************************************/
910 /************************* Functions for methods ******************************/ 
911 /******************************************************************************/
912
913
914 /*********************** Function: method_load *********************************
915
916         Loads a method from the class file and fills an existing 'methodinfo'
917         structure. For native methods, the function pointer field is set to the
918         real function pointer, for JavaVM methods a pointer to the compiler is used
919         preliminarily.
920         
921 *******************************************************************************/
922
923 static void method_load (methodinfo *m, classinfo *c)
924 {
925         u4 attrnum,i,e;
926         
927 #ifdef STATISTICS
928         count_all_methods++;
929 #endif
930
931         m -> class = c;
932         
933         m -> flags = suck_u2 ();
934         m -> name =  class_getconstant (c, suck_u2(), CONSTANT_Utf8);
935         m -> descriptor = class_getconstant (c, suck_u2(), CONSTANT_Utf8);
936         
937         m -> jcode = NULL;
938         m -> exceptiontable = NULL;
939         m -> entrypoint = NULL;
940         m -> mcode = NULL;
941         m -> stubroutine = NULL;
942         m -> methodUsed = NOTUSED;    
943         m -> monoPoly = MONO;    
944         m -> subRedefs = 0;
945         m -> subRedefsUsed = 0;
946
947         m->xta = NULL;
948         
949         if (! (m->flags & ACC_NATIVE) ) {
950                 m -> stubroutine = createcompilerstub (m);
951                 }
952         else {
953
954                 functionptr f = native_findfunction 
955                        (c->name, m->name, m->descriptor, (m->flags & ACC_STATIC) != 0);
956                 if (f) {
957                         m -> stubroutine = createnativestub (f, m);
958                         }
959                 }
960         
961         
962         attrnum = suck_u2();
963         for (i=0; i<attrnum; i++) {
964                 utf *aname;
965
966                 aname = class_getconstant (c, suck_u2(), CONSTANT_Utf8);
967
968                 if ( aname != utf_code)  {
969                         skipattributebody ();
970                         }
971                 else {
972                         if (m -> jcode) panic ("Two code-attributes for one method!");
973                         
974                         suck_u4();
975                         m -> maxstack = suck_u2();
976                         m -> maxlocals = suck_u2();
977                         m -> jcodelength = suck_u4();
978                         m -> jcode = MNEW (u1, m->jcodelength);
979                         suck_nbytes (m->jcode, m->jcodelength);
980                         m -> exceptiontablelength = suck_u2 ();
981                         m -> exceptiontable = 
982                            MNEW (exceptiontable, m->exceptiontablelength);
983
984 #ifdef STATISTICS
985         count_vmcode_len += m->jcodelength + 18;
986         count_extable_len += 8 * m->exceptiontablelength;
987 #endif
988
989                         for (e=0; e < m->exceptiontablelength; e++) {
990                                 u4 idx;
991                                 m -> exceptiontable[e].startpc = suck_u2();
992                                 m -> exceptiontable[e].endpc = suck_u2();
993                                 m -> exceptiontable[e].handlerpc = suck_u2();
994
995                                 idx = suck_u2();
996                                 if (!idx) m -> exceptiontable[e].catchtype = NULL;
997                                 else {
998                                         m -> exceptiontable[e].catchtype = 
999                                       class_getconstant (c, idx, CONSTANT_Class);
1000                                         }
1001                                 }                       
1002
1003                         skipattributes ( suck_u2() );
1004                         }
1005                         
1006                 }
1007
1008 }
1009
1010 /********************* Function: method_free ***********************************
1011
1012         frees all memory that was allocated for this method
1013
1014 *******************************************************************************/
1015
1016 static void method_free (methodinfo *m)
1017 {
1018         if (m->jcode) MFREE (m->jcode, u1, m->jcodelength);
1019         if (m->exceptiontable) 
1020                 MFREE (m->exceptiontable, exceptiontable, m->exceptiontablelength);
1021         if (m->mcode) CFREE (m->mcode, m->mcodelength);
1022         if (m->stubroutine) {
1023                 if (m->flags & ACC_NATIVE) removenativestub (m->stubroutine);
1024                 else                       removecompilerstub (m->stubroutine);
1025                 }
1026 }
1027
1028
1029 /************** Function: method_display  (debugging only) **************/
1030
1031 void method_display (methodinfo *m)
1032 {
1033         printf ("   ");
1034         printflags (m -> flags);
1035         printf (" ");
1036         utf_display (m -> name);
1037         printf (" "); 
1038         utf_display (m -> descriptor);
1039         printf ("\n");
1040 }
1041
1042
1043 /******************** Function: method_canoverwrite ****************************
1044
1045         Check if m and old are identical with respect to type and name. This means
1046         that old can be overwritten with m.
1047         
1048 *******************************************************************************/  
1049
1050 static bool method_canoverwrite (methodinfo *m, methodinfo *old)
1051 {
1052         if (m->name != old->name) return false;
1053         if (m->descriptor != old->descriptor) return false;
1054         if (m->flags & ACC_STATIC) return false;
1055         return true;
1056 }
1057
1058
1059
1060
1061 /******************************************************************************/
1062 /************************ Functions for class *********************************/
1063 /******************************************************************************/
1064
1065
1066 /******************** function:: class_getconstant ******************************
1067
1068         retrieves the value at position 'pos' of the constantpool of a class
1069         if the type of the value is other than 'ctype' the system is stopped
1070
1071 *******************************************************************************/
1072
1073 voidptr class_getconstant (classinfo *c, u4 pos, u4 ctype) 
1074 {
1075         /* invalid position in constantpool */  
1076         if (pos >= c->cpcount) 
1077                 panic ("Attempt to access constant outside range");
1078
1079         /* check type of constantpool entry */
1080         if (c->cptags[pos] != ctype) {
1081                 sprintf (logtext, "Type mismatch on constant: %d requested, %d here",
1082                  (int) ctype, (int) c->cptags[pos] );
1083                 error();
1084                 }
1085                 
1086         return c->cpinfos[pos];
1087 }
1088
1089
1090 /********************* Function: class_constanttype ****************************
1091
1092         Determines the type of a class entry in the ConstantPool
1093         
1094 *******************************************************************************/
1095
1096 u4 class_constanttype (classinfo *c, u4 pos)
1097 {
1098         if (pos >= c->cpcount) 
1099                 panic ("Attempt to access constant outside range");
1100         return c->cptags[pos];
1101 }
1102
1103
1104 /******************** function: class_loadcpool ********************************
1105
1106         loads the constantpool of a class, 
1107         the entries are transformed into a simpler format 
1108         by resolving references
1109         (a detailed overview of the compact structures can be found in global.h)        
1110
1111 *******************************************************************************/
1112
1113 static void class_loadcpool (classinfo *c)
1114 {
1115
1116         /* The following structures are used to save information which cannot be 
1117            processed during the first pass. After the complete constantpool has 
1118            been traversed the references can be resolved. 
1119            (only in specific order)                                                */
1120         
1121         /* CONSTANT_Class_info entries */
1122         typedef struct forward_class {      
1123                 struct forward_class *next; 
1124                 u2 thisindex;               
1125                 u2 name_index;              
1126         } forward_class;                    
1127                                         
1128         /* CONSTANT_String */                                      
1129         typedef struct forward_string { 
1130                 struct forward_string *next; 
1131                 u2 thisindex;                
1132                 u2 string_index;
1133         } forward_string;
1134
1135         /* CONSTANT_NameAndType */
1136         typedef struct forward_nameandtype {
1137                 struct forward_nameandtype *next;
1138                 u2 thisindex;
1139                 u2 name_index;
1140                 u2 sig_index;
1141         } forward_nameandtype;
1142
1143         /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
1144         typedef struct forward_fieldmethint {   
1145                 struct forward_fieldmethint *next;
1146                 u2 thisindex;
1147                 u1 tag;
1148                 u2 class_index;
1149                 u2 nameandtype_index;
1150         } forward_fieldmethint;
1151
1152
1153         u4 idx;
1154         long int dumpsize = dump_size ();
1155
1156         forward_class *forward_classes = NULL;
1157         forward_string *forward_strings = NULL;
1158         forward_nameandtype *forward_nameandtypes = NULL;
1159         forward_fieldmethint *forward_fieldmethints = NULL;
1160
1161         /* number of entries in the constant_pool table  */
1162         u4 cpcount       = c -> cpcount = suck_u2();
1163         /* allocate memory */
1164         u1 *cptags       = c -> cptags  = MNEW (u1, cpcount);
1165         voidptr *cpinfos = c -> cpinfos = MNEW (voidptr, cpcount);
1166
1167 #ifdef STATISTICS
1168         count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
1169 #endif
1170         
1171         /* initialize constantpool */
1172         for (idx=0; idx<cpcount; idx++) {
1173                 cptags[idx] = CONSTANT_UNUSED;
1174                 cpinfos[idx] = NULL;
1175                 }
1176
1177                         
1178                 /******* first pass *******/
1179                 /* entries which cannot be resolved now are written into 
1180                    temporary structures and traversed again later        */
1181                    
1182         idx = 1;
1183         while (idx < cpcount) {
1184                 /* get constant type */
1185                 u4 t = suck_u1 (); 
1186                 switch ( t ) {
1187
1188                         case CONSTANT_Class: { 
1189                                 forward_class *nfc = DNEW(forward_class);
1190
1191                                 nfc -> next = forward_classes;                                                                                  
1192                                 forward_classes = nfc;
1193
1194                                 nfc -> thisindex = idx;
1195                                 /* reference to CONSTANT_NameAndType */
1196                                 nfc -> name_index = suck_u2 (); 
1197
1198                                 idx++;
1199                                 break;
1200                                 }
1201                         
1202                         case CONSTANT_Fieldref:
1203                         case CONSTANT_Methodref:
1204                         case CONSTANT_InterfaceMethodref: { 
1205                                 forward_fieldmethint *nff = DNEW (forward_fieldmethint);
1206                                 
1207                                 nff -> next = forward_fieldmethints;
1208                                 forward_fieldmethints = nff;
1209
1210                                 nff -> thisindex = idx;
1211                                 /* constant type */
1212                                 nff -> tag = t;
1213                                 /* class or interface type that contains the declaration of the field or method */
1214                                 nff -> class_index = suck_u2 (); 
1215                                 /* name and descriptor of the field or method */
1216                                 nff -> nameandtype_index = suck_u2 ();
1217
1218                                 idx ++;
1219                                 break;
1220                                 }
1221                                 
1222                         case CONSTANT_String: {
1223                                 forward_string *nfs = DNEW (forward_string);
1224                                 
1225                                 nfs -> next = forward_strings;
1226                                 forward_strings = nfs;
1227                                 
1228                                 nfs -> thisindex = idx;
1229                                 /* reference to CONSTANT_Utf8_info with string characters */
1230                                 nfs -> string_index = suck_u2 ();
1231                                 
1232                                 idx ++;
1233                                 break;
1234                                 }
1235
1236                         case CONSTANT_NameAndType: {
1237                                 forward_nameandtype *nfn = DNEW (forward_nameandtype);
1238                                 
1239                                 nfn -> next = forward_nameandtypes;
1240                                 forward_nameandtypes = nfn;
1241                                 
1242                                 nfn -> thisindex = idx;
1243                                 /* reference to CONSTANT_Utf8_info containing simple name */
1244                                 nfn -> name_index = suck_u2 ();
1245                                 /* reference to CONSTANT_Utf8_info containing field or method descriptor */
1246                                 nfn -> sig_index = suck_u2 ();
1247                                 
1248                                 idx ++;
1249                                 break;
1250                                 }
1251
1252                         case CONSTANT_Integer: {
1253                                 constant_integer *ci = NEW (constant_integer);
1254
1255 #ifdef STATISTICS
1256         count_const_pool_len += sizeof(constant_integer);
1257 #endif
1258
1259                                 ci -> value = suck_s4 ();
1260                                 cptags [idx] = CONSTANT_Integer;
1261                                 cpinfos [idx] = ci;
1262                                 idx ++;
1263                                 
1264                                 break;
1265                                 }
1266                                 
1267                         case CONSTANT_Float: {
1268                                 constant_float *cf = NEW (constant_float);
1269
1270 #ifdef STATISTICS
1271         count_const_pool_len += sizeof(constant_float);
1272 #endif
1273
1274                                 cf -> value = suck_float ();
1275                                 cptags [idx] = CONSTANT_Float;
1276                                 cpinfos[idx] = cf;
1277                                 idx ++;
1278                                 break;
1279                                 }
1280                                 
1281                         case CONSTANT_Long: {
1282                                 constant_long *cl = NEW(constant_long);
1283                                         
1284 #ifdef STATISTICS
1285         count_const_pool_len += sizeof(constant_long);
1286 #endif
1287
1288                                 cl -> value = suck_s8 ();
1289                                 cptags [idx] = CONSTANT_Long;
1290                                 cpinfos [idx] = cl;
1291                                 idx += 2;
1292                                 break;
1293                                 }
1294                         
1295                         case CONSTANT_Double: {
1296                                 constant_double *cd = NEW(constant_double);
1297                                 
1298 #ifdef STATISTICS
1299         count_const_pool_len += sizeof(constant_double);
1300 #endif
1301
1302                                 cd -> value = suck_double ();
1303                                 cptags [idx] = CONSTANT_Double;
1304                                 cpinfos [idx] = cd;
1305                                 idx += 2;
1306                                 break;
1307                                 }
1308                                 
1309                         case CONSTANT_Utf8: { 
1310
1311                                 /* number of bytes in the bytes array (not string-length) */
1312                                 u4 length = suck_u2();
1313                                 cptags [idx]  = CONSTANT_Utf8;
1314                                 /* insert utf-string into the utf-symboltable */
1315                                 cpinfos [idx] = utf_new(classbuf_pos+1, length);
1316                                 /* skip bytes of the string */
1317                                 skip_nbytes(length);
1318                                 idx++;
1319                                 break;
1320                                 }
1321                                                                                 
1322                         default:
1323                                 sprintf (logtext, "Unkown constant type: %d",(int) t);
1324                                 error ();
1325                 
1326                         }  /* end switch */
1327                         
1328                 } /* end while */
1329                 
1330
1331
1332            /* resolve entries in temporary structures */
1333
1334         while (forward_classes) {
1335                 utf *name =
1336                   class_getconstant (c, forward_classes -> name_index, CONSTANT_Utf8);
1337                 
1338                 if ( (name->blength>0) && (name->text[0]=='[') ) {
1339                         /* check validity of descriptor */
1340                         checkfielddescriptor (name->text, utf_end(name)); 
1341
1342                         cptags  [forward_classes -> thisindex] = CONSTANT_Arraydescriptor;
1343                         cpinfos [forward_classes -> thisindex] = 
1344                            buildarraydescriptor(name->text, name->blength);
1345
1346                         }
1347                 else {                                  
1348                         cptags  [forward_classes -> thisindex] = CONSTANT_Class;
1349                         /* retrieve class from class-table */
1350                         cpinfos [forward_classes -> thisindex] = class_new (name);
1351                         }
1352                 forward_classes = forward_classes -> next;
1353                 
1354                 }
1355
1356         while (forward_strings) {
1357                 utf *text = 
1358                   class_getconstant (c, forward_strings -> string_index, CONSTANT_Utf8);
1359         
1360                 /* resolve utf-string */                
1361                 cptags   [forward_strings -> thisindex] = CONSTANT_String;
1362                 cpinfos  [forward_strings -> thisindex] = text;
1363                 
1364                 forward_strings = forward_strings -> next;
1365                 }       
1366
1367         while (forward_nameandtypes) {
1368                 constant_nameandtype *cn = NEW (constant_nameandtype);  
1369
1370 #ifdef STATISTICS
1371                 count_const_pool_len += sizeof(constant_nameandtype);
1372 #endif
1373
1374                 /* resolve simple name and descriptor */
1375                 cn -> name = class_getconstant 
1376                    (c, forward_nameandtypes -> name_index, CONSTANT_Utf8);
1377                 cn -> descriptor = class_getconstant
1378                    (c, forward_nameandtypes -> sig_index, CONSTANT_Utf8);
1379                  
1380                 cptags   [forward_nameandtypes -> thisindex] = CONSTANT_NameAndType;
1381                 cpinfos  [forward_nameandtypes -> thisindex] = cn;
1382                 
1383                 forward_nameandtypes = forward_nameandtypes -> next;
1384                 }
1385
1386
1387         while (forward_fieldmethints)  {
1388                 constant_nameandtype *nat;
1389                 constant_FMIref *fmi = NEW (constant_FMIref);
1390
1391 #ifdef STATISTICS
1392                 count_const_pool_len += sizeof(constant_FMIref);
1393 #endif
1394                 /* resolve simple name and descriptor */
1395                 nat = class_getconstant
1396                         (c, forward_fieldmethints -> nameandtype_index, CONSTANT_NameAndType);
1397
1398                 fmi -> class = class_getconstant 
1399                         (c, forward_fieldmethints -> class_index, CONSTANT_Class);
1400                 fmi -> name = nat -> name;
1401                 fmi -> descriptor = nat -> descriptor;
1402
1403                 cptags [forward_fieldmethints -> thisindex] = forward_fieldmethints -> tag;
1404                 cpinfos [forward_fieldmethints -> thisindex] = fmi;
1405         
1406                 switch (forward_fieldmethints -> tag) {
1407                 case CONSTANT_Fieldref:  /* check validity of descriptor */
1408                                          checkfielddescriptor (fmi->descriptor->text,utf_end(fmi->descriptor));
1409                                          break;
1410                 case CONSTANT_InterfaceMethodref: 
1411                 case CONSTANT_Methodref: /* check validity of descriptor */
1412                                          checkmethoddescriptor (fmi->descriptor);
1413                                          break;
1414                 }               
1415         
1416                 forward_fieldmethints = forward_fieldmethints -> next;
1417
1418                 }
1419
1420
1421         dump_release (dumpsize);
1422 }
1423
1424
1425 /********************** Function: class_load ***********************************
1426         
1427         Loads everything interesting about a class from the class file. The
1428         'classinfo' structure must have been allocated previously.
1429
1430         The super class and the interfaces implemented by this class need not be
1431         loaded. The link is set later by the function 'class_link'.
1432
1433         The loaded class is removed from the list 'unloadedclasses' and added to
1434         the list 'unlinkedclasses'.
1435         
1436 *******************************************************************************/
1437
1438 static int class_load (classinfo *c)
1439 {
1440         u4 i;
1441         u4 mi,ma;
1442
1443 #ifdef STATISTICS
1444         count_class_loads++;
1445 #endif
1446
1447         /* output for debugging purposes */
1448         if (loadverbose) {              
1449
1450                 sprintf (logtext, "Loading class: ");
1451                 utf_sprint (logtext+strlen(logtext), c->name );
1452                 dolog();
1453                 }
1454         
1455         /* load classdata, throw exception on error */
1456         if (!suck_start (c->name)) {
1457                 throw_classnotfoundexception();            
1458                 return false;
1459         }
1460         
1461         /* check signature */           
1462         if (suck_u4() != MAGIC) panic("Can not find class-file signature");     
1463         /* check version */
1464         mi = suck_u2(); 
1465         ma = suck_u2();
1466         if (ma != MAJOR_VERSION && (ma != MAJOR_VERSION+1 || mi != 0)) {
1467                 sprintf (logtext, "File version %d.%d is not supported",
1468                                  (int) ma, (int) mi);
1469                 error();
1470                 }
1471
1472
1473         class_loadcpool (c);
1474         
1475         c -> classUsed = NOTUSED; /* not used initially CO-RT */
1476         c -> impldBy = NULL;
1477
1478         /* ACC flags */
1479         c -> flags = suck_u2 (); 
1480         /* this class */
1481         suck_u2 ();       
1482         
1483         /* retrieve superclass */
1484         if ( (i = suck_u2 () ) ) {
1485                 c -> super = class_getconstant (c, i, CONSTANT_Class);
1486                 }
1487         else {
1488                 c -> super = NULL;
1489                 }
1490                          
1491         /* retrieve interfaces */
1492         c -> interfacescount = suck_u2 ();
1493         c -> interfaces = MNEW (classinfo*, c -> interfacescount);
1494         for (i=0; i < c -> interfacescount; i++) {
1495                 c -> interfaces [i] = 
1496                       class_getconstant (c, suck_u2(), CONSTANT_Class);
1497                 }
1498
1499         /* load fields */
1500         c -> fieldscount = suck_u2 ();
1501         c -> fields = GCNEW (fieldinfo, c -> fieldscount);
1502         for (i=0; i < c -> fieldscount; i++) {
1503                 field_load (&(c->fields[i]), c);
1504                 }
1505
1506         /* load methods */
1507         c -> methodscount = suck_u2 ();
1508         c -> methods = MNEW (methodinfo, c -> methodscount);
1509         for (i=0; i < c -> methodscount; i++) {
1510                 method_load (&(c -> methods [i]), c);
1511                 }
1512
1513 #ifdef STATISTICS
1514         count_class_infos += sizeof(classinfo*) * c -> interfacescount;
1515         count_class_infos += sizeof(fieldinfo) * c -> fieldscount;
1516         count_class_infos += sizeof(methodinfo) * c -> methodscount;
1517 #endif
1518
1519         /* load variable-length attribute structures */ 
1520         attribute_load (suck_u2(), c);
1521
1522         /* free memory */
1523         suck_stop ();
1524
1525         /* remove class from list of unloaded classes and 
1526            add to list of unlinked classes                */
1527         list_remove (&unloadedclasses, c);
1528         list_addlast (&unlinkedclasses, c);
1529
1530         return true;
1531 }
1532
1533
1534
1535 /************** internal Function: class_highestinterface ***********************
1536
1537         Used by the function class_link to determine the amount of memory needed
1538         for the interface table.
1539
1540 *******************************************************************************/
1541
1542 static s4 class_highestinterface (classinfo *c) 
1543 {
1544         s4 h;
1545         s4 i;
1546         
1547         if ( ! (c->flags & ACC_INTERFACE) ) {
1548                 sprintf (logtext, "Interface-methods count requested for non-interface:  ");
1549         utf_sprint (logtext+strlen(logtext), c->name);
1550         error();
1551         }
1552     
1553     h = c->index;
1554         for (i=0; i<c->interfacescount; i++) {
1555                 s4 h2 = class_highestinterface (c->interfaces[i]);
1556                 if (h2>h) h=h2;
1557                 }
1558         return h;
1559 }
1560
1561
1562 /* class_addinterface **********************************************************
1563
1564         Is needed by class_link for adding a VTBL to a class. All interfaces
1565         implemented by ic are added as well.
1566
1567 *******************************************************************************/        
1568
1569 static void class_addinterface (classinfo *c, classinfo *ic)
1570 {
1571         s4     j, m;
1572         s4     i     = ic->index;
1573         vftbl *vftbl = c->vftbl;
1574         
1575         if (i >= vftbl->interfacetablelength)
1576                 panic ("Inernal error: interfacetable overflow");
1577         if (vftbl->interfacetable[-i])
1578                 return;
1579
1580         if (ic->methodscount == 0) {  /* fake entry needed for subtype test */
1581                 vftbl->interfacevftbllength[i] = 1;
1582                 vftbl->interfacetable[-i] = MNEW(methodptr, 1);
1583                 vftbl->interfacetable[-i][0] = NULL;
1584                 }
1585         else {
1586                 vftbl->interfacevftbllength[i] = ic->methodscount;
1587                 vftbl->interfacetable[-i] = MNEW(methodptr, ic->methodscount); 
1588
1589 #ifdef STATISTICS
1590         count_vftbl_len += sizeof(methodptr) *
1591                                  (ic->methodscount + (ic->methodscount == 0));
1592 #endif
1593
1594                 for (j=0; j<ic->methodscount; j++) {
1595                         classinfo *sc = c;
1596                         while (sc) {
1597                                 for (m = 0; m < sc->methodscount; m++) {
1598                                         methodinfo *mi = &(sc->methods[m]);
1599                                         if (method_canoverwrite(mi, &(ic->methods[j]))) {
1600                                                 vftbl->interfacetable[-i][j] = 
1601                                                                           vftbl->table[mi->vftblindex];
1602                                                 goto foundmethod;
1603                                                 }
1604                                         }
1605                                 sc = sc->super;
1606                                 }
1607                          foundmethod: ;
1608                         }
1609                 }
1610
1611         for (j = 0; j < ic->interfacescount; j++) 
1612                 class_addinterface(c, ic->interfaces[j]);
1613 }
1614
1615
1616 /********************** Function: class_link ***********************************
1617
1618         Tries to link a class. The super class and every implemented interface must
1619         already have been linked. The function calculates the length in bytes that
1620         an instance of this class requires as well as the VTBL for methods and
1621         interface methods.
1622         
1623         If the class can be linked, it is removed from the list 'unlinkedclasses'
1624         and added to 'linkedclasses'. Otherwise, it is moved to the end of
1625         'unlinkedclasses'.
1626
1627         Attention: If cyclical class definitions are encountered, the program gets
1628         into an infinite loop (we'll have to work that out)
1629
1630 *******************************************************************************/
1631
1632 void class_link(classinfo *c)
1633 {
1634         s4 supervftbllength;          /* vftbllegnth of super class               */
1635         s4 vftbllength;               /* vftbllength of current class             */
1636         s4 interfacetablelength;      /* interface table length                   */
1637         classinfo *super = c->super;  /* super class                              */
1638         classinfo *ic, *c2;           /* intermediate class variables             */
1639         vftbl *v;                     /* vftbl of current class                   */
1640         s4 i;                         /* interface/method/field counter           */                     
1641
1642
1643         /*  check if all superclasses are already linked, if not put c at end of
1644             unlinked list and return. Additionally initialize class fields.       */
1645
1646         /*  check interfaces */
1647
1648         for (i = 0; i < c->interfacescount; i++) {
1649                 ic = c->interfaces[i];
1650                 if (!ic->linked) {
1651                         list_remove(&unlinkedclasses, c);
1652                         list_addlast(&unlinkedclasses, c);
1653                         return; 
1654                 }
1655         }
1656         
1657         /*  check super class */
1658
1659         if (super == NULL) {          /* class java.long.Object */
1660                 c->index = 0;
1661         c->classUsed = USED;     /* Object class is always used CO-RT*/
1662                 c -> impldBy = NULL;
1663                 c->instancesize = sizeof(java_objectheader);
1664                 
1665                 vftbllength = supervftbllength = 0;
1666
1667                 c->finalizer = NULL;
1668         }
1669         else {
1670                 if (!super->linked) {
1671                         list_remove(&unlinkedclasses, c);
1672                         list_addlast(&unlinkedclasses, c);
1673                         return; 
1674                 }
1675
1676                 if (c->flags & ACC_INTERFACE)
1677                         c->index = interfaceindex++;
1678                 else
1679                         c->index = super->index + 1;
1680                 
1681                 c->instancesize = super->instancesize;
1682                 
1683                 vftbllength = supervftbllength = super->vftbl->vftbllength;
1684                 
1685                 c->finalizer = super->finalizer;
1686         }
1687
1688
1689         if (linkverbose) {
1690                 sprintf (logtext, "Linking Class: ");
1691                 utf_sprint (logtext+strlen(logtext), c->name );
1692                 dolog ();
1693         }
1694
1695         /* compute vftbl length */
1696
1697         for (i = 0; i < c->methodscount; i++) {
1698                 methodinfo *m = &(c->methods[i]);
1699                         
1700                 if (!(m->flags & ACC_STATIC)) { /* is instance method */
1701                         classinfo *sc = super;
1702                         while (sc) {
1703                                 int j;
1704                                 for (j = 0; j < sc->methodscount; j++) {
1705                                         if (method_canoverwrite(m, &(sc->methods[j]))) {
1706                                                 m->vftblindex = sc->methods[j].vftblindex;
1707                                                 goto foundvftblindex;
1708                                         }
1709                                 }
1710                                 sc = sc->super;
1711                         }
1712                         m->vftblindex = (vftbllength++);
1713                 foundvftblindex: ;
1714                 }
1715         }       
1716         
1717 #ifdef STATISTICS
1718         count_vftbl_len += sizeof(vftbl) + sizeof(methodptr)*(vftbllength-1);
1719 #endif
1720
1721         /* compute interfacetable length */
1722
1723         interfacetablelength = 0;
1724         c2 = c;
1725         while (c2) {
1726                 for (i = 0; i < c2->interfacescount; i++) {
1727                         s4 h = class_highestinterface (c2->interfaces[i]) + 1;
1728                         if (h > interfacetablelength)
1729                                 interfacetablelength = h;
1730                 }
1731                 c2 = c2->super;
1732         }
1733
1734         /* allocate virtual function table */
1735
1736         v = (vftbl*) mem_alloc(sizeof(vftbl) + sizeof(methodptr) *
1737                                                    (vftbllength - 1) + sizeof(methodptr*) *
1738                                                    (interfacetablelength - (interfacetablelength > 0)));
1739         v = (vftbl*) (((methodptr*) v) + (interfacetablelength - 1) *
1740                                   (interfacetablelength > 1));
1741         c->header.vftbl = c->vftbl = v;
1742         v->class = c;
1743         v->vftbllength = vftbllength;
1744         v->interfacetablelength = interfacetablelength;
1745
1746         /* copy virtual function table of super class */
1747
1748         for (i = 0; i < supervftbllength; i++) 
1749                 v->table[i] = super->vftbl->table[i];
1750         
1751         /* add method stubs into virtual function table */
1752
1753         for (i = 0; i < c->methodscount; i++) {
1754                 methodinfo *m = &(c->methods[i]);
1755                 if (!(m->flags & ACC_STATIC)) {
1756                         v->table[m->vftblindex] = m->stubroutine;
1757                 }
1758         }
1759
1760         /* compute instance size and offset of each field */
1761         
1762         for (i = 0; i < c->fieldscount; i++) {
1763                 s4 dsize;
1764                 fieldinfo *f = &(c->fields[i]);
1765                 
1766                 if (!(f->flags & ACC_STATIC) ) {
1767                         dsize = desc_typesize (f->descriptor);
1768                         c->instancesize = ALIGN (c->instancesize, dsize);
1769                         f->offset = c->instancesize;
1770                         c->instancesize += dsize;
1771                 }
1772         }
1773
1774         /* initialize interfacetable and interfacevftbllength */
1775         
1776         v->interfacevftbllength = MNEW (s4, interfacetablelength);
1777
1778 #ifdef STATISTICS
1779         count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
1780 #endif
1781
1782         for (i = 0; i < interfacetablelength; i++) {
1783                 v->interfacevftbllength[i] = 0;
1784                 v->interfacetable[-i] = NULL;
1785         }
1786         
1787         /* add interfaces */
1788         
1789         for (c2 = c; c2 != NULL; c2 = c2->super)
1790                 for (i = 0; i < c2->interfacescount; i++) {
1791                         class_addinterface (c, c2->interfaces[i]);
1792                 }
1793
1794         /* add finalizer method (not for java.lang.Object) */
1795
1796         if (super != NULL) {
1797                 methodinfo *fi;
1798                 static utf *finame = NULL;
1799                 static utf *fidesc = NULL;
1800
1801                 if (finame == NULL)
1802                         finame = utf_finalize;
1803                 if (fidesc == NULL)
1804                         fidesc = utf_fidesc;
1805
1806                 fi = class_findmethod (c, finame, fidesc);
1807                 if (fi != NULL) {
1808                         if (!(fi->flags & ACC_STATIC)) {
1809                                 c->finalizer = fi;
1810                         }
1811                 }
1812         }
1813
1814         /* final tasks */
1815
1816         c->linked = true;       
1817
1818         list_remove(&unlinkedclasses, c);
1819         list_addlast(&linkedclasses, c);
1820 }
1821
1822
1823 /******************* Function: class_freepool **********************************
1824
1825         Frees all resources used by this classes Constant Pool.
1826
1827 *******************************************************************************/
1828
1829 static void class_freecpool (classinfo *c)
1830 {
1831         u4 idx;
1832         u4 tag;
1833         voidptr info;
1834         
1835         for (idx=0; idx < c->cpcount; idx++) {
1836                 tag = c->cptags[idx];
1837                 info = c->cpinfos[idx];
1838                 
1839                 if (info != NULL) {
1840                         switch (tag) {
1841                         case CONSTANT_Fieldref:
1842                         case CONSTANT_Methodref:
1843                         case CONSTANT_InterfaceMethodref:
1844                                 FREE (info, constant_FMIref);
1845                                 break;
1846                         case CONSTANT_Integer:
1847                                 FREE (info, constant_integer);
1848                                 break;
1849                         case CONSTANT_Float:
1850                                 FREE (info, constant_float);
1851                                 break;
1852                         case CONSTANT_Long:
1853                                 FREE (info, constant_long);
1854                                 break;
1855                         case CONSTANT_Double:
1856                                 FREE (info, constant_double);
1857                                 break;
1858                         case CONSTANT_NameAndType:
1859                                 FREE (info, constant_nameandtype);
1860                                 break;
1861                         case CONSTANT_Arraydescriptor:
1862                                 freearraydescriptor (info);
1863                                 break;
1864                         }
1865                         }
1866                 }
1867
1868         MFREE (c -> cptags,  u1, c -> cpcount);
1869         MFREE (c -> cpinfos, voidptr, c -> cpcount);
1870 }
1871
1872
1873 /*********************** Function: class_free **********************************
1874
1875         Frees all resources used by the class.
1876
1877 *******************************************************************************/
1878
1879 static void class_free (classinfo *c)
1880 {
1881         s4 i;
1882         vftbl *v;
1883                 
1884         class_freecpool (c);
1885
1886         MFREE (c->interfaces, classinfo*, c->interfacescount);
1887
1888         for (i = 0; i < c->fieldscount; i++)
1889                 field_free(&(c->fields[i]));
1890         
1891         for (i = 0; i < c->methodscount; i++)
1892                 method_free(&(c->methods[i]));
1893         MFREE (c->methods, methodinfo, c->methodscount);
1894
1895         if ((v = c->vftbl) != NULL) {
1896                 for (i = 0; i < v->interfacetablelength; i++) {
1897                         MFREE (v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
1898                         }
1899                 MFREE (v->interfacevftbllength, s4, v->interfacetablelength);
1900
1901                 i = sizeof(vftbl) + sizeof(methodptr) * (v->vftbllength - 1) +
1902                     sizeof(methodptr*) * (v->interfacetablelength -
1903                                          (v->interfacetablelength > 0));
1904                 v = (vftbl*) (((methodptr*) v) - (v->interfacetablelength - 1) *
1905                                              (v->interfacetablelength > 1));
1906                 mem_free (v, i);
1907                 }
1908
1909         if (c->innerclasscount)
1910                 MFREE (c->innerclass, innerclassinfo, c->innerclasscount);
1911
1912         if (c->classvftbl)
1913                 mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1));
1914         
1915         FREE (c, classinfo);
1916 }
1917
1918 /************************* Function: class_findfield ***************************
1919         
1920         Searches a 'classinfo' structure for a field having the given name and
1921         type.
1922
1923 *******************************************************************************/
1924
1925
1926 fieldinfo *class_findfield (classinfo *c, utf *name, utf *desc)
1927 {
1928         s4 i;
1929
1930         for (i = 0; i < c->fieldscount; i++) { 
1931                 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) 
1932                         return &(c->fields[i]);                                                         
1933     }
1934
1935         panic ("Can not find field given in CONSTANT_Fieldref");
1936         return NULL;
1937 }
1938
1939
1940 /************************* Function: class_findmethod **************************
1941         
1942         Searches a 'classinfo' structure for a method having the given name and
1943         type.
1944         If type is NULL, it is ignored.
1945
1946 *******************************************************************************/
1947
1948 methodinfo *class_findmethod (classinfo *c, utf *name, utf *desc)
1949 {
1950         s4 i;
1951         for (i = 0; i < c->methodscount; i++) {
1952                 if ((c->methods[i].name == name) && ((desc == NULL) ||
1953                                                    (c->methods[i].descriptor == desc)))
1954                         return &(c->methods[i]);
1955                 }
1956         return NULL;
1957 }
1958
1959 /************************* Function: class_findmethod_approx ******************
1960         
1961         like class_findmethod but ignores the return value when comparing the
1962         descriptor.
1963
1964 *******************************************************************************/
1965
1966 methodinfo *class_findmethod_approx (classinfo *c, utf *name, utf *desc)
1967 {
1968         s4 i;
1969
1970         for (i = 0; i < c->methodscount; i++) 
1971                 if (c->methods[i].name == name) {
1972                         utf *meth_descr = c->methods[i].descriptor;
1973                         
1974                         if (desc == NULL) 
1975                                 /* ignore type */
1976                                 return &(c->methods[i]);
1977
1978                         if (desc->blength <= meth_descr->blength) {
1979                                            /* current position in utf text   */
1980                                            char *desc_utf_ptr = desc->text;      
1981                                            char *meth_utf_ptr = meth_descr->text;                                         
1982                                            /* points behind utf strings */
1983                                            char *desc_end = utf_end(desc);         
1984                                            char *meth_end = utf_end(meth_descr);   
1985                                            char ch;
1986
1987                                            /* compare argument types */
1988                                            while (desc_utf_ptr<desc_end && meth_utf_ptr<meth_end) {
1989
1990                                                    if ((ch=*desc_utf_ptr++) != (*meth_utf_ptr++))
1991                                                            break; /* no match */
1992
1993                                                    if (ch==')')
1994                                                            return &(c->methods[i]);   /* all parameter types equal */
1995                                            }
1996                         }
1997                 }
1998
1999         return NULL;
2000 }
2001
2002 /***************** Function: class_resolvemethod_approx ***********************
2003         
2004         Searches a class and every super class for a method (without paying
2005         attention to the return value)
2006
2007 *******************************************************************************/
2008
2009 methodinfo *class_resolvemethod_approx (classinfo *c, utf *name, utf *desc)
2010 {
2011         while (c) {
2012                 /* search for method (ignore returntype) */
2013                 methodinfo *m = class_findmethod_approx (c, name, desc);
2014                 /* method found */
2015                 if (m) return m;
2016                 /* search superclass */
2017                 c = c->super;
2018                 }
2019         return NULL;
2020 }
2021
2022
2023 /************************* Function: class_resolvemethod ***********************
2024         
2025         Searches a class and every super class for a method.
2026
2027 *******************************************************************************/
2028
2029 methodinfo *class_resolvemethod (classinfo *c, utf *name, utf *desc)
2030 {
2031         while (c) {
2032                 methodinfo *m = class_findmethod(c, name, desc);
2033                 if (m) return m;
2034                 /* search superclass */
2035                 c = c->super;
2036         }
2037         return NULL;
2038 }
2039
2040
2041
2042 /************************* Function: class_issubclass **************************
2043
2044         Checks if sub is a descendant of super.
2045         
2046 *******************************************************************************/
2047
2048 bool class_issubclass(classinfo *sub, classinfo *super)
2049 {
2050         for (;;) {
2051                 if (!sub) return false;
2052                 if (sub==super) return true;
2053                 sub = sub -> super;
2054         }
2055 }
2056
2057
2058
2059 /****************** Initialization function for classes ******************
2060
2061         In Java, every class can have a static initialization function. This
2062         function has to be called BEFORE calling other methods or accessing static
2063         variables.
2064
2065 *******************************************************************************/
2066
2067 void class_init(classinfo *c)
2068 {
2069         methodinfo *m;
2070         java_objectheader *exceptionptr;
2071         s4 i;
2072         int b;
2073
2074         if (!makeinitializations)
2075                 return;
2076         if (c->initialized)
2077                 return;
2078
2079         c->initialized = true;
2080         
2081 #ifdef STATISTICS
2082         count_class_inits++;
2083 #endif
2084
2085         if (c->super)
2086                 class_init(c->super);
2087         for (i = 0; i < c->interfacescount; i++)
2088                 class_init(c->interfaces[i]);  /* real */
2089
2090         m = class_findmethod(c, utf_clinit, utf_fidesc);
2091
2092         if (!m) {
2093                 if (initverbose) {
2094                         sprintf(logtext, "Class ");
2095                         utf_sprint(logtext+strlen(logtext), c->name);
2096                         sprintf(logtext+strlen(logtext), " has no initializer");        
2097                         dolog();
2098                 }
2099                 return;
2100         }
2101                 
2102         if (!(m->flags & ACC_STATIC))
2103                 panic("Class initializer is not static!");
2104         
2105         if (initverbose) {
2106                 sprintf(logtext, "Starting initializer for class: ");
2107                 utf_sprint(logtext + strlen(logtext), c->name);
2108                 dolog();
2109         }
2110
2111 #ifdef USE_THREADS
2112         b = blockInts;
2113         blockInts = 0;
2114 #endif
2115
2116         exceptionptr = asm_calljavamethod(m, NULL, NULL, NULL, NULL);
2117
2118 #ifdef USE_THREADS
2119         assert(blockInts == 0);
2120         blockInts = b;
2121 #endif
2122
2123         if (exceptionptr) {
2124                 printf("#### Initializer of ");
2125                 utf_display(c->name);
2126                 printf(" has thrown: ");
2127                 utf_display(exceptionptr->vftbl->class->name);
2128                 printf("\n");
2129                 fflush(stdout);
2130         }
2131
2132         if (initverbose) {
2133                 sprintf(logtext, "Finished initializer for class: ");
2134                 utf_sprint(logtext + strlen(logtext), c->name);
2135                 dolog();
2136         }
2137
2138         if (c->name == utf_systemclass) {
2139                 /* class java.lang.System requires explicit initialization */
2140                 
2141                 if (initverbose)
2142                         printf("#### Initializing class System");
2143
2144                 /* find initializing method */     
2145                 m = class_findmethod(c, 
2146                                                          utf_initsystemclass,
2147                                                          utf_fidesc);
2148
2149                 if (!m) {
2150                         /* no method found */
2151                         printf("initializeSystemClass failed");
2152                         return;
2153                 }
2154
2155 #ifdef USE_THREADS
2156                 b = blockInts;
2157                 blockInts = 0;
2158 #endif
2159
2160                 exceptionptr = asm_calljavamethod(m, NULL, NULL, NULL, NULL);
2161
2162 #ifdef USE_THREADS
2163                 assert(blockInts == 0);
2164                 blockInts = b;
2165 #endif
2166
2167                 if (exceptionptr) {                     
2168                         printf("#### initializeSystemClass has thrown: ");
2169                         utf_display(exceptionptr->vftbl->class->name);
2170                         printf("\n");
2171                         fflush(stdout);
2172                 }
2173         }
2174 }
2175
2176
2177
2178
2179 /********* Function: find_class_method_constant *********/
2180 int find_class_method_constant (classinfo *c, utf * c1, utf* m1, utf* d1)  
2181 {
2182         u4 i;
2183         voidptr e;
2184
2185         for (i=0; i<c->cpcount; i++) {
2186                 
2187                 e = c -> cpinfos [i];
2188                 if (e) {
2189                         
2190                         switch (c -> cptags [i]) {
2191                         case CONSTANT_Methodref:
2192                                 {
2193                                         constant_FMIref *fmi = e;
2194                                         if (       (fmi->class->name == c1)  
2195                                                            && (fmi->name == m1)
2196                                                            && (fmi->descriptor == d1)) {
2197                                         
2198                                                 return i;
2199                                         }
2200                                 }
2201                                 break;
2202
2203                         case CONSTANT_InterfaceMethodref:
2204                                 {
2205                                         constant_FMIref *fmi = e;
2206                                         if (       (fmi->class->name == c1)  
2207                                                            && (fmi->name == m1)
2208                                                            && (fmi->descriptor == d1)) {
2209
2210                                                 return i;
2211                                         }
2212                                 }
2213                                 break;
2214                         }
2215                 }
2216         }
2217
2218         return -1;
2219 }
2220
2221
2222 void class_showconstanti(classinfo *c, int ii) 
2223 {
2224         u4 i = ii;
2225         voidptr e;
2226                 
2227         e = c->cpinfos [i];
2228         printf ("#%d:  ", (int) i);
2229         if (e) {
2230                 switch (c->cptags [i]) {
2231                 case CONSTANT_Class:
2232                         printf("Classreference -> ");
2233                         utf_display(((classinfo*)e)->name);
2234                         break;
2235                                 
2236                 case CONSTANT_Fieldref:
2237                         printf("Fieldref -> "); goto displayFMIi;
2238                 case CONSTANT_Methodref:
2239                         printf("Methodref -> "); goto displayFMIi;
2240                 case CONSTANT_InterfaceMethodref:
2241                         printf("InterfaceMethod -> "); goto displayFMIi;
2242                 displayFMIi:
2243                         {
2244                                 constant_FMIref *fmi = e;
2245                                 utf_display(fmi->class->name);
2246                                 printf(".");
2247                                 utf_display(fmi->name);
2248                                 printf(" ");
2249                                 utf_display(fmi->descriptor);
2250                         }
2251                         break;
2252
2253                 case CONSTANT_String:
2254                         printf("String -> ");
2255                         utf_display(e);
2256                         break;
2257                 case CONSTANT_Integer:
2258                         printf("Integer -> %d", (int) (((constant_integer*)e)->value));
2259                         break;
2260                 case CONSTANT_Float:
2261                         printf("Float -> %f", ((constant_float*)e)->value);
2262                         break;
2263                 case CONSTANT_Double:
2264                         printf("Double -> %f", ((constant_double*)e)->value);
2265                         break;
2266                 case CONSTANT_Long:
2267                         {
2268                                 u8 v = ((constant_long*)e)->value;
2269 #if U8_AVAILABLE
2270                                 printf("Long -> %ld", (long int) v);
2271 #else
2272                                 printf("Long -> HI: %ld, LO: %ld\n", 
2273                                             (long int) v.high, (long int) v.low);
2274 #endif 
2275                         }
2276                         break;
2277                 case CONSTANT_NameAndType:
2278                         { 
2279                                 constant_nameandtype *cnt = e;
2280                                 printf("NameAndType: ");
2281                                 utf_display(cnt->name);
2282                                 printf(" ");
2283                                 utf_display(cnt->descriptor);
2284                         }
2285                         break;
2286                 case CONSTANT_Utf8:
2287                         printf("Utf8 -> ");
2288                         utf_display(e);
2289                         break;
2290                 case CONSTANT_Arraydescriptor:  {
2291                         printf("Arraydescriptor: ");
2292                         displayarraydescriptor(e);
2293                 }
2294                 break;
2295                 default: 
2296                         panic("Invalid type of ConstantPool-Entry");
2297                 }
2298         }
2299         printf("\n");
2300 }
2301
2302
2303 void class_showconstantpool (classinfo *c) 
2304 {
2305         u4 i;
2306         voidptr e;
2307
2308         printf ("---- dump of constant pool ----\n");
2309
2310         for (i=0; i<c->cpcount; i++) {
2311                 printf ("#%d:  ", (int) i);
2312                 
2313                 e = c -> cpinfos [i];
2314                 if (e) {
2315                         
2316                         switch (c -> cptags [i]) {
2317                         case CONSTANT_Class:
2318                                 printf ("Classreference -> ");
2319                                 utf_display ( ((classinfo*)e) -> name );
2320                                 break;
2321                                 
2322                         case CONSTANT_Fieldref:
2323                                 printf ("Fieldref -> "); goto displayFMI;
2324                         case CONSTANT_Methodref:
2325                                 printf ("Methodref -> "); goto displayFMI;
2326                         case CONSTANT_InterfaceMethodref:
2327                                 printf ("InterfaceMethod -> "); goto displayFMI;
2328                         displayFMI:
2329                                 {
2330                                         constant_FMIref *fmi = e;
2331                                         utf_display ( fmi->class->name );
2332                                         printf (".");
2333                                         utf_display ( fmi->name);
2334                                         printf (" ");
2335                                         utf_display ( fmi->descriptor );
2336                                 }
2337                                 break;
2338
2339                         case CONSTANT_String:
2340                                 printf ("String -> ");
2341                                 utf_display (e);
2342                                 break;
2343                         case CONSTANT_Integer:
2344                                 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
2345                                 break;
2346                         case CONSTANT_Float:
2347                                 printf ("Float -> %f", ((constant_float*)e) -> value);
2348                                 break;
2349                         case CONSTANT_Double:
2350                                 printf ("Double -> %f", ((constant_double*)e) -> value);
2351                                 break;
2352                         case CONSTANT_Long:
2353                                 {
2354                                         u8 v = ((constant_long*)e) -> value;
2355 #if U8_AVAILABLE
2356                                         printf ("Long -> %ld", (long int) v);
2357 #else
2358                                         printf ("Long -> HI: %ld, LO: %ld\n", 
2359                                                         (long int) v.high, (long int) v.low);
2360 #endif 
2361                                 }
2362                                 break;
2363                         case CONSTANT_NameAndType:
2364                                 {
2365                                         constant_nameandtype *cnt = e;
2366                                         printf ("NameAndType: ");
2367                                         utf_display (cnt->name);
2368                                         printf (" ");
2369                                         utf_display (cnt->descriptor);
2370                                 }
2371                                 break;
2372                         case CONSTANT_Utf8:
2373                                 printf ("Utf8 -> ");
2374                                 utf_display (e);
2375                                 break;
2376                         case CONSTANT_Arraydescriptor:  {
2377                                 printf ("Arraydescriptor: ");
2378                                 displayarraydescriptor (e);
2379                         }
2380                         break;
2381                         default: 
2382                                 panic ("Invalid type of ConstantPool-Entry");
2383                         }
2384                 }
2385
2386                 printf ("\n");
2387         }
2388 }
2389
2390
2391
2392 /********** Function: class_showmethods   (debugging only) *************/
2393
2394 void class_showmethods (classinfo *c)
2395 {
2396         s4 i;
2397         
2398         printf ("--------- Fields and Methods ----------------\n");
2399         printf ("Flags: ");     printflags (c->flags);  printf ("\n");
2400
2401         printf ("This: "); utf_display (c->name); printf ("\n");
2402         if (c->super) {
2403                 printf ("Super: "); utf_display (c->super->name); printf ("\n");
2404                 }
2405         printf ("Index: %d\n", c->index);
2406         
2407         printf ("interfaces:\n");       
2408         for (i=0; i < c-> interfacescount; i++) {
2409                 printf ("   ");
2410                 utf_display (c -> interfaces[i] -> name);
2411                 printf (" (%d)\n", c->interfaces[i] -> index);
2412                 }
2413
2414         printf ("fields:\n");           
2415         for (i=0; i < c -> fieldscount; i++) {
2416                 field_display (&(c -> fields[i]));
2417                 }
2418
2419         printf ("methods:\n");
2420         for (i=0; i < c -> methodscount; i++) {
2421                 methodinfo *m = &(c->methods[i]);
2422                 if ( !(m->flags & ACC_STATIC)) 
2423                         printf ("vftblindex: %d   ", m->vftblindex);
2424
2425                 method_display ( m );
2426
2427                 }
2428
2429         printf ("Virtual function table:\n");
2430         for (i=0; i<c->vftbl->vftbllength; i++) {
2431                 printf ("entry: %d,  %ld\n", i, (long int) (c->vftbl->table[i]) );
2432                 }
2433
2434 }
2435
2436
2437
2438 /******************************************************************************/
2439 /******************* General functions for the class loader *******************/
2440 /******************************************************************************/
2441
2442 static int loader_inited = 0;
2443
2444 /********************* Function: loader_load ***********************************
2445
2446         Loads and links the class desired class and each class and interface
2447         referenced by it.
2448         Returns: a pointer to this class
2449
2450 *******************************************************************************/
2451
2452 classinfo *loader_load (utf *topname)
2453 {
2454         classinfo *top;
2455         classinfo *c;
2456         long int starttime=0,stoptime=0;
2457         
2458         intsDisable();                           /* schani */
2459
2460         if (getloadingtime)
2461                 starttime = getcputime();
2462
2463         top = class_new (topname);
2464
2465         /* load classes */
2466         while ( (c = list_first(&unloadedclasses)) ) {
2467                 if (!class_load (c)) {
2468                         list_remove (&unloadedclasses, c);
2469                         top=NULL;
2470                     }
2471         }
2472
2473         /* link classes */
2474         while ( (c = list_first(&unlinkedclasses)) ) {
2475                 class_link (c);
2476                 }
2477
2478         if (loader_inited)
2479                 loader_compute_subclasses();
2480
2481         /* measure time */
2482         if (getloadingtime) {
2483                 stoptime = getcputime();
2484                 loadingtime += (stoptime-starttime);
2485                 }
2486
2487         intsRestore();                          /* schani */
2488
2489         return top; 
2490 }
2491
2492
2493 /**************** function: create_primitive_classes ***************************
2494
2495         create classes representing primitive types 
2496
2497 ********************************************************************************/
2498
2499
2500 void create_primitive_classes()
2501 {  
2502         int i;
2503
2504         for (i=0;i<PRIMITIVETYPE_COUNT;i++) {
2505                 /* create primitive class */
2506                 classinfo *c = class_new ( utf_new_char(primitivetype_table[i].name) );
2507                 c -> classUsed = NOTUSED; /* not used initially CO-RT */                
2508                 c -> impldBy = NULL;
2509
2510                 /* prevent loader from loading primitive class */
2511                 list_remove (&unloadedclasses, c);
2512                 /* add to unlinked classes */
2513                 list_addlast (&unlinkedclasses, c);             
2514                 c -> super = class_java_lang_Object;
2515                 class_link (c);
2516
2517                 primitivetype_table[i].class_primitive = c;
2518
2519                 /* create class for wrapping the primitive type */
2520                 primitivetype_table[i].class_wrap =
2521                         class_new( utf_new_char(primitivetype_table[i].wrapname) );
2522                 primitivetype_table[i].class_wrap -> classUsed = NOTUSED; /* not used initially CO-RT */
2523                 primitivetype_table[i].class_wrap  -> impldBy = NULL;
2524         }
2525 }
2526
2527 /***************** function: create_array_class ********************************
2528
2529         create class representing an array
2530
2531 ********************************************************************************/
2532
2533
2534 classinfo *create_array_class(utf *u)
2535 {  
2536         classinfo *c = class_new (u);
2537         /* prevent loader from loading the array class */
2538         list_remove (&unloadedclasses, c);
2539         /* add to unlinked classes */
2540         list_addlast (&unlinkedclasses, c);
2541         c -> super = class_java_lang_Object;
2542         class_link(c);
2543
2544         return c;
2545 }
2546
2547 /********************** Function: loader_init **********************************
2548
2549         Initializes all lists and loads all classes required for the system or the
2550         compiler.
2551
2552 *******************************************************************************/
2553  
2554 void loader_init()
2555 {
2556         utf *string_class;
2557         interfaceindex = 0;
2558         
2559         list_init(&unloadedclasses, OFFSET(classinfo, listnode));
2560         list_init(&unlinkedclasses, OFFSET(classinfo, listnode));
2561         list_init(&linkedclasses, OFFSET(classinfo, listnode));
2562
2563         /* create utf-symbols for pointer comparison of frequently used strings */
2564         utf_innerclasses    = utf_new_char("InnerClasses");
2565         utf_constantvalue   = utf_new_char("ConstantValue");
2566         utf_code                = utf_new_char("Code");
2567         utf_finalize        = utf_new_char("finalize");
2568         utf_fidesc              = utf_new_char("()V");
2569         utf_clinit              = utf_new_char("<clinit>");
2570         utf_initsystemclass = utf_new_char("initializeSystemClass");
2571         utf_systemclass     = utf_new_char("java/lang/System");
2572
2573         /* create class for arrays */
2574         class_array = class_new(utf_new_char("The_Array_Class"));
2575     class_array->classUsed = NOTUSED; /* not used initially CO-RT */
2576         class_array->impldBy = NULL;
2577
2578         list_remove (&unloadedclasses, class_array);
2579
2580         /* create class for strings, load it after class Object was loaded */
2581         string_class = utf_new_char("java/lang/String");
2582         class_java_lang_String = class_new(string_class);
2583     class_java_lang_String->classUsed = NOTUSED; /* not used initially CO-RT */
2584         class_java_lang_String->impldBy = NULL;
2585
2586         list_remove(&unloadedclasses, class_java_lang_String);
2587
2588         class_java_lang_Object = 
2589                 loader_load(utf_new_char("java/lang/Object"));
2590
2591         list_addlast(&unloadedclasses, class_java_lang_String);
2592
2593         class_java_lang_String =
2594                 loader_load(string_class);
2595         class_java_lang_ClassCastException = 
2596                 loader_load(utf_new_char("java/lang/ClassCastException"));
2597         class_java_lang_NullPointerException = 
2598                 loader_load(utf_new_char("java/lang/NullPointerException"));
2599         class_java_lang_ArrayIndexOutOfBoundsException =
2600                 loader_load(utf_new_char("java/lang/ArrayIndexOutOfBoundsException"));
2601         class_java_lang_NegativeArraySizeException =
2602                 loader_load(utf_new_char("java/lang/NegativeArraySizeException"));
2603         class_java_lang_OutOfMemoryError =
2604                 loader_load(utf_new_char("java/lang/OutOfMemoryError"));
2605         class_java_lang_ArrayStoreException =
2606                 loader_load(utf_new_char("java/lang/ArrayStoreException"));
2607         class_java_lang_ArithmeticException = 
2608                 loader_load(utf_new_char("java/lang/ArithmeticException"));
2609         class_java_lang_ThreadDeath =
2610                 loader_load(utf_new_char("java/lang/ThreadDeath"));
2611
2612         /* link class for arrays */
2613         list_addlast(&unlinkedclasses, class_array);
2614         class_array->super = class_java_lang_Object;
2615         class_link(class_array);
2616
2617         /* correct vftbl-entries (retarded loading of class java/lang/String) */
2618         stringtable_update(); 
2619
2620         /* create classes representing primitive types */
2621         create_primitive_classes();
2622                 
2623         proto_java_lang_ClassCastException = 
2624                 builtin_new(class_java_lang_ClassCastException);
2625         heap_addreference((void**) &proto_java_lang_ClassCastException);
2626
2627         proto_java_lang_NullPointerException = 
2628                 builtin_new(class_java_lang_NullPointerException);
2629         heap_addreference((void**) &proto_java_lang_NullPointerException);
2630
2631         proto_java_lang_ArrayIndexOutOfBoundsException = 
2632                 builtin_new(class_java_lang_ArrayIndexOutOfBoundsException);
2633         heap_addreference((void**) &proto_java_lang_ArrayIndexOutOfBoundsException);
2634
2635         proto_java_lang_NegativeArraySizeException = 
2636                 builtin_new(class_java_lang_NegativeArraySizeException);
2637         heap_addreference((void**) &proto_java_lang_NegativeArraySizeException);
2638
2639         proto_java_lang_OutOfMemoryError = 
2640                 builtin_new(class_java_lang_OutOfMemoryError);
2641         heap_addreference((void**) &proto_java_lang_OutOfMemoryError);
2642
2643         proto_java_lang_ArithmeticException = 
2644                 builtin_new(class_java_lang_ArithmeticException);
2645         heap_addreference((void**) &proto_java_lang_ArithmeticException);
2646
2647         proto_java_lang_ArrayStoreException = 
2648                 builtin_new(class_java_lang_ArrayStoreException);
2649         heap_addreference((void**) &proto_java_lang_ArrayStoreException);
2650
2651         proto_java_lang_ThreadDeath =
2652                 builtin_new(class_java_lang_ThreadDeath);
2653         heap_addreference((void**) &proto_java_lang_ThreadDeath);
2654
2655         loader_inited = 1;
2656 }
2657
2658
2659
2660
2661 /********************* Function: loader_initclasses ****************************
2662
2663         Initializes all loaded but uninitialized classes
2664
2665 *******************************************************************************/
2666
2667 void loader_initclasses ()
2668 {
2669         classinfo *c;
2670         
2671         intsDisable();                     /* schani */
2672
2673         if (makeinitializations) {
2674                 c = list_first (&linkedclasses);
2675                 while (c) {
2676                         class_init (c);
2677                         c = list_next (&linkedclasses, c);
2678                         }
2679                 }
2680
2681         intsRestore();                      /* schani */
2682 }
2683
2684 static s4 classvalue;
2685
2686 static void loader_compute_class_values (classinfo *c)
2687 {
2688         classinfo *subs;
2689
2690         c->vftbl->baseval = ++classvalue;
2691
2692         subs = c->sub;
2693         while (subs != NULL) {
2694                 loader_compute_class_values(subs);
2695                 subs = subs->nextsub;
2696                 }
2697         c->vftbl->diffval = classvalue - c->vftbl->baseval;
2698         /*
2699         {
2700         int i;
2701         for (i = 0; i < c->index; i++)
2702                 printf(" ");
2703         printf("%3d  %3d  ", (int) c->vftbl->baseval, c->vftbl->diffval);
2704         utf_display(c->name);
2705         printf("\n");
2706         }
2707         */
2708 }
2709
2710
2711 void loader_compute_subclasses ()
2712 {
2713         classinfo *c;
2714         
2715         intsDisable();                     /* schani */
2716
2717         c = list_first (&linkedclasses);
2718         while (c) {
2719                 if (!(c->flags & ACC_INTERFACE)) {
2720                         c->nextsub = 0;
2721                         c->sub = 0;
2722                         }
2723                 c = list_next (&linkedclasses, c);
2724                 }
2725
2726         c = list_first (&linkedclasses);
2727         while (c) {
2728                 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
2729                         c->nextsub = c->super->sub;
2730                         c->super->sub = c;
2731                         }
2732                 c = list_next (&linkedclasses, c);
2733                 }
2734         classvalue = 0;
2735         loader_compute_class_values(class_java_lang_Object);
2736
2737         intsRestore();                      /* schani */
2738 }
2739
2740
2741
2742 /******************** function classloader_buffer ******************************
2743  
2744     sets buffer for reading classdata
2745
2746 *******************************************************************************/
2747
2748 void classload_buffer(u1 *buf, int len)
2749 {
2750         classbuffer        =  buf;
2751         classbuffer_size   =  len;
2752         classbuf_pos       =  buf - 1;
2753 }
2754
2755
2756 /******************** Function: loader_close ***********************************
2757
2758         Frees all resources
2759         
2760 *******************************************************************************/
2761
2762 void loader_close ()
2763 {
2764         classinfo *c;
2765
2766         while ( (c=list_first(&unloadedclasses)) ) {
2767                 list_remove (&unloadedclasses,c);
2768                 class_free (c);
2769                 }
2770         while ( (c=list_first(&unlinkedclasses)) ) {
2771                 list_remove (&unlinkedclasses,c);
2772                 class_free (c);
2773                 }
2774         while ( (c=list_first(&linkedclasses)) ) {
2775                 list_remove (&linkedclasses,c);
2776                 class_free (c);
2777                 }
2778 }
2779
2780
2781 /*
2782  * These are local overrides for various environment variables in Emacs.
2783  * Please do not remove this and leave it at the end of the file, where
2784  * Emacs will automagically detect them.
2785  * ---------------------------------------------------------------------
2786  * Local variables:
2787  * mode: c
2788  * indent-tabs-mode: t
2789  * c-basic-offset: 4
2790  * tab-width: 4
2791  * End:
2792  */