diff options
author | Tom Tromey <tromey@redhat.com> | 2002-12-05 07:43:45 +0000 |
---|---|---|
committer | Tom Tromey <tromey@gcc.gnu.org> | 2002-12-05 07:43:45 +0000 |
commit | eaa2834f9f7aeb81115213fcfb0d2e055afc779e (patch) | |
tree | c34b3facbe8521cce08d485b456e9ded07c686e8 /libjava/java/lang/natClass.cc | |
parent | 83f0a003b8206e33923ea484ec74e3ecee1f0c03 (diff) | |
download | gcc-eaa2834f9f7aeb81115213fcfb0d2e055afc779e.zip gcc-eaa2834f9f7aeb81115213fcfb0d2e055afc779e.tar.gz gcc-eaa2834f9f7aeb81115213fcfb0d2e055afc779e.tar.bz2 |
Class.h (_Jv_SetVTableEntries): Updated declaration.
* java/lang/Class.h (_Jv_SetVTableEntries): Updated declaration.
* resolve.cc: Don't include AbstractMethodError.h.
(_Jv_abstractMethodError): Removed.
* defineclass.cc (handleMethodsBegin): Initialize method index to
-1.
* java/lang/natClass.cc (_Jv_LayoutVTableMethods): Don't set
method index for "new" final method.
(_Jv_SetVTableEntries): Compare index against -1 instead of using
isVirtualMethod. Added `flags' argument.
(_Jv_MakeVTable): Throw exception for abstract method in concrete
class.
From-SVN: r59847
Diffstat (limited to 'libjava/java/lang/natClass.cc')
-rw-r--r-- | libjava/java/lang/natClass.cc | 71 |
1 files changed, 49 insertions, 22 deletions
diff --git a/libjava/java/lang/natClass.cc b/libjava/java/lang/natClass.cc index 68fbd54..bafac78 100644 --- a/libjava/java/lang/natClass.cc +++ b/libjava/java/lang/natClass.cc @@ -97,7 +97,7 @@ java::lang::Class::forName (jstring className) java::lang::Class *klass = NULL; try { - for (int i=1; !klass; i++) + for (int i = 1; !klass; i++) { klass = t->classAt (i); } @@ -1556,7 +1556,7 @@ _Jv_LinkOffsetTable(jclass klass) } // Returns true if METH should get an entry in a VTable. -static bool +static jboolean isVirtualMethod (_Jv_Method *meth) { using namespace java::lang::reflect; @@ -1574,7 +1574,7 @@ _Jv_LayoutVTableMethods (jclass klass) if (klass->vtable != NULL || klass->isInterface() || klass->vtable_method_count != -1) return; - + jclass superclass = klass->superclass; if (superclass != NULL && superclass->vtable_method_count == -1) @@ -1582,48 +1582,59 @@ _Jv_LayoutVTableMethods (jclass klass) JvSynchronize sync (superclass); _Jv_LayoutVTableMethods (superclass); } - + int index = (superclass == NULL ? 0 : superclass->vtable_method_count); for (int i = 0; i < klass->method_count; ++i) { _Jv_Method *meth = &klass->methods[i]; _Jv_Method *super_meth = NULL; - - if (!isVirtualMethod(meth)) - continue; - + + if (! isVirtualMethod (meth)) + continue; + if (superclass != NULL) super_meth = _Jv_LookupDeclaredMethod (superclass, meth->name, meth->signature); - + if (super_meth) meth->index = super_meth->index; - else + else if (! (meth->accflags & java::lang::reflect::Modifier::FINAL)) meth->index = index++; } - + klass->vtable_method_count = index; } -// Set entries in VTABLE for virtual methods declared in KLASS. If KLASS has -// an immediate abstract parent, recursivly do its methods first. +// Set entries in VTABLE for virtual methods declared in KLASS. If +// KLASS has an immediate abstract parent, recursively do its methods +// first. FLAGS is used to determine which slots we've actually set. void -_Jv_SetVTableEntries (jclass klass, _Jv_VTable *vtable) +_Jv_SetVTableEntries (jclass klass, _Jv_VTable *vtable, jboolean *flags) { using namespace java::lang::reflect; jclass superclass = klass->getSuperclass(); if (superclass != NULL && (superclass->getModifiers() & Modifier::ABSTRACT)) - _Jv_SetVTableEntries (superclass, vtable); - + _Jv_SetVTableEntries (superclass, vtable, flags); + for (int i = klass->method_count - 1; i >= 0; i--) { _Jv_Method *meth = &klass->methods[i]; - if (!isVirtualMethod(meth)) + if (meth->index == (_Jv_ushort) -1) continue; - vtable->set_method(meth->index, meth->ncode); + if ((meth->accflags & Modifier::ABSTRACT)) + { + // FIXME: we should set abstract slots to a function that + // throws AbstractMethodError. How can we do that on IA-64? + flags[meth->index] = false; + } + else + { + vtable->set_method(meth->index, meth->ncode); + flags[meth->index] = true; + } } } @@ -1639,7 +1650,7 @@ _Jv_MakeVTable (jclass klass) if (klass->vtable != NULL || klass->isInterface() || (klass->accflags & Modifier::ABSTRACT)) return; - + // out before we can create a vtable. if (klass->vtable_method_count == -1) _Jv_LayoutVTableMethods (klass); @@ -1647,7 +1658,11 @@ _Jv_MakeVTable (jclass klass) // Allocate the new vtable. _Jv_VTable *vtable = _Jv_VTable::new_vtable (klass->vtable_method_count); klass->vtable = vtable; - + + jboolean flags[klass->vtable_method_count]; + for (int i = 0; i < klass->vtable_method_count; ++i) + flags[i] = false; + // Copy the vtable of the closest non-abstract superclass. jclass superclass = klass->superclass; if (superclass != NULL) @@ -1662,7 +1677,10 @@ _Jv_MakeVTable (jclass klass) } for (int i = 0; i < superclass->vtable_method_count; ++i) - vtable->set_method (i, superclass->vtable->get_method (i)); + { + vtable->set_method (i, superclass->vtable->get_method (i)); + flags[i] = true; + } } // Set the class pointer and GC descriptor. @@ -1671,5 +1689,14 @@ _Jv_MakeVTable (jclass klass) // For each virtual declared in klass and any immediate abstract // superclasses, set new vtable entry or override an old one. - _Jv_SetVTableEntries (klass, vtable); + _Jv_SetVTableEntries (klass, vtable, flags); + + // It is an error to have an abstract method in a concrete class. + if (! (klass->accflags & Modifier::ABSTRACT)) + { + for (int i = 0; i < klass->vtable_method_count; ++i) + if (! flags[i]) + // FIXME: messsage. + throw new java::lang::AbstractMethodError (); + } } |