From: <cap...@us...> - 2008-06-11 22:32:07
|
Revision: 14471 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=14471&view=rev Author: captain5050 Date: 2008-06-11 15:32:02 -0700 (Wed, 11 Jun 2008) Log Message: ----------- Introduce new classes in java.lang and java.lang.reflect called VMCommonLibrarySupport that capture components of the library support that are common between GNU Classpath and Apache Harmony. Implement reflection code in Apache Harmony using this (RVM-529) and based on code in Apache Harmony. Implement annotation default reflection call in both. Incorporate the one line fix, RVM-303 from Yuval Yarom, at the same time. Modified Paths: -------------- rvmroot/trunk/libraryInterface/Common/src/java/lang/Class.java rvmroot/trunk/libraryInterface/GNUClasspath/CPL/src/java/lang/reflect/JikesRVMSupport.java rvmroot/trunk/libraryInterface/GNUClasspath/CPL/src/java/lang/reflect/VMArray.java rvmroot/trunk/libraryInterface/GNUClasspath/CPL/src/java/lang/reflect/VMConstructor.java rvmroot/trunk/libraryInterface/GNUClasspath/CPL/src/java/lang/reflect/VMField.java rvmroot/trunk/libraryInterface/GNUClasspath/CPL/src/java/lang/reflect/VMMethod.java rvmroot/trunk/libraryInterface/Harmony/ASF/src/java/lang/reflect/AccessibleObject.java rvmroot/trunk/libraryInterface/Harmony/ASF/src/java/lang/reflect/Array.java rvmroot/trunk/libraryInterface/Harmony/ASF/src/java/lang/reflect/Constructor.java rvmroot/trunk/libraryInterface/Harmony/ASF/src/java/lang/reflect/Field.java rvmroot/trunk/libraryInterface/Harmony/ASF/src/java/lang/reflect/Method.java rvmroot/trunk/libraryInterface/Harmony/CPL/src/java/lang/reflect/JikesRVMSupport.java Added Paths: ----------- rvmroot/trunk/libraryInterface/Common/src/java/lang/VMCommonLibrarySupport.java rvmroot/trunk/libraryInterface/Common/src/java/lang/reflect/VMCommonLibrarySupport.java Modified: rvmroot/trunk/libraryInterface/Common/src/java/lang/Class.java =================================================================== --- rvmroot/trunk/libraryInterface/Common/src/java/lang/Class.java 2008-06-11 22:23:42 UTC (rev 14470) +++ rvmroot/trunk/libraryInterface/Common/src/java/lang/Class.java 2008-06-11 22:32:02 UTC (rev 14471) @@ -613,7 +613,7 @@ // Check that caller is allowed to access it if (!defaultConstructor.isPublic()) { VM_Class accessingClass = VM_Class.getClassFromStackFrame(1); - JikesRVMSupport.checkAccess(defaultConstructor, accessingClass); + VMCommonLibrarySupport.checkAccess(defaultConstructor, accessingClass); } // Ensure that the class is initialized Added: rvmroot/trunk/libraryInterface/Common/src/java/lang/VMCommonLibrarySupport.java =================================================================== --- rvmroot/trunk/libraryInterface/Common/src/java/lang/VMCommonLibrarySupport.java (rev 0) +++ rvmroot/trunk/libraryInterface/Common/src/java/lang/VMCommonLibrarySupport.java 2008-06-11 22:32:02 UTC (rev 14471) @@ -0,0 +1,57 @@ +/* + * This file is part of the Jikes RVM project (http://jikesrvm.org). + * + * This file is licensed to You under the Common Public License (CPL); + * You may not use this file except in compliance with the License. You + * may obtain a copy of the License at + * + * http://www.opensource.org/licenses/cpl1.0.php + * + * See the COPYRIGHT.txt file distributed with this work for information + * regarding copyright ownership. + */ +package java.lang; + +import org.jikesrvm.classloader.VM_Class; +import org.jikesrvm.classloader.VM_Member; +import org.vmmagic.pragma.NoInline; + +/** + * Common utilities for Jikes RVM implementations of the java.lang API + */ +class VMCommonLibrarySupport { + /* ---- Non-inlined Exception Throwing Methods --- */ + /** + * Method just to throw an illegal access exception without being inlined + */ + @NoInline + private static void throwNewIllegalAccessException(VM_Member member, VM_Class accessingClass) throws IllegalAccessException{ + throw new IllegalAccessException("Access to " + member + " is denied to " + accessingClass); + } + /* ---- General Reflection Support ---- */ + /** + * Check to see if a method declared by the accessingClass + * should be allowed to access the argument VM_Member. + * Assumption: member is not public. This trivial case should + * be approved by the caller without needing to call this method. + */ + static void checkAccess(VM_Member member, VM_Class accessingClass) throws IllegalAccessException { + VM_Class declaringClass = member.getDeclaringClass(); + if (member.isPrivate()) { + // access from the declaringClass is allowed + if (accessingClass == declaringClass) return; + } else if (member.isProtected()) { + // access within the package is allowed. + if (declaringClass.getClassLoader() == accessingClass.getClassLoader() && declaringClass.getPackageName().equals(accessingClass.getPackageName())) return; + + // access by subclasses is allowed. + for (VM_Class cls = accessingClass; cls != null; cls = cls.getSuperClass()) { + if (accessingClass == declaringClass) return; + } + } else { + // default: access within package is allowed + if (declaringClass.getClassLoader() == accessingClass.getClassLoader() && declaringClass.getPackageName().equals(accessingClass.getPackageName())) return; + } + throwNewIllegalAccessException(member, accessingClass); + } +} Added: rvmroot/trunk/libraryInterface/Common/src/java/lang/reflect/VMCommonLibrarySupport.java =================================================================== --- rvmroot/trunk/libraryInterface/Common/src/java/lang/reflect/VMCommonLibrarySupport.java (rev 0) +++ rvmroot/trunk/libraryInterface/Common/src/java/lang/reflect/VMCommonLibrarySupport.java 2008-06-11 22:32:02 UTC (rev 14471) @@ -0,0 +1,883 @@ +/* + * This file is part of the Jikes RVM project (http://jikesrvm.org). + * + * This file is licensed to You under the Common Public License (CPL); + * You may not use this file except in compliance with the License. You + * may obtain a copy of the License at + * + * http://www.opensource.org/licenses/cpl1.0.php + * + * See the COPYRIGHT.txt file distributed with this work for information + * regarding copyright ownership. + */ +package java.lang.reflect; + +import org.jikesrvm.VM; +import org.jikesrvm.classloader.VM_Array; +import org.jikesrvm.classloader.VM_Class; +import org.jikesrvm.classloader.VM_Field; +import org.jikesrvm.classloader.VM_Member; +import org.jikesrvm.classloader.VM_Method; +import org.jikesrvm.classloader.VM_TypeReference; +import org.jikesrvm.classloader.VM_Type; +import org.jikesrvm.objectmodel.VM_ObjectModel; +import org.jikesrvm.runtime.RuntimeEntrypoints; +import org.jikesrvm.runtime.VM_Magic; +import org.jikesrvm.runtime.VM_Reflection; +import org.vmmagic.pragma.Inline; +import org.vmmagic.pragma.NoInline; +import org.vmmagic.pragma.Pure; + +/** + * Common utilities for Jikes RVM implementations of the java.lang.reflect API + */ +final class VMCommonLibrarySupport { + /* ---- Non-inlined Exception Throwing Methods --- */ + /** + * Method just to throw an illegal argument exception without being inlined + */ + @NoInline + private static void throwNewIllegalArgumentException() { + throw new IllegalArgumentException(); + } + + /** + * Method just to throw an illegal argument exception without being inlined + */ + @NoInline + private static void throwNewIllegalArgumentException(String str) { + throw new IllegalArgumentException(str); + } + /** + * Method just to throw an illegal access exception without being inlined + */ + @NoInline + private static void throwNewIllegalAccessException() throws IllegalAccessException{ + throw new IllegalAccessException(); + } + /** + * Method just to throw an illegal access exception without being inlined + */ + @NoInline + private static void throwNewIllegalAccessException(VM_Member member, VM_Class accessingClass) throws IllegalAccessException{ + throw new IllegalAccessException("Access to " + member + " is denied to " + accessingClass); + } + /** + * Method just to throw an instantiation exception without being inlined + */ + @NoInline + private static void throwNewInstantiationException(String str) throws InstantiationException{ + throw new InstantiationException(str); + } + /** + * Method just to throw a negative array size exception without being inlined + */ + @NoInline + private static void throwNewNegativeArraySizeException() { + throw new NegativeArraySizeException(); + } + /** + * Method just to throw an null pointer exception without being inlined + */ + @NoInline + private static void throwNewNullPointerException() { + throw new NullPointerException(); + } + /* ---- Array Methods ---- */ + /** + * Dynamically create an array of objects. + * + * @param cls guaranteed to be a valid object type + * @param length the length of the array + * @return the new array + * @throws NegativeArraySizeException if dim is negative + * @throws OutOfMemoryError if memory allocation fails + */ + static Object createArray(Class<?> cls, int length) + throws OutOfMemoryError, NegativeArraySizeException { + + if (cls == Void.TYPE) + throwNewIllegalArgumentException("Cannot create new array instance for the specified arguments"); + + // will raise NPE + VM_Array arrayType = java.lang.JikesRVMSupport.getTypeForClass(cls).getArrayTypeForElementType(); + if (!arrayType.isInitialized()) { + arrayType.resolve(); + arrayType.instantiate(); + arrayType.initialize(); + } + // will check -ve array size + return RuntimeEntrypoints.resolvedNewArray(length, arrayType); + } + + /** + * Dynamically create a multi-dimensional array of objects. + * + * @param cls guaranteed to be a valid object type + * @param dimensions the lengths for the dimensions of the array + * @return the new array + * @throws NegativeArraySizeException if any dimensions is negative + * @throws OutOfMemoryError if memory allocation fails + */ + static Object createArray(Class<?> cls, int[] dimensions) + throws OutOfMemoryError, NegativeArraySizeException { + + if ((dimensions.length == 0)||(cls == Void.TYPE)); + throwNewIllegalArgumentException("Cannot create new array instance for the specified arguments"); + + // will raise NPE + VM_Array arrayType = java.lang.JikesRVMSupport.getTypeForClass(cls).getArrayTypeForElementType(); + for (int i=1; i < dimensions.length; i++) { + arrayType = arrayType.getArrayTypeForElementType(); + } + // will check -ve array sizes + return RuntimeEntrypoints.buildMDAHelper(null, dimensions, 0, arrayType); + } + + /* ---- General Reflection Support ---- */ + /** + * Check to see if a method declared by the accessingClass + * should be allowed to access the argument VM_Member. + * Assumption: member is not public. This trivial case should + * be approved by the caller without needing to call this method. + */ + private static void checkAccess(VM_Member member, VM_Class accessingClass) throws IllegalAccessException { + VM_Class declaringClass = member.getDeclaringClass(); + if (member.isPrivate()) { + // access from the declaringClass is allowed + if (accessingClass == declaringClass) return; + } else if (member.isProtected()) { + // access within the package is allowed. + if (declaringClass.getClassLoader() == accessingClass.getClassLoader() && declaringClass.getPackageName().equals(accessingClass.getPackageName())) return; + + // access by subclasses is allowed. + for (VM_Class cls = accessingClass; cls != null; cls = cls.getSuperClass()) { + if (accessingClass == declaringClass) return; + } + } else { + // default: access within package is allowed + if (declaringClass.getClassLoader() == accessingClass.getClassLoader() && declaringClass.getPackageName().equals(accessingClass.getPackageName())) return; + } + throwNewIllegalAccessException(member, accessingClass); + } + /* ---- Reflective Method Invocation Support ---- */ + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2}) + static Object invoke(Object receiver, Object[] args, VM_Method method, Method jlrMethod, VM_Class accessingClass) + throws IllegalAccessException, IllegalArgumentException, + ExceptionInInitializerError, InvocationTargetException { + // validate number and types of arguments + if (checkArguments(args, method)) { + if (method.isStatic()) { + return invokeStatic(receiver, args, method, jlrMethod, accessingClass); + } else { + return invokeVirtual(receiver, args, method, jlrMethod, accessingClass); + } + } else { + Object[] compatibleArgs = makeArgumentsCompatible(args, method); + if (method.isStatic()) { + return invokeStatic(receiver, compatibleArgs, method, jlrMethod, accessingClass); + } else { + return invokeVirtual(receiver, compatibleArgs, method, jlrMethod, accessingClass); + } + } + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2}) + private static Object invokeStatic(Object receiver, Object[] args, VM_Method method, Method jlrMethod, VM_Class accessingClass) + throws IllegalAccessException, IllegalArgumentException, + ExceptionInInitializerError, InvocationTargetException { + // Accessibility checks + if (!method.isPublic() && !jlrMethod.isAccessible()) { + checkAccess(method, accessingClass); + } + + // Forces initialization of declaring class + VM_Class declaringClass = method.getDeclaringClass(); + if (!declaringClass.isInitialized()) { + runClassInitializer(declaringClass); + } + + // Invoke method + try { + return VM_Reflection.invoke(method, receiver, args); + } catch (Throwable t) { + throw new InvocationTargetException(t); + } + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2}) + private static Object invokeVirtual(Object receiver, Object[] args, VM_Method method, Method jlrMethod, VM_Class accessingClass) + throws IllegalAccessException, IllegalArgumentException, + ExceptionInInitializerError, InvocationTargetException { + // validate "this" argument + if (receiver == null) { + throwNewNullPointerException(); + } + VM_Class declaringClass = method.getDeclaringClass(); + if (!isArgumentCompatible(declaringClass, receiver)) { + throwNewIllegalArgumentException(); + } + + // Accessibility checks + if (!method.isPublic() && !jlrMethod.isAccessible()) { + checkAccess(method, accessingClass); + } + + // find the right method to call + VM_Class C = VM_Magic.getObjectType(receiver).asClass(); + method = C.findVirtualMethod(method.getName(), method.getDescriptor()); + + // Invoke method + try { + return VM_Reflection.invoke(method, receiver, args); + } catch (Throwable t) { + throw new InvocationTargetException(t); + } + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) + private static boolean checkArguments(Object[] args, VM_Method method) throws IllegalArgumentException { + VM_TypeReference[] parameterTypes = method.getParameterTypes(); + if (((args == null) && (parameterTypes.length != 0)) || + ((args != null) && (args.length != parameterTypes.length))) { + throwNewIllegalArgumentException("argument count mismatch"); + } + switch (parameterTypes.length) { + case 6: + if (!isArgumentCompatible(parameterTypes[5].resolve(), args[5])) { + return false; + } + case 5: + if (!isArgumentCompatible(parameterTypes[4].resolve(), args[4])) { + return false; + } + case 4: + if (!isArgumentCompatible(parameterTypes[3].resolve(), args[3])) { + return false; + } + case 3: + if (!isArgumentCompatible(parameterTypes[2].resolve(), args[2])) { + return false; + } + case 2: + if (!isArgumentCompatible(parameterTypes[1].resolve(), args[1])) { + return false; + } + case 1: + if (!isArgumentCompatible(parameterTypes[0].resolve(), args[0])) { + return false; + } + case 0: + return true; + default: + for (int i=0, n = parameterTypes.length; i < n; ++i) { + if (!isArgumentCompatible(parameterTypes[i].resolve(), args[i])) { + return false; + } + } + return true; + } + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) + private static Object[] makeArgumentsCompatible(Object[] args, VM_Method method) { + VM_TypeReference[] parameterTypes = method.getParameterTypes(); + int length = parameterTypes.length; + Object[] newArgs = new Object[length]; + switch(length) { + case 6: newArgs[5] = makeArgumentCompatible(parameterTypes[5].peekType(), args[5]); + case 5: newArgs[4] = makeArgumentCompatible(parameterTypes[4].peekType(), args[4]); + case 4: newArgs[3] = makeArgumentCompatible(parameterTypes[3].peekType(), args[3]); + case 3: newArgs[2] = makeArgumentCompatible(parameterTypes[2].peekType(), args[2]); + case 2: newArgs[1] = makeArgumentCompatible(parameterTypes[1].peekType(), args[1]); + case 1: newArgs[0] = makeArgumentCompatible(parameterTypes[0].peekType(), args[0]); + case 0: break; + default: { + for (int i = 0; i < length; ++i) { + newArgs[i] = makeArgumentCompatible(parameterTypes[i].peekType(), args[i]); + } + break; + } + } + return newArgs; + } + + @NoInline + private static void runClassInitializer(VM_Class declaringClass) throws ExceptionInInitializerError { + try { + RuntimeEntrypoints.initializeClassForDynamicLink(declaringClass); + } catch (Throwable e) { + ExceptionInInitializerError ex = new ExceptionInInitializerError(); + ex.initCause(e); + throw ex; + } + } + + /** + * Make possibly wrapped method argument compatible with expected type + */ + @SuppressWarnings({"UnnecessaryBoxing","PMD.IntegerInstantiation"}) + @NoInline + @Pure + private static Object makeArgumentCompatible(VM_Type expectedType, Object arg) { + if (expectedType.isPrimitiveType()) { + if (arg instanceof java.lang.Byte) { + if (expectedType.isByteType()) return arg; + if (expectedType.isShortType()) return Short.valueOf((Byte) arg); + if (expectedType.isIntType()) return Integer.valueOf((Byte) arg); + if (expectedType.isLongType()) return Long.valueOf((Byte) arg); + } else if (arg instanceof java.lang.Short) { + if (expectedType.isShortType()) return arg; + if (expectedType.isIntType()) return Integer.valueOf((Short) arg); + if (expectedType.isLongType()) return Long.valueOf((Short) arg); + } else if (arg instanceof java.lang.Character) { + if (expectedType.isCharType()) return arg; + if (expectedType.isIntType()) return Integer.valueOf((Character) arg); + if (expectedType.isLongType()) return Long.valueOf((Character) arg); + } else if (arg instanceof java.lang.Integer) { + if (expectedType.isIntType()) return arg; + if (expectedType.isLongType()) return Long.valueOf((Integer) arg); + } else if (arg instanceof java.lang.Float) { + if (expectedType.isDoubleType()) return Double.valueOf((Float) arg); + } + } + return arg; + } + + /** + * Are the 2 arguments compatible? Throw IllegalArgumentException if they + * can't be made compatible. + */ + @Pure + @Inline + private static boolean isArgumentCompatible(VM_Type expectedType, Object arg) { + if (expectedType.isPrimitiveType()) { + return isPrimitiveArgumentCompatible(expectedType, arg); + } else { + if (arg == null) return true; // null is always ok + VM_Type actualType = VM_ObjectModel.getObjectType(arg); + if (expectedType == actualType || + expectedType == VM_Type.JavaLangObjectType || + RuntimeEntrypoints.isAssignableWith(expectedType, actualType)) { + return true; + } else { + throwNewIllegalArgumentException(); + return false; + } + } + } + + /** + * Is a boxed primitive argument compatible with the expected type + */ + @Pure + @Inline + private static boolean isPrimitiveArgumentCompatible(VM_Type expectedType, Object arg) { + if (arg instanceof java.lang.Void) { + if (expectedType.isVoidType()) return true; + } else if (arg instanceof java.lang.Boolean) { + if (expectedType.isBooleanType()) return true; + } else if (arg instanceof java.lang.Byte) { + if (expectedType.isByteType()) return true; + if (expectedType.isShortType()) return false; + if (expectedType.isIntType()) return false; + if (expectedType.isLongType()) return false; + } else if (arg instanceof java.lang.Short) { + if (expectedType.isShortType()) return true; + if (expectedType.isIntType()) return false; + if (expectedType.isLongType()) return false; + } else if (arg instanceof java.lang.Character) { + if (expectedType.isCharType()) return true; + if (expectedType.isIntType()) return false; + if (expectedType.isLongType()) return false; + } else if (arg instanceof java.lang.Integer) { + if (expectedType.isIntType()) return true; + if (expectedType.isLongType()) return false; + } else if (arg instanceof java.lang.Long) { + if (expectedType.isLongType()) return true; + } else if (arg instanceof java.lang.Float) { + if (expectedType.isFloatType()) return true; + if (expectedType.isDoubleType()) return false; + } else if (arg instanceof java.lang.Double) { + if (expectedType.isDoubleType()) return true; + } + throwNewIllegalArgumentException(); + return false; + } + + /* ---- Constructor Support ---- */ + /** + * Construct an object from the given constructor args, called from the accessing class + */ + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={0}) + static Object construct(VM_Method constructor, Constructor<?> cons, Object[] args, VM_Class accessingClass) + throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + // Check accessibility + if (!constructor.isPublic() && !cons.isAccessible()) { + checkAccess(constructor, accessingClass); + } + // validate number and types of arguments to constructor + if (!checkArguments(args, constructor)) { + args = makeArgumentsCompatible(args, constructor); + } + VM_Class cls = constructor.getDeclaringClass(); + if (cls.isAbstract()) { + throwNewInstantiationException("Abstract class"); + } + // Ensure that the class is initialized + if (!cls.isInitialized()) { + runClassInitializer(cls); + } + // Allocate an uninitialized instance; + Object obj = RuntimeEntrypoints.resolvedNewScalar(cls); + // Run the constructor on the instance. + try { + VM_Reflection.invoke(constructor, obj, args); + } catch (Throwable e) { + throw new InvocationTargetException(e); + } + return obj; + } + /* ---- Constructor/Method Support ---- */ + /** + * Convert from "vm" type system to "jdk" type system. + */ + static Class<?>[] typesToClasses(VM_TypeReference[] types) { + Class<?>[] classes = new Class[types.length]; + for (int i = 0; i < types.length; i++) { + classes[i] = types[i].resolve().getClassForType(); + } + return classes; + } + /* ---- Field Support ---- */ + /** + * Check the field in the given object can be read + */ + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) + private static void checkReadAccess(Object obj, VM_Field field, Field jlrField, VM_Class accessingClass) throws IllegalAccessException, + IllegalArgumentException, + ExceptionInInitializerError { + VM_Class declaringClass = field.getDeclaringClass(); + if (!field.isStatic()) { + if (obj == null) { + throwNewNullPointerException(); + } + + VM_Type objType = VM_ObjectModel.getObjectType(obj); + if (objType != declaringClass && !RuntimeEntrypoints.isAssignableWith(declaringClass, objType)) { + throwNewIllegalArgumentException(); + } + } + + if (!field.isPublic() && !jlrField.isAccessible()) { + checkAccess(field, accessingClass); + } + + if (field.isStatic() && !declaringClass.isInitialized()) { + runClassInitializer(declaringClass); + } + } + + /** + * Check the field in the given object can be written to + */ + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) + private static void checkWriteAccess(Object obj, VM_Field field, Field jlrField, VM_Class accessingClass) throws IllegalAccessException, + IllegalArgumentException, + ExceptionInInitializerError { + + VM_Class declaringClass = field.getDeclaringClass(); + if (!field.isStatic()) { + if (obj == null) { + throwNewNullPointerException(); + } + + VM_Type objType = VM_ObjectModel.getObjectType(obj); + if (objType != declaringClass && !RuntimeEntrypoints.isAssignableWith(declaringClass, objType)) { + throwNewIllegalArgumentException(); + } + } + + if (!field.isPublic() && !jlrField.isAccessible()) { + checkAccess(field, accessingClass); + } + + if (field.isFinal() && (!jlrField.isAccessible() || field.isStatic())) + throwNewIllegalAccessException(); + + if (field.isStatic() && !declaringClass.isInitialized()) { + runClassInitializer(declaringClass); + } + } + + /** + * Read a field from an object + * @param object to read from + * @param field to be read + * @param jlrField API version of field + * @param accessingClass class performing access + * @return the field's value + * @throws IllegalAccessException + * @throws IllegalArgumentException + */ + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) + static Object get(Object object, VM_Field field, Field jlrField, VM_Class accessingClass) throws IllegalAccessException, IllegalArgumentException { + checkReadAccess(object, field, jlrField, accessingClass); + + if (field.isReferenceType()) { + return field.getObjectValueUnchecked(object); + } + VM_TypeReference type = field.getType(); + if (type.isIntType()) { + return field.getIntValueUnchecked(object); + } else if (type.isCharType()) { + return field.getCharValueUnchecked(object); + } else if (type.isShortType()) { + return field.getShortValueUnchecked(object); + } else if (type.isLongType()) { + return field.getLongValueUnchecked(object); + } else if (type.isByteType()) { + return field.getByteValueUnchecked(object); + } else if (type.isBooleanType()) { + return field.getBooleanValueUnchecked(object); + } else if (type.isDoubleType()) { + return field.getDoubleValueUnchecked(object); + } else { + if (VM.VerifyAssertions) VM._assert(type.isFloatType()); + return field.getFloatValueUnchecked(object); + } + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) + static boolean getBoolean(Object object, VM_Field field, Field jlrField, VM_Class accessingClass) throws IllegalAccessException, IllegalArgumentException { + checkReadAccess(object, field, jlrField, accessingClass); + VM_TypeReference type = field.getType(); + if (!type.isBooleanType()) throwNewIllegalArgumentException("field type mismatch"); + return field.getBooleanValueUnchecked(object); + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) + static byte getByte(Object object, VM_Field field, Field jlrField, VM_Class accessingClass) throws IllegalAccessException, IllegalArgumentException { + checkReadAccess(object, field, jlrField, accessingClass); + VM_TypeReference type = field.getType(); + if (!type.isByteType()) throwNewIllegalArgumentException("field type mismatch"); + return field.getByteValueUnchecked(object); + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) + static char getChar(Object object, VM_Field field, Field jlrField, VM_Class accessingClass) throws IllegalAccessException, IllegalArgumentException { + checkReadAccess(object, field, jlrField, accessingClass); + VM_TypeReference type = field.getType(); + if (!type.isCharType()) throwNewIllegalArgumentException("field type mismatch"); + return field.getCharValueUnchecked(object); + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) + static double getDouble(Object object, VM_Field field, Field jlrField, VM_Class accessingClass) throws IllegalAccessException, IllegalArgumentException { + checkReadAccess(object, field, jlrField, accessingClass); + VM_TypeReference type = field.getType(); + if (type.isDoubleType()) { + return field.getDoubleValueUnchecked(object); + } else if (type.isFloatType()) { + return (double)field.getFloatValueUnchecked(object); + } else if (type.isLongType()) { + return (double)field.getLongValueUnchecked(object); + } else if (type.isIntType()) { + return (double)field.getIntValueUnchecked(object); + } else if (type.isShortType()) { + return (double)field.getShortValueUnchecked(object); + } else if (type.isCharType()) { + return (double)field.getCharValueUnchecked(object); + } else if (type.isByteType()) { + return (double)field.getByteValueUnchecked(object); + } else { + throwNewIllegalArgumentException("field type mismatch"); + return 0.0d; + } + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) + static float getFloat(Object object, VM_Field field, Field jlrField, VM_Class accessingClass) throws IllegalAccessException, IllegalArgumentException { + checkReadAccess(object, field, jlrField, accessingClass); + VM_TypeReference type = field.getType(); + if (type.isFloatType()) { + return field.getFloatValueUnchecked(object); + } else if (type.isLongType()) { + return (float)field.getLongValueUnchecked(object); + } else if (type.isIntType()) { + return (float)field.getIntValueUnchecked(object); + } else if (type.isShortType()) { + return (float)field.getShortValueUnchecked(object); + } else if (type.isCharType()) { + return (float)field.getCharValueUnchecked(object); + } else if (type.isByteType()) { + return (float)field.getByteValueUnchecked(object); + } else { + throwNewIllegalArgumentException("field type mismatch"); + return 0.0f; + } + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) + static int getInt(Object object, VM_Field field, Field jlrField, VM_Class accessingClass) throws IllegalAccessException, IllegalArgumentException { + checkReadAccess(object, field, jlrField, accessingClass); + VM_TypeReference type = field.getType(); + if (type.isIntType()) { + return field.getIntValueUnchecked(object); + } else if (type.isShortType()) { + return (int)field.getShortValueUnchecked(object); + } else if (type.isCharType()) { + return (int)field.getCharValueUnchecked(object); + } else if (type.isByteType()) { + return (int)field.getByteValueUnchecked(object); + } else { + throwNewIllegalArgumentException("field type mismatch"); + return 0; + } + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) + static long getLong(Object object, VM_Field field, Field jlrField, VM_Class accessingClass) throws IllegalAccessException, IllegalArgumentException { + checkReadAccess(object, field, jlrField, accessingClass); + VM_TypeReference type = field.getType(); + if (type.isLongType()) { + return field.getLongValueUnchecked(object); + } else if (type.isIntType()) { + return (long)field.getIntValueUnchecked(object); + } else if (type.isShortType()) { + return (long)field.getShortValueUnchecked(object); + } else if (type.isCharType()) { + return (long)field.getCharValueUnchecked(object); + } else if (type.isByteType()) { + return (long)field.getByteValueUnchecked(object); + } else { + throwNewIllegalArgumentException("field type mismatch"); + return 0L; + } + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={1}) + static short getShort(Object object, VM_Field field, Field jlrField, VM_Class accessingClass) throws IllegalAccessException, IllegalArgumentException { + checkReadAccess(object, field, jlrField, accessingClass); + VM_TypeReference type = field.getType(); + if (type.isShortType()) { + return field.getShortValueUnchecked(object); + } else if (type.isByteType()) { + return (short)field.getByteValueUnchecked(object); + } else { + throwNewIllegalArgumentException("field type mismatch"); + return 0; + } + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2}) + static void set(Object object, Object value, VM_Field field, Field jlrField, VM_Class accessingClass) + throws IllegalAccessException, IllegalArgumentException { + checkWriteAccess(object, field, jlrField, accessingClass); + + if (field.isReferenceType()) { + if (value != null) { + VM_Type valueType = VM_ObjectModel.getObjectType(value); + VM_Type fieldType = null; + try { + fieldType = field.getType().resolve(); + } catch (NoClassDefFoundError e) { + throwNewIllegalArgumentException("field type mismatch"); + } + if (fieldType != valueType && + !RuntimeEntrypoints.isAssignableWith(fieldType, valueType)) { + throwNewIllegalArgumentException("field type mismatch"); + } + } + field.setObjectValueUnchecked(object, value); + } else if (value instanceof Character) { + setCharInternal(object, (Character) value, field); + } else if (value instanceof Double) { + setDoubleInternal(object, (Double) value, field); + } else if (value instanceof Float) { + setFloatInternal(object, (Float) value, field); + } else if (value instanceof Long) { + setLongInternal(object, (Long) value, field); + } else if (value instanceof Integer) { + setIntInternal(object, (Integer) value, field); + } else if (value instanceof Short) { + setShortInternal(object, (Short) value, field); + } else if (value instanceof Byte) { + setByteInternal(object, (Byte) value, field); + } else if (value instanceof Boolean) { + setBooleanInternal(object, (Boolean) value, field); + } else { + throw new IllegalArgumentException("field type mismatch"); + } + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2}) + static void setBoolean(Object object, boolean value, VM_Field field, Field jlrField, VM_Class accessingClass) + throws IllegalAccessException, IllegalArgumentException { + checkWriteAccess(object, field, jlrField, accessingClass); + setBooleanInternal(object, value, field); + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2}) + static void setByte(Object object, byte value, VM_Field field, Field jlrField, VM_Class accessingClass) + throws IllegalAccessException, IllegalArgumentException { + checkWriteAccess(object, field, jlrField, accessingClass); + setByteInternal(object, value, field); + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2}) + static void setChar(Object object, char value, VM_Field field, Field jlrField, VM_Class accessingClass) + throws IllegalAccessException, IllegalArgumentException { + checkWriteAccess(object, field, jlrField, accessingClass); + setCharInternal(object, value, field); + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2}) + static void setDouble(Object object, double value, VM_Field field, Field jlrField, VM_Class accessingClass) + throws IllegalAccessException, IllegalArgumentException { + checkWriteAccess(object, field, jlrField, accessingClass); + setDoubleInternal(object, value, field); + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2}) + static void setFloat(Object object, float value, VM_Field field, Field jlrField, VM_Class accessingClass) + throws IllegalAccessException, IllegalArgumentException { + checkWriteAccess(object, field, jlrField, accessingClass); + setFloatInternal(object, value, field); + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2}) + static void setInt(Object object, int value, VM_Field field, Field jlrField, VM_Class accessingClass) + throws IllegalAccessException, IllegalArgumentException { + checkWriteAccess(object, field, jlrField, accessingClass); + setIntInternal(object, value, field); + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2}) + static void setLong(Object object, long value, VM_Field field, Field jlrField, VM_Class accessingClass) + throws IllegalAccessException, IllegalArgumentException { + checkWriteAccess(object, field, jlrField, accessingClass); + setLongInternal(object, value, field); + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2}) + static void setShort(Object object, short value, VM_Field field, Field jlrField, VM_Class accessingClass) + throws IllegalAccessException, IllegalArgumentException { + checkWriteAccess(object, field, jlrField, accessingClass); + setShortInternal(object, value, field); + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2}) + private static void setBooleanInternal(Object object, boolean value, VM_Field field) + throws IllegalArgumentException { + VM_TypeReference type = field.getType(); + if (type.isBooleanType()) + field.setBooleanValueUnchecked(object, value); + else + throwNewIllegalArgumentException("field type mismatch"); + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2}) + private static void setByteInternal(Object object, byte value, VM_Field field) throws IllegalArgumentException { + VM_TypeReference type = field.getType(); + if (type.isByteType()) + field.setByteValueUnchecked(object, value); + else if (type.isLongType()) + field.setLongValueUnchecked(object, (long)value); + else if (type.isIntType()) + field.setIntValueUnchecked(object, (int)value); + else if (type.isShortType()) + field.setShortValueUnchecked(object, (short)value); + else if (type.isCharType()) + field.setCharValueUnchecked(object, (char)value); + else if (type.isDoubleType()) + field.setDoubleValueUnchecked(object, (double)value); + else if (type.isFloatType()) + field.setFloatValueUnchecked(object, (float)value); + else + throwNewIllegalArgumentException("field type mismatch"); + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2}) + private static void setCharInternal(Object object, char value, VM_Field field) throws IllegalArgumentException { + VM_TypeReference type = field.getType(); + if (type.isCharType()) + field.setCharValueUnchecked(object, value); + else if (type.isLongType()) + field.setLongValueUnchecked(object, (long)value); + else if (type.isIntType()) + field.setIntValueUnchecked(object, (int)value); + else if (type.isShortType()) + field.setShortValueUnchecked(object, (short)value); + else if (type.isDoubleType()) + field.setDoubleValueUnchecked(object, (double)value); + else if (type.isFloatType()) + field.setFloatValueUnchecked(object, (float)value); + else + throwNewIllegalArgumentException("field type mismatch"); + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2}) + private static void setDoubleInternal(Object object, double value, VM_Field field) throws IllegalArgumentException { + VM_TypeReference type = field.getType(); + if (type.isDoubleType()) + field.setDoubleValueUnchecked(object, value); + else + throwNewIllegalArgumentException("field type mismatch"); + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2}) + private static void setFloatInternal(Object object, float value, VM_Field field) throws IllegalArgumentException { + VM_TypeReference type = field.getType(); + if (type.isFloatType()) + field.setFloatValueUnchecked(object, value); + else if (type.isDoubleType()) + field.setDoubleValueUnchecked(object, (double)value); + else + throwNewIllegalArgumentException("field type mismatch"); + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2}) + private static void setIntInternal(Object object, int value, VM_Field field) throws IllegalArgumentException { + VM_TypeReference type = field.getType(); + if (type.isIntType()) + field.setIntValueUnchecked(object, value); + else if (type.isLongType()) + field.setLongValueUnchecked(object, (long) value); + else if (type.isDoubleType()) + field.setDoubleValueUnchecked(object, (double)value); + else if (type.isFloatType()) + field.setFloatValueUnchecked(object, (float)value); + else + throwNewIllegalArgumentException("field type mismatch"); + } + + @Inline(value=Inline.When.ArgumentsAreConstant, arguments={2}) + private static void setLongInternal(Object object, long value, VM_Field field) throws IllegalArgumentException { + VM_TypeReference type = field.getType(); + if (type.isLongType()) + field.setLongValueUnchecked(object, value); + else if (type.isDoubleType()) + field.setDoubleValueUnchecked(object, (double)value); + else if (type.isFloatType()) + field.setFloatValueUnchecked(object, (float)value); + else + throwNewIllegalArgumentException("field type mismatch"); + } + + private static void setShortInternal(Object object, short value, VM_Field field) throws IllegalArgumentException { + VM_TypeReference type = field.getType(); + if (type.isShortType()) + field.setShortValueUnchecked(object, value); + else if (type.isLongType()) + field.setLongValueUnchecked(object, (long)value); + else if (type.isIntType()) + field.setIntValueUnchecked(object, (int)value); + else if (type.isDoubleType()) + field.setDoubleValueUnchecked(object, (double)value); + else if (type.isFloatType()) + field.setFloatValueUnchecked(object, (float)value); + else + throwNewIllegalArgumentException("field type mismatch"); + } +} Modified: rvmroot/trunk/libraryInterface/GNUClasspath/CPL/src/java/lang/reflect/JikesRVMSupport.java =================================================================== --- rvmroot/trunk/libraryInterface/GNUClasspath/CPL/src/java/lang/reflect/JikesRVMSupport.java 2008-06-11 22:23:42 UTC (rev 14470) +++ rvmroot/trunk/libraryInterface/GNUClasspath/CPL/src/java/lang/reflect/JikesRVMSupport.java 2008-06-11 22:32:02 UTC (rev 14471) @@ -12,122 +12,13 @@ */ package java.lang.reflect; -import org.jikesrvm.objectmodel.VM_ObjectModel; -import org.jikesrvm.runtime.RuntimeEntrypoints; import org.jikesrvm.classloader.*; -import org.vmmagic.pragma.NoInline; -import org.vmmagic.pragma.Pure; -import org.vmmagic.pragma.Inline; /** * Library support interface of Jikes RVM */ public class JikesRVMSupport { - /** - * Convert from "vm" type system to "jdk" type system. - */ - static Class<?>[] typesToClasses(VM_TypeReference[] types) { - Class<?>[] classes = new Class[types.length]; - for (int i = 0; i < types.length; i++) { - classes[i] = types[i].resolve().getClassForType(); - } - return classes; - } - - /** - * Make possibly wrapped method argument compatible with expected type - */ - @SuppressWarnings({"UnnecessaryBoxing","PMD.IntegerInstantiation"}) - @NoInline - @Pure - static Object makeArgumentCompatible(VM_Type expectedType, Object arg) { - if (expectedType.isPrimitiveType()) { - if (arg instanceof java.lang.Byte) { - if (expectedType.isByteType()) return arg; - if (expectedType.isShortType()) return Short.valueOf((Byte) arg); - if (expectedType.isIntType()) return Integer.valueOf((Byte) arg); - if (expectedType.isLongType()) return Long.valueOf((Byte) arg); - } else if (arg instanceof java.lang.Short) { - if (expectedType.isShortType()) return arg; - if (expectedType.isIntType()) return Integer.valueOf((Short) arg); - if (expectedType.isLongType()) return Long.valueOf((Short) arg); - } else if (arg instanceof java.lang.Character) { - if (expectedType.isCharType()) return arg; - if (expectedType.isIntType()) return Integer.valueOf((Character) arg); - if (expectedType.isLongType()) return Long.valueOf((Character) arg); - } else if (arg instanceof java.lang.Integer) { - if (expectedType.isIntType()) return arg; - if (expectedType.isLongType()) return Long.valueOf((Integer) arg); - } else if (arg instanceof java.lang.Float) { - if (expectedType.isDoubleType()) return Double.valueOf((Float) arg); - } - } - return arg; - } - - /** - * Are the 2 arguments compatible? Throw IllegalArgumentException if they - * can't be made compatible. - */ - @Pure - @Inline - static boolean isArgumentCompatible(VM_Type expectedType, Object arg) { - if (expectedType.isPrimitiveType()) { - return isPrimitiveArgumentCompatible(expectedType, arg); - } else { - if (arg == null) return true; // null is always ok - VM_Type actualType = VM_ObjectModel.getObjectType(arg); - if (expectedType == actualType || - expectedType == VM_Type.JavaLangObjectType || - RuntimeEntrypoints.isAssignableWith(expectedType, actualType)) { - return true; - } else { - throwNewIllegalArgumentException(); - return false; - } - } - } - - @NoInline - private static void throwNewIllegalArgumentException() { - throw new IllegalArgumentException(); - } - @Pure - @Inline - private static boolean isPrimitiveArgumentCompatible(VM_Type expectedType, Object arg) { - if (arg instanceof java.lang.Void) { - if (expectedType.isVoidType()) return true; - } else if (arg instanceof java.lang.Boolean) { - if (expectedType.isBooleanType()) return true; - } else if (arg instanceof java.lang.Byte) { - if (expectedType.isByteType()) return true; - if (expectedType.isShortType()) return false; - if (expectedType.isIntType()) return false; - if (expectedType.isLongType()) return false; - } else if (arg instanceof java.lang.Short) { - if (expectedType.isShortType()) return true; - if (expectedType.isIntType()) return false; - if (expectedType.isLongType()) return false; - } else if (arg instanceof java.lang.Character) { - if (expectedType.isCharType()) return true; - if (expectedType.isIntType()) return false; - if (expectedType.isLongType()) return false; - } else if (arg instanceof java.lang.Integer) { - if (expectedType.isIntType()) return true; - if (expectedType.isLongType()) return false; - } else if (arg instanceof java.lang.Long) { - if (expectedType.isLongType()) return true; - } else if (arg instanceof java.lang.Float) { - if (expectedType.isFloatType()) return true; - if (expectedType.isDoubleType()) return false; - } else if (arg instanceof java.lang.Double) { - if (expectedType.isDoubleType()) return true; - } - throwNewIllegalArgumentException(); - return false; - } - public static Field createField(VM_Field f) { return new Field(new VMField(f)); } @@ -153,7 +44,7 @@ return m.m.method; } - public static VM_Method getMethodOf(Constructor cons) { + public static VM_Method getMethodOf(Constructor<?> cons) { return cons.cons.constructor; } @@ -168,33 +59,4 @@ public static VM_Method getMethodOf(VMConstructor cons) { return cons.constructor; } - - - /** - * Check to see if a method declared by the accessingClass - * should be allowed to access the argument VM_Member. - * Assumption: member is not public. This trivial case should - * be approved by the caller without needing to call this method. - */ - public static void checkAccess(VM_Member member, VM_Class accessingClass) throws IllegalAccessException { - VM_Class declaringClass = member.getDeclaringClass(); - if (member.isPrivate()) { - // access from the declaringClass is allowed - if (accessingClass == declaringClass) return; - } else if (member.isProtected()) { - // access within the package is allowed. - if (declaringClass.getClassLoader() == accessingClass.getClassLoader() && declaringClass.getPackageName().equals(accessingClass.getPackageName())) return; - - // access by subclasses is allowed. - for (VM_Class cls = accessingClass; cls != null; cls = cls.getSuperClass()) { - if (accessingClass == declaringClass) return; - } - } else { - // default: access within package is allowed - if (declaringClass.getClassLoader() == accessingClass.getClassLoader() && declaringClass.getPackageName().equals(accessingClass.getPackageName())) return; - } - - throw new IllegalAccessException("Access to "+member+" is denied to "+accessingClass); - } - } Modified: rvmroot/trunk/libraryInterface/GNUClasspath/CPL/src/java/lang/reflect/VMArray.java =================================================================== --- rvmroot/trunk/libraryInterface/GNUClasspath/CPL/src/java/lang/reflect/VMArray.java 2008-06-11 22:23:42 UTC (rev 14470) +++ rvmroot/trunk/libraryInterface/GNUClasspath/CPL/src/java/lang/reflect/VMArray.java 2008-06-11 22:32:02 UTC (rev 14471) @@ -12,9 +12,6 @@ */ package java.lang.reflect; -import org.jikesrvm.classloader.VM_Array; -import org.jikesrvm.runtime.RuntimeEntrypoints; - /** * VM dependent Array operations */ @@ -30,17 +27,6 @@ */ static Object createObjectArray(Class<?> cls, int length) throws OutOfMemoryError, NegativeArraySizeException { - if(cls == null) - throw new NullPointerException(); - if(length < 0) - throw new NegativeArraySizeException(); - - VM_Array arrayType = java.lang.JikesRVMSupport.getTypeForClass(cls).getArrayTypeForElementType(); - if (!arrayType.isInitialized()) { - arrayType.resolve(); - arrayType.instantiate(); - arrayType.initialize(); - } - return RuntimeEntrypoints.resolvedNewArray(length, arrayType); + return VMCommonLibrarySupport.createArray(cls, length); } } Modified: rvmroot/trunk/libraryInterface/GNUClasspath/CPL/src/java/lang/reflect/VMConstructor.java =================================================================== --- rvmroot/trunk/libraryInterface/GNUClasspath/CPL/src/java/lang/reflect/VMConstructor.java 2008-06-11 22:23:42 UTC (rev 14470) +++ rvmroot/trunk/libraryInterface/GNUClasspath/CPL/src/java/lang/reflect/VMConstructor.java 2008-06-11 22:32:02 UTC (rev 14471) @@ -14,9 +14,9 @@ import java.lang.annotation.Annotation; -import org.jikesrvm.classloader.*; -import org.jikesrvm.runtime.VM_Reflection; -import org.jikesrvm.runtime.RuntimeEntrypoints; +import org.jikesrvm.classloader.VM_Class; +import org.jikesrvm.classloader.VM_Method; +import org.jikesrvm.classloader.VM_TypeReference; /** * Implementation of java.lang.reflect.VMConstructor for JikesRVM. @@ -26,7 +26,7 @@ */ final class VMConstructor { final VM_Method constructor; - Constructor cons; + Constructor<?> cons; // Prevent this class from being instantiated. @SuppressWarnings("unused") @@ -41,22 +41,22 @@ public boolean equals(Object other) { if (other instanceof Constructor) { - return constructor == ((Constructor)other).cons.constructor; + return constructor == ((Constructor<?>)other).cons.constructor; } else { return false; } } - Class getDeclaringClass() { + Class<?> getDeclaringClass() { return constructor.getDeclaringClass().getClassForType(); } - Class[] getExceptionTypes() { + Class<?>[] getExceptionTypes() { VM_TypeReference[] exceptionTypes = constructor.getExceptionTypes(); if (exceptionTypes == null) { return new Class[0]; } else { - return JikesRVMSupport.typesToClasses(exceptionTypes); + return VMCommonLibrarySupport.typesToClasses(exceptionTypes); } } @@ -68,61 +68,15 @@ return getDeclaringClass().getName(); } - Class[] getParameterTypes() { - return JikesRVMSupport.typesToClasses(constructor.getParameterTypes()); + Class<?>[] getParameterTypes() { + return VMCommonLibrarySupport.typesToClasses(constructor.getParameterTypes()); } Object construct(Object[] args) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { - // Check accessibility - if (!constructor.isPublic() && !cons.isAccessible()) { - VM_Class accessingClass = VM_Class.getClassFromStackFrame(2); - JikesRVMSupport.checkAccess(constructor, accessingClass); - } - - // validate number and types of arguments to constructor - VM_TypeReference[] parameterTypes = constructor.getParameterTypes(); - if (args == null) { - if (parameterTypes.length != 0) { - throw new IllegalArgumentException("argument count mismatch"); - } - } else { - if (args.length != parameterTypes.length) { - throw new IllegalArgumentException("argument count mismatch"); - } - for (int i = 0; i < parameterTypes.length; i++) { - args[i] = JikesRVMSupport.makeArgumentCompatible(parameterTypes[i].resolve(), args[i]); - } - } - - VM_Class cls = constructor.getDeclaringClass(); - if (cls.isAbstract()) { - throw new InstantiationException("Abstract class"); - } - - // Ensure that the class is initialized - if (!cls.isInitialized()) { - try { - RuntimeEntrypoints.initializeClassForDynamicLink(cls); - } catch (Throwable e) { - ExceptionInInitializerError ex = new ExceptionInInitializerError(); - ex.initCause(e); - throw ex; - } - } - - // Allocate an uninitialized instance; - Object obj = RuntimeEntrypoints.resolvedNewScalar(cls); - - // Run the constructor on the instance. - try { - VM_Reflection.invoke(constructor, obj, args); - } catch (Throwable e) { - throw new InvocationTargetException(e); - } - return obj; + return VMCommonLibrarySupport.construct(constructor, cons, args, VM_Class.getClassFromStackFrame(2)); } String getSignature() { Modified: rvmroot/trunk/libraryInterface/GNUClasspath/CPL/src/java/lang/reflect/VMField.java =================================================================== --- rvmroot/trunk/libraryInterface/GNUClasspath/CPL/src/java/lang/reflect/VMField.java 2008-06-11 22:23:42 UTC (rev 14470) +++ rvmroot/trunk/libraryInterface/GNUClasspath/CPL/src/java/lang/reflect/VMField.java 2008-06-11 22:32:02 UTC (rev 14471) @@ -16,13 +16,7 @@ import org.jikesrvm.classloader.VM_Class; import org.jikesrvm.classloader.VM_Field; -import org.jikesrvm.classloader.VM_TypeReference; -import org.jikesrvm.classloader.VM_Type; -import org.jikesrvm.objectmodel.VM_ObjectModel; -import org.jikesrvm.VM; -import org.jikesrvm.runtime.RuntimeEntrypoints; - /** * Implementation of java.lang.reflect.Field for JikesRVM. * @@ -53,452 +47,103 @@ } } - Object get(Object object) throws IllegalAccessException, IllegalArgumentException { - checkReadAccess(object); + Class<?> getDeclaringClass() { + return field.getDeclaringClass().getClassForType(); + } - if (field.isReferenceType()) { - return field.getObjectValueUnchecked(object); - } - VM_TypeReference type = field.getType(); - if (type.isIntType()) { - return field.getIntValueUnchecked(object); - } else if (type.isCharType()) { - return field.getCharValueUnchecked(object); - } else if (type.isShortType()) { - return field.getShortValueUnchecked(object); - } else if (type.isLongType()) { - return field.getLongValueUnchecked(object); - } else if (type.isByteType()) { - return field.getByteValueUnchecked(object); - } else if (type.isBooleanType()) { - return field.getBooleanValueUnchecked(object); - } else if (type.isDoubleType()) { - return field.getDoubleValueUnchecked(object); - } else { - if (VM.VerifyAssertions) VM._assert(type.isFloatType()); - return field.getFloatValueUnchecked(object); - } + Object get(Object object) throws IllegalAccessException, IllegalArgumentException { + return VMCommonLibrarySupport.get(object, field, f, VM_Class.getClassFromStackFrame(2)); } boolean getBoolean(Object object) throws IllegalAccessException, IllegalArgumentException { - checkReadAccess(object); - return getBooleanInternal(object); + return VMCommonLibrarySupport.getBoolean(object, field, f, VM_Class.getClassFromStackFrame(2)); } byte getByte(Object object) throws IllegalAccessException, IllegalArgumentException { - checkReadAccess(object); - return getByteInternal(object); + return VMCommonLibrarySupport.getByte(object, field, f, VM_Class.getClassFromStackFrame(2)); } char getChar(Object object) throws IllegalAccessException, IllegalArgumentException { - checkReadAccess(object); - return getCharInternal(object); + return VMCommonLibrarySupport.getChar(object, field, f, VM_Class.getClassFromStackFrame(2)); } - public Class<?> getDeclaringClass() { - return field.getDeclaringClass().getClassForType(); - } - double getDouble(Object object) throws IllegalAccessException, IllegalArgumentException { - checkReadAccess(object); - return getDoubleInternal(object); + return VMCommonLibrarySupport.getDouble(object, field, f, VM_Class.getClassFromStackFrame(2)); } float getFloat(Object object) throws IllegalAccessException, IllegalArgumentException { - checkReadAccess(object); - return getFloatInternal(object); + return VMCommonLibrarySupport.getFloat(object, field, f, VM_Class.getClassFromStackFrame(2)); } int getInt(Object object) throws IllegalAccessException, IllegalArgumentException { - checkReadAccess(object); - return getIntInternal(object); + return VMCommonLibrarySupport.getInt(object, field, f, VM_Class.getClassFromStackFrame(2)); } long getLong(Object object) throws IllegalAccessException, IllegalArgumentException { - checkReadAccess(object); - return getLongInternal(object); + return VMCommonLibrarySupport.getLong(object, field, f, VM_Class.getClassFromStackFrame(2)); } + public short getShort(Object object) throws IllegalAccessException, IllegalArgumentException { + return VMCommonLibrarySupport.getShort(object, field, f, VM_Class.getClassFromStackFrame(2)); + } + int getModifiersInternal() { return field.getModifiers(); } - public String getName() { + String getName() { return field.getName().toString(); } - public short getShort(Object object) throws IllegalAccessException, IllegalArgumentException { - checkReadAccess(object); - return getShortInternal(object); - } - Class<?> getType() { return field.getType().resolve().getClassForType(); } void set(Object object, Object value) throws IllegalAccessException, IllegalArgumentException { - checkWriteAccess(object); - - if (field.isReferenceType()) { - if (value != null) { - VM_Type valueType = VM_ObjectModel.getObjectType(value); - VM_Type fieldType; - try { - fieldType = field.getType().resolve(); - } catch (NoClassDefFoundError e) { - throw new IllegalArgumentException("field type mismatch"); - } - if (fieldType != valueType && - !RuntimeEntrypoints.isAssignableWith(fieldType, valueType)) { - throw new IllegalArgumentException("field type mismatch"); - } - } - field.setObjectValueUnchecked(object, value); - } else if (value instanceof Character) { - setCharInternal(object, (Character) value); - } else if (value instanceof Double) { - setDoubleInternal(object, (Double) value); - } else if (value instanceof Float)... [truncated message content] |