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