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