fix Class.getDeclaredMethods

Internally, the VM augments the method tables for abstract classes
with any inherited abstract methods to make code simpler elsewhere,
but that means we can't use that table to construct the result of
Class.getDeclaredMethods since it would include methods not actually
declared in the class.  This commit ensures that we preserve and use
the original, un-augmented table for that purpose.
This commit is contained in:
Joel Dice 2011-04-09 21:20:56 -06:00
parent 1476243662
commit 00b829b8e8
3 changed files with 40 additions and 25 deletions

View File

@ -13,4 +13,5 @@ package avian;
public class ClassAddendum extends Addendum {
public Object[] interfaceTable;
public Object[] innerClassTable;
public Object[] methodTable;
}

View File

@ -1865,10 +1865,23 @@ interceptFileOperations(Thread* t)
voidPointer(getBootstrapResources));
}
object
getClassMethodTable(Thread* t, object c)
{
object addendum = classAddendum(t, c);
if (addendum) {
object table = classAddendumMethodTable(t, addendum);
if (table) {
return table;
}
}
return classMethodTable(t, c);
}
unsigned
countMethods(Thread* t, object c, bool publicOnly)
{
object table = classMethodTable(t, c);
object table = getClassMethodTable(t, c);
unsigned count = 0;
for (unsigned i = 0; i < arrayLength(t, table); ++i) {
object vmMethod = arrayBody(t, table, i);
@ -1902,7 +1915,7 @@ countFields(Thread* t, object c, bool publicOnly)
unsigned
countConstructors(Thread* t, object c, bool publicOnly)
{
object table = classMethodTable(t, c);
object table = getClassMethodTable(t, c);
unsigned count = 0;
for (unsigned i = 0; i < arrayLength(t, table); ++i) {
object vmMethod = arrayBody(t, table, i);
@ -4054,7 +4067,7 @@ jvmGetClassDeclaredMethods(Thread* t, uintptr_t* arguments)
jclass c = reinterpret_cast<jclass>(arguments[0]);
jboolean publicOnly = arguments[1];
object table = classMethodTable(t, jclassVmClass(t, *c));
object table = getClassMethodTable(t, jclassVmClass(t, *c));
if (table) {
PROTECT(t, table);
@ -4249,7 +4262,7 @@ jvmGetClassDeclaredConstructors(Thread* t, uintptr_t* arguments)
jclass c = reinterpret_cast<jclass>(arguments[0]);
jboolean publicOnly = arguments[1];
object table = classMethodTable(t, jclassVmClass(t, *c));
object table = getClassMethodTable(t, jclassVmClass(t, *c));
if (table) {
PROTECT(t, table);

View File

@ -969,6 +969,17 @@ addInterfaces(Thread* t, object class_, object map)
}
}
object
getClassAddendum(Thread* t, object class_, object pool)
{
object addendum = classAddendum(t, class_);
if (addendum == 0) {
addendum = makeClassAddendum(t, pool, 0, 0, 0, 0, 0);
set(t, class_, ClassAddendum, addendum);
}
return addendum;
}
void
parseInterfaceTable(Thread* t, Stream& s, object class_, object pool,
Machine::Type throwType)
@ -989,10 +1000,9 @@ parseInterfaceTable(Thread* t, Stream& s, object class_, object pool,
if (count) {
table = makeArray(t, count);
if (classAddendum(t, class_) == 0) {
object addendum = makeClassAddendum(t, pool, 0, 0, table, 0);
set(t, class_, ClassAddendum, addendum);
}
object addendum = getClassAddendum(t, class_, pool);
set(t, addendum, ClassAddendumInterfaceTable, table);
}
for (unsigned i = 0; i < count; ++i) {
@ -1644,6 +1654,10 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
if (abstractVirtuals) {
PROTECT(t, vtable);
object addendum = getClassAddendum(t, class_, pool);
set(t, addendum, ClassAddendumMethodTable,
classMethodTable(t, class_));
unsigned oldLength = arrayLength(t, classMethodTable(t, class_));
object newMethodTable = makeArray
(t, oldLength + listSize(t, abstractVirtuals));
@ -1707,9 +1721,6 @@ parseAttributeTable(Thread* t, Stream& s, object class_, object pool)
PROTECT(t, class_);
PROTECT(t, pool);
object addendum = classAddendum(t, class_);
PROTECT(t, addendum);
unsigned attributeCount = s.read2();
for (unsigned j = 0; j < attributeCount; ++j) {
object name = singletonObject(t, pool, s.read2() - 1);
@ -1722,19 +1733,12 @@ parseAttributeTable(Thread* t, Stream& s, object class_, object pool)
} else if (vm::strcmp(reinterpret_cast<const int8_t*>("Signature"),
&byteArrayBody(t, name, 0)) == 0)
{
if (addendum == 0) {
addendum = makeClassAddendum(t, pool, 0, 0, 0, 0);
}
object addendum = getClassAddendum(t, class_, pool);
set(t, addendum, AddendumSignature,
singletonObject(t, pool, s.read2() - 1));
} else if (vm::strcmp(reinterpret_cast<const int8_t*>("InnerClasses"),
&byteArrayBody(t, name, 0)) == 0)
{
if (addendum == 0) {
addendum = makeClassAddendum(t, pool, 0, 0, 0, 0);
}
unsigned innerClassCount = s.read2();
object table = makeArray(t, innerClassCount);
PROTECT(t, table);
@ -1754,25 +1758,22 @@ parseAttributeTable(Thread* t, Stream& s, object class_, object pool)
set(t, table, ArrayBody + (i * BytesPerWord), reference);
}
object addendum = getClassAddendum(t, class_, pool);
set(t, addendum, ClassAddendumInnerClassTable, table);
} else if (vm::strcmp(reinterpret_cast<const int8_t*>
("RuntimeVisibleAnnotations"),
&byteArrayBody(t, name, 0)) == 0)
{
if (addendum == 0) {
addendum = makeClassAddendum(t, pool, 0, 0, 0, 0);
}
object body = makeByteArray(t, length);
PROTECT(t, body);
s.read(reinterpret_cast<uint8_t*>(&byteArrayBody(t, body, 0)), length);
object addendum = getClassAddendum(t, class_, pool);
set(t, addendum, AddendumAnnotationTable, body);
} else {
s.skip(length);
}
}
set(t, class_, ClassAddendum, addendum);
}
void