Permalink
Browse files

fix Class.getModifiers for inner classes and implement JVM_GetDeclari…

…ngClass and JVM_GetEnclosingMethodInfo properly

This fixes a couple of tests in the Scala test suite
(run/reflection-modulemirror-toplevel-badpath.scala and
run/reflection-constructormirror-nested-good.scala).
  • Loading branch information...
dicej committed Apr 17, 2013
1 parent aa513c2 commit 81d77867160c69040b7f3b01fae1cc93459416ca
Showing with 105 additions and 30 deletions.
  1. +2 −0 classpath/avian/ClassAddendum.java
  2. +0 −16 classpath/avian/OpenJDK.java
  3. +75 −11 src/classpath-openjdk.cpp
  4. +25 −3 src/machine.cpp
  5. +3 −0 test/Misc.java
@@ -14,4 +14,6 @@
public Object[] interfaceTable;
public Object[] innerClassTable;
public Object[] methodTable;
+ public Object enclosingClass;
+ public Object enclosingMethod;
}
@@ -45,20 +45,4 @@ public static ProtectionDomain getProtectionDomain(VMClass c) {
}
return array;
}
-
- public static Class getDeclaringClass(VMClass c) {
- try {
- String name = new String
- (replace('/', '.', c.name, 0, c.name.length - 1), 0,
- c.name.length - 1);
- int index = name.lastIndexOf("$");
- if (index == -1) {
- return null;
- } else {
- return c.loader.loadClass(name.substring(0, index));
- }
- } catch (ClassNotFoundException e) {
- return null;
- }
- }
}
View
@@ -4445,8 +4445,8 @@ jvmGetDeclaredClasses(Thread* t, uintptr_t* arguments)
if (innerClassReferenceOuter(t, arrayBody(t, table, i))) {
object inner = getJClass
(t, resolveClass
- (t, classLoader(t, jclassVmClass(t, *c)), referenceName
- (t, innerClassReferenceInner(t, arrayBody(t, table, i)))));
+ (t, classLoader(t, jclassVmClass(t, *c)),
+ innerClassReferenceInner(t, arrayBody(t, table, i))));
-- count;
set(t, result, ArrayBody + (count * BytesPerWord), inner);
@@ -4474,13 +4474,29 @@ jvmGetDeclaringClass(Thread* t, uintptr_t* arguments)
{
jclass c = reinterpret_cast<jobject>(arguments[0]);
- object method = resolveMethod
- (t, root(t, Machine::BootLoader), "avian/OpenJDK", "getDeclaringClass",
- "(Lavian/VMClass;)Ljava/lang/Class;");
+ object class_ = jclassVmClass(t, *c);
+ object addendum = classAddendum(t, class_);
+ 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 (strcmp
+ (&byteArrayBody(t, innerClassReferenceInner(t, reference), 0),
+ &byteArrayBody(t, className(t, class_), 0)) == 0)
+ {
+ return reinterpret_cast<uintptr_t>
+ (makeLocalReference
+ (t, getJClass
+ (t, resolveClass
+ (t, classLoader(t, class_), innerClassReferenceOuter
+ (t, reference)))));
+ }
+ }
+ }
+ }
- return reinterpret_cast<uintptr_t>
- (makeLocalReference
- (t, t->m->processor->invoke(t, method, 0, jclassVmClass(t, *c))));
+ return 0;
}
extern "C" JNIEXPORT jclass JNICALL
@@ -5517,13 +5533,61 @@ EXPORT(JVM_GetManagement)(jint version)
extern "C" JNIEXPORT jobject JNICALL
EXPORT(JVM_InitAgentProperties)(Thread*, jobject) { abort(); }
-extern "C" JNIEXPORT jobjectArray JNICALL
-EXPORT(JVM_GetEnclosingMethodInfo)(JNIEnv*, jclass)
+uint64_t
+getEnclosingMethodInfo(Thread* t, uintptr_t* arguments)
{
- // todo: implement properly
+ jclass c = reinterpret_cast<jclass>(arguments[0]);
+ object class_ = jclassVmClass(t, *c);
+ PROTECT(t, class_);
+
+ object addendum = classAddendum(t, class_);
+ if (addendum) {
+ object enclosingClass = classAddendumEnclosingClass(t, addendum);
+ if (enclosingClass) {
+ PROTECT(t, enclosingClass);
+
+ object array = makeObjectArray(t, type(t, Machine::JobjectType), 3);
+ PROTECT(t, array);
+
+ enclosingClass = getJClass
+ (t, resolveClass(t, classLoader(t, class_), enclosingClass));
+
+ set(t, array, ArrayBody, enclosingClass);
+
+ object enclosingMethod = classAddendumEnclosingMethod(t, addendum);
+
+ if (enclosingMethod) {
+ PROTECT(t, enclosingMethod);
+
+ object name = t->m->classpath->makeString
+ (t, pairFirst(t, enclosingMethod), 0,
+ byteArrayLength(t, pairFirst(t, enclosingMethod)) - 1);
+
+ set(t, array, ArrayBody + BytesPerWord, name);
+
+ object spec = t->m->classpath->makeString
+ (t, pairSecond(t, enclosingMethod), 0,
+ byteArrayLength(t, pairSecond(t, enclosingMethod)) - 1);
+
+ set(t, array, ArrayBody + (2 * BytesPerWord), spec);
+ }
+
+ return reinterpret_cast<uintptr_t>(makeLocalReference(t, array));
+ }
+ }
return 0;
}
+
+extern "C" JNIEXPORT jobjectArray JNICALL
+EXPORT(JVM_GetEnclosingMethodInfo)(Thread* t, jclass c)
+{
+ uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c) };
+
+ return reinterpret_cast<jobjectArray>
+ (run(t, getEnclosingMethodInfo, arguments));
+}
+
extern "C" JNIEXPORT jintArray JNICALL
EXPORT(JVM_GetThreadStateValues)(JNIEnv*, jint) { abort(); }
View
@@ -1123,7 +1123,7 @@ getClassAddendum(Thread* t, object class_, object pool)
if (addendum == 0) {
PROTECT(t, class_);
- addendum = makeClassAddendum(t, pool, 0, 0, 0, 0, 0);
+ addendum = makeClassAddendum(t, pool, 0, 0, 0, 0, 0, 0, 0);
set(t, class_, ClassAddendum, addendum);
}
return addendum;
@@ -2303,12 +2303,20 @@ parseAttributeTable(Thread* t, Stream& s, object class_, object pool)
int16_t flags = s.read2();
object reference = makeInnerClassReference
- (t, inner ? singletonObject(t, pool, inner - 1) : 0,
- outer ? singletonObject(t, pool, outer - 1) : 0,
+ (t,
+ inner ? referenceName(t, singletonObject(t, pool, inner - 1)) : 0,
+ outer ? referenceName(t, singletonObject(t, pool, outer - 1)) : 0,
name ? singletonObject(t, pool, name - 1) : 0,
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);
@@ -2323,6 +2331,20 @@ parseAttributeTable(Thread* t, Stream& s, object class_, object pool)
object addendum = getClassAddendum(t, class_, pool);
set(t, addendum, AddendumAnnotationTable, body);
+ } else if (vm::strcmp(reinterpret_cast<const int8_t*>
+ ("EnclosingMethod"),
+ &byteArrayBody(t, name, 0)) == 0)
+ {
+ int16_t enclosingClass = s.read2();
+ int16_t enclosingMethod = s.read2();
+
+ object addendum = getClassAddendum(t, class_, pool);
+
+ set(t, addendum, ClassAddendumEnclosingClass,
+ referenceName(t, singletonObject(t, pool, enclosingClass - 1)));
+
+ set(t, addendum, ClassAddendumEnclosingMethod, enclosingMethod
+ ? singletonObject(t, pool, enclosingMethod - 1) : 0);
} else {
s.skip(length);
}
View
@@ -256,5 +256,8 @@ public static void main(String[] args) {
expect(new Object[0] instanceof Cloneable);
expect(new Object[0] instanceof java.io.Serializable);
+
+ expect((Baz.class.getModifiers() & java.lang.reflect.Modifier.STATIC)
+ != 0);
}
}

0 comments on commit 81d7786

Please sign in to comment.