* Updated header: Added 2006. Changed address of FSF. Changed email
[cacao.git] / src / vm / linker.c
1 /* src/vm/linker.c - class linker functions
2
3    Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, 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., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
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 4357 2006-01-22 23:33:38Z twisti $
36
37 */
38
39
40 #include "config.h"
41
42 #include <assert.h>
43
44 #include "vm/types.h"
45
46 #include "mm/memory.h"
47 #include "native/native.h"
48 #include "vm/builtin.h"
49 #include "vm/class.h"
50 #include "vm/classcache.h"
51 #include "vm/exceptions.h"
52 #include "vm/loader.h"
53 #include "vm/options.h"
54 #include "vm/resolve.h"
55 #include "vm/statistics.h"
56 #include "vm/stringlocal.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                 exceptions_throw_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(ENABLE_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(ENABLE_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(ENABLE_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 #if defined(ENABLE_JIT)
754 # if defined(ENABLE_INTRP)
755                         if (opt_intrp)
756                                 m->stubroutine = intrp_createcompilerstub(m);
757                         else
758 #endif
759                                 m->stubroutine = createcompilerstub(m);
760 #else
761                         m->stubroutine = intrp_createcompilerstub(m);
762 #endif
763                 }
764
765                 if (!(m->flags & ACC_STATIC))
766                         v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
767         }
768
769         /* compute instance size and offset of each field */
770         
771         for (i = 0; i < c->fieldscount; i++) {
772                 s4 dsize;
773                 fieldinfo *f = &(c->fields[i]);
774                 
775                 if (!(f->flags & ACC_STATIC)) {
776                         dsize = descriptor_typesize(f->parseddesc);
777                         c->instancesize = ALIGN(c->instancesize, dsize);
778                         f->offset = c->instancesize;
779                         c->instancesize += dsize;
780                 }
781         }
782
783         /* initialize interfacetable and interfacevftbllength */
784         
785         v->interfacevftbllength = MNEW(s4, interfacetablelength);
786
787 #if defined(ENABLE_STATISTICS)
788         if (opt_stat)
789                 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
790 #endif
791
792         for (i = 0; i < interfacetablelength; i++) {
793                 v->interfacevftbllength[i] = 0;
794                 v->interfacetable[-i] = NULL;
795         }
796         
797         /* add interfaces */
798         
799         for (tc = c; tc != NULL; tc = tc->super.cls)
800                 for (i = 0; i < tc->interfacescount; i++)
801                         linker_addinterface(c, tc->interfaces[i].cls);
802
803         /* add finalizer method (not for java.lang.Object) */
804
805         if (super) {
806                 methodinfo *fi;
807
808                 fi = class_findmethod(c, utf_finalize, utf_void__void);
809
810                 if (fi)
811                         if (!(fi->flags & ACC_STATIC))
812                                 c->finalizer = fi;
813         }
814
815         /* resolve exception class references */
816
817         for (i = 0; i < c->methodscount; i++) {
818                 methodinfo *m = &(c->methods[i]);
819
820                 for (j = 0; j < m->exceptiontablelength; j++) {
821                         if (!m->exceptiontable[j].catchtype.any)
822                                 continue;
823                         if (!resolve_classref_or_classinfo(NULL,
824                                                                                            m->exceptiontable[j].catchtype,
825                                                                                            resolveEager, true, false,
826                                                                                            &(m->exceptiontable[j].catchtype.cls)))
827                                 return NULL;
828                 }
829         }
830         
831         /* final tasks */
832
833         linker_compute_subclasses(c);
834
835         /* revert the linking state and class is linked */
836
837         c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
838
839         if (linkverbose)
840                 log_message_class("Linking done class: ", c);
841
842         /* just return c to show that we didn't had a problem */
843
844         return c;
845 }
846
847
848 /* link_array ******************************************************************
849
850    This function is called by link_class to create the arraydescriptor
851    for an array class.
852
853    This function returns NULL if the array cannot be linked because
854    the component type has not been linked yet.
855
856 *******************************************************************************/
857
858 static arraydescriptor *link_array(classinfo *c)
859 {
860         classinfo       *comp;
861         s4               namelen;
862         arraydescriptor *desc;
863         vftbl_t         *compvftbl;
864         utf             *u;
865
866         comp = NULL;
867         namelen = c->name->blength;
868
869         /* Check the component type */
870
871         switch (c->name->text[1]) {
872         case '[':
873                 /* c is an array of arrays. */
874                 u = utf_new(c->name->text + 1, namelen - 1);
875                 if (!(comp = load_class_from_classloader(u, c->classloader)))
876                         return NULL;
877                 break;
878
879         case 'L':
880                 /* c is an array of objects. */
881                 u = utf_new(c->name->text + 2, namelen - 3);
882                 if (!(comp = load_class_from_classloader(u, c->classloader)))
883                         return NULL;
884                 break;
885         }
886
887         /* If the component type has not been linked, link it now */
888
889         assert(!comp || (comp->state & CLASS_LOADED));
890
891         if (comp && !(comp->state & CLASS_LINKED))
892                 if (!link_class(comp))
893                         return NULL;
894
895         /* Allocate the arraydescriptor */
896
897         desc = NEW(arraydescriptor);
898
899         if (comp) {
900                 /* c is an array of references */
901                 desc->arraytype = ARRAYTYPE_OBJECT;
902                 desc->componentsize = sizeof(void*);
903                 desc->dataoffset = OFFSET(java_objectarray, data);
904                 
905                 compvftbl = comp->vftbl;
906
907                 if (!compvftbl) {
908                         log_text("Component class has no vftbl");
909                         assert(0);
910                 }
911
912                 desc->componentvftbl = compvftbl;
913                 
914                 if (compvftbl->arraydesc) {
915                         desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
916
917                         if (compvftbl->arraydesc->dimension >= 255) {
918                                 log_text("Creating array of dimension >255");
919                                 assert(0);
920                         }
921
922                         desc->dimension = compvftbl->arraydesc->dimension + 1;
923                         desc->elementtype = compvftbl->arraydesc->elementtype;
924
925                 } else {
926                         desc->elementvftbl = compvftbl;
927                         desc->dimension = 1;
928                         desc->elementtype = ARRAYTYPE_OBJECT;
929                 }
930
931         } else {
932                 /* c is an array of a primitive type */
933                 switch (c->name->text[1]) {
934                 case 'Z':
935                         desc->arraytype = ARRAYTYPE_BOOLEAN;
936                         desc->dataoffset = OFFSET(java_booleanarray,data);
937                         desc->componentsize = sizeof(u1);
938                         break;
939
940                 case 'B':
941                         desc->arraytype = ARRAYTYPE_BYTE;
942                         desc->dataoffset = OFFSET(java_bytearray,data);
943                         desc->componentsize = sizeof(u1);
944                         break;
945
946                 case 'C':
947                         desc->arraytype = ARRAYTYPE_CHAR;
948                         desc->dataoffset = OFFSET(java_chararray,data);
949                         desc->componentsize = sizeof(u2);
950                         break;
951
952                 case 'D':
953                         desc->arraytype = ARRAYTYPE_DOUBLE;
954                         desc->dataoffset = OFFSET(java_doublearray,data);
955                         desc->componentsize = sizeof(double);
956                         break;
957
958                 case 'F':
959                         desc->arraytype = ARRAYTYPE_FLOAT;
960                         desc->dataoffset = OFFSET(java_floatarray,data);
961                         desc->componentsize = sizeof(float);
962                         break;
963
964                 case 'I':
965                         desc->arraytype = ARRAYTYPE_INT;
966                         desc->dataoffset = OFFSET(java_intarray,data);
967                         desc->componentsize = sizeof(s4);
968                         break;
969
970                 case 'J':
971                         desc->arraytype = ARRAYTYPE_LONG;
972                         desc->dataoffset = OFFSET(java_longarray,data);
973                         desc->componentsize = sizeof(s8);
974                         break;
975
976                 case 'S':
977                         desc->arraytype = ARRAYTYPE_SHORT;
978                         desc->dataoffset = OFFSET(java_shortarray,data);
979                         desc->componentsize = sizeof(s2);
980                         break;
981
982                 default:
983                         *exceptionptr = new_noclassdeffounderror(c->name);
984                         return NULL;
985                 }
986                 
987                 desc->componentvftbl = NULL;
988                 desc->elementvftbl = NULL;
989                 desc->dimension = 1;
990                 desc->elementtype = desc->arraytype;
991         }
992
993         return desc;
994 }
995
996
997 /* linker_compute_subclasses ***************************************************
998
999    XXX
1000
1001 *******************************************************************************/
1002
1003 static void linker_compute_subclasses(classinfo *c)
1004 {
1005 #if defined(USE_THREADS)
1006 #if defined(NATIVE_THREADS)
1007         compiler_lock();
1008 #else
1009         intsDisable();
1010 #endif
1011 #endif
1012
1013         if (!(c->flags & ACC_INTERFACE)) {
1014                 c->nextsub = 0;
1015                 c->sub = 0;
1016         }
1017
1018         if (!(c->flags & ACC_INTERFACE) && (c->super.any != NULL)) {
1019                 c->nextsub = c->super.cls->sub;
1020                 c->super.cls->sub = c;
1021         }
1022
1023         classvalue = 0;
1024
1025         /* compute class values */
1026
1027         linker_compute_class_values(class_java_lang_Object);
1028
1029 #if defined(USE_THREADS)
1030 #if defined(NATIVE_THREADS)
1031         compiler_unlock();
1032 #else
1033         intsRestore();
1034 #endif
1035 #endif
1036 }
1037
1038
1039 /* linker_compute_class_values *************************************************
1040
1041    XXX
1042
1043 *******************************************************************************/
1044
1045 static void linker_compute_class_values(classinfo *c)
1046 {
1047         classinfo *subs;
1048
1049         c->vftbl->baseval = ++classvalue;
1050
1051         subs = c->sub;
1052
1053         while (subs) {
1054                 linker_compute_class_values(subs);
1055
1056                 subs = subs->nextsub;
1057         }
1058
1059         c->vftbl->diffval = classvalue - c->vftbl->baseval;
1060 }
1061
1062
1063 /* linker_addinterface *********************************************************
1064
1065    Is needed by link_class for adding a VTBL to a class. All
1066    interfaces implemented by ic are added as well.
1067
1068 *******************************************************************************/
1069
1070 static void linker_addinterface(classinfo *c, classinfo *ic)
1071 {
1072         s4     j, m;
1073         s4     i   = ic->index;
1074         vftbl_t *v = c->vftbl;
1075
1076         if (i >= v->interfacetablelength) {
1077                 log_text("Inernal error: interfacetable overflow");
1078                 assert(0);
1079         }
1080
1081         if (v->interfacetable[-i])
1082                 return;
1083
1084         if (ic->methodscount == 0) {  /* fake entry needed for subtype test */
1085                 v->interfacevftbllength[i] = 1;
1086                 v->interfacetable[-i] = MNEW(methodptr, 1);
1087                 v->interfacetable[-i][0] = NULL;
1088
1089         } else {
1090                 v->interfacevftbllength[i] = ic->methodscount;
1091                 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1092
1093 #if defined(ENABLE_STATISTICS)
1094                 if (opt_stat)
1095                         count_vftbl_len += sizeof(methodptr) *
1096                                 (ic->methodscount + (ic->methodscount == 0));
1097 #endif
1098
1099                 for (j = 0; j < ic->methodscount; j++) {
1100                         classinfo *sc = c;
1101
1102                         while (sc) {
1103                                 for (m = 0; m < sc->methodscount; m++) {
1104                                         methodinfo *mi = &(sc->methods[m]);
1105
1106                                         if (method_canoverwrite(mi, &(ic->methods[j]))) {
1107                                                 v->interfacetable[-i][j] = v->table[mi->vftblindex];
1108                                                 goto foundmethod;
1109                                         }
1110                                 }
1111                                 sc = sc->super.cls;
1112                         }
1113                 foundmethod:
1114                         ;
1115                 }
1116         }
1117
1118         for (j = 0; j < ic->interfacescount; j++) 
1119                 linker_addinterface(c, ic->interfaces[j].cls);
1120 }
1121
1122
1123 /* class_highestinterface ******************************************************
1124
1125    Used by the function link_class to determine the amount of memory
1126    needed for the interface table.
1127
1128 *******************************************************************************/
1129
1130 static s4 class_highestinterface(classinfo *c)
1131 {
1132         s4 h;
1133         s4 h2;
1134         s4 i;
1135         
1136     /* check for ACC_INTERFACE bit already done in link_class_intern */
1137
1138     h = c->index;
1139
1140         for (i = 0; i < c->interfacescount; i++) {
1141                 h2 = class_highestinterface(c->interfaces[i].cls);
1142
1143                 if (h2 > h)
1144                         h = h2;
1145         }
1146
1147         return h;
1148 }
1149
1150
1151 /*
1152  * These are local overrides for various environment variables in Emacs.
1153  * Please do not remove this and leave it at the end of the file, where
1154  * Emacs will automagically detect them.
1155  * ---------------------------------------------------------------------
1156  * Local variables:
1157  * mode: c
1158  * indent-tabs-mode: t
1159  * c-basic-offset: 4
1160  * tab-width: 4
1161  * End:
1162  */