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