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. |