mirror of
https://github.com/corda/corda.git
synced 2024-12-29 09:18:58 +00:00
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:
parent
4273ff834c
commit
17c1a552d5
@ -11,5 +11,6 @@
|
||||
package avian;
|
||||
|
||||
public class ClassAddendum extends Addendum {
|
||||
public volatile Class class_;
|
||||
public Object[] signers;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ package avian;
|
||||
import static avian.Stream.read1;
|
||||
import static avian.Stream.read2;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URL;
|
||||
@ -24,16 +25,26 @@ import java.io.IOException;
|
||||
public class SystemClassLoader extends ClassLoader {
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
protected URL findResource(String name) {
|
||||
@ -45,14 +56,14 @@ public class SystemClassLoader extends ClassLoader {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Class loadClass(ClassLoader loader,
|
||||
byte[] nameBytes, int offset, int length)
|
||||
private static VMClass loadVMClass(ClassLoader loader,
|
||||
byte[] nameBytes, int offset, int length)
|
||||
{
|
||||
byte[] spec = new byte[length + 1];
|
||||
System.arraycopy(nameBytes, offset, spec, 0, length);
|
||||
|
||||
try {
|
||||
Class c = resolveClass(loader, spec);
|
||||
VMClass c = resolveVMClass(loader, spec);
|
||||
if (c == null) {
|
||||
throw new NoClassDefFoundError();
|
||||
}
|
||||
@ -110,14 +121,14 @@ public class SystemClassLoader extends ClassLoader {
|
||||
byte[] name = (byte[]) Singleton.getObject(pool, read2(in) - 1);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
case 'c':{
|
||||
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 '@':
|
||||
@ -142,7 +153,8 @@ public class SystemClassLoader extends ClassLoader {
|
||||
{
|
||||
byte[] typeName = (byte[]) Singleton.getObject(pool, read2(in) - 1);
|
||||
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) {
|
||||
byte[] name = (byte[]) Singleton.getObject(pool, read2(in) - 1);
|
||||
@ -214,7 +226,7 @@ public class SystemClassLoader extends ClassLoader {
|
||||
return start + 1;
|
||||
}
|
||||
|
||||
loadClass(loader, spec, start, end - start);
|
||||
loadVMClass(loader, spec, start, end - start);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -223,7 +235,35 @@ public class SystemClassLoader extends ClassLoader {
|
||||
|
||||
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();
|
||||
try {
|
||||
if ((c.vmFlags & LinkFlag) == 0) {
|
||||
@ -234,15 +274,15 @@ public class SystemClassLoader extends ClassLoader {
|
||||
parseAnnotationTable(loader, c.addendum);
|
||||
|
||||
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) {
|
||||
link((Class) c.interfaceTable[i], loader);
|
||||
link((VMClass) c.interfaceTable[i], loader);
|
||||
}
|
||||
}
|
||||
|
||||
if (c.methodTable != null) {
|
||||
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;) {
|
||||
j = resolveSpec(loader, m.spec, j);
|
||||
@ -254,7 +294,7 @@ public class SystemClassLoader extends ClassLoader {
|
||||
|
||||
if (c.fieldTable != null) {
|
||||
for (int i = 0; i < c.fieldTable.length; ++i) {
|
||||
Field f = c.fieldTable[i];
|
||||
VMField f = c.fieldTable[i];
|
||||
|
||||
resolveSpec(loader, f.spec, 0);
|
||||
|
||||
@ -269,7 +309,7 @@ public class SystemClassLoader extends ClassLoader {
|
||||
}
|
||||
}
|
||||
|
||||
public static void link(Class c) {
|
||||
link(c, c.getClassLoader());
|
||||
public static void link(VMClass c) {
|
||||
link(c, c.loader);
|
||||
}
|
||||
}
|
||||
|
30
classpath/avian/VMClass.java
Normal file
30
classpath/avian/VMClass.java
Normal 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;
|
||||
}
|
22
classpath/avian/VMField.java
Normal file
22
classpath/avian/VMField.java
Normal 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_;
|
||||
}
|
26
classpath/avian/VMMethod.java
Normal file
26
classpath/avian/VMMethod.java
Normal 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;
|
||||
}
|
@ -10,7 +10,10 @@
|
||||
|
||||
package java.lang;
|
||||
|
||||
import avian.VMClass;
|
||||
import avian.ClassAddendum;
|
||||
import avian.AnnotationInvocationHandler;
|
||||
import avian.SystemClassLoader;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
@ -38,24 +41,13 @@ public final class Class <T>
|
||||
{
|
||||
private static final int PrimitiveFlag = 1 << 5;
|
||||
|
||||
private short flags;
|
||||
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;
|
||||
public final VMClass vmClass;
|
||||
|
||||
private Class() { }
|
||||
public Class(VMClass vmClass) {
|
||||
this.vmClass = vmClass;
|
||||
}
|
||||
|
||||
public static native VMClass vmClass(Object o);
|
||||
|
||||
public String toString() {
|
||||
return getName();
|
||||
@ -73,26 +65,30 @@ public final class Class <T>
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
if (name == null) {
|
||||
if ((vmFlags & PrimitiveFlag) != 0) {
|
||||
if (this == primitiveClass('V')) {
|
||||
name = "void\0".getBytes();
|
||||
} else if (this == primitiveClass('Z')) {
|
||||
name = "boolean\0".getBytes();
|
||||
} else if (this == primitiveClass('B')) {
|
||||
name = "byte\0".getBytes();
|
||||
} else if (this == primitiveClass('C')) {
|
||||
name = "char\0".getBytes();
|
||||
} else if (this == primitiveClass('S')) {
|
||||
name = "short\0".getBytes();
|
||||
} else if (this == primitiveClass('I')) {
|
||||
name = "int\0".getBytes();
|
||||
} else if (this == primitiveClass('F')) {
|
||||
name = "float\0".getBytes();
|
||||
} else if (this == primitiveClass('J')) {
|
||||
name = "long\0".getBytes();
|
||||
} else if (this == primitiveClass('D')) {
|
||||
name = "double\0".getBytes();
|
||||
return getName(vmClass);
|
||||
}
|
||||
|
||||
public static String getName(VMClass c) {
|
||||
if (c.name == null) {
|
||||
if ((c.vmFlags & PrimitiveFlag) != 0) {
|
||||
if (c == primitiveClass('V')) {
|
||||
c.name = "void\0".getBytes();
|
||||
} else if (c == primitiveClass('Z')) {
|
||||
c.name = "boolean\0".getBytes();
|
||||
} else if (c == primitiveClass('B')) {
|
||||
c.name = "byte\0".getBytes();
|
||||
} else if (c == primitiveClass('C')) {
|
||||
c.name = "char\0".getBytes();
|
||||
} else if (c == primitiveClass('S')) {
|
||||
c.name = "short\0".getBytes();
|
||||
} else if (c == primitiveClass('I')) {
|
||||
c.name = "int\0".getBytes();
|
||||
} else if (c == primitiveClass('F')) {
|
||||
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 {
|
||||
throw new AssertionError();
|
||||
}
|
||||
@ -102,11 +98,12 @@ public final class Class <T>
|
||||
}
|
||||
|
||||
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() {
|
||||
if ((vmFlags & PrimitiveFlag) != 0) {
|
||||
if ((vmClass.vmFlags & PrimitiveFlag) != 0) {
|
||||
return getName();
|
||||
} else if (isArray()) {
|
||||
return getComponentType().getCanonicalName() + "[]";
|
||||
@ -116,7 +113,7 @@ public final class Class <T>
|
||||
}
|
||||
|
||||
public String getSimpleName() {
|
||||
if ((vmFlags & PrimitiveFlag) != 0) {
|
||||
if ((vmClass.vmFlags & PrimitiveFlag) != 0) {
|
||||
return getName();
|
||||
} else if (isArray()) {
|
||||
return getComponentType().getSimpleName() + "[]";
|
||||
@ -131,10 +128,6 @@ public final class Class <T>
|
||||
}
|
||||
}
|
||||
|
||||
public Object staticTable() {
|
||||
return staticTable;
|
||||
}
|
||||
|
||||
public T newInstance()
|
||||
throws IllegalAccessException, InstantiationException
|
||||
{
|
||||
@ -148,8 +141,7 @@ public final class Class <T>
|
||||
}
|
||||
|
||||
public static Class forName(String name) throws ClassNotFoundException {
|
||||
return forName
|
||||
(name, true, Method.getCaller().getDeclaringClass().getClassLoader());
|
||||
return forName(name, true, Method.getCaller().class_.loader);
|
||||
}
|
||||
|
||||
public static Class forName(String name, boolean initialize,
|
||||
@ -157,19 +149,19 @@ public final class Class <T>
|
||||
throws ClassNotFoundException
|
||||
{
|
||||
if (loader == null) {
|
||||
loader = Class.class.loader;
|
||||
loader = Class.class.vmClass.loader;
|
||||
}
|
||||
Class c = loader.loadClass(name);
|
||||
avian.SystemClassLoader.link(c, loader);
|
||||
SystemClassLoader.link(c.vmClass, loader);
|
||||
if (initialize) {
|
||||
c.initialize();
|
||||
initialize(c.vmClass);
|
||||
}
|
||||
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) {
|
||||
return forCanonicalName(null, name);
|
||||
@ -183,7 +175,7 @@ public final class Class <T>
|
||||
return forName(name.substring(1, name.length() - 1), true, loader);
|
||||
} else {
|
||||
if (name.length() == 1) {
|
||||
return primitiveClass(name.charAt(0));
|
||||
return SystemClassLoader.getClass(primitiveClass(name.charAt(0)));
|
||||
} else {
|
||||
throw new ClassNotFoundException(name);
|
||||
}
|
||||
@ -197,39 +189,43 @@ public final class Class <T>
|
||||
if (isArray()) {
|
||||
String n = getName();
|
||||
if ("[Z".equals(n)) {
|
||||
return primitiveClass('Z');
|
||||
return SystemClassLoader.getClass(primitiveClass('Z'));
|
||||
} else if ("[B".equals(n)) {
|
||||
return primitiveClass('B');
|
||||
return SystemClassLoader.getClass(primitiveClass('B'));
|
||||
} else if ("[S".equals(n)) {
|
||||
return primitiveClass('S');
|
||||
return SystemClassLoader.getClass(primitiveClass('S'));
|
||||
} else if ("[C".equals(n)) {
|
||||
return primitiveClass('C');
|
||||
return SystemClassLoader.getClass(primitiveClass('C'));
|
||||
} else if ("[I".equals(n)) {
|
||||
return primitiveClass('I');
|
||||
return SystemClassLoader.getClass(primitiveClass('I'));
|
||||
} else if ("[F".equals(n)) {
|
||||
return primitiveClass('F');
|
||||
return SystemClassLoader.getClass(primitiveClass('F'));
|
||||
} else if ("[J".equals(n)) {
|
||||
return primitiveClass('J');
|
||||
return SystemClassLoader.getClass(primitiveClass('J'));
|
||||
} else if ("[D".equals(n)) {
|
||||
return primitiveClass('D');
|
||||
return SystemClassLoader.getClass(primitiveClass('D'));
|
||||
}
|
||||
|
||||
if (staticTable == null) throw new AssertionError(name);
|
||||
return (Class) staticTable;
|
||||
if (vmClass.staticTable == null) throw new AssertionError();
|
||||
return SystemClassLoader.getClass((VMClass) vmClass.staticTable);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public native boolean isAssignableFrom(Class c);
|
||||
public static native boolean isAssignableFrom(VMClass a, VMClass b);
|
||||
|
||||
private Field findField(String name) {
|
||||
if (fieldTable != null) {
|
||||
avian.SystemClassLoader.link(this);
|
||||
public boolean isAssignableFrom(Class c) {
|
||||
return isAssignableFrom(vmClass, c.vmClass);
|
||||
}
|
||||
|
||||
for (int i = 0; i < fieldTable.length; ++i) {
|
||||
if (fieldTable[i].getName().equals(name)) {
|
||||
return fieldTable[i];
|
||||
private static Field findField(VMClass vmClass, String name) {
|
||||
if (vmClass.fieldTable != null) {
|
||||
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 {
|
||||
Field f = findField(name);
|
||||
Field f = findField(vmClass, name);
|
||||
if (f == null) {
|
||||
throw new NoSuchFieldException(name);
|
||||
} else {
|
||||
@ -246,8 +242,8 @@ public final class Class <T>
|
||||
}
|
||||
|
||||
public Field getField(String name) throws NoSuchFieldException {
|
||||
for (Class c = this; c != null; c = c.super_) {
|
||||
Field f = c.findField(name);
|
||||
for (VMClass c = vmClass; c != null; c = c.super_) {
|
||||
Field f = findField(c, name);
|
||||
if (f != null) {
|
||||
return f;
|
||||
}
|
||||
@ -268,19 +264,22 @@ public final class Class <T>
|
||||
}
|
||||
}
|
||||
|
||||
private Method findMethod(String name, Class[] parameterTypes) {
|
||||
if (methodTable != null) {
|
||||
avian.SystemClassLoader.link(this);
|
||||
private static Method findMethod(VMClass vmClass, String name,
|
||||
Class[] parameterTypes)
|
||||
{
|
||||
if (vmClass.methodTable != null) {
|
||||
SystemClassLoader.link(vmClass);
|
||||
|
||||
if (parameterTypes == null) {
|
||||
parameterTypes = new Class[0];
|
||||
}
|
||||
|
||||
for (int i = 0; i < methodTable.length; ++i) {
|
||||
if (methodTable[i].getName().equals(name)
|
||||
&& match(parameterTypes, methodTable[i].getParameterTypes()))
|
||||
for (int i = 0; i < vmClass.methodTable.length; ++i) {
|
||||
if (Method.getName(vmClass.methodTable[i]).equals(name)
|
||||
&& 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("<")) {
|
||||
throw new NoSuchMethodException(name);
|
||||
}
|
||||
Method m = findMethod(name, parameterTypes);
|
||||
Method m = findMethod(vmClass, name, parameterTypes);
|
||||
if (m == null) {
|
||||
throw new NoSuchMethodException(name);
|
||||
} else {
|
||||
@ -307,8 +306,8 @@ public final class Class <T>
|
||||
if (name.startsWith("<")) {
|
||||
throw new NoSuchMethodException(name);
|
||||
}
|
||||
for (Class c = this; c != null; c = c.super_) {
|
||||
Method m = c.findMethod(name, parameterTypes);
|
||||
for (VMClass c = vmClass; c != null; c = c.super_) {
|
||||
Method m = findMethod(c, name, parameterTypes);
|
||||
if (m != null) {
|
||||
return m;
|
||||
}
|
||||
@ -319,7 +318,7 @@ public final class Class <T>
|
||||
public Constructor getConstructor(Class ... parameterTypes)
|
||||
throws NoSuchMethodException
|
||||
{
|
||||
Method m = findMethod("<init>", parameterTypes);
|
||||
Method m = findMethod(vmClass, "<init>", parameterTypes);
|
||||
if (m == null) {
|
||||
throw new NoSuchMethodException();
|
||||
} else {
|
||||
@ -348,11 +347,12 @@ public final class Class <T>
|
||||
|
||||
private int countConstructors(boolean publicOnly) {
|
||||
int count = 0;
|
||||
if (methodTable != null) {
|
||||
for (int i = 0; i < methodTable.length; ++i) {
|
||||
if (vmClass.methodTable != null) {
|
||||
for (int i = 0; i < vmClass.methodTable.length; ++i) {
|
||||
if (((! publicOnly)
|
||||
|| ((methodTable[i].getModifiers() & Modifier.PUBLIC)) != 0)
|
||||
&& methodTable[i].getName().equals("<init>"))
|
||||
|| ((vmClass.methodTable[i].flags & Modifier.PUBLIC))
|
||||
!= 0)
|
||||
&& Method.getName(vmClass.methodTable[i]).equals("<init>"))
|
||||
{
|
||||
++ count;
|
||||
}
|
||||
@ -363,13 +363,13 @@ public final class Class <T>
|
||||
|
||||
public Constructor[] getDeclaredConstructors() {
|
||||
Constructor[] array = new Constructor[countConstructors(false)];
|
||||
if (methodTable != null) {
|
||||
avian.SystemClassLoader.link(this);
|
||||
if (vmClass.methodTable != null) {
|
||||
SystemClassLoader.link(vmClass);
|
||||
|
||||
int index = 0;
|
||||
for (int i = 0; i < methodTable.length; ++i) {
|
||||
if (methodTable[i].getName().equals("<init>")) {
|
||||
array[index++] = new Constructor(methodTable[i]);
|
||||
for (int i = 0; i < vmClass.methodTable.length; ++i) {
|
||||
if (Method.getName(vmClass.methodTable[i]).equals("<init>")) {
|
||||
array[index++] = new Constructor(new Method(vmClass.methodTable[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -379,15 +379,15 @@ public final class Class <T>
|
||||
|
||||
public Constructor[] getConstructors() {
|
||||
Constructor[] array = new Constructor[countConstructors(true)];
|
||||
if (methodTable != null) {
|
||||
avian.SystemClassLoader.link(this);
|
||||
if (vmClass.methodTable != null) {
|
||||
SystemClassLoader.link(vmClass);
|
||||
|
||||
int index = 0;
|
||||
for (int i = 0; i < methodTable.length; ++i) {
|
||||
if (((methodTable[i].getModifiers() & Modifier.PUBLIC) != 0)
|
||||
&& methodTable[i].getName().equals("<init>"))
|
||||
for (int i = 0; i < vmClass.methodTable.length; ++i) {
|
||||
if (((vmClass.methodTable[i].flags & Modifier.PUBLIC) != 0)
|
||||
&& 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() {
|
||||
if (fieldTable != null) {
|
||||
Field[] array = new Field[fieldTable.length];
|
||||
System.arraycopy(fieldTable, 0, array, 0, fieldTable.length);
|
||||
if (vmClass.fieldTable != null) {
|
||||
Field[] array = new Field[vmClass.fieldTable.length];
|
||||
for (int i = 0; i < vmClass.fieldTable.length; ++i) {
|
||||
array[i] = new Field(vmClass.fieldTable[i]);
|
||||
}
|
||||
return array;
|
||||
} else {
|
||||
return new Field[0];
|
||||
@ -407,9 +409,9 @@ public final class Class <T>
|
||||
|
||||
private int countPublicFields() {
|
||||
int count = 0;
|
||||
if (fieldTable != null) {
|
||||
for (int i = 0; i < fieldTable.length; ++i) {
|
||||
if (((fieldTable[i].getModifiers() & Modifier.PUBLIC)) != 0) {
|
||||
if (vmClass.fieldTable != null) {
|
||||
for (int i = 0; i < vmClass.fieldTable.length; ++i) {
|
||||
if (((vmClass.fieldTable[i].flags & Modifier.PUBLIC)) != 0) {
|
||||
++ count;
|
||||
}
|
||||
}
|
||||
@ -419,13 +421,13 @@ public final class Class <T>
|
||||
|
||||
public Field[] getFields() {
|
||||
Field[] array = new Field[countPublicFields()];
|
||||
if (fieldTable != null) {
|
||||
avian.SystemClassLoader.link(this);
|
||||
if (vmClass.fieldTable != null) {
|
||||
SystemClassLoader.link(vmClass);
|
||||
|
||||
int ai = 0;
|
||||
for (int i = 0; i < fieldTable.length; ++i) {
|
||||
if (((fieldTable[i].getModifiers() & Modifier.PUBLIC)) != 0) {
|
||||
array[ai++] = fieldTable[i];
|
||||
for (int i = 0; i < vmClass.fieldTable.length; ++i) {
|
||||
if (((vmClass.fieldTable[i].flags & Modifier.PUBLIC)) != 0) {
|
||||
array[ai++] = new Field(vmClass.fieldTable[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -434,11 +436,12 @@ public final class Class <T>
|
||||
|
||||
private int countMethods(boolean publicOnly) {
|
||||
int count = 0;
|
||||
if (methodTable != null) {
|
||||
for (int i = 0; i < methodTable.length; ++i) {
|
||||
if (vmClass.methodTable != null) {
|
||||
for (int i = 0; i < vmClass.methodTable.length; ++i) {
|
||||
if (((! publicOnly)
|
||||
|| ((methodTable[i].getModifiers() & Modifier.PUBLIC)) != 0)
|
||||
&& (! methodTable[i].getName().startsWith("<")))
|
||||
|| ((vmClass.methodTable[i].flags & Modifier.PUBLIC))
|
||||
!= 0)
|
||||
&& (! Method.getName(vmClass.methodTable[i]).startsWith("<")))
|
||||
{
|
||||
++ count;
|
||||
}
|
||||
@ -449,13 +452,13 @@ public final class Class <T>
|
||||
|
||||
public Method[] getDeclaredMethods() {
|
||||
Method[] array = new Method[countMethods(false)];
|
||||
if (methodTable != null) {
|
||||
avian.SystemClassLoader.link(this);
|
||||
if (vmClass.methodTable != null) {
|
||||
SystemClassLoader.link(vmClass);
|
||||
|
||||
int ai = 0;
|
||||
for (int i = 0; i < methodTable.length; ++i) {
|
||||
if (! methodTable[i].getName().startsWith("<")) {
|
||||
array[ai++] = methodTable[i];
|
||||
for (int i = 0; i < vmClass.methodTable.length; ++i) {
|
||||
if (! Method.getName(vmClass.methodTable[i]).startsWith("<")) {
|
||||
array[ai++] = new Method(vmClass.methodTable[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -465,15 +468,15 @@ public final class Class <T>
|
||||
|
||||
public Method[] getMethods() {
|
||||
Method[] array = new Method[countMethods(true)];
|
||||
if (methodTable != null) {
|
||||
avian.SystemClassLoader.link(this);
|
||||
if (vmClass.methodTable != null) {
|
||||
SystemClassLoader.link(vmClass);
|
||||
|
||||
int index = 0;
|
||||
for (int i = 0; i < methodTable.length; ++i) {
|
||||
if (((methodTable[i].getModifiers() & Modifier.PUBLIC) != 0)
|
||||
&& (! methodTable[i].getName().startsWith("<")))
|
||||
for (int i = 0; i < vmClass.methodTable.length; ++i) {
|
||||
if (((vmClass.methodTable[i].flags & Modifier.PUBLIC) != 0)
|
||||
&& (! 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() {
|
||||
if (interfaceTable != null) {
|
||||
avian.SystemClassLoader.link(this);
|
||||
if (vmClass.interfaceTable != null) {
|
||||
SystemClassLoader.link(vmClass);
|
||||
|
||||
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) {
|
||||
array[i] = (Class) interfaceTable[i * stride];
|
||||
array[i] = SystemClassLoader.getClass
|
||||
((VMClass) vmClass.interfaceTable[i * stride]);
|
||||
}
|
||||
return array;
|
||||
} else {
|
||||
@ -509,36 +513,41 @@ public final class Class <T>
|
||||
}
|
||||
|
||||
public ClassLoader getClassLoader() {
|
||||
return loader;
|
||||
return vmClass.loader;
|
||||
}
|
||||
|
||||
public int getModifiers() {
|
||||
return flags;
|
||||
return vmClass.flags;
|
||||
}
|
||||
|
||||
public boolean isInterface() {
|
||||
return (flags & Modifier.INTERFACE) != 0;
|
||||
return (vmClass.flags & Modifier.INTERFACE) != 0;
|
||||
}
|
||||
|
||||
public Class getSuperclass() {
|
||||
return super_;
|
||||
return SystemClassLoader.getClass(vmClass.super_);
|
||||
}
|
||||
|
||||
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) {
|
||||
return o != null && isAssignableFrom(o.getClass());
|
||||
return isInstance(vmClass, o);
|
||||
}
|
||||
|
||||
public boolean isPrimitive() {
|
||||
return (vmFlags & PrimitiveFlag) != 0;
|
||||
return (vmClass.vmFlags & PrimitiveFlag) != 0;
|
||||
}
|
||||
|
||||
public URL getResource(String path) {
|
||||
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('/');
|
||||
if (index >= 0) {
|
||||
path = name.substring(0, index) + "/" + path;
|
||||
@ -573,11 +582,11 @@ public final class Class <T>
|
||||
}
|
||||
|
||||
public Object[] getSigners() {
|
||||
return addendum == null ? null : addendum.signers;
|
||||
return vmClass.addendum.signers;
|
||||
}
|
||||
|
||||
public Package getPackage() {
|
||||
if ((vmFlags & PrimitiveFlag) != 0 || isArray()) {
|
||||
if ((vmClass.vmFlags & PrimitiveFlag) != 0 || isArray()) {
|
||||
return null;
|
||||
} else {
|
||||
String name = getCanonicalName();
|
||||
@ -597,25 +606,25 @@ public final class Class <T>
|
||||
return getAnnotation(class_) != null;
|
||||
}
|
||||
|
||||
private Annotation getAnnotation(Object[] a) {
|
||||
private static Annotation getAnnotation(VMClass c, Object[] a) {
|
||||
if (a[0] == null) {
|
||||
a[0] = Proxy.newProxyInstance
|
||||
(loader, new Class[] { (Class) a[1] },
|
||||
(c.loader, new Class[] { (Class) a[1] },
|
||||
new AnnotationInvocationHandler(a));
|
||||
}
|
||||
return (Annotation) a[0];
|
||||
}
|
||||
|
||||
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) {
|
||||
avian.SystemClassLoader.link(c, c.loader);
|
||||
SystemClassLoader.link(c, c.loader);
|
||||
|
||||
Object[] table = (Object[]) c.addendum.annotationTable;
|
||||
for (int i = 0; i < table.length; ++i) {
|
||||
Object[] a = (Object[]) table[i];
|
||||
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() {
|
||||
if (addendum != null && addendum.annotationTable != null) {
|
||||
avian.SystemClassLoader.link(this);
|
||||
if (vmClass.addendum.annotationTable != null) {
|
||||
SystemClassLoader.link(vmClass);
|
||||
|
||||
Object[] table = (Object[]) addendum.annotationTable;
|
||||
Object[] table = (Object[]) vmClass.addendum.annotationTable;
|
||||
Annotation[] array = new Annotation[table.length];
|
||||
for (int i = 0; i < table.length; ++i) {
|
||||
array[i] = getAnnotation((Object[]) table[i]);
|
||||
array[i] = getAnnotation(vmClass, (Object[]) table[i]);
|
||||
}
|
||||
return array;
|
||||
} else {
|
||||
@ -640,7 +649,7 @@ public final class Class <T>
|
||||
|
||||
private int countAnnotations() {
|
||||
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) {
|
||||
count += ((Object[]) c.addendum.annotationTable).length;
|
||||
}
|
||||
@ -651,11 +660,11 @@ public final class Class <T>
|
||||
public Annotation[] getAnnotations() {
|
||||
Annotation[] array = new Annotation[countMethods(true)];
|
||||
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) {
|
||||
Object[] table = (Object[]) c.addendum.annotationTable;
|
||||
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());
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,8 @@ public abstract class ClassLoader {
|
||||
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 {
|
||||
@ -87,7 +88,7 @@ public abstract class ClassLoader {
|
||||
}
|
||||
|
||||
protected void resolveClass(Class c) {
|
||||
avian.SystemClassLoader.link(c, this);
|
||||
avian.SystemClassLoader.link(c.vmClass, this);
|
||||
}
|
||||
|
||||
private ClassLoader getParent() {
|
||||
|
@ -27,7 +27,11 @@ public class Object {
|
||||
|
||||
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();
|
||||
|
||||
|
@ -78,13 +78,13 @@ public class Constructor<T> extends AccessibleObject
|
||||
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)
|
||||
throws InvocationTargetException, InstantiationException,
|
||||
IllegalAccessException
|
||||
{
|
||||
T v = make(method.getDeclaringClass());
|
||||
T v = (T) make(method.getDeclaringClass().vmClass);
|
||||
method.invoke(v, arguments);
|
||||
return v;
|
||||
}
|
||||
|
@ -10,7 +10,9 @@
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
import avian.VMField;
|
||||
import avian.AnnotationInvocationHandler;
|
||||
import avian.SystemClassLoader;
|
||||
|
||||
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 ObjectField = 9;
|
||||
|
||||
private byte vmFlags;
|
||||
private byte code;
|
||||
private short flags;
|
||||
private short offset;
|
||||
private byte[] name;
|
||||
public byte[] spec;
|
||||
public avian.Addendum addendum;
|
||||
private Class<T> class_;
|
||||
private final VMField vmField;
|
||||
private boolean accessible = true;
|
||||
|
||||
private Field() { }
|
||||
public Field(VMField vmField) {
|
||||
this.vmField = vmField;
|
||||
}
|
||||
|
||||
public boolean isAccessible() {
|
||||
return (vmFlags & Accessible) != 0;
|
||||
return accessible;
|
||||
}
|
||||
|
||||
public void setAccessible(boolean v) {
|
||||
if (v) vmFlags |= Accessible; else vmFlags &= ~Accessible;
|
||||
accessible = v;
|
||||
}
|
||||
|
||||
public Class<T> getDeclaringClass() {
|
||||
return class_;
|
||||
return SystemClassLoader.getClass(vmField.class_);
|
||||
}
|
||||
|
||||
public int getModifiers() {
|
||||
return flags;
|
||||
return vmField.flags;
|
||||
}
|
||||
|
||||
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() {
|
||||
return Class.forCanonicalName(class_.getClassLoader(),
|
||||
new String(spec, 0, spec.length - 1, false));
|
||||
return Class.forCanonicalName
|
||||
(vmField.class_.loader,
|
||||
new String(vmField.spec, 0, vmField.spec.length - 1, false));
|
||||
}
|
||||
|
||||
public Object get(Object instance) throws IllegalAccessException {
|
||||
Object target;
|
||||
if ((flags & Modifier.STATIC) != 0) {
|
||||
target = class_.staticTable();
|
||||
} else if (class_.isInstance(instance)) {
|
||||
if ((vmField.flags & Modifier.STATIC) != 0) {
|
||||
target = vmField.class_.staticTable;
|
||||
} else if (Class.isInstance(vmField.class_, instance)) {
|
||||
target = instance;
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
switch (code) {
|
||||
switch (vmField.code) {
|
||||
case ByteField:
|
||||
return Byte.valueOf((byte) getPrimitive(target, code, offset));
|
||||
return Byte.valueOf
|
||||
((byte) getPrimitive(target, vmField.code, vmField.offset));
|
||||
|
||||
case BooleanField:
|
||||
return Boolean.valueOf(getPrimitive(target, code, offset) != 0);
|
||||
return Boolean.valueOf
|
||||
(getPrimitive(target, vmField.code, vmField.offset) != 0);
|
||||
|
||||
case CharField:
|
||||
return Character.valueOf((char) getPrimitive(target, code, offset));
|
||||
return Character.valueOf
|
||||
((char) getPrimitive(target, vmField.code, vmField.offset));
|
||||
|
||||
case ShortField:
|
||||
return Short.valueOf((short) getPrimitive(target, code, offset));
|
||||
return Short.valueOf
|
||||
((short) getPrimitive(target, vmField.code, vmField.offset));
|
||||
|
||||
case IntField:
|
||||
return Integer.valueOf((int) getPrimitive(target, code, offset));
|
||||
return Integer.valueOf
|
||||
((int) getPrimitive(target, vmField.code, vmField.offset));
|
||||
|
||||
case LongField:
|
||||
return Long.valueOf((int) getPrimitive(target, code, offset));
|
||||
return Long.valueOf
|
||||
((int) getPrimitive(target, vmField.code, vmField.offset));
|
||||
|
||||
case FloatField:
|
||||
return Float.valueOf
|
||||
(Float.intBitsToFloat((int) getPrimitive(target, code, offset)));
|
||||
(Float.intBitsToFloat
|
||||
((int) getPrimitive(target, vmField.code, vmField.offset)));
|
||||
|
||||
case DoubleField:
|
||||
return Double.valueOf
|
||||
(Double.longBitsToDouble(getPrimitive(target, code, offset)));
|
||||
(Double.longBitsToDouble
|
||||
(getPrimitive(target, vmField.code, vmField.offset)));
|
||||
|
||||
case ObjectField:
|
||||
return getObject(target, offset);
|
||||
return getObject(target, vmField.offset);
|
||||
|
||||
default:
|
||||
throw new Error();
|
||||
@ -143,56 +154,58 @@ public class Field<T> extends AccessibleObject {
|
||||
throws IllegalAccessException
|
||||
{
|
||||
Object target;
|
||||
if ((flags & Modifier.STATIC) != 0) {
|
||||
target = class_.staticTable();
|
||||
} else if (class_.isInstance(instance)) {
|
||||
if ((vmField.flags & Modifier.STATIC) != 0) {
|
||||
target = vmField.class_.staticTable;
|
||||
} else if (Class.isInstance(vmField.class_, instance)) {
|
||||
target = instance;
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
switch (code) {
|
||||
switch (vmField.code) {
|
||||
case ByteField:
|
||||
setPrimitive(target, code, offset, (Byte) value);
|
||||
setPrimitive(target, vmField.code, vmField.offset, (Byte) value);
|
||||
break;
|
||||
|
||||
case BooleanField:
|
||||
setPrimitive(target, code, offset, ((Boolean) value) ? 1 : 0);
|
||||
setPrimitive
|
||||
(target, vmField.code, vmField.offset, ((Boolean) value) ? 1 : 0);
|
||||
break;
|
||||
|
||||
case CharField:
|
||||
setPrimitive(target, code, offset, (Character) value);
|
||||
setPrimitive(target, vmField.code, vmField.offset, (Character) value);
|
||||
break;
|
||||
|
||||
case ShortField:
|
||||
setPrimitive(target, code, offset, (Short) value);
|
||||
setPrimitive(target, vmField.code, vmField.offset, (Short) value);
|
||||
break;
|
||||
|
||||
case IntField:
|
||||
setPrimitive(target, code, offset, (Integer) value);
|
||||
setPrimitive(target, vmField.code, vmField.offset, (Integer) value);
|
||||
break;
|
||||
|
||||
case LongField:
|
||||
setPrimitive(target, code, offset, (Long) value);
|
||||
setPrimitive(target, vmField.code, vmField.offset, (Long) value);
|
||||
break;
|
||||
|
||||
case FloatField:
|
||||
setPrimitive(target, code, offset,
|
||||
setPrimitive(target, vmField.code, vmField.offset,
|
||||
Float.floatToRawIntBits((Float) value));
|
||||
break;
|
||||
|
||||
case DoubleField:
|
||||
setPrimitive(target, code, offset,
|
||||
setPrimitive(target, vmField.code, vmField.offset,
|
||||
Double.doubleToRawLongBits((Double) value));
|
||||
break;
|
||||
|
||||
case ObjectField:
|
||||
if (value == null || getType().isInstance(value)) {
|
||||
setObject(target, offset, value);
|
||||
setObject(target, vmField.offset, value);
|
||||
} else {
|
||||
throw new IllegalArgumentException
|
||||
("needed " + getType() + ", got " + value.getClass().getName() +
|
||||
" when setting " + class_.getName() + "." + getName());
|
||||
("needed " + getType() + ", got "
|
||||
+ Class.getName(Class.vmClass(target)) +
|
||||
" when setting " + Class.getName(vmField.class_) + "." + getName());
|
||||
}
|
||||
break;
|
||||
|
||||
@ -204,15 +217,15 @@ public class Field<T> extends AccessibleObject {
|
||||
private Annotation getAnnotation(Object[] a) {
|
||||
if (a[0] == null) {
|
||||
a[0] = Proxy.newProxyInstance
|
||||
(class_.getClassLoader(), new Class[] { (Class) a[1] },
|
||||
(vmField.class_.loader, new Class[] { (Class) a[1] },
|
||||
new AnnotationInvocationHandler(a));
|
||||
}
|
||||
return (Annotation) a[0];
|
||||
}
|
||||
|
||||
public <T extends Annotation> T getAnnotation(Class<T> class_) {
|
||||
if (addendum != null && addendum.annotationTable != null) {
|
||||
Object[] table = (Object[]) addendum.annotationTable;
|
||||
if (vmField.addendum.annotationTable != null) {
|
||||
Object[] table = (Object[]) vmField.addendum.annotationTable;
|
||||
for (int i = 0; i < table.length; ++i) {
|
||||
Object[] a = (Object[]) table[i];
|
||||
if (a[1] == class_) {
|
||||
@ -224,8 +237,8 @@ public class Field<T> extends AccessibleObject {
|
||||
}
|
||||
|
||||
public Annotation[] getAnnotations() {
|
||||
if (addendum != null && addendum.annotationTable != null) {
|
||||
Object[] table = (Object[]) addendum.annotationTable;
|
||||
if (vmField.addendum.annotationTable != null) {
|
||||
Object[] table = (Object[]) vmField.addendum.annotationTable;
|
||||
Annotation[] array = new Annotation[table.length];
|
||||
for (int i = 0; i < table.length; ++i) {
|
||||
array[i] = getAnnotation((Object[]) table[i]);
|
||||
@ -255,9 +268,4 @@ public class Field<T> extends AccessibleObject {
|
||||
|
||||
private static native void setObject
|
||||
(Object instance, int offset, Object value);
|
||||
|
||||
public static class Addendum {
|
||||
public Object pool;
|
||||
public Object annotationTable;
|
||||
}
|
||||
}
|
||||
|
@ -10,53 +10,54 @@
|
||||
|
||||
package java.lang.reflect;
|
||||
|
||||
import avian.VMMethod;
|
||||
import avian.AnnotationInvocationHandler;
|
||||
import avian.SystemClassLoader;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
public class Method<T> extends AccessibleObject
|
||||
implements Member, GenericDeclaration
|
||||
{
|
||||
private byte vmFlags;
|
||||
private byte returnCode;
|
||||
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 final VMMethod vmMethod;
|
||||
private boolean accessible;
|
||||
|
||||
private Method() { }
|
||||
public Method(VMMethod vmMethod) {
|
||||
this.vmMethod = vmMethod;
|
||||
}
|
||||
|
||||
public boolean isAccessible() {
|
||||
return (vmFlags & Accessible) != 0;
|
||||
return accessible;
|
||||
}
|
||||
|
||||
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() {
|
||||
return class_;
|
||||
return SystemClassLoader.getClass(vmMethod.class_);
|
||||
}
|
||||
|
||||
public int getModifiers() {
|
||||
return flags;
|
||||
return vmMethod.flags;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return new String(name, 0, name.length - 1, false);
|
||||
return getName(vmMethod);
|
||||
}
|
||||
|
||||
String getSpec() {
|
||||
return new String(spec, 0, spec.length - 1, false);
|
||||
public static String getName(VMMethod vmMethod) {
|
||||
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) {
|
||||
@ -67,12 +68,17 @@ public class Method<T> extends AccessibleObject
|
||||
}
|
||||
|
||||
public Class[] getParameterTypes() {
|
||||
int count = parameterCount;
|
||||
return getParameterTypes(vmMethod);
|
||||
}
|
||||
|
||||
public static Class[] getParameterTypes(VMMethod vmMethod) {
|
||||
int count = vmMethod.parameterCount;
|
||||
|
||||
Class[] types = new Class[count];
|
||||
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 {
|
||||
for (int i = 0; i < spec.length(); ++i) {
|
||||
@ -83,7 +89,7 @@ public class Method<T> extends AccessibleObject
|
||||
int start = i + 1;
|
||||
i = next(';', spec, start);
|
||||
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 == '[') {
|
||||
int start = i;
|
||||
while (spec.charAt(i) == '[') ++i;
|
||||
@ -92,16 +98,16 @@ public class Method<T> extends AccessibleObject
|
||||
i = next(';', spec, i + 1);
|
||||
String name = spec.substring(start, i).replace('/', '.');
|
||||
types[index++] = Class.forName
|
||||
(name, true, class_.getClassLoader());
|
||||
(name, true, vmMethod.class_.loader);
|
||||
} else {
|
||||
String name = spec.substring(start, i + 1);
|
||||
types[index++] = Class.forCanonicalName
|
||||
(class_.getClassLoader(), name);
|
||||
(vmMethod.class_.loader, name);
|
||||
}
|
||||
} else {
|
||||
String name = spec.substring(i, i + 1);
|
||||
types[index++] = Class.forCanonicalName
|
||||
(class_.getClassLoader(), name);
|
||||
(vmMethod.class_.loader, name);
|
||||
}
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
@ -114,38 +120,43 @@ public class Method<T> extends AccessibleObject
|
||||
public Object invoke(Object instance, Object ... arguments)
|
||||
throws InvocationTargetException, IllegalAccessException
|
||||
{
|
||||
if ((flags & Modifier.STATIC) != 0 || class_.isInstance(instance)) {
|
||||
if ((flags & Modifier.STATIC) != 0) {
|
||||
if ((vmMethod.flags & Modifier.STATIC) != 0
|
||||
|| Class.isInstance(vmMethod.class_, instance))
|
||||
{
|
||||
if ((vmMethod.flags & Modifier.STATIC) != 0) {
|
||||
instance = null;
|
||||
}
|
||||
|
||||
if (arguments == null) {
|
||||
if (parameterCount > 0) {
|
||||
if (vmMethod.parameterCount > 0) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
arguments = new Object[0];
|
||||
}
|
||||
|
||||
if (arguments.length == parameterCount) {
|
||||
return invoke(this, instance, arguments);
|
||||
if (arguments.length == vmMethod.parameterCount) {
|
||||
return invoke(vmMethod, instance, arguments);
|
||||
} else {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
} else {
|
||||
// System.out.println
|
||||
// (getDeclaringClass() + "." + getName() + " flags: " + vmMethod.flags + " vm flags: " + vmMethod.vmFlags + " return code: " + vmMethod.returnCode);
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
private static native Object invoke(Method method, Object instance,
|
||||
private static native Object invoke(VMMethod method, Object instance,
|
||||
Object ... arguments)
|
||||
throws InvocationTargetException, IllegalAccessException;
|
||||
|
||||
public Class getReturnType() {
|
||||
for (int i = 0; i < spec.length - 1; ++i) {
|
||||
if (spec[i] == ')') {
|
||||
for (int i = 0; i < vmMethod.spec.length - 1; ++i) {
|
||||
if (vmMethod.spec[i] == ')') {
|
||||
return Class.forCanonicalName
|
||||
(class_.getClassLoader(),
|
||||
new String(spec, i + 1, spec.length - i - 2, false));
|
||||
(vmMethod.class_.loader,
|
||||
new String
|
||||
(vmMethod.spec, i + 1, vmMethod.spec.length - i - 2, false));
|
||||
}
|
||||
}
|
||||
throw new RuntimeException();
|
||||
@ -154,15 +165,15 @@ public class Method<T> extends AccessibleObject
|
||||
private Annotation getAnnotation(Object[] a) {
|
||||
if (a[0] == null) {
|
||||
a[0] = Proxy.newProxyInstance
|
||||
(class_.getClassLoader(), new Class[] { (Class) a[1] },
|
||||
(vmMethod.class_.loader, new Class[] { (Class) a[1] },
|
||||
new AnnotationInvocationHandler(a));
|
||||
}
|
||||
return (Annotation) a[0];
|
||||
}
|
||||
|
||||
public <T extends Annotation> T getAnnotation(Class<T> class_) {
|
||||
if (addendum != null && addendum.annotationTable != null) {
|
||||
Object[] table = (Object[]) addendum.annotationTable;
|
||||
if (vmMethod.addendum.annotationTable != null) {
|
||||
Object[] table = (Object[]) vmMethod.addendum.annotationTable;
|
||||
for (int i = 0; i < table.length; ++i) {
|
||||
Object[] a = (Object[]) table[i];
|
||||
if (a[1] == class_) {
|
||||
@ -174,8 +185,8 @@ public class Method<T> extends AccessibleObject
|
||||
}
|
||||
|
||||
public Annotation[] getAnnotations() {
|
||||
if (addendum != null && addendum.annotationTable != null) {
|
||||
Object[] table = (Object[]) addendum.annotationTable;
|
||||
if (vmMethod.addendum.annotationTable != null) {
|
||||
Object[] table = (Object[]) vmMethod.addendum.annotationTable;
|
||||
Annotation[] array = new Annotation[table.length];
|
||||
for (int i = 0; i < table.length; ++i) {
|
||||
array[i] = getAnnotation((Object[]) table[i]);
|
||||
|
@ -45,12 +45,14 @@ public class Proxy {
|
||||
private static final int getfield = 0xb4;
|
||||
private static final int iload = 0x15;
|
||||
private static final int invokeinterface = 0xb9;
|
||||
private static final int invokespecial = 0xb7;
|
||||
private static final int invokestatic = 0xb8;
|
||||
private static final int invokevirtual = 0xb6;
|
||||
private static final int ireturn = 0xac;
|
||||
private static final int ldc_w = 0x13;
|
||||
private static final int lload = 0x16;
|
||||
private static final int lreturn = 0xad;
|
||||
private static final int new_ = 0xbb;
|
||||
private static final int pop = 0x57;
|
||||
private static final int putfield = 0xb5;
|
||||
private static final int return_ = 0xb1;
|
||||
@ -172,15 +174,26 @@ public class Proxy {
|
||||
|
||||
write1(out, aload_0);
|
||||
|
||||
write1(out, new_);
|
||||
write2(out, poolAddClass(pool, "java/lang/reflect/Method") + 1);
|
||||
write1(out, dup);
|
||||
write1(out, ldc_w);
|
||||
write2(out, poolAddClass(pool, className) + 1);
|
||||
write1(out, getfield);
|
||||
write2(out, poolAddFieldRef
|
||||
(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);
|
||||
write2(out, poolAddInteger(pool, index) + 1);
|
||||
write1(out, aaload);
|
||||
write1(out, invokespecial);
|
||||
write2(out, poolAddMethodRef
|
||||
(pool, "java/lang/reflect/Method",
|
||||
"<init>", "(Lavian/VMMethod;)V") + 1);
|
||||
|
||||
write1(out, ldc_w);
|
||||
write2(out, poolAddInteger(pool, parameterCount) + 1);
|
||||
@ -434,22 +447,22 @@ public class Proxy {
|
||||
interfaceIndexes[i] = poolAddClass(pool, interfaces[i].getName());
|
||||
}
|
||||
|
||||
Map<String,Method> virtualMap = new HashMap();
|
||||
Map<String,avian.VMMethod> virtualMap = new HashMap();
|
||||
for (Class c: interfaces) {
|
||||
Method[] ivtable = c.virtualTable;
|
||||
avian.VMMethod[] ivtable = c.vmClass.virtualTable;
|
||||
if (ivtable != null) {
|
||||
for (Method m: ivtable) {
|
||||
virtualMap.put(m.getName() + m.getSpec(), m);
|
||||
for (avian.VMMethod m: ivtable) {
|
||||
virtualMap.put(Method.getName(m) + Method.getSpec(m), m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MethodData[] methodTable = new MethodData[virtualMap.size() + 1];
|
||||
{ int i = 0;
|
||||
for (Method m: virtualMap.values()) {
|
||||
for (avian.VMMethod m: virtualMap.values()) {
|
||||
methodTable[i] = new MethodData
|
||||
(poolAddUtf8(pool, m.getName()),
|
||||
poolAddUtf8(pool, m.getSpec()),
|
||||
(poolAddUtf8(pool, Method.getName(m)),
|
||||
poolAddUtf8(pool, Method.getSpec(m)),
|
||||
makeInvokeCode(pool, name, m.spec, m.parameterCount,
|
||||
m.parameterFootprint, i));
|
||||
++ i;
|
||||
@ -501,8 +514,9 @@ public class Proxy {
|
||||
write2(out, 0); // attribute count
|
||||
|
||||
byte[] classData = out.toByteArray();
|
||||
return avian.SystemClassLoader.defineClass
|
||||
(loader, classData, 0, classData.length);
|
||||
return avian.SystemClassLoader.getClass
|
||||
(avian.SystemClassLoader.defineVMClass
|
||||
(loader, classData, 0, classData.length));
|
||||
}
|
||||
|
||||
public static Object newProxyInstance(ClassLoader loader,
|
||||
|
@ -94,13 +94,12 @@ public abstract class ResourceBundle {
|
||||
}
|
||||
|
||||
public static ResourceBundle getBundle(String name, Locale locale) {
|
||||
return getBundle(name, locale,
|
||||
Method.getCaller().getDeclaringClass().getClassLoader());
|
||||
return getBundle(name, locale, Method.getCaller().class_.loader);
|
||||
}
|
||||
|
||||
public static ResourceBundle getBundle(String name) {
|
||||
return getBundle(name, Locale.getDefault(),
|
||||
Method.getCaller().getDeclaringClass().getClassLoader());
|
||||
return getBundle
|
||||
(name, Locale.getDefault(), Method.getCaller().class_.loader);
|
||||
}
|
||||
|
||||
public Object getObject(String key) {
|
||||
|
@ -107,15 +107,15 @@ public class Logger {
|
||||
return logger.getLevel();
|
||||
}
|
||||
|
||||
private void log(Level level, Method caller, String message,
|
||||
private void log(Level level, avian.VMMethod caller, String message,
|
||||
Throwable exception) {
|
||||
|
||||
if (level.intValue() < getEffectiveLevel().intValue()) {
|
||||
return;
|
||||
}
|
||||
LogRecord r = new LogRecord
|
||||
(name, caller == null ? "<unknown>" : caller.getName(), level, message,
|
||||
exception);
|
||||
(name, caller == null ? "<unknown>" : Method.getName(caller), level,
|
||||
message, exception);
|
||||
publish(r);
|
||||
}
|
||||
|
||||
|
@ -97,12 +97,12 @@ Avian_java_lang_Object_toString
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT int64_t JNICALL
|
||||
Avian_java_lang_Object_getClass
|
||||
Avian_java_lang_Object_getVMClass
|
||||
(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
|
||||
@ -183,7 +183,15 @@ Avian_avian_SystemClassLoader_releaseClassLock
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
object loader = reinterpret_cast<object>(arguments[0]);
|
||||
@ -214,25 +222,25 @@ Avian_avian_SystemClassLoader_defineClass
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT int64_t JNICALL
|
||||
Avian_avian_SystemClassLoader_reallyFindLoadedClass
|
||||
Avian_avian_SystemClassLoader_findLoadedVMClass
|
||||
(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);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT int64_t JNICALL
|
||||
Avian_avian_SystemClassLoader_findClass
|
||||
Avian_avian_SystemClassLoader_findVMClass
|
||||
(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);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT int64_t JNICALL
|
||||
Avian_avian_SystemClassLoader_resolveClass
|
||||
Avian_avian_SystemClassLoader_resolveVMClass
|
||||
(Thread* t, object, uintptr_t* arguments)
|
||||
{
|
||||
object loader = reinterpret_cast<object>(arguments[0]);
|
||||
@ -245,7 +253,7 @@ extern "C" JNIEXPORT int64_t JNICALL
|
||||
Avian_avian_SystemClassLoader_resourceExists
|
||||
(Thread* t, object, uintptr_t* arguments)
|
||||
{
|
||||
object name = reinterpret_cast<object>(arguments[1]);
|
||||
object name = reinterpret_cast<object>(arguments[0]);
|
||||
|
||||
if (LIKELY(name)) {
|
||||
RUNTIME_ARRAY(char, n, stringLength(t, name) + 1);
|
||||
|
@ -4370,7 +4370,11 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
||||
object class_ = resolveClassInPool(t, context->method, index - 1);
|
||||
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 {
|
||||
frame->pushObject(frame->append(v));
|
||||
}
|
||||
@ -6160,9 +6164,6 @@ invokeNativeSlow(MyThread* t, object method)
|
||||
{
|
||||
PROTECT(t, method);
|
||||
|
||||
object class_ = methodClass(t, method);
|
||||
PROTECT(t, class_);
|
||||
|
||||
unsigned footprint = methodParameterFootprint(t, method) + 1;
|
||||
if (methodFlags(t, method) & ACC_STATIC) {
|
||||
++ footprint;
|
||||
@ -6181,9 +6182,13 @@ invokeNativeSlow(MyThread* t, object method)
|
||||
+ t->arch->frameFooterSize()
|
||||
+ t->arch->frameReturnAddressSize();
|
||||
|
||||
object jclass = 0;
|
||||
PROTECT(t, jclass);
|
||||
|
||||
if (methodFlags(t, method) & ACC_STATIC) {
|
||||
jclass = getJClass(t, methodClass(t, method));
|
||||
RUNTIME_ARRAY_BODY(args)[argOffset++]
|
||||
= reinterpret_cast<uintptr_t>(&class_);
|
||||
= reinterpret_cast<uintptr_t>(&jclass);
|
||||
} else {
|
||||
RUNTIME_ARRAY_BODY(args)[argOffset++]
|
||||
= reinterpret_cast<uintptr_t>(sp++);
|
||||
|
@ -2224,7 +2224,11 @@ interpret(Thread* t)
|
||||
(t, frameMethod(t, frame), index - 1);
|
||||
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 {
|
||||
pushObject(t, v);
|
||||
}
|
||||
|
@ -248,7 +248,9 @@ FindClass(Thread* t, const char* name)
|
||||
object n = makeByteArray(t, strlen(name) + 1);
|
||||
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
|
||||
@ -270,7 +272,7 @@ ThrowNew(Thread* t, jclass c, const char* message)
|
||||
object trace = makeTrace(t);
|
||||
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, ThrowableTrace, trace);
|
||||
|
||||
@ -316,7 +318,7 @@ GetObjectClass(Thread* t, jobject o)
|
||||
{
|
||||
ENTER(t, Thread::ActiveState);
|
||||
|
||||
return makeLocalReference(t, objectClass(t, *o));
|
||||
return makeLocalReference(t, getJClass(t, objectClass(t, *o)));
|
||||
}
|
||||
|
||||
jboolean JNICALL
|
||||
@ -324,7 +326,7 @@ IsInstanceOf(Thread* t, jobject o, jclass c)
|
||||
{
|
||||
ENTER(t, Thread::ActiveState);
|
||||
|
||||
return instanceOf(t, *c, *o);
|
||||
return instanceOf(t, jclassVmClass(t, *c), *o);
|
||||
}
|
||||
|
||||
object
|
||||
@ -334,7 +336,7 @@ findMethod(Thread* t, jclass c, const char* name, const char* spec)
|
||||
PROTECT(t, n);
|
||||
|
||||
object s = makeByteArray(t, "%s", spec);
|
||||
return vm::findMethod(t, *c, n, s);
|
||||
return vm::findMethod(t, jclassVmClass(t, *c), n, s);
|
||||
}
|
||||
|
||||
jint
|
||||
@ -395,7 +397,7 @@ NewObjectV(Thread* t, jclass c, jmethodID m, va_list a)
|
||||
{
|
||||
ENTER(t, Thread::ActiveState);
|
||||
|
||||
object o = make(t, *c);
|
||||
object o = make(t, jclassVmClass(t, *c));
|
||||
PROTECT(t, o);
|
||||
|
||||
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);
|
||||
|
||||
object field = resolveField(t, *c, name, spec);
|
||||
object field = resolveField(t, jclassVmClass(t, *c), name, spec);
|
||||
if (UNLIKELY(t->exception)) return 0;
|
||||
|
||||
return fieldOffset(t, field);
|
||||
@ -886,7 +888,7 @@ GetStaticFieldID(Thread* t, jclass c, const char* name, const char* spec)
|
||||
{
|
||||
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;
|
||||
|
||||
return fieldOffset(t, field);
|
||||
@ -1041,7 +1043,8 @@ GetStaticObjectField(Thread* t, jclass c, jfieldID field)
|
||||
{
|
||||
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
|
||||
@ -1049,7 +1052,7 @@ GetStaticBooleanField(Thread* t, jclass c, jfieldID field)
|
||||
{
|
||||
ENTER(t, Thread::ActiveState);
|
||||
|
||||
return cast<int8_t>(classStaticTable(t, *c), field);
|
||||
return cast<int8_t>(classStaticTable(t, jclassVmClass(t, *c)), field);
|
||||
}
|
||||
|
||||
jbyte JNICALL
|
||||
@ -1057,7 +1060,7 @@ GetStaticByteField(Thread* t, jclass c, jfieldID field)
|
||||
{
|
||||
ENTER(t, Thread::ActiveState);
|
||||
|
||||
return cast<int8_t>(classStaticTable(t, *c), field);
|
||||
return cast<int8_t>(classStaticTable(t, jclassVmClass(t, *c)), field);
|
||||
}
|
||||
|
||||
jchar JNICALL
|
||||
@ -1065,7 +1068,7 @@ GetStaticCharField(Thread* t, jclass c, jfieldID field)
|
||||
{
|
||||
ENTER(t, Thread::ActiveState);
|
||||
|
||||
return cast<uint16_t>(classStaticTable(t, *c), field);
|
||||
return cast<uint16_t>(classStaticTable(t, jclassVmClass(t, *c)), field);
|
||||
}
|
||||
|
||||
jshort JNICALL
|
||||
@ -1073,7 +1076,7 @@ GetStaticShortField(Thread* t, jclass c, jfieldID field)
|
||||
{
|
||||
ENTER(t, Thread::ActiveState);
|
||||
|
||||
return cast<int16_t>(classStaticTable(t, *c), field);
|
||||
return cast<int16_t>(classStaticTable(t, jclassVmClass(t, *c)), field);
|
||||
}
|
||||
|
||||
jint JNICALL
|
||||
@ -1081,7 +1084,7 @@ GetStaticIntField(Thread* t, jclass c, jfieldID field)
|
||||
{
|
||||
ENTER(t, Thread::ActiveState);
|
||||
|
||||
return cast<int32_t>(classStaticTable(t, *c), field);
|
||||
return cast<int32_t>(classStaticTable(t, jclassVmClass(t, *c)), field);
|
||||
}
|
||||
|
||||
jlong JNICALL
|
||||
@ -1089,7 +1092,7 @@ GetStaticLongField(Thread* t, jclass c, jfieldID field)
|
||||
{
|
||||
ENTER(t, Thread::ActiveState);
|
||||
|
||||
return cast<int64_t>(classStaticTable(t, *c), field);
|
||||
return cast<int64_t>(classStaticTable(t, jclassVmClass(t, *c)), field);
|
||||
}
|
||||
|
||||
jfloat JNICALL
|
||||
@ -1097,7 +1100,7 @@ GetStaticFloatField(Thread* t, jclass c, jfieldID field)
|
||||
{
|
||||
ENTER(t, Thread::ActiveState);
|
||||
|
||||
return cast<float>(classStaticTable(t, *c), field);
|
||||
return cast<float>(classStaticTable(t, jclassVmClass(t, *c)), field);
|
||||
}
|
||||
|
||||
jdouble JNICALL
|
||||
@ -1105,7 +1108,7 @@ GetStaticDoubleField(Thread* t, jclass c, jfieldID field)
|
||||
{
|
||||
ENTER(t, Thread::ActiveState);
|
||||
|
||||
return cast<double>(classStaticTable(t, *c), field);
|
||||
return cast<double>(classStaticTable(t, jclassVmClass(t, *c)), field);
|
||||
}
|
||||
|
||||
void JNICALL
|
||||
@ -1121,7 +1124,7 @@ SetStaticBooleanField(Thread* t, jclass c, jfieldID field, jboolean v)
|
||||
{
|
||||
ENTER(t, Thread::ActiveState);
|
||||
|
||||
cast<int8_t>(classStaticTable(t, *c), field) = v;
|
||||
cast<int8_t>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
|
||||
}
|
||||
|
||||
void JNICALL
|
||||
@ -1129,7 +1132,7 @@ SetStaticByteField(Thread* t, jclass c, jfieldID field, jbyte v)
|
||||
{
|
||||
ENTER(t, Thread::ActiveState);
|
||||
|
||||
cast<int8_t>(classStaticTable(t, *c), field) = v;
|
||||
cast<int8_t>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
|
||||
}
|
||||
|
||||
void JNICALL
|
||||
@ -1137,7 +1140,7 @@ SetStaticCharField(Thread* t, jclass c, jfieldID field, jchar v)
|
||||
{
|
||||
ENTER(t, Thread::ActiveState);
|
||||
|
||||
cast<uint16_t>(classStaticTable(t, *c), field) = v;
|
||||
cast<uint16_t>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
|
||||
}
|
||||
|
||||
void JNICALL
|
||||
@ -1145,7 +1148,7 @@ SetStaticShortField(Thread* t, jclass c, jfieldID field, jshort v)
|
||||
{
|
||||
ENTER(t, Thread::ActiveState);
|
||||
|
||||
cast<int16_t>(classStaticTable(t, *c), field) = v;
|
||||
cast<int16_t>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
|
||||
}
|
||||
|
||||
void JNICALL
|
||||
@ -1153,7 +1156,7 @@ SetStaticIntField(Thread* t, jclass c, jfieldID field, jint v)
|
||||
{
|
||||
ENTER(t, Thread::ActiveState);
|
||||
|
||||
cast<int32_t>(classStaticTable(t, *c), field) = v;
|
||||
cast<int32_t>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
|
||||
}
|
||||
|
||||
void JNICALL
|
||||
@ -1161,7 +1164,7 @@ SetStaticLongField(Thread* t, jclass c, jfieldID field, jlong v)
|
||||
{
|
||||
ENTER(t, Thread::ActiveState);
|
||||
|
||||
cast<int64_t>(classStaticTable(t, *c), field) = v;
|
||||
cast<int64_t>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
|
||||
}
|
||||
|
||||
void JNICALL
|
||||
@ -1169,7 +1172,7 @@ SetStaticFloatField(Thread* t, jclass c, jfieldID field, jfloat v)
|
||||
{
|
||||
ENTER(t, Thread::ActiveState);
|
||||
|
||||
cast<float>(classStaticTable(t, *c), field) = v;
|
||||
cast<float>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
|
||||
}
|
||||
|
||||
void JNICALL
|
||||
@ -1177,7 +1180,7 @@ SetStaticDoubleField(Thread* t, jclass c, jfieldID field, jdouble v)
|
||||
{
|
||||
ENTER(t, Thread::ActiveState);
|
||||
|
||||
cast<double>(classStaticTable(t, *c), field) = v;
|
||||
cast<double>(classStaticTable(t, jclassVmClass(t, *c)), field) = v;
|
||||
}
|
||||
|
||||
jobject JNICALL
|
||||
@ -1248,7 +1251,9 @@ NewObjectArray(Thread* t, jsize length, jclass class_, jobject init)
|
||||
{
|
||||
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);
|
||||
for (jsize i = 0; i < length; ++i) {
|
||||
set(t, a, ArrayBody + (i * BytesPerWord), value);
|
||||
|
@ -1627,7 +1627,7 @@ parseAttributeTable(Thread* t, Stream& s, object class_, object pool)
|
||||
object body = makeByteArray(t, 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);
|
||||
} else {
|
||||
|
@ -3000,6 +3000,29 @@ resolveMethod(Thread* t, object method, unsigned 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
|
||||
dumpHeap(Thread* t, FILE* out);
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
(type jobject java/lang/Object)
|
||||
|
||||
(type class java/lang/Class
|
||||
(type class avian/VMClass
|
||||
(array void* vtable))
|
||||
|
||||
(type jclass java/lang/Class)
|
||||
|
||||
(type singleton
|
||||
(array uintptr_t body))
|
||||
|
||||
@ -11,13 +13,10 @@
|
||||
|
||||
(type systemClassLoader avian/SystemClassLoader)
|
||||
|
||||
(type accessibleObject java/lang/reflect/AccessibleObject)
|
||||
(type field avian/VMField)
|
||||
|
||||
(type field java/lang/reflect/Field)
|
||||
|
||||
(type method java/lang/reflect/Method)
|
||||
|
||||
(type proxy java/lang/reflect/Proxy)
|
||||
(type method avian/VMMethod
|
||||
(intptr_t compiled))
|
||||
|
||||
(type addendum avian/Addendum)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user