diff --git a/classpath/java/lang/Class.java b/classpath/java/lang/Class.java index 6aceca3606..d5672c7183 100644 --- a/classpath/java/lang/Class.java +++ b/classpath/java/lang/Class.java @@ -405,34 +405,64 @@ public final class Class implements Type, AnnotatedElement { } public Class[] getDeclaredClasses() { - if (vmClass.addendum == null || vmClass.addendum.innerClassTable == null) { - return new Class[0]; + ClassAddendum addendum = vmClass.addendum; + if (addendum != null) { + InnerClassReference[] table = addendum.innerClassTable; + if (table != null) { + int count = 0; + for (int i = 0; i < table.length; ++i) { + InnerClassReference reference = table[i]; + if (reference.outer != null + && Arrays.equals(vmClass.name, reference.outer)) + { + ++ count; + } + } + + Class[] result = new Class[count]; + for (int i = 0; i < table.length; ++i) { + InnerClassReference reference = table[i]; + if (reference.outer != null + && Arrays.equals(vmClass.name, reference.outer)) + { + try { + result[--count] = getClassLoader().loadClass + (new String(reference.inner, 0, reference.inner.length - 1)); + } catch (ClassNotFoundException e) { + throw new Error(e); + } + } + } + + return result; + } } - InnerClassReference[] table = vmClass.addendum.innerClassTable; - Class[] result = new Class[table.length]; - int counter = 0; - String prefix = getName().replace('.', '/') + "$"; - for (int i = 0; i < table.length; ++i) try { - byte[] inner = table[i].inner; - if (inner != null && inner.length > 1) { - String name = new String(inner, 0, inner.length - 1); - if (name.startsWith(prefix) && name.indexOf('$', prefix.length()) < 0) { - Class innerClass = getClassLoader().loadClass(name); - result[counter++] = innerClass; + return new Class[0]; + } + + public Class getDeclaringClass() { + 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)) { + if (reference.outer != null) { + try { + return getClassLoader().loadClass + (new String(reference.outer, 0, reference.outer.length - 1)); + } catch (ClassNotFoundException e) { + throw new Error(e); + } + } else { + return null; + } + } } } - } catch (ClassNotFoundException e) { - throw new Error(e); } - if (counter == result.length) { - return result; - } - if (counter == 0) { - return new Class[0]; - } - Class[] result2 = new Class[counter]; - System.arraycopy(result, 0, result2, 0, counter); - return result2; + return null; } public ClassLoader getClassLoader() { diff --git a/src/avian/classpath-common.h b/src/avian/classpath-common.h index 994b1b1897..b41734e006 100644 --- a/src/avian/classpath-common.h +++ b/src/avian/classpath-common.h @@ -731,7 +731,7 @@ getDeclaringClass(Thread* t, object c) if (table) { for (unsigned i = 0; i < arrayLength(t, table); ++i) { object reference = arrayBody(t, table, i); - if (strcmp + if (innerClassReferenceOuter(t, reference) and strcmp (&byteArrayBody(t, innerClassReferenceInner(t, reference), 0), &byteArrayBody(t, className(t, c), 0)) == 0) { diff --git a/test/Reflection.java b/test/Reflection.java index bd054f9ef9..2661c07ff5 100644 --- a/test/Reflection.java +++ b/test/Reflection.java @@ -243,6 +243,12 @@ public class Reflection { expect((Baz.class.getModifiers() & Modifier.PUBLIC) == 0); expect(B.class.getDeclaredMethods().length == 0); + + new Runnable() { + public void run() { + expect(getClass().getDeclaringClass() == null); + } + }.run(); } protected static class Baz {