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