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