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