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