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