1 /* src/vm/linker.c - class linker functions
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Reinhard Grafl
29 Changes: Andreas Krall
35 $Id: linker.c 4520 2006-02-14 20:09:53Z edwin $
46 #include "mm/memory.h"
47 #include "native/native.h"
48 #include "vm/builtin.h"
50 #include "vm/classcache.h"
51 #include "vm/exceptions.h"
52 #include "vm/loader.h"
53 #include "vm/options.h"
54 #include "vm/resolve.h"
55 #include "vm/statistics.h"
56 #include "vm/stringlocal.h"
57 #include "vm/access.h"
60 /* global variables ***********************************************************/
62 static s4 interfaceindex; /* sequential numbering of interfaces */
66 /* primitivetype_table *********************************************************
68 Structure for primitive classes: contains the class for wrapping
69 the primitive type, the primitive class, the name of the class for
70 wrapping, the one character type signature and the name of the
73 CAUTION: Don't change the order of the types. This table is indexed
74 by the ARRAYTYPE_ constants (except ARRAYTYPE_OBJECT).
76 *******************************************************************************/
78 primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = {
79 { NULL, NULL, "java/lang/Integer", 'I', "int" , "[I", NULL, NULL },
80 { NULL, NULL, "java/lang/Long", 'J', "long" , "[J", NULL, NULL },
81 { NULL, NULL, "java/lang/Float", 'F', "float" , "[F", NULL, NULL },
82 { NULL, NULL, "java/lang/Double", 'D', "double" , "[D", NULL, NULL },
83 { NULL, NULL, NULL, 0 , NULL , NULL, NULL, NULL },
84 { NULL, NULL, "java/lang/Byte", 'B', "byte" , "[B", NULL, NULL },
85 { NULL, NULL, "java/lang/Character", 'C', "char" , "[C", NULL, NULL },
86 { NULL, NULL, "java/lang/Short", 'S', "short" , "[S", NULL, NULL },
87 { NULL, NULL, "java/lang/Boolean", 'Z', "boolean" , "[Z", NULL, NULL },
88 { NULL, NULL, NULL, 0 , NULL , NULL, NULL, NULL },
89 { NULL, NULL, "java/lang/Void", 'V', "void" , NULL, NULL, NULL }
93 /* private functions **********************************************************/
95 static bool link_primitivetype_table(void);
96 static classinfo *link_class_intern(classinfo *c);
97 static arraydescriptor *link_array(classinfo *c);
98 static void linker_compute_class_values(classinfo *c);
99 static void linker_compute_subclasses(classinfo *c);
100 static void linker_addinterface(classinfo *c, classinfo *ic);
101 static s4 class_highestinterface(classinfo *c);
104 /* linker_init *****************************************************************
106 Initializes the linker subsystem.
108 *******************************************************************************/
110 bool linker_init(void)
112 /* reset interface index */
116 /* link java.lang.Class as first class of the system, because we
117 need it's vftbl for all other classes so we can use a class as
120 if (!link_class(class_java_lang_Class))
123 /* now set the header.vftbl of all classes which were created
124 before java.lang.Class was linked */
126 class_postset_header_vftbl();
129 /* link important system classes */
131 if (!link_class(class_java_lang_Object))
134 if (!link_class(class_java_lang_String))
137 if (!link_class(class_java_lang_Cloneable))
140 if (!link_class(class_java_io_Serializable))
144 /* link classes for wrapping primitive types */
146 if (!link_class(class_java_lang_Void))
149 if (!link_class(class_java_lang_Boolean))
152 if (!link_class(class_java_lang_Byte))
155 if (!link_class(class_java_lang_Character))
158 if (!link_class(class_java_lang_Short))
161 if (!link_class(class_java_lang_Integer))
164 if (!link_class(class_java_lang_Long))
167 if (!link_class(class_java_lang_Float))
170 if (!link_class(class_java_lang_Double))
174 /* load some other important classes */
176 if (!link_class(class_java_lang_ClassLoader))
179 if (!link_class(class_java_lang_SecurityManager))
182 if (!link_class(class_java_lang_System))
185 if (!link_class(class_java_lang_Thread))
188 if (!link_class(class_java_lang_ThreadGroup))
191 if (!link_class(class_java_lang_VMThread))
195 /* some classes which may be used more often */
197 if (!link_class(class_java_lang_StackTraceElement))
200 if (!link_class(class_java_lang_reflect_Constructor))
203 if (!link_class(class_java_lang_reflect_Field))
206 if (!link_class(class_java_lang_reflect_Method))
209 if (!link_class(class_java_security_PrivilegedAction))
212 if (!link_class(class_java_util_Vector))
215 if (!link_class(arrayclass_java_lang_Object))
219 /* create pseudo classes used by the typechecker */
221 /* pseudo class for Arraystubs (extends java.lang.Object) */
223 pseudo_class_Arraystub =
224 class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
225 pseudo_class_Arraystub->state |= CLASS_LOADED;
226 pseudo_class_Arraystub->super.cls = class_java_lang_Object;
227 pseudo_class_Arraystub->interfacescount = 2;
228 pseudo_class_Arraystub->interfaces = MNEW(classref_or_classinfo, 2);
229 pseudo_class_Arraystub->interfaces[0].cls = class_java_lang_Cloneable;
230 pseudo_class_Arraystub->interfaces[1].cls = class_java_io_Serializable;
232 if (!classcache_store_unique(pseudo_class_Arraystub)) {
233 log_text("could not cache pseudo_class_Arraystub");
237 if (!link_class(pseudo_class_Arraystub))
240 /* pseudo class representing the null type */
242 pseudo_class_Null = class_create_classinfo(utf_new_char("$NULL$"));
243 pseudo_class_Null->state |= CLASS_LOADED;
244 pseudo_class_Null->super.cls = class_java_lang_Object;
246 if (!classcache_store_unique(pseudo_class_Null)) {
247 log_text("could not cache pseudo_class_Null");
251 if (!link_class(pseudo_class_Null))
254 /* pseudo class representing new uninitialized objects */
256 pseudo_class_New = class_create_classinfo(utf_new_char("$NEW$"));
257 pseudo_class_New->state |= CLASS_LOADED;
258 pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
259 pseudo_class_New->super.cls = class_java_lang_Object;
261 if (!classcache_store_unique(pseudo_class_New)) {
262 log_text("could not cache pseudo_class_New");
266 /* create classes representing primitive types */
268 if (!link_primitivetype_table())
272 /* Correct vftbl-entries (retarded loading and linking of class */
273 /* java/lang/String). */
275 stringtable_update();
281 /* link_primitivetype_table ****************************************************
283 Create classes representing primitive types.
285 *******************************************************************************/
287 static bool link_primitivetype_table(void)
293 for (i = 0; i < PRIMITIVETYPE_COUNT; i++) {
296 if (!primitivetype_table[i].name)
299 /* create primitive class */
301 c = class_create_classinfo(utf_new_char(primitivetype_table[i].name));
303 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
305 /* prevent loader from loading primitive class */
307 c->state |= CLASS_LOADED;
309 /* INFO: don't put primitive classes into the classcache */
314 primitivetype_table[i].class_primitive = c;
316 /* create class for wrapping the primitive type */
318 u = utf_new_char(primitivetype_table[i].wrapname);
320 if (!(c = load_class_bootstrap(u)))
323 primitivetype_table[i].class_wrap = c;
325 /* create the primitive array class */
327 if (primitivetype_table[i].arrayname) {
328 u = utf_new_char(primitivetype_table[i].arrayname);
329 c = class_create_classinfo(u);
330 c = load_newly_created_array(c, NULL);
334 primitivetype_table[i].arrayclass = c;
336 assert(c->state & CLASS_LOADED);
338 if (!(c->state & CLASS_LINKED))
342 primitivetype_table[i].arrayvftbl = c->vftbl;
350 /* link_class ******************************************************************
352 Wrapper function for link_class_intern to ease monitor enter/exit
353 and exception handling.
355 *******************************************************************************/
357 classinfo *link_class(classinfo *c)
362 exceptions_throw_nullpointerexception();
366 #if defined(USE_THREADS)
367 /* enter a monitor on the class */
369 builtin_monitorenter((java_objectheader *) c);
372 /* maybe the class is already linked */
374 if (c->state & CLASS_LINKED) {
375 #if defined(USE_THREADS)
376 builtin_monitorexit((java_objectheader *) c);
382 #if defined(ENABLE_STATISTICS)
385 if (getcompilingtime)
386 compilingtime_stop();
392 /* call the internal function */
394 r = link_class_intern(c);
396 /* if return value is NULL, we had a problem and the class is not linked */
399 c->state &= ~CLASS_LINKING;
401 #if defined(ENABLE_STATISTICS)
407 if (getcompilingtime)
408 compilingtime_start();
411 #if defined(USE_THREADS)
412 /* leave the monitor */
414 builtin_monitorexit((java_objectheader *) c);
421 /* link_class_intern ***********************************************************
423 Tries to link a class. The function calculates the length in bytes
424 that an instance of this class requires as well as the VTBL for
425 methods and interface methods.
427 *******************************************************************************/
429 static classinfo *link_class_intern(classinfo *c)
431 classinfo *super; /* super class */
432 classinfo *tc; /* temporary class variable */
433 s4 supervftbllength; /* vftbllegnth of super class */
434 s4 vftbllength; /* vftbllength of current class */
435 s4 interfacetablelength; /* interface table length */
436 vftbl_t *v; /* vftbl of current class */
437 s4 i,j; /* interface/method/field counter */
438 arraydescriptor *arraydesc; /* descriptor for array classes */
440 /* the class is already linked */
442 if (c->state & CLASS_LINKED)
446 log_message_class("Linking class: ", c);
448 /* the class must be loaded */
450 /* XXX should this be a specific exception? */
451 assert(c->state & CLASS_LOADED);
453 /* cache the self-reference of this class */
454 /* we do this for cases where the defining loader of the class */
455 /* has not yet been recorded as an initiating loader for the class */
456 /* this is needed so subsequent code can assume that self-refs */
457 /* will always resolve lazily */
458 /* No need to do it for the bootloader - it is always registered */
459 /* as initiating loader for the classes it loads. */
461 classcache_store(c->classloader,c,false);
463 /* this class is currently linking */
465 c->state |= CLASS_LINKING;
469 /* check interfaces */
471 for (i = 0; i < c->interfacescount; i++) {
472 /* resolve this super interface */
474 if (!resolve_classref_or_classinfo(NULL, c->interfaces[i], resolveEager,
478 c->interfaces[i].cls = tc;
480 /* detect circularity */
484 new_exception_utfmessage(string_java_lang_ClassCircularityError,
489 assert(tc->state & CLASS_LOADED);
491 if (!(tc->flags & ACC_INTERFACE)) {
493 new_exception_message(string_java_lang_IncompatibleClassChangeError,
494 "Implementing class");
498 if (!(tc->state & CLASS_LINKED))
503 /* check super class */
507 if (c->super.any == NULL) { /* class java.lang.Object */
509 c->instancesize = sizeof(java_objectheader);
511 vftbllength = supervftbllength = 0;
516 /* resolve super class */
518 if (!resolve_classref_or_classinfo(NULL, c->super, resolveEager, true, false,
521 c->super.cls = super;
523 /* detect circularity */
527 new_exception_utfmessage(string_java_lang_ClassCircularityError,
532 assert(super->state & CLASS_LOADED);
534 if (super->flags & ACC_INTERFACE) {
535 /* java.lang.IncompatibleClassChangeError: class a has interface java.lang.Cloneable as super class */
536 log_text("Interface specified as super class");
540 /* Don't allow extending final classes */
542 if (super->flags & ACC_FINAL) {
544 new_exception_message(string_java_lang_VerifyError,
545 "Cannot inherit from final class");
549 if (!(super->state & CLASS_LINKED))
550 if (!link_class(super))
553 /* handle array classes */
555 if (c->name->text[0] == '[')
556 if (!(arraydesc = link_array(c)))
559 if (c->flags & ACC_INTERFACE)
560 c->index = interfaceindex++;
562 c->index = super->index + 1;
564 c->instancesize = super->instancesize;
566 vftbllength = supervftbllength = super->vftbl->vftbllength;
568 c->finalizer = super->finalizer;
572 /* compute vftbl length */
574 for (i = 0; i < c->methodscount; i++) {
575 methodinfo *m = &(c->methods[i]);
577 if (!(m->flags & ACC_STATIC)) { /* is instance method */
583 for (j = 0; j < tc->methodscount; j++) {
584 if (method_canoverwrite(m, &(tc->methods[j]))) {
585 if (tc->methods[j].flags & ACC_PRIVATE)
586 goto notfoundvftblindex;
588 /* package-private methods in other packages */
589 /* must not be overridden */
590 /* (see Java Language Specification 8.4.8.1) */
591 if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED))
592 && !SAME_PACKAGE(c,tc) )
594 goto notfoundvftblindex;
597 if (tc->methods[j].flags & ACC_FINAL) {
598 /* class a overrides final method . */
600 new_exception(string_java_lang_VerifyError);
604 m->vftblindex = tc->methods[j].vftblindex;
605 goto foundvftblindex;
613 m->vftblindex = (vftbllength++);
620 /* check interfaces of ABSTRACT class for unimplemented methods */
622 if (c->flags & ACC_ABSTRACT) {
625 s4 abstractmethodscount;
629 abstractmethodscount = 0;
631 for (i = 0; i < c->interfacescount; i++) {
632 ic = c->interfaces[i].cls;
634 for (j = 0; j < ic->methodscount; j++) {
635 im = &(ic->methods[j]);
637 /* skip `<clinit>' and `<init>' */
639 if (im->name == utf_clinit || im->name == utf_init)
645 for (k = 0; k < tc->methodscount; k++) {
646 if (method_canoverwrite(im, &(tc->methods[k])))
647 goto noabstractmethod;
653 abstractmethodscount++;
660 if (abstractmethodscount > 0) {
663 /* reallocate methods memory */
665 c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
666 c->methodscount + abstractmethodscount);
668 for (i = 0; i < c->interfacescount; i++) {
669 ic = c->interfaces[i].cls;
671 for (j = 0; j < ic->methodscount; j++) {
672 im = &(ic->methods[j]);
674 /* skip `<clinit>' and `<init>' */
676 if (im->name == utf_clinit || im->name == utf_init)
682 for (k = 0; k < tc->methodscount; k++) {
683 if (method_canoverwrite(im, &(tc->methods[k])))
684 goto noabstractmethod2;
690 am = &(c->methods[c->methodscount]);
693 MCOPY(am, im, methodinfo, 1);
695 am->vftblindex = (vftbllength++);
706 #if defined(ENABLE_STATISTICS)
709 sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
712 /* compute interfacetable length */
714 interfacetablelength = 0;
717 for (i = 0; i < tc->interfacescount; i++) {
718 s4 h = class_highestinterface(tc->interfaces[i].cls) + 1;
719 if (h > interfacetablelength)
720 interfacetablelength = h;
725 /* allocate virtual function table */
727 v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
728 sizeof(methodptr) * (vftbllength - 1) +
729 sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
730 v = (vftbl_t *) (((methodptr *) v) +
731 (interfacetablelength - 1) * (interfacetablelength > 1));
734 v->vftbllength = vftbllength;
735 v->interfacetablelength = interfacetablelength;
736 v->arraydesc = arraydesc;
738 /* store interface index in vftbl */
740 if (c->flags & ACC_INTERFACE)
741 v->baseval = -(c->index);
743 /* copy virtual function table of super class */
745 for (i = 0; i < supervftbllength; i++)
746 v->table[i] = super->vftbl->table[i];
748 /* add method stubs into virtual function table */
750 for (i = 0; i < c->methodscount; i++) {
751 methodinfo *m = &(c->methods[i]);
753 /* Methods in ABSTRACT classes from interfaces maybe already have a */
756 if (!m->stubroutine) {
757 #if defined(ENABLE_JIT)
758 # if defined(ENABLE_INTRP)
760 m->stubroutine = intrp_createcompilerstub(m);
763 m->stubroutine = createcompilerstub(m);
765 m->stubroutine = intrp_createcompilerstub(m);
769 if (!(m->flags & ACC_STATIC))
770 v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
773 /* compute instance size and offset of each field */
775 for (i = 0; i < c->fieldscount; i++) {
777 fieldinfo *f = &(c->fields[i]);
779 if (!(f->flags & ACC_STATIC)) {
780 dsize = descriptor_typesize(f->parseddesc);
781 c->instancesize = ALIGN(c->instancesize, dsize);
782 f->offset = c->instancesize;
783 c->instancesize += dsize;
787 /* initialize interfacetable and interfacevftbllength */
789 v->interfacevftbllength = MNEW(s4, interfacetablelength);
791 #if defined(ENABLE_STATISTICS)
793 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
796 for (i = 0; i < interfacetablelength; i++) {
797 v->interfacevftbllength[i] = 0;
798 v->interfacetable[-i] = NULL;
803 for (tc = c; tc != NULL; tc = tc->super.cls)
804 for (i = 0; i < tc->interfacescount; i++)
805 linker_addinterface(c, tc->interfaces[i].cls);
807 /* add finalizer method (not for java.lang.Object) */
812 fi = class_findmethod(c, utf_finalize, utf_void__void);
815 if (!(fi->flags & ACC_STATIC))
819 /* resolve exception class references */
821 for (i = 0; i < c->methodscount; i++) {
822 methodinfo *m = &(c->methods[i]);
824 for (j = 0; j < m->exceptiontablelength; j++) {
825 if (!m->exceptiontable[j].catchtype.any)
827 if (!resolve_classref_or_classinfo(NULL,
828 m->exceptiontable[j].catchtype,
829 resolveEager, true, false,
830 &(m->exceptiontable[j].catchtype.cls)))
837 linker_compute_subclasses(c);
839 /* revert the linking state and class is linked */
841 c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
844 log_message_class("Linking done class: ", c);
846 /* just return c to show that we didn't had a problem */
852 /* link_array ******************************************************************
854 This function is called by link_class to create the arraydescriptor
857 This function returns NULL if the array cannot be linked because
858 the component type has not been linked yet.
860 *******************************************************************************/
862 static arraydescriptor *link_array(classinfo *c)
866 arraydescriptor *desc;
871 namelen = c->name->blength;
873 /* Check the component type */
875 switch (c->name->text[1]) {
877 /* c is an array of arrays. */
878 u = utf_new(c->name->text + 1, namelen - 1);
879 if (!(comp = load_class_from_classloader(u, c->classloader)))
884 /* c is an array of objects. */
885 u = utf_new(c->name->text + 2, namelen - 3);
886 if (!(comp = load_class_from_classloader(u, c->classloader)))
891 /* If the component type has not been linked, link it now */
893 assert(!comp || (comp->state & CLASS_LOADED));
895 if (comp && !(comp->state & CLASS_LINKED))
896 if (!link_class(comp))
899 /* Allocate the arraydescriptor */
901 desc = NEW(arraydescriptor);
904 /* c is an array of references */
905 desc->arraytype = ARRAYTYPE_OBJECT;
906 desc->componentsize = sizeof(void*);
907 desc->dataoffset = OFFSET(java_objectarray, data);
909 compvftbl = comp->vftbl;
912 log_text("Component class has no vftbl");
916 desc->componentvftbl = compvftbl;
918 if (compvftbl->arraydesc) {
919 desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
921 if (compvftbl->arraydesc->dimension >= 255) {
922 log_text("Creating array of dimension >255");
926 desc->dimension = compvftbl->arraydesc->dimension + 1;
927 desc->elementtype = compvftbl->arraydesc->elementtype;
930 desc->elementvftbl = compvftbl;
932 desc->elementtype = ARRAYTYPE_OBJECT;
936 /* c is an array of a primitive type */
937 switch (c->name->text[1]) {
939 desc->arraytype = ARRAYTYPE_BOOLEAN;
940 desc->dataoffset = OFFSET(java_booleanarray,data);
941 desc->componentsize = sizeof(u1);
945 desc->arraytype = ARRAYTYPE_BYTE;
946 desc->dataoffset = OFFSET(java_bytearray,data);
947 desc->componentsize = sizeof(u1);
951 desc->arraytype = ARRAYTYPE_CHAR;
952 desc->dataoffset = OFFSET(java_chararray,data);
953 desc->componentsize = sizeof(u2);
957 desc->arraytype = ARRAYTYPE_DOUBLE;
958 desc->dataoffset = OFFSET(java_doublearray,data);
959 desc->componentsize = sizeof(double);
963 desc->arraytype = ARRAYTYPE_FLOAT;
964 desc->dataoffset = OFFSET(java_floatarray,data);
965 desc->componentsize = sizeof(float);
969 desc->arraytype = ARRAYTYPE_INT;
970 desc->dataoffset = OFFSET(java_intarray,data);
971 desc->componentsize = sizeof(s4);
975 desc->arraytype = ARRAYTYPE_LONG;
976 desc->dataoffset = OFFSET(java_longarray,data);
977 desc->componentsize = sizeof(s8);
981 desc->arraytype = ARRAYTYPE_SHORT;
982 desc->dataoffset = OFFSET(java_shortarray,data);
983 desc->componentsize = sizeof(s2);
987 *exceptionptr = new_noclassdeffounderror(c->name);
991 desc->componentvftbl = NULL;
992 desc->elementvftbl = NULL;
994 desc->elementtype = desc->arraytype;
1001 /* linker_compute_subclasses ***************************************************
1005 *******************************************************************************/
1007 static void linker_compute_subclasses(classinfo *c)
1009 #if defined(USE_THREADS)
1010 #if defined(NATIVE_THREADS)
1017 if (!(c->flags & ACC_INTERFACE)) {
1022 if (!(c->flags & ACC_INTERFACE) && (c->super.any != NULL)) {
1023 c->nextsub = c->super.cls->sub;
1024 c->super.cls->sub = c;
1029 /* compute class values */
1031 linker_compute_class_values(class_java_lang_Object);
1033 #if defined(USE_THREADS)
1034 #if defined(NATIVE_THREADS)
1043 /* linker_compute_class_values *************************************************
1047 *******************************************************************************/
1049 static void linker_compute_class_values(classinfo *c)
1053 c->vftbl->baseval = ++classvalue;
1058 linker_compute_class_values(subs);
1060 subs = subs->nextsub;
1063 c->vftbl->diffval = classvalue - c->vftbl->baseval;
1067 /* linker_addinterface *********************************************************
1069 Is needed by link_class for adding a VTBL to a class. All
1070 interfaces implemented by ic are added as well.
1072 *******************************************************************************/
1074 static void linker_addinterface(classinfo *c, classinfo *ic)
1078 vftbl_t *v = c->vftbl;
1080 if (i >= v->interfacetablelength) {
1081 log_text("Inernal error: interfacetable overflow");
1085 if (v->interfacetable[-i])
1088 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1089 v->interfacevftbllength[i] = 1;
1090 v->interfacetable[-i] = MNEW(methodptr, 1);
1091 v->interfacetable[-i][0] = NULL;
1094 v->interfacevftbllength[i] = ic->methodscount;
1095 v->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1097 #if defined(ENABLE_STATISTICS)
1099 count_vftbl_len += sizeof(methodptr) *
1100 (ic->methodscount + (ic->methodscount == 0));
1103 for (j = 0; j < ic->methodscount; j++) {
1107 for (m = 0; m < sc->methodscount; m++) {
1108 methodinfo *mi = &(sc->methods[m]);
1110 if (method_canoverwrite(mi, &(ic->methods[j]))) {
1111 v->interfacetable[-i][j] = v->table[mi->vftblindex];
1122 for (j = 0; j < ic->interfacescount; j++)
1123 linker_addinterface(c, ic->interfaces[j].cls);
1127 /* class_highestinterface ******************************************************
1129 Used by the function link_class to determine the amount of memory
1130 needed for the interface table.
1132 *******************************************************************************/
1134 static s4 class_highestinterface(classinfo *c)
1140 /* check for ACC_INTERFACE bit already done in link_class_intern */
1144 for (i = 0; i < c->interfacescount; i++) {
1145 h2 = class_highestinterface(c->interfaces[i].cls);
1156 * These are local overrides for various environment variables in Emacs.
1157 * Please do not remove this and leave it at the end of the file, where
1158 * Emacs will automagically detect them.
1159 * ---------------------------------------------------------------------
1162 * indent-tabs-mode: t
1166 * vim:noexpandtab:sw=4:ts=4: