mirror of
https://github.com/corda/corda.git
synced 2025-01-07 13:38:47 +00:00
Merge pull request #186 from dicej/getDeclaredMethods
fix Class.getDeclaredMethods
This commit is contained in:
commit
60d841df06
@ -13,7 +13,14 @@ package avian;
|
|||||||
public class ClassAddendum extends Addendum {
|
public class ClassAddendum extends Addendum {
|
||||||
public Object[] interfaceTable;
|
public Object[] interfaceTable;
|
||||||
public InnerClassReference[] innerClassTable;
|
public InnerClassReference[] innerClassTable;
|
||||||
public Object[] methodTable;
|
/**
|
||||||
|
* If this value is negative, all the methods in VMClass.methodTable
|
||||||
|
* were declared in that class. Otherwise, only the first
|
||||||
|
* declaredMethodCount methods in that table were declared in that
|
||||||
|
* class, while the rest were declared in interfaces implemented or
|
||||||
|
* extended by that class.
|
||||||
|
*/
|
||||||
|
public int declaredMethodCount;
|
||||||
public Object enclosingClass;
|
public Object enclosingClass;
|
||||||
public Object enclosingMethod;
|
public Object enclosingMethod;
|
||||||
}
|
}
|
||||||
|
@ -221,6 +221,18 @@ public class Classes {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int declaredMethodCount(VMClass c) {
|
||||||
|
ClassAddendum a = c.addendum;
|
||||||
|
if (a != null) {
|
||||||
|
int count = a.declaredMethodCount;
|
||||||
|
if (count >= 0) {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
VMMethod[] table = c.methodTable;
|
||||||
|
return table == null ? 0 : table.length;
|
||||||
|
}
|
||||||
|
|
||||||
public static void link(VMClass c, ClassLoader loader) {
|
public static void link(VMClass c, ClassLoader loader) {
|
||||||
acquireClassLock();
|
acquireClassLock();
|
||||||
try {
|
try {
|
||||||
@ -238,9 +250,10 @@ public class Classes {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c.methodTable != null) {
|
VMMethod[] methodTable = c.methodTable;
|
||||||
for (int i = 0; i < c.methodTable.length; ++i) {
|
if (methodTable != null) {
|
||||||
VMMethod m = c.methodTable[i];
|
for (int i = 0; i < methodTable.length; ++i) {
|
||||||
|
VMMethod m = methodTable[i];
|
||||||
|
|
||||||
for (int j = 1; j < m.spec.length;) {
|
for (int j = 1; j < m.spec.length;) {
|
||||||
j = resolveSpec(loader, m.spec, j);
|
j = resolveSpec(loader, m.spec, j);
|
||||||
@ -394,17 +407,18 @@ public class Classes {
|
|||||||
public static int findMethod(VMClass vmClass, String name,
|
public static int findMethod(VMClass vmClass, String name,
|
||||||
Class[] parameterTypes)
|
Class[] parameterTypes)
|
||||||
{
|
{
|
||||||
if (vmClass.methodTable != null) {
|
VMMethod[] methodTable = vmClass.methodTable;
|
||||||
|
if (methodTable != null) {
|
||||||
Classes.link(vmClass);
|
Classes.link(vmClass);
|
||||||
|
|
||||||
if (parameterTypes == null) {
|
if (parameterTypes == null) {
|
||||||
parameterTypes = new Class[0];
|
parameterTypes = new Class[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < vmClass.methodTable.length; ++i) {
|
for (int i = 0; i < methodTable.length; ++i) {
|
||||||
if (toString(vmClass.methodTable[i].name).equals(name)
|
VMMethod m = methodTable[i];
|
||||||
&& match(parameterTypes,
|
if (toString(m.name).equals(name)
|
||||||
getParameterTypes(vmClass.methodTable[i])))
|
&& match(parameterTypes, getParameterTypes(m)))
|
||||||
{
|
{
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@ -415,12 +429,12 @@ public class Classes {
|
|||||||
|
|
||||||
public static int countMethods(VMClass vmClass, boolean publicOnly) {
|
public static int countMethods(VMClass vmClass, boolean publicOnly) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
if (vmClass.methodTable != null) {
|
VMMethod[] methodTable = vmClass.methodTable;
|
||||||
for (int i = 0; i < vmClass.methodTable.length; ++i) {
|
if (methodTable != null) {
|
||||||
if (((! publicOnly)
|
for (int i = 0, j = declaredMethodCount(vmClass); i < j; ++i) {
|
||||||
|| ((vmClass.methodTable[i].flags & Modifier.PUBLIC))
|
VMMethod m = methodTable[i];
|
||||||
!= 0)
|
if (((! publicOnly) || ((m.flags & Modifier.PUBLIC)) != 0)
|
||||||
&& (! toString(vmClass.methodTable[i].name).startsWith("<")))
|
&& (! toString(m.name).startsWith("<")))
|
||||||
{
|
{
|
||||||
++ count;
|
++ count;
|
||||||
}
|
}
|
||||||
@ -431,14 +445,15 @@ public class Classes {
|
|||||||
|
|
||||||
public static Method[] getMethods(VMClass vmClass, boolean publicOnly) {
|
public static Method[] getMethods(VMClass vmClass, boolean publicOnly) {
|
||||||
Method[] array = new Method[countMethods(vmClass, publicOnly)];
|
Method[] array = new Method[countMethods(vmClass, publicOnly)];
|
||||||
if (vmClass.methodTable != null) {
|
VMMethod[] methodTable = vmClass.methodTable;
|
||||||
|
if (methodTable != null) {
|
||||||
Classes.link(vmClass);
|
Classes.link(vmClass);
|
||||||
|
|
||||||
int ai = 0;
|
int ai = 0;
|
||||||
for (int i = 0; i < vmClass.methodTable.length; ++i) {
|
for (int i = 0, j = declaredMethodCount(vmClass); i < j; ++i) {
|
||||||
if ((((vmClass.methodTable[i].flags & Modifier.PUBLIC) != 0)
|
VMMethod m = methodTable[i];
|
||||||
|| (! publicOnly))
|
if (((! publicOnly) || ((m.flags & Modifier.PUBLIC) != 0))
|
||||||
&& ! toString(vmClass.methodTable[i].name).startsWith("<"))
|
&& ! toString(m.name).startsWith("<"))
|
||||||
{
|
{
|
||||||
array[ai++] = makeMethod(SystemClassLoader.getClass(vmClass), i);
|
array[ai++] = makeMethod(SystemClassLoader.getClass(vmClass), i);
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,15 @@ public class VMClass {
|
|||||||
public Object[] interfaceTable;
|
public Object[] interfaceTable;
|
||||||
public VMMethod[] virtualTable;
|
public VMMethod[] virtualTable;
|
||||||
public VMField[] fieldTable;
|
public VMField[] fieldTable;
|
||||||
|
/**
|
||||||
|
* Methods declared in this class, plus any abstract virtual methods
|
||||||
|
* inherited from implemented or extended interfaces. If addendum
|
||||||
|
* is non-null and addendum.declaredMethodCount is non-negative,
|
||||||
|
* then the first addendum.declaredMethodCount methods are declared
|
||||||
|
* methods, while the rest are abstract virtual methods. If
|
||||||
|
* addendum is null or addendum.declaredMethodCount is negative, all
|
||||||
|
* are declared methods.
|
||||||
|
*/
|
||||||
public VMMethod[] methodTable;
|
public VMMethod[] methodTable;
|
||||||
public ClassAddendum addendum;
|
public ClassAddendum addendum;
|
||||||
public Object staticTable;
|
public Object staticTable;
|
||||||
|
@ -2121,25 +2121,26 @@ interceptFileOperations(Thread* t, bool updateRuntimeData)
|
|||||||
}
|
}
|
||||||
#endif // AVIAN_OPENJDK_SRC
|
#endif // AVIAN_OPENJDK_SRC
|
||||||
|
|
||||||
object
|
unsigned
|
||||||
getClassMethodTable(Thread* t, object c)
|
classDeclaredMethodCount(Thread* t, object c)
|
||||||
{
|
{
|
||||||
object addendum = classAddendum(t, c);
|
object addendum = classAddendum(t, c);
|
||||||
if (addendum) {
|
if (addendum) {
|
||||||
object table = classAddendumMethodTable(t, addendum);
|
int count = classAddendumDeclaredMethodCount(t, addendum);
|
||||||
if (table) {
|
if (count >= 0) {
|
||||||
return table;
|
return count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return classMethodTable(t, c);
|
object table = classMethodTable(t, c);
|
||||||
|
return table == 0 ? 0 : arrayLength(t, table);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
countMethods(Thread* t, object c, bool publicOnly)
|
countMethods(Thread* t, object c, bool publicOnly)
|
||||||
{
|
{
|
||||||
object table = getClassMethodTable(t, c);
|
object table = classMethodTable(t, c);
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
for (unsigned i = 0; i < arrayLength(t, table); ++i) {
|
for (unsigned i = 0, j = classDeclaredMethodCount(t, c); i < j; ++i) {
|
||||||
object vmMethod = arrayBody(t, table, i);
|
object vmMethod = arrayBody(t, table, i);
|
||||||
if (((not publicOnly) or (methodFlags(t, vmMethod) & ACC_PUBLIC))
|
if (((not publicOnly) or (methodFlags(t, vmMethod) & ACC_PUBLIC))
|
||||||
and byteArrayBody(t, methodName(t, vmMethod), 0) != '<')
|
and byteArrayBody(t, methodName(t, vmMethod), 0) != '<')
|
||||||
@ -2171,9 +2172,9 @@ countFields(Thread* t, object c, bool publicOnly)
|
|||||||
unsigned
|
unsigned
|
||||||
countConstructors(Thread* t, object c, bool publicOnly)
|
countConstructors(Thread* t, object c, bool publicOnly)
|
||||||
{
|
{
|
||||||
object table = getClassMethodTable(t, c);
|
object table = classMethodTable(t, c);
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
for (unsigned i = 0; i < arrayLength(t, table); ++i) {
|
for (unsigned i = 0, j = classDeclaredMethodCount(t, c); i < j; ++i) {
|
||||||
object vmMethod = arrayBody(t, table, i);
|
object vmMethod = arrayBody(t, table, i);
|
||||||
if (((not publicOnly) or (methodFlags(t, vmMethod) & ACC_PUBLIC))
|
if (((not publicOnly) or (methodFlags(t, vmMethod) & ACC_PUBLIC))
|
||||||
and strcmp(reinterpret_cast<char*>
|
and strcmp(reinterpret_cast<char*>
|
||||||
@ -4214,7 +4215,7 @@ jvmGetClassDeclaredMethods(Thread* t, uintptr_t* arguments)
|
|||||||
jclass c = reinterpret_cast<jclass>(arguments[0]);
|
jclass c = reinterpret_cast<jclass>(arguments[0]);
|
||||||
jboolean publicOnly = arguments[1];
|
jboolean publicOnly = arguments[1];
|
||||||
|
|
||||||
object table = getClassMethodTable(t, jclassVmClass(t, *c));
|
object table = classMethodTable(t, jclassVmClass(t, *c));
|
||||||
if (table) {
|
if (table) {
|
||||||
PROTECT(t, table);
|
PROTECT(t, table);
|
||||||
|
|
||||||
@ -4224,7 +4225,9 @@ jvmGetClassDeclaredMethods(Thread* t, uintptr_t* arguments)
|
|||||||
PROTECT(t, array);
|
PROTECT(t, array);
|
||||||
|
|
||||||
unsigned ai = 0;
|
unsigned ai = 0;
|
||||||
for (unsigned i = 0; i < arrayLength(t, table); ++i) {
|
for (unsigned i = 0, j = classDeclaredMethodCount(t, jclassVmClass(t, *c));
|
||||||
|
i < j; ++i)
|
||||||
|
{
|
||||||
object vmMethod = arrayBody(t, table, i);
|
object vmMethod = arrayBody(t, table, i);
|
||||||
PROTECT(t, vmMethod);
|
PROTECT(t, vmMethod);
|
||||||
|
|
||||||
@ -4308,7 +4311,7 @@ jvmGetClassDeclaredConstructors(Thread* t, uintptr_t* arguments)
|
|||||||
jclass c = reinterpret_cast<jclass>(arguments[0]);
|
jclass c = reinterpret_cast<jclass>(arguments[0]);
|
||||||
jboolean publicOnly = arguments[1];
|
jboolean publicOnly = arguments[1];
|
||||||
|
|
||||||
object table = getClassMethodTable(t, jclassVmClass(t, *c));
|
object table = classMethodTable(t, jclassVmClass(t, *c));
|
||||||
if (table) {
|
if (table) {
|
||||||
PROTECT(t, table);
|
PROTECT(t, table);
|
||||||
|
|
||||||
@ -4318,7 +4321,9 @@ jvmGetClassDeclaredConstructors(Thread* t, uintptr_t* arguments)
|
|||||||
PROTECT(t, array);
|
PROTECT(t, array);
|
||||||
|
|
||||||
unsigned ai = 0;
|
unsigned ai = 0;
|
||||||
for (unsigned i = 0; i < arrayLength(t, table); ++i) {
|
for (unsigned i = 0, j = classDeclaredMethodCount(t, jclassVmClass(t, *c));
|
||||||
|
i < j; ++i)
|
||||||
|
{
|
||||||
object vmMethod = arrayBody(t, table, i);
|
object vmMethod = arrayBody(t, table, i);
|
||||||
PROTECT(t, vmMethod);
|
PROTECT(t, vmMethod);
|
||||||
|
|
||||||
|
@ -1123,7 +1123,7 @@ getClassAddendum(Thread* t, object class_, object pool)
|
|||||||
if (addendum == 0) {
|
if (addendum == 0) {
|
||||||
PROTECT(t, class_);
|
PROTECT(t, class_);
|
||||||
|
|
||||||
addendum = makeClassAddendum(t, pool, 0, 0, 0, 0, 0, 0, 0);
|
addendum = makeClassAddendum(t, pool, 0, 0, 0, 0, -1, 0, 0);
|
||||||
set(t, class_, ClassAddendum, addendum);
|
set(t, class_, ClassAddendum, addendum);
|
||||||
}
|
}
|
||||||
return addendum;
|
return addendum;
|
||||||
@ -2206,13 +2206,15 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
|
|||||||
if (abstractVirtuals) {
|
if (abstractVirtuals) {
|
||||||
PROTECT(t, vtable);
|
PROTECT(t, vtable);
|
||||||
|
|
||||||
object addendum = getClassAddendum(t, class_, pool);
|
object originalMethodTable = classMethodTable(t, class_);
|
||||||
set(t, addendum, ClassAddendumMethodTable,
|
PROTECT(t, originalMethodTable);
|
||||||
classMethodTable(t, class_));
|
|
||||||
|
|
||||||
unsigned oldLength = classMethodTable(t, class_) ?
|
unsigned oldLength = classMethodTable(t, class_) ?
|
||||||
arrayLength(t, classMethodTable(t, class_)) : 0;
|
arrayLength(t, classMethodTable(t, class_)) : 0;
|
||||||
|
|
||||||
|
object addendum = getClassAddendum(t, class_, pool);
|
||||||
|
classAddendumDeclaredMethodCount(t, addendum) = oldLength;
|
||||||
|
|
||||||
object newMethodTable = makeArray
|
object newMethodTable = makeArray
|
||||||
(t, oldLength + listSize(t, abstractVirtuals));
|
(t, oldLength + listSize(t, abstractVirtuals));
|
||||||
|
|
||||||
|
@ -241,6 +241,8 @@ public class Reflection {
|
|||||||
expect(avian.TestReflection.get(Baz.class.getField("foo"), new Baz())
|
expect(avian.TestReflection.get(Baz.class.getField("foo"), new Baz())
|
||||||
.equals(42));
|
.equals(42));
|
||||||
expect((Baz.class.getModifiers() & Modifier.PUBLIC) == 0);
|
expect((Baz.class.getModifiers() & Modifier.PUBLIC) == 0);
|
||||||
|
|
||||||
|
expect(B.class.getDeclaredMethods().length == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static class Baz {
|
protected static class Baz {
|
||||||
@ -263,3 +265,9 @@ class Foo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MyException extends RuntimeException { }
|
class MyException extends RuntimeException { }
|
||||||
|
|
||||||
|
interface A {
|
||||||
|
void foo();
|
||||||
|
}
|
||||||
|
|
||||||
|
interface B extends A { }
|
||||||
|
Loading…
Reference in New Issue
Block a user