break each Class, Field, and Method into separate classes

In order to facilitate making the VM compatible with multiple class
libraries, it's useful to separate the VM-specific representation of
these classes from the library implementations.  This commit
introduces VMClass, VMField, and VMMethod for that purpose.
This commit is contained in:
Joel Dice 2010-09-01 10:13:52 -06:00
parent 4273ff834c
commit 17c1a552d5
21 changed files with 547 additions and 348 deletions

View File

@ -11,5 +11,6 @@
package avian; package avian;
public class ClassAddendum extends Addendum { public class ClassAddendum extends Addendum {
public volatile Class class_;
public Object[] signers; public Object[] signers;
} }

View File

@ -13,6 +13,7 @@ package avian;
import static avian.Stream.read1; import static avian.Stream.read1;
import static avian.Stream.read2; import static avian.Stream.read2;
import java.lang.reflect.Modifier;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.net.URL; import java.net.URL;
@ -24,16 +25,26 @@ import java.io.IOException;
public class SystemClassLoader extends ClassLoader { public class SystemClassLoader extends ClassLoader {
private static final int LinkFlag = 1 << 8; private static final int LinkFlag = 1 << 8;
public static native Class defineClass public static native VMClass defineVMClass
(ClassLoader loader, byte[] b, int offset, int length); (ClassLoader loader, byte[] b, int offset, int length);
protected native Class findClass(String name) throws ClassNotFoundException; private static native VMClass findVMClass(String name)
throws ClassNotFoundException;
protected native Class reallyFindLoadedClass(String name); protected Class findClass(String name) throws ClassNotFoundException {
return getClass(findVMClass(name));
}
private native boolean resourceExists(String name); private static native VMClass findLoadedVMClass(String name);
private static native Class resolveClass(ClassLoader loader, byte[] spec) protected Class reallyFindLoadedClass(String name){
VMClass c = findLoadedVMClass(name);
return c == null ? null : getClass(c);
}
private static native boolean resourceExists(String name);
private static native VMClass resolveVMClass(ClassLoader loader, byte[] spec)
throws ClassNotFoundException; throws ClassNotFoundException;
protected URL findResource(String name) { protected URL findResource(String name) {
@ -45,14 +56,14 @@ public class SystemClassLoader extends ClassLoader {
return null; return null;
} }
private static Class loadClass(ClassLoader loader, private static VMClass loadVMClass(ClassLoader loader,
byte[] nameBytes, int offset, int length) byte[] nameBytes, int offset, int length)
{ {
byte[] spec = new byte[length + 1]; byte[] spec = new byte[length + 1];
System.arraycopy(nameBytes, offset, spec, 0, length); System.arraycopy(nameBytes, offset, spec, 0, length);
try { try {
Class c = resolveClass(loader, spec); VMClass c = resolveVMClass(loader, spec);
if (c == null) { if (c == null) {
throw new NoClassDefFoundError(); throw new NoClassDefFoundError();
} }
@ -110,14 +121,14 @@ public class SystemClassLoader extends ClassLoader {
byte[] name = (byte[]) Singleton.getObject(pool, read2(in) - 1); byte[] name = (byte[]) Singleton.getObject(pool, read2(in) - 1);
return Enum.valueOf return Enum.valueOf
(loadClass(loader, typeName, 1, typeName.length - 3), (getClass(loadVMClass(loader, typeName, 1, typeName.length - 3)),
new String(name, 0, name.length - 1, false)); new String(name, 0, name.length - 1, false));
} }
case 'c':{ case 'c':{
byte[] name = (byte[]) Singleton.getObject(pool, read2(in) - 1); byte[] name = (byte[]) Singleton.getObject(pool, read2(in) - 1);
return loadClass(loader, name, 1, name.length - 3); return getClass(loadVMClass(loader, name, 1, name.length - 3));
} }
case '@': case '@':
@ -142,7 +153,8 @@ public class SystemClassLoader extends ClassLoader {
{ {
byte[] typeName = (byte[]) Singleton.getObject(pool, read2(in) - 1); byte[] typeName = (byte[]) Singleton.getObject(pool, read2(in) - 1);
Object[] annotation = new Object[(read2(in) + 1) * 2]; Object[] annotation = new Object[(read2(in) + 1) * 2];
annotation[1] = loadClass(loader, typeName, 1, typeName.length - 3); annotation[1] = getClass
(loadVMClass(loader, typeName, 1, typeName.length - 3));
for (int i = 2; i < annotation.length; i += 2) { for (int i = 2; i < annotation.length; i += 2) {
byte[] name = (byte[]) Singleton.getObject(pool, read2(in) - 1); byte[] name = (byte[]) Singleton.getObject(pool, read2(in) - 1);
@ -214,7 +226,7 @@ public class SystemClassLoader extends ClassLoader {
return start + 1; return start + 1;
} }
loadClass(loader, spec, start, end - start); loadVMClass(loader, spec, start, end - start);
return result; return result;
} }
@ -223,7 +235,35 @@ public class SystemClassLoader extends ClassLoader {
private static native void releaseClassLock(); private static native void releaseClassLock();
public static void link(Class c, ClassLoader loader) { public static Class getClass(VMClass vmClass) {
if (vmClass.addendum == null) {
SystemClassLoader.acquireClassLock();
try {
if (vmClass.addendum == null) {
vmClass.addendum = new ClassAddendum();
}
} finally {
SystemClassLoader.releaseClassLock();
}
}
if (vmClass.addendum.class_ == null) {
SystemClassLoader.acquireClassLock();
try {
if (vmClass.addendum.class_ == null) {
vmClass.addendum.class_ = new Class(vmClass);
}
} finally {
SystemClassLoader.releaseClassLock();
}
}
return vmClass.addendum.class_;
}
public static native VMClass getVMClass(Object o);
public static void link(VMClass c, ClassLoader loader) {
acquireClassLock(); acquireClassLock();
try { try {
if ((c.vmFlags & LinkFlag) == 0) { if ((c.vmFlags & LinkFlag) == 0) {
@ -234,15 +274,15 @@ public class SystemClassLoader extends ClassLoader {
parseAnnotationTable(loader, c.addendum); parseAnnotationTable(loader, c.addendum);
if (c.interfaceTable != null) { if (c.interfaceTable != null) {
int stride = (c.isInterface() ? 1 : 2); int stride = ((c.flags & Modifier.INTERFACE) != 0 ? 1 : 2);
for (int i = 0; i < c.interfaceTable.length; i += stride) { for (int i = 0; i < c.interfaceTable.length; i += stride) {
link((Class) c.interfaceTable[i], loader); link((VMClass) c.interfaceTable[i], loader);
} }
} }
if (c.methodTable != null) { if (c.methodTable != null) {
for (int i = 0; i < c.methodTable.length; ++i) { for (int i = 0; i < c.methodTable.length; ++i) {
Method m = c.methodTable[i]; VMMethod m = c.methodTable[i];
for (int j = 1; j < m.spec.length;) { for (int j = 1; j < m.spec.length;) {
j = resolveSpec(loader, m.spec, j); j = resolveSpec(loader, m.spec, j);
@ -254,7 +294,7 @@ public class SystemClassLoader extends ClassLoader {
if (c.fieldTable != null) { if (c.fieldTable != null) {
for (int i = 0; i < c.fieldTable.length; ++i) { for (int i = 0; i < c.fieldTable.length; ++i) {
Field f = c.fieldTable[i]; VMField f = c.fieldTable[i];
resolveSpec(loader, f.spec, 0); resolveSpec(loader, f.spec, 0);
@ -269,7 +309,7 @@ public class SystemClassLoader extends ClassLoader {
} }
} }
public static void link(Class c) { public static void link(VMClass c) {
link(c, c.getClassLoader()); link(c, c.loader);
} }
} }

View File

@ -0,0 +1,30 @@
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package avian;
public class VMClass {
public short flags;
public short vmFlags;
public short fixedSize;
public byte arrayElementSize;
public byte arrayDimensions;
public int[] objectMask;
public byte[] name;
public byte[] sourceFile;
public VMClass super_;
public Object[] interfaceTable;
public VMMethod[] virtualTable;
public VMField[] fieldTable;
public VMMethod[] methodTable;
public volatile avian.ClassAddendum addendum;
public Object staticTable;
public ClassLoader loader;
}

View File

@ -0,0 +1,22 @@
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package avian;
public class VMField {
public byte vmFlags;
public byte code;
public short flags;
public short offset;
public byte[] name;
public byte[] spec;
public avian.Addendum addendum;
public VMClass class_;
}

View File

@ -0,0 +1,26 @@
/* Copyright (c) 2008-2010, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
package avian;
public class VMMethod {
public byte vmFlags;
public byte returnCode;
public byte parameterCount;
public byte parameterFootprint;
public short flags;
public short offset;
public int nativeID;
public byte[] name;
public byte[] spec;
public avian.Addendum addendum;
public VMClass class_;
public Object code;
}

View File

@ -10,7 +10,10 @@
package java.lang; package java.lang;
import avian.VMClass;
import avian.ClassAddendum;
import avian.AnnotationInvocationHandler; import avian.AnnotationInvocationHandler;
import avian.SystemClassLoader;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@ -38,24 +41,13 @@ public final class Class <T>
{ {
private static final int PrimitiveFlag = 1 << 5; private static final int PrimitiveFlag = 1 << 5;
private short flags; public final VMClass vmClass;
public short vmFlags;
private short fixedSize;
private byte arrayElementSize;
private byte arrayDimensions;
private int[] objectMask;
private byte[] name;
private byte[] sourceFile;
public Class super_;
public Object[] interfaceTable;
public Method[] virtualTable;
public Field[] fieldTable;
public Method[] methodTable;
public avian.ClassAddendum addendum;
private Object staticTable;
private ClassLoader loader;
private Class() { } public Class(VMClass vmClass) {
this.vmClass = vmClass;
}
public static native VMClass vmClass(Object o);
public String toString() { public String toString() {
return getName(); return getName();
@ -73,26 +65,30 @@ public final class Class <T>
} }
public String getName() { public String getName() {
if (name == null) { return getName(vmClass);
if ((vmFlags & PrimitiveFlag) != 0) { }
if (this == primitiveClass('V')) {
name = "void\0".getBytes(); public static String getName(VMClass c) {
} else if (this == primitiveClass('Z')) { if (c.name == null) {
name = "boolean\0".getBytes(); if ((c.vmFlags & PrimitiveFlag) != 0) {
} else if (this == primitiveClass('B')) { if (c == primitiveClass('V')) {
name = "byte\0".getBytes(); c.name = "void\0".getBytes();
} else if (this == primitiveClass('C')) { } else if (c == primitiveClass('Z')) {
name = "char\0".getBytes(); c.name = "boolean\0".getBytes();
} else if (this == primitiveClass('S')) { } else if (c == primitiveClass('B')) {
name = "short\0".getBytes(); c.name = "byte\0".getBytes();
} else if (this == primitiveClass('I')) { } else if (c == primitiveClass('C')) {
name = "int\0".getBytes(); c.name = "char\0".getBytes();
} else if (this == primitiveClass('F')) { } else if (c == primitiveClass('S')) {
name = "float\0".getBytes(); c.name = "short\0".getBytes();
} else if (this == primitiveClass('J')) { } else if (c == primitiveClass('I')) {
name = "long\0".getBytes(); c.name = "int\0".getBytes();
} else if (this == primitiveClass('D')) { } else if (c == primitiveClass('F')) {
name = "double\0".getBytes(); c.name = "float\0".getBytes();
} else if (c == primitiveClass('J')) {
c.name = "long\0".getBytes();
} else if (c == primitiveClass('D')) {
c.name = "double\0".getBytes();
} else { } else {
throw new AssertionError(); throw new AssertionError();
} }
@ -102,11 +98,12 @@ public final class Class <T>
} }
return new String return new String
(replace('/', '.', name, 0, name.length - 1), 0, name.length - 1, false); (replace('/', '.', c.name, 0, c.name.length - 1), 0, c.name.length - 1,
false);
} }
public String getCanonicalName() { public String getCanonicalName() {
if ((vmFlags & PrimitiveFlag) != 0) { if ((vmClass.vmFlags & PrimitiveFlag) != 0) {
return getName(); return getName();
} else if (isArray()) { } else if (isArray()) {
return getComponentType().getCanonicalName() + "[]"; return getComponentType().getCanonicalName() + "[]";
@ -116,7 +113,7 @@ public final class Class <T>
} }
public String getSimpleName() { public String getSimpleName() {
if ((vmFlags & PrimitiveFlag) != 0) { if ((vmClass.vmFlags & PrimitiveFlag) != 0) {
return getName(); return getName();
} else if (isArray()) { } else if (isArray()) {
return getComponentType().getSimpleName() + "[]"; return getComponentType().getSimpleName() + "[]";
@ -131,10 +128,6 @@ public final class Class <T>
} }
} }
public Object staticTable() {
return staticTable;
}
public T newInstance() public T newInstance()
throws IllegalAccessException, InstantiationException throws IllegalAccessException, InstantiationException
{ {
@ -148,8 +141,7 @@ public final class Class <T>
} }
public static Class forName(String name) throws ClassNotFoundException { public static Class forName(String name) throws ClassNotFoundException {
return forName return forName(name, true, Method.getCaller().class_.loader);
(name, true, Method.getCaller().getDeclaringClass().getClassLoader());
} }
public static Class forName(String name, boolean initialize, public static Class forName(String name, boolean initialize,
@ -157,19 +149,19 @@ public final class Class <T>
throws ClassNotFoundException throws ClassNotFoundException
{ {
if (loader == null) { if (loader == null) {
loader = Class.class.loader; loader = Class.class.vmClass.loader;
} }
Class c = loader.loadClass(name); Class c = loader.loadClass(name);
avian.SystemClassLoader.link(c, loader); SystemClassLoader.link(c.vmClass, loader);
if (initialize) { if (initialize) {
c.initialize(); initialize(c.vmClass);
} }
return c; return c;
} }
private static native Class primitiveClass(char name); private static native VMClass primitiveClass(char name);
private native void initialize(); private static native void initialize(VMClass vmClass);
public static Class forCanonicalName(String name) { public static Class forCanonicalName(String name) {
return forCanonicalName(null, name); return forCanonicalName(null, name);
@ -183,7 +175,7 @@ public final class Class <T>
return forName(name.substring(1, name.length() - 1), true, loader); return forName(name.substring(1, name.length() - 1), true, loader);
} else { } else {
if (name.length() == 1) { if (name.length() == 1) {
return primitiveClass(name.charAt(0)); return SystemClassLoader.getClass(primitiveClass(name.charAt(0)));
} else { } else {
throw new ClassNotFoundException(name); throw new ClassNotFoundException(name);
} }
@ -197,39 +189,43 @@ public final class Class <T>
if (isArray()) { if (isArray()) {
String n = getName(); String n = getName();
if ("[Z".equals(n)) { if ("[Z".equals(n)) {
return primitiveClass('Z'); return SystemClassLoader.getClass(primitiveClass('Z'));
} else if ("[B".equals(n)) { } else if ("[B".equals(n)) {
return primitiveClass('B'); return SystemClassLoader.getClass(primitiveClass('B'));
} else if ("[S".equals(n)) { } else if ("[S".equals(n)) {
return primitiveClass('S'); return SystemClassLoader.getClass(primitiveClass('S'));
} else if ("[C".equals(n)) { } else if ("[C".equals(n)) {
return primitiveClass('C'); return SystemClassLoader.getClass(primitiveClass('C'));
} else if ("[I".equals(n)) { } else if ("[I".equals(n)) {
return primitiveClass('I'); return SystemClassLoader.getClass(primitiveClass('I'));
} else if ("[F".equals(n)) { } else if ("[F".equals(n)) {
return primitiveClass('F'); return SystemClassLoader.getClass(primitiveClass('F'));
} else if ("[J".equals(n)) { } else if ("[J".equals(n)) {
return primitiveClass('J'); return SystemClassLoader.getClass(primitiveClass('J'));
} else if ("[D".equals(n)) { } else if ("[D".equals(n)) {
return primitiveClass('D'); return SystemClassLoader.getClass(primitiveClass('D'));
} }
if (staticTable == null) throw new AssertionError(name); if (vmClass.staticTable == null) throw new AssertionError();
return (Class) staticTable; return SystemClassLoader.getClass((VMClass) vmClass.staticTable);
} else { } else {
return null; return null;
} }
} }
public native boolean isAssignableFrom(Class c); public static native boolean isAssignableFrom(VMClass a, VMClass b);
private Field findField(String name) { public boolean isAssignableFrom(Class c) {
if (fieldTable != null) { return isAssignableFrom(vmClass, c.vmClass);
avian.SystemClassLoader.link(this); }
for (int i = 0; i < fieldTable.length; ++i) { private static Field findField(VMClass vmClass, String name) {
if (fieldTable[i].getName().equals(name)) { if (vmClass.fieldTable != null) {
return fieldTable[i]; SystemClassLoader.link(vmClass);
for (int i = 0; i < vmClass.fieldTable.length; ++i) {
if (Field.getName(vmClass.fieldTable[i]).equals(name)) {
return new Field(vmClass.fieldTable[i]);
} }
} }
} }
@ -237,7 +233,7 @@ public final class Class <T>
} }
public Field getDeclaredField(String name) throws NoSuchFieldException { public Field getDeclaredField(String name) throws NoSuchFieldException {
Field f = findField(name); Field f = findField(vmClass, name);
if (f == null) { if (f == null) {
throw new NoSuchFieldException(name); throw new NoSuchFieldException(name);
} else { } else {
@ -246,8 +242,8 @@ public final class Class <T>
} }
public Field getField(String name) throws NoSuchFieldException { public Field getField(String name) throws NoSuchFieldException {
for (Class c = this; c != null; c = c.super_) { for (VMClass c = vmClass; c != null; c = c.super_) {
Field f = c.findField(name); Field f = findField(c, name);
if (f != null) { if (f != null) {
return f; return f;
} }
@ -268,19 +264,22 @@ public final class Class <T>
} }
} }
private Method findMethod(String name, Class[] parameterTypes) { private static Method findMethod(VMClass vmClass, String name,
if (methodTable != null) { Class[] parameterTypes)
avian.SystemClassLoader.link(this); {
if (vmClass.methodTable != null) {
SystemClassLoader.link(vmClass);
if (parameterTypes == null) { if (parameterTypes == null) {
parameterTypes = new Class[0]; parameterTypes = new Class[0];
} }
for (int i = 0; i < methodTable.length; ++i) { for (int i = 0; i < vmClass.methodTable.length; ++i) {
if (methodTable[i].getName().equals(name) if (Method.getName(vmClass.methodTable[i]).equals(name)
&& match(parameterTypes, methodTable[i].getParameterTypes())) && match(parameterTypes,
Method.getParameterTypes(vmClass.methodTable[i])))
{ {
return methodTable[i]; return new Method(vmClass.methodTable[i]);
} }
} }
} }
@ -293,7 +292,7 @@ public final class Class <T>
if (name.startsWith("<")) { if (name.startsWith("<")) {
throw new NoSuchMethodException(name); throw new NoSuchMethodException(name);
} }
Method m = findMethod(name, parameterTypes); Method m = findMethod(vmClass, name, parameterTypes);
if (m == null) { if (m == null) {
throw new NoSuchMethodException(name); throw new NoSuchMethodException(name);
} else { } else {
@ -307,8 +306,8 @@ public final class Class <T>
if (name.startsWith("<")) { if (name.startsWith("<")) {
throw new NoSuchMethodException(name); throw new NoSuchMethodException(name);
} }
for (Class c = this; c != null; c = c.super_) { for (VMClass c = vmClass; c != null; c = c.super_) {
Method m = c.findMethod(name, parameterTypes); Method m = findMethod(c, name, parameterTypes);
if (m != null) { if (m != null) {
return m; return m;
} }
@ -319,7 +318,7 @@ public final class Class <T>
public Constructor getConstructor(Class ... parameterTypes) public Constructor getConstructor(Class ... parameterTypes)
throws NoSuchMethodException throws NoSuchMethodException
{ {
Method m = findMethod("<init>", parameterTypes); Method m = findMethod(vmClass, "<init>", parameterTypes);
if (m == null) { if (m == null) {
throw new NoSuchMethodException(); throw new NoSuchMethodException();
} else { } else {
@ -348,11 +347,12 @@ public final class Class <T>
private int countConstructors(boolean publicOnly) { private int countConstructors(boolean publicOnly) {
int count = 0; int count = 0;
if (methodTable != null) { if (vmClass.methodTable != null) {
for (int i = 0; i < methodTable.length; ++i) { for (int i = 0; i < vmClass.methodTable.length; ++i) {
if (((! publicOnly) if (((! publicOnly)
|| ((methodTable[i].getModifiers() & Modifier.PUBLIC)) != 0) || ((vmClass.methodTable[i].flags & Modifier.PUBLIC))
&& methodTable[i].getName().equals("<init>")) != 0)
&& Method.getName(vmClass.methodTable[i]).equals("<init>"))
{ {
++ count; ++ count;
} }
@ -363,13 +363,13 @@ public final class Class <T>
public Constructor[] getDeclaredConstructors() { public Constructor[] getDeclaredConstructors() {
Constructor[] array = new Constructor[countConstructors(false)]; Constructor[] array = new Constructor[countConstructors(false)];
if (methodTable != null) { if (vmClass.methodTable != null) {
avian.SystemClassLoader.link(this); SystemClassLoader.link(vmClass);
int index = 0; int index = 0;
for (int i = 0; i < methodTable.length; ++i) { for (int i = 0; i < vmClass.methodTable.length; ++i) {
if (methodTable[i].getName().equals("<init>")) { if (Method.getName(vmClass.methodTable[i]).equals("<init>")) {
array[index++] = new Constructor(methodTable[i]); array[index++] = new Constructor(new Method(vmClass.methodTable[i]));
} }
} }
} }
@ -379,15 +379,15 @@ public final class Class <T>
public Constructor[] getConstructors() { public Constructor[] getConstructors() {
Constructor[] array = new Constructor[countConstructors(true)]; Constructor[] array = new Constructor[countConstructors(true)];
if (methodTable != null) { if (vmClass.methodTable != null) {
avian.SystemClassLoader.link(this); SystemClassLoader.link(vmClass);
int index = 0; int index = 0;
for (int i = 0; i < methodTable.length; ++i) { for (int i = 0; i < vmClass.methodTable.length; ++i) {
if (((methodTable[i].getModifiers() & Modifier.PUBLIC) != 0) if (((vmClass.methodTable[i].flags & Modifier.PUBLIC) != 0)
&& methodTable[i].getName().equals("<init>")) && Method.getName(vmClass.methodTable[i]).equals("<init>"))
{ {
array[index++] = new Constructor(methodTable[i]); array[index++] = new Constructor(new Method(vmClass.methodTable[i]));
} }
} }
} }
@ -396,9 +396,11 @@ public final class Class <T>
} }
public Field[] getDeclaredFields() { public Field[] getDeclaredFields() {
if (fieldTable != null) { if (vmClass.fieldTable != null) {
Field[] array = new Field[fieldTable.length]; Field[] array = new Field[vmClass.fieldTable.length];
System.arraycopy(fieldTable, 0, array, 0, fieldTable.length); for (int i = 0; i < vmClass.fieldTable.length; ++i) {
array[i] = new Field(vmClass.fieldTable[i]);
}
return array; return array;
} else { } else {
return new Field[0]; return new Field[0];
@ -407,9 +409,9 @@ public final class Class <T>
private int countPublicFields() { private int countPublicFields() {
int count = 0; int count = 0;
if (fieldTable != null) { if (vmClass.fieldTable != null) {
for (int i = 0; i < fieldTable.length; ++i) { for (int i = 0; i < vmClass.fieldTable.length; ++i) {
if (((fieldTable[i].getModifiers() & Modifier.PUBLIC)) != 0) { if (((vmClass.fieldTable[i].flags & Modifier.PUBLIC)) != 0) {
++ count; ++ count;
} }
} }
@ -419,13 +421,13 @@ public final class Class <T>
public Field[] getFields() { public Field[] getFields() {
Field[] array = new Field[countPublicFields()]; Field[] array = new Field[countPublicFields()];
if (fieldTable != null) { if (vmClass.fieldTable != null) {
avian.SystemClassLoader.link(this); SystemClassLoader.link(vmClass);
int ai = 0; int ai = 0;
for (int i = 0; i < fieldTable.length; ++i) { for (int i = 0; i < vmClass.fieldTable.length; ++i) {
if (((fieldTable[i].getModifiers() & Modifier.PUBLIC)) != 0) { if (((vmClass.fieldTable[i].flags & Modifier.PUBLIC)) != 0) {
array[ai++] = fieldTable[i]; array[ai++] = new Field(vmClass.fieldTable[i]);
} }
} }
} }
@ -434,11 +436,12 @@ public final class Class <T>
private int countMethods(boolean publicOnly) { private int countMethods(boolean publicOnly) {
int count = 0; int count = 0;
if (methodTable != null) { if (vmClass.methodTable != null) {
for (int i = 0; i < methodTable.length; ++i) { for (int i = 0; i < vmClass.methodTable.length; ++i) {
if (((! publicOnly) if (((! publicOnly)
|| ((methodTable[i].getModifiers() & Modifier.PUBLIC)) != 0) || ((vmClass.methodTable[i].flags & Modifier.PUBLIC))
&& (! methodTable[i].getName().startsWith("<"))) != 0)
&& (! Method.getName(vmClass.methodTable[i]).startsWith("<")))
{ {
++ count; ++ count;
} }
@ -449,13 +452,13 @@ public final class Class <T>
public Method[] getDeclaredMethods() { public Method[] getDeclaredMethods() {
Method[] array = new Method[countMethods(false)]; Method[] array = new Method[countMethods(false)];
if (methodTable != null) { if (vmClass.methodTable != null) {
avian.SystemClassLoader.link(this); SystemClassLoader.link(vmClass);
int ai = 0; int ai = 0;
for (int i = 0; i < methodTable.length; ++i) { for (int i = 0; i < vmClass.methodTable.length; ++i) {
if (! methodTable[i].getName().startsWith("<")) { if (! Method.getName(vmClass.methodTable[i]).startsWith("<")) {
array[ai++] = methodTable[i]; array[ai++] = new Method(vmClass.methodTable[i]);
} }
} }
} }
@ -465,15 +468,15 @@ public final class Class <T>
public Method[] getMethods() { public Method[] getMethods() {
Method[] array = new Method[countMethods(true)]; Method[] array = new Method[countMethods(true)];
if (methodTable != null) { if (vmClass.methodTable != null) {
avian.SystemClassLoader.link(this); SystemClassLoader.link(vmClass);
int index = 0; int index = 0;
for (int i = 0; i < methodTable.length; ++i) { for (int i = 0; i < vmClass.methodTable.length; ++i) {
if (((methodTable[i].getModifiers() & Modifier.PUBLIC) != 0) if (((vmClass.methodTable[i].flags & Modifier.PUBLIC) != 0)
&& (! methodTable[i].getName().startsWith("<"))) && (! Method.getName(vmClass.methodTable[i]).startsWith("<")))
{ {
array[index++] = methodTable[i]; array[index++] = new Method(vmClass.methodTable[i]);
} }
} }
} }
@ -482,13 +485,14 @@ public final class Class <T>
} }
public Class[] getInterfaces() { public Class[] getInterfaces() {
if (interfaceTable != null) { if (vmClass.interfaceTable != null) {
avian.SystemClassLoader.link(this); SystemClassLoader.link(vmClass);
int stride = (isInterface() ? 1 : 2); int stride = (isInterface() ? 1 : 2);
Class[] array = new Class[interfaceTable.length / stride]; Class[] array = new Class[vmClass.interfaceTable.length / stride];
for (int i = 0; i < array.length; ++i) { for (int i = 0; i < array.length; ++i) {
array[i] = (Class) interfaceTable[i * stride]; array[i] = SystemClassLoader.getClass
((VMClass) vmClass.interfaceTable[i * stride]);
} }
return array; return array;
} else { } else {
@ -509,36 +513,41 @@ public final class Class <T>
} }
public ClassLoader getClassLoader() { public ClassLoader getClassLoader() {
return loader; return vmClass.loader;
} }
public int getModifiers() { public int getModifiers() {
return flags; return vmClass.flags;
} }
public boolean isInterface() { public boolean isInterface() {
return (flags & Modifier.INTERFACE) != 0; return (vmClass.flags & Modifier.INTERFACE) != 0;
} }
public Class getSuperclass() { public Class getSuperclass() {
return super_; return SystemClassLoader.getClass(vmClass.super_);
} }
public boolean isArray() { public boolean isArray() {
return arrayDimensions != 0; return vmClass.arrayDimensions != 0;
}
public static boolean isInstance(VMClass c, Object o) {
return o != null && isAssignableFrom(c, SystemClassLoader.getVMClass(o));
} }
public boolean isInstance(Object o) { public boolean isInstance(Object o) {
return o != null && isAssignableFrom(o.getClass()); return isInstance(vmClass, o);
} }
public boolean isPrimitive() { public boolean isPrimitive() {
return (vmFlags & PrimitiveFlag) != 0; return (vmClass.vmFlags & PrimitiveFlag) != 0;
} }
public URL getResource(String path) { public URL getResource(String path) {
if (! path.startsWith("/")) { if (! path.startsWith("/")) {
String name = new String(this.name, 0, this.name.length - 1, false); String name = new String
(vmClass.name, 0, vmClass.name.length - 1, false);
int index = name.lastIndexOf('/'); int index = name.lastIndexOf('/');
if (index >= 0) { if (index >= 0) {
path = name.substring(0, index) + "/" + path; path = name.substring(0, index) + "/" + path;
@ -573,11 +582,11 @@ public final class Class <T>
} }
public Object[] getSigners() { public Object[] getSigners() {
return addendum == null ? null : addendum.signers; return vmClass.addendum.signers;
} }
public Package getPackage() { public Package getPackage() {
if ((vmFlags & PrimitiveFlag) != 0 || isArray()) { if ((vmClass.vmFlags & PrimitiveFlag) != 0 || isArray()) {
return null; return null;
} else { } else {
String name = getCanonicalName(); String name = getCanonicalName();
@ -597,25 +606,25 @@ public final class Class <T>
return getAnnotation(class_) != null; return getAnnotation(class_) != null;
} }
private Annotation getAnnotation(Object[] a) { private static Annotation getAnnotation(VMClass c, Object[] a) {
if (a[0] == null) { if (a[0] == null) {
a[0] = Proxy.newProxyInstance a[0] = Proxy.newProxyInstance
(loader, new Class[] { (Class) a[1] }, (c.loader, new Class[] { (Class) a[1] },
new AnnotationInvocationHandler(a)); new AnnotationInvocationHandler(a));
} }
return (Annotation) a[0]; return (Annotation) a[0];
} }
public <T extends Annotation> T getAnnotation(Class<T> class_) { public <T extends Annotation> T getAnnotation(Class<T> class_) {
for (Class c = this; c != null; c = c.super_) { for (VMClass c = vmClass; c != null; c = c.super_) {
if (c.addendum != null && c.addendum.annotationTable != null) { if (c.addendum != null && c.addendum.annotationTable != null) {
avian.SystemClassLoader.link(c, c.loader); SystemClassLoader.link(c, c.loader);
Object[] table = (Object[]) c.addendum.annotationTable; Object[] table = (Object[]) c.addendum.annotationTable;
for (int i = 0; i < table.length; ++i) { for (int i = 0; i < table.length; ++i) {
Object[] a = (Object[]) table[i]; Object[] a = (Object[]) table[i];
if (a[1] == class_) { if (a[1] == class_) {
return (T) c.getAnnotation(a); return (T) getAnnotation(c, a);
} }
} }
} }
@ -624,13 +633,13 @@ public final class Class <T>
} }
public Annotation[] getDeclaredAnnotations() { public Annotation[] getDeclaredAnnotations() {
if (addendum != null && addendum.annotationTable != null) { if (vmClass.addendum.annotationTable != null) {
avian.SystemClassLoader.link(this); SystemClassLoader.link(vmClass);
Object[] table = (Object[]) addendum.annotationTable; Object[] table = (Object[]) vmClass.addendum.annotationTable;
Annotation[] array = new Annotation[table.length]; Annotation[] array = new Annotation[table.length];
for (int i = 0; i < table.length; ++i) { for (int i = 0; i < table.length; ++i) {
array[i] = getAnnotation((Object[]) table[i]); array[i] = getAnnotation(vmClass, (Object[]) table[i]);
} }
return array; return array;
} else { } else {
@ -640,7 +649,7 @@ public final class Class <T>
private int countAnnotations() { private int countAnnotations() {
int count = 0; int count = 0;
for (Class c = this; c != null; c = c.super_) { for (VMClass c = vmClass; c != null; c = c.super_) {
if (c.addendum != null && c.addendum.annotationTable != null) { if (c.addendum != null && c.addendum.annotationTable != null) {
count += ((Object[]) c.addendum.annotationTable).length; count += ((Object[]) c.addendum.annotationTable).length;
} }
@ -651,11 +660,11 @@ public final class Class <T>
public Annotation[] getAnnotations() { public Annotation[] getAnnotations() {
Annotation[] array = new Annotation[countMethods(true)]; Annotation[] array = new Annotation[countMethods(true)];
int i = 0; int i = 0;
for (Class c = this; c != null; c = c.super_) { for (VMClass c = vmClass; c != null; c = c.super_) {
if (c.addendum != null && c.addendum.annotationTable != null) { if (c.addendum != null && c.addendum.annotationTable != null) {
Object[] table = (Object[]) c.addendum.annotationTable; Object[] table = (Object[]) c.addendum.annotationTable;
for (int j = 0; j < table.length; ++j) { for (int j = 0; j < table.length; ++j) {
array[i++] = getAnnotation((Object[]) table[j]); array[i++] = getAnnotation(vmClass, (Object[]) table[j]);
} }
} }
} }
@ -692,14 +701,4 @@ public final class Class <T>
p.add(new AllPermission()); p.add(new AllPermission());
return new ProtectionDomain(null, p); return new ProtectionDomain(null, p);
} }
// for GNU Classpath compatibility:
void setSigners(Object[] signers) {
if (signers != null && signers.length > 0) {
if (addendum == null) {
addendum = new avian.ClassAddendum();
}
addendum.signers = signers;
}
}
} }

View File

@ -46,7 +46,8 @@ public abstract class ClassLoader {
throw new IndexOutOfBoundsException(); throw new IndexOutOfBoundsException();
} }
return avian.SystemClassLoader.defineClass(this, b, offset, length); return avian.SystemClassLoader.getClass
(avian.SystemClassLoader.defineVMClass(this, b, offset, length));
} }
protected Class findClass(String name) throws ClassNotFoundException { protected Class findClass(String name) throws ClassNotFoundException {
@ -87,7 +88,7 @@ public abstract class ClassLoader {
} }
protected void resolveClass(Class c) { protected void resolveClass(Class c) {
avian.SystemClassLoader.link(c, this); avian.SystemClassLoader.link(c.vmClass, this);
} }
private ClassLoader getParent() { private ClassLoader getParent() {

View File

@ -27,7 +27,11 @@ public class Object {
protected void finalize() throws Throwable { } protected void finalize() throws Throwable { }
public native final Class<? extends Object> getClass(); public final Class<? extends Object> getClass() {
return avian.SystemClassLoader.getClass(getVMClass(this));
}
private static native avian.VMClass getVMClass(Object o);
public native int hashCode(); public native int hashCode();

View File

@ -78,13 +78,13 @@ public class Constructor<T> extends AccessibleObject
return method.getGenericParameterTypes(); return method.getGenericParameterTypes();
} }
private static native <T> T make(Class<T> c); private static native Object make(avian.VMClass c);
public T newInstance(Object ... arguments) public T newInstance(Object ... arguments)
throws InvocationTargetException, InstantiationException, throws InvocationTargetException, InstantiationException,
IllegalAccessException IllegalAccessException
{ {
T v = make(method.getDeclaringClass()); T v = (T) make(method.getDeclaringClass().vmClass);
method.invoke(v, arguments); method.invoke(v, arguments);
return v; return v;
} }

View File

@ -10,7 +10,9 @@
package java.lang.reflect; package java.lang.reflect;
import avian.VMField;
import avian.AnnotationInvocationHandler; import avian.AnnotationInvocationHandler;
import avian.SystemClassLoader;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
@ -26,81 +28,90 @@ public class Field<T> extends AccessibleObject {
private static final int BooleanField = 8; private static final int BooleanField = 8;
private static final int ObjectField = 9; private static final int ObjectField = 9;
private byte vmFlags; private final VMField vmField;
private byte code; private boolean accessible = true;
private short flags;
private short offset;
private byte[] name;
public byte[] spec;
public avian.Addendum addendum;
private Class<T> class_;
private Field() { } public Field(VMField vmField) {
this.vmField = vmField;
}
public boolean isAccessible() { public boolean isAccessible() {
return (vmFlags & Accessible) != 0; return accessible;
} }
public void setAccessible(boolean v) { public void setAccessible(boolean v) {
if (v) vmFlags |= Accessible; else vmFlags &= ~Accessible; accessible = v;
} }
public Class<T> getDeclaringClass() { public Class<T> getDeclaringClass() {
return class_; return SystemClassLoader.getClass(vmField.class_);
} }
public int getModifiers() { public int getModifiers() {
return flags; return vmField.flags;
} }
public String getName() { public String getName() {
return new String(name, 0, name.length - 1, false); return getName(vmField);
}
public static String getName(VMField vmField) {
return new String(vmField.name, 0, vmField.name.length - 1, false);
} }
public Class getType() { public Class getType() {
return Class.forCanonicalName(class_.getClassLoader(), return Class.forCanonicalName
new String(spec, 0, spec.length - 1, false)); (vmField.class_.loader,
new String(vmField.spec, 0, vmField.spec.length - 1, false));
} }
public Object get(Object instance) throws IllegalAccessException { public Object get(Object instance) throws IllegalAccessException {
Object target; Object target;
if ((flags & Modifier.STATIC) != 0) { if ((vmField.flags & Modifier.STATIC) != 0) {
target = class_.staticTable(); target = vmField.class_.staticTable;
} else if (class_.isInstance(instance)) { } else if (Class.isInstance(vmField.class_, instance)) {
target = instance; target = instance;
} else { } else {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
switch (code) { switch (vmField.code) {
case ByteField: case ByteField:
return Byte.valueOf((byte) getPrimitive(target, code, offset)); return Byte.valueOf
((byte) getPrimitive(target, vmField.code, vmField.offset));
case BooleanField: case BooleanField:
return Boolean.valueOf(getPrimitive(target, code, offset) != 0); return Boolean.valueOf
(getPrimitive(target, vmField.code, vmField.offset) != 0);
case CharField: case CharField:
return Character.valueOf((char) getPrimitive(target, code, offset)); return Character.valueOf
((char) getPrimitive(target, vmField.code, vmField.offset));
case ShortField: case ShortField:
return Short.valueOf((short) getPrimitive(target, code, offset)); return Short.valueOf
((short) getPrimitive(target, vmField.code, vmField.offset));
case IntField: case IntField:
return Integer.valueOf((int) getPrimitive(target, code, offset)); return Integer.valueOf
((int) getPrimitive(target, vmField.code, vmField.offset));
case LongField: case LongField:
return Long.valueOf((int) getPrimitive(target, code, offset)); return Long.valueOf
((int) getPrimitive(target, vmField.code, vmField.offset));
case FloatField: case FloatField:
return Float.valueOf return Float.valueOf
(Float.intBitsToFloat((int) getPrimitive(target, code, offset))); (Float.intBitsToFloat
((int) getPrimitive(target, vmField.code, vmField.offset)));
case DoubleField: case DoubleField:
return Double.valueOf return Double.valueOf
(Double.longBitsToDouble(getPrimitive(target, code, offset))); (Double.longBitsToDouble
(getPrimitive(target, vmField.code, vmField.offset)));
case ObjectField: case ObjectField:
return getObject(target, offset); return getObject(target, vmField.offset);
default: default:
throw new Error(); throw new Error();
@ -143,56 +154,58 @@ public class Field<T> extends AccessibleObject {
throws IllegalAccessException throws IllegalAccessException
{ {
Object target; Object target;
if ((flags & Modifier.STATIC) != 0) { if ((vmField.flags & Modifier.STATIC) != 0) {
target = class_.staticTable(); target = vmField.class_.staticTable;
} else if (class_.isInstance(instance)) { } else if (Class.isInstance(vmField.class_, instance)) {
target = instance; target = instance;
} else { } else {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
switch (code) { switch (vmField.code) {
case ByteField: case ByteField:
setPrimitive(target, code, offset, (Byte) value); setPrimitive(target, vmField.code, vmField.offset, (Byte) value);
break; break;
case BooleanField: case BooleanField:
setPrimitive(target, code, offset, ((Boolean) value) ? 1 : 0); setPrimitive
(target, vmField.code, vmField.offset, ((Boolean) value) ? 1 : 0);
break; break;
case CharField: case CharField:
setPrimitive(target, code, offset, (Character) value); setPrimitive(target, vmField.code, vmField.offset, (Character) value);
break; break;
case ShortField: case ShortField:
setPrimitive(target, code, offset, (Short) value); setPrimitive(target, vmField.code, vmField.offset, (Short) value);
break; break;
case IntField: case IntField:
setPrimitive(target, code, offset, (Integer) value); setPrimitive(target, vmField.code, vmField.offset, (Integer) value);
break; break;
case LongField: case LongField:
setPrimitive(target, code, offset, (Long) value); setPrimitive(target, vmField.code, vmField.offset, (Long) value);
break; break;
case FloatField: case FloatField:
setPrimitive(target, code, offset, setPrimitive(target, vmField.code, vmField.offset,
Float.floatToRawIntBits((Float) value)); Float.floatToRawIntBits((Float) value));
break; break;
case DoubleField: case DoubleField:
setPrimitive(target, code, offset, setPrimitive(target, vmField.code, vmField.offset,
Double.doubleToRawLongBits((Double) value)); Double.doubleToRawLongBits((Double) value));
break; break;
case ObjectField: case ObjectField:
if (value == null || getType().isInstance(value)) { if (value == null || getType().isInstance(value)) {
setObject(target, offset, value); setObject(target, vmField.offset, value);
} else { } else {
throw new IllegalArgumentException throw new IllegalArgumentException
("needed " + getType() + ", got " + value.getClass().getName() + ("needed " + getType() + ", got "
" when setting " + class_.getName() + "." + getName()); + Class.getName(Class.vmClass(target)) +
" when setting " + Class.getName(vmField.class_) + "." + getName());
} }
break; break;
@ -204,15 +217,15 @@ public class Field<T> extends AccessibleObject {
private Annotation getAnnotation(Object[] a) { private Annotation getAnnotation(Object[] a) {
if (a[0] == null) { if (a[0] == null) {
a[0] = Proxy.newProxyInstance a[0] = Proxy.newProxyInstance
(class_.getClassLoader(), new Class[] { (Class) a[1] }, (vmField.class_.loader, new Class[] { (Class) a[1] },
new AnnotationInvocationHandler(a)); new AnnotationInvocationHandler(a));
} }
return (Annotation) a[0]; return (Annotation) a[0];
} }
public <T extends Annotation> T getAnnotation(Class<T> class_) { public <T extends Annotation> T getAnnotation(Class<T> class_) {
if (addendum != null && addendum.annotationTable != null) { if (vmField.addendum.annotationTable != null) {
Object[] table = (Object[]) addendum.annotationTable; Object[] table = (Object[]) vmField.addendum.annotationTable;
for (int i = 0; i < table.length; ++i) { for (int i = 0; i < table.length; ++i) {
Object[] a = (Object[]) table[i]; Object[] a = (Object[]) table[i];
if (a[1] == class_) { if (a[1] == class_) {
@ -224,8 +237,8 @@ public class Field<T> extends AccessibleObject {
} }
public Annotation[] getAnnotations() { public Annotation[] getAnnotations() {
if (addendum != null && addendum.annotationTable != null) { if (vmField.addendum.annotationTable != null) {
Object[] table = (Object[]) addendum.annotationTable; Object[] table = (Object[]) vmField.addendum.annotationTable;
Annotation[] array = new Annotation[table.length]; Annotation[] array = new Annotation[table.length];
for (int i = 0; i < table.length; ++i) { for (int i = 0; i < table.length; ++i) {
array[i] = getAnnotation((Object[]) table[i]); array[i] = getAnnotation((Object[]) table[i]);
@ -255,9 +268,4 @@ public class Field<T> extends AccessibleObject {
private static native void setObject private static native void setObject
(Object instance, int offset, Object value); (Object instance, int offset, Object value);
public static class Addendum {
public Object pool;
public Object annotationTable;
}
} }

View File

@ -10,53 +10,54 @@
package java.lang.reflect; package java.lang.reflect;
import avian.VMMethod;
import avian.AnnotationInvocationHandler; import avian.AnnotationInvocationHandler;
import avian.SystemClassLoader;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
public class Method<T> extends AccessibleObject public class Method<T> extends AccessibleObject
implements Member, GenericDeclaration implements Member, GenericDeclaration
{ {
private byte vmFlags; private final VMMethod vmMethod;
private byte returnCode; private boolean accessible;
public byte parameterCount;
public byte parameterFootprint;
private short flags;
private short offset;
private int nativeID;
private byte[] name;
public byte[] spec;
public avian.Addendum addendum;
private Class<T> class_;
private Object code;
private long compiled;
private Method() { } public Method(VMMethod vmMethod) {
this.vmMethod = vmMethod;
}
public boolean isAccessible() { public boolean isAccessible() {
return (vmFlags & Accessible) != 0; return accessible;
} }
public void setAccessible(boolean v) { public void setAccessible(boolean v) {
if (v) vmFlags |= Accessible; else vmFlags &= ~Accessible; accessible = v;
} }
public static native Method getCaller(); public static native VMMethod getCaller();
public Class<T> getDeclaringClass() { public Class<T> getDeclaringClass() {
return class_; return SystemClassLoader.getClass(vmMethod.class_);
} }
public int getModifiers() { public int getModifiers() {
return flags; return vmMethod.flags;
} }
public String getName() { public String getName() {
return new String(name, 0, name.length - 1, false); return getName(vmMethod);
} }
String getSpec() { public static String getName(VMMethod vmMethod) {
return new String(spec, 0, spec.length - 1, false); return new String(vmMethod.name, 0, vmMethod.name.length - 1, false);
}
private String getSpec() {
return getSpec(vmMethod);
}
public static String getSpec(VMMethod vmMethod) {
return new String(vmMethod.spec, 0, vmMethod.spec.length - 1, false);
} }
private static int next(char c, String s, int start) { private static int next(char c, String s, int start) {
@ -67,12 +68,17 @@ public class Method<T> extends AccessibleObject
} }
public Class[] getParameterTypes() { public Class[] getParameterTypes() {
int count = parameterCount; return getParameterTypes(vmMethod);
}
public static Class[] getParameterTypes(VMMethod vmMethod) {
int count = vmMethod.parameterCount;
Class[] types = new Class[count]; Class[] types = new Class[count];
int index = 0; int index = 0;
String spec = new String(this.spec, 1, this.spec.length - 1, false); String spec = new String
(vmMethod.spec, 1, vmMethod.spec.length - 1, false);
try { try {
for (int i = 0; i < spec.length(); ++i) { for (int i = 0; i < spec.length(); ++i) {
@ -83,7 +89,7 @@ public class Method<T> extends AccessibleObject
int start = i + 1; int start = i + 1;
i = next(';', spec, start); i = next(';', spec, start);
String name = spec.substring(start, i).replace('/', '.'); String name = spec.substring(start, i).replace('/', '.');
types[index++] = Class.forName(name, true, class_.getClassLoader()); types[index++] = Class.forName(name, true, vmMethod.class_.loader);
} else if (c == '[') { } else if (c == '[') {
int start = i; int start = i;
while (spec.charAt(i) == '[') ++i; while (spec.charAt(i) == '[') ++i;
@ -92,16 +98,16 @@ public class Method<T> extends AccessibleObject
i = next(';', spec, i + 1); i = next(';', spec, i + 1);
String name = spec.substring(start, i).replace('/', '.'); String name = spec.substring(start, i).replace('/', '.');
types[index++] = Class.forName types[index++] = Class.forName
(name, true, class_.getClassLoader()); (name, true, vmMethod.class_.loader);
} else { } else {
String name = spec.substring(start, i + 1); String name = spec.substring(start, i + 1);
types[index++] = Class.forCanonicalName types[index++] = Class.forCanonicalName
(class_.getClassLoader(), name); (vmMethod.class_.loader, name);
} }
} else { } else {
String name = spec.substring(i, i + 1); String name = spec.substring(i, i + 1);
types[index++] = Class.forCanonicalName types[index++] = Class.forCanonicalName
(class_.getClassLoader(), name); (vmMethod.class_.loader, name);
} }
} }
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
@ -114,38 +120,43 @@ public class Method<T> extends AccessibleObject
public Object invoke(Object instance, Object ... arguments) public Object invoke(Object instance, Object ... arguments)
throws InvocationTargetException, IllegalAccessException throws InvocationTargetException, IllegalAccessException
{ {
if ((flags & Modifier.STATIC) != 0 || class_.isInstance(instance)) { if ((vmMethod.flags & Modifier.STATIC) != 0
if ((flags & Modifier.STATIC) != 0) { || Class.isInstance(vmMethod.class_, instance))
{
if ((vmMethod.flags & Modifier.STATIC) != 0) {
instance = null; instance = null;
} }
if (arguments == null) { if (arguments == null) {
if (parameterCount > 0) { if (vmMethod.parameterCount > 0) {
throw new NullPointerException(); throw new NullPointerException();
} }
arguments = new Object[0]; arguments = new Object[0];
} }
if (arguments.length == parameterCount) { if (arguments.length == vmMethod.parameterCount) {
return invoke(this, instance, arguments); return invoke(vmMethod, instance, arguments);
} else { } else {
throw new ArrayIndexOutOfBoundsException(); throw new ArrayIndexOutOfBoundsException();
} }
} else { } else {
// System.out.println
// (getDeclaringClass() + "." + getName() + " flags: " + vmMethod.flags + " vm flags: " + vmMethod.vmFlags + " return code: " + vmMethod.returnCode);
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
} }
private static native Object invoke(Method method, Object instance, private static native Object invoke(VMMethod method, Object instance,
Object ... arguments) Object ... arguments)
throws InvocationTargetException, IllegalAccessException; throws InvocationTargetException, IllegalAccessException;
public Class getReturnType() { public Class getReturnType() {
for (int i = 0; i < spec.length - 1; ++i) { for (int i = 0; i < vmMethod.spec.length - 1; ++i) {
if (spec[i] == ')') { if (vmMethod.spec[i] == ')') {
return Class.forCanonicalName return Class.forCanonicalName
(class_.getClassLoader(), (vmMethod.class_.loader,
new String(spec, i + 1, spec.length - i - 2, false)); new String
(vmMethod.spec, i + 1, vmMethod.spec.length - i - 2, false));
} }
} }
throw new RuntimeException(); throw new RuntimeException();
@ -154,15 +165,15 @@ public class Method<T> extends AccessibleObject
private Annotation getAnnotation(Object[] a) { private Annotation getAnnotation(Object[] a) {
if (a[0] == null) { if (a[0] == null) {
a[0] = Proxy.newProxyInstance a[0] = Proxy.newProxyInstance
(class_.getClassLoader(), new Class[] { (Class) a[1] }, (vmMethod.class_.loader, new Class[] { (Class) a[1] },
new AnnotationInvocationHandler(a)); new AnnotationInvocationHandler(a));
} }
return (Annotation) a[0]; return (Annotation) a[0];
} }
public <T extends Annotation> T getAnnotation(Class<T> class_) { public <T extends Annotation> T getAnnotation(Class<T> class_) {
if (addendum != null && addendum.annotationTable != null) { if (vmMethod.addendum.annotationTable != null) {
Object[] table = (Object[]) addendum.annotationTable; Object[] table = (Object[]) vmMethod.addendum.annotationTable;
for (int i = 0; i < table.length; ++i) { for (int i = 0; i < table.length; ++i) {
Object[] a = (Object[]) table[i]; Object[] a = (Object[]) table[i];
if (a[1] == class_) { if (a[1] == class_) {
@ -174,8 +185,8 @@ public class Method<T> extends AccessibleObject
} }
public Annotation[] getAnnotations() { public Annotation[] getAnnotations() {
if (addendum != null && addendum.annotationTable != null) { if (vmMethod.addendum.annotationTable != null) {
Object[] table = (Object[]) addendum.annotationTable; Object[] table = (Object[]) vmMethod.addendum.annotationTable;
Annotation[] array = new Annotation[table.length]; Annotation[] array = new Annotation[table.length];
for (int i = 0; i < table.length; ++i) { for (int i = 0; i < table.length; ++i) {
array[i] = getAnnotation((Object[]) table[i]); array[i] = getAnnotation((Object[]) table[i]);

View File

@ -45,12 +45,14 @@ public class Proxy {
private static final int getfield = 0xb4; private static final int getfield = 0xb4;
private static final int iload = 0x15; private static final int iload = 0x15;
private static final int invokeinterface = 0xb9; private static final int invokeinterface = 0xb9;
private static final int invokespecial = 0xb7;
private static final int invokestatic = 0xb8; private static final int invokestatic = 0xb8;
private static final int invokevirtual = 0xb6; private static final int invokevirtual = 0xb6;
private static final int ireturn = 0xac; private static final int ireturn = 0xac;
private static final int ldc_w = 0x13; private static final int ldc_w = 0x13;
private static final int lload = 0x16; private static final int lload = 0x16;
private static final int lreturn = 0xad; private static final int lreturn = 0xad;
private static final int new_ = 0xbb;
private static final int pop = 0x57; private static final int pop = 0x57;
private static final int putfield = 0xb5; private static final int putfield = 0xb5;
private static final int return_ = 0xb1; private static final int return_ = 0xb1;
@ -172,15 +174,26 @@ public class Proxy {
write1(out, aload_0); write1(out, aload_0);
write1(out, new_);
write2(out, poolAddClass(pool, "java/lang/reflect/Method") + 1);
write1(out, dup);
write1(out, ldc_w); write1(out, ldc_w);
write2(out, poolAddClass(pool, className) + 1); write2(out, poolAddClass(pool, className) + 1);
write1(out, getfield); write1(out, getfield);
write2(out, poolAddFieldRef write2(out, poolAddFieldRef
(pool, "java/lang/Class", (pool, "java/lang/Class",
"methodTable", "[Ljava/lang/reflect/Method;") + 1); "vmClass", "Lavian/VMClass;") + 1);
write1(out, getfield);
write2(out, poolAddFieldRef
(pool, "avian/VMClass",
"methodTable", "[Lavian/VMMethod;") + 1);
write1(out, ldc_w); write1(out, ldc_w);
write2(out, poolAddInteger(pool, index) + 1); write2(out, poolAddInteger(pool, index) + 1);
write1(out, aaload); write1(out, aaload);
write1(out, invokespecial);
write2(out, poolAddMethodRef
(pool, "java/lang/reflect/Method",
"<init>", "(Lavian/VMMethod;)V") + 1);
write1(out, ldc_w); write1(out, ldc_w);
write2(out, poolAddInteger(pool, parameterCount) + 1); write2(out, poolAddInteger(pool, parameterCount) + 1);
@ -434,22 +447,22 @@ public class Proxy {
interfaceIndexes[i] = poolAddClass(pool, interfaces[i].getName()); interfaceIndexes[i] = poolAddClass(pool, interfaces[i].getName());
} }
Map<String,Method> virtualMap = new HashMap(); Map<String,avian.VMMethod> virtualMap = new HashMap();
for (Class c: interfaces) { for (Class c: interfaces) {
Method[] ivtable = c.virtualTable; avian.VMMethod[] ivtable = c.vmClass.virtualTable;
if (ivtable != null) { if (ivtable != null) {
for (Method m: ivtable) { for (avian.VMMethod m: ivtable) {
virtualMap.put(m.getName() + m.getSpec(), m); virtualMap.put(Method.getName(m) + Method.getSpec(m), m);
} }
} }
} }
MethodData[] methodTable = new MethodData[virtualMap.size() + 1]; MethodData[] methodTable = new MethodData[virtualMap.size() + 1];
{ int i = 0; { int i = 0;
for (Method m: virtualMap.values()) { for (avian.VMMethod m: virtualMap.values()) {
methodTable[i] = new MethodData methodTable[i] = new MethodData
(poolAddUtf8(pool, m.getName()), (poolAddUtf8(pool, Method.getName(m)),
poolAddUtf8(pool, m.getSpec()), poolAddUtf8(pool, Method.getSpec(m)),
makeInvokeCode(pool, name, m.spec, m.parameterCount, makeInvokeCode(pool, name, m.spec, m.parameterCount,
m.parameterFootprint, i)); m.parameterFootprint, i));
++ i; ++ i;
@ -501,8 +514,9 @@ public class Proxy {
write2(out, 0); // attribute count write2(out, 0); // attribute count
byte[] classData = out.toByteArray(); byte[] classData = out.toByteArray();
return avian.SystemClassLoader.defineClass return avian.SystemClassLoader.getClass
(loader, classData, 0, classData.length); (avian.SystemClassLoader.defineVMClass
(loader, classData, 0, classData.length));
} }
public static Object newProxyInstance(ClassLoader loader, public static Object newProxyInstance(ClassLoader loader,

View File

@ -94,13 +94,12 @@ public abstract class ResourceBundle {
} }
public static ResourceBundle getBundle(String name, Locale locale) { public static ResourceBundle getBundle(String name, Locale locale) {
return getBundle(name, locale, return getBundle(name, locale, Method.getCaller().class_.loader);
Method.getCaller().getDeclaringClass().getClassLoader());
} }
public static ResourceBundle getBundle(String name) { public static ResourceBundle getBundle(String name) {
return getBundle(name, Locale.getDefault(), return getBundle
Method.getCaller().getDeclaringClass().getClassLoader()); (name, Locale.getDefault(), Method.getCaller().class_.loader);
} }
public Object getObject(String key) { public Object getObject(String key) {

View File

@ -107,15 +107,15 @@ public class Logger {
return logger.getLevel(); return logger.getLevel();
} }
private void log(Level level, Method caller, String message, private void log(Level level, avian.VMMethod caller, String message,
Throwable exception) { Throwable exception) {
if (level.intValue() < getEffectiveLevel().intValue()) { if (level.intValue() < getEffectiveLevel().intValue()) {
return; return;
} }
LogRecord r = new LogRecord LogRecord r = new LogRecord
(name, caller == null ? "<unknown>" : caller.getName(), level, message, (name, caller == null ? "<unknown>" : Method.getName(caller), level,
exception); message, exception);
publish(r); publish(r);
} }

View File

@ -97,12 +97,12 @@ Avian_java_lang_Object_toString
} }
extern "C" JNIEXPORT int64_t JNICALL extern "C" JNIEXPORT int64_t JNICALL
Avian_java_lang_Object_getClass Avian_java_lang_Object_getVMClass
(Thread* t, object, uintptr_t* arguments) (Thread* t, object, uintptr_t* arguments)
{ {
object this_ = reinterpret_cast<object>(arguments[0]); object o = reinterpret_cast<object>(arguments[0]);
return reinterpret_cast<int64_t>(objectClass(t, this_)); return reinterpret_cast<int64_t>(objectClass(t, o));
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL
@ -183,7 +183,15 @@ Avian_avian_SystemClassLoader_releaseClassLock
} }
extern "C" JNIEXPORT int64_t JNICALL extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_defineClass Avian_avian_SystemClassLoader_getVMClass
(Thread* t, object, uintptr_t* arguments)
{
return reinterpret_cast<int64_t>
(objectClass(t, reinterpret_cast<object>(arguments[0])));
}
extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_defineVMClass
(Thread* t, object, uintptr_t* arguments) (Thread* t, object, uintptr_t* arguments)
{ {
object loader = reinterpret_cast<object>(arguments[0]); object loader = reinterpret_cast<object>(arguments[0]);
@ -214,25 +222,25 @@ Avian_avian_SystemClassLoader_defineClass
} }
extern "C" JNIEXPORT int64_t JNICALL extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_reallyFindLoadedClass Avian_avian_SystemClassLoader_findLoadedVMClass
(Thread* t, object, uintptr_t* arguments) (Thread* t, object, uintptr_t* arguments)
{ {
object name = reinterpret_cast<object>(arguments[1]); object name = reinterpret_cast<object>(arguments[0]);
return search(t, name, findLoadedSystemClass, true); return search(t, name, findLoadedSystemClass, true);
} }
extern "C" JNIEXPORT int64_t JNICALL extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_findClass Avian_avian_SystemClassLoader_findVMClass
(Thread* t, object, uintptr_t* arguments) (Thread* t, object, uintptr_t* arguments)
{ {
object name = reinterpret_cast<object>(arguments[1]); object name = reinterpret_cast<object>(arguments[0]);
return search(t, name, resolveSystemClass, true); return search(t, name, resolveSystemClass, true);
} }
extern "C" JNIEXPORT int64_t JNICALL extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_resolveClass Avian_avian_SystemClassLoader_resolveVMClass
(Thread* t, object, uintptr_t* arguments) (Thread* t, object, uintptr_t* arguments)
{ {
object loader = reinterpret_cast<object>(arguments[0]); object loader = reinterpret_cast<object>(arguments[0]);
@ -245,7 +253,7 @@ extern "C" JNIEXPORT int64_t JNICALL
Avian_avian_SystemClassLoader_resourceExists Avian_avian_SystemClassLoader_resourceExists
(Thread* t, object, uintptr_t* arguments) (Thread* t, object, uintptr_t* arguments)
{ {
object name = reinterpret_cast<object>(arguments[1]); object name = reinterpret_cast<object>(arguments[0]);
if (LIKELY(name)) { if (LIKELY(name)) {
RUNTIME_ARRAY(char, n, stringLength(t, name) + 1); RUNTIME_ARRAY(char, n, stringLength(t, name) + 1);

View File

@ -4370,7 +4370,11 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
object class_ = resolveClassInPool(t, context->method, index - 1); object class_ = resolveClassInPool(t, context->method, index - 1);
if (UNLIKELY(t->exception)) return; if (UNLIKELY(t->exception)) return;
frame->pushObject(frame->append(class_)); frame->pushObject(frame->append(getJClass(t, class_)));
} else if (objectClass(t, v)
== arrayBody(t, t->m->types, Machine::ClassType))
{
frame->pushObject(frame->append(getJClass(t, v)));
} else { } else {
frame->pushObject(frame->append(v)); frame->pushObject(frame->append(v));
} }
@ -6160,9 +6164,6 @@ invokeNativeSlow(MyThread* t, object method)
{ {
PROTECT(t, method); PROTECT(t, method);
object class_ = methodClass(t, method);
PROTECT(t, class_);
unsigned footprint = methodParameterFootprint(t, method) + 1; unsigned footprint = methodParameterFootprint(t, method) + 1;
if (methodFlags(t, method) & ACC_STATIC) { if (methodFlags(t, method) & ACC_STATIC) {
++ footprint; ++ footprint;
@ -6181,9 +6182,13 @@ invokeNativeSlow(MyThread* t, object method)
+ t->arch->frameFooterSize() + t->arch->frameFooterSize()
+ t->arch->frameReturnAddressSize(); + t->arch->frameReturnAddressSize();
object jclass = 0;
PROTECT(t, jclass);
if (methodFlags(t, method) & ACC_STATIC) { if (methodFlags(t, method) & ACC_STATIC) {
jclass = getJClass(t, methodClass(t, method));
RUNTIME_ARRAY_BODY(args)[argOffset++] RUNTIME_ARRAY_BODY(args)[argOffset++]
= reinterpret_cast<uintptr_t>(&class_); = reinterpret_cast<uintptr_t>(&jclass);
} else { } else {
RUNTIME_ARRAY_BODY(args)[argOffset++] RUNTIME_ARRAY_BODY(args)[argOffset++]
= reinterpret_cast<uintptr_t>(sp++); = reinterpret_cast<uintptr_t>(sp++);

View File

@ -2224,7 +2224,11 @@ interpret(Thread* t)
(t, frameMethod(t, frame), index - 1); (t, frameMethod(t, frame), index - 1);
if (UNLIKELY(exception)) goto throw_; if (UNLIKELY(exception)) goto throw_;
pushObject(t, class_); pushObject(t, getJClass(t, class_));
} else if (objectClass(t, v)
== arrayBody(t, t->m->types, Machine::ClassType))
{
pushObject(t, getJClass(t, v));
} else { } else {
pushObject(t, v); pushObject(t, v);
} }

View File

@ -248,7 +248,9 @@ FindClass(Thread* t, const char* name)
object n = makeByteArray(t, strlen(name) + 1); object n = makeByteArray(t, strlen(name) + 1);
replace('.', '/', name, &byteArrayBody(t, n, 0)); replace('.', '/', name, &byteArrayBody(t, n, 0));
return makeLocalReference(t, resolveClass(t, t->m->loader, n)); object c = resolveClass(t, t->m->loader, n);
return makeLocalReference(t, c == 0 ? 0 : getJClass(t, c));
} }
jint JNICALL jint JNICALL
@ -270,7 +272,7 @@ ThrowNew(Thread* t, jclass c, const char* message)
object trace = makeTrace(t); object trace = makeTrace(t);
PROTECT(t, trace); PROTECT(t, trace);
t->exception = make(t, *c); t->exception = make(t, jclassVmClass(t, *c));
set(t, t->exception, ThrowableMessage, m); set(t, t->exception, ThrowableMessage, m);
set(t, t->exception, ThrowableTrace, trace); set(t, t->exception, ThrowableTrace, trace);
@ -316,7 +318,7 @@ GetObjectClass(Thread* t, jobject o)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return makeLocalReference(t, objectClass(t, *o)); return makeLocalReference(t, getJClass(t, objectClass(t, *o)));
} }
jboolean JNICALL jboolean JNICALL
@ -324,7 +326,7 @@ IsInstanceOf(Thread* t, jobject o, jclass c)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return instanceOf(t, *c, *o); return instanceOf(t, jclassVmClass(t, *c), *o);
} }
object object
@ -334,7 +336,7 @@ findMethod(Thread* t, jclass c, const char* name, const char* spec)
PROTECT(t, n); PROTECT(t, n);
object s = makeByteArray(t, "%s", spec); object s = makeByteArray(t, "%s", spec);
return vm::findMethod(t, *c, n, s); return vm::findMethod(t, jclassVmClass(t, *c), n, s);
} }
jint jint
@ -395,7 +397,7 @@ NewObjectV(Thread* t, jclass c, jmethodID m, va_list a)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
object o = make(t, *c); object o = make(t, jclassVmClass(t, *c));
PROTECT(t, o); PROTECT(t, o);
t->m->processor->invokeList(t, getMethod(t, m), o, true, a); t->m->processor->invokeList(t, getMethod(t, m), o, true, a);
@ -875,7 +877,7 @@ GetFieldID(Thread* t, jclass c, const char* name, const char* spec)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
object field = resolveField(t, *c, name, spec); object field = resolveField(t, jclassVmClass(t, *c), name, spec);
if (UNLIKELY(t->exception)) return 0; if (UNLIKELY(t->exception)) return 0;
return fieldOffset(t, field); return fieldOffset(t, field);
@ -886,7 +888,7 @@ GetStaticFieldID(Thread* t, jclass c, const char* name, const char* spec)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
object field = resolveField(t, *c, name, spec); object field = resolveField(t, jclassVmClass(t, *c), name, spec);
if (UNLIKELY(t->exception)) return 0; if (UNLIKELY(t->exception)) return 0;
return fieldOffset(t, field); return fieldOffset(t, field);
@ -1041,7 +1043,8 @@ GetStaticObjectField(Thread* t, jclass c, jfieldID field)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return makeLocalReference(t, cast<object>(classStaticTable(t, *c), field)); return makeLocalReference
(t, cast<object>(classStaticTable(t, jclassVmClass(t, *c)), field));
} }
jboolean JNICALL jboolean JNICALL
@ -1049,7 +1052,7 @@ GetStaticBooleanField(Thread* t, jclass c, jfieldID field)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return cast<int8_t>(classStaticTable(t, *c), field); return cast<int8_t>(classStaticTable(t, jclassVmClass(t, *c)), field);
} }
jbyte JNICALL jbyte JNICALL
@ -1057,7 +1060,7 @@ GetStaticByteField(Thread* t, jclass c, jfieldID field)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return cast<int8_t>(classStaticTable(t, *c), field); return cast<int8_t>(classStaticTable(t, jclassVmClass(t, *c)), field);
} }
jchar JNICALL jchar JNICALL
@ -1065,7 +1068,7 @@ GetStaticCharField(Thread* t, jclass c, jfieldID field)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return cast<uint16_t>(classStaticTable(t, *c), field); return cast<uint16_t>(classStaticTable(t, jclassVmClass(t, *c)), field);
} }
jshort JNICALL jshort JNICALL
@ -1073,7 +1076,7 @@ GetStaticShortField(Thread* t, jclass c, jfieldID field)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return cast<int16_t>(classStaticTable(t, *c), field); return cast<int16_t>(classStaticTable(t, jclassVmClass(t, *c)), field);
} }
jint JNICALL jint JNICALL
@ -1081,7 +1084,7 @@ GetStaticIntField(Thread* t, jclass c, jfieldID field)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return cast<int32_t>(classStaticTable(t, *c), field); return cast<int32_t>(classStaticTable(t, jclassVmClass(t, *c)), field);
} }
jlong JNICALL jlong JNICALL
@ -1089,7 +1092,7 @@ GetStaticLongField(Thread* t, jclass c, jfieldID field)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return cast<int64_t>(classStaticTable(t, *c), field); return cast<int64_t>(classStaticTable(t, jclassVmClass(t, *c)), field);
} }
jfloat JNICALL jfloat JNICALL
@ -1097,7 +1100,7 @@ GetStaticFloatField(Thread* t, jclass c, jfieldID field)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return cast<float>(classStaticTable(t, *c), field); return cast<float>(classStaticTable(t, jclassVmClass(t, *c)), field);
} }
jdouble JNICALL jdouble JNICALL
@ -1105,7 +1108,7 @@ GetStaticDoubleField(Thread* t, jclass c, jfieldID field)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
return cast<double>(classStaticTable(t, *c), field); return cast<double>(classStaticTable(t, jclassVmClass(t, *c)), field);
} }
void JNICALL void JNICALL
@ -1121,7 +1124,7 @@ SetStaticBooleanField(Thread* t, jclass c, jfieldID field, jboolean v)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
cast<int8_t>(classStaticTable(t, *c), field) = v; cast<int8_t>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
} }
void JNICALL void JNICALL
@ -1129,7 +1132,7 @@ SetStaticByteField(Thread* t, jclass c, jfieldID field, jbyte v)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
cast<int8_t>(classStaticTable(t, *c), field) = v; cast<int8_t>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
} }
void JNICALL void JNICALL
@ -1137,7 +1140,7 @@ SetStaticCharField(Thread* t, jclass c, jfieldID field, jchar v)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
cast<uint16_t>(classStaticTable(t, *c), field) = v; cast<uint16_t>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
} }
void JNICALL void JNICALL
@ -1145,7 +1148,7 @@ SetStaticShortField(Thread* t, jclass c, jfieldID field, jshort v)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
cast<int16_t>(classStaticTable(t, *c), field) = v; cast<int16_t>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
} }
void JNICALL void JNICALL
@ -1153,7 +1156,7 @@ SetStaticIntField(Thread* t, jclass c, jfieldID field, jint v)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
cast<int32_t>(classStaticTable(t, *c), field) = v; cast<int32_t>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
} }
void JNICALL void JNICALL
@ -1161,7 +1164,7 @@ SetStaticLongField(Thread* t, jclass c, jfieldID field, jlong v)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
cast<int64_t>(classStaticTable(t, *c), field) = v; cast<int64_t>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
} }
void JNICALL void JNICALL
@ -1169,7 +1172,7 @@ SetStaticFloatField(Thread* t, jclass c, jfieldID field, jfloat v)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
cast<float>(classStaticTable(t, *c), field) = v; cast<float>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
} }
void JNICALL void JNICALL
@ -1177,7 +1180,7 @@ SetStaticDoubleField(Thread* t, jclass c, jfieldID field, jdouble v)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
cast<double>(classStaticTable(t, *c), field) = v; cast<double>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
} }
jobject JNICALL jobject JNICALL
@ -1248,7 +1251,9 @@ NewObjectArray(Thread* t, jsize length, jclass class_, jobject init)
{ {
ENTER(t, Thread::ActiveState); ENTER(t, Thread::ActiveState);
object a = makeObjectArray(t, classLoader(t, *class_), *class_, length); object a = makeObjectArray
(t, classLoader(t, jclassVmClass(t, *class_)), jclassVmClass(t, *class_),
length);
object value = (init ? *init : 0); object value = (init ? *init : 0);
for (jsize i = 0; i < length; ++i) { for (jsize i = 0; i < length; ++i) {
set(t, a, ArrayBody + (i * BytesPerWord), value); set(t, a, ArrayBody + (i * BytesPerWord), value);

View File

@ -1627,7 +1627,7 @@ parseAttributeTable(Thread* t, Stream& s, object class_, object pool)
object body = makeByteArray(t, length); object body = makeByteArray(t, length);
s.read(reinterpret_cast<uint8_t*>(&byteArrayBody(t, body, 0)), length); s.read(reinterpret_cast<uint8_t*>(&byteArrayBody(t, body, 0)), length);
object addendum = makeClassAddendum(t, pool, body, 0); object addendum = makeClassAddendum(t, pool, body, 0, 0);
set(t, class_, ClassAddendum, addendum); set(t, class_, ClassAddendum, addendum);
} else { } else {

View File

@ -3000,6 +3000,29 @@ resolveMethod(Thread* t, object method, unsigned index)
(t, classLoader(t, methodClass(t, method)), method, index); (t, classLoader(t, methodClass(t, method)), method, index);
} }
inline object
getJClass(Thread* t, object c)
{
if (classAddendum(t, c) == 0) {
ACQUIRE(t, t->m->classLock);
object addendum = makeClassAddendum(t, 0, 0, 0, 0);
set(t, c, ClassAddendum, addendum);
}
object jclass = classAddendumClass(t, classAddendum(t, c));
if (jclass == 0) {
ACQUIRE(t, t->m->classLock);
jclass = makeJclass(t, c);
set(t, classAddendum(t, c), ClassAddendumClass, jclass);
}
return jclass;
}
void void
dumpHeap(Thread* t, FILE* out); dumpHeap(Thread* t, FILE* out);

View File

@ -1,8 +1,10 @@
(type jobject java/lang/Object) (type jobject java/lang/Object)
(type class java/lang/Class (type class avian/VMClass
(array void* vtable)) (array void* vtable))
(type jclass java/lang/Class)
(type singleton (type singleton
(array uintptr_t body)) (array uintptr_t body))
@ -11,13 +13,10 @@
(type systemClassLoader avian/SystemClassLoader) (type systemClassLoader avian/SystemClassLoader)
(type accessibleObject java/lang/reflect/AccessibleObject) (type field avian/VMField)
(type field java/lang/reflect/Field) (type method avian/VMMethod
(intptr_t compiled))
(type method java/lang/reflect/Method)
(type proxy java/lang/reflect/Proxy)
(type addendum avian/Addendum) (type addendum avian/Addendum)