class loading synchronization: throw away loaded class if a class with the
[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 2725 2005-06-16 19:10:35Z edwin $
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                                                                                    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, 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 = native_findfunction(c->name,
727                                                                                                         m->name, m->descriptor,
728                                                                                                         (m->flags & ACC_STATIC));
729 #if defined(STATIC_CLASSPATH)
730                                 if (f)
731 #endif
732                                         m->stubroutine = codegen_createnativestub(f, m);
733                         }
734                 }
735
736                 if (!(m->flags & ACC_STATIC))
737                         v->table[m->vftblindex] = (methodptr) m->stubroutine;
738         }
739
740         /* compute instance size and offset of each field */
741         
742         for (i = 0; i < c->fieldscount; i++) {
743                 s4 dsize;
744                 fieldinfo *f = &(c->fields[i]);
745                 
746                 if (!(f->flags & ACC_STATIC)) {
747                         dsize = desc_typesize(f->descriptor);
748                         c->instancesize = ALIGN(c->instancesize, dsize);
749                         f->offset = c->instancesize;
750                         c->instancesize += dsize;
751                 }
752         }
753
754         /* initialize interfacetable and interfacevftbllength */
755         
756         v->interfacevftbllength = MNEW(s4, interfacetablelength);
757
758 #if defined(STATISTICS)
759         if (opt_stat)
760                 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
761 #endif
762
763         for (i = 0; i < interfacetablelength; i++) {
764                 v->interfacevftbllength[i] = 0;
765                 v->interfacetable[-i] = NULL;
766         }
767         
768         /* add interfaces */
769         
770         for (tc = c; tc != NULL; tc = tc->super.cls)
771                 for (i = 0; i < tc->interfacescount; i++)
772                         linker_addinterface(c, tc->interfaces[i].cls);
773
774         /* add finalizer method (not for java.lang.Object) */
775
776         if (super) {
777                 methodinfo *fi;
778
779                 fi = class_findmethod(c, utf_finalize, utf_void__void);
780
781                 if (fi)
782                         if (!(fi->flags & ACC_STATIC))
783                                 c->finalizer = fi;
784         }
785
786         /* resolve exception class references */
787
788         for (i = 0; i < c->methodscount; i++) {
789                 methodinfo *m = &(c->methods[i]);
790
791                 for (j = 0; j < m->exceptiontablelength; j++) {
792                         if (!m->exceptiontable[j].catchtype.any)
793                                 continue;
794                         if (!resolve_classref_or_classinfo(NULL,
795                                                                                            m->exceptiontable[j].catchtype,
796                                                                                            resolveEager, false,
797                                                                                            &(m->exceptiontable[j].catchtype.cls)))
798                                 return NULL;
799                 }
800
801                 for (j = 0; j < m->thrownexceptionscount; j++)
802                         if (!resolve_classref_or_classinfo(NULL, m->thrownexceptions[j],
803                                                                                            resolveEager, false,
804                                                                                            &(m->thrownexceptions[j].cls)))
805                                 return NULL;
806         }
807         
808         /* final tasks */
809
810         linker_compute_subclasses(c);
811
812         if (linkverbose)
813                 log_message_class("Linking done class: ", c);
814
815         /* just return c to show that we didn't had a problem */
816
817         return c;
818 }
819
820
821 /* link_array ******************************************************************
822
823    This function is called by link_class to create the arraydescriptor
824    for an array class.
825
826    This function returns NULL if the array cannot be linked because
827    the component type has not been linked yet.
828
829 *******************************************************************************/
830
831 static arraydescriptor *link_array(classinfo *c)
832 {
833         classinfo       *comp;
834         s4               namelen;
835         arraydescriptor *desc;
836         vftbl_t         *compvftbl;
837         utf             *u;
838
839         comp = NULL;
840         namelen = c->name->blength;
841
842         /* Check the component type */
843
844         switch (c->name->text[1]) {
845         case '[':
846                 /* c is an array of arrays. */
847                 u = utf_new_intern(c->name->text + 1, namelen - 1);
848                 if (!(comp = load_class_from_classloader(u, c->classloader)))
849                         return NULL;
850                 break;
851
852         case 'L':
853                 /* c is an array of objects. */
854                 u = utf_new_intern(c->name->text + 2, namelen - 3);
855                 if (!(comp = load_class_from_classloader(u, c->classloader)))
856                         return NULL;
857                 break;
858         }
859
860         /* If the component type has not been linked, link it now */
861         assert(!comp || comp->loaded);
862         if (comp && !comp->linked) {
863
864                 if (!link_class(comp))
865                         return NULL;
866         }
867
868         /* Allocate the arraydescriptor */
869         desc = NEW(arraydescriptor);
870
871         if (comp) {
872                 /* c is an array of references */
873                 desc->arraytype = ARRAYTYPE_OBJECT;
874                 desc->componentsize = sizeof(void*);
875                 desc->dataoffset = OFFSET(java_objectarray, data);
876                 
877                 compvftbl = comp->vftbl;
878
879                 if (!compvftbl) {
880                         log_text("Component class has no vftbl");
881                         assert(0);
882                 }
883
884                 desc->componentvftbl = compvftbl;
885                 
886                 if (compvftbl->arraydesc) {
887                         desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
888
889                         if (compvftbl->arraydesc->dimension >= 255) {
890                                 log_text("Creating array of dimension >255");
891                                 assert(0);
892                         }
893
894                         desc->dimension = compvftbl->arraydesc->dimension + 1;
895                         desc->elementtype = compvftbl->arraydesc->elementtype;
896
897                 } else {
898                         desc->elementvftbl = compvftbl;
899                         desc->dimension = 1;
900                         desc->elementtype = ARRAYTYPE_OBJECT;
901                 }
902
903         } else {
904                 /* c is an array of a primitive type */
905                 switch (c->name->text[1]) {
906                 case 'Z':
907                         desc->arraytype = ARRAYTYPE_BOOLEAN;
908                         desc->dataoffset = OFFSET(java_booleanarray,data);
909                         desc->componentsize = sizeof(u1);
910                         break;
911
912                 case 'B':
913                         desc->arraytype = ARRAYTYPE_BYTE;
914                         desc->dataoffset = OFFSET(java_bytearray,data);
915                         desc->componentsize = sizeof(u1);
916                         break;
917
918                 case 'C':
919                         desc->arraytype = ARRAYTYPE_CHAR;
920                         desc->dataoffset = OFFSET(java_chararray,data);
921                         desc->componentsize = sizeof(u2);
922                         break;
923
924                 case 'D':
925                         desc->arraytype = ARRAYTYPE_DOUBLE;
926                         desc->dataoffset = OFFSET(java_doublearray,data);
927                         desc->componentsize = sizeof(double);
928                         break;
929
930                 case 'F':
931                         desc->arraytype = ARRAYTYPE_FLOAT;
932                         desc->dataoffset = OFFSET(java_floatarray,data);
933                         desc->componentsize = sizeof(float);
934                         break;
935
936                 case 'I':
937                         desc->arraytype = ARRAYTYPE_INT;
938                         desc->dataoffset = OFFSET(java_intarray,data);
939                         desc->componentsize = sizeof(s4);
940                         break;
941
942                 case 'J':
943                         desc->arraytype = ARRAYTYPE_LONG;
944                         desc->dataoffset = OFFSET(java_longarray,data);
945                         desc->componentsize = sizeof(s8);
946                         break;
947
948                 case 'S':
949                         desc->arraytype = ARRAYTYPE_SHORT;
950                         desc->dataoffset = OFFSET(java_shortarray,data);
951                         desc->componentsize = sizeof(s2);
952                         break;
953
954                 default:
955                         log_text("Invalid array class name");
956                         assert(0);
957                 }
958                 
959                 desc->componentvftbl = NULL;
960                 desc->elementvftbl = NULL;
961                 desc->dimension = 1;
962                 desc->elementtype = desc->arraytype;
963         }
964
965         return desc;
966 }
967
968
969 /* linker_compute_subclasses ***************************************************
970
971    XXX
972
973 *******************************************************************************/
974
975 static void linker_compute_subclasses(classinfo *c)
976 {
977 #if defined(USE_THREADS)
978 #if defined(NATIVE_THREADS)
979         compiler_lock();
980 #else
981         intsDisable();
982 #endif
983 #endif
984
985         if (!(c->flags & ACC_INTERFACE)) {
986                 c->nextsub = 0;
987                 c->sub = 0;
988         }
989
990         if (!(c->flags & ACC_INTERFACE) && (c->super.any != NULL)) {
991                 c->nextsub = c->super.cls->sub;
992                 c->super.cls->sub = c;
993         }
994
995         classvalue = 0;
996
997         /* compute class values */
998
999         linker_compute_class_values(class_java_lang_Object);
1000
1001 #if defined(USE_THREADS)
1002 #if defined(NATIVE_THREADS)
1003         compiler_unlock();
1004 #else
1005         intsRestore();
1006 #endif
1007 #endif
1008 }
1009
1010
1011 /* linker_compute_class_values *************************************************
1012
1013    XXX
1014
1015 *******************************************************************************/
1016
1017 static void linker_compute_class_values(classinfo *c)
1018 {
1019         classinfo *subs;
1020
1021         c->vftbl->baseval = ++classvalue;
1022
1023         subs = c->sub;
1024
1025         while (subs) {
1026                 linker_compute_class_values(subs);
1027
1028                 subs = subs->nextsub;
1029         }
1030
1031         c->vftbl->diffval = classvalue - c->vftbl->baseval;
1032 }
1033
1034
1035 /* linker_addinterface *********************************************************
1036
1037    Is needed by link_class for adding a VTBL to a class. All
1038    interfaces implemented by ic are added as well.
1039
1040 *******************************************************************************/
1041
1042 static void linker_addinterface(classinfo *c, classinfo *ic)
1043 {
1044         s4     j, m;
1045         s4     i   = ic->index;
1046         vftbl_t *v = c->vftbl;
1047
1048         if (i >= v->interfacetablelength) {
1049                 log_text("Inernal error: interfacetable overflow");
1050                 assert(0);
1051         }
1052
1053         if (v->interfacetable[-i])
1054                 return;
1055
1056         if (ic->methodscount == 0) {  /* fake entry needed for subtype test */
1057                 v->interfacevftbllength[i] = 1;
1058                 v->interfacetable[-i] = MNEW(methodptr, 1);
1059                 v->interfacetable[-i][0] = NULL;
1060
1061         } else {
1062                 v->interfacevftbllength[i] = ic->methodscount;
1063                 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1064
1065 #if defined(STATISTICS)
1066                 if (opt_stat)
1067                         count_vftbl_len += sizeof(methodptr) *
1068                                 (ic->methodscount + (ic->methodscount == 0));
1069 #endif
1070
1071                 for (j = 0; j < ic->methodscount; j++) {
1072                         classinfo *sc = c;
1073
1074                         while (sc) {
1075                                 for (m = 0; m < sc->methodscount; m++) {
1076                                         methodinfo *mi = &(sc->methods[m]);
1077
1078                                         if (method_canoverwrite(mi, &(ic->methods[j]))) {
1079                                                 v->interfacetable[-i][j] = v->table[mi->vftblindex];
1080                                                 goto foundmethod;
1081                                         }
1082                                 }
1083                                 sc = sc->super.cls;
1084                         }
1085                 foundmethod:
1086                         ;
1087                 }
1088         }
1089
1090         for (j = 0; j < ic->interfacescount; j++) 
1091                 linker_addinterface(c, ic->interfaces[j].cls);
1092 }
1093
1094
1095 /* class_highestinterface ******************************************************
1096
1097    Used by the function link_class to determine the amount of memory
1098    needed for the interface table.
1099
1100 *******************************************************************************/
1101
1102 static s4 class_highestinterface(classinfo *c)
1103 {
1104         s4 h;
1105         s4 h2;
1106         s4 i;
1107         
1108     /* check for ACC_INTERFACE bit already done in link_class_intern */
1109
1110     h = c->index;
1111
1112         for (i = 0; i < c->interfacescount; i++) {
1113                 h2 = class_highestinterface(c->interfaces[i].cls);
1114
1115                 if (h2 > h)
1116                         h = h2;
1117         }
1118
1119         return h;
1120 }
1121
1122
1123 /*
1124  * These are local overrides for various environment variables in Emacs.
1125  * Please do not remove this and leave it at the end of the file, where
1126  * Emacs will automagically detect them.
1127  * ---------------------------------------------------------------------
1128  * Local variables:
1129  * mode: c
1130  * indent-tabs-mode: t
1131  * c-basic-offset: 4
1132  * tab-width: 4
1133  * End:
1134  */