provide proper implementations of JVM_GetDeclaredClasses, JVM_GetDeclaringClass

This commit is contained in:
Joel Dice 2011-03-31 19:47:26 -06:00
parent ef86530080
commit b0ae6343ad
5 changed files with 148 additions and 17 deletions

View File

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

View File

@ -34,4 +34,31 @@ public class OpenJDK {
return new ProtectionDomain(source, p);
}
private static byte[] replace(int a, int b, byte[] s, int offset,
int length)
{
byte[] array = new byte[length];
for (int i = 0; i < length; ++i) {
byte c = s[i];
array[i] = (byte) (c == a ? b : 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 File

@ -3743,31 +3743,101 @@ EXPORT(JVM_GetClassModifiers)(Thread* t, jclass c)
return classFlags(t, jclassVmClass(t, *c));
}
uint64_t
jvmGetDeclaredClasses(Thread* t, uintptr_t* arguments)
{
jclass c = reinterpret_cast<jobject>(arguments[0]);
object addendum = classAddendum(t, jclassVmClass(t, *c));
if (addendum) {
object table = classAddendumInnerClassTable(t, addendum);
if (table) {
PROTECT(t, table);
unsigned count = 0;
for (unsigned i = 0; i < arrayLength(t, table); ++i) {
if (innerClassReferenceOuter(t, arrayBody(t, table, i))) {
++ count;
}
}
object result = makeObjectArray(t, count);
PROTECT(t, result);
for (unsigned i = 0; i < arrayLength(t, table); ++i) {
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)))));
-- count;
set(t, result, ArrayBody + (count * BytesPerWord), inner);
}
}
return reinterpret_cast<uintptr_t>(makeLocalReference(t, result));
}
}
return reinterpret_cast<uintptr_t>
(makeLocalReference(t, makeObjectArray(t, 0)));
}
extern "C" JNIEXPORT jobjectArray JNICALL
EXPORT(JVM_GetDeclaredClasses)(Thread*, jclass) { abort(); }
EXPORT(JVM_GetDeclaredClasses)(Thread* t, jclass c)
{
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c) };
return reinterpret_cast<jclass>(run(t, jvmGetDeclaredClasses, arguments));
}
uint64_t
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;");
return reinterpret_cast<uintptr_t>
(makeLocalReference
(t, t->m->processor->invoke(t, method, 0, jclassVmClass(t, *c))));
}
extern "C" JNIEXPORT jclass JNICALL
EXPORT(JVM_GetDeclaringClass)(Thread*, jclass)
EXPORT(JVM_GetDeclaringClass)(Thread* t, jclass c)
{
// todo: implement properly
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c) };
return reinterpret_cast<jclass>(run(t, jvmGetDeclaringClass, arguments));
}
uint64_t
jvmGetClassSignature(Thread* t, uintptr_t* arguments)
{
jclass c = reinterpret_cast<jobject>(arguments[0]);
object addendum = classAddendum(t, jclassVmClass(t, *c));
if (addendum) {
object signature = addendumSignature(t, addendum);
if (signature) {
return reinterpret_cast<uintptr_t>
(makeLocalReference
(t, t->m->classpath->makeString
(t, signature, 0, byteArrayLength(t, signature) - 1)));
}
}
return 0;
}
extern "C" JNIEXPORT jstring JNICALL
EXPORT(JVM_GetClassSignature)(Thread* t, jclass c)
{
ENTER(t, Thread::ActiveState);
uintptr_t arguments[] = { reinterpret_cast<uintptr_t>(c) };
object addendum = classAddendum(t, jclassVmClass(t, *c));
if (addendum) {
object signature = addendumSignature(t, addendum);
if (signature) {
return makeLocalReference
(t, t->m->classpath->makeString
(t, signature, 0, byteArrayLength(t, signature) - 1));
}
}
return 0;
return reinterpret_cast<jclass>(run(t, jvmGetClassSignature, arguments));
}
extern "C" JNIEXPORT jbyteArray JNICALL

View File

@ -991,7 +991,7 @@ 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);
object addendum = makeClassAddendum(t, pool, 0, 0, table, 0);
set(t, class_, ClassAddendum, addendum);
}
}
@ -1724,17 +1724,44 @@ parseAttributeTable(Thread* t, Stream& s, object class_, object pool)
&byteArrayBody(t, name, 0)) == 0)
{
if (addendum == 0) {
addendum = makeClassAddendum(t, pool, 0, 0, 0);
addendum = makeClassAddendum(t, pool, 0, 0, 0, 0);
}
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);
for (unsigned i = 0; i < innerClassCount; ++i) {
int16_t inner = s.read2();
int16_t outer = s.read2();
int16_t name = s.read2();
int16_t flags = s.read2();
object reference = makeInnerClassReference
(t, inner ? singletonObject(t, pool, inner - 1) : 0,
outer ? singletonObject(t, pool, outer - 1) : 0,
name ? singletonObject(t, pool, name - 1) : 0,
flags);
set(t, table, ArrayBody + (i * BytesPerWord), reference);
}
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);
addendum = makeClassAddendum(t, pool, 0, 0, 0, 0);
}
object body = makeByteArray(t, length);

View File

@ -161,6 +161,12 @@
(void* value)
(object next))
(type innerClassReference
(object inner)
(object outer)
(object name)
(int16_t flags))
(type continuationContext
(object next)
(object before)