|
From: <ls...@us...> - 2008-12-30 18:20:30
|
Revision: 4810
http://jnode.svn.sourceforge.net/jnode/?rev=4810&view=rev
Author: lsantha
Date: 2008-12-30 18:20:25 +0000 (Tue, 30 Dec 2008)
Log Message:
-----------
Bugfixes and cleanups related to reflection.
Modified Paths:
--------------
trunk/core/src/classpath/vm/gnu/classpath/jdwp/NativeVMVirtualMachine.java
trunk/core/src/core/org/jnode/util/IOUtils.java
trunk/core/src/core/org/jnode/vm/VmReflection.java
trunk/core/src/core/org/jnode/vm/classmgr/ClassDecoder.java
trunk/core/src/core/org/jnode/vm/classmgr/TIBBuilder.java
trunk/core/src/core/org/jnode/vm/classmgr/VmClassType.java
Modified: trunk/core/src/classpath/vm/gnu/classpath/jdwp/NativeVMVirtualMachine.java
===================================================================
--- trunk/core/src/classpath/vm/gnu/classpath/jdwp/NativeVMVirtualMachine.java 2008-12-27 17:00:27 UTC (rev 4809)
+++ trunk/core/src/classpath/vm/gnu/classpath/jdwp/NativeVMVirtualMachine.java 2008-12-30 18:20:25 UTC (rev 4810)
@@ -68,7 +68,7 @@
}
public Object next() {
- return iter.next().newClass();
+ return iter.next().asClass();
}
public void remove() {
Modified: trunk/core/src/core/org/jnode/util/IOUtils.java
===================================================================
--- trunk/core/src/core/org/jnode/util/IOUtils.java 2008-12-27 17:00:27 UTC (rev 4809)
+++ trunk/core/src/core/org/jnode/util/IOUtils.java 2008-12-30 18:20:25 UTC (rev 4810)
@@ -106,7 +106,9 @@
try {
Class<FilterInputStream> cls = FilterInputStream.class;
Field field = cls.getDeclaredField("in");
+ field.setAccessible(true);
Object in = field.get(inputStream);
+ field.setAccessible(false);
return (InputStream) in;
} catch (Exception ex) {
Logger.getLogger(IOUtils.class).error("Cannot extract the 'in' field", ex);
Modified: trunk/core/src/core/org/jnode/vm/VmReflection.java
===================================================================
--- trunk/core/src/core/org/jnode/vm/VmReflection.java 2008-12-27 17:00:27 UTC (rev 4809)
+++ trunk/core/src/core/org/jnode/vm/VmReflection.java 2008-12-30 18:20:25 UTC (rev 4810)
@@ -82,7 +82,7 @@
return (byte) getStaticFieldAddress(sf).loadInt();
} else {
final VmInstanceField inf = (VmInstanceField) field;
- return (byte) getInstanceFieldAddress(o, inf).loadByte();
+ return getInstanceFieldAddress(o, inf).loadByte();
}
}
@@ -93,7 +93,7 @@
return (char) getStaticFieldAddress(sf).loadInt();
} else {
final VmInstanceField inf = (VmInstanceField) field;
- return (char) getInstanceFieldAddress(o, inf).loadChar();
+ return getInstanceFieldAddress(o, inf).loadChar();
}
}
@@ -104,7 +104,7 @@
return (short) getStaticFieldAddress(sf).loadInt();
} else {
final VmInstanceField inf = (VmInstanceField) field;
- return (short) getInstanceFieldAddress(o, inf).loadShort();
+ return getInstanceFieldAddress(o, inf).loadShort();
}
}
@@ -343,39 +343,133 @@
Unsafe.pushObject(o);
if (!method.isConstructor()) {
- method = VmType.fromClass(o.getClass()).getMethod(method.getName(), method.getSignature());
+ //todo implement dynamic method lookup according to JLS 15.12.4.4
+ if(method.isAbstract())
+ method = VmType.fromClass(o.getClass()).getMethod(method.getName(), method.getSignature());
+ else if(java.lang.reflect.Proxy.isProxyClass(o.getClass())) {
+ method = VmType.fromClass(o.getClass()).getMethod(method.getName(), method.getSignature());
+ }
}
} else {
method.getDeclaringClass().initialize();
}
+
for (int i = 0; i < argCount; i++) {
final VmType<?> argType = method.getArgumentType(i);
final Object arg = args[i];
if (argType.isPrimitive()) {
+ if (arg == null)
+ throw new IllegalArgumentException();
+
int v = 0;
long lv = 0;
boolean wide = false;
- if (arg == null) {
- /* do nothing */
- } else if (arg instanceof Boolean) {
- v = ((Boolean) arg).booleanValue() ? 1 : 0;
- } else if (arg instanceof Byte) {
- v = ((Byte) arg).byteValue();
- } else if (arg instanceof Character) {
- v = ((Character) arg).charValue();
- } else if (arg instanceof Short) {
- v = ((Short) arg).shortValue();
- } else if (arg instanceof Integer) {
- v = ((Integer) arg).intValue();
- } else if (arg instanceof Long) {
- lv = ((Long) arg).longValue();
- wide = true;
- } else if (arg instanceof Float) {
- v = Float.floatToRawIntBits(((Float) arg).floatValue());
- } else if (arg instanceof Double) {
- lv = Double.doubleToRawLongBits(((Double) arg)
- .doubleValue());
- wide = true;
+ switch (argType.getJvmType()) {
+ case JvmType.BOOLEAN: {
+ if (arg instanceof Boolean) {
+ v = (Boolean) arg ? 1 : 0;
+ } else {
+ throw new IllegalArgumentException("argument type mismatch");
+ }
+ break;
+ }
+ case JvmType.INT: {
+ if (arg instanceof Integer) {
+ v = (Integer) arg;
+ } else if (arg instanceof Byte) {
+ v = (Byte) arg;
+ } else if (arg instanceof Character) {
+ v = (Character) arg;
+ } else if (arg instanceof Short) {
+ v = (Short) arg;
+ } else {
+ throw new IllegalArgumentException("argument type mismatch");
+ }
+ break;
+ }
+ case JvmType.CHAR: {
+ if (arg instanceof Character) {
+ v = (Character) arg;
+ } else {
+ throw new IllegalArgumentException("argument type mismatch");
+ }
+ break;
+ }
+ case JvmType.BYTE: {
+ if (arg instanceof Byte) {
+ v = (Byte) arg;
+ } else {
+ throw new IllegalArgumentException("argument type mismatch");
+ }
+ break;
+ }
+ case JvmType.SHORT: {
+ if (arg instanceof Short) {
+ v = (Short) arg;
+ } else if (arg instanceof Byte) {
+ v = (Byte) arg;
+ } else {
+ throw new IllegalArgumentException("argument type mismatch");
+ }
+ break;
+ }
+ case JvmType.FLOAT: {
+ if (arg instanceof Float) {
+ v = Float.floatToRawIntBits((Float) arg);
+ } else if (arg instanceof Byte) {
+ v = Float.floatToRawIntBits((Byte) arg);
+ } else if (arg instanceof Short) {
+ v = Float.floatToRawIntBits((Short) arg);
+ } else if (arg instanceof Integer) {
+ v = Float.floatToRawIntBits((Integer) arg);
+ } else if (arg instanceof Character) {
+ v = Float.floatToRawIntBits((Character) arg);
+ } else {
+ throw new IllegalArgumentException("argument type mismatch");
+ }
+ break;
+ }
+ case JvmType.LONG: {
+ wide = true;
+ if (arg instanceof Long) {
+ lv = (Long) arg;
+ } else if (arg instanceof Integer) {
+ lv = (Integer) arg;
+ } else if (arg instanceof Byte) {
+ lv = (Byte) arg;
+ } else if (arg instanceof Short) {
+ lv = (Short) arg;
+ } else if (arg instanceof Character) {
+ lv = (Character) arg;
+ } else {
+ throw new IllegalArgumentException("argument type mismatch");
+ }
+ break;
+ }
+ case JvmType.DOUBLE: {
+ wide = true;
+ if (arg instanceof Double) {
+ lv = Double.doubleToRawLongBits((Double) arg);
+ } else if (arg instanceof Integer) {
+ lv = Double.doubleToRawLongBits((Integer) arg);
+ } else if (arg instanceof Byte) {
+ lv = Double.doubleToRawLongBits((Byte) arg);
+ } else if (arg instanceof Short) {
+ lv = Double.doubleToRawLongBits((Short) arg);
+ } else if (arg instanceof Character) {
+ lv = Double.doubleToRawLongBits((Character) arg);
+ } else if (arg instanceof Float) {
+ lv = Double.doubleToRawLongBits((Float) arg);
+ } else if (arg instanceof Long) {
+ lv = Double.doubleToRawLongBits((Long) arg);
+ } else {
+ throw new IllegalArgumentException("argument type mismatch");
+ }
+ break;
+ }
+ default: {
+ throw new RuntimeException("invalid argument type: " + argType);
+ }
}
final Class argClass = argType.asClass();
@@ -395,6 +489,11 @@
}
}
} else {
+ if(arg != null) {
+ if(!argType.isAssignableFrom(VmType.fromClass(arg.getClass()))) {
+ throw new IllegalArgumentException ("argument type mismatch");
+ }
+ }
// Non-primitive argument
Unsafe.pushObject(arg);
}
@@ -410,25 +509,25 @@
long rc = Unsafe.invokeLong(method);
final Class<?> retType = method.getReturnType().asClass();
if (Long.TYPE == retType) {
- return new Long(rc);
+ return rc;
} else {
- return new Double(Double.longBitsToDouble(rc));
+ return Double.longBitsToDouble(rc);
}
} else {
int rc = Unsafe.invokeInt(method);
final Class retType = method.getReturnType().asClass();
if (Byte.TYPE == retType) {
- return new Byte((byte) rc);
+ return (byte) rc;
} else if (Boolean.TYPE == retType) {
- return Boolean.valueOf(rc != 0);
+ return rc != 0;
} else if (Character.TYPE == retType) {
- return new Character((char) rc);
+ return (char) rc;
} else if (Short.TYPE == retType) {
- return new Short((short) rc);
+ return (short) rc;
} else if (Float.TYPE == retType) {
- return new Float(Float.intBitsToFloat(rc));
+ return Float.intBitsToFloat(rc);
} else {
- return new Integer(rc);
+ return rc;
}
}
} catch (Throwable ex) {
Modified: trunk/core/src/core/org/jnode/vm/classmgr/ClassDecoder.java
===================================================================
--- trunk/core/src/core/org/jnode/vm/classmgr/ClassDecoder.java 2008-12-27 17:00:27 UTC (rev 4809)
+++ trunk/core/src/core/org/jnode/vm/classmgr/ClassDecoder.java 2008-12-30 18:20:25 UTC (rev 4810)
@@ -1015,7 +1015,7 @@
break;
}
- r_class = vtm.newClass();
+ r_class = vtm.asClass();
} else {
try {
r_class = Class.forName(vtm.getName(), false, vtm.getLoader().asClassLoader());
@@ -1024,7 +1024,7 @@
}
}
Object defo = AnnotationParser.parseMemberValue(r_class, data, new VmConstantPool(cls),
- cls.newClass());
+ cls.asClass());
mts.setAnnotationDefault(defo);
} else {
skip(data, length);
@@ -1263,7 +1263,7 @@
break;
}
- r_class = vtm.newClass();
+ r_class = vtm.asClass();
} else {
try {
r_class = vtm.getLoader().asClassLoader().loadClass(vtm.getName());
Modified: trunk/core/src/core/org/jnode/vm/classmgr/TIBBuilder.java
===================================================================
--- trunk/core/src/core/org/jnode/vm/classmgr/TIBBuilder.java 2008-12-27 17:00:27 UTC (rev 4809)
+++ trunk/core/src/core/org/jnode/vm/classmgr/TIBBuilder.java 2008-12-30 18:20:25 UTC (rev 4810)
@@ -23,6 +23,7 @@
import java.util.ArrayList;
import java.util.HashMap;
+import gnu.java.lang.VMClassHelper;
/**
* @author epr
@@ -103,7 +104,28 @@
method.setTibOffset(index);
}
+ //todo review rules for overriding and do more testing
/**
+ * Check if the method has the correct visibility ofr overriding the method at index.
+ * It asumed that the signutares were already checked and they match
+ * @param index
+ * @param method
+ * @return
+ */
+ boolean overrides(int index, VmInstanceMethod method) {
+ if (tibAsArray != null) {
+ throw new RuntimeException("This VMT is locked");
+ }
+ if (index < FIRST_METHOD_INDEX) {
+ throw new IndexOutOfBoundsException("Index (" + index + ")must be >= " + FIRST_METHOD_INDEX);
+ }
+ VmInstanceMethod met = (VmInstanceMethod) tibAsList.get(index);
+ return (met.isPublic() || met.isProtected() || (!met.isPrivate() &&
+ VMClassHelper.getPackagePortion(met.getDeclaringClass().getName()).
+ equals(VMClassHelper.getPackagePortion(method.getDeclaringClass().getName()))));
+ }
+
+ /**
* Search through a given VMT for a method with a given name & signature.
* Return the index in the VMT (0..length-1) if found, -1 otherwise.
*
Modified: trunk/core/src/core/org/jnode/vm/classmgr/VmClassType.java
===================================================================
--- trunk/core/src/core/org/jnode/vm/classmgr/VmClassType.java 2008-12-27 17:00:27 UTC (rev 4809)
+++ trunk/core/src/core/org/jnode/vm/classmgr/VmClassType.java 2008-12-30 18:20:25 UTC (rev 4810)
@@ -148,7 +148,11 @@
final int index = vmt.indexOf(name, signature);
if (index >= 0) {
// The method existed in the super class, overwrite it
- vmt.set(index, method);
+ if(vmt.overrides(index, method)){
+ vmt.set(index, method);
+ } else {
+ vmt.add(method);
+ }
} else {
// The method does not exist yet.
vmt.add(method);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|