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.InputStream;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.util.Arrays;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Map; import java.util.Map;
import java.util.HashMap; import java.util.HashMap;
@ -439,6 +440,19 @@ public final class Class <T> implements Type, AnnotatedElement {
} }
public int getModifiers() { 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; return vmClass.flags;
} }

View File

@ -746,6 +746,28 @@ getDeclaringClass(Thread* t, object c)
return 0; 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 } // namespace vm
#endif//CLASSPATH_COMMON_H #endif//CLASSPATH_COMMON_H

View File

@ -1634,7 +1634,7 @@ extern "C" AVIAN_EXPORT int64_t JNICALL
Avian_java_lang_Class_getModifiers Avian_java_lang_Class_getModifiers
(Thread* t, object, uintptr_t* arguments) (Thread* t, object, uintptr_t* arguments)
{ {
return classFlags return classModifiers
(t, jclassVmClass(t, reinterpret_cast<object>(arguments[0]))); (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)); 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 extern "C" AVIAN_EXPORT jint JNICALL
EXPORT(JVM_GetClassModifiers)(Thread* t, jclass c) 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 uint64_t
@ -4349,7 +4356,9 @@ EXPORT(JVM_GetClassDeclaredConstructors)(Thread* t, jclass c,
extern "C" AVIAN_EXPORT jint JNICALL extern "C" AVIAN_EXPORT jint JNICALL
EXPORT(JVM_GetClassAccessFlags)(Thread* t, jclass c) 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 uint64_t

View File

@ -2314,13 +2314,6 @@ parseAttributeTable(Thread* t, Stream& s, object class_, object pool)
flags); flags);
set(t, table, ArrayBody + (i * BytesPerWord), reference); 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); object addendum = getClassAddendum(t, class_, pool);

View File

@ -49,8 +49,9 @@ public class Reflection {
private static void innerClasses() throws Exception { private static void innerClasses() throws Exception {
Class c = Reflection.class; Class c = Reflection.class;
Class[] inner = c.getDeclaredClasses(); Class[] inner = c.getDeclaredClasses();
expect(1 == inner.length); expect(2 == inner.length);
expect(Hello.class == inner[0]); expect(Hello.class == inner[0]
|| Hello.class == inner[1]);
} }
private int egads; private int egads;
@ -236,6 +237,14 @@ public class Reflection {
expect((Foo.class.getMethod("toString").getModifiers() expect((Foo.class.getMethod("toString").getModifiers()
& Modifier.PUBLIC) != 0); & 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);
}
}