Commit eaa2834f by Tom Tromey Committed by Tom Tromey

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
parent 83f0a003
2002-12-05 Tom Tromey <tromey@redhat.com>
* 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.
2002-12-04 Tom Tromey <tromey@redhat.com> 2002-12-04 Tom Tromey <tromey@redhat.com>
* java/net/SocketPermission.java (hashCode): Rewrote. * java/net/SocketPermission.java (hashCode): Rewrote.
......
...@@ -1184,15 +1184,17 @@ void _Jv_ClassReader::handleFieldsEnd () ...@@ -1184,15 +1184,17 @@ void _Jv_ClassReader::handleFieldsEnd ()
void void
_Jv_ClassReader::handleMethodsBegin (int count) _Jv_ClassReader::handleMethodsBegin (int count)
{ {
def->methods = (_Jv_Method*) def->methods = (_Jv_Method *) _Jv_AllocBytes (sizeof (_Jv_Method) * count);
_Jv_AllocBytes (sizeof (_Jv_Method)*count);
def->interpreted_methods def->interpreted_methods
= (_Jv_MethodBase **) _Jv_AllocBytes (sizeof (_Jv_MethodBase *) = (_Jv_MethodBase **) _Jv_AllocBytes (sizeof (_Jv_MethodBase *)
* count); * count);
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
def->interpreted_methods[i] = 0; {
def->interpreted_methods[i] = 0;
def->methods[i].index = (_Jv_ushort) -1;
}
def->method_count = count; def->method_count = count;
} }
...@@ -1376,12 +1378,14 @@ throw_internal_error (char *msg) ...@@ -1376,12 +1378,14 @@ throw_internal_error (char *msg)
throw new java::lang::InternalError (JvNewStringLatin1 (msg)); throw new java::lang::InternalError (JvNewStringLatin1 (msg));
} }
static void throw_incompatible_class_change_error (jstring msg) static void
throw_incompatible_class_change_error (jstring msg)
{ {
throw new java::lang::IncompatibleClassChangeError (msg); throw new java::lang::IncompatibleClassChangeError (msg);
} }
static void throw_class_circularity_error (jstring msg) static void
throw_class_circularity_error (jstring msg)
{ {
throw new java::lang::ClassCircularityError (msg); throw new java::lang::ClassCircularityError (msg);
} }
......
...@@ -325,7 +325,7 @@ private: ...@@ -325,7 +325,7 @@ private:
friend jshort _Jv_FindIIndex (jclass *, jshort *, jshort); friend jshort _Jv_FindIIndex (jclass *, jshort *, jshort);
friend void _Jv_LinkOffsetTable (jclass); friend void _Jv_LinkOffsetTable (jclass);
friend void _Jv_LayoutVTableMethods (jclass klass); friend void _Jv_LayoutVTableMethods (jclass klass);
friend void _Jv_SetVTableEntries (jclass, _Jv_VTable *); friend void _Jv_SetVTableEntries (jclass, _Jv_VTable *, jboolean *);
friend void _Jv_MakeVTable (jclass); friend void _Jv_MakeVTable (jclass);
// Return array class corresponding to element type KLASS, creating it if // Return array class corresponding to element type KLASS, creating it if
......
...@@ -97,7 +97,7 @@ java::lang::Class::forName (jstring className) ...@@ -97,7 +97,7 @@ java::lang::Class::forName (jstring className)
java::lang::Class *klass = NULL; java::lang::Class *klass = NULL;
try try
{ {
for (int i=1; !klass; i++) for (int i = 1; !klass; i++)
{ {
klass = t->classAt (i); klass = t->classAt (i);
} }
...@@ -1556,7 +1556,7 @@ _Jv_LinkOffsetTable(jclass klass) ...@@ -1556,7 +1556,7 @@ _Jv_LinkOffsetTable(jclass klass)
} }
// Returns true if METH should get an entry in a VTable. // Returns true if METH should get an entry in a VTable.
static bool static jboolean
isVirtualMethod (_Jv_Method *meth) isVirtualMethod (_Jv_Method *meth)
{ {
using namespace java::lang::reflect; using namespace java::lang::reflect;
...@@ -1574,7 +1574,7 @@ _Jv_LayoutVTableMethods (jclass klass) ...@@ -1574,7 +1574,7 @@ _Jv_LayoutVTableMethods (jclass klass)
if (klass->vtable != NULL || klass->isInterface() if (klass->vtable != NULL || klass->isInterface()
|| klass->vtable_method_count != -1) || klass->vtable_method_count != -1)
return; return;
jclass superclass = klass->superclass; jclass superclass = klass->superclass;
if (superclass != NULL && superclass->vtable_method_count == -1) if (superclass != NULL && superclass->vtable_method_count == -1)
...@@ -1582,48 +1582,59 @@ _Jv_LayoutVTableMethods (jclass klass) ...@@ -1582,48 +1582,59 @@ _Jv_LayoutVTableMethods (jclass klass)
JvSynchronize sync (superclass); JvSynchronize sync (superclass);
_Jv_LayoutVTableMethods (superclass); _Jv_LayoutVTableMethods (superclass);
} }
int index = (superclass == NULL ? 0 : superclass->vtable_method_count); int index = (superclass == NULL ? 0 : superclass->vtable_method_count);
for (int i = 0; i < klass->method_count; ++i) for (int i = 0; i < klass->method_count; ++i)
{ {
_Jv_Method *meth = &klass->methods[i]; _Jv_Method *meth = &klass->methods[i];
_Jv_Method *super_meth = NULL; _Jv_Method *super_meth = NULL;
if (!isVirtualMethod(meth)) if (! isVirtualMethod (meth))
continue; continue;
if (superclass != NULL) if (superclass != NULL)
super_meth = _Jv_LookupDeclaredMethod (superclass, meth->name, super_meth = _Jv_LookupDeclaredMethod (superclass, meth->name,
meth->signature); meth->signature);
if (super_meth) if (super_meth)
meth->index = super_meth->index; meth->index = super_meth->index;
else else if (! (meth->accflags & java::lang::reflect::Modifier::FINAL))
meth->index = index++; meth->index = index++;
} }
klass->vtable_method_count = index; klass->vtable_method_count = index;
} }
// Set entries in VTABLE for virtual methods declared in KLASS. If KLASS has // Set entries in VTABLE for virtual methods declared in KLASS. If
// an immediate abstract parent, recursivly do its methods first. // KLASS has an immediate abstract parent, recursively do its methods
// first. FLAGS is used to determine which slots we've actually set.
void void
_Jv_SetVTableEntries (jclass klass, _Jv_VTable *vtable) _Jv_SetVTableEntries (jclass klass, _Jv_VTable *vtable, jboolean *flags)
{ {
using namespace java::lang::reflect; using namespace java::lang::reflect;
jclass superclass = klass->getSuperclass(); jclass superclass = klass->getSuperclass();
if (superclass != NULL && (superclass->getModifiers() & Modifier::ABSTRACT)) 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--) for (int i = klass->method_count - 1; i >= 0; i--)
{ {
_Jv_Method *meth = &klass->methods[i]; _Jv_Method *meth = &klass->methods[i];
if (!isVirtualMethod(meth)) if (meth->index == (_Jv_ushort) -1)
continue; 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) ...@@ -1639,7 +1650,7 @@ _Jv_MakeVTable (jclass klass)
if (klass->vtable != NULL || klass->isInterface() if (klass->vtable != NULL || klass->isInterface()
|| (klass->accflags & Modifier::ABSTRACT)) || (klass->accflags & Modifier::ABSTRACT))
return; return;
// out before we can create a vtable. // out before we can create a vtable.
if (klass->vtable_method_count == -1) if (klass->vtable_method_count == -1)
_Jv_LayoutVTableMethods (klass); _Jv_LayoutVTableMethods (klass);
...@@ -1647,7 +1658,11 @@ _Jv_MakeVTable (jclass klass) ...@@ -1647,7 +1658,11 @@ _Jv_MakeVTable (jclass klass)
// Allocate the new vtable. // Allocate the new vtable.
_Jv_VTable *vtable = _Jv_VTable::new_vtable (klass->vtable_method_count); _Jv_VTable *vtable = _Jv_VTable::new_vtable (klass->vtable_method_count);
klass->vtable = vtable; 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. // Copy the vtable of the closest non-abstract superclass.
jclass superclass = klass->superclass; jclass superclass = klass->superclass;
if (superclass != NULL) if (superclass != NULL)
...@@ -1662,7 +1677,10 @@ _Jv_MakeVTable (jclass klass) ...@@ -1662,7 +1677,10 @@ _Jv_MakeVTable (jclass klass)
} }
for (int i = 0; i < superclass->vtable_method_count; ++i) 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. // Set the class pointer and GC descriptor.
...@@ -1671,5 +1689,14 @@ _Jv_MakeVTable (jclass klass) ...@@ -1671,5 +1689,14 @@ _Jv_MakeVTable (jclass klass)
// For each virtual declared in klass and any immediate abstract // For each virtual declared in klass and any immediate abstract
// superclasses, set new vtable entry or override an old one. // 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 ();
}
} }
...@@ -363,13 +363,6 @@ _Jv_SearchMethodInClass (jclass cls, jclass klass, ...@@ -363,13 +363,6 @@ _Jv_SearchMethodInClass (jclass cls, jclass klass,
return 0; return 0;
} }
/* this is installed in place of abstract methods */
static void
_Jv_abstractMethodError ()
{
throw new java::lang::AbstractMethodError;
}
void void
_Jv_PrepareClass(jclass klass) _Jv_PrepareClass(jclass klass)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment