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