* Renamed STATIC_CLASSPATH to ENABLE_STATICVM
[cacao.git] / src / vm / linker.c
1 /* src/vm/linker.c - class linker functions
2
3    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6    Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Reinhard Grafl
28
29    Changes: Andreas Krall
30             Roman Obermaiser
31             Mark Probst
32             Edwin Steiner
33             Christian Thalinger
34
35    $Id: linker.c 2868 2005-06-28 18:53:28Z twisti $
36
37 */
38
39
40 #include <assert.h>
41
42 #include "mm/memory.h"
43 #include "native/native.h"
44 #include "vm/builtin.h"
45 #include "vm/class.h"
46 #include "vm/classcache.h"
47 #include "vm/exceptions.h"
48 #include "vm/loader.h"
49 #include "vm/options.h"
50 #include "vm/resolve.h"
51 #include "vm/statistics.h"
52 #include "vm/stringlocal.h"
53 #include "vm/jit/codegen.inc.h"
54
55
56 /* global variables ***********************************************************/
57
58 static s4 interfaceindex;       /* sequential numbering of interfaces         */
59 static s4 classvalue;
60
61
62 /* primitivetype_table *********************************************************
63
64    Structure for primitive classes: contains the class for wrapping
65    the primitive type, the primitive class, the name of the class for
66    wrapping, the one character type signature and the name of the
67    primitive class.
68  
69    CAUTION: Don't change the order of the types. This table is indexed
70    by the ARRAYTYPE_ constants (expcept ARRAYTYPE_OBJECT).
71
72 *******************************************************************************/
73
74 primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = { 
75         { NULL, NULL, "java/lang/Integer",   'I', "int"     , "[I", NULL, NULL },
76         { NULL, NULL, "java/lang/Long",      'J', "long"    , "[J", NULL, NULL },
77         { NULL, NULL, "java/lang/Float",     'F', "float"   , "[F", NULL, NULL },
78         { NULL, NULL, "java/lang/Double",    'D', "double"  , "[D", NULL, NULL },
79         { NULL, NULL, NULL,                   0 , NULL      , NULL, NULL, NULL },
80         { NULL, NULL, "java/lang/Byte",      'B', "byte"    , "[B", NULL, NULL },
81         { NULL, NULL, "java/lang/Character", 'C', "char"    , "[C", NULL, NULL },
82         { NULL, NULL, "java/lang/Short",     'S', "short"   , "[S", NULL, NULL },
83         { NULL, NULL, "java/lang/Boolean",   'Z', "boolean" , "[Z", NULL, NULL },
84         { NULL, NULL, NULL,                   0 , NULL      , NULL, NULL, NULL },
85         { NULL, NULL, "java/lang/Void",      'V', "void"    , NULL, NULL, NULL }
86 };
87
88
89 /* private functions **********************************************************/
90
91 static bool link_primitivetype_table(void);
92 static classinfo *link_class_intern(classinfo *c);
93 static arraydescriptor *link_array(classinfo *c);
94 static void linker_compute_class_values(classinfo *c);
95 static void linker_compute_subclasses(classinfo *c);
96 static void linker_addinterface(classinfo *c, classinfo *ic);
97 static s4 class_highestinterface(classinfo *c);
98
99
100 /* linker_init *****************************************************************
101
102    Initializes the linker subsystem.
103
104 *******************************************************************************/
105
106 bool linker_init(void)
107 {
108         /* reset interface index */
109
110         interfaceindex = 0;
111
112         /* link important system classes */
113
114         if (!link_class(class_java_lang_Object))
115                 return false;
116
117         if (!link_class(class_java_lang_String))
118                 return false;
119
120         if (!link_class(class_java_lang_Cloneable))
121                 return false;
122
123         if (!link_class(class_java_io_Serializable))
124                 return false;
125
126
127         /* link classes for wrapping primitive types */
128
129         if (!link_class(class_java_lang_Void))
130                 return false;
131
132         if (!link_class(class_java_lang_Boolean))
133                 return false;
134
135         if (!link_class(class_java_lang_Byte))
136                 return false;
137
138         if (!link_class(class_java_lang_Character))
139                 return false;
140
141         if (!link_class(class_java_lang_Short))
142                 return false;
143
144         if (!link_class(class_java_lang_Integer))
145                 return false;
146
147         if (!link_class(class_java_lang_Long))
148                 return false;
149
150         if (!link_class(class_java_lang_Float))
151                 return false;
152
153         if (!link_class(class_java_lang_Double))
154                 return false;
155
156
157         /* load some other important classes */
158
159         if (!link_class(class_java_lang_Class))
160                 return false;
161
162         if (!link_class(class_java_lang_ClassLoader))
163                 return false;
164
165         if (!link_class(class_java_lang_SecurityManager))
166                 return false;
167
168         if (!link_class(class_java_lang_System))
169                 return false;
170
171         if (!link_class(class_java_lang_ThreadGroup))
172                 return false;
173
174
175         /* some classes which may be used more often */
176
177         if (!link_class(class_java_lang_StackTraceElement))
178                 return false;
179
180         if (!link_class(class_java_lang_reflect_Constructor))
181                 return false;
182
183         if (!link_class(class_java_lang_reflect_Field))
184                 return false;
185
186         if (!link_class(class_java_lang_reflect_Method))
187                 return false;
188
189         if (!link_class(class_java_security_PrivilegedAction))
190                 return false;
191
192         if (!link_class(class_java_util_Vector))
193                 return false;
194
195         if (!link_class(arrayclass_java_lang_Object))
196                 return false;
197
198
199         /* create pseudo classes used by the typechecker */
200
201     /* pseudo class for Arraystubs (extends java.lang.Object) */
202     
203     pseudo_class_Arraystub =
204                 class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
205         pseudo_class_Arraystub->loaded = true;
206     pseudo_class_Arraystub->super.cls = class_java_lang_Object;
207     pseudo_class_Arraystub->interfacescount = 2;
208     pseudo_class_Arraystub->interfaces = MNEW(classref_or_classinfo, 2);
209     pseudo_class_Arraystub->interfaces[0].cls = class_java_lang_Cloneable;
210     pseudo_class_Arraystub->interfaces[1].cls = class_java_io_Serializable;
211
212         if (!classcache_store_unique(pseudo_class_Arraystub)) {
213                 log_text("could not cache pseudo_class_Arraystub");
214                 assert(0);
215         }
216
217     if (!link_class(pseudo_class_Arraystub))
218                 return false;
219
220     /* pseudo class representing the null type */
221     
222         pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
223         pseudo_class_Null->loaded = true;
224     pseudo_class_Null->super.cls = class_java_lang_Object;
225
226         if (!classcache_store_unique(pseudo_class_Null)) {
227                 log_text("could not cache pseudo_class_Null");
228                 assert(0);
229         }
230
231         if (!link_class(pseudo_class_Null))
232                 return false;
233
234     /* pseudo class representing new uninitialized objects */
235     
236         pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
237         pseudo_class_New->loaded = true;
238         pseudo_class_New->linked = true; /* XXX is this allright? */
239         pseudo_class_New->super.cls = class_java_lang_Object;
240
241         if (!classcache_store_unique(pseudo_class_New)) {
242                 log_text("could not cache pseudo_class_New");
243                 assert(0);
244         }
245
246         /* create classes representing primitive types */
247
248         if (!link_primitivetype_table())
249                 return false;
250
251
252         /* Correct vftbl-entries (retarded loading and linking of class           */
253         /* java/lang/String).                                                     */
254
255         stringtable_update();
256
257         return true;
258 }
259
260
261 /* link_primitivetype_table ****************************************************
262
263    Create classes representing primitive types.
264
265 *******************************************************************************/
266
267 static bool link_primitivetype_table(void)
268 {  
269         classinfo *c;
270         utf       *u;
271         s4         i;
272
273         for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
274                 /* skip dummies */
275
276                 if (!primitivetype_table[i].name)
277                         continue;
278                 
279                 /* create primitive class */
280
281                 c = class_create_classinfo(utf_new_char(primitivetype_table[i].name));
282                 c->classUsed = NOTUSED; /* not used initially CO-RT */
283                 c->impldBy = NULL;
284                 
285                 /* prevent loader from loading primitive class */
286
287                 c->loaded = true;
288                 if (!classcache_store_unique(c)) {
289                         log_text("Could not cache primitive class");
290                         return false;
291                 }
292                 if (!link_class(c))
293                         return false;
294
295                 primitivetype_table[i].class_primitive = c;
296
297                 /* create class for wrapping the primitive type */
298
299                 u = utf_new_char(primitivetype_table[i].wrapname);
300
301                 if (!(c = load_class_bootstrap(u)))
302                         return false;
303
304                 primitivetype_table[i].class_wrap = c;
305                 primitivetype_table[i].class_wrap->classUsed = NOTUSED; /* not used initially CO-RT */
306                 primitivetype_table[i].class_wrap->impldBy = NULL;
307
308                 /* create the primitive array class */
309
310                 if (primitivetype_table[i].arrayname) {
311                         u = utf_new_char(primitivetype_table[i].arrayname);
312                         c = class_create_classinfo(u);
313                         c = load_newly_created_array(c, NULL);
314                         if (c == NULL)
315                                 return false;
316
317                         primitivetype_table[i].arrayclass = c;
318
319                         assert(c->loaded);
320                         if (!c->linked)
321                                 if (!link_class(c))
322                                         return false;
323
324                         primitivetype_table[i].arrayvftbl = c->vftbl;
325                 }
326         }
327
328         return true;
329 }
330
331
332 /* link_class ******************************************************************
333
334    Wrapper function for link_class_intern to ease monitor enter/exit
335    and exception handling.
336
337 *******************************************************************************/
338
339 classinfo *link_class(classinfo *c)
340 {
341         classinfo *r;
342
343         if (!c) {
344                 *exceptionptr = new_nullpointerexception();
345                 return NULL;
346         }
347
348 #if defined(USE_THREADS)
349         /* enter a monitor on the class */
350
351         builtin_monitorenter((java_objectheader *) c);
352 #endif
353
354         /* maybe the class is already linked */
355         if (c->linked) {
356 #if defined(USE_THREADS)
357                 builtin_monitorexit((java_objectheader *) c);
358 #endif
359
360                 return c;
361         }
362
363 #if defined(STATISTICS)
364         /* measure time */
365
366         if (getcompilingtime)
367                 compilingtime_stop();
368
369         if (getloadingtime)
370                 loadingtime_start();
371 #endif
372
373         /* call the internal function */
374
375         r = link_class_intern(c);
376
377         /* if return value is NULL, we had a problem and the class is not linked */
378
379         if (!r)
380                 c->linked = false;
381
382 #if defined(STATISTICS)
383         /* measure time */
384
385         if (getloadingtime)
386                 loadingtime_stop();
387
388         if (getcompilingtime)
389                 compilingtime_start();
390 #endif
391
392 #if defined(USE_THREADS)
393         /* leave the monitor */
394
395         builtin_monitorexit((java_objectheader *) c);
396 #endif
397
398         return r;
399 }
400
401
402 /* link_class_intern ***********************************************************
403
404    Tries to link a class. The function calculates the length in bytes
405    that an instance of this class requires as well as the VTBL for
406    methods and interface methods.
407         
408 *******************************************************************************/
409
410 static classinfo *link_class_intern(classinfo *c)
411 {
412         classinfo *super;             /* super class                              */
413         classinfo *tc;                /* temporary class variable                 */
414         s4 supervftbllength;          /* vftbllegnth of super class               */
415         s4 vftbllength;               /* vftbllength of current class             */
416         s4 interfacetablelength;      /* interface table length                   */
417         vftbl_t *v;                   /* vftbl of current class                   */
418         s4 i,j;                       /* interface/method/field counter           */
419         arraydescriptor *arraydesc;   /* descriptor for array classes             */
420
421         /* maybe the class is already linked */
422
423         if (c->linked)
424                 return c;
425
426         if (linkverbose)
427                 log_message_class("Linking class: ", c);
428
429         /* the class must be loaded */
430
431         if (!c->loaded)
432                 throw_cacao_exception_exit(string_java_lang_InternalError,
433                                                                    "Trying to link unloaded class");
434
435         /* ok, this class is somewhat linked */
436
437         c->linked = true;
438
439         arraydesc = NULL;
440
441         /* check interfaces */
442
443         for (i = 0; i < c->interfacescount; i++) {
444                 /* resolve this super interface */
445
446                 if (!resolve_classref_or_classinfo(NULL, c->interfaces[i], resolveEager,
447                                                                                    true, false, &tc))
448                         return NULL;
449
450                 c->interfaces[i].cls = tc;
451                 
452                 /* detect circularity */
453
454                 if (tc == c) {
455                         *exceptionptr =
456                                 new_exception_utfmessage(string_java_lang_ClassCircularityError,
457                                                                                  c->name);
458                         return NULL;
459                 }
460
461                 assert(tc->loaded);
462
463                 if (!(tc->flags & ACC_INTERFACE)) {
464                         *exceptionptr =
465                                 new_exception_message(string_java_lang_IncompatibleClassChangeError,
466                                                                           "Implementing class");
467                         return NULL;
468                 }
469
470                 if (!tc->linked)
471                         if (!link_class(tc))
472                                 return NULL;
473         }
474         
475         /* check super class */
476
477         super = NULL;
478
479         if (c->super.any == NULL) {                     /* class java.lang.Object */
480                 c->index = 0;
481         c->classUsed = USED;              /* Object class is always used CO-RT*/
482                 c->impldBy = NULL;
483                 c->instancesize = sizeof(java_objectheader);
484                 
485                 vftbllength = supervftbllength = 0;
486
487                 c->finalizer = NULL;
488
489         } else {
490                 /* resolve super class */
491
492                 if (!resolve_classref_or_classinfo(NULL, c->super, resolveEager, true, false,
493                                                                                    &super))
494                         return NULL;
495                 c->super.cls = super;
496                 
497                 /* detect circularity */
498
499                 if (super == c) {
500                         *exceptionptr =
501                                 new_exception_utfmessage(string_java_lang_ClassCircularityError,
502                                                                                  c->name);
503                         return NULL;
504                 }
505
506                 assert(super->loaded);
507
508                 if (super->flags & ACC_INTERFACE) {
509                         /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
510                         log_text("Interface specified as super class");
511                         assert(0);
512                 }
513
514                 /* Don't allow extending final classes */
515
516                 if (super->flags & ACC_FINAL) {
517                         *exceptionptr =
518                                 new_exception_message(string_java_lang_VerifyError,
519                                                                           "Cannot inherit from final class");
520                         return NULL;
521                 }
522                 
523                 if (!super->linked)
524                         if (!link_class(super))
525                                 return NULL;
526
527                 /* handle array classes */
528
529                 if (c->name->text[0] == '[')
530                         if (!(arraydesc = link_array(c)))
531                                 return NULL;
532
533                 if (c->flags & ACC_INTERFACE)
534                         c->index = interfaceindex++;
535                 else
536                         c->index = super->index + 1;
537                 
538                 c->instancesize = super->instancesize;
539                 
540                 vftbllength = supervftbllength = super->vftbl->vftbllength;
541                 
542                 c->finalizer = super->finalizer;
543         }
544
545
546         /* compute vftbl length */
547
548         for (i = 0; i < c->methodscount; i++) {
549                 methodinfo *m = &(c->methods[i]);
550
551                 if (!(m->flags & ACC_STATIC)) { /* is instance method */
552                         tc = super;
553
554                         while (tc) {
555                                 s4 j;
556
557                                 for (j = 0; j < tc->methodscount; j++) {
558                                         if (method_canoverwrite(m, &(tc->methods[j]))) {
559                                                 if (tc->methods[j].flags & ACC_PRIVATE)
560                                                         goto notfoundvftblindex;
561
562                                                 if (tc->methods[j].flags & ACC_FINAL) {
563                                                         /* class a overrides final method . */
564                                                         *exceptionptr =
565                                                                 new_exception(string_java_lang_VerifyError);
566                                                         return NULL;
567                                                 }
568
569                                                 m->vftblindex = tc->methods[j].vftblindex;
570                                                 goto foundvftblindex;
571                                         }
572                                 }
573
574                                 tc = tc->super.cls;
575                         }
576
577                 notfoundvftblindex:
578                         m->vftblindex = (vftbllength++);
579                 foundvftblindex:
580                         ;
581                 }
582         }       
583
584
585         /* check interfaces of ABSTRACT class for unimplemented methods */
586
587         if (c->flags & ACC_ABSTRACT) {
588                 classinfo  *ic;
589                 methodinfo *im;
590                 s4 abstractmethodscount;
591                 s4 j;
592                 s4 k;
593
594                 abstractmethodscount = 0;
595
596                 for (i = 0; i < c->interfacescount; i++) {
597                         ic = c->interfaces[i].cls;
598
599                         for (j = 0; j < ic->methodscount; j++) {
600                                 im = &(ic->methods[j]);
601
602                                 /* skip `<clinit>' and `<init>' */
603
604                                 if (im->name == utf_clinit || im->name == utf_init)
605                                         continue;
606
607                                 tc = c;
608
609                                 while (tc) {
610                                         for (k = 0; k < tc->methodscount; k++) {
611                                                 if (method_canoverwrite(im, &(tc->methods[k])))
612                                                         goto noabstractmethod;
613                                         }
614
615                                         tc = tc->super.cls;
616                                 }
617
618                                 abstractmethodscount++;
619
620                         noabstractmethod:
621                                 ;
622                         }
623                 }
624
625                 if (abstractmethodscount > 0) {
626                         methodinfo *am;
627
628                         /* reallocate methods memory */
629
630                         c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
631                                                                   c->methodscount + abstractmethodscount);
632
633                         for (i = 0; i < c->interfacescount; i++) {
634                                 ic = c->interfaces[i].cls;
635
636                                 for (j = 0; j < ic->methodscount; j++) {
637                                         im = &(ic->methods[j]);
638
639                                         /* skip `<clinit>' and `<init>' */
640
641                                         if (im->name == utf_clinit || im->name == utf_init)
642                                                 continue;
643
644                                         tc = c;
645
646                                         while (tc) {
647                                                 for (k = 0; k < tc->methodscount; k++) {
648                                                         if (method_canoverwrite(im, &(tc->methods[k])))
649                                                                 goto noabstractmethod2;
650                                                 }
651
652                                                 tc = tc->super.cls;
653                                         }
654
655                                         am = &(c->methods[c->methodscount]);
656                                         c->methodscount++;
657
658                                         MCOPY(am, im, methodinfo, 1);
659
660                                         am->vftblindex = (vftbllength++);
661                                         am->class = c;
662
663                                 noabstractmethod2:
664                                         ;
665                                 }
666                         }
667                 }
668         }
669
670
671 #if defined(STATISTICS)
672         if (opt_stat)
673                 count_vftbl_len +=
674                         sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
675 #endif
676
677         /* compute interfacetable length */
678
679         interfacetablelength = 0;
680         tc = c;
681         while (tc) {
682                 for (i = 0; i < tc->interfacescount; i++) {
683                         s4 h = class_highestinterface(tc->interfaces[i].cls) + 1;
684                         if (h > interfacetablelength)
685                                 interfacetablelength = h;
686                 }
687                 tc = tc->super.cls;
688         }
689
690         /* allocate virtual function table */
691
692         v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
693                                                           sizeof(methodptr) * (vftbllength - 1) +
694                                                           sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
695         v = (vftbl_t *) (((methodptr *) v) +
696                                          (interfacetablelength - 1) * (interfacetablelength > 1));
697         c->header.vftbl = c->vftbl = v;
698         v->class = c;
699         v->vftbllength = vftbllength;
700         v->interfacetablelength = interfacetablelength;
701         v->arraydesc = arraydesc;
702
703         /* store interface index in vftbl */
704
705         if (c->flags & ACC_INTERFACE)
706                 v->baseval = -(c->index);
707
708         /* copy virtual function table of super class */
709
710         for (i = 0; i < supervftbllength; i++) 
711                 v->table[i] = super->vftbl->table[i];
712         
713         /* add method stubs into virtual function table */
714
715         for (i = 0; i < c->methodscount; i++) {
716                 methodinfo *m = &(c->methods[i]);
717
718                 /* Methods in ABSTRACT classes from interfaces maybe already have a   */
719                 /* stubroutine.                                                       */
720
721                 if (!m->stubroutine) {
722                         if (!(m->flags & ACC_NATIVE)) {
723                                 m->stubroutine = createcompilerstub(m);
724
725                         } else {
726                                 functionptr f = NULL;
727
728 #if defined(ENABLE_STATICVM)
729                                 f = native_findfunction(c->name, m->name, m->descriptor,
730                                                                                 (m->flags & ACC_STATIC));
731                                 if (!f)
732                                         return NULL;
733 #endif
734
735                                 m->stubroutine = codegen_createnativestub(f, m);
736                         }
737                 }
738
739                 if (!(m->flags & ACC_STATIC))
740                         v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
741         }
742
743         /* compute instance size and offset of each field */
744         
745         for (i = 0; i < c->fieldscount; i++) {
746                 s4 dsize;
747                 fieldinfo *f = &(c->fields[i]);
748                 
749                 if (!(f->flags & ACC_STATIC)) {
750                         dsize = desc_typesize(f->descriptor);
751                         c->instancesize = ALIGN(c->instancesize, dsize);
752                         f->offset = c->instancesize;
753                         c->instancesize += dsize;
754                 }
755         }
756
757         /* initialize interfacetable and interfacevftbllength */
758         
759         v->interfacevftbllength = MNEW(s4, interfacetablelength);
760
761 #if defined(STATISTICS)
762         if (opt_stat)
763                 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
764 #endif
765
766         for (i = 0; i < interfacetablelength; i++) {
767                 v->interfacevftbllength[i] = 0;
768                 v->interfacetable[-i] = NULL;
769         }
770         
771         /* add interfaces */
772         
773         for (tc = c; tc != NULL; tc = tc->super.cls)
774                 for (i = 0; i < tc->interfacescount; i++)
775                         linker_addinterface(c, tc->interfaces[i].cls);
776
777         /* add finalizer method (not for java.lang.Object) */
778
779         if (super) {
780                 methodinfo *fi;
781
782                 fi = class_findmethod(c, utf_finalize, utf_void__void);
783
784                 if (fi)
785                         if (!(fi->flags & ACC_STATIC))
786                                 c->finalizer = fi;
787         }
788
789         /* resolve exception class references */
790
791         for (i = 0; i < c->methodscount; i++) {
792                 methodinfo *m = &(c->methods[i]);
793
794                 for (j = 0; j < m->exceptiontablelength; j++) {
795                         if (!m->exceptiontable[j].catchtype.any)
796                                 continue;
797                         if (!resolve_classref_or_classinfo(NULL,
798                                                                                            m->exceptiontable[j].catchtype,
799                                                                                            resolveEager, true, false,
800                                                                                            &(m->exceptiontable[j].catchtype.cls)))
801                                 return NULL;
802                 }
803
804                 for (j = 0; j < m->thrownexceptionscount; j++)
805                         if (!resolve_classref_or_classinfo(NULL, m->thrownexceptions[j],
806                                                                                            resolveEager, true, false,
807                                                                                            &(m->thrownexceptions[j].cls)))
808                                 return NULL;
809         }
810         
811         /* final tasks */
812
813         linker_compute_subclasses(c);
814
815         if (linkverbose)
816                 log_message_class("Linking done class: ", c);
817
818         /* just return c to show that we didn't had a problem */
819
820         return c;
821 }
822
823
824 /* link_array ******************************************************************
825
826    This function is called by link_class to create the arraydescriptor
827    for an array class.
828
829    This function returns NULL if the array cannot be linked because
830    the component type has not been linked yet.
831
832 *******************************************************************************/
833
834 static arraydescriptor *link_array(classinfo *c)
835 {
836         classinfo       *comp;
837         s4               namelen;
838         arraydescriptor *desc;
839         vftbl_t         *compvftbl;
840         utf             *u;
841
842         comp = NULL;
843         namelen = c->name->blength;
844
845         /* Check the component type */
846
847         switch (c->name->text[1]) {
848         case '[':
849                 /* c is an array of arrays. */
850                 u = utf_new_intern(c->name->text + 1, namelen - 1);
851                 if (!(comp = load_class_from_classloader(u, c->classloader)))
852                         return NULL;
853                 break;
854
855         case 'L':
856                 /* c is an array of objects. */
857                 u = utf_new_intern(c->name->text + 2, namelen - 3);
858                 if (!(comp = load_class_from_classloader(u, c->classloader)))
859                         return NULL;
860                 break;
861         }
862
863         /* If the component type has not been linked, link it now */
864         assert(!comp || comp->loaded);
865         if (comp && !comp->linked) {
866
867                 if (!link_class(comp))
868                         return NULL;
869         }
870
871         /* Allocate the arraydescriptor */
872         desc = NEW(arraydescriptor);
873
874         if (comp) {
875                 /* c is an array of references */
876                 desc->arraytype = ARRAYTYPE_OBJECT;
877                 desc->componentsize = sizeof(void*);
878                 desc->dataoffset = OFFSET(java_objectarray, data);
879                 
880                 compvftbl = comp->vftbl;
881
882                 if (!compvftbl) {
883                         log_text("Component class has no vftbl");
884                         assert(0);
885                 }
886
887                 desc->componentvftbl = compvftbl;
888                 
889                 if (compvftbl->arraydesc) {
890                         desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
891
892                         if (compvftbl->arraydesc->dimension >= 255) {
893                                 log_text("Creating array of dimension >255");
894                                 assert(0);
895                         }
896
897                         desc->dimension = compvftbl->arraydesc->dimension + 1;
898                         desc->elementtype = compvftbl->arraydesc->elementtype;
899
900                 } else {
901                         desc->elementvftbl = compvftbl;
902                         desc->dimension = 1;
903                         desc->elementtype = ARRAYTYPE_OBJECT;
904                 }
905
906         } else {
907                 /* c is an array of a primitive type */
908                 switch (c->name->text[1]) {
909                 case 'Z':
910                         desc->arraytype = ARRAYTYPE_BOOLEAN;
911                         desc->dataoffset = OFFSET(java_booleanarray,data);
912                         desc->componentsize = sizeof(u1);
913                         break;
914
915                 case 'B':
916                         desc->arraytype = ARRAYTYPE_BYTE;
917                         desc->dataoffset = OFFSET(java_bytearray,data);
918                         desc->componentsize = sizeof(u1);
919                         break;
920
921                 case 'C':
922                         desc->arraytype = ARRAYTYPE_CHAR;
923                         desc->dataoffset = OFFSET(java_chararray,data);
924                         desc->componentsize = sizeof(u2);
925                         break;
926
927                 case 'D':
928                         desc->arraytype = ARRAYTYPE_DOUBLE;
929                         desc->dataoffset = OFFSET(java_doublearray,data);
930                         desc->componentsize = sizeof(double);
931                         break;
932
933                 case 'F':
934                         desc->arraytype = ARRAYTYPE_FLOAT;
935                         desc->dataoffset = OFFSET(java_floatarray,data);
936                         desc->componentsize = sizeof(float);
937                         break;
938
939                 case 'I':
940                         desc->arraytype = ARRAYTYPE_INT;
941                         desc->dataoffset = OFFSET(java_intarray,data);
942                         desc->componentsize = sizeof(s4);
943                         break;
944
945                 case 'J':
946                         desc->arraytype = ARRAYTYPE_LONG;
947                         desc->dataoffset = OFFSET(java_longarray,data);
948                         desc->componentsize = sizeof(s8);
949                         break;
950
951                 case 'S':
952                         desc->arraytype = ARRAYTYPE_SHORT;
953                         desc->dataoffset = OFFSET(java_shortarray,data);
954                         desc->componentsize = sizeof(s2);
955                         break;
956
957                 default:
958                         log_text("Invalid array class name");
959                         assert(0);
960                 }
961                 
962                 desc->componentvftbl = NULL;
963                 desc->elementvftbl = NULL;
964                 desc->dimension = 1;
965                 desc->elementtype = desc->arraytype;
966         }
967
968         return desc;
969 }
970
971
972 /* linker_compute_subclasses ***************************************************
973
974    XXX
975
976 *******************************************************************************/
977
978 static void linker_compute_subclasses(classinfo *c)
979 {
980 #if defined(USE_THREADS)
981 #if defined(NATIVE_THREADS)
982         compiler_lock();
983 #else
984         intsDisable();
985 #endif
986 #endif
987
988         if (!(c->flags & ACC_INTERFACE)) {
989                 c->nextsub = 0;
990                 c->sub = 0;
991         }
992
993         if (!(c->flags & ACC_INTERFACE) && (c->super.any != NULL)) {
994                 c->nextsub = c->super.cls->sub;
995                 c->super.cls->sub = c;
996         }
997
998         classvalue = 0;
999
1000         /* compute class values */
1001
1002         linker_compute_class_values(class_java_lang_Object);
1003
1004 #if defined(USE_THREADS)
1005 #if defined(NATIVE_THREADS)
1006         compiler_unlock();
1007 #else
1008         intsRestore();
1009 #endif
1010 #endif
1011 }
1012
1013
1014 /* linker_compute_class_values *************************************************
1015
1016    XXX
1017
1018 *******************************************************************************/
1019
1020 static void linker_compute_class_values(classinfo *c)
1021 {
1022         classinfo *subs;
1023
1024         c->vftbl->baseval = ++classvalue;
1025
1026         subs = c->sub;
1027
1028         while (subs) {
1029                 linker_compute_class_values(subs);
1030
1031                 subs = subs->nextsub;
1032         }
1033
1034         c->vftbl->diffval = classvalue - c->vftbl->baseval;
1035 }
1036
1037
1038 /* linker_addinterface *********************************************************
1039
1040    Is needed by link_class for adding a VTBL to a class. All
1041    interfaces implemented by ic are added as well.
1042
1043 *******************************************************************************/
1044
1045 static void linker_addinterface(classinfo *c, classinfo *ic)
1046 {
1047         s4     j, m;
1048         s4     i   = ic->index;
1049         vftbl_t *v = c->vftbl;
1050
1051         if (i >= v->interfacetablelength) {
1052                 log_text("Inernal error: interfacetable overflow");
1053                 assert(0);
1054         }
1055
1056         if (v->interfacetable[-i])
1057                 return;
1058
1059         if (ic->methodscount == 0) {  /* fake entry needed for subtype test */
1060                 v->interfacevftbllength[i] = 1;
1061                 v->interfacetable[-i] = MNEW(methodptr, 1);
1062                 v->interfacetable[-i][0] = NULL;
1063
1064         } else {
1065                 v->interfacevftbllength[i] = ic->methodscount;
1066                 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1067
1068 #if defined(STATISTICS)
1069                 if (opt_stat)
1070                         count_vftbl_len += sizeof(methodptr) *
1071                                 (ic->methodscount + (ic->methodscount == 0));
1072 #endif
1073
1074                 for (j = 0; j < ic->methodscount; j++) {
1075                         classinfo *sc = c;
1076
1077                         while (sc) {
1078                                 for (m = 0; m < sc->methodscount; m++) {
1079                                         methodinfo *mi = &(sc->methods[m]);
1080
1081                                         if (method_canoverwrite(mi, &(ic->methods[j]))) {
1082                                                 v->interfacetable[-i][j] = v->table[mi->vftblindex];
1083                                                 goto foundmethod;
1084                                         }
1085                                 }
1086                                 sc = sc->super.cls;
1087                         }
1088                 foundmethod:
1089                         ;
1090                 }
1091         }
1092
1093         for (j = 0; j < ic->interfacescount; j++) 
1094                 linker_addinterface(c, ic->interfaces[j].cls);
1095 }
1096
1097
1098 /* class_highestinterface ******************************************************
1099
1100    Used by the function link_class to determine the amount of memory
1101    needed for the interface table.
1102
1103 *******************************************************************************/
1104
1105 static s4 class_highestinterface(classinfo *c)
1106 {
1107         s4 h;
1108         s4 h2;
1109         s4 i;
1110         
1111     /* check for ACC_INTERFACE bit already done in link_class_intern */
1112
1113     h = c->index;
1114
1115         for (i = 0; i < c->interfacescount; i++) {
1116                 h2 = class_highestinterface(c->interfaces[i].cls);
1117
1118                 if (h2 > h)
1119                         h = h2;
1120         }
1121
1122         return h;
1123 }
1124
1125
1126 /*
1127  * These are local overrides for various environment variables in Emacs.
1128  * Please do not remove this and leave it at the end of the file, where
1129  * Emacs will automagically detect them.
1130  * ---------------------------------------------------------------------
1131  * Local variables:
1132  * mode: c
1133  * indent-tabs-mode: t
1134  * c-basic-offset: 4
1135  * tab-width: 4
1136  * End:
1137  */