only return declared interfaces from Class.getInterfaces

The result of Class.getInterfaces should not include interfaces
declared to be implemented/extended by superclasses/superinterfaces,
only those declared by the class itself.  This is important because it
influences how java.io.ObjectStreamClass calculates serial version
IDs.
This commit is contained in:
Joel Dice 2011-03-27 20:29:31 -06:00
parent 56e832d3e8
commit 9fe41b2afc
3 changed files with 35 additions and 21 deletions

View File

@ -10,4 +10,6 @@
package avian;
public class ClassAddendum extends Addendum { }
public class ClassAddendum extends Addendum {
public Object[] interfaceTable;
}

View File

@ -3553,28 +3553,27 @@ jvmGetClassInterfaces(Thread* t, uintptr_t* arguments)
{
jclass c = reinterpret_cast<jclass>(arguments[0]);
object table = classInterfaceTable(t, jclassVmClass(t, *c));
if (table) {
PROTECT(t, table);
object addendum = classAddendum(t, jclassVmClass(t, *c));
if (addendum) {
object table = classAddendumInterfaceTable(t, addendum);
if (table) {
PROTECT(t, table);
unsigned stride =
(classFlags(t, jclassVmClass(t, *c)) & ACC_INTERFACE) == 0 ? 2 : 1;
object array = makeObjectArray(t, arrayLength(t, table));
PROTECT(t, array);
object array = makeObjectArray
(t, type(t, Machine::JclassType), arrayLength(t, table) / stride);
PROTECT(t, array);
for (unsigned i = 0; i < arrayLength(t, table); ++i) {
object c = getJClass(t, arrayBody(t, table, i));
set(t, array, ArrayBody + (i * BytesPerWord), c);
}
for (unsigned i = 0; i < objectArrayLength(t, array); ++i) {
object interface = getJClass(t, arrayBody(t, table, i * stride));
set(t, array, ArrayBody + (i * BytesPerWord), interface);
return reinterpret_cast<uint64_t>(makeLocalReference(t, array));
}
return reinterpret_cast<uint64_t>(makeLocalReference(t, array));
} else {
return reinterpret_cast<uint64_t>
(makeLocalReference
(t, makeObjectArray(t, type(t, Machine::JclassType), 0)));
}
return reinterpret_cast<uint64_t>
(makeLocalReference
(t, makeObjectArray(t, type(t, Machine::JclassType), 0)));
}
extern "C" JNIEXPORT jobjectArray JNICALL

View File

@ -986,6 +986,17 @@ parseInterfaceTable(Thread* t, Stream& s, object class_, object pool,
}
unsigned count = s.read2();
object table = 0;
PROTECT(t, table);
if (count) {
table = makeArray(t, count);
if (classAddendum(t, class_) == 0) {
object addendum = makeClassAddendum(t, pool, 0, 0, table);
set(t, class_, ClassAddendum, addendum);
}
}
for (unsigned i = 0; i < count; ++i) {
object name = referenceName(t, singletonObject(t, pool, s.read2() - 1));
PROTECT(t, name);
@ -995,6 +1006,8 @@ parseInterfaceTable(Thread* t, Stream& s, object class_, object pool,
PROTECT(t, interface);
set(t, table, ArrayBody + (i * BytesPerWord), interface);
hashMapInsertMaybe(t, map, name, interface, byteArrayHash, byteArrayEqual);
addInterfaces(t, interface, map);
@ -1696,7 +1709,7 @@ parseAttributeTable(Thread* t, Stream& s, object class_, object pool)
PROTECT(t, class_);
PROTECT(t, pool);
object addendum = 0;
object addendum = classAddendum(t, class_);
PROTECT(t, addendum);
unsigned attributeCount = s.read2();
@ -1712,7 +1725,7 @@ parseAttributeTable(Thread* t, Stream& s, object class_, object pool)
&byteArrayBody(t, name, 0)) == 0)
{
if (addendum == 0) {
addendum = makeClassAddendum(t, pool, 0, 0);
addendum = makeClassAddendum(t, pool, 0, 0, 0);
}
set(t, addendum, AddendumSignature,
@ -1722,7 +1735,7 @@ parseAttributeTable(Thread* t, Stream& s, object class_, object pool)
&byteArrayBody(t, name, 0)) == 0)
{
if (addendum == 0) {
addendum = makeClassAddendum(t, pool, 0, 0);
addendum = makeClassAddendum(t, pool, 0, 0, 0);
}
object body = makeByteArray(t, length);