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