Edwin Steiner
Christian Thalinger
- $Id: linker.c 5036 2006-06-19 21:04:37Z twisti $
+ $Id: linker.c 5058 2006-06-28 21:46:41Z twisti $
*/
#include "vm/stringlocal.h"
#include "vm/access.h"
#include "vm/rt-timing.h"
+#include "vm/vm.h"
+#include "vm/jit/asmpart.h"
/* global variables ***********************************************************/
for (i = 0; i < supervftbllength; i++)
v->table[i] = super->vftbl->table[i];
-
+
+ /* Fill the remaining vftbl slots with the AbstractMethodError
+ stub (all after the super class slots, because they are already
+ initialized). */
+
+ for (; i < vftbllength; i++)
+ v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
+
/* add method stubs into virtual function table */
for (i = 0; i < c->methodscount; i++) {
methodinfo *m = &(c->methods[i]);
- /* Methods in ABSTRACT classes from interfaces maybe already
- have a stubroutine. */
+ assert(m->stubroutine == NULL);
+
+ /* Don't create a compiler stub for abstract methods as they
+ throw an AbstractMethodError with the default stub in the
+ vftbl. This entry is simply copied by sub-classes. */
+
+ if (m->flags & ACC_ABSTRACT)
+ continue;
- if (m->stubroutine == NULL) {
#if defined(ENABLE_JIT)
# if defined(ENABLE_INTRP)
- if (opt_intrp)
- m->stubroutine = intrp_createcompilerstub(m);
- else
+ if (opt_intrp)
+ m->stubroutine = intrp_createcompilerstub(m);
+ else
#endif
- m->stubroutine = createcompilerstub(m);
+ m->stubroutine = createcompilerstub(m);
#else
- m->stubroutine = intrp_createcompilerstub(m);
+ m->stubroutine = intrp_createcompilerstub(m);
#endif
- }
- if (!(m->flags & ACC_STATIC))
- v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
+ /* static methods are not in the vftbl */
+
+ if (m->flags & ACC_STATIC)
+ continue;
+
+ /* insert the stubroutine into the vftbl */
+
+ v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
}
RT_TIMING_GET_TIME(time_fill_vftbl);
v->interfacevftbllength[i] = 1;
v->interfacetable[-i] = MNEW(methodptr, 1);
v->interfacetable[-i][0] = NULL;
-
}
else {
v->interfacevftbllength[i] = ic->methodscount;
}
}
}
+
+ /* If no method was found, insert the AbstractMethodError
+ stub. */
+
+ v->interfacetable[-i][j] =
+ (methodptr) (ptrint) &asm_abstractmethoderror;
+
foundmethod:
;
}