# HG changeset patch # User Jaroslav Tulach # Date 1354627871 -3600 # Node ID 1d03cb35fbda736c65ad2a22e8af5bbf4269c4fb # Parent 9b0fbf4ec230e06b2a2c6c66e2b494dc4af96956 Removing default implementation from reflection APIs diff -r 9b0fbf4ec230 -r 1d03cb35fbda emul/src/main/java/java/lang/Class.java --- a/emul/src/main/java/java/lang/Class.java Tue Dec 04 14:08:19 2012 +0100 +++ b/emul/src/main/java/java/lang/Class.java Tue Dec 04 14:31:11 2012 +0100 @@ -27,6 +27,7 @@ import java.io.InputStream; import java.lang.annotation.Annotation; +import java.lang.reflect.TypeVariable; import org.apidesign.bck2brwsr.core.JavaScriptBody; /** @@ -75,10 +76,10 @@ * @since JDK1.0 */ public final - class Class implements java.io.Serializable { -// java.lang.reflect.GenericDeclaration, -// java.lang.reflect.Type, -// java.lang.reflect.AnnotatedElement { + class Class implements java.io.Serializable, + java.lang.reflect.GenericDeclaration, + java.lang.reflect.Type, + java.lang.reflect.AnnotatedElement { private static final int ANNOTATION= 0x00002000; private static final int ENUM = 0x00004000; private static final int SYNTHETIC = 0x00001000; @@ -396,6 +397,26 @@ @JavaScriptBody(args = "self", body = "return self.jvmName;") private native String jvmName(); + + /** + * Returns an array of {@code TypeVariable} objects that represent the + * type variables declared by the generic declaration represented by this + * {@code GenericDeclaration} object, in declaration order. Returns an + * array of length 0 if the underlying generic declaration declares no type + * variables. + * + * @return an array of {@code TypeVariable} objects that represent + * the type variables declared by this generic declaration + * @throws java.lang.reflect.GenericSignatureFormatError if the generic + * signature of this generic declaration does not conform to + * the format specified in + * The Java™ Virtual Machine Specification + * @since 1.5 + */ + public TypeVariable>[] getTypeParameters() { + throw new UnsupportedOperationException(); + } + /** * Returns the {@code Class} representing the superclass of the entity * (class, interface, primitive type or void) represented by this diff -r 9b0fbf4ec230 -r 1d03cb35fbda emul/src/main/java/java/lang/reflect/AccessibleObject.java --- a/emul/src/main/java/java/lang/reflect/AccessibleObject.java Tue Dec 04 14:08:19 2012 +0100 +++ b/emul/src/main/java/java/lang/reflect/AccessibleObject.java Tue Dec 04 14:31:11 2012 +0100 @@ -25,9 +25,6 @@ package java.lang.reflect; -import java.security.AccessController; -import sun.reflect.Reflection; -import sun.reflect.ReflectionFactory; import java.lang.annotation.Annotation; /** @@ -57,14 +54,6 @@ public class AccessibleObject implements AnnotatedElement { /** - * The Permission object that is used to check whether a client - * has sufficient privilege to defeat Java language access - * control checks. - */ - static final private java.security.Permission ACCESS_PERMISSION = - new ReflectPermission("suppressAccessChecks"); - - /** * Convenience method to set the {@code accessible} flag for an * array of objects with a single security check (for efficiency). * @@ -91,11 +80,7 @@ */ public static void setAccessible(AccessibleObject[] array, boolean flag) throws SecurityException { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) sm.checkPermission(ACCESS_PERMISSION); - for (int i = 0; i < array.length; i++) { - setAccessible0(array[i], flag); - } + throw new SecurityException(); } /** @@ -124,23 +109,7 @@ * @see java.lang.RuntimePermission */ public void setAccessible(boolean flag) throws SecurityException { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) sm.checkPermission(ACCESS_PERMISSION); - setAccessible0(this, flag); - } - - /* Check that you aren't exposing java.lang.Class.. */ - private static void setAccessible0(AccessibleObject obj, boolean flag) - throws SecurityException - { - if (obj instanceof Constructor && flag == true) { - Constructor c = (Constructor)obj; - if (c.getDeclaringClass() == Class.class) { - throw new SecurityException("Can not make a java.lang.Class" + - " constructor accessible"); - } - } - obj.override = flag; + throw new SecurityException(); } /** @@ -165,13 +134,6 @@ // outside this package. boolean override; - // Reflection factory used by subclasses for creating field, - // method, and constructor accessors. Note that this is called - // very early in the bootstrapping process. - static final ReflectionFactory reflectionFactory = - AccessController.doPrivileged( - new sun.reflect.ReflectionFactory.GetReflectionFactoryAction()); - /** * @throws NullPointerException {@inheritDoc} * @since 1.5 @@ -202,73 +164,4 @@ public Annotation[] getDeclaredAnnotations() { throw new AssertionError("All subclasses should override this method"); } - - - // Shared access checking logic. - - // For non-public members or members in package-private classes, - // it is necessary to perform somewhat expensive security checks. - // If the security check succeeds for a given class, it will - // always succeed (it is not affected by the granting or revoking - // of permissions); we speed up the check in the common case by - // remembering the last Class for which the check succeeded. - // - // The simple security check for Constructor is to see if - // the caller has already been seen, verified, and cached. - // (See also Class.newInstance(), which uses a similar method.) - // - // A more complicated security check cache is needed for Method and Field - // The cache can be either null (empty cache), a 2-array of {caller,target}, - // or a caller (with target implicitly equal to this.clazz). - // In the 2-array case, the target is always different from the clazz. - volatile Object securityCheckCache; - - void checkAccess(Class caller, Class clazz, Object obj, int modifiers) - throws IllegalAccessException - { - if (caller == clazz) { // quick check - return; // ACCESS IS OK - } - Object cache = securityCheckCache; // read volatile - Class targetClass = clazz; - if (obj != null - && Modifier.isProtected(modifiers) - && ((targetClass = obj.getClass()) != clazz)) { - // Must match a 2-list of { caller, targetClass }. - if (cache instanceof Class[]) { - Class[] cache2 = (Class[]) cache; - if (cache2[1] == targetClass && - cache2[0] == caller) { - return; // ACCESS IS OK - } - // (Test cache[1] first since range check for [1] - // subsumes range check for [0].) - } - } else if (cache == caller) { - // Non-protected case (or obj.class == this.clazz). - return; // ACCESS IS OK - } - - // If no return, fall through to the slow path. - slowCheckMemberAccess(caller, clazz, obj, modifiers, targetClass); - } - - // Keep all this slow stuff out of line: - void slowCheckMemberAccess(Class caller, Class clazz, Object obj, int modifiers, - Class targetClass) - throws IllegalAccessException - { - Reflection.ensureMemberAccess(caller, clazz, obj, modifiers); - - // Success: Update the cache. - Object cache = ((targetClass == clazz) - ? caller - : new Class[] { caller, targetClass }); - - // Note: The two cache elements are not volatile, - // but they are effectively final. The Java memory model - // guarantees that the initializing stores for the cache - // elements will occur before the volatile write. - securityCheckCache = cache; // write volatile - } } diff -r 9b0fbf4ec230 -r 1d03cb35fbda emul/src/main/java/java/lang/reflect/Field.java --- a/emul/src/main/java/java/lang/reflect/Field.java Tue Dec 04 14:08:19 2012 +0100 +++ b/emul/src/main/java/java/lang/reflect/Field.java Tue Dec 04 14:31:11 2012 +0100 @@ -25,15 +25,7 @@ package java.lang.reflect; -import sun.reflect.FieldAccessor; -import sun.reflect.Reflection; -import sun.reflect.generics.repository.FieldRepository; -import sun.reflect.generics.factory.CoreReflectionFactory; -import sun.reflect.generics.factory.GenericsFactory; -import sun.reflect.generics.scope.ClassScope; import java.lang.annotation.Annotation; -import java.util.Map; -import sun.reflect.annotation.AnnotationParser; /** @@ -67,13 +59,7 @@ private int modifiers; // Generics and annotations support private transient String signature; - // generic info repository; lazily initialized - private transient FieldRepository genericInfo; private byte[] annotations; - // Cached field accessor created without override - private FieldAccessor fieldAccessor; - // Cached field accessor created with override - private FieldAccessor overrideFieldAccessor; // For sharing of FieldAccessors. This branching structure is // currently only two levels deep (i.e., one root Field and // potentially many Field objects pointing to it.) @@ -83,24 +69,6 @@ private String getGenericSignature() {return signature;} - // Accessor for factory - private GenericsFactory getFactory() { - Class c = getDeclaringClass(); - // create scope and factory - return CoreReflectionFactory.make(c, ClassScope.make(c)); - } - - // Accessor for generic info repository - private FieldRepository getGenericInfo() { - // lazily initialize repository if necessary - if (genericInfo == null) { - // create and cache generic info repository - genericInfo = FieldRepository.make(getGenericSignature(), - getFactory()); - } - return genericInfo; //return cached repository - } - /** * Package-private constructor used by ReflectAccess to enable @@ -139,9 +107,6 @@ // objects.) Field res = new Field(clazz, name, type, modifiers, slot, signature, annotations); res.root = this; - // Might as well eagerly propagate this if already present - res.fieldAccessor = fieldAccessor; - res.overrideFieldAccessor = overrideFieldAccessor; return res; } @@ -232,10 +197,7 @@ * @since 1.5 */ public Type getGenericType() { - if (getGenericSignature() != null) - return getGenericInfo().getGenericType(); - else - return getType(); + throw new UnsupportedOperationException(); } @@ -924,65 +886,28 @@ private FieldAccessor getFieldAccessor(Object obj) throws IllegalAccessException { - doSecurityCheck(obj); - boolean ov = override; - FieldAccessor a = (ov)? overrideFieldAccessor : fieldAccessor; - return (a != null)? a : acquireFieldAccessor(ov); + throw new SecurityException(); } - - // NOTE that there is no synchronization used here. It is correct - // (though not efficient) to generate more than one FieldAccessor - // for a given Field. However, avoiding synchronization will - // probably make the implementation more scalable. - private FieldAccessor acquireFieldAccessor(boolean overrideFinalCheck) { - // First check to see if one has been created yet, and take it - // if so - FieldAccessor tmp = null; - if (root != null) tmp = root.getFieldAccessor(overrideFinalCheck); - if (tmp != null) { - if (overrideFinalCheck) - overrideFieldAccessor = tmp; - else - fieldAccessor = tmp; - } else { - // Otherwise fabricate one and propagate it up to the root - tmp = reflectionFactory.newFieldAccessor(this, overrideFinalCheck); - setFieldAccessor(tmp, overrideFinalCheck); - } - - return tmp; - } - - // Returns FieldAccessor for this Field object, not looking up - // the chain to the root - private FieldAccessor getFieldAccessor(boolean overrideFinalCheck) { - return (overrideFinalCheck)? overrideFieldAccessor : fieldAccessor; - } - - // Sets the FieldAccessor for this Field object and - // (recursively) its root - private void setFieldAccessor(FieldAccessor accessor, boolean overrideFinalCheck) { - if (overrideFinalCheck) - overrideFieldAccessor = accessor; - else - fieldAccessor = accessor; - // Propagate up - if (root != null) { - root.setFieldAccessor(accessor, overrideFinalCheck); - } - } - - // NOTE: be very careful if you change the stack depth of this - // routine. The depth of the "getCallerClass" call is hardwired so - // that the compiler can have an easier time if this gets inlined. - private void doSecurityCheck(Object obj) throws IllegalAccessException { - if (!override) { - if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { - Class caller = Reflection.getCallerClass(4); - - checkAccess(caller, clazz, obj, modifiers); - } - } + + private static abstract class FieldAccessor { + abstract void setShort(Object obj, short s); + abstract void setInt(Object obj, int i); + abstract void setChar(Object obj, char c); + abstract void setByte(Object obj, byte b); + abstract void setBoolean(Object obj, boolean z); + abstract void set(Object obj, Object value); + abstract double getDouble(Object obj); + abstract void setLong(Object obj, long l); + abstract void setFloat(Object obj, float f); + abstract void setDouble(Object obj, double d); + abstract long getLong(Object obj); + abstract int getInt(Object obj); + abstract short getShort(Object obj); + abstract char getChar(Object obj); + abstract byte getByte(Object obj); + abstract boolean getBoolean(Object obj); + abstract Object get(Object obj); + abstract float getFloat(Object obj); } /* @@ -1016,25 +941,13 @@ if (annotationClass == null) throw new NullPointerException(); - return (T) declaredAnnotations().get(annotationClass); + throw new UnsupportedOperationException(); } /** * @since 1.5 */ public Annotation[] getDeclaredAnnotations() { - return AnnotationParser.toArray(declaredAnnotations()); - } - - private transient Map, Annotation> declaredAnnotations; - - private synchronized Map, Annotation> declaredAnnotations() { - if (declaredAnnotations == null) { - declaredAnnotations = AnnotationParser.parseAnnotations( - annotations, sun.misc.SharedSecrets.getJavaLangAccess(). - getConstantPool(getDeclaringClass()), - getDeclaringClass()); - } - return declaredAnnotations; + throw new UnsupportedOperationException(); } } diff -r 9b0fbf4ec230 -r 1d03cb35fbda emul/src/main/java/java/lang/reflect/Method.java --- a/emul/src/main/java/java/lang/reflect/Method.java Tue Dec 04 14:08:19 2012 +0100 +++ b/emul/src/main/java/java/lang/reflect/Method.java Tue Dec 04 14:31:11 2012 +0100 @@ -25,18 +25,7 @@ package java.lang.reflect; -import sun.reflect.MethodAccessor; -import sun.reflect.Reflection; -import sun.reflect.generics.repository.MethodRepository; -import sun.reflect.generics.factory.CoreReflectionFactory; -import sun.reflect.generics.factory.GenericsFactory; -import sun.reflect.generics.scope.MethodScope; -import sun.reflect.annotation.AnnotationType; -import sun.reflect.annotation.AnnotationParser; import java.lang.annotation.Annotation; -import java.lang.annotation.AnnotationFormatError; -import java.nio.ByteBuffer; -import java.util.Map; /** * A {@code Method} provides information about, and access to, a single method @@ -72,12 +61,9 @@ private int modifiers; // Generics and annotations support private transient String signature; - // generic info repository; lazily initialized - private transient MethodRepository genericInfo; private byte[] annotations; private byte[] parameterAnnotations; private byte[] annotationDefault; - private volatile MethodAccessor methodAccessor; // For sharing of MethodAccessors. This branching structure is // currently only two levels deep (i.e., one root Method and // potentially many Method objects pointing to it.) @@ -87,23 +73,6 @@ private String getGenericSignature() {return signature;} - // Accessor for factory - private GenericsFactory getFactory() { - // create scope and factory - return CoreReflectionFactory.make(this, MethodScope.make(this)); - } - - // Accessor for generic info repository - private MethodRepository getGenericInfo() { - // lazily initialize repository if necessary - if (genericInfo == null) { - // create and cache generic info repository - genericInfo = MethodRepository.make(getGenericSignature(), - getFactory()); - } - return genericInfo; //return cached repository - } - /** * Package-private constructor used by ReflectAccess to enable * instantiation of these objects in Java code from the java.lang @@ -151,8 +120,6 @@ exceptionTypes, modifiers, slot, signature, annotations, parameterAnnotations, annotationDefault); res.root = this; - // Might as well eagerly propagate this if already present - res.methodAccessor = methodAccessor; return res; } @@ -199,10 +166,7 @@ * @since 1.5 */ public TypeVariable[] getTypeParameters() { - if (getGenericSignature() != null) - return (TypeVariable[])getGenericInfo().getTypeParameters(); - else - return (TypeVariable[])new TypeVariable[0]; + throw new UnsupportedOperationException(); } /** @@ -240,9 +204,7 @@ * @since 1.5 */ public Type getGenericReturnType() { - if (getGenericSignature() != null) { - return getGenericInfo().getReturnType(); - } else { return getReturnType();} + throw new UnsupportedOperationException(); } @@ -287,10 +249,7 @@ * @since 1.5 */ public Type[] getGenericParameterTypes() { - if (getGenericSignature() != null) - return getGenericInfo().getParameterTypes(); - else - return getParameterTypes(); + throw new UnsupportedOperationException(); } @@ -331,12 +290,7 @@ * @since 1.5 */ public Type[] getGenericExceptionTypes() { - Type[] result; - if (getGenericSignature() != null && - ((result = getGenericInfo().getExceptionTypes()).length > 0)) - return result; - else - return getExceptionTypes(); + throw new UnsupportedOperationException(); } /** @@ -587,18 +541,7 @@ throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { - if (!override) { - if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { - Class caller = Reflection.getCallerClass(1); - - checkAccess(caller, clazz, obj, modifiers); - } - } - MethodAccessor ma = methodAccessor; // read volatile - if (ma == null) { - ma = acquireMethodAccessor(); - } - return ma.invoke(obj, args); + throw new UnsupportedOperationException(); } /** @@ -638,42 +581,6 @@ return Modifier.isSynthetic(getModifiers()); } - // NOTE that there is no synchronization used here. It is correct - // (though not efficient) to generate more than one MethodAccessor - // for a given Method. However, avoiding synchronization will - // probably make the implementation more scalable. - private MethodAccessor acquireMethodAccessor() { - // First check to see if one has been created yet, and take it - // if so - MethodAccessor tmp = null; - if (root != null) tmp = root.getMethodAccessor(); - if (tmp != null) { - methodAccessor = tmp; - } else { - // Otherwise fabricate one and propagate it up to the root - tmp = reflectionFactory.newMethodAccessor(this); - setMethodAccessor(tmp); - } - - return tmp; - } - - // Returns MethodAccessor for this Method object, not looking up - // the chain to the root - MethodAccessor getMethodAccessor() { - return methodAccessor; - } - - // Sets the MethodAccessor for this Method object and - // (recursively) its root - void setMethodAccessor(MethodAccessor accessor) { - methodAccessor = accessor; - // Propagate up - if (root != null) { - root.setMethodAccessor(accessor); - } - } - /** * @throws NullPointerException {@inheritDoc} * @since 1.5 @@ -682,26 +589,14 @@ if (annotationClass == null) throw new NullPointerException(); - return (T) declaredAnnotations().get(annotationClass); + throw new UnsupportedOperationException(); } /** * @since 1.5 */ public Annotation[] getDeclaredAnnotations() { - return AnnotationParser.toArray(declaredAnnotations()); - } - - private transient Map, Annotation> declaredAnnotations; - - private synchronized Map, Annotation> declaredAnnotations() { - if (declaredAnnotations == null) { - declaredAnnotations = AnnotationParser.parseAnnotations( - annotations, sun.misc.SharedSecrets.getJavaLangAccess(). - getConstantPool(getDeclaringClass()), - getDeclaringClass()); - } - return declaredAnnotations; + throw new UnsupportedOperationException(); } /** @@ -721,16 +616,7 @@ public Object getDefaultValue() { if (annotationDefault == null) return null; - Class memberType = AnnotationType.invocationHandlerReturnType( - getReturnType()); - Object result = AnnotationParser.parseMemberValue( - memberType, ByteBuffer.wrap(annotationDefault), - sun.misc.SharedSecrets.getJavaLangAccess(). - getConstantPool(getDeclaringClass()), - getDeclaringClass()); - if (result instanceof sun.reflect.annotation.ExceptionProxy) - throw new AnnotationFormatError("Invalid default: " + this); - return result; + throw new UnsupportedOperationException(); } /** @@ -754,14 +640,6 @@ if (parameterAnnotations == null) return new Annotation[numParameters][0]; - Annotation[][] result = AnnotationParser.parseParameterAnnotations( - parameterAnnotations, - sun.misc.SharedSecrets.getJavaLangAccess(). - getConstantPool(getDeclaringClass()), - getDeclaringClass()); - if (result.length != numParameters) - throw new java.lang.annotation.AnnotationFormatError( - "Parameter annotations don't match number of parameters"); - return result; + throw new UnsupportedOperationException(); } } diff -r 9b0fbf4ec230 -r 1d03cb35fbda emul/src/main/java/java/lang/reflect/Modifier.java --- a/emul/src/main/java/java/lang/reflect/Modifier.java Tue Dec 04 14:08:19 2012 +0100 +++ b/emul/src/main/java/java/lang/reflect/Modifier.java Tue Dec 04 14:31:11 2012 +0100 @@ -25,10 +25,6 @@ package java.lang.reflect; -import java.security.AccessController; -import sun.reflect.LangReflectAccess; -import sun.reflect.ReflectionFactory; - /** * The Modifier class provides {@code static} methods and * constants to decode class and member access modifiers. The sets of @@ -46,17 +42,6 @@ public class Modifier { - /* - * Bootstrapping protocol between java.lang and java.lang.reflect - * packages - */ - static { - sun.reflect.ReflectionFactory factory = - AccessController.doPrivileged( - new ReflectionFactory.GetReflectionFactoryAction()); - factory.setLangReflectAccess(new java.lang.reflect.ReflectAccess()); - } - /** * Return {@code true} if the integer argument includes the * {@code public} modifier, {@code false} otherwise.