Merge pull request #192 from dicej/inner-class-modifiers

match Java's schizophrenic concept of inner class access modifiers
This commit is contained in:
Joshua Warner 2014-03-07 08:19:38 -07:00
commit f0fa06b3b7
7 changed files with 69 additions and 13 deletions

View File

@ -30,6 +30,7 @@ import java.lang.annotation.Annotation;
import java.io.InputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
@ -439,6 +440,19 @@ public final class Class <T> implements Type, AnnotatedElement {
}
public int getModifiers() {
ClassAddendum addendum = vmClass.addendum;
if (addendum != null) {
InnerClassReference[] table = addendum.innerClassTable;
if (table != null) {
for (int i = 0; i < table.length; ++i) {
InnerClassReference reference = table[i];
if (Arrays.equals(vmClass.name, reference.inner)) {
return reference.flags;
}
}
}
}
return vmClass.flags;
}

View File

@ -746,6 +746,28 @@ getDeclaringClass(Thread* t, object c)
return 0;
}
unsigned
classModifiers(Thread* t, object c)
{
object addendum = classAddendum(t, c);
if (addendum) {
object table = classAddendumInnerClassTable(t, addendum);
if (table) {
for (unsigned i = 0; i < arrayLength(t, table); ++i) {
object reference = arrayBody(t, table, i);
if (0 == strcmp
(&byteArrayBody(t, className(t, c), 0),
&byteArrayBody(t, innerClassReferenceInner(t, reference), 0)))
{
return innerClassReferenceFlags(t, reference);
}
}
}
}
return classFlags(t, c);
}
} // namespace vm
#endif//CLASSPATH_COMMON_H

View File

@ -1634,7 +1634,7 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_Class_getModifiers
(Thread* t, object, uintptr_t* arguments)
{
return classFlags
return classModifiers
(t, jclassVmClass(t, reinterpret_cast<object>(arguments[0])));
}

View File

@ -4123,12 +4123,19 @@ EXPORT(JVM_GetComponentType)(Thread* t, jclass c)
return reinterpret_cast<jclass>(run(t, jvmGetComponentType, arguments));
}
uint64_t
jvmGetClassModifiers(Thread* t, uintptr_t* arguments)
{
return classModifiers
(t, jclassVmClass(t, *reinterpret_cast<jobject>(arguments[0])));
}
extern "C" AVIAN_EXPORT jint JNICALL
EXPORT(JVM_GetClassModifiers)(Thread* t, jclass c)
{
ENTER(t, Thread::ActiveState);
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c) };
return classFlags(t, jclassVmClass(t, *c));
return run(t, jvmGetClassModifiers, arguments);
}
uint64_t
@ -4349,7 +4356,9 @@ EXPORT(JVM_GetClassDeclaredConstructors)(Thread* t, jclass c,
extern "C" AVIAN_EXPORT jint JNICALL
EXPORT(JVM_GetClassAccessFlags)(Thread* t, jclass c)
{
return EXPORT(JVM_GetClassModifiers)(t, c);
ENTER(t, Thread::ActiveState);
return classFlags(t, jclassVmClass(t, *c));
}
uint64_t

View File

@ -2314,13 +2314,6 @@ parseAttributeTable(Thread* t, Stream& s, object class_, object pool)
flags);
set(t, table, ArrayBody + (i * BytesPerWord), reference);
if (0 == strcmp
(&byteArrayBody(t, className(t, class_), 0),
&byteArrayBody(t, innerClassReferenceInner(t, reference), 0)))
{
classFlags(t, class_) = flags;
}
}
object addendum = getClassAddendum(t, class_, pool);

View File

@ -49,8 +49,9 @@ public class Reflection {
private static void innerClasses() throws Exception {
Class c = Reflection.class;
Class[] inner = c.getDeclaredClasses();
expect(1 == inner.length);
expect(Hello.class == inner[0]);
expect(2 == inner.length);
expect(Hello.class == inner[0]
|| Hello.class == inner[1]);
}
private int egads;
@ -236,6 +237,14 @@ public class Reflection {
expect((Foo.class.getMethod("toString").getModifiers()
& Modifier.PUBLIC) != 0);
expect(avian.TestReflection.get(Baz.class.getField("foo"), new Baz())
.equals(42));
expect((Baz.class.getModifiers() & Modifier.PUBLIC) == 0);
}
protected static class Baz {
public int foo = 42;
}
}

View File

@ -0,0 +1,9 @@
package avian;
import java.lang.reflect.Field;
public class TestReflection {
public static Object get(Field field, Object target) throws Exception {
return field.get(target);
}
}