feat(jdk8): move files to new folder to avoid resources compiled.

This commit is contained in:
2025-09-07 15:25:52 +08:00
parent 3f0047bf6f
commit 8c35cfb1c0
17415 changed files with 217 additions and 213 deletions

View File

@@ -0,0 +1,716 @@
/*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.*;
import sun.misc.Unsafe;
/** Shared functionality for all accessor generators */
class AccessorGenerator implements ClassFileConstants {
static final Unsafe unsafe = Unsafe.getUnsafe();
// Constants because there's no way to say "short integer constant",
// i.e., "1S"
protected static final short S0 = (short) 0;
protected static final short S1 = (short) 1;
protected static final short S2 = (short) 2;
protected static final short S3 = (short) 3;
protected static final short S4 = (short) 4;
protected static final short S5 = (short) 5;
protected static final short S6 = (short) 6;
// Instance variables for shared functionality between
// FieldAccessorGenerator and MethodAccessorGenerator
protected ClassFileAssembler asm;
protected int modifiers;
protected short thisClass;
protected short superClass;
protected short targetClass;
// Common constant pool entries to FieldAccessor and MethodAccessor
protected short throwableClass;
protected short classCastClass;
protected short nullPointerClass;
protected short illegalArgumentClass;
protected short invocationTargetClass;
protected short initIdx;
protected short initNameAndTypeIdx;
protected short initStringNameAndTypeIdx;
protected short nullPointerCtorIdx;
protected short illegalArgumentCtorIdx;
protected short illegalArgumentStringCtorIdx;
protected short invocationTargetCtorIdx;
protected short superCtorIdx;
protected short objectClass;
protected short toStringIdx;
protected short codeIdx;
protected short exceptionsIdx;
// Boxing
protected short booleanIdx;
protected short booleanCtorIdx;
protected short booleanUnboxIdx;
protected short byteIdx;
protected short byteCtorIdx;
protected short byteUnboxIdx;
protected short characterIdx;
protected short characterCtorIdx;
protected short characterUnboxIdx;
protected short doubleIdx;
protected short doubleCtorIdx;
protected short doubleUnboxIdx;
protected short floatIdx;
protected short floatCtorIdx;
protected short floatUnboxIdx;
protected short integerIdx;
protected short integerCtorIdx;
protected short integerUnboxIdx;
protected short longIdx;
protected short longCtorIdx;
protected short longUnboxIdx;
protected short shortIdx;
protected short shortCtorIdx;
protected short shortUnboxIdx;
protected final short NUM_COMMON_CPOOL_ENTRIES = (short) 30;
protected final short NUM_BOXING_CPOOL_ENTRIES = (short) 72;
// Requires that superClass has been set up
protected void emitCommonConstantPoolEntries() {
// + [UTF-8] "java/lang/Throwable"
// + [CONSTANT_Class_info] for above
// + [UTF-8] "java/lang/ClassCastException"
// + [CONSTANT_Class_info] for above
// + [UTF-8] "java/lang/NullPointerException"
// + [CONSTANT_Class_info] for above
// + [UTF-8] "java/lang/IllegalArgumentException"
// + [CONSTANT_Class_info] for above
// + [UTF-8] "java/lang/InvocationTargetException"
// + [CONSTANT_Class_info] for above
// + [UTF-8] "<init>"
// + [UTF-8] "()V"
// + [CONSTANT_NameAndType_info] for above
// + [CONSTANT_Methodref_info] for NullPointerException's constructor
// + [CONSTANT_Methodref_info] for IllegalArgumentException's constructor
// + [UTF-8] "(Ljava/lang/String;)V"
// + [CONSTANT_NameAndType_info] for "<init>(Ljava/lang/String;)V"
// + [CONSTANT_Methodref_info] for IllegalArgumentException's constructor taking a String
// + [UTF-8] "(Ljava/lang/Throwable;)V"
// + [CONSTANT_NameAndType_info] for "<init>(Ljava/lang/Throwable;)V"
// + [CONSTANT_Methodref_info] for InvocationTargetException's constructor
// + [CONSTANT_Methodref_info] for "super()"
// + [UTF-8] "java/lang/Object"
// + [CONSTANT_Class_info] for above
// + [UTF-8] "toString"
// + [UTF-8] "()Ljava/lang/String;"
// + [CONSTANT_NameAndType_info] for "toString()Ljava/lang/String;"
// + [CONSTANT_Methodref_info] for Object's toString method
// + [UTF-8] "Code"
// + [UTF-8] "Exceptions"
asm.emitConstantPoolUTF8("java/lang/Throwable");
asm.emitConstantPoolClass(asm.cpi());
throwableClass = asm.cpi();
asm.emitConstantPoolUTF8("java/lang/ClassCastException");
asm.emitConstantPoolClass(asm.cpi());
classCastClass = asm.cpi();
asm.emitConstantPoolUTF8("java/lang/NullPointerException");
asm.emitConstantPoolClass(asm.cpi());
nullPointerClass = asm.cpi();
asm.emitConstantPoolUTF8("java/lang/IllegalArgumentException");
asm.emitConstantPoolClass(asm.cpi());
illegalArgumentClass = asm.cpi();
asm.emitConstantPoolUTF8("java/lang/reflect/InvocationTargetException");
asm.emitConstantPoolClass(asm.cpi());
invocationTargetClass = asm.cpi();
asm.emitConstantPoolUTF8("<init>");
initIdx = asm.cpi();
asm.emitConstantPoolUTF8("()V");
asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
initNameAndTypeIdx = asm.cpi();
asm.emitConstantPoolMethodref(nullPointerClass, initNameAndTypeIdx);
nullPointerCtorIdx = asm.cpi();
asm.emitConstantPoolMethodref(illegalArgumentClass, initNameAndTypeIdx);
illegalArgumentCtorIdx = asm.cpi();
asm.emitConstantPoolUTF8("(Ljava/lang/String;)V");
asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
initStringNameAndTypeIdx = asm.cpi();
asm.emitConstantPoolMethodref(illegalArgumentClass, initStringNameAndTypeIdx);
illegalArgumentStringCtorIdx = asm.cpi();
asm.emitConstantPoolUTF8("(Ljava/lang/Throwable;)V");
asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
asm.emitConstantPoolMethodref(invocationTargetClass, asm.cpi());
invocationTargetCtorIdx = asm.cpi();
asm.emitConstantPoolMethodref(superClass, initNameAndTypeIdx);
superCtorIdx = asm.cpi();
asm.emitConstantPoolUTF8("java/lang/Object");
asm.emitConstantPoolClass(asm.cpi());
objectClass = asm.cpi();
asm.emitConstantPoolUTF8("toString");
asm.emitConstantPoolUTF8("()Ljava/lang/String;");
asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
asm.emitConstantPoolMethodref(objectClass, asm.cpi());
toStringIdx = asm.cpi();
asm.emitConstantPoolUTF8("Code");
codeIdx = asm.cpi();
asm.emitConstantPoolUTF8("Exceptions");
exceptionsIdx = asm.cpi();
}
/** Constant pool entries required to be able to box/unbox primitive
types. Note that we don't emit these if we don't need them. */
protected void emitBoxingContantPoolEntries() {
// * [UTF-8] "java/lang/Boolean"
// * [CONSTANT_Class_info] for above
// * [UTF-8] "(Z)V"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "booleanValue"
// * [UTF-8] "()Z"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "java/lang/Byte"
// * [CONSTANT_Class_info] for above
// * [UTF-8] "(B)V"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "byteValue"
// * [UTF-8] "()B"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "java/lang/Character"
// * [CONSTANT_Class_info] for above
// * [UTF-8] "(C)V"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "charValue"
// * [UTF-8] "()C"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "java/lang/Double"
// * [CONSTANT_Class_info] for above
// * [UTF-8] "(D)V"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "doubleValue"
// * [UTF-8] "()D"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "java/lang/Float"
// * [CONSTANT_Class_info] for above
// * [UTF-8] "(F)V"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "floatValue"
// * [UTF-8] "()F"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "java/lang/Integer"
// * [CONSTANT_Class_info] for above
// * [UTF-8] "(I)V"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "intValue"
// * [UTF-8] "()I"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "java/lang/Long"
// * [CONSTANT_Class_info] for above
// * [UTF-8] "(J)V"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "longValue"
// * [UTF-8] "()J"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "java/lang/Short"
// * [CONSTANT_Class_info] for above
// * [UTF-8] "(S)V"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "shortValue"
// * [UTF-8] "()S"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// Boolean
asm.emitConstantPoolUTF8("java/lang/Boolean");
asm.emitConstantPoolClass(asm.cpi());
booleanIdx = asm.cpi();
asm.emitConstantPoolUTF8("(Z)V");
asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
booleanCtorIdx = asm.cpi();
asm.emitConstantPoolUTF8("booleanValue");
asm.emitConstantPoolUTF8("()Z");
asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());
booleanUnboxIdx = asm.cpi();
// Byte
asm.emitConstantPoolUTF8("java/lang/Byte");
asm.emitConstantPoolClass(asm.cpi());
byteIdx = asm.cpi();
asm.emitConstantPoolUTF8("(B)V");
asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
byteCtorIdx = asm.cpi();
asm.emitConstantPoolUTF8("byteValue");
asm.emitConstantPoolUTF8("()B");
asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());
byteUnboxIdx = asm.cpi();
// Character
asm.emitConstantPoolUTF8("java/lang/Character");
asm.emitConstantPoolClass(asm.cpi());
characterIdx = asm.cpi();
asm.emitConstantPoolUTF8("(C)V");
asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
characterCtorIdx = asm.cpi();
asm.emitConstantPoolUTF8("charValue");
asm.emitConstantPoolUTF8("()C");
asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());
characterUnboxIdx = asm.cpi();
// Double
asm.emitConstantPoolUTF8("java/lang/Double");
asm.emitConstantPoolClass(asm.cpi());
doubleIdx = asm.cpi();
asm.emitConstantPoolUTF8("(D)V");
asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
doubleCtorIdx = asm.cpi();
asm.emitConstantPoolUTF8("doubleValue");
asm.emitConstantPoolUTF8("()D");
asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());
doubleUnboxIdx = asm.cpi();
// Float
asm.emitConstantPoolUTF8("java/lang/Float");
asm.emitConstantPoolClass(asm.cpi());
floatIdx = asm.cpi();
asm.emitConstantPoolUTF8("(F)V");
asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
floatCtorIdx = asm.cpi();
asm.emitConstantPoolUTF8("floatValue");
asm.emitConstantPoolUTF8("()F");
asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());
floatUnboxIdx = asm.cpi();
// Integer
asm.emitConstantPoolUTF8("java/lang/Integer");
asm.emitConstantPoolClass(asm.cpi());
integerIdx = asm.cpi();
asm.emitConstantPoolUTF8("(I)V");
asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
integerCtorIdx = asm.cpi();
asm.emitConstantPoolUTF8("intValue");
asm.emitConstantPoolUTF8("()I");
asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());
integerUnboxIdx = asm.cpi();
// Long
asm.emitConstantPoolUTF8("java/lang/Long");
asm.emitConstantPoolClass(asm.cpi());
longIdx = asm.cpi();
asm.emitConstantPoolUTF8("(J)V");
asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
longCtorIdx = asm.cpi();
asm.emitConstantPoolUTF8("longValue");
asm.emitConstantPoolUTF8("()J");
asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());
longUnboxIdx = asm.cpi();
// Short
asm.emitConstantPoolUTF8("java/lang/Short");
asm.emitConstantPoolClass(asm.cpi());
shortIdx = asm.cpi();
asm.emitConstantPoolUTF8("(S)V");
asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
shortCtorIdx = asm.cpi();
asm.emitConstantPoolUTF8("shortValue");
asm.emitConstantPoolUTF8("()S");
asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());
shortUnboxIdx = asm.cpi();
}
// Necessary because of Java's annoying promotion rules
protected static short add(short s1, short s2) {
return (short) (s1 + s2);
}
protected static short sub(short s1, short s2) {
return (short) (s1 - s2);
}
protected boolean isStatic() {
return Modifier.isStatic(modifiers);
}
protected boolean isPrivate() {
return Modifier.isPrivate(modifiers);
}
/** Returns class name in "internal" form (i.e., '/' separators
instead of '.') */
protected static String getClassName
(Class<?> c, boolean addPrefixAndSuffixForNonPrimitiveTypes)
{
if (c.isPrimitive()) {
if (c == Boolean.TYPE) {
return "Z";
} else if (c == Byte.TYPE) {
return "B";
} else if (c == Character.TYPE) {
return "C";
} else if (c == Double.TYPE) {
return "D";
} else if (c == Float.TYPE) {
return "F";
} else if (c == Integer.TYPE) {
return "I";
} else if (c == Long.TYPE) {
return "J";
} else if (c == Short.TYPE) {
return "S";
} else if (c == Void.TYPE) {
return "V";
}
throw new InternalError("Should have found primitive type");
} else if (c.isArray()) {
return "[" + getClassName(c.getComponentType(), true);
} else {
if (addPrefixAndSuffixForNonPrimitiveTypes) {
return internalize("L" + c.getName() + ";");
} else {
return internalize(c.getName());
}
}
}
private static String internalize(String className) {
return className.replace('.', '/');
}
protected void emitConstructor() {
// Generate code into fresh code buffer
ClassFileAssembler cb = new ClassFileAssembler();
// 0 incoming arguments
cb.setMaxLocals(1);
cb.opc_aload_0();
cb.opc_invokespecial(superCtorIdx, 0, 0);
cb.opc_return();
// Emit method
emitMethod(initIdx, cb.getMaxLocals(), cb, null, null);
}
// The descriptor's index in the constant pool must be (1 +
// nameIdx). "numArgs" must indicate ALL arguments, including the
// implicit "this" argument; double and long arguments each count
// as 2 in this count. The code buffer must NOT contain the code
// length. The exception table may be null, but if non-null must
// NOT contain the exception table's length. The checked exception
// indices may be null.
protected void emitMethod(short nameIdx,
int numArgs,
ClassFileAssembler code,
ClassFileAssembler exceptionTable,
short[] checkedExceptionIndices)
{
int codeLen = code.getLength();
int excLen = 0;
if (exceptionTable != null) {
excLen = exceptionTable.getLength();
if ((excLen % 8) != 0) {
throw new IllegalArgumentException("Illegal exception table");
}
}
int attrLen = 12 + codeLen + excLen;
excLen = excLen / 8; // No-op if no exception table
asm.emitShort(ACC_PUBLIC);
asm.emitShort(nameIdx);
asm.emitShort(add(nameIdx, S1));
if (checkedExceptionIndices == null) {
// Code attribute only
asm.emitShort(S1);
} else {
// Code and Exceptions attributes
asm.emitShort(S2);
}
// Code attribute
asm.emitShort(codeIdx);
asm.emitInt(attrLen);
asm.emitShort(code.getMaxStack());
asm.emitShort((short) Math.max(numArgs, code.getMaxLocals()));
asm.emitInt(codeLen);
asm.append(code);
asm.emitShort((short) excLen);
if (exceptionTable != null) {
asm.append(exceptionTable);
}
asm.emitShort(S0); // No additional attributes for Code attribute
if (checkedExceptionIndices != null) {
// Exceptions attribute
asm.emitShort(exceptionsIdx);
asm.emitInt(2 + 2 * checkedExceptionIndices.length);
asm.emitShort((short) checkedExceptionIndices.length);
for (int i = 0; i < checkedExceptionIndices.length; i++) {
asm.emitShort(checkedExceptionIndices[i]);
}
}
}
protected short indexForPrimitiveType(Class<?> type) {
if (type == Boolean.TYPE) {
return booleanIdx;
} else if (type == Byte.TYPE) {
return byteIdx;
} else if (type == Character.TYPE) {
return characterIdx;
} else if (type == Double.TYPE) {
return doubleIdx;
} else if (type == Float.TYPE) {
return floatIdx;
} else if (type == Integer.TYPE) {
return integerIdx;
} else if (type == Long.TYPE) {
return longIdx;
} else if (type == Short.TYPE) {
return shortIdx;
}
throw new InternalError("Should have found primitive type");
}
protected short ctorIndexForPrimitiveType(Class<?> type) {
if (type == Boolean.TYPE) {
return booleanCtorIdx;
} else if (type == Byte.TYPE) {
return byteCtorIdx;
} else if (type == Character.TYPE) {
return characterCtorIdx;
} else if (type == Double.TYPE) {
return doubleCtorIdx;
} else if (type == Float.TYPE) {
return floatCtorIdx;
} else if (type == Integer.TYPE) {
return integerCtorIdx;
} else if (type == Long.TYPE) {
return longCtorIdx;
} else if (type == Short.TYPE) {
return shortCtorIdx;
}
throw new InternalError("Should have found primitive type");
}
/** Returns true for widening or identity conversions for primitive
types only */
protected static boolean canWidenTo(Class<?> type, Class<?> otherType) {
if (!type.isPrimitive()) {
return false;
}
// Widening conversions (from JVM spec):
// byte to short, int, long, float, or double
// short to int, long, float, or double
// char to int, long, float, or double
// int to long, float, or double
// long to float or double
// float to double
if (type == Boolean.TYPE) {
if (otherType == Boolean.TYPE) {
return true;
}
} else if (type == Byte.TYPE) {
if ( otherType == Byte.TYPE
|| otherType == Short.TYPE
|| otherType == Integer.TYPE
|| otherType == Long.TYPE
|| otherType == Float.TYPE
|| otherType == Double.TYPE) {
return true;
}
} else if (type == Short.TYPE) {
if ( otherType == Short.TYPE
|| otherType == Integer.TYPE
|| otherType == Long.TYPE
|| otherType == Float.TYPE
|| otherType == Double.TYPE) {
return true;
}
} else if (type == Character.TYPE) {
if ( otherType == Character.TYPE
|| otherType == Integer.TYPE
|| otherType == Long.TYPE
|| otherType == Float.TYPE
|| otherType == Double.TYPE) {
return true;
}
} else if (type == Integer.TYPE) {
if ( otherType == Integer.TYPE
|| otherType == Long.TYPE
|| otherType == Float.TYPE
|| otherType == Double.TYPE) {
return true;
}
} else if (type == Long.TYPE) {
if ( otherType == Long.TYPE
|| otherType == Float.TYPE
|| otherType == Double.TYPE) {
return true;
}
} else if (type == Float.TYPE) {
if ( otherType == Float.TYPE
|| otherType == Double.TYPE) {
return true;
}
} else if (type == Double.TYPE) {
if (otherType == Double.TYPE) {
return true;
}
}
return false;
}
/** Emits the widening bytecode for the given primitive conversion
(or none if the identity conversion). Requires that a primitive
conversion exists; i.e., canWidenTo must have already been
called and returned true. */
protected static void emitWideningBytecodeForPrimitiveConversion
(ClassFileAssembler cb,
Class<?> fromType,
Class<?> toType)
{
// Note that widening conversions for integral types (i.e., "b2s",
// "s2i") are no-ops since values on the Java stack are
// sign-extended.
// Widening conversions (from JVM spec):
// byte to short, int, long, float, or double
// short to int, long, float, or double
// char to int, long, float, or double
// int to long, float, or double
// long to float or double
// float to double
if ( fromType == Byte.TYPE
|| fromType == Short.TYPE
|| fromType == Character.TYPE
|| fromType == Integer.TYPE) {
if (toType == Long.TYPE) {
cb.opc_i2l();
} else if (toType == Float.TYPE) {
cb.opc_i2f();
} else if (toType == Double.TYPE) {
cb.opc_i2d();
}
} else if (fromType == Long.TYPE) {
if (toType == Float.TYPE) {
cb.opc_l2f();
} else if (toType == Double.TYPE) {
cb.opc_l2d();
}
} else if (fromType == Float.TYPE) {
if (toType == Double.TYPE) {
cb.opc_f2d();
}
}
// Otherwise, was identity or no-op conversion. Fall through.
}
protected short unboxingMethodForPrimitiveType(Class<?> primType) {
if (primType == Boolean.TYPE) {
return booleanUnboxIdx;
} else if (primType == Byte.TYPE) {
return byteUnboxIdx;
} else if (primType == Character.TYPE) {
return characterUnboxIdx;
} else if (primType == Short.TYPE) {
return shortUnboxIdx;
} else if (primType == Integer.TYPE) {
return integerUnboxIdx;
} else if (primType == Long.TYPE) {
return longUnboxIdx;
} else if (primType == Float.TYPE) {
return floatUnboxIdx;
} else if (primType == Double.TYPE) {
return doubleUnboxIdx;
}
throw new InternalError("Illegal primitive type " + primType.getName());
}
protected static final Class<?>[] primitiveTypes = new Class<?>[] {
Boolean.TYPE,
Byte.TYPE,
Character.TYPE,
Short.TYPE,
Integer.TYPE,
Long.TYPE,
Float.TYPE,
Double.TYPE
};
/** We don't consider "Void" to be a primitive type */
protected static boolean isPrimitive(Class<?> c) {
return (c.isPrimitive() && c != Void.TYPE);
}
protected int typeSizeInStackSlots(Class<?> c) {
if (c == Void.TYPE) {
return 0;
}
if (c == Long.TYPE || c == Double.TYPE) {
return 2;
}
return 1;
}
private ClassFileAssembler illegalArgumentCodeBuffer;
protected ClassFileAssembler illegalArgumentCodeBuffer() {
if (illegalArgumentCodeBuffer == null) {
illegalArgumentCodeBuffer = new ClassFileAssembler();
illegalArgumentCodeBuffer.opc_new(illegalArgumentClass);
illegalArgumentCodeBuffer.opc_dup();
illegalArgumentCodeBuffer.opc_invokespecial(illegalArgumentCtorIdx, 0, 0);
illegalArgumentCodeBuffer.opc_athrow();
}
return illegalArgumentCodeBuffer;
}
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Constructor;
/** Uses Unsafe.allocateObject() to instantiate classes; only used for
bootstrapping. */
class BootstrapConstructorAccessorImpl extends ConstructorAccessorImpl {
private final Constructor<?> constructor;
BootstrapConstructorAccessorImpl(Constructor<?> c) {
this.constructor = c;
}
public Object newInstance(Object[] args)
throws IllegalArgumentException, InvocationTargetException
{
try {
return UnsafeFieldAccessorImpl.unsafe.
allocateInstance(constructor.getDeclaringClass());
} catch (InstantiationException e) {
throw new InvocationTargetException(e);
}
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
/** A growable array of bytes. */
interface ByteVector {
public int getLength();
public byte get(int index);
public void put(int index, byte value);
public void add(byte value);
public void trim();
public byte[] getData();
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
class ByteVectorFactory {
static ByteVector create() {
return new ByteVectorImpl();
}
static ByteVector create(int sz) {
return new ByteVectorImpl(sz);
}
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
class ByteVectorImpl implements ByteVector {
private byte[] data;
private int pos;
public ByteVectorImpl() {
this(100);
}
public ByteVectorImpl(int sz) {
data = new byte[sz];
pos = -1;
}
public int getLength() {
return pos + 1;
}
public byte get(int index) {
if (index >= data.length) {
resize(index);
pos = index;
}
return data[index];
}
public void put(int index, byte value) {
if (index >= data.length) {
resize(index);
pos = index;
}
data[index] = value;
}
public void add(byte value) {
if (++pos >= data.length) {
resize(pos);
}
data[pos] = value;
}
public void trim() {
if (pos != data.length - 1) {
byte[] newData = new byte[pos + 1];
System.arraycopy(data, 0, newData, 0, pos + 1);
data = newData;
}
}
public byte[] getData() {
return data;
}
private void resize(int minSize) {
if (minSize <= 2 * data.length) {
minSize = 2 * data.length;
}
byte[] newData = new byte[minSize];
System.arraycopy(data, 0, newData, 0, data.length);
data = newData;
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
/**
* A method annotated @CallerSensitive is sensitive to its calling class,
* via {@link sun.reflect.Reflection#getCallerClass Reflection.getCallerClass},
* or via some equivalent.
*
* @author John R. Rose
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({METHOD})
public @interface CallerSensitive {
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.security.AccessController;
import java.security.PrivilegedAction;
import sun.misc.Unsafe;
/** Utility class which assists in calling Unsafe.defineClass() by
creating a new class loader which delegates to the one needed in
order for proper resolution of the given bytecodes to occur. */
class ClassDefiner {
static final Unsafe unsafe = Unsafe.getUnsafe();
/** <P> We define generated code into a new class loader which
delegates to the defining loader of the target class. It is
necessary for the VM to be able to resolve references to the
target class from the generated bytecodes, which could not occur
if the generated code was loaded into the bootstrap class
loader. </P>
<P> There are two primary reasons for creating a new loader
instead of defining these bytecodes directly into the defining
loader of the target class: first, it avoids any possible
security risk of having these bytecodes in the same loader.
Second, it allows the generated bytecodes to be unloaded earlier
than would otherwise be possible, decreasing run-time
footprint. </P>
*/
static Class<?> defineClass(String name, byte[] bytes, int off, int len,
final ClassLoader parentClassLoader)
{
ClassLoader newLoader = AccessController.doPrivileged(
new PrivilegedAction<ClassLoader>() {
public ClassLoader run() {
return new DelegatingClassLoader(parentClassLoader);
}
});
return unsafe.defineClass(name, bytes, off, len, newLoader, null);
}
}
// NOTE: this class's name and presence are known to the virtual
// machine as of the fix for 4474172.
class DelegatingClassLoader extends ClassLoader {
DelegatingClassLoader(ClassLoader parent) {
super(parent);
}
}

View File

@@ -0,0 +1,671 @@
/*
* Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
class ClassFileAssembler implements ClassFileConstants {
private ByteVector vec;
private short cpIdx = 0;
public ClassFileAssembler() {
this(ByteVectorFactory.create());
}
public ClassFileAssembler(ByteVector vec) {
this.vec = vec;
}
public ByteVector getData() {
return vec;
}
/** Length in bytes */
public short getLength() {
return (short) vec.getLength();
}
public void emitMagicAndVersion() {
emitInt(0xCAFEBABE);
emitShort((short) 0);
emitShort((short) 49);
}
public void emitInt(int val) {
emitByte((byte) (val >> 24));
emitByte((byte) ((val >> 16) & 0xFF));
emitByte((byte) ((val >> 8) & 0xFF));
emitByte((byte) (val & 0xFF));
}
public void emitShort(short val) {
emitByte((byte) ((val >> 8) & 0xFF));
emitByte((byte) (val & 0xFF));
}
// Support for labels; package-private
void emitShort(short bci, short val) {
vec.put(bci, (byte) ((val >> 8) & 0xFF));
vec.put(bci + 1, (byte) (val & 0xFF));
}
public void emitByte(byte val) {
vec.add(val);
}
public void append(ClassFileAssembler asm) {
append(asm.vec);
}
public void append(ByteVector vec) {
for (int i = 0; i < vec.getLength(); i++) {
emitByte(vec.get(i));
}
}
/** Keeps track of the current (one-based) constant pool index;
incremented after emitting one of the following constant pool
entries. Can fetch the current constant pool index for use in
later entries. Index points at the last valid constant pool
entry; initially invalid. It is illegal to fetch the constant
pool index before emitting at least one constant pool entry. */
public short cpi() {
if (cpIdx == 0) {
throw new RuntimeException("Illegal use of ClassFileAssembler");
}
return cpIdx;
}
public void emitConstantPoolUTF8(String str) {
// NOTE: can not use str.getBytes("UTF-8") here because of
// bootstrapping issues with the character set converters.
byte[] bytes = UTF8.encode(str);
emitByte(CONSTANT_Utf8);
emitShort((short) bytes.length);
for (int i = 0; i < bytes.length; i++) {
emitByte(bytes[i]);
}
cpIdx++;
}
public void emitConstantPoolClass(short index) {
emitByte(CONSTANT_Class);
emitShort(index);
cpIdx++;
}
public void emitConstantPoolNameAndType(short nameIndex, short typeIndex) {
emitByte(CONSTANT_NameAndType);
emitShort(nameIndex);
emitShort(typeIndex);
cpIdx++;
}
public void emitConstantPoolFieldref
(short classIndex, short nameAndTypeIndex)
{
emitByte(CONSTANT_Fieldref);
emitShort(classIndex);
emitShort(nameAndTypeIndex);
cpIdx++;
}
public void emitConstantPoolMethodref
(short classIndex, short nameAndTypeIndex)
{
emitByte(CONSTANT_Methodref);
emitShort(classIndex);
emitShort(nameAndTypeIndex);
cpIdx++;
}
public void emitConstantPoolInterfaceMethodref
(short classIndex, short nameAndTypeIndex)
{
emitByte(CONSTANT_InterfaceMethodref);
emitShort(classIndex);
emitShort(nameAndTypeIndex);
cpIdx++;
}
public void emitConstantPoolString(short utf8Index) {
emitByte(CONSTANT_String);
emitShort(utf8Index);
cpIdx++;
}
//----------------------------------------------------------------------
// Opcodes. Keeps track of maximum stack and locals. Make a new
// assembler for each piece of assembled code, then append the
// result to the previous assembler's class file.
//
private int stack = 0;
private int maxStack = 0;
private int maxLocals = 0;
private void incStack() {
setStack(stack + 1);
}
private void decStack() {
--stack;
}
public short getMaxStack() {
return (short) maxStack;
}
public short getMaxLocals() {
return (short) maxLocals;
}
/** It's necessary to be able to specify the number of arguments at
the beginning of the method (which translates to the initial
value of max locals) */
public void setMaxLocals(int maxLocals) {
this.maxLocals = maxLocals;
}
/** Needed to do flow control. Returns current stack depth. */
public int getStack() {
return stack;
}
/** Needed to do flow control. */
public void setStack(int value) {
stack = value;
if (stack > maxStack) {
maxStack = stack;
}
}
///////////////
// Constants //
///////////////
public void opc_aconst_null() {
emitByte(opc_aconst_null);
incStack();
}
public void opc_sipush(short constant) {
emitByte(opc_sipush);
emitShort(constant);
incStack();
}
public void opc_ldc(byte cpIdx) {
emitByte(opc_ldc);
emitByte(cpIdx);
incStack();
}
/////////////////////////////////////
// Local variable loads and stores //
/////////////////////////////////////
public void opc_iload_0() {
emitByte(opc_iload_0);
if (maxLocals < 1) maxLocals = 1;
incStack();
}
public void opc_iload_1() {
emitByte(opc_iload_1);
if (maxLocals < 2) maxLocals = 2;
incStack();
}
public void opc_iload_2() {
emitByte(opc_iload_2);
if (maxLocals < 3) maxLocals = 3;
incStack();
}
public void opc_iload_3() {
emitByte(opc_iload_3);
if (maxLocals < 4) maxLocals = 4;
incStack();
}
public void opc_lload_0() {
emitByte(opc_lload_0);
if (maxLocals < 2) maxLocals = 2;
incStack();
incStack();
}
public void opc_lload_1() {
emitByte(opc_lload_1);
if (maxLocals < 3) maxLocals = 3;
incStack();
incStack();
}
public void opc_lload_2() {
emitByte(opc_lload_2);
if (maxLocals < 4) maxLocals = 4;
incStack();
incStack();
}
public void opc_lload_3() {
emitByte(opc_lload_3);
if (maxLocals < 5) maxLocals = 5;
incStack();
incStack();
}
public void opc_fload_0() {
emitByte(opc_fload_0);
if (maxLocals < 1) maxLocals = 1;
incStack();
}
public void opc_fload_1() {
emitByte(opc_fload_1);
if (maxLocals < 2) maxLocals = 2;
incStack();
}
public void opc_fload_2() {
emitByte(opc_fload_2);
if (maxLocals < 3) maxLocals = 3;
incStack();
}
public void opc_fload_3() {
emitByte(opc_fload_3);
if (maxLocals < 4) maxLocals = 4;
incStack();
}
public void opc_dload_0() {
emitByte(opc_dload_0);
if (maxLocals < 2) maxLocals = 2;
incStack();
incStack();
}
public void opc_dload_1() {
emitByte(opc_dload_1);
if (maxLocals < 3) maxLocals = 3;
incStack();
incStack();
}
public void opc_dload_2() {
emitByte(opc_dload_2);
if (maxLocals < 4) maxLocals = 4;
incStack();
incStack();
}
public void opc_dload_3() {
emitByte(opc_dload_3);
if (maxLocals < 5) maxLocals = 5;
incStack();
incStack();
}
public void opc_aload_0() {
emitByte(opc_aload_0);
if (maxLocals < 1) maxLocals = 1;
incStack();
}
public void opc_aload_1() {
emitByte(opc_aload_1);
if (maxLocals < 2) maxLocals = 2;
incStack();
}
public void opc_aload_2() {
emitByte(opc_aload_2);
if (maxLocals < 3) maxLocals = 3;
incStack();
}
public void opc_aload_3() {
emitByte(opc_aload_3);
if (maxLocals < 4) maxLocals = 4;
incStack();
}
public void opc_aaload() {
emitByte(opc_aaload);
decStack();
}
public void opc_astore_0() {
emitByte(opc_astore_0);
if (maxLocals < 1) maxLocals = 1;
decStack();
}
public void opc_astore_1() {
emitByte(opc_astore_1);
if (maxLocals < 2) maxLocals = 2;
decStack();
}
public void opc_astore_2() {
emitByte(opc_astore_2);
if (maxLocals < 3) maxLocals = 3;
decStack();
}
public void opc_astore_3() {
emitByte(opc_astore_3);
if (maxLocals < 4) maxLocals = 4;
decStack();
}
////////////////////////
// Stack manipulation //
////////////////////////
public void opc_pop() {
emitByte(opc_pop);
decStack();
}
public void opc_dup() {
emitByte(opc_dup);
incStack();
}
public void opc_dup_x1() {
emitByte(opc_dup_x1);
incStack();
}
public void opc_swap() {
emitByte(opc_swap);
}
///////////////////////////////
// Widening conversions only //
///////////////////////////////
public void opc_i2l() {
emitByte(opc_i2l);
}
public void opc_i2f() {
emitByte(opc_i2f);
}
public void opc_i2d() {
emitByte(opc_i2d);
}
public void opc_l2f() {
emitByte(opc_l2f);
}
public void opc_l2d() {
emitByte(opc_l2d);
}
public void opc_f2d() {
emitByte(opc_f2d);
}
//////////////////
// Control flow //
//////////////////
public void opc_ifeq(short bciOffset) {
emitByte(opc_ifeq);
emitShort(bciOffset);
decStack();
}
/** Control flow with forward-reference BCI. Stack assumes
straight-through control flow. */
public void opc_ifeq(Label l) {
short instrBCI = getLength();
emitByte(opc_ifeq);
l.add(this, instrBCI, getLength(), getStack() - 1);
emitShort((short) -1); // Must be patched later
}
public void opc_if_icmpeq(short bciOffset) {
emitByte(opc_if_icmpeq);
emitShort(bciOffset);
setStack(getStack() - 2);
}
/** Control flow with forward-reference BCI. Stack assumes straight
control flow. */
public void opc_if_icmpeq(Label l) {
short instrBCI = getLength();
emitByte(opc_if_icmpeq);
l.add(this, instrBCI, getLength(), getStack() - 2);
emitShort((short) -1); // Must be patched later
}
public void opc_goto(short bciOffset) {
emitByte(opc_goto);
emitShort(bciOffset);
}
/** Control flow with forward-reference BCI. Stack assumes straight
control flow. */
public void opc_goto(Label l) {
short instrBCI = getLength();
emitByte(opc_goto);
l.add(this, instrBCI, getLength(), getStack());
emitShort((short) -1); // Must be patched later
}
public void opc_ifnull(short bciOffset) {
emitByte(opc_ifnull);
emitShort(bciOffset);
decStack();
}
/** Control flow with forward-reference BCI. Stack assumes straight
control flow. */
public void opc_ifnull(Label l) {
short instrBCI = getLength();
emitByte(opc_ifnull);
l.add(this, instrBCI, getLength(), getStack() - 1);
emitShort((short) -1); // Must be patched later
decStack();
}
public void opc_ifnonnull(short bciOffset) {
emitByte(opc_ifnonnull);
emitShort(bciOffset);
decStack();
}
/** Control flow with forward-reference BCI. Stack assumes straight
control flow. */
public void opc_ifnonnull(Label l) {
short instrBCI = getLength();
emitByte(opc_ifnonnull);
l.add(this, instrBCI, getLength(), getStack() - 1);
emitShort((short) -1); // Must be patched later
decStack();
}
/////////////////////////
// Return instructions //
/////////////////////////
public void opc_ireturn() {
emitByte(opc_ireturn);
setStack(0);
}
public void opc_lreturn() {
emitByte(opc_lreturn);
setStack(0);
}
public void opc_freturn() {
emitByte(opc_freturn);
setStack(0);
}
public void opc_dreturn() {
emitByte(opc_dreturn);
setStack(0);
}
public void opc_areturn() {
emitByte(opc_areturn);
setStack(0);
}
public void opc_return() {
emitByte(opc_return);
setStack(0);
}
//////////////////////
// Field operations //
//////////////////////
public void opc_getstatic(short fieldIndex, int fieldSizeInStackSlots) {
emitByte(opc_getstatic);
emitShort(fieldIndex);
setStack(getStack() + fieldSizeInStackSlots);
}
public void opc_putstatic(short fieldIndex, int fieldSizeInStackSlots) {
emitByte(opc_putstatic);
emitShort(fieldIndex);
setStack(getStack() - fieldSizeInStackSlots);
}
public void opc_getfield(short fieldIndex, int fieldSizeInStackSlots) {
emitByte(opc_getfield);
emitShort(fieldIndex);
setStack(getStack() + fieldSizeInStackSlots - 1);
}
public void opc_putfield(short fieldIndex, int fieldSizeInStackSlots) {
emitByte(opc_putfield);
emitShort(fieldIndex);
setStack(getStack() - fieldSizeInStackSlots - 1);
}
////////////////////////
// Method invocations //
////////////////////////
/** Long and double arguments and return types count as 2 arguments;
other values count as 1. */
public void opc_invokevirtual(short methodIndex,
int numArgs,
int numReturnValues)
{
emitByte(opc_invokevirtual);
emitShort(methodIndex);
setStack(getStack() - numArgs - 1 + numReturnValues);
}
/** Long and double arguments and return types count as 2 arguments;
other values count as 1. */
public void opc_invokespecial(short methodIndex,
int numArgs,
int numReturnValues)
{
emitByte(opc_invokespecial);
emitShort(methodIndex);
setStack(getStack() - numArgs - 1 + numReturnValues);
}
/** Long and double arguments and return types count as 2 arguments;
other values count as 1. */
public void opc_invokestatic(short methodIndex,
int numArgs,
int numReturnValues)
{
emitByte(opc_invokestatic);
emitShort(methodIndex);
setStack(getStack() - numArgs + numReturnValues);
}
/** Long and double arguments and return types count as 2 arguments;
other values count as 1. */
public void opc_invokeinterface(short methodIndex,
int numArgs,
byte count,
int numReturnValues)
{
emitByte(opc_invokeinterface);
emitShort(methodIndex);
emitByte(count);
emitByte((byte) 0);
setStack(getStack() - numArgs - 1 + numReturnValues);
}
//////////////////
// Array length //
//////////////////
public void opc_arraylength() {
emitByte(opc_arraylength);
}
/////////
// New //
/////////
public void opc_new(short classIndex) {
emitByte(opc_new);
emitShort(classIndex);
incStack();
}
////////////
// Athrow //
////////////
public void opc_athrow() {
emitByte(opc_athrow);
setStack(1);
}
//////////////////////////////
// Checkcast and instanceof //
//////////////////////////////
/** Assumes the checkcast succeeds */
public void opc_checkcast(short classIndex) {
emitByte(opc_checkcast);
emitShort(classIndex);
}
public void opc_instanceof(short classIndex) {
emitByte(opc_instanceof);
emitShort(classIndex);
}
}

View File

@@ -0,0 +1,140 @@
/*
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
/** Minimal set of class file constants for assembly of field and
method accessors. */
interface ClassFileConstants {
// Constants
public static final byte opc_aconst_null = (byte) 0x1;
public static final byte opc_sipush = (byte) 0x11;
public static final byte opc_ldc = (byte) 0x12;
// Local variable loads and stores
public static final byte opc_iload_0 = (byte) 0x1a;
public static final byte opc_iload_1 = (byte) 0x1b;
public static final byte opc_iload_2 = (byte) 0x1c;
public static final byte opc_iload_3 = (byte) 0x1d;
public static final byte opc_lload_0 = (byte) 0x1e;
public static final byte opc_lload_1 = (byte) 0x1f;
public static final byte opc_lload_2 = (byte) 0x20;
public static final byte opc_lload_3 = (byte) 0x21;
public static final byte opc_fload_0 = (byte) 0x22;
public static final byte opc_fload_1 = (byte) 0x23;
public static final byte opc_fload_2 = (byte) 0x24;
public static final byte opc_fload_3 = (byte) 0x25;
public static final byte opc_dload_0 = (byte) 0x26;
public static final byte opc_dload_1 = (byte) 0x27;
public static final byte opc_dload_2 = (byte) 0x28;
public static final byte opc_dload_3 = (byte) 0x29;
public static final byte opc_aload_0 = (byte) 0x2a;
public static final byte opc_aload_1 = (byte) 0x2b;
public static final byte opc_aload_2 = (byte) 0x2c;
public static final byte opc_aload_3 = (byte) 0x2d;
public static final byte opc_aaload = (byte) 0x32;
public static final byte opc_astore_0 = (byte) 0x4b;
public static final byte opc_astore_1 = (byte) 0x4c;
public static final byte opc_astore_2 = (byte) 0x4d;
public static final byte opc_astore_3 = (byte) 0x4e;
// Stack manipulation
public static final byte opc_pop = (byte) 0x57;
public static final byte opc_dup = (byte) 0x59;
public static final byte opc_dup_x1 = (byte) 0x5a;
public static final byte opc_swap = (byte) 0x5f;
// Conversions
public static final byte opc_i2l = (byte) 0x85;
public static final byte opc_i2f = (byte) 0x86;
public static final byte opc_i2d = (byte) 0x87;
public static final byte opc_l2i = (byte) 0x88;
public static final byte opc_l2f = (byte) 0x89;
public static final byte opc_l2d = (byte) 0x8a;
public static final byte opc_f2i = (byte) 0x8b;
public static final byte opc_f2l = (byte) 0x8c;
public static final byte opc_f2d = (byte) 0x8d;
public static final byte opc_d2i = (byte) 0x8e;
public static final byte opc_d2l = (byte) 0x8f;
public static final byte opc_d2f = (byte) 0x90;
public static final byte opc_i2b = (byte) 0x91;
public static final byte opc_i2c = (byte) 0x92;
public static final byte opc_i2s = (byte) 0x93;
// Control flow
public static final byte opc_ifeq = (byte) 0x99;
public static final byte opc_if_icmpeq = (byte) 0x9f;
public static final byte opc_goto = (byte) 0xa7;
// Return instructions
public static final byte opc_ireturn = (byte) 0xac;
public static final byte opc_lreturn = (byte) 0xad;
public static final byte opc_freturn = (byte) 0xae;
public static final byte opc_dreturn = (byte) 0xaf;
public static final byte opc_areturn = (byte) 0xb0;
public static final byte opc_return = (byte) 0xb1;
// Field operations
public static final byte opc_getstatic = (byte) 0xb2;
public static final byte opc_putstatic = (byte) 0xb3;
public static final byte opc_getfield = (byte) 0xb4;
public static final byte opc_putfield = (byte) 0xb5;
// Method invocations
public static final byte opc_invokevirtual = (byte) 0xb6;
public static final byte opc_invokespecial = (byte) 0xb7;
public static final byte opc_invokestatic = (byte) 0xb8;
public static final byte opc_invokeinterface = (byte) 0xb9;
// Array length
public static final byte opc_arraylength = (byte) 0xbe;
// New
public static final byte opc_new = (byte) 0xbb;
// Athrow
public static final byte opc_athrow = (byte) 0xbf;
// Checkcast and instanceof
public static final byte opc_checkcast = (byte) 0xc0;
public static final byte opc_instanceof = (byte) 0xc1;
// Ifnull and ifnonnull
public static final byte opc_ifnull = (byte) 0xc6;
public static final byte opc_ifnonnull = (byte) 0xc7;
// Constant pool tags
public static final byte CONSTANT_Class = (byte) 7;
public static final byte CONSTANT_Fieldref = (byte) 9;
public static final byte CONSTANT_Methodref = (byte) 10;
public static final byte CONSTANT_InterfaceMethodref = (byte) 11;
public static final byte CONSTANT_NameAndType = (byte) 12;
public static final byte CONSTANT_String = (byte) 8;
public static final byte CONSTANT_Utf8 = (byte) 1;
// Access flags
public static final short ACC_PUBLIC = (short) 0x0001;
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.*;
/** Provides reflective access to the constant pools of classes.
Currently this is needed to provide reflective access to annotations
but may be used by other internal subsystems in the future. */
public class ConstantPool {
// Number of entries in this constant pool (= maximum valid constant pool index)
public int getSize() { return getSize0 (constantPoolOop); }
public Class<?> getClassAt (int index) { return getClassAt0 (constantPoolOop, index); }
public Class<?> getClassAtIfLoaded (int index) { return getClassAtIfLoaded0 (constantPoolOop, index); }
// Returns either a Method or Constructor.
// Static initializers are returned as Method objects.
public Member getMethodAt (int index) { return getMethodAt0 (constantPoolOop, index); }
public Member getMethodAtIfLoaded(int index) { return getMethodAtIfLoaded0(constantPoolOop, index); }
public Field getFieldAt (int index) { return getFieldAt0 (constantPoolOop, index); }
public Field getFieldAtIfLoaded (int index) { return getFieldAtIfLoaded0 (constantPoolOop, index); }
// Fetches the class name, member (field, method or interface
// method) name, and type descriptor as an array of three Strings
public String[] getMemberRefInfoAt (int index) { return getMemberRefInfoAt0 (constantPoolOop, index); }
public int getIntAt (int index) { return getIntAt0 (constantPoolOop, index); }
public long getLongAt (int index) { return getLongAt0 (constantPoolOop, index); }
public float getFloatAt (int index) { return getFloatAt0 (constantPoolOop, index); }
public double getDoubleAt (int index) { return getDoubleAt0 (constantPoolOop, index); }
public String getStringAt (int index) { return getStringAt0 (constantPoolOop, index); }
public String getUTF8At (int index) { return getUTF8At0 (constantPoolOop, index); }
//---------------------------------------------------------------------------
// Internals only below this point
//
static {
Reflection.registerFieldsToFilter(ConstantPool.class, new String[] { "constantPoolOop" });
}
// HotSpot-internal constant pool object (set by the VM, name known to the VM)
private Object constantPoolOop;
private native int getSize0 (Object constantPoolOop);
private native Class<?> getClassAt0 (Object constantPoolOop, int index);
private native Class<?> getClassAtIfLoaded0 (Object constantPoolOop, int index);
private native Member getMethodAt0 (Object constantPoolOop, int index);
private native Member getMethodAtIfLoaded0(Object constantPoolOop, int index);
private native Field getFieldAt0 (Object constantPoolOop, int index);
private native Field getFieldAtIfLoaded0 (Object constantPoolOop, int index);
private native String[] getMemberRefInfoAt0 (Object constantPoolOop, int index);
private native int getIntAt0 (Object constantPoolOop, int index);
private native long getLongAt0 (Object constantPoolOop, int index);
private native float getFloatAt0 (Object constantPoolOop, int index);
private native double getDoubleAt0 (Object constantPoolOop, int index);
private native String getStringAt0 (Object constantPoolOop, int index);
private native String getUTF8At0 (Object constantPoolOop, int index);
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.InvocationTargetException;
/** This interface provides the declaration for
java.lang.reflect.Constructor.invoke(). Each Constructor object is
configured with a (possibly dynamically-generated) class which
implements this interface. */
public interface ConstructorAccessor {
/** Matches specification in {@link java.lang.reflect.Constructor} */
public Object newInstance(Object[] args)
throws InstantiationException,
IllegalArgumentException,
InvocationTargetException;
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.InvocationTargetException;
/** Package-private implementation of the ConstructorAccessor
interface which has access to all classes and all fields,
regardless of language restrictions. See MagicAccessorImpl. */
abstract class ConstructorAccessorImpl extends MagicAccessorImpl
implements ConstructorAccessor {
/** Matches specification in {@link java.lang.reflect.Constructor} */
public abstract Object newInstance(Object[] args)
throws InstantiationException,
IllegalArgumentException,
InvocationTargetException;
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.InvocationTargetException;
/** Delegates its invocation to another ConstructorAccessorImpl and can
change its delegate at run time. */
class DelegatingConstructorAccessorImpl extends ConstructorAccessorImpl {
private ConstructorAccessorImpl delegate;
DelegatingConstructorAccessorImpl(ConstructorAccessorImpl delegate) {
setDelegate(delegate);
}
public Object newInstance(Object[] args)
throws InstantiationException,
IllegalArgumentException,
InvocationTargetException
{
return delegate.newInstance(args);
}
void setDelegate(ConstructorAccessorImpl delegate) {
this.delegate = delegate;
}
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.InvocationTargetException;
/** Delegates its invocation to another MethodAccessorImpl and can
change its delegate at run time. */
class DelegatingMethodAccessorImpl extends MethodAccessorImpl {
private MethodAccessorImpl delegate;
DelegatingMethodAccessorImpl(MethodAccessorImpl delegate) {
setDelegate(delegate);
}
public Object invoke(Object obj, Object[] args)
throws IllegalArgumentException, InvocationTargetException
{
return delegate.invoke(obj, args);
}
void setDelegate(MethodAccessorImpl delegate) {
this.delegate = delegate;
}
}

View File

@@ -0,0 +1,96 @@
/*
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
/** This interface provides the declarations for the accessor methods
of java.lang.reflect.Field. Each Field object is configured with a
(possibly dynamically-generated) class which implements this
interface. */
public interface FieldAccessor {
/** Matches specification in {@link java.lang.reflect.Field} */
public Object get(Object obj) throws IllegalArgumentException;
/** Matches specification in {@link java.lang.reflect.Field} */
public boolean getBoolean(Object obj) throws IllegalArgumentException;
/** Matches specification in {@link java.lang.reflect.Field} */
public byte getByte(Object obj) throws IllegalArgumentException;
/** Matches specification in {@link java.lang.reflect.Field} */
public char getChar(Object obj) throws IllegalArgumentException;
/** Matches specification in {@link java.lang.reflect.Field} */
public short getShort(Object obj) throws IllegalArgumentException;
/** Matches specification in {@link java.lang.reflect.Field} */
public int getInt(Object obj) throws IllegalArgumentException;
/** Matches specification in {@link java.lang.reflect.Field} */
public long getLong(Object obj) throws IllegalArgumentException;
/** Matches specification in {@link java.lang.reflect.Field} */
public float getFloat(Object obj) throws IllegalArgumentException;
/** Matches specification in {@link java.lang.reflect.Field} */
public double getDouble(Object obj) throws IllegalArgumentException;
/** Matches specification in {@link java.lang.reflect.Field} */
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException;
/** Matches specification in {@link java.lang.reflect.Field} */
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException;
/** Matches specification in {@link java.lang.reflect.Field} */
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException;
/** Matches specification in {@link java.lang.reflect.Field} */
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException;
/** Matches specification in {@link java.lang.reflect.Field} */
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException;
/** Matches specification in {@link java.lang.reflect.Field} */
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException;
/** Matches specification in {@link java.lang.reflect.Field} */
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException;
/** Matches specification in {@link java.lang.reflect.Field} */
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException;
/** Matches specification in {@link java.lang.reflect.Field} */
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException;
}

View File

@@ -0,0 +1,105 @@
/*
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
/** Package-private implementation of the FieldAccessor interface
which has access to all classes and all fields, regardless of
language restrictions. See MagicAccessorImpl. */
abstract class FieldAccessorImpl extends MagicAccessorImpl
implements FieldAccessor {
/** Matches specification in {@link java.lang.reflect.Field} */
public abstract Object get(Object obj)
throws IllegalArgumentException;
/** Matches specification in {@link java.lang.reflect.Field} */
public abstract boolean getBoolean(Object obj)
throws IllegalArgumentException;
/** Matches specification in {@link java.lang.reflect.Field} */
public abstract byte getByte(Object obj)
throws IllegalArgumentException;
/** Matches specification in {@link java.lang.reflect.Field} */
public abstract char getChar(Object obj)
throws IllegalArgumentException;
/** Matches specification in {@link java.lang.reflect.Field} */
public abstract short getShort(Object obj)
throws IllegalArgumentException;
/** Matches specification in {@link java.lang.reflect.Field} */
public abstract int getInt(Object obj)
throws IllegalArgumentException;
/** Matches specification in {@link java.lang.reflect.Field} */
public abstract long getLong(Object obj)
throws IllegalArgumentException;
/** Matches specification in {@link java.lang.reflect.Field} */
public abstract float getFloat(Object obj)
throws IllegalArgumentException;
/** Matches specification in {@link java.lang.reflect.Field} */
public abstract double getDouble(Object obj)
throws IllegalArgumentException;
/** Matches specification in {@link java.lang.reflect.Field} */
public abstract void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException;
/** Matches specification in {@link java.lang.reflect.Field} */
public abstract void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException;
/** Matches specification in {@link java.lang.reflect.Field} */
public abstract void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException;
/** Matches specification in {@link java.lang.reflect.Field} */
public abstract void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException;
/** Matches specification in {@link java.lang.reflect.Field} */
public abstract void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException;
/** Matches specification in {@link java.lang.reflect.Field} */
public abstract void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException;
/** Matches specification in {@link java.lang.reflect.Field} */
public abstract void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException;
/** Matches specification in {@link java.lang.reflect.Field} */
public abstract void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException;
/** Matches specification in {@link java.lang.reflect.Field} */
public abstract void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException;
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
/** NOTE: obsolete as of JDK 1.4 B75 and should be removed from the
workspace (FIXME) */
public class FieldInfo {
// Set by the VM directly. Do not move these fields around or add
// others before (or after) them without also modifying the VM's code.
private String name;
private String signature;
private int modifiers;
// This is compatible with the old reflection implementation's
// "slot" value to allow sun.misc.Unsafe to work
private int slot;
// Not really necessary to provide a constructor since the VM
// creates these directly
FieldInfo() {
}
public String name() {
return name;
}
/** This is in "external" format, i.e. having '.' as separator
rather than '/' */
public String signature() {
return signature;
}
public int modifiers() {
return modifiers;
}
public int slot() {
return slot;
}
/** Convenience routine */
public boolean isPublic() {
return (Modifier.isPublic(modifiers()));
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/** Throws an InstantiationException with given error message upon
newInstance() call */
class InstantiationExceptionConstructorAccessorImpl
extends ConstructorAccessorImpl {
private final String message;
InstantiationExceptionConstructorAccessorImpl(String message) {
this.message = message;
}
public Object newInstance(Object[] args)
throws InstantiationException,
IllegalArgumentException,
InvocationTargetException
{
if (message == null) {
throw new InstantiationException();
}
throw new InstantiationException(message);
}
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.util.List;
import java.util.ArrayList;
/** Allows forward references in bytecode streams emitted by
ClassFileAssembler. Assumes that the start of the method body is
the first byte in the assembler's buffer. May be used at more than
one branch site. */
class Label {
static class PatchInfo {
PatchInfo(ClassFileAssembler asm,
short instrBCI,
short patchBCI,
int stackDepth)
{
this.asm = asm;
this.instrBCI = instrBCI;
this.patchBCI = patchBCI;
this.stackDepth = stackDepth;
}
// This won't work for more than one assembler anyway, so this is
// unnecessary
final ClassFileAssembler asm;
final short instrBCI;
final short patchBCI;
final int stackDepth;
}
private List<PatchInfo> patches = new ArrayList<>();
public Label() {
}
void add(ClassFileAssembler asm,
short instrBCI,
short patchBCI,
int stackDepth)
{
patches.add(new PatchInfo(asm, instrBCI, patchBCI, stackDepth));
}
public void bind() {
for (PatchInfo patch : patches){
short curBCI = patch.asm.getLength();
short offset = (short) (curBCI - patch.instrBCI);
patch.asm.emitShort(patch.patchBCI, offset);
patch.asm.setStack(patch.stackDepth);
}
}
}

View File

@@ -0,0 +1,112 @@
/*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.*;
/** An interface which gives privileged packages Java-level access to
internals of java.lang.reflect. */
public interface LangReflectAccess {
/** Creates a new java.lang.reflect.Field. Access checks as per
java.lang.reflect.AccessibleObject are not overridden. */
public Field newField(Class<?> declaringClass,
String name,
Class<?> type,
int modifiers,
int slot,
String signature,
byte[] annotations);
/** Creates a new java.lang.reflect.Method. Access checks as per
java.lang.reflect.AccessibleObject are not overridden. */
public Method newMethod(Class<?> declaringClass,
String name,
Class<?>[] parameterTypes,
Class<?> returnType,
Class<?>[] checkedExceptions,
int modifiers,
int slot,
String signature,
byte[] annotations,
byte[] parameterAnnotations,
byte[] annotationDefault);
/** Creates a new java.lang.reflect.Constructor. Access checks as
per java.lang.reflect.AccessibleObject are not overridden. */
public <T> Constructor<T> newConstructor(Class<T> declaringClass,
Class<?>[] parameterTypes,
Class<?>[] checkedExceptions,
int modifiers,
int slot,
String signature,
byte[] annotations,
byte[] parameterAnnotations);
/** Gets the MethodAccessor object for a java.lang.reflect.Method */
public MethodAccessor getMethodAccessor(Method m);
/** Sets the MethodAccessor object for a java.lang.reflect.Method */
public void setMethodAccessor(Method m, MethodAccessor accessor);
/** Gets the ConstructorAccessor object for a
java.lang.reflect.Constructor */
public ConstructorAccessor getConstructorAccessor(Constructor<?> c);
/** Sets the ConstructorAccessor object for a
java.lang.reflect.Constructor */
public void setConstructorAccessor(Constructor<?> c,
ConstructorAccessor accessor);
/** Gets the byte[] that encodes TypeAnnotations on an Executable. */
public byte[] getExecutableTypeAnnotationBytes(Executable ex);
/** Gets the "slot" field from a Constructor (used for serialization) */
public int getConstructorSlot(Constructor<?> c);
/** Gets the "signature" field from a Constructor (used for serialization) */
public String getConstructorSignature(Constructor<?> c);
/** Gets the "annotations" field from a Constructor (used for serialization) */
public byte[] getConstructorAnnotations(Constructor<?> c);
/** Gets the "parameterAnnotations" field from a Constructor (used for serialization) */
public byte[] getConstructorParameterAnnotations(Constructor<?> c);
//
// Copying routines, needed to quickly fabricate new Field,
// Method, and Constructor objects from templates
//
/** Makes a "child" copy of a Method */
public Method copyMethod(Method arg);
/** Makes a "child" copy of a Field */
public Field copyField(Field arg);
/** Makes a "child" copy of a Constructor */
public <T> Constructor<T> copyConstructor(Constructor<T> arg);
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
/** <P> MagicAccessorImpl (named for parity with FieldAccessorImpl and
others, not because it actually implements an interface) is a
marker class in the hierarchy. All subclasses of this class are
"magically" granted access by the VM to otherwise inaccessible
fields and methods of other classes. It is used to hold the code
for dynamically-generated FieldAccessorImpl and MethodAccessorImpl
subclasses. (Use of the word "unsafe" was avoided in this class's
name to avoid confusion with {@link sun.misc.Unsafe}.) </P>
<P> The bug fix for 4486457 also necessitated disabling
verification for this class and all subclasses, as opposed to just
SerializationConstructorAccessorImpl and subclasses, to avoid
having to indicate to the VM which of these dynamically-generated
stub classes were known to be able to pass the verifier. </P>
<P> Do not change the name of this class without also changing the
VM's code. </P> */
class MagicAccessorImpl {
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.InvocationTargetException;
/** This interface provides the declaration for
java.lang.reflect.Method.invoke(). Each Method object is
configured with a (possibly dynamically-generated) class which
implements this interface.
*/
public interface MethodAccessor {
/** Matches specification in {@link java.lang.reflect.Method} */
public Object invoke(Object obj, Object[] args)
throws IllegalArgumentException, InvocationTargetException;
}

View File

@@ -0,0 +1,780 @@
/*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.security.AccessController;
import java.security.PrivilegedAction;
/** Generator for sun.reflect.MethodAccessor and
sun.reflect.ConstructorAccessor objects using bytecodes to
implement reflection. A java.lang.reflect.Method or
java.lang.reflect.Constructor object can delegate its invoke or
newInstance method to an accessor using native code or to one
generated by this class. (Methods and Constructors were merged
together in this class to ensure maximum code sharing.) */
class MethodAccessorGenerator extends AccessorGenerator {
private static final short NUM_BASE_CPOOL_ENTRIES = (short) 12;
// One for invoke() plus one for constructor
private static final short NUM_METHODS = (short) 2;
// Only used if forSerialization is true
private static final short NUM_SERIALIZATION_CPOOL_ENTRIES = (short) 2;
private static volatile int methodSymnum = 0;
private static volatile int constructorSymnum = 0;
private static volatile int serializationConstructorSymnum = 0;
private Class<?> declaringClass;
private Class<?>[] parameterTypes;
private Class<?> returnType;
private boolean isConstructor;
private boolean forSerialization;
private short targetMethodRef;
private short invokeIdx;
private short invokeDescriptorIdx;
// Constant pool index of CONSTANT_Class_info for first
// non-primitive parameter type. Should be incremented by 2.
private short nonPrimitiveParametersBaseIdx;
MethodAccessorGenerator() {
}
/** This routine is not thread-safe */
public MethodAccessor generateMethod(Class<?> declaringClass,
String name,
Class<?>[] parameterTypes,
Class<?> returnType,
Class<?>[] checkedExceptions,
int modifiers)
{
return (MethodAccessor) generate(declaringClass,
name,
parameterTypes,
returnType,
checkedExceptions,
modifiers,
false,
false,
null);
}
/** This routine is not thread-safe */
public ConstructorAccessor generateConstructor(Class<?> declaringClass,
Class<?>[] parameterTypes,
Class<?>[] checkedExceptions,
int modifiers)
{
return (ConstructorAccessor) generate(declaringClass,
"<init>",
parameterTypes,
Void.TYPE,
checkedExceptions,
modifiers,
true,
false,
null);
}
/** This routine is not thread-safe */
public SerializationConstructorAccessorImpl
generateSerializationConstructor(Class<?> declaringClass,
Class<?>[] parameterTypes,
Class<?>[] checkedExceptions,
int modifiers,
Class<?> targetConstructorClass)
{
return (SerializationConstructorAccessorImpl)
generate(declaringClass,
"<init>",
parameterTypes,
Void.TYPE,
checkedExceptions,
modifiers,
true,
true,
targetConstructorClass);
}
/** This routine is not thread-safe */
private MagicAccessorImpl generate(final Class<?> declaringClass,
String name,
Class<?>[] parameterTypes,
Class<?> returnType,
Class<?>[] checkedExceptions,
int modifiers,
boolean isConstructor,
boolean forSerialization,
Class<?> serializationTargetClass)
{
ByteVector vec = ByteVectorFactory.create();
asm = new ClassFileAssembler(vec);
this.declaringClass = declaringClass;
this.parameterTypes = parameterTypes;
this.returnType = returnType;
this.modifiers = modifiers;
this.isConstructor = isConstructor;
this.forSerialization = forSerialization;
asm.emitMagicAndVersion();
// Constant pool entries:
// ( * = Boxing information: optional)
// (+ = Shared entries provided by AccessorGenerator)
// (^ = Only present if generating SerializationConstructorAccessor)
// [UTF-8] [This class's name]
// [CONSTANT_Class_info] for above
// [UTF-8] "sun/reflect/{MethodAccessorImpl,ConstructorAccessorImpl,SerializationConstructorAccessorImpl}"
// [CONSTANT_Class_info] for above
// [UTF-8] [Target class's name]
// [CONSTANT_Class_info] for above
// ^ [UTF-8] [Serialization: Class's name in which to invoke constructor]
// ^ [CONSTANT_Class_info] for above
// [UTF-8] target method or constructor name
// [UTF-8] target method or constructor signature
// [CONSTANT_NameAndType_info] for above
// [CONSTANT_Methodref_info or CONSTANT_InterfaceMethodref_info] for target method
// [UTF-8] "invoke" or "newInstance"
// [UTF-8] invoke or newInstance descriptor
// [UTF-8] descriptor for type of non-primitive parameter 1
// [CONSTANT_Class_info] for type of non-primitive parameter 1
// ...
// [UTF-8] descriptor for type of non-primitive parameter n
// [CONSTANT_Class_info] for type of non-primitive parameter n
// + [UTF-8] "java/lang/Exception"
// + [CONSTANT_Class_info] for above
// + [UTF-8] "java/lang/ClassCastException"
// + [CONSTANT_Class_info] for above
// + [UTF-8] "java/lang/NullPointerException"
// + [CONSTANT_Class_info] for above
// + [UTF-8] "java/lang/IllegalArgumentException"
// + [CONSTANT_Class_info] for above
// + [UTF-8] "java/lang/InvocationTargetException"
// + [CONSTANT_Class_info] for above
// + [UTF-8] "<init>"
// + [UTF-8] "()V"
// + [CONSTANT_NameAndType_info] for above
// + [CONSTANT_Methodref_info] for NullPointerException's constructor
// + [CONSTANT_Methodref_info] for IllegalArgumentException's constructor
// + [UTF-8] "(Ljava/lang/String;)V"
// + [CONSTANT_NameAndType_info] for "<init>(Ljava/lang/String;)V"
// + [CONSTANT_Methodref_info] for IllegalArgumentException's constructor taking a String
// + [UTF-8] "(Ljava/lang/Throwable;)V"
// + [CONSTANT_NameAndType_info] for "<init>(Ljava/lang/Throwable;)V"
// + [CONSTANT_Methodref_info] for InvocationTargetException's constructor
// + [CONSTANT_Methodref_info] for "super()"
// + [UTF-8] "java/lang/Object"
// + [CONSTANT_Class_info] for above
// + [UTF-8] "toString"
// + [UTF-8] "()Ljava/lang/String;"
// + [CONSTANT_NameAndType_info] for "toString()Ljava/lang/String;"
// + [CONSTANT_Methodref_info] for Object's toString method
// + [UTF-8] "Code"
// + [UTF-8] "Exceptions"
// * [UTF-8] "java/lang/Boolean"
// * [CONSTANT_Class_info] for above
// * [UTF-8] "(Z)V"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "booleanValue"
// * [UTF-8] "()Z"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "java/lang/Byte"
// * [CONSTANT_Class_info] for above
// * [UTF-8] "(B)V"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "byteValue"
// * [UTF-8] "()B"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "java/lang/Character"
// * [CONSTANT_Class_info] for above
// * [UTF-8] "(C)V"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "charValue"
// * [UTF-8] "()C"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "java/lang/Double"
// * [CONSTANT_Class_info] for above
// * [UTF-8] "(D)V"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "doubleValue"
// * [UTF-8] "()D"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "java/lang/Float"
// * [CONSTANT_Class_info] for above
// * [UTF-8] "(F)V"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "floatValue"
// * [UTF-8] "()F"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "java/lang/Integer"
// * [CONSTANT_Class_info] for above
// * [UTF-8] "(I)V"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "intValue"
// * [UTF-8] "()I"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "java/lang/Long"
// * [CONSTANT_Class_info] for above
// * [UTF-8] "(J)V"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "longValue"
// * [UTF-8] "()J"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "java/lang/Short"
// * [CONSTANT_Class_info] for above
// * [UTF-8] "(S)V"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
// * [UTF-8] "shortValue"
// * [UTF-8] "()S"
// * [CONSTANT_NameAndType_info] for above
// * [CONSTANT_Methodref_info] for above
short numCPEntries = NUM_BASE_CPOOL_ENTRIES + NUM_COMMON_CPOOL_ENTRIES;
boolean usesPrimitives = usesPrimitiveTypes();
if (usesPrimitives) {
numCPEntries += NUM_BOXING_CPOOL_ENTRIES;
}
if (forSerialization) {
numCPEntries += NUM_SERIALIZATION_CPOOL_ENTRIES;
}
// Add in variable-length number of entries to be able to describe
// non-primitive parameter types and checked exceptions.
numCPEntries += (short) (2 * numNonPrimitiveParameterTypes());
asm.emitShort(add(numCPEntries, S1));
final String generatedName = generateName(isConstructor, forSerialization);
asm.emitConstantPoolUTF8(generatedName);
asm.emitConstantPoolClass(asm.cpi());
thisClass = asm.cpi();
if (isConstructor) {
if (forSerialization) {
asm.emitConstantPoolUTF8
("sun/reflect/SerializationConstructorAccessorImpl");
} else {
asm.emitConstantPoolUTF8("sun/reflect/ConstructorAccessorImpl");
}
} else {
asm.emitConstantPoolUTF8("sun/reflect/MethodAccessorImpl");
}
asm.emitConstantPoolClass(asm.cpi());
superClass = asm.cpi();
asm.emitConstantPoolUTF8(getClassName(declaringClass, false));
asm.emitConstantPoolClass(asm.cpi());
targetClass = asm.cpi();
short serializationTargetClassIdx = (short) 0;
if (forSerialization) {
asm.emitConstantPoolUTF8(getClassName(serializationTargetClass, false));
asm.emitConstantPoolClass(asm.cpi());
serializationTargetClassIdx = asm.cpi();
}
asm.emitConstantPoolUTF8(name);
asm.emitConstantPoolUTF8(buildInternalSignature());
asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
if (isInterface()) {
asm.emitConstantPoolInterfaceMethodref(targetClass, asm.cpi());
} else {
if (forSerialization) {
asm.emitConstantPoolMethodref(serializationTargetClassIdx, asm.cpi());
} else {
asm.emitConstantPoolMethodref(targetClass, asm.cpi());
}
}
targetMethodRef = asm.cpi();
if (isConstructor) {
asm.emitConstantPoolUTF8("newInstance");
} else {
asm.emitConstantPoolUTF8("invoke");
}
invokeIdx = asm.cpi();
if (isConstructor) {
asm.emitConstantPoolUTF8("([Ljava/lang/Object;)Ljava/lang/Object;");
} else {
asm.emitConstantPoolUTF8
("(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;");
}
invokeDescriptorIdx = asm.cpi();
// Output class information for non-primitive parameter types
nonPrimitiveParametersBaseIdx = add(asm.cpi(), S2);
for (int i = 0; i < parameterTypes.length; i++) {
Class<?> c = parameterTypes[i];
if (!isPrimitive(c)) {
asm.emitConstantPoolUTF8(getClassName(c, false));
asm.emitConstantPoolClass(asm.cpi());
}
}
// Entries common to FieldAccessor, MethodAccessor and ConstructorAccessor
emitCommonConstantPoolEntries();
// Boxing entries
if (usesPrimitives) {
emitBoxingContantPoolEntries();
}
if (asm.cpi() != numCPEntries) {
throw new InternalError("Adjust this code (cpi = " + asm.cpi() +
", numCPEntries = " + numCPEntries + ")");
}
// Access flags
asm.emitShort(ACC_PUBLIC);
// This class
asm.emitShort(thisClass);
// Superclass
asm.emitShort(superClass);
// Interfaces count and interfaces
asm.emitShort(S0);
// Fields count and fields
asm.emitShort(S0);
// Methods count and methods
asm.emitShort(NUM_METHODS);
emitConstructor();
emitInvoke();
// Additional attributes (none)
asm.emitShort(S0);
// Load class
vec.trim();
final byte[] bytes = vec.getData();
// Note: the class loader is the only thing that really matters
// here -- it's important to get the generated code into the
// same namespace as the target class. Since the generated code
// is privileged anyway, the protection domain probably doesn't
// matter.
return AccessController.doPrivileged(
new PrivilegedAction<MagicAccessorImpl>() {
public MagicAccessorImpl run() {
try {
return (MagicAccessorImpl)
ClassDefiner.defineClass
(generatedName,
bytes,
0,
bytes.length,
declaringClass.getClassLoader()).newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new InternalError(e);
}
}
});
}
/** This emits the code for either invoke() or newInstance() */
private void emitInvoke() {
// NOTE that this code will only handle 65535 parameters since we
// use the sipush instruction to get the array index on the
// operand stack.
if (parameterTypes.length > 65535) {
throw new InternalError("Can't handle more than 65535 parameters");
}
// Generate code into fresh code buffer
ClassFileAssembler cb = new ClassFileAssembler();
if (isConstructor) {
// 1 incoming argument
cb.setMaxLocals(2);
} else {
// 2 incoming arguments
cb.setMaxLocals(3);
}
short illegalArgStartPC = 0;
if (isConstructor) {
// Instantiate target class before continuing
// new <target class type>
// dup
cb.opc_new(targetClass);
cb.opc_dup();
} else {
// Setup before iterating down argument list
if (isPrimitive(returnType)) {
// new <boxing type for primitive type>
// dup
// ... (see below:)
// invokespecial <constructor for boxing type for primitive type>
// areturn
cb.opc_new(indexForPrimitiveType(returnType));
cb.opc_dup();
}
// Get target object on operand stack if necessary.
// We need to do an explicit null check here; we won't see
// NullPointerExceptions from the invoke bytecode, since it's
// covered by an exception handler.
if (!isStatic()) {
// aload_1
// ifnonnull <checkcast label>
// new <NullPointerException>
// dup
// invokespecial <NullPointerException ctor>
// athrow
// <checkcast label:>
// aload_1
// checkcast <target class's type>
cb.opc_aload_1();
Label l = new Label();
cb.opc_ifnonnull(l);
cb.opc_new(nullPointerClass);
cb.opc_dup();
cb.opc_invokespecial(nullPointerCtorIdx, 0, 0);
cb.opc_athrow();
l.bind();
illegalArgStartPC = cb.getLength();
cb.opc_aload_1();
cb.opc_checkcast(targetClass);
}
}
// Have to check length of incoming array and throw
// IllegalArgumentException if not correct. A concession to the
// JCK (isn't clearly specified in the spec): we allow null in the
// case where the argument list is zero length.
// if no-arg:
// aload_2 | aload_1 (Method | Constructor)
// ifnull <success label>
// aload_2 | aload_1
// arraylength
// sipush <num parameter types>
// if_icmpeq <success label>
// new <IllegalArgumentException>
// dup
// invokespecial <IllegalArgumentException ctor>
// athrow
// <success label:>
Label successLabel = new Label();
if (parameterTypes.length == 0) {
if (isConstructor) {
cb.opc_aload_1();
} else {
cb.opc_aload_2();
}
cb.opc_ifnull(successLabel);
}
if (isConstructor) {
cb.opc_aload_1();
} else {
cb.opc_aload_2();
}
cb.opc_arraylength();
cb.opc_sipush((short) parameterTypes.length);
cb.opc_if_icmpeq(successLabel);
cb.opc_new(illegalArgumentClass);
cb.opc_dup();
cb.opc_invokespecial(illegalArgumentCtorIdx, 0, 0);
cb.opc_athrow();
successLabel.bind();
// Iterate through incoming actual parameters, ensuring that each
// is compatible with the formal parameter type, and pushing the
// actual on the operand stack (unboxing and widening if necessary).
short paramTypeCPIdx = nonPrimitiveParametersBaseIdx;
Label nextParamLabel = null;
byte count = 1; // both invokeinterface opcode's "count" as well as
// num args of other invoke bytecodes
for (int i = 0; i < parameterTypes.length; i++) {
Class<?> paramType = parameterTypes[i];
count += (byte) typeSizeInStackSlots(paramType);
if (nextParamLabel != null) {
nextParamLabel.bind();
nextParamLabel = null;
}
// aload_2 | aload_1
// sipush <index>
// aaload
if (isConstructor) {
cb.opc_aload_1();
} else {
cb.opc_aload_2();
}
cb.opc_sipush((short) i);
cb.opc_aaload();
if (isPrimitive(paramType)) {
// Unboxing code.
// Put parameter into temporary local variable
// astore_3 | astore_2
if (isConstructor) {
cb.opc_astore_2();
} else {
cb.opc_astore_3();
}
// repeat for all possible widening conversions:
// aload_3 | aload_2
// instanceof <primitive boxing type>
// ifeq <next unboxing label>
// aload_3 | aload_2
// checkcast <primitive boxing type> // Note: this is "redundant",
// // but necessary for the verifier
// invokevirtual <unboxing method>
// <widening conversion bytecode, if necessary>
// goto <next parameter label>
// <next unboxing label:> ...
// last unboxing label:
// new <IllegalArgumentException>
// dup
// invokespecial <IllegalArgumentException ctor>
// athrow
Label l = null; // unboxing label
nextParamLabel = new Label();
for (int j = 0; j < primitiveTypes.length; j++) {
Class<?> c = primitiveTypes[j];
if (canWidenTo(c, paramType)) {
if (l != null) {
l.bind();
}
// Emit checking and unboxing code for this type
if (isConstructor) {
cb.opc_aload_2();
} else {
cb.opc_aload_3();
}
cb.opc_instanceof(indexForPrimitiveType(c));
l = new Label();
cb.opc_ifeq(l);
if (isConstructor) {
cb.opc_aload_2();
} else {
cb.opc_aload_3();
}
cb.opc_checkcast(indexForPrimitiveType(c));
cb.opc_invokevirtual(unboxingMethodForPrimitiveType(c),
0,
typeSizeInStackSlots(c));
emitWideningBytecodeForPrimitiveConversion(cb,
c,
paramType);
cb.opc_goto(nextParamLabel);
}
}
if (l == null) {
throw new InternalError
("Must have found at least identity conversion");
}
// Fell through; given object is null or invalid. According to
// the spec, we can throw IllegalArgumentException for both of
// these cases.
l.bind();
cb.opc_new(illegalArgumentClass);
cb.opc_dup();
cb.opc_invokespecial(illegalArgumentCtorIdx, 0, 0);
cb.opc_athrow();
} else {
// Emit appropriate checkcast
cb.opc_checkcast(paramTypeCPIdx);
paramTypeCPIdx = add(paramTypeCPIdx, S2);
// Fall through to next argument
}
}
// Bind last goto if present
if (nextParamLabel != null) {
nextParamLabel.bind();
}
short invokeStartPC = cb.getLength();
// OK, ready to perform the invocation.
if (isConstructor) {
cb.opc_invokespecial(targetMethodRef, count, 0);
} else {
if (isStatic()) {
cb.opc_invokestatic(targetMethodRef,
count,
typeSizeInStackSlots(returnType));
} else {
if (isInterface()) {
if (isPrivate()) {
cb.opc_invokespecial(targetMethodRef, count, 0);
} else {
cb.opc_invokeinterface(targetMethodRef,
count,
count,
typeSizeInStackSlots(returnType));
}
} else {
cb.opc_invokevirtual(targetMethodRef,
count,
typeSizeInStackSlots(returnType));
}
}
}
short invokeEndPC = cb.getLength();
if (!isConstructor) {
// Box return value if necessary
if (isPrimitive(returnType)) {
cb.opc_invokespecial(ctorIndexForPrimitiveType(returnType),
typeSizeInStackSlots(returnType),
0);
} else if (returnType == Void.TYPE) {
cb.opc_aconst_null();
}
}
cb.opc_areturn();
// We generate two exception handlers; one which is responsible
// for catching ClassCastException and NullPointerException and
// throwing IllegalArgumentException, and the other which catches
// all java/lang/Throwable objects thrown from the target method
// and wraps them in InvocationTargetExceptions.
short classCastHandler = cb.getLength();
// ClassCast, etc. exception handler
cb.setStack(1);
cb.opc_invokespecial(toStringIdx, 0, 1);
cb.opc_new(illegalArgumentClass);
cb.opc_dup_x1();
cb.opc_swap();
cb.opc_invokespecial(illegalArgumentStringCtorIdx, 1, 0);
cb.opc_athrow();
short invocationTargetHandler = cb.getLength();
// InvocationTargetException exception handler
cb.setStack(1);
cb.opc_new(invocationTargetClass);
cb.opc_dup_x1();
cb.opc_swap();
cb.opc_invokespecial(invocationTargetCtorIdx, 1, 0);
cb.opc_athrow();
// Generate exception table. We cover the entire code sequence
// with an exception handler which catches ClassCastException and
// converts it into an IllegalArgumentException.
ClassFileAssembler exc = new ClassFileAssembler();
exc.emitShort(illegalArgStartPC); // start PC
exc.emitShort(invokeStartPC); // end PC
exc.emitShort(classCastHandler); // handler PC
exc.emitShort(classCastClass); // catch type
exc.emitShort(illegalArgStartPC); // start PC
exc.emitShort(invokeStartPC); // end PC
exc.emitShort(classCastHandler); // handler PC
exc.emitShort(nullPointerClass); // catch type
exc.emitShort(invokeStartPC); // start PC
exc.emitShort(invokeEndPC); // end PC
exc.emitShort(invocationTargetHandler); // handler PC
exc.emitShort(throwableClass); // catch type
emitMethod(invokeIdx, cb.getMaxLocals(), cb, exc,
new short[] { invocationTargetClass });
}
private boolean usesPrimitiveTypes() {
// We need to emit boxing/unboxing constant pool information if
// the method takes a primitive type for any of its parameters or
// returns a primitive value (except void)
if (returnType.isPrimitive()) {
return true;
}
for (int i = 0; i < parameterTypes.length; i++) {
if (parameterTypes[i].isPrimitive()) {
return true;
}
}
return false;
}
private int numNonPrimitiveParameterTypes() {
int num = 0;
for (int i = 0; i < parameterTypes.length; i++) {
if (!parameterTypes[i].isPrimitive()) {
++num;
}
}
return num;
}
private boolean isInterface() {
return declaringClass.isInterface();
}
private String buildInternalSignature() {
StringBuffer buf = new StringBuffer();
buf.append("(");
for (int i = 0; i < parameterTypes.length; i++) {
buf.append(getClassName(parameterTypes[i], true));
}
buf.append(")");
buf.append(getClassName(returnType, true));
return buf.toString();
}
private static synchronized String generateName(boolean isConstructor,
boolean forSerialization)
{
if (isConstructor) {
if (forSerialization) {
int num = ++serializationConstructorSymnum;
return "sun/reflect/GeneratedSerializationConstructorAccessor" + num;
} else {
int num = ++constructorSymnum;
return "sun/reflect/GeneratedConstructorAccessor" + num;
}
} else {
int num = ++methodSymnum;
return "sun/reflect/GeneratedMethodAccessor" + num;
}
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.InvocationTargetException;
/** <P> Package-private implementation of the MethodAccessor interface
which has access to all classes and all fields, regardless of
language restrictions. See MagicAccessor. </P>
<P> This class is known to the VM; do not change its name without
also changing the VM's code. </P>
<P> NOTE: ALL methods of subclasses are skipped during security
walks up the stack. The assumption is that the only such methods
that will persistently show up on the stack are the implementing
methods for java.lang.reflect.Method.invoke(). </P>
*/
abstract class MethodAccessorImpl extends MagicAccessorImpl
implements MethodAccessor {
/** Matches specification in {@link java.lang.reflect.Method} */
public abstract Object invoke(Object obj, Object[] args)
throws IllegalArgumentException, InvocationTargetException;
}

View File

@@ -0,0 +1,73 @@
/*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.*;
import sun.reflect.misc.ReflectUtil;
/** Used only for the first few invocations of a Constructor;
afterward, switches to bytecode-based implementation */
class NativeConstructorAccessorImpl extends ConstructorAccessorImpl {
private final Constructor<?> c;
private DelegatingConstructorAccessorImpl parent;
private int numInvocations;
NativeConstructorAccessorImpl(Constructor<?> c) {
this.c = c;
}
public Object newInstance(Object[] args)
throws InstantiationException,
IllegalArgumentException,
InvocationTargetException
{
// We can't inflate a constructor belonging to a vm-anonymous class
// because that kind of class can't be referred to by name, hence can't
// be found from the generated bytecode.
if (++numInvocations > ReflectionFactory.inflationThreshold()
&& !ReflectUtil.isVMAnonymousClass(c.getDeclaringClass())) {
ConstructorAccessorImpl acc = (ConstructorAccessorImpl)
new MethodAccessorGenerator().
generateConstructor(c.getDeclaringClass(),
c.getParameterTypes(),
c.getExceptionTypes(),
c.getModifiers());
parent.setDelegate(acc);
}
return newInstance0(c, args);
}
void setParent(DelegatingConstructorAccessorImpl parent) {
this.parent = parent;
}
private static native Object newInstance0(Constructor<?> c, Object[] args)
throws InstantiationException,
IllegalArgumentException,
InvocationTargetException;
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.*;
import sun.reflect.misc.ReflectUtil;
/** Used only for the first few invocations of a Method; afterward,
switches to bytecode-based implementation */
class NativeMethodAccessorImpl extends MethodAccessorImpl {
private final Method method;
private DelegatingMethodAccessorImpl parent;
private int numInvocations;
NativeMethodAccessorImpl(Method method) {
this.method = method;
}
public Object invoke(Object obj, Object[] args)
throws IllegalArgumentException, InvocationTargetException
{
// We can't inflate methods belonging to vm-anonymous classes because
// that kind of class can't be referred to by name, hence can't be
// found from the generated bytecode.
if (++numInvocations > ReflectionFactory.inflationThreshold()
&& !ReflectUtil.isVMAnonymousClass(method.getDeclaringClass())) {
MethodAccessorImpl acc = (MethodAccessorImpl)
new MethodAccessorGenerator().
generateMethod(method.getDeclaringClass(),
method.getName(),
method.getParameterTypes(),
method.getReturnType(),
method.getExceptionTypes(),
method.getModifiers());
parent.setDelegate(acc);
}
return invoke0(method, obj, args);
}
void setParent(DelegatingMethodAccessorImpl parent) {
this.parent = parent;
}
private static native Object invoke0(Method m, Object obj, Object[] args);
}

View File

@@ -0,0 +1,351 @@
/*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.*;
import java.util.HashMap;
import java.util.Map;
/** Common utility routines used by both java.lang and
java.lang.reflect */
public class Reflection {
/** Used to filter out fields and methods from certain classes from public
view, where they are sensitive or they may contain VM-internal objects.
These Maps are updated very rarely. Rather than synchronize on
each access, we use copy-on-write */
private static volatile Map<Class<?>,String[]> fieldFilterMap;
private static volatile Map<Class<?>,String[]> methodFilterMap;
static {
Map<Class<?>,String[]> map = new HashMap<Class<?>,String[]>();
map.put(Reflection.class,
new String[] {"fieldFilterMap", "methodFilterMap"});
map.put(System.class, new String[] {"security"});
map.put(Class.class, new String[] {"classLoader"});
fieldFilterMap = map;
methodFilterMap = new HashMap<>();
}
/** Returns the class of the caller of the method calling this method,
ignoring frames associated with java.lang.reflect.Method.invoke()
and its implementation. */
@CallerSensitive
public static native Class<?> getCallerClass();
/**
* @deprecated This method will be removed in JDK 9.
* This method is a private JDK API and retained temporarily for
* existing code to run until a replacement API is defined.
*/
@Deprecated
public static native Class<?> getCallerClass(int depth);
/** Retrieves the access flags written to the class file. For
inner classes these flags may differ from those returned by
Class.getModifiers(), which searches the InnerClasses
attribute to find the source-level access flags. This is used
instead of Class.getModifiers() for run-time access checks due
to compatibility reasons; see 4471811. Only the values of the
low 13 bits (i.e., a mask of 0x1FFF) are guaranteed to be
valid. */
public static native int getClassAccessFlags(Class<?> c);
/** A quick "fast-path" check to try to avoid getCallerClass()
calls. */
public static boolean quickCheckMemberAccess(Class<?> memberClass,
int modifiers)
{
return Modifier.isPublic(getClassAccessFlags(memberClass) & modifiers);
}
public static void ensureMemberAccess(Class<?> currentClass,
Class<?> memberClass,
Object target,
int modifiers)
throws IllegalAccessException
{
if (currentClass == null || memberClass == null) {
throw new InternalError();
}
if (!verifyMemberAccess(currentClass, memberClass, target, modifiers)) {
throw new IllegalAccessException("Class " + currentClass.getName() +
" can not access a member of class " +
memberClass.getName() +
" with modifiers \"" +
Modifier.toString(modifiers) +
"\"");
}
}
public static boolean verifyMemberAccess(Class<?> currentClass,
// Declaring class of field
// or method
Class<?> memberClass,
// May be NULL in case of statics
Object target,
int modifiers)
{
// Verify that currentClass can access a field, method, or
// constructor of memberClass, where that member's access bits are
// "modifiers".
boolean gotIsSameClassPackage = false;
boolean isSameClassPackage = false;
if (currentClass == memberClass) {
// Always succeeds
return true;
}
if (!Modifier.isPublic(getClassAccessFlags(memberClass))) {
isSameClassPackage = isSameClassPackage(currentClass, memberClass);
gotIsSameClassPackage = true;
if (!isSameClassPackage) {
return false;
}
}
// At this point we know that currentClass can access memberClass.
if (Modifier.isPublic(modifiers)) {
return true;
}
boolean successSoFar = false;
if (Modifier.isProtected(modifiers)) {
// See if currentClass is a subclass of memberClass
if (isSubclassOf(currentClass, memberClass)) {
successSoFar = true;
}
}
if (!successSoFar && !Modifier.isPrivate(modifiers)) {
if (!gotIsSameClassPackage) {
isSameClassPackage = isSameClassPackage(currentClass,
memberClass);
gotIsSameClassPackage = true;
}
if (isSameClassPackage) {
successSoFar = true;
}
}
if (!successSoFar) {
return false;
}
if (Modifier.isProtected(modifiers)) {
// Additional test for protected members: JLS 6.6.2
Class<?> targetClass = (target == null ? memberClass : target.getClass());
if (targetClass != currentClass) {
if (!gotIsSameClassPackage) {
isSameClassPackage = isSameClassPackage(currentClass, memberClass);
gotIsSameClassPackage = true;
}
if (!isSameClassPackage) {
if (!isSubclassOf(targetClass, currentClass)) {
return false;
}
}
}
}
return true;
}
private static boolean isSameClassPackage(Class<?> c1, Class<?> c2) {
return isSameClassPackage(c1.getClassLoader(), c1.getName(),
c2.getClassLoader(), c2.getName());
}
/** Returns true if two classes are in the same package; classloader
and classname information is enough to determine a class's package */
private static boolean isSameClassPackage(ClassLoader loader1, String name1,
ClassLoader loader2, String name2)
{
if (loader1 != loader2) {
return false;
} else {
int lastDot1 = name1.lastIndexOf('.');
int lastDot2 = name2.lastIndexOf('.');
if ((lastDot1 == -1) || (lastDot2 == -1)) {
// One of the two doesn't have a package. Only return true
// if the other one also doesn't have a package.
return (lastDot1 == lastDot2);
} else {
int idx1 = 0;
int idx2 = 0;
// Skip over '['s
if (name1.charAt(idx1) == '[') {
do {
idx1++;
} while (name1.charAt(idx1) == '[');
if (name1.charAt(idx1) != 'L') {
// Something is terribly wrong. Shouldn't be here.
throw new InternalError("Illegal class name " + name1);
}
}
if (name2.charAt(idx2) == '[') {
do {
idx2++;
} while (name2.charAt(idx2) == '[');
if (name2.charAt(idx2) != 'L') {
// Something is terribly wrong. Shouldn't be here.
throw new InternalError("Illegal class name " + name2);
}
}
// Check that package part is identical
int length1 = lastDot1 - idx1;
int length2 = lastDot2 - idx2;
if (length1 != length2) {
return false;
}
return name1.regionMatches(false, idx1, name2, idx2, length1);
}
}
}
static boolean isSubclassOf(Class<?> queryClass,
Class<?> ofClass)
{
while (queryClass != null) {
if (queryClass == ofClass) {
return true;
}
queryClass = queryClass.getSuperclass();
}
return false;
}
// fieldNames must contain only interned Strings
public static synchronized void registerFieldsToFilter(Class<?> containingClass,
String ... fieldNames) {
fieldFilterMap =
registerFilter(fieldFilterMap, containingClass, fieldNames);
}
// methodNames must contain only interned Strings
public static synchronized void registerMethodsToFilter(Class<?> containingClass,
String ... methodNames) {
methodFilterMap =
registerFilter(methodFilterMap, containingClass, methodNames);
}
private static Map<Class<?>,String[]> registerFilter(Map<Class<?>,String[]> map,
Class<?> containingClass, String ... names) {
if (map.get(containingClass) != null) {
throw new IllegalArgumentException
("Filter already registered: " + containingClass);
}
map = new HashMap<Class<?>,String[]>(map);
map.put(containingClass, names);
return map;
}
public static Field[] filterFields(Class<?> containingClass,
Field[] fields) {
if (fieldFilterMap == null) {
// Bootstrapping
return fields;
}
return (Field[])filter(fields, fieldFilterMap.get(containingClass));
}
public static Method[] filterMethods(Class<?> containingClass, Method[] methods) {
if (methodFilterMap == null) {
// Bootstrapping
return methods;
}
return (Method[])filter(methods, methodFilterMap.get(containingClass));
}
private static Member[] filter(Member[] members, String[] filteredNames) {
if ((filteredNames == null) || (members.length == 0)) {
return members;
}
int numNewMembers = 0;
for (Member member : members) {
boolean shouldSkip = false;
for (String filteredName : filteredNames) {
if (member.getName() == filteredName) {
shouldSkip = true;
break;
}
}
if (!shouldSkip) {
++numNewMembers;
}
}
Member[] newMembers =
(Member[])Array.newInstance(members[0].getClass(), numNewMembers);
int destIdx = 0;
for (Member member : members) {
boolean shouldSkip = false;
for (String filteredName : filteredNames) {
if (member.getName() == filteredName) {
shouldSkip = true;
break;
}
}
if (!shouldSkip) {
newMembers[destIdx++] = member;
}
}
return newMembers;
}
/**
* Tests if the given method is caller-sensitive and the declaring class
* is defined by either the bootstrap class loader or extension class loader.
*/
public static boolean isCallerSensitive(Method m) {
final ClassLoader loader = m.getDeclaringClass().getClassLoader();
if (sun.misc.VM.isSystemDomainLoader(loader) || isExtClassLoader(loader)) {
return m.isAnnotationPresent(CallerSensitive.class);
}
return false;
}
private static boolean isExtClassLoader(ClassLoader loader) {
ClassLoader cl = ClassLoader.getSystemClassLoader();
while (cl != null) {
if (cl.getParent() == null && cl == loader) {
return true;
}
cl = cl.getParent();
}
return false;
}
}

View File

@@ -0,0 +1,708 @@
/*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.io.Externalizable;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.io.OptionalDataException;
import java.io.Serializable;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Field;
import java.lang.reflect.Executable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
import java.util.Objects;
import sun.reflect.misc.ReflectUtil;
/** <P> The master factory for all reflective objects, both those in
java.lang.reflect (Fields, Methods, Constructors) as well as their
delegates (FieldAccessors, MethodAccessors, ConstructorAccessors).
</P>
<P> The methods in this class are extremely unsafe and can cause
subversion of both the language and the verifier. For this reason,
they are all instance methods, and access to the constructor of
this factory is guarded by a security check, in similar style to
{@link sun.misc.Unsafe}. </P>
*/
public class ReflectionFactory {
private static boolean initted = false;
private static final Permission reflectionFactoryAccessPerm
= new RuntimePermission("reflectionFactoryAccess");
private static final ReflectionFactory soleInstance = new ReflectionFactory();
// Provides access to package-private mechanisms in java.lang.reflect
private static volatile LangReflectAccess langReflectAccess;
/* Method for static class initializer <clinit>, or null */
private static volatile Method hasStaticInitializerMethod;
//
// "Inflation" mechanism. Loading bytecodes to implement
// Method.invoke() and Constructor.newInstance() currently costs
// 3-4x more than an invocation via native code for the first
// invocation (though subsequent invocations have been benchmarked
// to be over 20x faster). Unfortunately this cost increases
// startup time for certain applications that use reflection
// intensively (but only once per class) to bootstrap themselves.
// To avoid this penalty we reuse the existing JVM entry points
// for the first few invocations of Methods and Constructors and
// then switch to the bytecode-based implementations.
//
// Package-private to be accessible to NativeMethodAccessorImpl
// and NativeConstructorAccessorImpl
private static boolean noInflation = false;
private static int inflationThreshold = 15;
private ReflectionFactory() {}
/**
* A convenience class for acquiring the capability to instantiate
* reflective objects. Use this instead of a raw call to {@link
* #getReflectionFactory} in order to avoid being limited by the
* permissions of your callers.
*
* <p>An instance of this class can be used as the argument of
* <code>AccessController.doPrivileged</code>.
*/
public static final class GetReflectionFactoryAction
implements PrivilegedAction<ReflectionFactory> {
public ReflectionFactory run() {
return getReflectionFactory();
}
}
/**
* Provides the caller with the capability to instantiate reflective
* objects.
*
* <p> First, if there is a security manager, its
* <code>checkPermission</code> method is called with a {@link
* java.lang.RuntimePermission} with target
* <code>"reflectionFactoryAccess"</code>. This may result in a
* security exception.
*
* <p> The returned <code>ReflectionFactory</code> object should be
* carefully guarded by the caller, since it can be used to read and
* write private data and invoke private methods, as well as to load
* unverified bytecodes. It must never be passed to untrusted code.
*
* @exception SecurityException if a security manager exists and its
* <code>checkPermission</code> method doesn't allow
* access to the RuntimePermission "reflectionFactoryAccess". */
public static ReflectionFactory getReflectionFactory() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
// TO DO: security.checkReflectionFactoryAccess();
security.checkPermission(reflectionFactoryAccessPerm);
}
return soleInstance;
}
//--------------------------------------------------------------------------
//
// Routines used by java.lang.reflect
//
//
/** Called only by java.lang.reflect.Modifier's static initializer */
public void setLangReflectAccess(LangReflectAccess access) {
langReflectAccess = access;
}
/**
* Note: this routine can cause the declaring class for the field
* be initialized and therefore must not be called until the
* first get/set of this field.
* @param field the field
* @param override true if caller has overridden aaccessibility
*/
public FieldAccessor newFieldAccessor(Field field, boolean override) {
checkInitted();
return UnsafeFieldAccessorFactory.newFieldAccessor(field, override);
}
public MethodAccessor newMethodAccessor(Method method) {
checkInitted();
if (noInflation && !ReflectUtil.isVMAnonymousClass(method.getDeclaringClass())) {
return new MethodAccessorGenerator().
generateMethod(method.getDeclaringClass(),
method.getName(),
method.getParameterTypes(),
method.getReturnType(),
method.getExceptionTypes(),
method.getModifiers());
} else {
NativeMethodAccessorImpl acc =
new NativeMethodAccessorImpl(method);
DelegatingMethodAccessorImpl res =
new DelegatingMethodAccessorImpl(acc);
acc.setParent(res);
return res;
}
}
public ConstructorAccessor newConstructorAccessor(Constructor<?> c) {
checkInitted();
Class<?> declaringClass = c.getDeclaringClass();
if (Modifier.isAbstract(declaringClass.getModifiers())) {
return new InstantiationExceptionConstructorAccessorImpl(null);
}
if (declaringClass == Class.class) {
return new InstantiationExceptionConstructorAccessorImpl
("Can not instantiate java.lang.Class");
}
// Bootstrapping issue: since we use Class.newInstance() in
// the ConstructorAccessor generation process, we have to
// break the cycle here.
if (Reflection.isSubclassOf(declaringClass,
ConstructorAccessorImpl.class)) {
return new BootstrapConstructorAccessorImpl(c);
}
if (noInflation && !ReflectUtil.isVMAnonymousClass(c.getDeclaringClass())) {
return new MethodAccessorGenerator().
generateConstructor(c.getDeclaringClass(),
c.getParameterTypes(),
c.getExceptionTypes(),
c.getModifiers());
} else {
NativeConstructorAccessorImpl acc =
new NativeConstructorAccessorImpl(c);
DelegatingConstructorAccessorImpl res =
new DelegatingConstructorAccessorImpl(acc);
acc.setParent(res);
return res;
}
}
//--------------------------------------------------------------------------
//
// Routines used by java.lang
//
//
/** Creates a new java.lang.reflect.Field. Access checks as per
java.lang.reflect.AccessibleObject are not overridden. */
public Field newField(Class<?> declaringClass,
String name,
Class<?> type,
int modifiers,
int slot,
String signature,
byte[] annotations)
{
return langReflectAccess().newField(declaringClass,
name,
type,
modifiers,
slot,
signature,
annotations);
}
/** Creates a new java.lang.reflect.Method. Access checks as per
java.lang.reflect.AccessibleObject are not overridden. */
public Method newMethod(Class<?> declaringClass,
String name,
Class<?>[] parameterTypes,
Class<?> returnType,
Class<?>[] checkedExceptions,
int modifiers,
int slot,
String signature,
byte[] annotations,
byte[] parameterAnnotations,
byte[] annotationDefault)
{
return langReflectAccess().newMethod(declaringClass,
name,
parameterTypes,
returnType,
checkedExceptions,
modifiers,
slot,
signature,
annotations,
parameterAnnotations,
annotationDefault);
}
/** Creates a new java.lang.reflect.Constructor. Access checks as
per java.lang.reflect.AccessibleObject are not overridden. */
public Constructor<?> newConstructor(Class<?> declaringClass,
Class<?>[] parameterTypes,
Class<?>[] checkedExceptions,
int modifiers,
int slot,
String signature,
byte[] annotations,
byte[] parameterAnnotations)
{
return langReflectAccess().newConstructor(declaringClass,
parameterTypes,
checkedExceptions,
modifiers,
slot,
signature,
annotations,
parameterAnnotations);
}
/** Gets the MethodAccessor object for a java.lang.reflect.Method */
public MethodAccessor getMethodAccessor(Method m) {
return langReflectAccess().getMethodAccessor(m);
}
/** Sets the MethodAccessor object for a java.lang.reflect.Method */
public void setMethodAccessor(Method m, MethodAccessor accessor) {
langReflectAccess().setMethodAccessor(m, accessor);
}
/** Gets the ConstructorAccessor object for a
java.lang.reflect.Constructor */
public ConstructorAccessor getConstructorAccessor(Constructor<?> c) {
return langReflectAccess().getConstructorAccessor(c);
}
/** Sets the ConstructorAccessor object for a
java.lang.reflect.Constructor */
public void setConstructorAccessor(Constructor<?> c,
ConstructorAccessor accessor)
{
langReflectAccess().setConstructorAccessor(c, accessor);
}
/** Makes a copy of the passed method. The returned method is a
"child" of the passed one; see the comments in Method.java for
details. */
public Method copyMethod(Method arg) {
return langReflectAccess().copyMethod(arg);
}
/** Makes a copy of the passed field. The returned field is a
"child" of the passed one; see the comments in Field.java for
details. */
public Field copyField(Field arg) {
return langReflectAccess().copyField(arg);
}
/** Makes a copy of the passed constructor. The returned
constructor is a "child" of the passed one; see the comments
in Constructor.java for details. */
public <T> Constructor<T> copyConstructor(Constructor<T> arg) {
return langReflectAccess().copyConstructor(arg);
}
/** Gets the byte[] that encodes TypeAnnotations on an executable.
*/
public byte[] getExecutableTypeAnnotationBytes(Executable ex) {
return langReflectAccess().getExecutableTypeAnnotationBytes(ex);
}
//--------------------------------------------------------------------------
//
// Routines used by serialization
//
//
/**
* Returns an accessible constructor capable of creating instances
* of the given class, initialized by the given constructor.
*
* @param classToInstantiate the class to instantiate
* @param constructorToCall the constructor to call
* @return an accessible constructor
*/
public Constructor<?> newConstructorForSerialization
(Class<?> classToInstantiate, Constructor<?> constructorToCall)
{
// Fast path
if (constructorToCall.getDeclaringClass() == classToInstantiate) {
return constructorToCall;
}
return generateConstructor(classToInstantiate, constructorToCall);
}
/**
* Returns an accessible no-arg constructor for a class.
* The no-arg constructor is found searching the class and its supertypes.
*
* @param cl the class to instantiate
* @return a no-arg constructor for the class or {@code null} if
* the class or supertypes do not have a suitable no-arg constructor
*/
public final Constructor<?> newConstructorForSerialization(Class<?> cl) {
Class<?> initCl = cl;
while (Serializable.class.isAssignableFrom(initCl)) {
if ((initCl = initCl.getSuperclass()) == null) {
return null;
}
}
Constructor<?> constructorToCall;
try {
constructorToCall = initCl.getDeclaredConstructor();
int mods = constructorToCall.getModifiers();
if ((mods & Modifier.PRIVATE) != 0 ||
((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
!packageEquals(cl, initCl))) {
return null;
}
} catch (NoSuchMethodException ex) {
return null;
}
return generateConstructor(cl, constructorToCall);
}
private final Constructor<?> generateConstructor(Class<?> classToInstantiate,
Constructor<?> constructorToCall) {
ConstructorAccessor acc = new MethodAccessorGenerator().
generateSerializationConstructor(classToInstantiate,
constructorToCall.getParameterTypes(),
constructorToCall.getExceptionTypes(),
constructorToCall.getModifiers(),
constructorToCall.getDeclaringClass());
Constructor<?> c = newConstructor(constructorToCall.getDeclaringClass(),
constructorToCall.getParameterTypes(),
constructorToCall.getExceptionTypes(),
constructorToCall.getModifiers(),
langReflectAccess().
getConstructorSlot(constructorToCall),
langReflectAccess().
getConstructorSignature(constructorToCall),
langReflectAccess().
getConstructorAnnotations(constructorToCall),
langReflectAccess().
getConstructorParameterAnnotations(constructorToCall));
setConstructorAccessor(c, acc);
c.setAccessible(true);
return c;
}
/**
* Returns an accessible no-arg constructor for an externalizable class to be
* initialized using a public no-argument constructor.
*
* @param cl the class to instantiate
* @return A no-arg constructor for the class; returns {@code null} if
* the class does not implement {@link java.io.Externalizable}
*/
public final Constructor<?> newConstructorForExternalization(Class<?> cl) {
if (!Externalizable.class.isAssignableFrom(cl)) {
return null;
}
try {
Constructor<?> cons = cl.getConstructor();
cons.setAccessible(true);
return cons;
} catch (NoSuchMethodException ex) {
return null;
}
}
/**
* Returns a direct MethodHandle for the {@code readObject} method on
* a Serializable class.
* The first argument of {@link MethodHandle#invoke} is the serializable
* object and the second argument is the {@code ObjectInputStream} passed to
* {@code readObject}.
*
* @param cl a Serializable class
* @return a direct MethodHandle for the {@code readObject} method of the class or
* {@code null} if the class does not have a {@code readObject} method
*/
public final MethodHandle readObjectForSerialization(Class<?> cl) {
return findReadWriteObjectForSerialization(cl, "readObject", ObjectInputStream.class);
}
/**
* Returns a direct MethodHandle for the {@code readObjectNoData} method on
* a Serializable class.
* The first argument of {@link MethodHandle#invoke} is the serializable
* object and the second argument is the {@code ObjectInputStream} passed to
* {@code readObjectNoData}.
*
* @param cl a Serializable class
* @return a direct MethodHandle for the {@code readObjectNoData} method
* of the class or {@code null} if the class does not have a
* {@code readObjectNoData} method
*/
public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) {
return findReadWriteObjectForSerialization(cl, "readObjectNoData", ObjectInputStream.class);
}
/**
* Returns a direct MethodHandle for the {@code writeObject} method on
* a Serializable class.
* The first argument of {@link MethodHandle#invoke} is the serializable
* object and the second argument is the {@code ObjectOutputStream} passed to
* {@code writeObject}.
*
* @param cl a Serializable class
* @return a direct MethodHandle for the {@code writeObject} method of the class or
* {@code null} if the class does not have a {@code writeObject} method
*/
public final MethodHandle writeObjectForSerialization(Class<?> cl) {
return findReadWriteObjectForSerialization(cl, "writeObject", ObjectOutputStream.class);
}
private final MethodHandle findReadWriteObjectForSerialization(Class<?> cl,
String methodName,
Class<?> streamClass) {
if (!Serializable.class.isAssignableFrom(cl)) {
return null;
}
try {
Method meth = cl.getDeclaredMethod(methodName, streamClass);
int mods = meth.getModifiers();
if (meth.getReturnType() != Void.TYPE ||
Modifier.isStatic(mods) ||
!Modifier.isPrivate(mods)) {
return null;
}
meth.setAccessible(true);
return MethodHandles.lookup().unreflect(meth);
} catch (NoSuchMethodException ex) {
return null;
} catch (IllegalAccessException ex1) {
throw new InternalError("Error", ex1);
}
}
/**
* Returns a direct MethodHandle for the {@code readResolve} method on
* a serializable class.
* The single argument of {@link MethodHandle#invoke} is the serializable
* object.
*
* @param cl the Serializable class
* @return a direct MethodHandle for the {@code readResolve} method of the class or
* {@code null} if the class does not have a {@code readResolve} method
*/
public final MethodHandle readResolveForSerialization(Class<?> cl) {
return getReplaceResolveForSerialization(cl, "readResolve");
}
/**
* Returns a direct MethodHandle for the {@code writeReplace} method on
* a serializable class.
* The single argument of {@link MethodHandle#invoke} is the serializable
* object.
*
* @param cl the Serializable class
* @return a direct MethodHandle for the {@code writeReplace} method of the class or
* {@code null} if the class does not have a {@code writeReplace} method
*/
public final MethodHandle writeReplaceForSerialization(Class<?> cl) {
return getReplaceResolveForSerialization(cl, "writeReplace");
}
/**
* Returns a direct MethodHandle for the {@code writeReplace} method on
* a serializable class.
* The single argument of {@link MethodHandle#invoke} is the serializable
* object.
*
* @param cl the Serializable class
* @return a direct MethodHandle for the {@code writeReplace} method of the class or
* {@code null} if the class does not have a {@code writeReplace} method
*/
private MethodHandle getReplaceResolveForSerialization(Class<?> cl,
String methodName) {
if (!Serializable.class.isAssignableFrom(cl)) {
return null;
}
Class<?> defCl = cl;
while (defCl != null) {
try {
Method m = defCl.getDeclaredMethod(methodName);
if (m.getReturnType() != Object.class) {
return null;
}
int mods = m.getModifiers();
if (Modifier.isStatic(mods) | Modifier.isAbstract(mods)) {
return null;
} else if (Modifier.isPublic(mods) | Modifier.isProtected(mods)) {
// fall through
} else if (Modifier.isPrivate(mods) && (cl != defCl)) {
return null;
} else if (!packageEquals(cl, defCl)) {
return null;
}
try {
// Normal return
m.setAccessible(true);
return MethodHandles.lookup().unreflect(m);
} catch (IllegalAccessException ex0) {
// setAccessible should prevent IAE
throw new InternalError("Error", ex0);
}
} catch (NoSuchMethodException ex) {
defCl = defCl.getSuperclass();
}
}
return null;
}
/**
* Returns true if the class has a static initializer.
* The presence of a static initializer is used to compute the serialVersionUID.
* @param cl a serializable classLook
* @return {@code true} if the class has a static initializer,
* otherwise {@code false}
*/
public final boolean hasStaticInitializerForSerialization(Class<?> cl) {
Method m = hasStaticInitializerMethod;
if (m == null) {
try {
m = ObjectStreamClass.class.getDeclaredMethod("hasStaticInitializer",
new Class<?>[]{Class.class});
m.setAccessible(true);
hasStaticInitializerMethod = m;
} catch (NoSuchMethodException ex) {
throw new InternalError("No such method hasStaticInitializer on "
+ ObjectStreamClass.class, ex);
}
}
try {
return (Boolean) m.invoke(null, cl);
} catch (InvocationTargetException | IllegalAccessException ex) {
throw new InternalError("Exception invoking hasStaticInitializer", ex);
}
}
/**
* Returns a new OptionalDataException with {@code eof} set to {@code true}
* or {@code false}.
* @param bool the value of {@code eof} in the created OptionalDataException
* @return a new OptionalDataException
*/
public final OptionalDataException newOptionalDataExceptionForSerialization(boolean bool) {
try {
Constructor<OptionalDataException> boolCtor =
OptionalDataException.class.getDeclaredConstructor(Boolean.TYPE);
boolCtor.setAccessible(true);
return boolCtor.newInstance(bool);
} catch (NoSuchMethodException | InstantiationException|
IllegalAccessException|InvocationTargetException ex) {
throw new InternalError("unable to create OptionalDataException", ex);
}
}
//--------------------------------------------------------------------------
//
// Internals only below this point
//
static int inflationThreshold() {
return inflationThreshold;
}
/** We have to defer full initialization of this class until after
the static initializer is run since java.lang.reflect.Method's
static initializer (more properly, that for
java.lang.reflect.AccessibleObject) causes this class's to be
run, before the system properties are set up. */
private static void checkInitted() {
if (initted) return;
AccessController.doPrivileged(
new PrivilegedAction<Void>() {
public Void run() {
// Tests to ensure the system properties table is fully
// initialized. This is needed because reflection code is
// called very early in the initialization process (before
// command-line arguments have been parsed and therefore
// these user-settable properties installed.) We assume that
// if System.out is non-null then the System class has been
// fully initialized and that the bulk of the startup code
// has been run.
if (System.out == null) {
// java.lang.System not yet fully initialized
return null;
}
String val = System.getProperty("sun.reflect.noInflation");
if (val != null && val.equals("true")) {
noInflation = true;
}
val = System.getProperty("sun.reflect.inflationThreshold");
if (val != null) {
try {
inflationThreshold = Integer.parseInt(val);
} catch (NumberFormatException e) {
throw new RuntimeException("Unable to parse property sun.reflect.inflationThreshold", e);
}
}
initted = true;
return null;
}
});
}
private static LangReflectAccess langReflectAccess() {
if (langReflectAccess == null) {
// Call a static method to get class java.lang.reflect.Modifier
// initialized. Its static initializer will cause
// setLangReflectAccess() to be called from the context of the
// java.lang.reflect package.
Modifier.isPublic(Modifier.PUBLIC);
}
return langReflectAccess;
}
/**
* Returns true if classes are defined in the classloader and same package, false
* otherwise.
* @param cl1 a class
* @param cl2 another class
* @returns true if the two classes are in the same classloader and package
*/
private static boolean packageEquals(Class<?> cl1, Class<?> cl2) {
return cl1.getClassLoader() == cl2.getClassLoader() &&
Objects.equals(cl1.getPackage(), cl2.getPackage());
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
/** <P> Java serialization (in java.io) expects to be able to
instantiate a class and invoke a no-arg constructor of that
class's first non-Serializable superclass. This is not a valid
operation according to the VM specification; one can not (for
classes A and B, where B is a subclass of A) write "new B;
invokespecial A()" without getting a verification error. </P>
<P> In all other respects, the bytecode-based reflection framework
can be reused for this purpose. This marker class was originally
known to the VM and verification disabled for it and all
subclasses, but the bug fix for 4486457 necessitated disabling
verification for all of the dynamically-generated bytecodes
associated with reflection. This class has been left in place to
make future debugging easier. </P> */
abstract class SerializationConstructorAccessorImpl
extends ConstructorAccessorImpl {
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
/** Assists in iterating down a method's signature */
public class SignatureIterator {
private final String sig;
private int idx;
public SignatureIterator(String sig) {
this.sig = sig;
reset();
}
public void reset() {
idx = 1;
}
public boolean atEnd() {
return sig.charAt(idx) == ')';
}
public String next() {
if (atEnd()) return null;
char c = sig.charAt(idx);
if (c != '[' && c != 'L') {
++idx;
return new String(new char[] { c });
}
// Walk forward to end of entry
int endIdx = idx;
if (c == '[') {
while ((c = sig.charAt(endIdx)) == '[') {
endIdx++;
}
}
if (c == 'L') {
while (sig.charAt(endIdx) != ';') {
endIdx++;
}
}
int beginIdx = idx;
idx = endIdx + 1;
return sig.substring(beginIdx, idx);
}
/** Should only be called when atEnd() is true. Does not change
state of iterator. */
public String returnType() {
if (!atEnd()) {
throw new InternalError("Illegal use of SignatureIterator");
}
return sig.substring(idx + 1, sig.length());
}
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
/** It is necessary to use a "bootstrap" UTF-8 encoder for encoding
constant pool entries because the character set converters rely on
Class.newInstance(). */
class UTF8 {
// This encoder is not quite correct. It does not handle surrogate pairs.
static byte[] encode(String str) {
int len = str.length();
byte[] res = new byte[utf8Length(str)];
int utf8Idx = 0;
try {
for (int i = 0; i < len; i++) {
int c = str.charAt(i) & 0xFFFF;
if (c >= 0x0001 && c <= 0x007F) {
res[utf8Idx++] = (byte) c;
} else if (c == 0x0000 ||
(c >= 0x0080 && c <= 0x07FF)) {
res[utf8Idx++] = (byte) (0xC0 + (c >> 6));
res[utf8Idx++] = (byte) (0x80 + (c & 0x3F));
} else {
res[utf8Idx++] = (byte) (0xE0 + (c >> 12));
res[utf8Idx++] = (byte) (0x80 + ((c >> 6) & 0x3F));
res[utf8Idx++] = (byte) (0x80 + (c & 0x3F));
}
}
} catch (ArrayIndexOutOfBoundsException e) {
throw new InternalError
("Bug in sun.reflect bootstrap UTF-8 encoder", e);
}
return res;
}
private static int utf8Length(String str) {
int len = str.length();
int utf8Len = 0;
for (int i = 0; i < len; i++) {
int c = str.charAt(i) & 0xFFFF;
if (c >= 0x0001 && c <= 0x007F) {
utf8Len += 1;
} else if (c == 0x0000 ||
(c >= 0x0080 && c <= 0x07FF)) {
utf8Len += 2;
} else {
utf8Len += 3;
}
}
return utf8Len;
}
}

View File

@@ -0,0 +1,140 @@
/*
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeBooleanFieldAccessorImpl extends UnsafeFieldAccessorImpl {
UnsafeBooleanFieldAccessorImpl(Field field) {
super(field);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Boolean(getBoolean(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
ensureObj(obj);
return unsafe.getBoolean(obj, fieldOffset);
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
throw newGetIntIllegalArgumentException();
}
public long getLong(Object obj) throws IllegalArgumentException {
throw newGetLongIllegalArgumentException();
}
public float getFloat(Object obj) throws IllegalArgumentException {
throw newGetFloatIllegalArgumentException();
}
public double getDouble(Object obj) throws IllegalArgumentException {
throw newGetDoubleIllegalArgumentException();
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isFinal) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Boolean) {
unsafe.putBoolean(obj, fieldOffset, ((Boolean) value).booleanValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isFinal) {
throwFinalFieldIllegalAccessException(z);
}
unsafe.putBoolean(obj, fieldOffset, z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,140 @@
/*
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeByteFieldAccessorImpl extends UnsafeFieldAccessorImpl {
UnsafeByteFieldAccessorImpl(Field field) {
super(field);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Byte(getByte(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
ensureObj(obj);
return unsafe.getByte(obj, fieldOffset);
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
return getByte(obj);
}
public int getInt(Object obj) throws IllegalArgumentException {
return getByte(obj);
}
public long getLong(Object obj) throws IllegalArgumentException {
return getByte(obj);
}
public float getFloat(Object obj) throws IllegalArgumentException {
return getByte(obj);
}
public double getDouble(Object obj) throws IllegalArgumentException {
return getByte(obj);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isFinal) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Byte) {
unsafe.putByte(obj, fieldOffset, ((Byte) value).byteValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isFinal) {
throwFinalFieldIllegalAccessException(b);
}
unsafe.putByte(obj, fieldOffset, b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,140 @@
/*
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeCharacterFieldAccessorImpl extends UnsafeFieldAccessorImpl {
UnsafeCharacterFieldAccessorImpl(Field field) {
super(field);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Character(getChar(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
ensureObj(obj);
return unsafe.getChar(obj, fieldOffset);
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
return getChar(obj);
}
public long getLong(Object obj) throws IllegalArgumentException {
return getChar(obj);
}
public float getFloat(Object obj) throws IllegalArgumentException {
return getChar(obj);
}
public double getDouble(Object obj) throws IllegalArgumentException {
return getChar(obj);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isFinal) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Character) {
unsafe.putChar(obj, fieldOffset, ((Character) value).charValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isFinal) {
throwFinalFieldIllegalAccessException(c);
}
unsafe.putChar(obj, fieldOffset, c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,164 @@
/*
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeDoubleFieldAccessorImpl extends UnsafeFieldAccessorImpl {
UnsafeDoubleFieldAccessorImpl(Field field) {
super(field);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Double(getDouble(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
throw newGetIntIllegalArgumentException();
}
public long getLong(Object obj) throws IllegalArgumentException {
throw newGetLongIllegalArgumentException();
}
public float getFloat(Object obj) throws IllegalArgumentException {
throw newGetFloatIllegalArgumentException();
}
public double getDouble(Object obj) throws IllegalArgumentException {
ensureObj(obj);
return unsafe.getDouble(obj, fieldOffset);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isFinal) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Byte) {
unsafe.putDouble(obj, fieldOffset, ((Byte) value).byteValue());
return;
}
if (value instanceof Short) {
unsafe.putDouble(obj, fieldOffset, ((Short) value).shortValue());
return;
}
if (value instanceof Character) {
unsafe.putDouble(obj, fieldOffset, ((Character) value).charValue());
return;
}
if (value instanceof Integer) {
unsafe.putDouble(obj, fieldOffset, ((Integer) value).intValue());
return;
}
if (value instanceof Long) {
unsafe.putDouble(obj, fieldOffset, ((Long) value).longValue());
return;
}
if (value instanceof Float) {
unsafe.putDouble(obj, fieldOffset, ((Float) value).floatValue());
return;
}
if (value instanceof Double) {
unsafe.putDouble(obj, fieldOffset, ((Double) value).doubleValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
setDouble(obj, b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
setDouble(obj, c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
setDouble(obj, s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
setDouble(obj, i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
setDouble(obj, l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
setDouble(obj, f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isFinal) {
throwFinalFieldIllegalAccessException(d);
}
unsafe.putDouble(obj, fieldOffset, d);
}
}

View File

@@ -0,0 +1,130 @@
/*
* Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
class UnsafeFieldAccessorFactory {
static FieldAccessor newFieldAccessor(Field field, boolean override) {
Class<?> type = field.getType();
boolean isStatic = Modifier.isStatic(field.getModifiers());
boolean isFinal = Modifier.isFinal(field.getModifiers());
boolean isVolatile = Modifier.isVolatile(field.getModifiers());
boolean isQualified = isFinal || isVolatile;
boolean isReadOnly = isFinal && (isStatic || !override);
if (isStatic) {
// This code path does not guarantee that the field's
// declaring class has been initialized, but it must be
// before performing reflective operations.
UnsafeFieldAccessorImpl.unsafe.ensureClassInitialized(field.getDeclaringClass());
if (!isQualified) {
if (type == Boolean.TYPE) {
return new UnsafeStaticBooleanFieldAccessorImpl(field);
} else if (type == Byte.TYPE) {
return new UnsafeStaticByteFieldAccessorImpl(field);
} else if (type == Short.TYPE) {
return new UnsafeStaticShortFieldAccessorImpl(field);
} else if (type == Character.TYPE) {
return new UnsafeStaticCharacterFieldAccessorImpl(field);
} else if (type == Integer.TYPE) {
return new UnsafeStaticIntegerFieldAccessorImpl(field);
} else if (type == Long.TYPE) {
return new UnsafeStaticLongFieldAccessorImpl(field);
} else if (type == Float.TYPE) {
return new UnsafeStaticFloatFieldAccessorImpl(field);
} else if (type == Double.TYPE) {
return new UnsafeStaticDoubleFieldAccessorImpl(field);
} else {
return new UnsafeStaticObjectFieldAccessorImpl(field);
}
} else {
if (type == Boolean.TYPE) {
return new UnsafeQualifiedStaticBooleanFieldAccessorImpl(field, isReadOnly);
} else if (type == Byte.TYPE) {
return new UnsafeQualifiedStaticByteFieldAccessorImpl(field, isReadOnly);
} else if (type == Short.TYPE) {
return new UnsafeQualifiedStaticShortFieldAccessorImpl(field, isReadOnly);
} else if (type == Character.TYPE) {
return new UnsafeQualifiedStaticCharacterFieldAccessorImpl(field, isReadOnly);
} else if (type == Integer.TYPE) {
return new UnsafeQualifiedStaticIntegerFieldAccessorImpl(field, isReadOnly);
} else if (type == Long.TYPE) {
return new UnsafeQualifiedStaticLongFieldAccessorImpl(field, isReadOnly);
} else if (type == Float.TYPE) {
return new UnsafeQualifiedStaticFloatFieldAccessorImpl(field, isReadOnly);
} else if (type == Double.TYPE) {
return new UnsafeQualifiedStaticDoubleFieldAccessorImpl(field, isReadOnly);
} else {
return new UnsafeQualifiedStaticObjectFieldAccessorImpl(field, isReadOnly);
}
}
} else {
if (!isQualified) {
if (type == Boolean.TYPE) {
return new UnsafeBooleanFieldAccessorImpl(field);
} else if (type == Byte.TYPE) {
return new UnsafeByteFieldAccessorImpl(field);
} else if (type == Short.TYPE) {
return new UnsafeShortFieldAccessorImpl(field);
} else if (type == Character.TYPE) {
return new UnsafeCharacterFieldAccessorImpl(field);
} else if (type == Integer.TYPE) {
return new UnsafeIntegerFieldAccessorImpl(field);
} else if (type == Long.TYPE) {
return new UnsafeLongFieldAccessorImpl(field);
} else if (type == Float.TYPE) {
return new UnsafeFloatFieldAccessorImpl(field);
} else if (type == Double.TYPE) {
return new UnsafeDoubleFieldAccessorImpl(field);
} else {
return new UnsafeObjectFieldAccessorImpl(field);
}
} else {
if (type == Boolean.TYPE) {
return new UnsafeQualifiedBooleanFieldAccessorImpl(field, isReadOnly);
} else if (type == Byte.TYPE) {
return new UnsafeQualifiedByteFieldAccessorImpl(field, isReadOnly);
} else if (type == Short.TYPE) {
return new UnsafeQualifiedShortFieldAccessorImpl(field, isReadOnly);
} else if (type == Character.TYPE) {
return new UnsafeQualifiedCharacterFieldAccessorImpl(field, isReadOnly);
} else if (type == Integer.TYPE) {
return new UnsafeQualifiedIntegerFieldAccessorImpl(field, isReadOnly);
} else if (type == Long.TYPE) {
return new UnsafeQualifiedLongFieldAccessorImpl(field, isReadOnly);
} else if (type == Float.TYPE) {
return new UnsafeQualifiedFloatFieldAccessorImpl(field, isReadOnly);
} else if (type == Double.TYPE) {
return new UnsafeQualifiedDoubleFieldAccessorImpl(field, isReadOnly);
} else {
return new UnsafeQualifiedObjectFieldAccessorImpl(field, isReadOnly);
}
}
}
}
}

View File

@@ -0,0 +1,206 @@
/*
* Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import sun.misc.Unsafe;
/** Base class for sun.misc.Unsafe-based FieldAccessors. The
observation is that there are only nine types of fields from the
standpoint of reflection code: the eight primitive types and
Object. Using class Unsafe instead of generated bytecodes saves
memory and loading time for the dynamically-generated
FieldAccessors. */
abstract class UnsafeFieldAccessorImpl extends FieldAccessorImpl {
static final Unsafe unsafe = Unsafe.getUnsafe();
protected final Field field;
protected final long fieldOffset;
protected final boolean isFinal;
UnsafeFieldAccessorImpl(Field field) {
this.field = field;
if (Modifier.isStatic(field.getModifiers()))
fieldOffset = unsafe.staticFieldOffset(field);
else
fieldOffset = unsafe.objectFieldOffset(field);
isFinal = Modifier.isFinal(field.getModifiers());
}
protected void ensureObj(Object o) {
// NOTE: will throw NullPointerException, as specified, if o is null
if (!field.getDeclaringClass().isAssignableFrom(o.getClass())) {
throwSetIllegalArgumentException(o);
}
}
private String getQualifiedFieldName() {
return field.getDeclaringClass().getName() + "." +field.getName();
}
protected IllegalArgumentException newGetIllegalArgumentException(String type) {
return new IllegalArgumentException(
"Attempt to get "+field.getType().getName()+" field \"" +
getQualifiedFieldName() + "\" with illegal data type conversion to "+type
);
}
protected void throwFinalFieldIllegalAccessException(String attemptedType,
String attemptedValue)
throws IllegalAccessException {
throw new IllegalAccessException(getSetMessage(attemptedType, attemptedValue));
}
protected void throwFinalFieldIllegalAccessException(Object o) throws IllegalAccessException {
throwFinalFieldIllegalAccessException(o != null ? o.getClass().getName() : "", "");
}
protected void throwFinalFieldIllegalAccessException(boolean z) throws IllegalAccessException {
throwFinalFieldIllegalAccessException("boolean", Boolean.toString(z));
}
protected void throwFinalFieldIllegalAccessException(char b) throws IllegalAccessException {
throwFinalFieldIllegalAccessException("char", Character.toString(b));
}
protected void throwFinalFieldIllegalAccessException(byte b) throws IllegalAccessException {
throwFinalFieldIllegalAccessException("byte", Byte.toString(b));
}
protected void throwFinalFieldIllegalAccessException(short b) throws IllegalAccessException {
throwFinalFieldIllegalAccessException("short", Short.toString(b));
}
protected void throwFinalFieldIllegalAccessException(int i) throws IllegalAccessException {
throwFinalFieldIllegalAccessException("int", Integer.toString(i));
}
protected void throwFinalFieldIllegalAccessException(long i) throws IllegalAccessException {
throwFinalFieldIllegalAccessException("long", Long.toString(i));
}
protected void throwFinalFieldIllegalAccessException(float f) throws IllegalAccessException {
throwFinalFieldIllegalAccessException("float", Float.toString(f));
}
protected void throwFinalFieldIllegalAccessException(double f) throws IllegalAccessException {
throwFinalFieldIllegalAccessException("double", Double.toString(f));
}
protected IllegalArgumentException newGetBooleanIllegalArgumentException() {
return newGetIllegalArgumentException("boolean");
}
protected IllegalArgumentException newGetByteIllegalArgumentException() {
return newGetIllegalArgumentException("byte");
}
protected IllegalArgumentException newGetCharIllegalArgumentException() {
return newGetIllegalArgumentException("char");
}
protected IllegalArgumentException newGetShortIllegalArgumentException() {
return newGetIllegalArgumentException("short");
}
protected IllegalArgumentException newGetIntIllegalArgumentException() {
return newGetIllegalArgumentException("int");
}
protected IllegalArgumentException newGetLongIllegalArgumentException() {
return newGetIllegalArgumentException("long");
}
protected IllegalArgumentException newGetFloatIllegalArgumentException() {
return newGetIllegalArgumentException("float");
}
protected IllegalArgumentException newGetDoubleIllegalArgumentException() {
return newGetIllegalArgumentException("double");
}
protected String getSetMessage(String attemptedType, String attemptedValue) {
String err = "Can not set";
if (Modifier.isStatic(field.getModifiers()))
err += " static";
if (isFinal)
err += " final";
err += " " + field.getType().getName() + " field " + getQualifiedFieldName() + " to ";
if (attemptedValue.length() > 0) {
err += "(" + attemptedType + ")" + attemptedValue;
} else {
if (attemptedType.length() > 0)
err += attemptedType;
else
err += "null value";
}
return err;
}
protected void throwSetIllegalArgumentException(String attemptedType,
String attemptedValue) {
throw new IllegalArgumentException(getSetMessage(attemptedType,attemptedValue));
}
protected void throwSetIllegalArgumentException(Object o) {
throwSetIllegalArgumentException(o != null ? o.getClass().getName() : "", "");
}
protected void throwSetIllegalArgumentException(boolean b) {
throwSetIllegalArgumentException("boolean", Boolean.toString(b));
}
protected void throwSetIllegalArgumentException(byte b) {
throwSetIllegalArgumentException("byte", Byte.toString(b));
}
protected void throwSetIllegalArgumentException(char c) {
throwSetIllegalArgumentException("char", Character.toString(c));
}
protected void throwSetIllegalArgumentException(short s) {
throwSetIllegalArgumentException("short", Short.toString(s));
}
protected void throwSetIllegalArgumentException(int i) {
throwSetIllegalArgumentException("int", Integer.toString(i));
}
protected void throwSetIllegalArgumentException(long l) {
throwSetIllegalArgumentException("long", Long.toString(l));
}
protected void throwSetIllegalArgumentException(float f) {
throwSetIllegalArgumentException("float", Float.toString(f));
}
protected void throwSetIllegalArgumentException(double d) {
throwSetIllegalArgumentException("double", Double.toString(d));
}
}

View File

@@ -0,0 +1,160 @@
/*
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeFloatFieldAccessorImpl extends UnsafeFieldAccessorImpl {
UnsafeFloatFieldAccessorImpl(Field field) {
super(field);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Float(getFloat(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
throw newGetIntIllegalArgumentException();
}
public long getLong(Object obj) throws IllegalArgumentException {
throw newGetLongIllegalArgumentException();
}
public float getFloat(Object obj) throws IllegalArgumentException {
ensureObj(obj);
return unsafe.getFloat(obj, fieldOffset);
}
public double getDouble(Object obj) throws IllegalArgumentException {
return getFloat(obj);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isFinal) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Byte) {
unsafe.putFloat(obj, fieldOffset, ((Byte) value).byteValue());
return;
}
if (value instanceof Short) {
unsafe.putFloat(obj, fieldOffset, ((Short) value).shortValue());
return;
}
if (value instanceof Character) {
unsafe.putFloat(obj, fieldOffset, ((Character) value).charValue());
return;
}
if (value instanceof Integer) {
unsafe.putFloat(obj, fieldOffset, ((Integer) value).intValue());
return;
}
if (value instanceof Long) {
unsafe.putFloat(obj, fieldOffset, ((Long) value).longValue());
return;
}
if (value instanceof Float) {
unsafe.putFloat(obj, fieldOffset, ((Float) value).floatValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
setFloat(obj, b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
setFloat(obj, c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
setFloat(obj, s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
setFloat(obj, i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
setFloat(obj, l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isFinal) {
throwFinalFieldIllegalAccessException(f);
}
unsafe.putFloat(obj, fieldOffset, f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,152 @@
/*
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeIntegerFieldAccessorImpl extends UnsafeFieldAccessorImpl {
UnsafeIntegerFieldAccessorImpl(Field field) {
super(field);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Integer(getInt(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
ensureObj(obj);
return unsafe.getInt(obj, fieldOffset);
}
public long getLong(Object obj) throws IllegalArgumentException {
return getInt(obj);
}
public float getFloat(Object obj) throws IllegalArgumentException {
return getInt(obj);
}
public double getDouble(Object obj) throws IllegalArgumentException {
return getInt(obj);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isFinal) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Byte) {
unsafe.putInt(obj, fieldOffset, ((Byte) value).byteValue());
return;
}
if (value instanceof Short) {
unsafe.putInt(obj, fieldOffset, ((Short) value).shortValue());
return;
}
if (value instanceof Character) {
unsafe.putInt(obj, fieldOffset, ((Character) value).charValue());
return;
}
if (value instanceof Integer) {
unsafe.putInt(obj, fieldOffset, ((Integer) value).intValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
setInt(obj, b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
setInt(obj, c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
setInt(obj, s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isFinal) {
throwFinalFieldIllegalAccessException(i);
}
unsafe.putInt(obj, fieldOffset, i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,156 @@
/*
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeLongFieldAccessorImpl extends UnsafeFieldAccessorImpl {
UnsafeLongFieldAccessorImpl(Field field) {
super(field);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Long(getLong(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
throw newGetIntIllegalArgumentException();
}
public long getLong(Object obj) throws IllegalArgumentException {
ensureObj(obj);
return unsafe.getLong(obj, fieldOffset);
}
public float getFloat(Object obj) throws IllegalArgumentException {
return getLong(obj);
}
public double getDouble(Object obj) throws IllegalArgumentException {
return getLong(obj);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isFinal) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Byte) {
unsafe.putLong(obj, fieldOffset, ((Byte) value).byteValue());
return;
}
if (value instanceof Short) {
unsafe.putLong(obj, fieldOffset, ((Short) value).shortValue());
return;
}
if (value instanceof Character) {
unsafe.putLong(obj, fieldOffset, ((Character) value).charValue());
return;
}
if (value instanceof Integer) {
unsafe.putLong(obj, fieldOffset, ((Integer) value).intValue());
return;
}
if (value instanceof Long) {
unsafe.putLong(obj, fieldOffset, ((Long) value).longValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
setLong(obj, b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
setLong(obj, c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
setLong(obj, s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
setLong(obj, i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isFinal) {
throwFinalFieldIllegalAccessException(l);
}
unsafe.putLong(obj, fieldOffset, l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,134 @@
/*
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeObjectFieldAccessorImpl extends UnsafeFieldAccessorImpl {
UnsafeObjectFieldAccessorImpl(Field field) {
super(field);
}
public Object get(Object obj) throws IllegalArgumentException {
ensureObj(obj);
return unsafe.getObject(obj, fieldOffset);
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
throw newGetIntIllegalArgumentException();
}
public long getLong(Object obj) throws IllegalArgumentException {
throw newGetLongIllegalArgumentException();
}
public float getFloat(Object obj) throws IllegalArgumentException {
throw newGetFloatIllegalArgumentException();
}
public double getDouble(Object obj) throws IllegalArgumentException {
throw newGetDoubleIllegalArgumentException();
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isFinal) {
throwFinalFieldIllegalAccessException(value);
}
if (value != null) {
if (!field.getType().isAssignableFrom(value.getClass())) {
throwSetIllegalArgumentException(value);
}
}
unsafe.putObject(obj, fieldOffset, value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,142 @@
/*
* Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeQualifiedBooleanFieldAccessorImpl
extends UnsafeQualifiedFieldAccessorImpl
{
UnsafeQualifiedBooleanFieldAccessorImpl(Field field, boolean isReadOnly) {
super(field, isReadOnly);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Boolean(getBoolean(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
ensureObj(obj);
return unsafe.getBooleanVolatile(obj, fieldOffset);
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
throw newGetIntIllegalArgumentException();
}
public long getLong(Object obj) throws IllegalArgumentException {
throw newGetLongIllegalArgumentException();
}
public float getFloat(Object obj) throws IllegalArgumentException {
throw newGetFloatIllegalArgumentException();
}
public double getDouble(Object obj) throws IllegalArgumentException {
throw newGetDoubleIllegalArgumentException();
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isReadOnly) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Boolean) {
unsafe.putBooleanVolatile(obj, fieldOffset, ((Boolean) value).booleanValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isReadOnly) {
throwFinalFieldIllegalAccessException(z);
}
unsafe.putBooleanVolatile(obj, fieldOffset, z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,142 @@
/*
* Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeQualifiedByteFieldAccessorImpl
extends UnsafeQualifiedFieldAccessorImpl
{
UnsafeQualifiedByteFieldAccessorImpl(Field field, boolean isReadOnly) {
super(field, isReadOnly);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Byte(getByte(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
ensureObj(obj);
return unsafe.getByteVolatile(obj, fieldOffset);
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
return getByte(obj);
}
public int getInt(Object obj) throws IllegalArgumentException {
return getByte(obj);
}
public long getLong(Object obj) throws IllegalArgumentException {
return getByte(obj);
}
public float getFloat(Object obj) throws IllegalArgumentException {
return getByte(obj);
}
public double getDouble(Object obj) throws IllegalArgumentException {
return getByte(obj);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isReadOnly) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Byte) {
unsafe.putByteVolatile(obj, fieldOffset, ((Byte) value).byteValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isReadOnly) {
throwFinalFieldIllegalAccessException(b);
}
unsafe.putByteVolatile(obj, fieldOffset, b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,142 @@
/*
* Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeQualifiedCharacterFieldAccessorImpl
extends UnsafeQualifiedFieldAccessorImpl
{
UnsafeQualifiedCharacterFieldAccessorImpl(Field field, boolean isReadOnly) {
super(field, isReadOnly);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Character(getChar(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
ensureObj(obj);
return unsafe.getCharVolatile(obj, fieldOffset);
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
return getChar(obj);
}
public long getLong(Object obj) throws IllegalArgumentException {
return getChar(obj);
}
public float getFloat(Object obj) throws IllegalArgumentException {
return getChar(obj);
}
public double getDouble(Object obj) throws IllegalArgumentException {
return getChar(obj);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isReadOnly) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Character) {
unsafe.putCharVolatile(obj, fieldOffset, ((Character) value).charValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isReadOnly) {
throwFinalFieldIllegalAccessException(c);
}
unsafe.putCharVolatile(obj, fieldOffset, c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,166 @@
/*
* Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeQualifiedDoubleFieldAccessorImpl
extends UnsafeQualifiedFieldAccessorImpl
{
UnsafeQualifiedDoubleFieldAccessorImpl(Field field, boolean isReadOnly) {
super(field, isReadOnly);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Double(getDouble(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
throw newGetIntIllegalArgumentException();
}
public long getLong(Object obj) throws IllegalArgumentException {
throw newGetLongIllegalArgumentException();
}
public float getFloat(Object obj) throws IllegalArgumentException {
throw newGetFloatIllegalArgumentException();
}
public double getDouble(Object obj) throws IllegalArgumentException {
ensureObj(obj);
return unsafe.getDoubleVolatile(obj, fieldOffset);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isReadOnly) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Byte) {
unsafe.putDoubleVolatile(obj, fieldOffset, ((Byte) value).byteValue());
return;
}
if (value instanceof Short) {
unsafe.putDoubleVolatile(obj, fieldOffset, ((Short) value).shortValue());
return;
}
if (value instanceof Character) {
unsafe.putDoubleVolatile(obj, fieldOffset, ((Character) value).charValue());
return;
}
if (value instanceof Integer) {
unsafe.putDoubleVolatile(obj, fieldOffset, ((Integer) value).intValue());
return;
}
if (value instanceof Long) {
unsafe.putDoubleVolatile(obj, fieldOffset, ((Long) value).longValue());
return;
}
if (value instanceof Float) {
unsafe.putDoubleVolatile(obj, fieldOffset, ((Float) value).floatValue());
return;
}
if (value instanceof Double) {
unsafe.putDoubleVolatile(obj, fieldOffset, ((Double) value).doubleValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
setDouble(obj, b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
setDouble(obj, c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
setDouble(obj, s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
setDouble(obj, i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
setDouble(obj, l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
setDouble(obj, f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isReadOnly) {
throwFinalFieldIllegalAccessException(d);
}
unsafe.putDoubleVolatile(obj, fieldOffset, d);
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import sun.misc.Unsafe;
/**
* Base class for sun.misc.Unsafe-based FieldAccessors for fields with
* final or volatile qualifiers. These differ from unqualified
* versions in that (1) they check for read-only status (2) they use
* the volatile forms of Unsafe get/put methods. (When accessed via
* reflection, finals act as slightly "lighter" forms of volatiles. So
* the volatile forms are heavier than necessary in terms of
* underlying reordering rules and memory barriers, but preserve
* correctness.)
*/
abstract class UnsafeQualifiedFieldAccessorImpl
extends UnsafeFieldAccessorImpl
{
protected final boolean isReadOnly;
UnsafeQualifiedFieldAccessorImpl(Field field, boolean isReadOnly) {
super(field);
this.isReadOnly = isReadOnly;
}
}

View File

@@ -0,0 +1,162 @@
/*
* Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeQualifiedFloatFieldAccessorImpl
extends UnsafeQualifiedFieldAccessorImpl
{
UnsafeQualifiedFloatFieldAccessorImpl(Field field, boolean isReadOnly) {
super(field, isReadOnly);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Float(getFloat(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
throw newGetIntIllegalArgumentException();
}
public long getLong(Object obj) throws IllegalArgumentException {
throw newGetLongIllegalArgumentException();
}
public float getFloat(Object obj) throws IllegalArgumentException {
ensureObj(obj);
return unsafe.getFloatVolatile(obj, fieldOffset);
}
public double getDouble(Object obj) throws IllegalArgumentException {
return getFloat(obj);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isReadOnly) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Byte) {
unsafe.putFloatVolatile(obj, fieldOffset, ((Byte) value).byteValue());
return;
}
if (value instanceof Short) {
unsafe.putFloatVolatile(obj, fieldOffset, ((Short) value).shortValue());
return;
}
if (value instanceof Character) {
unsafe.putFloatVolatile(obj, fieldOffset, ((Character) value).charValue());
return;
}
if (value instanceof Integer) {
unsafe.putFloatVolatile(obj, fieldOffset, ((Integer) value).intValue());
return;
}
if (value instanceof Long) {
unsafe.putFloatVolatile(obj, fieldOffset, ((Long) value).longValue());
return;
}
if (value instanceof Float) {
unsafe.putFloatVolatile(obj, fieldOffset, ((Float) value).floatValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
setFloat(obj, b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
setFloat(obj, c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
setFloat(obj, s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
setFloat(obj, i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
setFloat(obj, l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isReadOnly) {
throwFinalFieldIllegalAccessException(f);
}
unsafe.putFloatVolatile(obj, fieldOffset, f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,154 @@
/*
* Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeQualifiedIntegerFieldAccessorImpl
extends UnsafeQualifiedFieldAccessorImpl
{
UnsafeQualifiedIntegerFieldAccessorImpl(Field field, boolean isReadOnly) {
super(field, isReadOnly);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Integer(getInt(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
ensureObj(obj);
return unsafe.getIntVolatile(obj, fieldOffset);
}
public long getLong(Object obj) throws IllegalArgumentException {
return getInt(obj);
}
public float getFloat(Object obj) throws IllegalArgumentException {
return getInt(obj);
}
public double getDouble(Object obj) throws IllegalArgumentException {
return getInt(obj);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isReadOnly) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Byte) {
unsafe.putIntVolatile(obj, fieldOffset, ((Byte) value).byteValue());
return;
}
if (value instanceof Short) {
unsafe.putIntVolatile(obj, fieldOffset, ((Short) value).shortValue());
return;
}
if (value instanceof Character) {
unsafe.putIntVolatile(obj, fieldOffset, ((Character) value).charValue());
return;
}
if (value instanceof Integer) {
unsafe.putIntVolatile(obj, fieldOffset, ((Integer) value).intValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
setInt(obj, b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
setInt(obj, c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
setInt(obj, s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isReadOnly) {
throwFinalFieldIllegalAccessException(i);
}
unsafe.putIntVolatile(obj, fieldOffset, i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,158 @@
/*
* Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeQualifiedLongFieldAccessorImpl
extends UnsafeQualifiedFieldAccessorImpl
{
UnsafeQualifiedLongFieldAccessorImpl(Field field, boolean isReadOnly) {
super(field, isReadOnly);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Long(getLong(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
throw newGetIntIllegalArgumentException();
}
public long getLong(Object obj) throws IllegalArgumentException {
ensureObj(obj);
return unsafe.getLongVolatile(obj, fieldOffset);
}
public float getFloat(Object obj) throws IllegalArgumentException {
return getLong(obj);
}
public double getDouble(Object obj) throws IllegalArgumentException {
return getLong(obj);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isReadOnly) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Byte) {
unsafe.putLongVolatile(obj, fieldOffset, ((Byte) value).byteValue());
return;
}
if (value instanceof Short) {
unsafe.putLongVolatile(obj, fieldOffset, ((Short) value).shortValue());
return;
}
if (value instanceof Character) {
unsafe.putLongVolatile(obj, fieldOffset, ((Character) value).charValue());
return;
}
if (value instanceof Integer) {
unsafe.putLongVolatile(obj, fieldOffset, ((Integer) value).intValue());
return;
}
if (value instanceof Long) {
unsafe.putLongVolatile(obj, fieldOffset, ((Long) value).longValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
setLong(obj, b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
setLong(obj, c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
setLong(obj, s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
setLong(obj, i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isReadOnly) {
throwFinalFieldIllegalAccessException(l);
}
unsafe.putLongVolatile(obj, fieldOffset, l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,136 @@
/*
* Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeQualifiedObjectFieldAccessorImpl
extends UnsafeQualifiedFieldAccessorImpl
{
UnsafeQualifiedObjectFieldAccessorImpl(Field field, boolean isReadOnly) {
super(field, isReadOnly);
}
public Object get(Object obj) throws IllegalArgumentException {
ensureObj(obj);
return unsafe.getObjectVolatile(obj, fieldOffset);
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
throw newGetIntIllegalArgumentException();
}
public long getLong(Object obj) throws IllegalArgumentException {
throw newGetLongIllegalArgumentException();
}
public float getFloat(Object obj) throws IllegalArgumentException {
throw newGetFloatIllegalArgumentException();
}
public double getDouble(Object obj) throws IllegalArgumentException {
throw newGetDoubleIllegalArgumentException();
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isReadOnly) {
throwFinalFieldIllegalAccessException(value);
}
if (value != null) {
if (!field.getType().isAssignableFrom(value.getClass())) {
throwSetIllegalArgumentException(value);
}
}
unsafe.putObjectVolatile(obj, fieldOffset, value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,146 @@
/*
* Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeQualifiedShortFieldAccessorImpl
extends UnsafeQualifiedFieldAccessorImpl
{
UnsafeQualifiedShortFieldAccessorImpl(Field field, boolean isReadOnly) {
super(field, isReadOnly);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Short(getShort(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
ensureObj(obj);
return unsafe.getShortVolatile(obj, fieldOffset);
}
public int getInt(Object obj) throws IllegalArgumentException {
return getShort(obj);
}
public long getLong(Object obj) throws IllegalArgumentException {
return getShort(obj);
}
public float getFloat(Object obj) throws IllegalArgumentException {
return getShort(obj);
}
public double getDouble(Object obj) throws IllegalArgumentException {
return getShort(obj);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isReadOnly) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Byte) {
unsafe.putShortVolatile(obj, fieldOffset, ((Byte) value).byteValue());
return;
}
if (value instanceof Short) {
unsafe.putShortVolatile(obj, fieldOffset, ((Short) value).shortValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
setShort(obj, b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isReadOnly) {
throwFinalFieldIllegalAccessException(s);
}
unsafe.putShortVolatile(obj, fieldOffset, s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,139 @@
/*
* Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeQualifiedStaticBooleanFieldAccessorImpl
extends UnsafeQualifiedStaticFieldAccessorImpl
{
UnsafeQualifiedStaticBooleanFieldAccessorImpl(Field field, boolean isReadOnly) {
super(field, isReadOnly);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Boolean(getBoolean(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
return unsafe.getBooleanVolatile(base, fieldOffset);
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
throw newGetIntIllegalArgumentException();
}
public long getLong(Object obj) throws IllegalArgumentException {
throw newGetLongIllegalArgumentException();
}
public float getFloat(Object obj) throws IllegalArgumentException {
throw newGetFloatIllegalArgumentException();
}
public double getDouble(Object obj) throws IllegalArgumentException {
throw newGetDoubleIllegalArgumentException();
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
if (isReadOnly) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Boolean) {
unsafe.putBooleanVolatile(base, fieldOffset, ((Boolean) value).booleanValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
if (isReadOnly) {
throwFinalFieldIllegalAccessException(z);
}
unsafe.putBooleanVolatile(base, fieldOffset, z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,139 @@
/*
* Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeQualifiedStaticByteFieldAccessorImpl
extends UnsafeQualifiedStaticFieldAccessorImpl
{
UnsafeQualifiedStaticByteFieldAccessorImpl(Field field, boolean isReadOnly) {
super(field, isReadOnly);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Byte(getByte(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
return unsafe.getByteVolatile(base, fieldOffset);
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
return getByte(obj);
}
public int getInt(Object obj) throws IllegalArgumentException {
return getByte(obj);
}
public long getLong(Object obj) throws IllegalArgumentException {
return getByte(obj);
}
public float getFloat(Object obj) throws IllegalArgumentException {
return getByte(obj);
}
public double getDouble(Object obj) throws IllegalArgumentException {
return getByte(obj);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
if (isReadOnly) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Byte) {
unsafe.putByteVolatile(base, fieldOffset, ((Byte) value).byteValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
if (isReadOnly) {
throwFinalFieldIllegalAccessException(b);
}
unsafe.putByteVolatile(base, fieldOffset, b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,139 @@
/*
* Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeQualifiedStaticCharacterFieldAccessorImpl
extends UnsafeQualifiedStaticFieldAccessorImpl
{
UnsafeQualifiedStaticCharacterFieldAccessorImpl(Field field, boolean isReadOnly) {
super(field, isReadOnly);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Character(getChar(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
return unsafe.getCharVolatile(base, fieldOffset);
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
return getChar(obj);
}
public long getLong(Object obj) throws IllegalArgumentException {
return getChar(obj);
}
public float getFloat(Object obj) throws IllegalArgumentException {
return getChar(obj);
}
public double getDouble(Object obj) throws IllegalArgumentException {
return getChar(obj);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
if (isReadOnly) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Character) {
unsafe.putCharVolatile(base, fieldOffset, ((Character) value).charValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
if (isReadOnly) {
throwFinalFieldIllegalAccessException(c);
}
unsafe.putCharVolatile(base, fieldOffset, c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,163 @@
/*
* Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeQualifiedStaticDoubleFieldAccessorImpl
extends UnsafeQualifiedStaticFieldAccessorImpl
{
UnsafeQualifiedStaticDoubleFieldAccessorImpl(Field field, boolean isReadOnly) {
super(field, isReadOnly);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Double(getDouble(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
throw newGetIntIllegalArgumentException();
}
public long getLong(Object obj) throws IllegalArgumentException {
throw newGetLongIllegalArgumentException();
}
public float getFloat(Object obj) throws IllegalArgumentException {
throw newGetFloatIllegalArgumentException();
}
public double getDouble(Object obj) throws IllegalArgumentException {
return unsafe.getDoubleVolatile(base, fieldOffset);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
if (isReadOnly) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Byte) {
unsafe.putDoubleVolatile(base, fieldOffset, ((Byte) value).byteValue());
return;
}
if (value instanceof Short) {
unsafe.putDoubleVolatile(base, fieldOffset, ((Short) value).shortValue());
return;
}
if (value instanceof Character) {
unsafe.putDoubleVolatile(base, fieldOffset, ((Character) value).charValue());
return;
}
if (value instanceof Integer) {
unsafe.putDoubleVolatile(base, fieldOffset, ((Integer) value).intValue());
return;
}
if (value instanceof Long) {
unsafe.putDoubleVolatile(base, fieldOffset, ((Long) value).longValue());
return;
}
if (value instanceof Float) {
unsafe.putDoubleVolatile(base, fieldOffset, ((Float) value).floatValue());
return;
}
if (value instanceof Double) {
unsafe.putDoubleVolatile(base, fieldOffset, ((Double) value).doubleValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
setDouble(obj, b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
setDouble(obj, c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
setDouble(obj, s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
setDouble(obj, i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
setDouble(obj, l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
setDouble(obj, f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
if (isReadOnly) {
throwFinalFieldIllegalAccessException(d);
}
unsafe.putDoubleVolatile(base, fieldOffset, d);
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.security.AccessController;
import sun.misc.Unsafe;
/** Base class for sun.misc.Unsafe-based FieldAccessors for final or
volatile static fields. */
abstract class UnsafeQualifiedStaticFieldAccessorImpl
extends UnsafeStaticFieldAccessorImpl
{
protected final boolean isReadOnly;
UnsafeQualifiedStaticFieldAccessorImpl(Field field, boolean isReadOnly) {
super(field);
this.isReadOnly = isReadOnly;
}
}

View File

@@ -0,0 +1,159 @@
/*
* Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeQualifiedStaticFloatFieldAccessorImpl
extends UnsafeQualifiedStaticFieldAccessorImpl
{
UnsafeQualifiedStaticFloatFieldAccessorImpl(Field field, boolean isReadOnly) {
super(field, isReadOnly);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Float(getFloat(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
throw newGetIntIllegalArgumentException();
}
public long getLong(Object obj) throws IllegalArgumentException {
throw newGetLongIllegalArgumentException();
}
public float getFloat(Object obj) throws IllegalArgumentException {
return unsafe.getFloatVolatile(base, fieldOffset);
}
public double getDouble(Object obj) throws IllegalArgumentException {
return getFloat(obj);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
if (isReadOnly) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Byte) {
unsafe.putFloatVolatile(base, fieldOffset, ((Byte) value).byteValue());
return;
}
if (value instanceof Short) {
unsafe.putFloatVolatile(base, fieldOffset, ((Short) value).shortValue());
return;
}
if (value instanceof Character) {
unsafe.putFloatVolatile(base, fieldOffset, ((Character) value).charValue());
return;
}
if (value instanceof Integer) {
unsafe.putFloatVolatile(base, fieldOffset, ((Integer) value).intValue());
return;
}
if (value instanceof Long) {
unsafe.putFloatVolatile(base, fieldOffset, ((Long) value).longValue());
return;
}
if (value instanceof Float) {
unsafe.putFloatVolatile(base, fieldOffset, ((Float) value).floatValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
setFloat(obj, b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
setFloat(obj, c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
setFloat(obj, s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
setFloat(obj, i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
setFloat(obj, l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
if (isReadOnly) {
throwFinalFieldIllegalAccessException(f);
}
unsafe.putFloatVolatile(base, fieldOffset, f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,151 @@
/*
* Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeQualifiedStaticIntegerFieldAccessorImpl
extends UnsafeQualifiedStaticFieldAccessorImpl
{
UnsafeQualifiedStaticIntegerFieldAccessorImpl(Field field, boolean isReadOnly) {
super(field, isReadOnly);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Integer(getInt(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
return unsafe.getIntVolatile(base, fieldOffset);
}
public long getLong(Object obj) throws IllegalArgumentException {
return getInt(obj);
}
public float getFloat(Object obj) throws IllegalArgumentException {
return getInt(obj);
}
public double getDouble(Object obj) throws IllegalArgumentException {
return getInt(obj);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
if (isReadOnly) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Byte) {
unsafe.putIntVolatile(base, fieldOffset, ((Byte) value).byteValue());
return;
}
if (value instanceof Short) {
unsafe.putIntVolatile(base, fieldOffset, ((Short) value).shortValue());
return;
}
if (value instanceof Character) {
unsafe.putIntVolatile(base, fieldOffset, ((Character) value).charValue());
return;
}
if (value instanceof Integer) {
unsafe.putIntVolatile(base, fieldOffset, ((Integer) value).intValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
setInt(obj, b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
setInt(obj, c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
setInt(obj, s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
if (isReadOnly) {
throwFinalFieldIllegalAccessException(i);
}
unsafe.putIntVolatile(base, fieldOffset, i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,155 @@
/*
* Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeQualifiedStaticLongFieldAccessorImpl
extends UnsafeQualifiedStaticFieldAccessorImpl
{
UnsafeQualifiedStaticLongFieldAccessorImpl(Field field, boolean isReadOnly) {
super(field, isReadOnly);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Long(getLong(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
throw newGetIntIllegalArgumentException();
}
public long getLong(Object obj) throws IllegalArgumentException {
return unsafe.getLongVolatile(base, fieldOffset);
}
public float getFloat(Object obj) throws IllegalArgumentException {
return getLong(obj);
}
public double getDouble(Object obj) throws IllegalArgumentException {
return getLong(obj);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
if (isReadOnly) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Byte) {
unsafe.putLongVolatile(base, fieldOffset, ((Byte) value).byteValue());
return;
}
if (value instanceof Short) {
unsafe.putLongVolatile(base, fieldOffset, ((Short) value).shortValue());
return;
}
if (value instanceof Character) {
unsafe.putLongVolatile(base, fieldOffset, ((Character) value).charValue());
return;
}
if (value instanceof Integer) {
unsafe.putLongVolatile(base, fieldOffset, ((Integer) value).intValue());
return;
}
if (value instanceof Long) {
unsafe.putLongVolatile(base, fieldOffset, ((Long) value).longValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
setLong(obj, b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
setLong(obj, c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
setLong(obj, s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
setLong(obj, i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
if (isReadOnly) {
throwFinalFieldIllegalAccessException(l);
}
unsafe.putLongVolatile(base, fieldOffset, l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,134 @@
/*
* Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeQualifiedStaticObjectFieldAccessorImpl
extends UnsafeQualifiedStaticFieldAccessorImpl
{
UnsafeQualifiedStaticObjectFieldAccessorImpl(Field field, boolean isReadOnly) {
super(field, isReadOnly);
}
public Object get(Object obj) throws IllegalArgumentException {
return unsafe.getObjectVolatile(base, fieldOffset);
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
throw newGetIntIllegalArgumentException();
}
public long getLong(Object obj) throws IllegalArgumentException {
throw newGetLongIllegalArgumentException();
}
public float getFloat(Object obj) throws IllegalArgumentException {
throw newGetFloatIllegalArgumentException();
}
public double getDouble(Object obj) throws IllegalArgumentException {
throw newGetDoubleIllegalArgumentException();
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
if (isReadOnly) {
throwFinalFieldIllegalAccessException(value);
}
if (value != null) {
if (!field.getType().isAssignableFrom(value.getClass())) {
throwSetIllegalArgumentException(value);
}
}
unsafe.putObjectVolatile(base, fieldOffset, value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,143 @@
/*
* Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeQualifiedStaticShortFieldAccessorImpl
extends UnsafeQualifiedStaticFieldAccessorImpl
{
UnsafeQualifiedStaticShortFieldAccessorImpl(Field field, boolean isReadOnly) {
super(field, isReadOnly);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Short(getShort(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
return unsafe.getShortVolatile(base, fieldOffset);
}
public int getInt(Object obj) throws IllegalArgumentException {
return getShort(obj);
}
public long getLong(Object obj) throws IllegalArgumentException {
return getShort(obj);
}
public float getFloat(Object obj) throws IllegalArgumentException {
return getShort(obj);
}
public double getDouble(Object obj) throws IllegalArgumentException {
return getShort(obj);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
if (isReadOnly) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Byte) {
unsafe.putShortVolatile(base, fieldOffset, ((Byte) value).byteValue());
return;
}
if (value instanceof Short) {
unsafe.putShortVolatile(base, fieldOffset, ((Short) value).shortValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
setShort(obj, b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
if (isReadOnly) {
throwFinalFieldIllegalAccessException(s);
}
unsafe.putShortVolatile(base, fieldOffset, s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,144 @@
/*
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeShortFieldAccessorImpl extends UnsafeFieldAccessorImpl {
UnsafeShortFieldAccessorImpl(Field field) {
super(field);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Short(getShort(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
ensureObj(obj);
return unsafe.getShort(obj, fieldOffset);
}
public int getInt(Object obj) throws IllegalArgumentException {
return getShort(obj);
}
public long getLong(Object obj) throws IllegalArgumentException {
return getShort(obj);
}
public float getFloat(Object obj) throws IllegalArgumentException {
return getShort(obj);
}
public double getDouble(Object obj) throws IllegalArgumentException {
return getShort(obj);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isFinal) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Byte) {
unsafe.putShort(obj, fieldOffset, ((Byte) value).byteValue());
return;
}
if (value instanceof Short) {
unsafe.putShort(obj, fieldOffset, ((Short) value).shortValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
setShort(obj, b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
ensureObj(obj);
if (isFinal) {
throwFinalFieldIllegalAccessException(s);
}
unsafe.putShort(obj, fieldOffset, s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,137 @@
/*
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeStaticBooleanFieldAccessorImpl extends UnsafeStaticFieldAccessorImpl {
UnsafeStaticBooleanFieldAccessorImpl(Field field) {
super(field);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Boolean(getBoolean(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
return unsafe.getBoolean(base, fieldOffset);
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
throw newGetIntIllegalArgumentException();
}
public long getLong(Object obj) throws IllegalArgumentException {
throw newGetLongIllegalArgumentException();
}
public float getFloat(Object obj) throws IllegalArgumentException {
throw newGetFloatIllegalArgumentException();
}
public double getDouble(Object obj) throws IllegalArgumentException {
throw newGetDoubleIllegalArgumentException();
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
if (isFinal) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Boolean) {
unsafe.putBoolean(base, fieldOffset, ((Boolean) value).booleanValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
if (isFinal) {
throwFinalFieldIllegalAccessException(z);
}
unsafe.putBoolean(base, fieldOffset, z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,137 @@
/*
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeStaticByteFieldAccessorImpl extends UnsafeStaticFieldAccessorImpl {
UnsafeStaticByteFieldAccessorImpl(Field field) {
super(field);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Byte(getByte(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
return unsafe.getByte(base, fieldOffset);
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
return getByte(obj);
}
public int getInt(Object obj) throws IllegalArgumentException {
return getByte(obj);
}
public long getLong(Object obj) throws IllegalArgumentException {
return getByte(obj);
}
public float getFloat(Object obj) throws IllegalArgumentException {
return getByte(obj);
}
public double getDouble(Object obj) throws IllegalArgumentException {
return getByte(obj);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
if (isFinal) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Byte) {
unsafe.putByte(base, fieldOffset, ((Byte) value).byteValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
if (isFinal) {
throwFinalFieldIllegalAccessException(b);
}
unsafe.putByte(base, fieldOffset, b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,137 @@
/*
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeStaticCharacterFieldAccessorImpl extends UnsafeStaticFieldAccessorImpl {
UnsafeStaticCharacterFieldAccessorImpl(Field field) {
super(field);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Character(getChar(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
return unsafe.getChar(base, fieldOffset);
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
return getChar(obj);
}
public long getLong(Object obj) throws IllegalArgumentException {
return getChar(obj);
}
public float getFloat(Object obj) throws IllegalArgumentException {
return getChar(obj);
}
public double getDouble(Object obj) throws IllegalArgumentException {
return getChar(obj);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
if (isFinal) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Character) {
unsafe.putChar(base, fieldOffset, ((Character) value).charValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
if (isFinal) {
throwFinalFieldIllegalAccessException(c);
}
unsafe.putChar(base, fieldOffset, c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,161 @@
/*
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeStaticDoubleFieldAccessorImpl extends UnsafeStaticFieldAccessorImpl {
UnsafeStaticDoubleFieldAccessorImpl(Field field) {
super(field);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Double(getDouble(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
throw newGetIntIllegalArgumentException();
}
public long getLong(Object obj) throws IllegalArgumentException {
throw newGetLongIllegalArgumentException();
}
public float getFloat(Object obj) throws IllegalArgumentException {
throw newGetFloatIllegalArgumentException();
}
public double getDouble(Object obj) throws IllegalArgumentException {
return unsafe.getDouble(base, fieldOffset);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
if (isFinal) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Byte) {
unsafe.putDouble(base, fieldOffset, ((Byte) value).byteValue());
return;
}
if (value instanceof Short) {
unsafe.putDouble(base, fieldOffset, ((Short) value).shortValue());
return;
}
if (value instanceof Character) {
unsafe.putDouble(base, fieldOffset, ((Character) value).charValue());
return;
}
if (value instanceof Integer) {
unsafe.putDouble(base, fieldOffset, ((Integer) value).intValue());
return;
}
if (value instanceof Long) {
unsafe.putDouble(base, fieldOffset, ((Long) value).longValue());
return;
}
if (value instanceof Float) {
unsafe.putDouble(base, fieldOffset, ((Float) value).floatValue());
return;
}
if (value instanceof Double) {
unsafe.putDouble(base, fieldOffset, ((Double) value).doubleValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
setDouble(obj, b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
setDouble(obj, c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
setDouble(obj, s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
setDouble(obj, i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
setDouble(obj, l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
setDouble(obj, f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
if (isFinal) {
throwFinalFieldIllegalAccessException(d);
}
unsafe.putDouble(base, fieldOffset, d);
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.security.AccessController;
import sun.misc.Unsafe;
/** Base class for sun.misc.Unsafe-based FieldAccessors for static
fields. The observation is that there are only nine types of
fields from the standpoint of reflection code: the eight primitive
types and Object. Using class Unsafe instead of generated
bytecodes saves memory and loading time for the
dynamically-generated FieldAccessors. */
abstract class UnsafeStaticFieldAccessorImpl extends UnsafeFieldAccessorImpl {
static {
Reflection.registerFieldsToFilter(UnsafeStaticFieldAccessorImpl.class,
new String[] { "base" });
}
protected final Object base; // base
UnsafeStaticFieldAccessorImpl(Field field) {
super(field);
base = unsafe.staticFieldBase(field);
}
}

View File

@@ -0,0 +1,157 @@
/*
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeStaticFloatFieldAccessorImpl extends UnsafeStaticFieldAccessorImpl {
UnsafeStaticFloatFieldAccessorImpl(Field field) {
super(field);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Float(getFloat(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
throw newGetIntIllegalArgumentException();
}
public long getLong(Object obj) throws IllegalArgumentException {
throw newGetLongIllegalArgumentException();
}
public float getFloat(Object obj) throws IllegalArgumentException {
return unsafe.getFloat(base, fieldOffset);
}
public double getDouble(Object obj) throws IllegalArgumentException {
return getFloat(obj);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
if (isFinal) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Byte) {
unsafe.putFloat(base, fieldOffset, ((Byte) value).byteValue());
return;
}
if (value instanceof Short) {
unsafe.putFloat(base, fieldOffset, ((Short) value).shortValue());
return;
}
if (value instanceof Character) {
unsafe.putFloat(base, fieldOffset, ((Character) value).charValue());
return;
}
if (value instanceof Integer) {
unsafe.putFloat(base, fieldOffset, ((Integer) value).intValue());
return;
}
if (value instanceof Long) {
unsafe.putFloat(base, fieldOffset, ((Long) value).longValue());
return;
}
if (value instanceof Float) {
unsafe.putFloat(base, fieldOffset, ((Float) value).floatValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
setFloat(obj, b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
setFloat(obj, c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
setFloat(obj, s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
setFloat(obj, i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
setFloat(obj, l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
if (isFinal) {
throwFinalFieldIllegalAccessException(f);
}
unsafe.putFloat(base, fieldOffset, f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,149 @@
/*
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeStaticIntegerFieldAccessorImpl extends UnsafeStaticFieldAccessorImpl {
UnsafeStaticIntegerFieldAccessorImpl(Field field) {
super(field);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Integer(getInt(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
return unsafe.getInt(base, fieldOffset);
}
public long getLong(Object obj) throws IllegalArgumentException {
return getInt(obj);
}
public float getFloat(Object obj) throws IllegalArgumentException {
return getInt(obj);
}
public double getDouble(Object obj) throws IllegalArgumentException {
return getInt(obj);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
if (isFinal) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Byte) {
unsafe.putInt(base, fieldOffset, ((Byte) value).byteValue());
return;
}
if (value instanceof Short) {
unsafe.putInt(base, fieldOffset, ((Short) value).shortValue());
return;
}
if (value instanceof Character) {
unsafe.putInt(base, fieldOffset, ((Character) value).charValue());
return;
}
if (value instanceof Integer) {
unsafe.putInt(base, fieldOffset, ((Integer) value).intValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
setInt(obj, b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
setInt(obj, c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
setInt(obj, s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
if (isFinal) {
throwFinalFieldIllegalAccessException(i);
}
unsafe.putInt(base, fieldOffset, i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,153 @@
/*
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeStaticLongFieldAccessorImpl extends UnsafeStaticFieldAccessorImpl {
UnsafeStaticLongFieldAccessorImpl(Field field) {
super(field);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Long(getLong(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
throw newGetIntIllegalArgumentException();
}
public long getLong(Object obj) throws IllegalArgumentException {
return unsafe.getLong(base, fieldOffset);
}
public float getFloat(Object obj) throws IllegalArgumentException {
return getLong(obj);
}
public double getDouble(Object obj) throws IllegalArgumentException {
return getLong(obj);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
if (isFinal) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Byte) {
unsafe.putLong(base, fieldOffset, ((Byte) value).byteValue());
return;
}
if (value instanceof Short) {
unsafe.putLong(base, fieldOffset, ((Short) value).shortValue());
return;
}
if (value instanceof Character) {
unsafe.putLong(base, fieldOffset, ((Character) value).charValue());
return;
}
if (value instanceof Integer) {
unsafe.putLong(base, fieldOffset, ((Integer) value).intValue());
return;
}
if (value instanceof Long) {
unsafe.putLong(base, fieldOffset, ((Long) value).longValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
setLong(obj, b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
setLong(obj, c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
setLong(obj, s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
setLong(obj, i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
if (isFinal) {
throwFinalFieldIllegalAccessException(l);
}
unsafe.putLong(base, fieldOffset, l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,132 @@
/*
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeStaticObjectFieldAccessorImpl extends UnsafeStaticFieldAccessorImpl {
UnsafeStaticObjectFieldAccessorImpl(Field field) {
super(field);
}
public Object get(Object obj) throws IllegalArgumentException {
return unsafe.getObject(base, fieldOffset);
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
throw newGetShortIllegalArgumentException();
}
public int getInt(Object obj) throws IllegalArgumentException {
throw newGetIntIllegalArgumentException();
}
public long getLong(Object obj) throws IllegalArgumentException {
throw newGetLongIllegalArgumentException();
}
public float getFloat(Object obj) throws IllegalArgumentException {
throw newGetFloatIllegalArgumentException();
}
public double getDouble(Object obj) throws IllegalArgumentException {
throw newGetDoubleIllegalArgumentException();
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
if (isFinal) {
throwFinalFieldIllegalAccessException(value);
}
if (value != null) {
if (!field.getType().isAssignableFrom(value.getClass())) {
throwSetIllegalArgumentException(value);
}
}
unsafe.putObject(base, fieldOffset, value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,141 @@
/*
* Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect;
import java.lang.reflect.Field;
class UnsafeStaticShortFieldAccessorImpl extends UnsafeStaticFieldAccessorImpl {
UnsafeStaticShortFieldAccessorImpl(Field field) {
super(field);
}
public Object get(Object obj) throws IllegalArgumentException {
return new Short(getShort(obj));
}
public boolean getBoolean(Object obj) throws IllegalArgumentException {
throw newGetBooleanIllegalArgumentException();
}
public byte getByte(Object obj) throws IllegalArgumentException {
throw newGetByteIllegalArgumentException();
}
public char getChar(Object obj) throws IllegalArgumentException {
throw newGetCharIllegalArgumentException();
}
public short getShort(Object obj) throws IllegalArgumentException {
return unsafe.getShort(base, fieldOffset);
}
public int getInt(Object obj) throws IllegalArgumentException {
return getShort(obj);
}
public long getLong(Object obj) throws IllegalArgumentException {
return getShort(obj);
}
public float getFloat(Object obj) throws IllegalArgumentException {
return getShort(obj);
}
public double getDouble(Object obj) throws IllegalArgumentException {
return getShort(obj);
}
public void set(Object obj, Object value)
throws IllegalArgumentException, IllegalAccessException
{
if (isFinal) {
throwFinalFieldIllegalAccessException(value);
}
if (value == null) {
throwSetIllegalArgumentException(value);
}
if (value instanceof Byte) {
unsafe.putShort(base, fieldOffset, ((Byte) value).byteValue());
return;
}
if (value instanceof Short) {
unsafe.putShort(base, fieldOffset, ((Short) value).shortValue());
return;
}
throwSetIllegalArgumentException(value);
}
public void setBoolean(Object obj, boolean z)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(z);
}
public void setByte(Object obj, byte b)
throws IllegalArgumentException, IllegalAccessException
{
setShort(obj, b);
}
public void setChar(Object obj, char c)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(c);
}
public void setShort(Object obj, short s)
throws IllegalArgumentException, IllegalAccessException
{
if (isFinal) {
throwFinalFieldIllegalAccessException(s);
}
unsafe.putShort(base, fieldOffset, s);
}
public void setInt(Object obj, int i)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(i);
}
public void setLong(Object obj, long l)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(l);
}
public void setFloat(Object obj, float f)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(f);
}
public void setDouble(Object obj, double d)
throws IllegalArgumentException, IllegalAccessException
{
throwSetIllegalArgumentException(d);
}
}

View File

@@ -0,0 +1,319 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.annotation;
import java.lang.annotation.*;
import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import static sun.reflect.annotation.TypeAnnotation.*;
public final class AnnotatedTypeFactory {
/**
* Create an AnnotatedType.
*
* @param type the type this AnnotatedType corresponds to
* @param currentLoc the location this AnnotatedType corresponds to
* @param actualTypeAnnos the type annotations this AnnotatedType has
* @param allOnSameTarget all type annotation on the same TypeAnnotationTarget
* as the AnnotatedType being built
* @param decl the declaration having the type use this AnnotatedType
* corresponds to
*/
public static AnnotatedType buildAnnotatedType(Type type,
LocationInfo currentLoc,
TypeAnnotation[] actualTypeAnnos,
TypeAnnotation[] allOnSameTarget,
AnnotatedElement decl) {
if (type == null) {
return EMPTY_ANNOTATED_TYPE;
}
if (isArray(type))
return new AnnotatedArrayTypeImpl(type,
currentLoc,
actualTypeAnnos,
allOnSameTarget,
decl);
if (type instanceof Class) {
return new AnnotatedTypeBaseImpl(type,
addNesting(type, currentLoc),
actualTypeAnnos,
allOnSameTarget,
decl);
} else if (type instanceof TypeVariable) {
return new AnnotatedTypeVariableImpl((TypeVariable)type,
currentLoc,
actualTypeAnnos,
allOnSameTarget,
decl);
} else if (type instanceof ParameterizedType) {
return new AnnotatedParameterizedTypeImpl((ParameterizedType)type,
addNesting(type, currentLoc),
actualTypeAnnos,
allOnSameTarget,
decl);
} else if (type instanceof WildcardType) {
return new AnnotatedWildcardTypeImpl((WildcardType) type,
currentLoc,
actualTypeAnnos,
allOnSameTarget,
decl);
}
throw new AssertionError("Unknown instance of Type: " + type + "\nThis should not happen.");
}
private static LocationInfo addNesting(Type type, LocationInfo addTo) {
if (isArray(type))
return addTo;
if (type instanceof Class) {
Class<?> clz = (Class)type;
if (clz.getEnclosingClass() == null)
return addTo;
if (Modifier.isStatic(clz.getModifiers()))
return addNesting(clz.getEnclosingClass(), addTo);
return addNesting(clz.getEnclosingClass(), addTo.pushInner());
} else if (type instanceof ParameterizedType) {
ParameterizedType t = (ParameterizedType)type;
if (t.getOwnerType() == null)
return addTo;
return addNesting(t.getOwnerType(), addTo.pushInner());
}
return addTo;
}
private static boolean isArray(Type t) {
if (t instanceof Class) {
Class<?> c = (Class)t;
if (c.isArray())
return true;
} else if (t instanceof GenericArrayType) {
return true;
}
return false;
}
static final AnnotatedType EMPTY_ANNOTATED_TYPE = new AnnotatedTypeBaseImpl(null, LocationInfo.BASE_LOCATION,
new TypeAnnotation[0], new TypeAnnotation[0], null);
static final AnnotatedType[] EMPTY_ANNOTATED_TYPE_ARRAY = new AnnotatedType[0];
private static class AnnotatedTypeBaseImpl implements AnnotatedType {
private final Type type;
private final AnnotatedElement decl;
private final LocationInfo location;
private final TypeAnnotation[] allOnSameTargetTypeAnnotations;
private final Map<Class <? extends Annotation>, Annotation> annotations;
AnnotatedTypeBaseImpl(Type type, LocationInfo location,
TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
AnnotatedElement decl) {
this.type = type;
this.decl = decl;
this.location = location;
this.allOnSameTargetTypeAnnotations = allOnSameTargetTypeAnnotations;
this.annotations = TypeAnnotationParser.mapTypeAnnotations(location.filter(actualTypeAnnotations));
}
// AnnotatedElement
@Override
public final Annotation[] getAnnotations() {
return getDeclaredAnnotations();
}
@Override
public final <T extends Annotation> T getAnnotation(Class<T> annotation) {
return getDeclaredAnnotation(annotation);
}
@Override
public final <T extends Annotation> T[] getAnnotationsByType(Class<T> annotation) {
return getDeclaredAnnotationsByType(annotation);
}
@Override
public final Annotation[] getDeclaredAnnotations() {
return annotations.values().toArray(new Annotation[0]);
}
@Override
@SuppressWarnings("unchecked")
public final <T extends Annotation> T getDeclaredAnnotation(Class<T> annotation) {
return (T)annotations.get(annotation);
}
@Override
public final <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotation) {
return AnnotationSupport.getDirectlyAndIndirectlyPresent(annotations, annotation);
}
// AnnotatedType
@Override
public final Type getType() {
return type;
}
// Implementation details
final LocationInfo getLocation() {
return location;
}
final TypeAnnotation[] getTypeAnnotations() {
return allOnSameTargetTypeAnnotations;
}
final AnnotatedElement getDecl() {
return decl;
}
}
private static final class AnnotatedArrayTypeImpl extends AnnotatedTypeBaseImpl implements AnnotatedArrayType {
AnnotatedArrayTypeImpl(Type type, LocationInfo location,
TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
AnnotatedElement decl) {
super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl);
}
@Override
public AnnotatedType getAnnotatedGenericComponentType() {
return AnnotatedTypeFactory.buildAnnotatedType(getComponentType(),
getLocation().pushArray(),
getTypeAnnotations(),
getTypeAnnotations(),
getDecl());
}
private Type getComponentType() {
Type t = getType();
if (t instanceof Class) {
Class<?> c = (Class)t;
return c.getComponentType();
}
return ((GenericArrayType)t).getGenericComponentType();
}
}
private static final class AnnotatedTypeVariableImpl extends AnnotatedTypeBaseImpl implements AnnotatedTypeVariable {
AnnotatedTypeVariableImpl(TypeVariable<?> type, LocationInfo location,
TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
AnnotatedElement decl) {
super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl);
}
@Override
public AnnotatedType[] getAnnotatedBounds() {
return getTypeVariable().getAnnotatedBounds();
}
private TypeVariable<?> getTypeVariable() {
return (TypeVariable)getType();
}
}
private static final class AnnotatedParameterizedTypeImpl extends AnnotatedTypeBaseImpl
implements AnnotatedParameterizedType {
AnnotatedParameterizedTypeImpl(ParameterizedType type, LocationInfo location,
TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
AnnotatedElement decl) {
super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl);
}
@Override
public AnnotatedType[] getAnnotatedActualTypeArguments() {
Type[] arguments = getParameterizedType().getActualTypeArguments();
AnnotatedType[] res = new AnnotatedType[arguments.length];
Arrays.fill(res, EMPTY_ANNOTATED_TYPE);
int initialCapacity = getTypeAnnotations().length;
for (int i = 0; i < res.length; i++) {
List<TypeAnnotation> l = new ArrayList<>(initialCapacity);
LocationInfo newLoc = getLocation().pushTypeArg((byte)i);
for (TypeAnnotation t : getTypeAnnotations())
if (t.getLocationInfo().isSameLocationInfo(newLoc))
l.add(t);
res[i] = buildAnnotatedType(arguments[i],
newLoc,
l.toArray(new TypeAnnotation[0]),
getTypeAnnotations(),
getDecl());
}
return res;
}
private ParameterizedType getParameterizedType() {
return (ParameterizedType)getType();
}
}
private static final class AnnotatedWildcardTypeImpl extends AnnotatedTypeBaseImpl implements AnnotatedWildcardType {
private final boolean hasUpperBounds;
AnnotatedWildcardTypeImpl(WildcardType type, LocationInfo location,
TypeAnnotation[] actualTypeAnnotations, TypeAnnotation[] allOnSameTargetTypeAnnotations,
AnnotatedElement decl) {
super(type, location, actualTypeAnnotations, allOnSameTargetTypeAnnotations, decl);
hasUpperBounds = (type.getLowerBounds().length == 0);
}
@Override
public AnnotatedType[] getAnnotatedUpperBounds() {
if (!hasUpperBounds())
return new AnnotatedType[0];
return getAnnotatedBounds(getWildcardType().getUpperBounds());
}
@Override
public AnnotatedType[] getAnnotatedLowerBounds() {
if (hasUpperBounds)
return new AnnotatedType[0];
return getAnnotatedBounds(getWildcardType().getLowerBounds());
}
private AnnotatedType[] getAnnotatedBounds(Type[] bounds) {
AnnotatedType[] res = new AnnotatedType[bounds.length];
Arrays.fill(res, EMPTY_ANNOTATED_TYPE);
LocationInfo newLoc = getLocation().pushWildcard();
int initialCapacity = getTypeAnnotations().length;
for (int i = 0; i < res.length; i++) {
List<TypeAnnotation> l = new ArrayList<>(initialCapacity);
for (TypeAnnotation t : getTypeAnnotations())
if (t.getLocationInfo().isSameLocationInfo(newLoc))
l.add(t);
res[i] = buildAnnotatedType(bounds[i],
newLoc,
l.toArray(new TypeAnnotation[0]),
getTypeAnnotations(),
getDecl());
}
return res;
}
private WildcardType getWildcardType() {
return (WildcardType)getType();
}
private boolean hasUpperBounds() {
return hasUpperBounds;
}
}
}

View File

@@ -0,0 +1,506 @@
/*
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.annotation;
import java.io.ObjectInputStream;
import java.lang.annotation.*;
import java.lang.reflect.*;
import java.io.Serializable;
import java.util.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
/**
* InvocationHandler for dynamic proxy implementation of Annotation.
*
* @author Josh Bloch
* @since 1.5
*/
class AnnotationInvocationHandler implements InvocationHandler, Serializable {
private static final long serialVersionUID = 6182022883658399397L;
private final Class<? extends Annotation> type;
private final Map<String, Object> memberValues;
AnnotationInvocationHandler(Class<? extends Annotation> type, Map<String, Object> memberValues) {
Class<?>[] superInterfaces = type.getInterfaces();
if (!type.isAnnotation() ||
superInterfaces.length != 1 ||
superInterfaces[0] != java.lang.annotation.Annotation.class)
throw new AnnotationFormatError("Attempt to create proxy for a non-annotation type.");
this.type = type;
this.memberValues = memberValues;
}
public Object invoke(Object proxy, Method method, Object[] args) {
String member = method.getName();
Class<?>[] paramTypes = method.getParameterTypes();
// Handle Object and Annotation methods
if (member.equals("equals") && paramTypes.length == 1 &&
paramTypes[0] == Object.class)
return equalsImpl(args[0]);
if (paramTypes.length != 0)
throw new AssertionError("Too many parameters for an annotation method");
switch(member) {
case "toString":
return toStringImpl();
case "hashCode":
return hashCodeImpl();
case "annotationType":
return type;
}
// Handle annotation member accessors
Object result = memberValues.get(member);
if (result == null)
throw new IncompleteAnnotationException(type, member);
if (result instanceof ExceptionProxy)
throw ((ExceptionProxy) result).generateException();
if (result.getClass().isArray() && Array.getLength(result) != 0)
result = cloneArray(result);
return result;
}
/**
* This method, which clones its array argument, would not be necessary
* if Cloneable had a public clone method.
*/
private Object cloneArray(Object array) {
Class<?> type = array.getClass();
if (type == byte[].class) {
byte[] byteArray = (byte[])array;
return byteArray.clone();
}
if (type == char[].class) {
char[] charArray = (char[])array;
return charArray.clone();
}
if (type == double[].class) {
double[] doubleArray = (double[])array;
return doubleArray.clone();
}
if (type == float[].class) {
float[] floatArray = (float[])array;
return floatArray.clone();
}
if (type == int[].class) {
int[] intArray = (int[])array;
return intArray.clone();
}
if (type == long[].class) {
long[] longArray = (long[])array;
return longArray.clone();
}
if (type == short[].class) {
short[] shortArray = (short[])array;
return shortArray.clone();
}
if (type == boolean[].class) {
boolean[] booleanArray = (boolean[])array;
return booleanArray.clone();
}
Object[] objectArray = (Object[])array;
return objectArray.clone();
}
/**
* Implementation of dynamicProxy.toString()
*/
private String toStringImpl() {
StringBuilder result = new StringBuilder(128);
result.append('@');
result.append(type.getName());
result.append('(');
boolean firstMember = true;
for (Map.Entry<String, Object> e : memberValues.entrySet()) {
if (firstMember)
firstMember = false;
else
result.append(", ");
result.append(e.getKey());
result.append('=');
result.append(memberValueToString(e.getValue()));
}
result.append(')');
return result.toString();
}
/**
* Translates a member value (in "dynamic proxy return form") into a string
*/
private static String memberValueToString(Object value) {
Class<?> type = value.getClass();
if (!type.isArray()) // primitive, string, class, enum const,
// or annotation
return value.toString();
if (type == byte[].class)
return Arrays.toString((byte[]) value);
if (type == char[].class)
return Arrays.toString((char[]) value);
if (type == double[].class)
return Arrays.toString((double[]) value);
if (type == float[].class)
return Arrays.toString((float[]) value);
if (type == int[].class)
return Arrays.toString((int[]) value);
if (type == long[].class)
return Arrays.toString((long[]) value);
if (type == short[].class)
return Arrays.toString((short[]) value);
if (type == boolean[].class)
return Arrays.toString((boolean[]) value);
return Arrays.toString((Object[]) value);
}
/**
* Implementation of dynamicProxy.equals(Object o)
*/
private Boolean equalsImpl(Object o) {
if (o == this)
return true;
if (!type.isInstance(o))
return false;
for (Method memberMethod : getMemberMethods()) {
String member = memberMethod.getName();
Object ourValue = memberValues.get(member);
Object hisValue = null;
AnnotationInvocationHandler hisHandler = asOneOfUs(o);
if (hisHandler != null) {
hisValue = hisHandler.memberValues.get(member);
} else {
try {
hisValue = memberMethod.invoke(o);
} catch (InvocationTargetException e) {
return false;
} catch (IllegalAccessException e) {
throw new AssertionError(e);
}
}
if (!memberValueEquals(ourValue, hisValue))
return false;
}
return true;
}
/**
* Returns an object's invocation handler if that object is a dynamic
* proxy with a handler of type AnnotationInvocationHandler.
* Returns null otherwise.
*/
private AnnotationInvocationHandler asOneOfUs(Object o) {
if (Proxy.isProxyClass(o.getClass())) {
InvocationHandler handler = Proxy.getInvocationHandler(o);
if (handler instanceof AnnotationInvocationHandler)
return (AnnotationInvocationHandler) handler;
}
return null;
}
/**
* Returns true iff the two member values in "dynamic proxy return form"
* are equal using the appropriate equality function depending on the
* member type. The two values will be of the same type unless one of
* the containing annotations is ill-formed. If one of the containing
* annotations is ill-formed, this method will return false unless the
* two members are identical object references.
*/
private static boolean memberValueEquals(Object v1, Object v2) {
Class<?> type = v1.getClass();
// Check for primitive, string, class, enum const, annotation,
// or ExceptionProxy
if (!type.isArray())
return v1.equals(v2);
// Check for array of string, class, enum const, annotation,
// or ExceptionProxy
if (v1 instanceof Object[] && v2 instanceof Object[])
return Arrays.equals((Object[]) v1, (Object[]) v2);
// Check for ill formed annotation(s)
if (v2.getClass() != type)
return false;
// Deal with array of primitives
if (type == byte[].class)
return Arrays.equals((byte[]) v1, (byte[]) v2);
if (type == char[].class)
return Arrays.equals((char[]) v1, (char[]) v2);
if (type == double[].class)
return Arrays.equals((double[]) v1, (double[]) v2);
if (type == float[].class)
return Arrays.equals((float[]) v1, (float[]) v2);
if (type == int[].class)
return Arrays.equals((int[]) v1, (int[]) v2);
if (type == long[].class)
return Arrays.equals((long[]) v1, (long[]) v2);
if (type == short[].class)
return Arrays.equals((short[]) v1, (short[]) v2);
assert type == boolean[].class;
return Arrays.equals((boolean[]) v1, (boolean[]) v2);
}
/**
* Returns the member methods for our annotation type. These are
* obtained lazily and cached, as they're expensive to obtain
* and we only need them if our equals method is invoked (which should
* be rare).
*/
private Method[] getMemberMethods() {
if (memberMethods == null) {
memberMethods = AccessController.doPrivileged(
new PrivilegedAction<Method[]>() {
public Method[] run() {
final Method[] mm = type.getDeclaredMethods();
validateAnnotationMethods(mm);
AccessibleObject.setAccessible(mm, true);
return mm;
}
});
}
return memberMethods;
}
private transient volatile Method[] memberMethods = null;
/**
* Validates that a method is structurally appropriate for an
* annotation type. As of Java SE 8, annotation types cannot
* contain static methods and the declared methods of an
* annotation type must take zero arguments and there are
* restrictions on the return type.
*/
private void validateAnnotationMethods(Method[] memberMethods) {
/*
* Specification citations below are from JLS
* 9.6.1. Annotation Type Elements
*/
boolean valid = true;
for(Method method : memberMethods) {
/*
* "By virtue of the AnnotationTypeElementDeclaration
* production, a method declaration in an annotation type
* declaration cannot have formal parameters, type
* parameters, or a throws clause.
*
* "By virtue of the AnnotationTypeElementModifier
* production, a method declaration in an annotation type
* declaration cannot be default or static."
*/
if (method.getModifiers() != (Modifier.PUBLIC | Modifier.ABSTRACT) ||
method.isDefault() ||
method.getParameterCount() != 0 ||
method.getExceptionTypes().length != 0) {
valid = false;
break;
}
/*
* "It is a compile-time error if the return type of a
* method declared in an annotation type is not one of the
* following: a primitive type, String, Class, any
* parameterized invocation of Class, an enum type
* (section 8.9), an annotation type, or an array type
* (chapter 10) whose element type is one of the preceding
* types."
*/
Class<?> returnType = method.getReturnType();
if (returnType.isArray()) {
returnType = returnType.getComponentType();
if (returnType.isArray()) { // Only single dimensional arrays
valid = false;
break;
}
}
if (!((returnType.isPrimitive() && returnType != void.class) ||
returnType == java.lang.String.class ||
returnType == java.lang.Class.class ||
returnType.isEnum() ||
returnType.isAnnotation())) {
valid = false;
break;
}
/*
* "It is a compile-time error if any method declared in an
* annotation type has a signature that is
* override-equivalent to that of any public or protected
* method declared in class Object or in the interface
* java.lang.annotation.Annotation."
*
* The methods in Object or Annotation meeting the other
* criteria (no arguments, contrained return type, etc.)
* above are:
*
* String toString()
* int hashCode()
* Class<? extends Annotation> annotationType()
*/
String methodName = method.getName();
if ((methodName.equals("toString") && returnType == java.lang.String.class) ||
(methodName.equals("hashCode") && returnType == int.class) ||
(methodName.equals("annotationType") && returnType == java.lang.Class.class)) {
valid = false;
break;
}
}
if (valid)
return;
else
throw new AnnotationFormatError("Malformed method on an annotation type");
}
/**
* Implementation of dynamicProxy.hashCode()
*/
private int hashCodeImpl() {
int result = 0;
for (Map.Entry<String, Object> e : memberValues.entrySet()) {
result += (127 * e.getKey().hashCode()) ^
memberValueHashCode(e.getValue());
}
return result;
}
/**
* Computes hashCode of a member value (in "dynamic proxy return form")
*/
private static int memberValueHashCode(Object value) {
Class<?> type = value.getClass();
if (!type.isArray()) // primitive, string, class, enum const,
// or annotation
return value.hashCode();
if (type == byte[].class)
return Arrays.hashCode((byte[]) value);
if (type == char[].class)
return Arrays.hashCode((char[]) value);
if (type == double[].class)
return Arrays.hashCode((double[]) value);
if (type == float[].class)
return Arrays.hashCode((float[]) value);
if (type == int[].class)
return Arrays.hashCode((int[]) value);
if (type == long[].class)
return Arrays.hashCode((long[]) value);
if (type == short[].class)
return Arrays.hashCode((short[]) value);
if (type == boolean[].class)
return Arrays.hashCode((boolean[]) value);
return Arrays.hashCode((Object[]) value);
}
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
ObjectInputStream.GetField fields = s.readFields();
@SuppressWarnings("unchecked")
Class<? extends Annotation> t = (Class<? extends Annotation>)fields.get("type", null);
@SuppressWarnings("unchecked")
Map<String, Object> streamVals = (Map<String, Object>)fields.get("memberValues", null);
// Check to make sure that types have not evolved incompatibly
AnnotationType annotationType = null;
try {
annotationType = AnnotationType.getInstance(t);
} catch(IllegalArgumentException e) {
// Class is no longer an annotation type; time to punch out
throw new java.io.InvalidObjectException("Non-annotation type in annotation serial stream");
}
Map<String, Class<?>> memberTypes = annotationType.memberTypes();
// consistent with runtime Map type
Map<String, Object> mv = new LinkedHashMap<>();
// If there are annotation members without values, that
// situation is handled by the invoke method.
for (Map.Entry<String, Object> memberValue : streamVals.entrySet()) {
String name = memberValue.getKey();
Object value = null;
Class<?> memberType = memberTypes.get(name);
if (memberType != null) { // i.e. member still exists
value = memberValue.getValue();
if (!(memberType.isInstance(value) ||
value instanceof ExceptionProxy)) {
value = new AnnotationTypeMismatchExceptionProxy(
objectToString(value))
.setMember(annotationType.members().get(name));
}
}
mv.put(name, value);
}
UnsafeAccessor.setType(this, t);
UnsafeAccessor.setMemberValues(this, mv);
}
/*
* Create a textual representation of the argument without calling
* any overridable methods of the argument.
*/
private static String objectToString(Object value) {
return value.getClass().getName() + "@" +
Integer.toHexString(System.identityHashCode(value));
}
private static class UnsafeAccessor {
private static final sun.misc.Unsafe unsafe;
private static final long typeOffset;
private static final long memberValuesOffset;
static {
try {
unsafe = sun.misc.Unsafe.getUnsafe();
typeOffset = unsafe.objectFieldOffset
(AnnotationInvocationHandler.class.getDeclaredField("type"));
memberValuesOffset = unsafe.objectFieldOffset
(AnnotationInvocationHandler.class.getDeclaredField("memberValues"));
} catch (Exception ex) {
throw new ExceptionInInitializerError(ex);
}
}
static void setType(AnnotationInvocationHandler o,
Class<? extends Annotation> type) {
unsafe.putObject(o, typeOffset, type);
}
static void setMemberValues(AnnotationInvocationHandler o,
Map<String, Object> memberValues) {
unsafe.putObject(o, memberValuesOffset, memberValues);
}
}
}

View File

@@ -0,0 +1,869 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.annotation;
import java.lang.annotation.*;
import java.util.*;
import java.nio.ByteBuffer;
import java.nio.BufferUnderflowException;
import java.lang.reflect.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
import sun.reflect.ConstantPool;
import sun.reflect.generics.parser.SignatureParser;
import sun.reflect.generics.tree.TypeSignature;
import sun.reflect.generics.factory.GenericsFactory;
import sun.reflect.generics.factory.CoreReflectionFactory;
import sun.reflect.generics.visitor.Reifier;
import sun.reflect.generics.scope.ClassScope;
/**
* Parser for Java programming language annotations. Translates
* annotation byte streams emitted by compiler into annotation objects.
*
* @author Josh Bloch
* @since 1.5
*/
public class AnnotationParser {
/**
* Parses the annotations described by the specified byte array.
* resolving constant references in the specified constant pool.
* The array must contain an array of annotations as described
* in the RuntimeVisibleAnnotations_attribute:
*
* u2 num_annotations;
* annotation annotations[num_annotations];
*
* @throws AnnotationFormatError if an annotation is found to be
* malformed.
*/
public static Map<Class<? extends Annotation>, Annotation> parseAnnotations(
byte[] rawAnnotations,
ConstantPool constPool,
Class<?> container) {
if (rawAnnotations == null)
return Collections.emptyMap();
try {
return parseAnnotations2(rawAnnotations, constPool, container, null);
} catch(BufferUnderflowException e) {
throw new AnnotationFormatError("Unexpected end of annotations.");
} catch(IllegalArgumentException e) {
// Type mismatch in constant pool
throw new AnnotationFormatError(e);
}
}
/**
* Like {@link #parseAnnotations(byte[], sun.reflect.ConstantPool, Class)}
* with an additional parameter {@code selectAnnotationClasses} which selects the
* annotation types to parse (other than selected are quickly skipped).<p>
* This method is only used to parse select meta annotations in the construction
* phase of {@link AnnotationType} instances to prevent infinite recursion.
*
* @param selectAnnotationClasses an array of annotation types to select when parsing
*/
@SafeVarargs
@SuppressWarnings("varargs") // selectAnnotationClasses is used safely
static Map<Class<? extends Annotation>, Annotation> parseSelectAnnotations(
byte[] rawAnnotations,
ConstantPool constPool,
Class<?> container,
Class<? extends Annotation> ... selectAnnotationClasses) {
if (rawAnnotations == null)
return Collections.emptyMap();
try {
return parseAnnotations2(rawAnnotations, constPool, container, selectAnnotationClasses);
} catch(BufferUnderflowException e) {
throw new AnnotationFormatError("Unexpected end of annotations.");
} catch(IllegalArgumentException e) {
// Type mismatch in constant pool
throw new AnnotationFormatError(e);
}
}
private static Map<Class<? extends Annotation>, Annotation> parseAnnotations2(
byte[] rawAnnotations,
ConstantPool constPool,
Class<?> container,
Class<? extends Annotation>[] selectAnnotationClasses) {
Map<Class<? extends Annotation>, Annotation> result =
new LinkedHashMap<Class<? extends Annotation>, Annotation>();
ByteBuffer buf = ByteBuffer.wrap(rawAnnotations);
int numAnnotations = buf.getShort() & 0xFFFF;
for (int i = 0; i < numAnnotations; i++) {
Annotation a = parseAnnotation2(buf, constPool, container, false, selectAnnotationClasses);
if (a != null) {
Class<? extends Annotation> klass = a.annotationType();
if (AnnotationType.getInstance(klass).retention() == RetentionPolicy.RUNTIME &&
result.put(klass, a) != null) {
throw new AnnotationFormatError(
"Duplicate annotation for class: "+klass+": " + a);
}
}
}
return result;
}
/**
* Parses the parameter annotations described by the specified byte array.
* resolving constant references in the specified constant pool.
* The array must contain an array of annotations as described
* in the RuntimeVisibleParameterAnnotations_attribute:
*
* u1 num_parameters;
* {
* u2 num_annotations;
* annotation annotations[num_annotations];
* } parameter_annotations[num_parameters];
*
* Unlike parseAnnotations, rawAnnotations must not be null!
* A null value must be handled by the caller. This is so because
* we cannot determine the number of parameters if rawAnnotations
* is null. Also, the caller should check that the number
* of parameters indicated by the return value of this method
* matches the actual number of method parameters. A mismatch
* indicates that an AnnotationFormatError should be thrown.
*
* @throws AnnotationFormatError if an annotation is found to be
* malformed.
*/
public static Annotation[][] parseParameterAnnotations(
byte[] rawAnnotations,
ConstantPool constPool,
Class<?> container) {
try {
return parseParameterAnnotations2(rawAnnotations, constPool, container);
} catch(BufferUnderflowException e) {
throw new AnnotationFormatError(
"Unexpected end of parameter annotations.");
} catch(IllegalArgumentException e) {
// Type mismatch in constant pool
throw new AnnotationFormatError(e);
}
}
private static Annotation[][] parseParameterAnnotations2(
byte[] rawAnnotations,
ConstantPool constPool,
Class<?> container) {
ByteBuffer buf = ByteBuffer.wrap(rawAnnotations);
int numParameters = buf.get() & 0xFF;
Annotation[][] result = new Annotation[numParameters][];
for (int i = 0; i < numParameters; i++) {
int numAnnotations = buf.getShort() & 0xFFFF;
List<Annotation> annotations =
new ArrayList<Annotation>(numAnnotations);
for (int j = 0; j < numAnnotations; j++) {
Annotation a = parseAnnotation(buf, constPool, container, false);
if (a != null) {
AnnotationType type = AnnotationType.getInstance(
a.annotationType());
if (type.retention() == RetentionPolicy.RUNTIME)
annotations.add(a);
}
}
result[i] = annotations.toArray(EMPTY_ANNOTATIONS_ARRAY);
}
return result;
}
private static final Annotation[] EMPTY_ANNOTATIONS_ARRAY =
new Annotation[0];
/**
* Parses the annotation at the current position in the specified
* byte buffer, resolving constant references in the specified constant
* pool. The cursor of the byte buffer must point to an "annotation
* structure" as described in the RuntimeVisibleAnnotations_attribute:
*
* annotation {
* u2 type_index;
* u2 num_member_value_pairs;
* { u2 member_name_index;
* member_value value;
* } member_value_pairs[num_member_value_pairs];
* }
* }
*
* Returns the annotation, or null if the annotation's type cannot
* be found by the VM, or is not a valid annotation type.
*
* @param exceptionOnMissingAnnotationClass if true, throw
* TypeNotPresentException if a referenced annotation type is not
* available at runtime
*/
static Annotation parseAnnotation(ByteBuffer buf,
ConstantPool constPool,
Class<?> container,
boolean exceptionOnMissingAnnotationClass) {
return parseAnnotation2(buf, constPool, container, exceptionOnMissingAnnotationClass, null);
}
@SuppressWarnings("unchecked")
private static Annotation parseAnnotation2(ByteBuffer buf,
ConstantPool constPool,
Class<?> container,
boolean exceptionOnMissingAnnotationClass,
Class<? extends Annotation>[] selectAnnotationClasses) {
int typeIndex = buf.getShort() & 0xFFFF;
Class<? extends Annotation> annotationClass = null;
String sig = "[unknown]";
try {
try {
sig = constPool.getUTF8At(typeIndex);
annotationClass = (Class<? extends Annotation>)parseSig(sig, container);
} catch (IllegalArgumentException ex) {
// support obsolete early jsr175 format class files
annotationClass = (Class<? extends Annotation>)constPool.getClassAt(typeIndex);
}
} catch (NoClassDefFoundError e) {
if (exceptionOnMissingAnnotationClass)
// note: at this point sig is "[unknown]" or VM-style
// name instead of a binary name
throw new TypeNotPresentException(sig, e);
skipAnnotation(buf, false);
return null;
}
catch (TypeNotPresentException e) {
if (exceptionOnMissingAnnotationClass)
throw e;
skipAnnotation(buf, false);
return null;
}
if (selectAnnotationClasses != null && !contains(selectAnnotationClasses, annotationClass)) {
skipAnnotation(buf, false);
return null;
}
AnnotationType type = null;
try {
type = AnnotationType.getInstance(annotationClass);
} catch (IllegalArgumentException e) {
skipAnnotation(buf, false);
return null;
}
Map<String, Class<?>> memberTypes = type.memberTypes();
Map<String, Object> memberValues =
new LinkedHashMap<String, Object>(type.memberDefaults());
int numMembers = buf.getShort() & 0xFFFF;
for (int i = 0; i < numMembers; i++) {
int memberNameIndex = buf.getShort() & 0xFFFF;
String memberName = constPool.getUTF8At(memberNameIndex);
Class<?> memberType = memberTypes.get(memberName);
if (memberType == null) {
// Member is no longer present in annotation type; ignore it
skipMemberValue(buf);
} else {
Object value = parseMemberValue(memberType, buf, constPool, container);
if (value instanceof AnnotationTypeMismatchExceptionProxy)
((AnnotationTypeMismatchExceptionProxy) value).
setMember(type.members().get(memberName));
memberValues.put(memberName, value);
}
}
return annotationForMap(annotationClass, memberValues);
}
/**
* Returns an annotation of the given type backed by the given
* member -> value map.
*/
public static Annotation annotationForMap(final Class<? extends Annotation> type,
final Map<String, Object> memberValues)
{
return AccessController.doPrivileged(new PrivilegedAction<Annotation>() {
public Annotation run() {
return (Annotation) Proxy.newProxyInstance(
type.getClassLoader(), new Class<?>[] { type },
new AnnotationInvocationHandler(type, memberValues));
}});
}
/**
* Parses the annotation member value at the current position in the
* specified byte buffer, resolving constant references in the specified
* constant pool. The cursor of the byte buffer must point to a
* "member_value structure" as described in the
* RuntimeVisibleAnnotations_attribute:
*
* member_value {
* u1 tag;
* union {
* u2 const_value_index;
* {
* u2 type_name_index;
* u2 const_name_index;
* } enum_const_value;
* u2 class_info_index;
* annotation annotation_value;
* {
* u2 num_values;
* member_value values[num_values];
* } array_value;
* } value;
* }
*
* The member must be of the indicated type. If it is not, this
* method returns an AnnotationTypeMismatchExceptionProxy.
*/
@SuppressWarnings("unchecked")
public static Object parseMemberValue(Class<?> memberType,
ByteBuffer buf,
ConstantPool constPool,
Class<?> container) {
Object result = null;
int tag = buf.get();
switch(tag) {
case 'e':
return parseEnumValue((Class<? extends Enum<?>>)memberType, buf, constPool, container);
case 'c':
result = parseClassValue(buf, constPool, container);
break;
case '@':
result = parseAnnotation(buf, constPool, container, true);
break;
case '[':
return parseArray(memberType, buf, constPool, container);
default:
result = parseConst(tag, buf, constPool);
}
if (!(result instanceof ExceptionProxy) &&
!memberType.isInstance(result))
result = new AnnotationTypeMismatchExceptionProxy(
result.getClass() + "[" + result + "]");
return result;
}
/**
* Parses the primitive or String annotation member value indicated by
* the specified tag byte at the current position in the specified byte
* buffer, resolving constant reference in the specified constant pool.
* The cursor of the byte buffer must point to an annotation member value
* of the type indicated by the specified tag, as described in the
* RuntimeVisibleAnnotations_attribute:
*
* u2 const_value_index;
*/
private static Object parseConst(int tag,
ByteBuffer buf, ConstantPool constPool) {
int constIndex = buf.getShort() & 0xFFFF;
switch(tag) {
case 'B':
return Byte.valueOf((byte) constPool.getIntAt(constIndex));
case 'C':
return Character.valueOf((char) constPool.getIntAt(constIndex));
case 'D':
return Double.valueOf(constPool.getDoubleAt(constIndex));
case 'F':
return Float.valueOf(constPool.getFloatAt(constIndex));
case 'I':
return Integer.valueOf(constPool.getIntAt(constIndex));
case 'J':
return Long.valueOf(constPool.getLongAt(constIndex));
case 'S':
return Short.valueOf((short) constPool.getIntAt(constIndex));
case 'Z':
return Boolean.valueOf(constPool.getIntAt(constIndex) != 0);
case 's':
return constPool.getUTF8At(constIndex);
default:
throw new AnnotationFormatError(
"Invalid member-value tag in annotation: " + tag);
}
}
/**
* Parses the Class member value at the current position in the
* specified byte buffer, resolving constant references in the specified
* constant pool. The cursor of the byte buffer must point to a "class
* info index" as described in the RuntimeVisibleAnnotations_attribute:
*
* u2 class_info_index;
*/
private static Object parseClassValue(ByteBuffer buf,
ConstantPool constPool,
Class<?> container) {
int classIndex = buf.getShort() & 0xFFFF;
try {
try {
String sig = constPool.getUTF8At(classIndex);
return parseSig(sig, container);
} catch (IllegalArgumentException ex) {
// support obsolete early jsr175 format class files
return constPool.getClassAt(classIndex);
}
} catch (NoClassDefFoundError e) {
return new TypeNotPresentExceptionProxy("[unknown]", e);
}
catch (TypeNotPresentException e) {
return new TypeNotPresentExceptionProxy(e.typeName(), e.getCause());
}
}
private static Class<?> parseSig(String sig, Class<?> container) {
if (sig.equals("V")) return void.class;
SignatureParser parser = SignatureParser.make();
TypeSignature typeSig = parser.parseTypeSig(sig);
GenericsFactory factory = CoreReflectionFactory.make(container, ClassScope.make(container));
Reifier reify = Reifier.make(factory);
typeSig.accept(reify);
Type result = reify.getResult();
return toClass(result);
}
static Class<?> toClass(Type o) {
if (o instanceof GenericArrayType)
return Array.newInstance(toClass(((GenericArrayType)o).getGenericComponentType()),
0)
.getClass();
return (Class)o;
}
/**
* Parses the enum constant member value at the current position in the
* specified byte buffer, resolving constant references in the specified
* constant pool. The cursor of the byte buffer must point to a
* "enum_const_value structure" as described in the
* RuntimeVisibleAnnotations_attribute:
*
* {
* u2 type_name_index;
* u2 const_name_index;
* } enum_const_value;
*/
@SuppressWarnings({"rawtypes", "unchecked"})
private static Object parseEnumValue(Class<? extends Enum> enumType, ByteBuffer buf,
ConstantPool constPool,
Class<?> container) {
int typeNameIndex = buf.getShort() & 0xFFFF;
String typeName = constPool.getUTF8At(typeNameIndex);
int constNameIndex = buf.getShort() & 0xFFFF;
String constName = constPool.getUTF8At(constNameIndex);
if (!typeName.endsWith(";")) {
// support now-obsolete early jsr175-format class files.
if (!enumType.getName().equals(typeName))
return new AnnotationTypeMismatchExceptionProxy(
typeName + "." + constName);
} else if (enumType != parseSig(typeName, container)) {
return new AnnotationTypeMismatchExceptionProxy(
typeName + "." + constName);
}
try {
return Enum.valueOf(enumType, constName);
} catch(IllegalArgumentException e) {
return new EnumConstantNotPresentExceptionProxy(
(Class<? extends Enum<?>>)enumType, constName);
}
}
/**
* Parses the array value at the current position in the specified byte
* buffer, resolving constant references in the specified constant pool.
* The cursor of the byte buffer must point to an array value struct
* as specified in the RuntimeVisibleAnnotations_attribute:
*
* {
* u2 num_values;
* member_value values[num_values];
* } array_value;
*
* If the array values do not match arrayType, an
* AnnotationTypeMismatchExceptionProxy will be returned.
*/
@SuppressWarnings("unchecked")
private static Object parseArray(Class<?> arrayType,
ByteBuffer buf,
ConstantPool constPool,
Class<?> container) {
int length = buf.getShort() & 0xFFFF; // Number of array components
Class<?> componentType = arrayType.getComponentType();
if (componentType == byte.class) {
return parseByteArray(length, buf, constPool);
} else if (componentType == char.class) {
return parseCharArray(length, buf, constPool);
} else if (componentType == double.class) {
return parseDoubleArray(length, buf, constPool);
} else if (componentType == float.class) {
return parseFloatArray(length, buf, constPool);
} else if (componentType == int.class) {
return parseIntArray(length, buf, constPool);
} else if (componentType == long.class) {
return parseLongArray(length, buf, constPool);
} else if (componentType == short.class) {
return parseShortArray(length, buf, constPool);
} else if (componentType == boolean.class) {
return parseBooleanArray(length, buf, constPool);
} else if (componentType == String.class) {
return parseStringArray(length, buf, constPool);
} else if (componentType == Class.class) {
return parseClassArray(length, buf, constPool, container);
} else if (componentType.isEnum()) {
return parseEnumArray(length, (Class<? extends Enum<?>>)componentType, buf,
constPool, container);
} else {
assert componentType.isAnnotation();
return parseAnnotationArray(length, (Class <? extends Annotation>)componentType, buf,
constPool, container);
}
}
private static Object parseByteArray(int length,
ByteBuffer buf, ConstantPool constPool) {
byte[] result = new byte[length];
boolean typeMismatch = false;
int tag = 0;
for (int i = 0; i < length; i++) {
tag = buf.get();
if (tag == 'B') {
int index = buf.getShort() & 0xFFFF;
result[i] = (byte) constPool.getIntAt(index);
} else {
skipMemberValue(tag, buf);
typeMismatch = true;
}
}
return typeMismatch ? exceptionProxy(tag) : result;
}
private static Object parseCharArray(int length,
ByteBuffer buf, ConstantPool constPool) {
char[] result = new char[length];
boolean typeMismatch = false;
byte tag = 0;
for (int i = 0; i < length; i++) {
tag = buf.get();
if (tag == 'C') {
int index = buf.getShort() & 0xFFFF;
result[i] = (char) constPool.getIntAt(index);
} else {
skipMemberValue(tag, buf);
typeMismatch = true;
}
}
return typeMismatch ? exceptionProxy(tag) : result;
}
private static Object parseDoubleArray(int length,
ByteBuffer buf, ConstantPool constPool) {
double[] result = new double[length];
boolean typeMismatch = false;
int tag = 0;
for (int i = 0; i < length; i++) {
tag = buf.get();
if (tag == 'D') {
int index = buf.getShort() & 0xFFFF;
result[i] = constPool.getDoubleAt(index);
} else {
skipMemberValue(tag, buf);
typeMismatch = true;
}
}
return typeMismatch ? exceptionProxy(tag) : result;
}
private static Object parseFloatArray(int length,
ByteBuffer buf, ConstantPool constPool) {
float[] result = new float[length];
boolean typeMismatch = false;
int tag = 0;
for (int i = 0; i < length; i++) {
tag = buf.get();
if (tag == 'F') {
int index = buf.getShort() & 0xFFFF;
result[i] = constPool.getFloatAt(index);
} else {
skipMemberValue(tag, buf);
typeMismatch = true;
}
}
return typeMismatch ? exceptionProxy(tag) : result;
}
private static Object parseIntArray(int length,
ByteBuffer buf, ConstantPool constPool) {
int[] result = new int[length];
boolean typeMismatch = false;
int tag = 0;
for (int i = 0; i < length; i++) {
tag = buf.get();
if (tag == 'I') {
int index = buf.getShort() & 0xFFFF;
result[i] = constPool.getIntAt(index);
} else {
skipMemberValue(tag, buf);
typeMismatch = true;
}
}
return typeMismatch ? exceptionProxy(tag) : result;
}
private static Object parseLongArray(int length,
ByteBuffer buf, ConstantPool constPool) {
long[] result = new long[length];
boolean typeMismatch = false;
int tag = 0;
for (int i = 0; i < length; i++) {
tag = buf.get();
if (tag == 'J') {
int index = buf.getShort() & 0xFFFF;
result[i] = constPool.getLongAt(index);
} else {
skipMemberValue(tag, buf);
typeMismatch = true;
}
}
return typeMismatch ? exceptionProxy(tag) : result;
}
private static Object parseShortArray(int length,
ByteBuffer buf, ConstantPool constPool) {
short[] result = new short[length];
boolean typeMismatch = false;
int tag = 0;
for (int i = 0; i < length; i++) {
tag = buf.get();
if (tag == 'S') {
int index = buf.getShort() & 0xFFFF;
result[i] = (short) constPool.getIntAt(index);
} else {
skipMemberValue(tag, buf);
typeMismatch = true;
}
}
return typeMismatch ? exceptionProxy(tag) : result;
}
private static Object parseBooleanArray(int length,
ByteBuffer buf, ConstantPool constPool) {
boolean[] result = new boolean[length];
boolean typeMismatch = false;
int tag = 0;
for (int i = 0; i < length; i++) {
tag = buf.get();
if (tag == 'Z') {
int index = buf.getShort() & 0xFFFF;
result[i] = (constPool.getIntAt(index) != 0);
} else {
skipMemberValue(tag, buf);
typeMismatch = true;
}
}
return typeMismatch ? exceptionProxy(tag) : result;
}
private static Object parseStringArray(int length,
ByteBuffer buf, ConstantPool constPool) {
String[] result = new String[length];
boolean typeMismatch = false;
int tag = 0;
for (int i = 0; i < length; i++) {
tag = buf.get();
if (tag == 's') {
int index = buf.getShort() & 0xFFFF;
result[i] = constPool.getUTF8At(index);
} else {
skipMemberValue(tag, buf);
typeMismatch = true;
}
}
return typeMismatch ? exceptionProxy(tag) : result;
}
private static Object parseClassArray(int length,
ByteBuffer buf,
ConstantPool constPool,
Class<?> container) {
Object[] result = new Class<?>[length];
boolean typeMismatch = false;
int tag = 0;
for (int i = 0; i < length; i++) {
tag = buf.get();
if (tag == 'c') {
result[i] = parseClassValue(buf, constPool, container);
} else {
skipMemberValue(tag, buf);
typeMismatch = true;
}
}
return typeMismatch ? exceptionProxy(tag) : result;
}
private static Object parseEnumArray(int length, Class<? extends Enum<?>> enumType,
ByteBuffer buf,
ConstantPool constPool,
Class<?> container) {
Object[] result = (Object[]) Array.newInstance(enumType, length);
boolean typeMismatch = false;
int tag = 0;
for (int i = 0; i < length; i++) {
tag = buf.get();
if (tag == 'e') {
result[i] = parseEnumValue(enumType, buf, constPool, container);
} else {
skipMemberValue(tag, buf);
typeMismatch = true;
}
}
return typeMismatch ? exceptionProxy(tag) : result;
}
private static Object parseAnnotationArray(int length,
Class<? extends Annotation> annotationType,
ByteBuffer buf,
ConstantPool constPool,
Class<?> container) {
Object[] result = (Object[]) Array.newInstance(annotationType, length);
boolean typeMismatch = false;
int tag = 0;
for (int i = 0; i < length; i++) {
tag = buf.get();
if (tag == '@') {
result[i] = parseAnnotation(buf, constPool, container, true);
} else {
skipMemberValue(tag, buf);
typeMismatch = true;
}
}
return typeMismatch ? exceptionProxy(tag) : result;
}
/**
* Return an appropriate exception proxy for a mismatching array
* annotation where the erroneous array has the specified tag.
*/
private static ExceptionProxy exceptionProxy(int tag) {
return new AnnotationTypeMismatchExceptionProxy(
"Array with component tag: " + tag);
}
/**
* Skips the annotation at the current position in the specified
* byte buffer. The cursor of the byte buffer must point to
* an "annotation structure" OR two bytes into an annotation
* structure (i.e., after the type index).
*
* @parameter complete true if the byte buffer points to the beginning
* of an annotation structure (rather than two bytes in).
*/
private static void skipAnnotation(ByteBuffer buf, boolean complete) {
if (complete)
buf.getShort(); // Skip type index
int numMembers = buf.getShort() & 0xFFFF;
for (int i = 0; i < numMembers; i++) {
buf.getShort(); // Skip memberNameIndex
skipMemberValue(buf);
}
}
/**
* Skips the annotation member value at the current position in the
* specified byte buffer. The cursor of the byte buffer must point to a
* "member_value structure."
*/
private static void skipMemberValue(ByteBuffer buf) {
int tag = buf.get();
skipMemberValue(tag, buf);
}
/**
* Skips the annotation member value at the current position in the
* specified byte buffer. The cursor of the byte buffer must point
* immediately after the tag in a "member_value structure."
*/
private static void skipMemberValue(int tag, ByteBuffer buf) {
switch(tag) {
case 'e': // Enum value
buf.getInt(); // (Two shorts, actually.)
break;
case '@':
skipAnnotation(buf, true);
break;
case '[':
skipArray(buf);
break;
default:
// Class, primitive, or String
buf.getShort();
}
}
/**
* Skips the array value at the current position in the specified byte
* buffer. The cursor of the byte buffer must point to an array value
* struct.
*/
private static void skipArray(ByteBuffer buf) {
int length = buf.getShort() & 0xFFFF;
for (int i = 0; i < length; i++)
skipMemberValue(buf);
}
/**
* Searches for given {@code element} in given {@code array} by identity.
* Returns {@code true} if found {@code false} if not.
*/
private static boolean contains(Object[] array, Object element) {
for (Object e : array)
if (e == element)
return true;
return false;
}
/*
* This method converts the annotation map returned by the parseAnnotations()
* method to an array. It is called by Field.getDeclaredAnnotations(),
* Method.getDeclaredAnnotations(), and Constructor.getDeclaredAnnotations().
* This avoids the reflection classes to load the Annotation class until
* it is needed.
*/
private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0];
public static Annotation[] toArray(Map<Class<? extends Annotation>, Annotation> annotations) {
return annotations.values().toArray(EMPTY_ANNOTATION_ARRAY);
}
static Annotation[] getEmptyAnnotationArray() { return EMPTY_ANNOTATION_ARRAY; }
}

View File

@@ -0,0 +1,239 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.annotation;
import java.lang.annotation.*;
import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import sun.misc.JavaLangAccess;
public final class AnnotationSupport {
private static final JavaLangAccess LANG_ACCESS = sun.misc.SharedSecrets.getJavaLangAccess();
/**
* Finds and returns all annotations in {@code annotations} matching
* the given {@code annoClass}.
*
* Apart from annotations directly present in {@code annotations} this
* method searches for annotations inside containers i.e. indirectly
* present annotations.
*
* The order of the elements in the array returned depends on the iteration
* order of the provided map. Specifically, the directly present annotations
* come before the indirectly present annotations if and only if the
* directly present annotations come before the indirectly present
* annotations in the map.
*
* @param annotations the {@code Map} in which to search for annotations
* @param annoClass the type of annotation to search for
*
* @return an array of instances of {@code annoClass} or an empty
* array if none were found
*/
public static <A extends Annotation> A[] getDirectlyAndIndirectlyPresent(
Map<Class<? extends Annotation>, Annotation> annotations,
Class<A> annoClass) {
List<A> result = new ArrayList<A>();
@SuppressWarnings("unchecked")
A direct = (A) annotations.get(annoClass);
if (direct != null)
result.add(direct);
A[] indirect = getIndirectlyPresent(annotations, annoClass);
if (indirect != null && indirect.length != 0) {
boolean indirectFirst = direct == null ||
containerBeforeContainee(annotations, annoClass);
result.addAll((indirectFirst ? 0 : 1), Arrays.asList(indirect));
}
@SuppressWarnings("unchecked")
A[] arr = (A[]) Array.newInstance(annoClass, result.size());
return result.toArray(arr);
}
/**
* Finds and returns all annotations matching the given {@code annoClass}
* indirectly present in {@code annotations}.
*
* @param annotations annotations to search indexed by their types
* @param annoClass the type of annotation to search for
*
* @return an array of instances of {@code annoClass} or an empty array if no
* indirectly present annotations were found
*/
private static <A extends Annotation> A[] getIndirectlyPresent(
Map<Class<? extends Annotation>, Annotation> annotations,
Class<A> annoClass) {
Repeatable repeatable = annoClass.getDeclaredAnnotation(Repeatable.class);
if (repeatable == null)
return null; // Not repeatable -> no indirectly present annotations
Class<? extends Annotation> containerClass = repeatable.value();
Annotation container = annotations.get(containerClass);
if (container == null)
return null;
// Unpack container
A[] valueArray = getValueArray(container);
checkTypes(valueArray, container, annoClass);
return valueArray;
}
/**
* Figures out if conatiner class comes before containee class among the
* keys of the given map.
*
* @return true if container class is found before containee class when
* iterating over annotations.keySet().
*/
private static <A extends Annotation> boolean containerBeforeContainee(
Map<Class<? extends Annotation>, Annotation> annotations,
Class<A> annoClass) {
Class<? extends Annotation> containerClass =
annoClass.getDeclaredAnnotation(Repeatable.class).value();
for (Class<? extends Annotation> c : annotations.keySet()) {
if (c == containerClass) return true;
if (c == annoClass) return false;
}
// Neither containee nor container present
return false;
}
/**
* Finds and returns all associated annotations matching the given class.
*
* The order of the elements in the array returned depends on the iteration
* order of the provided maps. Specifically, the directly present annotations
* come before the indirectly present annotations if and only if the
* directly present annotations come before the indirectly present
* annotations in the relevant map.
*
* @param declaredAnnotations the declared annotations indexed by their types
* @param decl the class declaration on which to search for annotations
* @param annoClass the type of annotation to search for
*
* @return an array of instances of {@code annoClass} or an empty array if none were found.
*/
public static <A extends Annotation> A[] getAssociatedAnnotations(
Map<Class<? extends Annotation>, Annotation> declaredAnnotations,
Class<?> decl,
Class<A> annoClass) {
Objects.requireNonNull(decl);
// Search declared
A[] result = getDirectlyAndIndirectlyPresent(declaredAnnotations, annoClass);
// Search inherited
if(AnnotationType.getInstance(annoClass).isInherited()) {
Class<?> superDecl = decl.getSuperclass();
while (result.length == 0 && superDecl != null) {
result = getDirectlyAndIndirectlyPresent(LANG_ACCESS.getDeclaredAnnotationMap(superDecl), annoClass);
superDecl = superDecl.getSuperclass();
}
}
return result;
}
/* Reflectively invoke the values-method of the given annotation
* (container), cast it to an array of annotations and return the result.
*/
private static <A extends Annotation> A[] getValueArray(Annotation container) {
try {
// According to JLS the container must have an array-valued value
// method. Get the AnnotationType, get the "value" method and invoke
// it to get the content.
Class<? extends Annotation> containerClass = container.annotationType();
AnnotationType annoType = AnnotationType.getInstance(containerClass);
if (annoType == null)
throw invalidContainerException(container, null);
Method m = annoType.members().get("value");
if (m == null)
throw invalidContainerException(container, null);
m.setAccessible(true);
// This will erase to (Annotation[]) but we do a runtime cast on the
// return-value in the method that call this method.
@SuppressWarnings("unchecked")
A[] values = (A[]) m.invoke(container);
return values;
} catch (IllegalAccessException | // couldn't loosen security
IllegalArgumentException | // parameters doesn't match
InvocationTargetException | // the value method threw an exception
ClassCastException e) {
throw invalidContainerException(container, e);
}
}
private static AnnotationFormatError invalidContainerException(Annotation anno,
Throwable cause) {
return new AnnotationFormatError(
anno + " is an invalid container for repeating annotations",
cause);
}
/* Sanity check type of all the annotation instances of type {@code annoClass}
* from {@code container}.
*/
private static <A extends Annotation> void checkTypes(A[] annotations,
Annotation container,
Class<A> annoClass) {
for (A a : annotations) {
if (!annoClass.isInstance(a)) {
throw new AnnotationFormatError(
String.format("%s is an invalid container for " +
"repeating annotations of type: %s",
container, annoClass));
}
}
}
}

View File

@@ -0,0 +1,238 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.annotation;
import sun.misc.JavaLangAccess;
import java.lang.annotation.*;
import java.lang.reflect.*;
import java.util.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
/**
* Represents an annotation type at run time. Used to type-check annotations
* and apply member defaults.
*
* @author Josh Bloch
* @since 1.5
*/
public class AnnotationType {
/**
* Member name -> type mapping. Note that primitive types
* are represented by the class objects for the corresponding wrapper
* types. This matches the return value that must be used for a
* dynamic proxy, allowing for a simple isInstance test.
*/
private final Map<String, Class<?>> memberTypes;
/**
* Member name -> default value mapping.
*/
private final Map<String, Object> memberDefaults;
/**
* Member name -> Method object mapping. This (and its assoicated
* accessor) are used only to generate AnnotationTypeMismatchExceptions.
*/
private final Map<String, Method> members;
/**
* The retention policy for this annotation type.
*/
private final RetentionPolicy retention;
/**
* Whether this annotation type is inherited.
*/
private final boolean inherited;
/**
* Returns an AnnotationType instance for the specified annotation type.
*
* @throw IllegalArgumentException if the specified class object for
* does not represent a valid annotation type
*/
public static AnnotationType getInstance(
Class<? extends Annotation> annotationClass)
{
JavaLangAccess jla = sun.misc.SharedSecrets.getJavaLangAccess();
AnnotationType result = jla.getAnnotationType(annotationClass); // volatile read
if (result == null) {
result = new AnnotationType(annotationClass);
// try to CAS the AnnotationType: null -> result
if (!jla.casAnnotationType(annotationClass, null, result)) {
// somebody was quicker -> read it's result
result = jla.getAnnotationType(annotationClass);
assert result != null;
}
}
return result;
}
/**
* Sole constructor.
*
* @param annotationClass the class object for the annotation type
* @throw IllegalArgumentException if the specified class object for
* does not represent a valid annotation type
*/
private AnnotationType(final Class<? extends Annotation> annotationClass) {
if (!annotationClass.isAnnotation())
throw new IllegalArgumentException("Not an annotation type");
Method[] methods =
AccessController.doPrivileged(new PrivilegedAction<Method[]>() {
public Method[] run() {
// Initialize memberTypes and defaultValues
return annotationClass.getDeclaredMethods();
}
});
memberTypes = new HashMap<String,Class<?>>(methods.length+1, 1.0f);
memberDefaults = new HashMap<String, Object>(0);
members = new HashMap<String, Method>(methods.length+1, 1.0f);
for (Method method : methods) {
if (Modifier.isPublic(method.getModifiers()) &&
Modifier.isAbstract(method.getModifiers()) &&
!method.isSynthetic()) {
if (method.getParameterTypes().length != 0) {
throw new IllegalArgumentException(method + " has params");
}
String name = method.getName();
Class<?> type = method.getReturnType();
memberTypes.put(name, invocationHandlerReturnType(type));
members.put(name, method);
Object defaultValue = method.getDefaultValue();
if (defaultValue != null) {
memberDefaults.put(name, defaultValue);
}
}
}
// Initialize retention, & inherited fields. Special treatment
// of the corresponding annotation types breaks infinite recursion.
if (annotationClass != Retention.class &&
annotationClass != Inherited.class) {
JavaLangAccess jla = sun.misc.SharedSecrets.getJavaLangAccess();
Map<Class<? extends Annotation>, Annotation> metaAnnotations =
AnnotationParser.parseSelectAnnotations(
jla.getRawClassAnnotations(annotationClass),
jla.getConstantPool(annotationClass),
annotationClass,
Retention.class, Inherited.class
);
Retention ret = (Retention) metaAnnotations.get(Retention.class);
retention = (ret == null ? RetentionPolicy.CLASS : ret.value());
inherited = metaAnnotations.containsKey(Inherited.class);
}
else {
retention = RetentionPolicy.RUNTIME;
inherited = false;
}
}
/**
* Returns the type that must be returned by the invocation handler
* of a dynamic proxy in order to have the dynamic proxy return
* the specified type (which is assumed to be a legal member type
* for an annotation).
*/
public static Class<?> invocationHandlerReturnType(Class<?> type) {
// Translate primitives to wrappers
if (type == byte.class)
return Byte.class;
if (type == char.class)
return Character.class;
if (type == double.class)
return Double.class;
if (type == float.class)
return Float.class;
if (type == int.class)
return Integer.class;
if (type == long.class)
return Long.class;
if (type == short.class)
return Short.class;
if (type == boolean.class)
return Boolean.class;
// Otherwise, just return declared type
return type;
}
/**
* Returns member types for this annotation type
* (member name -> type mapping).
*/
public Map<String, Class<?>> memberTypes() {
return memberTypes;
}
/**
* Returns members of this annotation type
* (member name -> associated Method object mapping).
*/
public Map<String, Method> members() {
return members;
}
/**
* Returns the default values for this annotation type
* (Member name -> default value mapping).
*/
public Map<String, Object> memberDefaults() {
return memberDefaults;
}
/**
* Returns the retention policy for this annotation type.
*/
public RetentionPolicy retention() {
return retention;
}
/**
* Returns true if this this annotation type is inherited.
*/
public boolean isInherited() {
return inherited;
}
/**
* For debugging.
*/
public String toString() {
return "Annotation Type:\n" +
" Member types: " + memberTypes + "\n" +
" Member defaults: " + memberDefaults + "\n" +
" Retention policy: " + retention + "\n" +
" Inherited: " + inherited;
}
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.annotation;
import java.lang.annotation.*;
import java.lang.reflect.Method;
/**
* ExceptionProxy for AnnotationTypeMismatchException.
*
* @author Josh Bloch
* @since 1.5
*/
class AnnotationTypeMismatchExceptionProxy extends ExceptionProxy {
private static final long serialVersionUID = 7844069490309503934L;
private Method member;
private String foundType;
/**
* It turns out to be convenient to construct these proxies in
* two stages. Since this is a private implementation class, we
* permit ourselves this liberty even though it's normally a very
* bad idea.
*/
AnnotationTypeMismatchExceptionProxy(String foundType) {
this.foundType = foundType;
}
AnnotationTypeMismatchExceptionProxy setMember(Method member) {
this.member = member;
return this;
}
protected RuntimeException generateException() {
return new AnnotationTypeMismatchException(member, foundType);
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.annotation;
/**
* ExceptionProxy for EnumConstantNotPresentException.
*
* @author Josh Bloch
* @since 1.5
*/
public class EnumConstantNotPresentExceptionProxy extends ExceptionProxy {
private static final long serialVersionUID = -604662101303187330L;
Class<? extends Enum<?>> enumType;
String constName;
public EnumConstantNotPresentExceptionProxy(Class<? extends Enum<?>> enumType,
String constName) {
this.enumType = enumType;
this.constName = constName;
}
protected RuntimeException generateException() {
return new EnumConstantNotPresentException(enumType, constName);
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.annotation;
/**
* An instance of this class is stored in an AnnotationInvocationHandler's
* "memberValues" map in lieu of a value for an annotation member that
* cannot be returned due to some exceptional condition (typically some
* form of illegal evolution of the annotation class). The ExceptionProxy
* instance describes the exception that the dynamic proxy should throw if
* it is queried for this member.
*
* @author Josh Bloch
* @since 1.5
*/
public abstract class ExceptionProxy implements java.io.Serializable {
protected abstract RuntimeException generateException();
}

View File

@@ -0,0 +1,229 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.annotation;
import java.lang.annotation.Annotation;
import java.lang.annotation.AnnotationFormatError;
import java.lang.reflect.AnnotatedElement;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
/**
* A TypeAnnotation contains all the information needed to transform type
* annotations on declarations in the class file to actual Annotations in
* AnnotatedType instances.
*
* TypeAnnotaions contain a base Annotation, location info (which lets you
* distinguish between '@A Inner.@B Outer' in for example nested types),
* target info and the declaration the TypeAnnotaiton was parsed from.
*/
public final class TypeAnnotation {
private final TypeAnnotationTargetInfo targetInfo;
private final LocationInfo loc;
private final Annotation annotation;
private final AnnotatedElement baseDeclaration;
public TypeAnnotation(TypeAnnotationTargetInfo targetInfo,
LocationInfo loc,
Annotation annotation,
AnnotatedElement baseDeclaration) {
this.targetInfo = targetInfo;
this.loc = loc;
this.annotation = annotation;
this.baseDeclaration = baseDeclaration;
}
public TypeAnnotationTargetInfo getTargetInfo() {
return targetInfo;
}
public Annotation getAnnotation() {
return annotation;
}
public AnnotatedElement getBaseDeclaration() {
return baseDeclaration;
}
public LocationInfo getLocationInfo() {
return loc;
}
public static List<TypeAnnotation> filter(TypeAnnotation[] typeAnnotations,
TypeAnnotationTarget predicate) {
ArrayList<TypeAnnotation> typeAnnos = new ArrayList<>(typeAnnotations.length);
for (TypeAnnotation t : typeAnnotations)
if (t.getTargetInfo().getTarget() == predicate)
typeAnnos.add(t);
typeAnnos.trimToSize();
return typeAnnos;
}
public static enum TypeAnnotationTarget {
CLASS_TYPE_PARAMETER,
METHOD_TYPE_PARAMETER,
CLASS_EXTENDS,
CLASS_IMPLEMENTS, // Not in the spec
CLASS_TYPE_PARAMETER_BOUND,
METHOD_TYPE_PARAMETER_BOUND,
FIELD,
METHOD_RETURN,
METHOD_RECEIVER,
METHOD_FORMAL_PARAMETER,
THROWS;
}
public static final class TypeAnnotationTargetInfo {
private final TypeAnnotationTarget target;
private final int count;
private final int secondaryIndex;
private static final int UNUSED_INDEX = -2; // this is not a valid index in the 308 spec
public TypeAnnotationTargetInfo(TypeAnnotationTarget target) {
this(target, UNUSED_INDEX, UNUSED_INDEX);
}
public TypeAnnotationTargetInfo(TypeAnnotationTarget target,
int count) {
this(target, count, UNUSED_INDEX);
}
public TypeAnnotationTargetInfo(TypeAnnotationTarget target,
int count,
int secondaryIndex) {
this.target = target;
this.count = count;
this.secondaryIndex = secondaryIndex;
}
public TypeAnnotationTarget getTarget() {
return target;
}
public int getCount() {
return count;
}
public int getSecondaryIndex() {
return secondaryIndex;
}
@Override
public String toString() {
return "" + target + ": " + count + ", " + secondaryIndex;
}
}
public static final class LocationInfo {
private final int depth;
private final Location[] locations;
private LocationInfo() {
this(0, new Location[0]);
}
private LocationInfo(int depth, Location[] locations) {
this.depth = depth;
this.locations = locations;
}
public static final LocationInfo BASE_LOCATION = new LocationInfo();
public static LocationInfo parseLocationInfo(ByteBuffer buf) {
int depth = buf.get() & 0xFF;
if (depth == 0)
return BASE_LOCATION;
Location[] locations = new Location[depth];
for (int i = 0; i < depth; i++) {
byte tag = buf.get();
short index = (short)(buf.get() & 0xFF);
if (!(tag == 0 || tag == 1 | tag == 2 || tag == 3))
throw new AnnotationFormatError("Bad Location encoding in Type Annotation");
if (tag != 3 && index != 0)
throw new AnnotationFormatError("Bad Location encoding in Type Annotation");
locations[i] = new Location(tag, index);
}
return new LocationInfo(depth, locations);
}
public LocationInfo pushArray() {
return pushLocation((byte)0, (short)0);
}
public LocationInfo pushInner() {
return pushLocation((byte)1, (short)0);
}
public LocationInfo pushWildcard() {
return pushLocation((byte) 2, (short) 0);
}
public LocationInfo pushTypeArg(short index) {
return pushLocation((byte) 3, index);
}
public LocationInfo pushLocation(byte tag, short index) {
int newDepth = this.depth + 1;
Location[] res = new Location[newDepth];
System.arraycopy(this.locations, 0, res, 0, depth);
res[newDepth - 1] = new Location(tag, (short)(index & 0xFF));
return new LocationInfo(newDepth, res);
}
public TypeAnnotation[] filter(TypeAnnotation[] ta) {
ArrayList<TypeAnnotation> l = new ArrayList<>(ta.length);
for (TypeAnnotation t : ta) {
if (isSameLocationInfo(t.getLocationInfo()))
l.add(t);
}
return l.toArray(new TypeAnnotation[0]);
}
boolean isSameLocationInfo(LocationInfo other) {
if (depth != other.depth)
return false;
for (int i = 0; i < depth; i++)
if (!locations[i].isSameLocation(other.locations[i]))
return false;
return true;
}
public static final class Location {
public final byte tag;
public final short index;
boolean isSameLocation(Location other) {
return tag == other.tag && index == other.index;
}
public Location(byte tag, short index) {
this.tag = tag;
this.index = index;
}
}
}
@Override
public String toString() {
return annotation.toString() + " with Targetnfo: " +
targetInfo.toString() + " on base declaration: " +
baseDeclaration.toString();
}
}

View File

@@ -0,0 +1,503 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.annotation;
import java.lang.annotation.*;
import java.lang.reflect.*;
import java.nio.ByteBuffer;
import java.nio.BufferUnderflowException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import sun.misc.JavaLangAccess;
import sun.reflect.ConstantPool;
import static sun.reflect.annotation.TypeAnnotation.*;
/**
* TypeAnnotationParser implements the logic needed to parse
* TypeAnnotations from an array of bytes.
*/
public final class TypeAnnotationParser {
private static final TypeAnnotation[] EMPTY_TYPE_ANNOTATION_ARRAY = new TypeAnnotation[0];
/**
* Build an AnnotatedType from the parameters supplied.
*
* This method and {@code buildAnnotatedTypes} are probably
* the entry points you are looking for.
*
* @param rawAnnotations the byte[] encoding of all type annotations on this declaration
* @param cp the ConstantPool needed to parse the embedded Annotation
* @param decl the declaration this type annotation is on
* @param container the Class this type annotation is on (may be the same as decl)
* @param type the type the AnnotatedType corresponds to
* @param filter the type annotation targets included in this AnnotatedType
*/
public static AnnotatedType buildAnnotatedType(byte[] rawAnnotations,
ConstantPool cp,
AnnotatedElement decl,
Class<?> container,
Type type,
TypeAnnotationTarget filter) {
TypeAnnotation[] tas = parseTypeAnnotations(rawAnnotations,
cp,
decl,
container);
List<TypeAnnotation> l = new ArrayList<>(tas.length);
for (TypeAnnotation t : tas) {
TypeAnnotationTargetInfo ti = t.getTargetInfo();
if (ti.getTarget() == filter)
l.add(t);
}
TypeAnnotation[] typeAnnotations = l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY);
return AnnotatedTypeFactory.buildAnnotatedType(type,
LocationInfo.BASE_LOCATION,
typeAnnotations,
typeAnnotations,
decl);
}
/**
* Build an array of AnnotatedTypes from the parameters supplied.
*
* This method and {@code buildAnnotatedType} are probably
* the entry points you are looking for.
*
* @param rawAnnotations the byte[] encoding of all type annotations on this declaration
* @param cp the ConstantPool needed to parse the embedded Annotation
* @param decl the declaration this type annotation is on
* @param container the Class this type annotation is on (may be the same as decl)
* @param types the Types the AnnotatedTypes corresponds to
* @param filter the type annotation targets that included in this AnnotatedType
*/
public static AnnotatedType[] buildAnnotatedTypes(byte[] rawAnnotations,
ConstantPool cp,
AnnotatedElement decl,
Class<?> container,
Type[] types,
TypeAnnotationTarget filter) {
int size = types.length;
AnnotatedType[] result = new AnnotatedType[size];
Arrays.fill(result, AnnotatedTypeFactory.EMPTY_ANNOTATED_TYPE);
@SuppressWarnings("rawtypes")
ArrayList[] l = new ArrayList[size]; // array of ArrayList<TypeAnnotation>
TypeAnnotation[] tas = parseTypeAnnotations(rawAnnotations,
cp,
decl,
container);
for (TypeAnnotation t : tas) {
TypeAnnotationTargetInfo ti = t.getTargetInfo();
if (ti.getTarget() == filter) {
int pos = ti.getCount();
if (l[pos] == null) {
ArrayList<TypeAnnotation> tmp = new ArrayList<>(tas.length);
l[pos] = tmp;
}
@SuppressWarnings("unchecked")
ArrayList<TypeAnnotation> tmp = l[pos];
tmp.add(t);
}
}
for (int i = 0; i < size; i++) {
@SuppressWarnings("unchecked")
ArrayList<TypeAnnotation> list = l[i];
TypeAnnotation[] typeAnnotations;
if (list != null) {
typeAnnotations = list.toArray(new TypeAnnotation[list.size()]);
} else {
typeAnnotations = EMPTY_TYPE_ANNOTATION_ARRAY;
}
result[i] = AnnotatedTypeFactory.buildAnnotatedType(types[i],
LocationInfo.BASE_LOCATION,
typeAnnotations,
typeAnnotations,
decl);
}
return result;
}
// Class helpers
/**
* Build an AnnotatedType for the class decl's supertype.
*
* @param rawAnnotations the byte[] encoding of all type annotations on this declaration
* @param cp the ConstantPool needed to parse the embedded Annotation
* @param decl the Class which annotated supertype is being built
*/
public static AnnotatedType buildAnnotatedSuperclass(byte[] rawAnnotations,
ConstantPool cp,
Class<?> decl) {
Type supertype = decl.getGenericSuperclass();
if (supertype == null)
return AnnotatedTypeFactory.EMPTY_ANNOTATED_TYPE;
return buildAnnotatedType(rawAnnotations,
cp,
decl,
decl,
supertype,
TypeAnnotationTarget.CLASS_EXTENDS);
}
/**
* Build an array of AnnotatedTypes for the class decl's implemented
* interfaces.
*
* @param rawAnnotations the byte[] encoding of all type annotations on this declaration
* @param cp the ConstantPool needed to parse the embedded Annotation
* @param decl the Class whose annotated implemented interfaces is being built
*/
public static AnnotatedType[] buildAnnotatedInterfaces(byte[] rawAnnotations,
ConstantPool cp,
Class<?> decl) {
if (decl == Object.class ||
decl.isArray() ||
decl.isPrimitive() ||
decl == Void.TYPE)
return AnnotatedTypeFactory.EMPTY_ANNOTATED_TYPE_ARRAY;
return buildAnnotatedTypes(rawAnnotations,
cp,
decl,
decl,
decl.getGenericInterfaces(),
TypeAnnotationTarget.CLASS_IMPLEMENTS);
}
// TypeVariable helpers
/**
* Parse regular annotations on a TypeVariable declared on genericDecl.
*
* Regular Annotations on TypeVariables are stored in the type
* annotation byte[] in the class file.
*
* @param genericsDecl the declaration declaring the type variable
* @param typeVarIndex the 0-based index of this type variable in the declaration
*/
public static <D extends GenericDeclaration> Annotation[] parseTypeVariableAnnotations(D genericDecl,
int typeVarIndex) {
AnnotatedElement decl;
TypeAnnotationTarget predicate;
if (genericDecl instanceof Class) {
decl = (Class<?>)genericDecl;
predicate = TypeAnnotationTarget.CLASS_TYPE_PARAMETER;
} else if (genericDecl instanceof Executable) {
decl = (Executable)genericDecl;
predicate = TypeAnnotationTarget.METHOD_TYPE_PARAMETER;
} else {
throw new AssertionError("Unknown GenericDeclaration " + genericDecl + "\nthis should not happen.");
}
List<TypeAnnotation> typeVarAnnos = TypeAnnotation.filter(parseAllTypeAnnotations(decl),
predicate);
List<Annotation> res = new ArrayList<>(typeVarAnnos.size());
for (TypeAnnotation t : typeVarAnnos)
if (t.getTargetInfo().getCount() == typeVarIndex)
res.add(t.getAnnotation());
return res.toArray(new Annotation[0]);
}
/**
* Build an array of AnnotatedTypes for the declaration decl's bounds.
*
* @param bounds the bounds corresponding to the annotated bounds
* @param decl the declaration whose annotated bounds is being built
* @param typeVarIndex the index of this type variable on the decl
*/
public static <D extends GenericDeclaration> AnnotatedType[] parseAnnotatedBounds(Type[] bounds,
D decl,
int typeVarIndex) {
return parseAnnotatedBounds(bounds, decl, typeVarIndex, LocationInfo.BASE_LOCATION);
}
//helper for above
private static <D extends GenericDeclaration> AnnotatedType[] parseAnnotatedBounds(Type[] bounds,
D decl,
int typeVarIndex,
LocationInfo loc) {
List<TypeAnnotation> candidates = fetchBounds(decl);
if (bounds != null) {
int startIndex = 0;
AnnotatedType[] res = new AnnotatedType[bounds.length];
// Adjust bounds index
//
// Figure out if the type annotations for this bound starts with 0
// or 1. The spec says within a bound the 0:th type annotation will
// always be on an bound of a Class type (not Interface type). So
// if the programmer starts with an Interface type for the first
// (and following) bound(s) the implicit Object bound is considered
// the first (that is 0:th) bound and type annotations start on
// index 1.
if (bounds.length > 0) {
Type b0 = bounds[0];
if (!(b0 instanceof Class<?>)) {
startIndex = 1;
} else {
Class<?> c = (Class<?>)b0;
if (c.isInterface()) {
startIndex = 1;
}
}
}
for (int i = 0; i < bounds.length; i++) {
List<TypeAnnotation> l = new ArrayList<>(candidates.size());
for (TypeAnnotation t : candidates) {
TypeAnnotationTargetInfo tInfo = t.getTargetInfo();
if (tInfo.getSecondaryIndex() == i + startIndex &&
tInfo.getCount() == typeVarIndex) {
l.add(t);
}
}
res[i] = AnnotatedTypeFactory.buildAnnotatedType(bounds[i],
loc,
l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY),
candidates.toArray(EMPTY_TYPE_ANNOTATION_ARRAY),
(AnnotatedElement)decl);
}
return res;
}
return new AnnotatedType[0];
}
private static <D extends GenericDeclaration> List<TypeAnnotation> fetchBounds(D decl) {
AnnotatedElement boundsDecl;
TypeAnnotationTarget target;
if (decl instanceof Class) {
target = TypeAnnotationTarget.CLASS_TYPE_PARAMETER_BOUND;
boundsDecl = (Class)decl;
} else {
target = TypeAnnotationTarget.METHOD_TYPE_PARAMETER_BOUND;
boundsDecl = (Executable)decl;
}
return TypeAnnotation.filter(TypeAnnotationParser.parseAllTypeAnnotations(boundsDecl), target);
}
/*
* Parse all type annotations on the declaration supplied. This is needed
* when you go from for example an annotated return type on a method that
* is a type variable declared on the class. In this case you need to
* 'jump' to the decl of the class and parse all type annotations there to
* find the ones that are applicable to the type variable.
*/
static TypeAnnotation[] parseAllTypeAnnotations(AnnotatedElement decl) {
Class<?> container;
byte[] rawBytes;
JavaLangAccess javaLangAccess = sun.misc.SharedSecrets.getJavaLangAccess();
if (decl instanceof Class) {
container = (Class<?>)decl;
rawBytes = javaLangAccess.getRawClassTypeAnnotations(container);
} else if (decl instanceof Executable) {
container = ((Executable)decl).getDeclaringClass();
rawBytes = javaLangAccess.getRawExecutableTypeAnnotations((Executable)decl);
} else {
// Should not reach here. Assert?
return EMPTY_TYPE_ANNOTATION_ARRAY;
}
return parseTypeAnnotations(rawBytes, javaLangAccess.getConstantPool(container),
decl, container);
}
/* Parse type annotations encoded as an array of bytes */
private static TypeAnnotation[] parseTypeAnnotations(byte[] rawAnnotations,
ConstantPool cp,
AnnotatedElement baseDecl,
Class<?> container) {
if (rawAnnotations == null)
return EMPTY_TYPE_ANNOTATION_ARRAY;
ByteBuffer buf = ByteBuffer.wrap(rawAnnotations);
int annotationCount = buf.getShort() & 0xFFFF;
List<TypeAnnotation> typeAnnotations = new ArrayList<>(annotationCount);
// Parse each TypeAnnotation
for (int i = 0; i < annotationCount; i++) {
TypeAnnotation ta = parseTypeAnnotation(buf, cp, baseDecl, container);
if (ta != null)
typeAnnotations.add(ta);
}
return typeAnnotations.toArray(EMPTY_TYPE_ANNOTATION_ARRAY);
}
// Helper
static Map<Class<? extends Annotation>, Annotation> mapTypeAnnotations(TypeAnnotation[] typeAnnos) {
Map<Class<? extends Annotation>, Annotation> result =
new LinkedHashMap<>();
for (TypeAnnotation t : typeAnnos) {
Annotation a = t.getAnnotation();
Class<? extends Annotation> klass = a.annotationType();
AnnotationType type = AnnotationType.getInstance(klass);
if (type.retention() == RetentionPolicy.RUNTIME)
if (result.put(klass, a) != null)
throw new AnnotationFormatError("Duplicate annotation for class: "+klass+": " + a);
}
return result;
}
// Position codes
// Regular type parameter annotations
private static final byte CLASS_TYPE_PARAMETER = 0x00;
private static final byte METHOD_TYPE_PARAMETER = 0x01;
// Type Annotations outside method bodies
private static final byte CLASS_EXTENDS = 0x10;
private static final byte CLASS_TYPE_PARAMETER_BOUND = 0x11;
private static final byte METHOD_TYPE_PARAMETER_BOUND = 0x12;
private static final byte FIELD = 0x13;
private static final byte METHOD_RETURN = 0x14;
private static final byte METHOD_RECEIVER = 0x15;
private static final byte METHOD_FORMAL_PARAMETER = 0x16;
private static final byte THROWS = 0x17;
// Type Annotations inside method bodies
private static final byte LOCAL_VARIABLE = (byte)0x40;
private static final byte RESOURCE_VARIABLE = (byte)0x41;
private static final byte EXCEPTION_PARAMETER = (byte)0x42;
private static final byte INSTANCEOF = (byte)0x43;
private static final byte NEW = (byte)0x44;
private static final byte CONSTRUCTOR_REFERENCE = (byte)0x45;
private static final byte METHOD_REFERENCE = (byte)0x46;
private static final byte CAST = (byte)0x47;
private static final byte CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = (byte)0x48;
private static final byte METHOD_INVOCATION_TYPE_ARGUMENT = (byte)0x49;
private static final byte CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = (byte)0x4A;
private static final byte METHOD_REFERENCE_TYPE_ARGUMENT = (byte)0x4B;
private static TypeAnnotation parseTypeAnnotation(ByteBuffer buf,
ConstantPool cp,
AnnotatedElement baseDecl,
Class<?> container) {
try {
TypeAnnotationTargetInfo ti = parseTargetInfo(buf);
LocationInfo locationInfo = LocationInfo.parseLocationInfo(buf);
Annotation a = AnnotationParser.parseAnnotation(buf, cp, container, false);
if (ti == null) // Inside a method for example
return null;
return new TypeAnnotation(ti, locationInfo, a, baseDecl);
} catch (IllegalArgumentException | // Bad type in const pool at specified index
BufferUnderflowException e) {
throw new AnnotationFormatError(e);
}
}
private static TypeAnnotationTargetInfo parseTargetInfo(ByteBuffer buf) {
int posCode = buf.get() & 0xFF;
switch(posCode) {
case CLASS_TYPE_PARAMETER:
case METHOD_TYPE_PARAMETER: {
int index = buf.get() & 0xFF;
TypeAnnotationTargetInfo res;
if (posCode == CLASS_TYPE_PARAMETER)
res = new TypeAnnotationTargetInfo(TypeAnnotationTarget.CLASS_TYPE_PARAMETER,
index);
else
res = new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_TYPE_PARAMETER,
index);
return res;
} // unreachable break;
case CLASS_EXTENDS: {
short index = buf.getShort(); //needs to be signed
if (index == -1) {
return new TypeAnnotationTargetInfo(TypeAnnotationTarget.CLASS_EXTENDS);
} else if (index >= 0) {
TypeAnnotationTargetInfo res = new TypeAnnotationTargetInfo(TypeAnnotationTarget.CLASS_IMPLEMENTS,
index);
return res;
}} break;
case CLASS_TYPE_PARAMETER_BOUND:
return parse2ByteTarget(TypeAnnotationTarget.CLASS_TYPE_PARAMETER_BOUND, buf);
case METHOD_TYPE_PARAMETER_BOUND:
return parse2ByteTarget(TypeAnnotationTarget.METHOD_TYPE_PARAMETER_BOUND, buf);
case FIELD:
return new TypeAnnotationTargetInfo(TypeAnnotationTarget.FIELD);
case METHOD_RETURN:
return new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_RETURN);
case METHOD_RECEIVER:
return new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_RECEIVER);
case METHOD_FORMAL_PARAMETER: {
int index = buf.get() & 0xFF;
return new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_FORMAL_PARAMETER,
index);
} //unreachable break;
case THROWS:
return parseShortTarget(TypeAnnotationTarget.THROWS, buf);
/*
* The ones below are inside method bodies, we don't care about them for core reflection
* other than adjusting for them in the byte stream.
*/
case LOCAL_VARIABLE:
case RESOURCE_VARIABLE:
short length = buf.getShort();
for (int i = 0; i < length; ++i) {
short offset = buf.getShort();
short varLength = buf.getShort();
short index = buf.getShort();
}
return null;
case EXCEPTION_PARAMETER: {
byte index = buf.get();
}
return null;
case INSTANCEOF:
case NEW:
case CONSTRUCTOR_REFERENCE:
case METHOD_REFERENCE: {
short offset = buf.getShort();
}
return null;
case CAST:
case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
case METHOD_INVOCATION_TYPE_ARGUMENT:
case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
case METHOD_REFERENCE_TYPE_ARGUMENT: {
short offset = buf.getShort();
byte index = buf.get();
}
return null;
default:
// will throw error below
break;
}
throw new AnnotationFormatError("Could not parse bytes for type annotations");
}
private static TypeAnnotationTargetInfo parseShortTarget(TypeAnnotationTarget target, ByteBuffer buf) {
int index = buf.getShort() & 0xFFFF;
return new TypeAnnotationTargetInfo(target, index);
}
private static TypeAnnotationTargetInfo parse2ByteTarget(TypeAnnotationTarget target, ByteBuffer buf) {
int count = buf.get() & 0xFF;
int secondaryIndex = buf.get() & 0xFF;
return new TypeAnnotationTargetInfo(target,
count,
secondaryIndex);
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.annotation;
import java.lang.annotation.*;
/**
* ExceptionProxy for TypeNotPresentException.
*
* @author Josh Bloch
* @since 1.5
*/
public class TypeNotPresentExceptionProxy extends ExceptionProxy {
private static final long serialVersionUID = 5565925172427947573L;
String typeName;
Throwable cause;
public TypeNotPresentExceptionProxy(String typeName, Throwable cause) {
this.typeName = typeName;
this.cause = cause;
}
protected RuntimeException generateException() {
return new TypeNotPresentException(typeName, cause);
}
}

View File

@@ -0,0 +1,138 @@
/*
* Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.generics.factory;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import sun.reflect.generics.reflectiveObjects.*;
import sun.reflect.generics.scope.Scope;
import sun.reflect.generics.tree.FieldTypeSignature;
/**
* Factory for reflective generic type objects for use by
* core reflection (java.lang.reflect).
*/
public class CoreReflectionFactory implements GenericsFactory {
private final GenericDeclaration decl;
private final Scope scope;
private CoreReflectionFactory(GenericDeclaration d, Scope s) {
decl = d;
scope = s;
}
private GenericDeclaration getDecl(){ return decl;}
private Scope getScope(){ return scope;}
private ClassLoader getDeclsLoader() {
if (decl instanceof Class) {return ((Class) decl).getClassLoader();}
if (decl instanceof Method) {
return ((Method) decl).getDeclaringClass().getClassLoader();
}
assert decl instanceof Constructor : "Constructor expected";
return ((Constructor) decl).getDeclaringClass().getClassLoader();
}
/**
* Factory for this class. Returns an instance of
* <tt>CoreReflectionFactory</tt> for the declaration and scope
* provided.
* This factory will produce reflective objects of the appropriate
* kind. Classes produced will be those that would be loaded by the
* defining class loader of the declaration <tt>d</tt> (if <tt>d</tt>
* is a type declaration, or by the defining loader of the declaring
* class of <tt>d</tt> otherwise.
* <p> Type variables will be created or lookup as necessary in the
* scope <tt> s</tt>.
* @param d - the generic declaration (class, interface, method or
* constructor) that thsi factory services
* @param s the scope in which the factory will allocate and search for
* type variables
* @return an instance of <tt>CoreReflectionFactory</tt>
*/
public static CoreReflectionFactory make(GenericDeclaration d, Scope s) {
return new CoreReflectionFactory(d, s);
}
public TypeVariable<?> makeTypeVariable(String name,
FieldTypeSignature[] bounds){
return TypeVariableImpl.make(getDecl(), name, bounds, this);
}
public WildcardType makeWildcard(FieldTypeSignature[] ubs,
FieldTypeSignature[] lbs) {
return WildcardTypeImpl.make(ubs, lbs, this);
}
public ParameterizedType makeParameterizedType(Type declaration,
Type[] typeArgs,
Type owner) {
return ParameterizedTypeImpl.make((Class<?>) declaration,
typeArgs, owner);
}
public TypeVariable<?> findTypeVariable(String name){
return getScope().lookup(name);
}
public Type makeNamedType(String name){
try {return Class.forName(name, false, // don't initialize
getDeclsLoader());}
catch (ClassNotFoundException c) {
throw new TypeNotPresentException(name, c);
}
}
public Type makeArrayType(Type componentType){
if (componentType instanceof Class<?>)
return Array.newInstance((Class<?>) componentType, 0).getClass();
else
return GenericArrayTypeImpl.make(componentType);
}
public Type makeByte(){return byte.class;}
public Type makeBool(){return boolean.class;}
public Type makeShort(){return short.class;}
public Type makeChar(){return char.class;}
public Type makeInt(){return int.class;}
public Type makeLong(){return long.class;}
public Type makeFloat(){return float.class;}
public Type makeDouble(){return double.class;}
public Type makeVoid(){return void.class;}
}

View File

@@ -0,0 +1,190 @@
/*
* Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.generics.factory;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import sun.reflect.generics.tree.FieldTypeSignature;
/**
* A factory interface for reflective objects representing generic types.
* Implementors (such as core reflection or JDI, or possibly javadoc
* will manufacture instances of (potentially) different classes
* in response to invocations of the methods described here.
* <p> The intent is that reflective systems use these factories to
* produce generic type information on demand.
* Certain components of such reflective systems can be independent
* of a specific implementation by using this interface. For example,
* repositories of generic type information are initialized with a
* factory conforming to this interface, and use it to generate the
* tpe information they are required to provide. As a result, such
* repository code can be shared across different reflective systems.
*/
public interface GenericsFactory {
/**
* Returns a new type variable declaration. Note that <tt>name</tt>
* may be empty (but not <tt>null</tt>). If <tt>bounds</tt> is
* empty, a bound of <tt>java.lang.Object</tt> is used.
* @param name The name of the type variable
* @param bounds An array of abstract syntax trees representing
* the upper bound(s) on the type variable being declared
* @return a new type variable declaration
* @throws NullPointerException - if any of the actual parameters
* or any of the elements of <tt>bounds</tt> are <tt>null</tt>.
*/
TypeVariable<?> makeTypeVariable(String name,
FieldTypeSignature[] bounds);
/**
* Return an instance of the <tt>ParameterizedType</tt> interface
* that corresponds to a generic type instantiation of the
* generic declaration <tt>declaration</tt> with actual type arguments
* <tt>typeArgs</tt>.
* If <tt>owner</tt> is <tt>null</tt>, the declaring class of
* <tt>declaration</tt> is used as the owner of this parameterized
* type.
* <p> This method throws a MalformedParameterizedTypeException
* under the following circumstances:
* If the type declaration does not represent a generic declaration
* (i.e., it is not an instance of <tt>GenericDeclaration</tt>).
* If the number of actual type arguments (i.e., the size of the
* array <tt>typeArgs</tt>) does not correspond to the number of
* formal type arguments.
* If any of the actual type arguments is not an instance of the
* bounds on the corresponding formal.
* @param declaration - the generic type declaration that is to be
* instantiated
* @param typeArgs - the list of actual type arguments
* @return - a parameterized type representing the instantiation
* of the declaration with the actual type arguments
* @throws MalformedParameterizedTypeException - if the instantiation
* is invalid
* @throws NullPointerException - if any of <tt>declaration</tt>
* , <tt>typeArgs</tt>
* or any of the elements of <tt>typeArgs</tt> are <tt>null</tt>
*/
ParameterizedType makeParameterizedType(Type declaration,
Type[] typeArgs,
Type owner);
/**
* Returns the type variable with name <tt>name</tt>, if such
* a type variable is declared in the
* scope used to create this factory.
* Returns <tt>null</tt> otherwise.
* @param name - the name of the type variable to search for
* @return - the type variable with name <tt>name</tt>, or <tt>null</tt>
* @throws NullPointerException - if any of actual parameters are
* <tt>null</tt>
*/
TypeVariable<?> findTypeVariable(String name);
/**
* Returns a new wildcard type variable. If
* <tt>ubs</tt> is empty, a bound of <tt>java.lang.Object</tt> is used.
* @param ubs An array of abstract syntax trees representing
* the upper bound(s) on the type variable being declared
* @param lbs An array of abstract syntax trees representing
* the lower bound(s) on the type variable being declared
* @return a new wildcard type variable
* @throws NullPointerException - if any of the actual parameters
* or any of the elements of <tt>ubs</tt> or <tt>lbs</tt>are
* <tt>null</tt>
*/
WildcardType makeWildcard(FieldTypeSignature[] ubs,
FieldTypeSignature[] lbs);
Type makeNamedType(String name);
/**
* Returns a (possibly generic) array type.
* If the component type is a parameterized type, it must
* only have unbounded wildcard arguemnts, otherwise
* a MalformedParameterizedTypeException is thrown.
* @param componentType - the component type of the array
* @return a (possibly generic) array type.
* @throws MalformedParameterizedTypeException if <tt>componentType</tt>
* is a parameterized type with non-wildcard type arguments
* @throws NullPointerException - if any of the actual parameters
* are <tt>null</tt>
*/
Type makeArrayType(Type componentType);
/**
* Returns the reflective representation of type <tt>byte</tt>.
* @return the reflective representation of type <tt>byte</tt>.
*/
Type makeByte();
/**
* Returns the reflective representation of type <tt>boolean</tt>.
* @return the reflective representation of type <tt>boolean</tt>.
*/
Type makeBool();
/**
* Returns the reflective representation of type <tt>short</tt>.
* @return the reflective representation of type <tt>short</tt>.
*/
Type makeShort();
/**
* Returns the reflective representation of type <tt>char</tt>.
* @return the reflective representation of type <tt>char</tt>.
*/
Type makeChar();
/**
* Returns the reflective representation of type <tt>int</tt>.
* @return the reflective representation of type <tt>int</tt>.
*/
Type makeInt();
/**
* Returns the reflective representation of type <tt>long</tt>.
* @return the reflective representation of type <tt>long</tt>.
*/
Type makeLong();
/**
* Returns the reflective representation of type <tt>float</tt>.
* @return the reflective representation of type <tt>float</tt>.
*/
Type makeFloat();
/**
* Returns the reflective representation of type <tt>double</tt>.
* @return the reflective representation of type <tt>double</tt>.
*/
Type makeDouble();
/**
* Returns the reflective representation of <tt>void</tt>.
* @return the reflective representation of <tt>void</tt>.
*/
Type makeVoid();
}

View File

@@ -0,0 +1,634 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.generics.parser;
import java.lang.reflect.GenericSignatureFormatError;
import java.util.*;
import sun.reflect.generics.tree.*;
/**
* Parser for type signatures, as defined in the Java Virtual
* Machine Specification (JVMS) chapter 4.
* Converts the signatures into an abstract syntax tree (AST) representation.
* See the package sun.reflect.generics.tree for details of the AST.
*/
public class SignatureParser {
// The input is conceptually a character stream (though currently it's
// a string). This is slightly different than traditional parsers,
// because there is no lexical scanner performing tokenization.
// Having a separate tokenizer does not fit with the nature of the
// input format.
// Other than the absence of a tokenizer, this parser is a classic
// recursive descent parser. Its structure corresponds as closely
// as possible to the grammar in the JVMS.
//
// A note on asserts vs. errors: The code contains assertions
// in situations that should never occur. An assertion failure
// indicates a failure of the parser logic. A common pattern
// is an assertion that the current input is a particular
// character. This is often paired with a separate check
// that this is the case, which seems redundant. For example:
//
// assert(current() != x);
// if (current != x {error("expected an x");
//
// where x is some character constant.
// The assertion indicates, that, as currently written,
// the code should never reach this point unless the input is an
// x. On the other hand, the test is there to check the legality
// of the input wrt to a given production. It may be that at a later
// time the code might be called directly, and if the input is
// invalid, the parser should flag an error in accordance
// with its logic.
private String input; // the input signature
private int index; // index into the input
private int mark; // index of mark
// used to mark end of input
private static final char EOI = ':';
private static final boolean DEBUG = false;
// private constructor - enforces use of static factory
private SignatureParser(){}
// prepares parser for new parsing session
private void init(String s) {
input = s;
mark = index = 0;
}
// Utility methods.
// Most parsing routines use the following routines to access the
// input stream, and advance it as necessary.
// This makes it easy to adapt the parser to operate on streams
// of various kinds as well as strings.
// returns current element of the input
private char current(){
assert(index <= input.length());
return index < input.length() ? input.charAt(index) : EOI;
}
// advance the input
private void advance(){
assert(index <= input.length());
if (index < input.length()) index++;
}
// mark current position
private void mark() {
mark = index;
}
// For debugging, prints current character to the end of the input.
private String remainder() {
return input.substring(index);
}
// returns a substring of input from mark (inclusive)
// to current position (exclusive)
private String markToCurrent() {
return input.substring(mark, index);
}
// Error handling routine. Encapsulates error handling.
// Takes a string error message as argument.
// Currently throws a GenericSignatureFormatError.
private Error error(String errorMsg) {
return new GenericSignatureFormatError("Signature Parse error: " + errorMsg +
"\n\tRemaining input: " + remainder());
}
/**
* Verify the parse has made forward progress; throw an exception
* if no progress.
*/
private void progress(int startingPosition) {
if (index <= startingPosition)
throw error("Failure to make progress!");
}
/**
* Static factory method. Produces a parser instance.
* @return an instance of <tt>SignatureParser</tt>
*/
public static SignatureParser make() {
return new SignatureParser();
}
/**
* Parses a class signature (as defined in the JVMS, chapter 4)
* and produces an abstract syntax tree representing it.
* @param s a string representing the input class signature
* @return An abstract syntax tree for a class signature
* corresponding to the input string
* @throws GenericSignatureFormatError if the input is not a valid
* class signature
*/
public ClassSignature parseClassSig(String s) {
if (DEBUG) System.out.println("Parsing class sig:" + s);
init(s);
return parseClassSignature();
}
/**
* Parses a method signature (as defined in the JVMS, chapter 4)
* and produces an abstract syntax tree representing it.
* @param s a string representing the input method signature
* @return An abstract syntax tree for a method signature
* corresponding to the input string
* @throws GenericSignatureFormatError if the input is not a valid
* method signature
*/
public MethodTypeSignature parseMethodSig(String s) {
if (DEBUG) System.out.println("Parsing method sig:" + s);
init(s);
return parseMethodTypeSignature();
}
/**
* Parses a type signature
* and produces an abstract syntax tree representing it.
*
* @param s a string representing the input type signature
* @return An abstract syntax tree for a type signature
* corresponding to the input string
* @throws GenericSignatureFormatError if the input is not a valid
* type signature
*/
public TypeSignature parseTypeSig(String s) {
if (DEBUG) System.out.println("Parsing type sig:" + s);
init(s);
return parseTypeSignature();
}
// Parsing routines.
// As a rule, the parsing routines access the input using the
// utilities current() and advance().
// The convention is that when a parsing routine is invoked
// it expects the current input to be the first character it should parse
// and when it completes parsing, it leaves the input at the first
// character after the input parses.
/*
* Note on grammar conventions: a trailing "*" matches zero or
* more occurrences, a trailing "+" matches one or more occurrences,
* "_opt" indicates an optional component.
*/
/**
* ClassSignature:
* FormalTypeParameters_opt SuperclassSignature SuperinterfaceSignature*
*/
private ClassSignature parseClassSignature() {
// parse a class signature based on the implicit input.
assert(index == 0);
return ClassSignature.make(parseZeroOrMoreFormalTypeParameters(),
parseClassTypeSignature(), // Only rule for SuperclassSignature
parseSuperInterfaces());
}
private FormalTypeParameter[] parseZeroOrMoreFormalTypeParameters(){
if (current() == '<') {
return parseFormalTypeParameters();
} else {
return new FormalTypeParameter[0];
}
}
/**
* FormalTypeParameters:
* "<" FormalTypeParameter+ ">"
*/
private FormalTypeParameter[] parseFormalTypeParameters(){
List<FormalTypeParameter> ftps = new ArrayList<>(3);
assert(current() == '<'); // should not have been called at all
if (current() != '<') { throw error("expected '<'");}
advance();
ftps.add(parseFormalTypeParameter());
while (current() != '>') {
int startingPosition = index;
ftps.add(parseFormalTypeParameter());
progress(startingPosition);
}
advance();
return ftps.toArray(new FormalTypeParameter[ftps.size()]);
}
/**
* FormalTypeParameter:
* Identifier ClassBound InterfaceBound*
*/
private FormalTypeParameter parseFormalTypeParameter(){
String id = parseIdentifier();
FieldTypeSignature[] bs = parseBounds();
return FormalTypeParameter.make(id, bs);
}
private String parseIdentifier() {
mark();
skipIdentifier();
return markToCurrent();
}
private void skipIdentifier() {
char c = current();
while (c != ';' && c != '.' && c != '/' &&
c != '[' && c != ':' && c != '>' &&
c != '<' && !Character.isWhitespace(c)) {
advance();
c = current();
}
}
/**
* FieldTypeSignature:
* ClassTypeSignature
* ArrayTypeSignature
* TypeVariableSignature
*/
private FieldTypeSignature parseFieldTypeSignature() {
return parseFieldTypeSignature(true);
}
private FieldTypeSignature parseFieldTypeSignature(boolean allowArrays) {
switch(current()) {
case 'L':
return parseClassTypeSignature();
case 'T':
return parseTypeVariableSignature();
case '[':
if (allowArrays)
return parseArrayTypeSignature();
else
throw error("Array signature not allowed here.");
default: throw error("Expected Field Type Signature");
}
}
/**
* ClassTypeSignature:
* "L" PackageSpecifier_opt SimpleClassTypeSignature ClassTypeSignatureSuffix* ";"
*/
private ClassTypeSignature parseClassTypeSignature(){
assert(current() == 'L');
if (current() != 'L') { throw error("expected a class type");}
advance();
List<SimpleClassTypeSignature> scts = new ArrayList<>(5);
scts.add(parsePackageNameAndSimpleClassTypeSignature());
parseClassTypeSignatureSuffix(scts);
if (current() != ';')
throw error("expected ';' got '" + current() + "'");
advance();
return ClassTypeSignature.make(scts);
}
/**
* PackageSpecifier:
* Identifier "/" PackageSpecifier*
*/
private SimpleClassTypeSignature parsePackageNameAndSimpleClassTypeSignature() {
// Parse both any optional leading PackageSpecifier as well as
// the following SimpleClassTypeSignature.
mark();
skipIdentifier();
while (current() == '/') {
advance();
skipIdentifier();
}
String id = markToCurrent().replace('/', '.');
switch (current()) {
case ';':
return SimpleClassTypeSignature.make(id, false, new TypeArgument[0]); // all done!
case '<':
if (DEBUG) System.out.println("\t remainder: " + remainder());
return SimpleClassTypeSignature.make(id, false, parseTypeArguments());
default:
throw error("expected '<' or ';' but got " + current());
}
}
/**
* SimpleClassTypeSignature:
* Identifier TypeArguments_opt
*/
private SimpleClassTypeSignature parseSimpleClassTypeSignature(boolean dollar){
String id = parseIdentifier();
char c = current();
switch (c) {
case ';':
case '.':
return SimpleClassTypeSignature.make(id, dollar, new TypeArgument[0]) ;
case '<':
return SimpleClassTypeSignature.make(id, dollar, parseTypeArguments());
default:
throw error("expected '<' or ';' or '.', got '" + c + "'.");
}
}
/**
* ClassTypeSignatureSuffix:
* "." SimpleClassTypeSignature
*/
private void parseClassTypeSignatureSuffix(List<SimpleClassTypeSignature> scts) {
while (current() == '.') {
advance();
scts.add(parseSimpleClassTypeSignature(true));
}
}
/**
* TypeArguments:
* "<" TypeArgument+ ">"
*/
private TypeArgument[] parseTypeArguments() {
List<TypeArgument> tas = new ArrayList<>(3);
assert(current() == '<');
if (current() != '<') { throw error("expected '<'");}
advance();
tas.add(parseTypeArgument());
while (current() != '>') {
//(matches(current(), '+', '-', 'L', '[', 'T', '*')) {
tas.add(parseTypeArgument());
}
advance();
return tas.toArray(new TypeArgument[tas.size()]);
}
/**
* TypeArgument:
* WildcardIndicator_opt FieldTypeSignature
* "*"
*/
private TypeArgument parseTypeArgument() {
FieldTypeSignature[] ub, lb;
ub = new FieldTypeSignature[1];
lb = new FieldTypeSignature[1];
TypeArgument[] ta = new TypeArgument[0];
char c = current();
switch (c) {
case '+': {
advance();
ub[0] = parseFieldTypeSignature();
lb[0] = BottomSignature.make(); // bottom
return Wildcard.make(ub, lb);
}
case '*':{
advance();
ub[0] = SimpleClassTypeSignature.make("java.lang.Object", false, ta);
lb[0] = BottomSignature.make(); // bottom
return Wildcard.make(ub, lb);
}
case '-': {
advance();
lb[0] = parseFieldTypeSignature();
ub[0] = SimpleClassTypeSignature.make("java.lang.Object", false, ta);
return Wildcard.make(ub, lb);
}
default:
return parseFieldTypeSignature();
}
}
/**
* TypeVariableSignature:
* "T" Identifier ";"
*/
private TypeVariableSignature parseTypeVariableSignature() {
assert(current() == 'T');
if (current() != 'T') { throw error("expected a type variable usage");}
advance();
TypeVariableSignature ts = TypeVariableSignature.make(parseIdentifier());
if (current() != ';') {
throw error("; expected in signature of type variable named" +
ts.getIdentifier());
}
advance();
return ts;
}
/**
* ArrayTypeSignature:
* "[" TypeSignature
*/
private ArrayTypeSignature parseArrayTypeSignature() {
if (current() != '[') {throw error("expected array type signature");}
advance();
return ArrayTypeSignature.make(parseTypeSignature());
}
/**
* TypeSignature:
* FieldTypeSignature
* BaseType
*/
private TypeSignature parseTypeSignature() {
switch (current()) {
case 'B':
case 'C':
case 'D':
case 'F':
case 'I':
case 'J':
case 'S':
case 'Z':
return parseBaseType();
default:
return parseFieldTypeSignature();
}
}
private BaseType parseBaseType() {
switch(current()) {
case 'B':
advance();
return ByteSignature.make();
case 'C':
advance();
return CharSignature.make();
case 'D':
advance();
return DoubleSignature.make();
case 'F':
advance();
return FloatSignature.make();
case 'I':
advance();
return IntSignature.make();
case 'J':
advance();
return LongSignature.make();
case 'S':
advance();
return ShortSignature.make();
case 'Z':
advance();
return BooleanSignature.make();
default: {
assert(false);
throw error("expected primitive type");
}
}
}
/**
* ClassBound:
* ":" FieldTypeSignature_opt
*
* InterfaceBound:
* ":" FieldTypeSignature
*/
private FieldTypeSignature[] parseBounds() {
List<FieldTypeSignature> fts = new ArrayList<>(3);
if (current() == ':') {
advance();
switch(current()) {
case ':': // empty class bound
break;
default: // parse class bound
fts.add(parseFieldTypeSignature());
}
// zero or more interface bounds
while (current() == ':') {
advance();
fts.add(parseFieldTypeSignature());
}
} else
error("Bound expected");
return fts.toArray(new FieldTypeSignature[fts.size()]);
}
/**
* SuperclassSignature:
* ClassTypeSignature
*/
private ClassTypeSignature[] parseSuperInterfaces() {
List<ClassTypeSignature> cts = new ArrayList<>(5);
while(current() == 'L') {
cts.add(parseClassTypeSignature());
}
return cts.toArray(new ClassTypeSignature[cts.size()]);
}
/**
* MethodTypeSignature:
* FormalTypeParameters_opt "(" TypeSignature* ")" ReturnType ThrowsSignature*
*/
private MethodTypeSignature parseMethodTypeSignature() {
// Parse a method signature based on the implicit input.
FieldTypeSignature[] ets;
assert(index == 0);
return MethodTypeSignature.make(parseZeroOrMoreFormalTypeParameters(),
parseFormalParameters(),
parseReturnType(),
parseZeroOrMoreThrowsSignatures());
}
// "(" TypeSignature* ")"
private TypeSignature[] parseFormalParameters() {
if (current() != '(') {throw error("expected '('");}
advance();
TypeSignature[] pts = parseZeroOrMoreTypeSignatures();
if (current() != ')') {throw error("expected ')'");}
advance();
return pts;
}
// TypeSignature*
private TypeSignature[] parseZeroOrMoreTypeSignatures() {
List<TypeSignature> ts = new ArrayList<>();
boolean stop = false;
while (!stop) {
switch(current()) {
case 'B':
case 'C':
case 'D':
case 'F':
case 'I':
case 'J':
case 'S':
case 'Z':
case 'L':
case 'T':
case '[': {
ts.add(parseTypeSignature());
break;
}
default: stop = true;
}
}
return ts.toArray(new TypeSignature[ts.size()]);
}
/**
* ReturnType:
* TypeSignature
* VoidDescriptor
*/
private ReturnType parseReturnType(){
if (current() == 'V') {
advance();
return VoidDescriptor.make();
} else
return parseTypeSignature();
}
// ThrowSignature*
private FieldTypeSignature[] parseZeroOrMoreThrowsSignatures(){
List<FieldTypeSignature> ets = new ArrayList<>(3);
while( current() == '^') {
ets.add(parseThrowsSignature());
}
return ets.toArray(new FieldTypeSignature[ets.size()]);
}
/**
* ThrowsSignature:
* "^" ClassTypeSignature
* "^" TypeVariableSignature
*/
private FieldTypeSignature parseThrowsSignature() {
assert(current() == '^');
if (current() != '^') { throw error("expected throws signature");}
advance();
return parseFieldTypeSignature(false);
}
}

View File

@@ -0,0 +1,93 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.generics.reflectiveObjects;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Type;
import java.util.Objects;
/**
* Implementation of GenericArrayType interface for core reflection.
*/
public class GenericArrayTypeImpl
implements GenericArrayType {
private final Type genericComponentType;
// private constructor enforces use of static factory
private GenericArrayTypeImpl(Type ct) {
genericComponentType = ct;
}
/**
* Factory method.
* @param ct - the desired component type of the generic array type
* being created
* @return a generic array type with the desired component type
*/
public static GenericArrayTypeImpl make(Type ct) {
return new GenericArrayTypeImpl(ct);
}
/**
* Returns a <tt>Type</tt> object representing the component type
* of this array.
*
* @return a <tt>Type</tt> object representing the component type
* of this array
* @since 1.5
*/
public Type getGenericComponentType() {
return genericComponentType; // return cached component type
}
public String toString() {
Type componentType = getGenericComponentType();
StringBuilder sb = new StringBuilder();
if (componentType instanceof Class)
sb.append(((Class)componentType).getName() );
else
sb.append(componentType.toString());
sb.append("[]");
return sb.toString();
}
@Override
public boolean equals(Object o) {
if (o instanceof GenericArrayType) {
GenericArrayType that = (GenericArrayType) o;
return Objects.equals(genericComponentType, that.getGenericComponentType());
} else
return false;
}
@Override
public int hashCode() {
return Objects.hashCode(genericComponentType);
}
}

View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.generics.reflectiveObjects;
import sun.reflect.generics.factory.GenericsFactory;
import sun.reflect.generics.visitor.Reifier;
/**
* Common infrastructure for things that lazily generate reflective generics
* objects.
* <p> In all these cases, one needs produce a visitor that will, on demand,
* traverse the stored AST(s) and reify them into reflective objects.
* The visitor needs to be initialized with a factory, which will be
* provided when the instance is initialized.
* The factory should be cached.
*
*/
public abstract class LazyReflectiveObjectGenerator {
private final GenericsFactory factory; // cached factory
protected LazyReflectiveObjectGenerator(GenericsFactory f) {
factory = f;
}
// accessor for factory
private GenericsFactory getFactory() {
return factory;
}
// produce a reifying visitor (could this be typed as a TypeTreeVisitor?
protected Reifier getReifier(){return Reifier.make(getFactory());}
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.generics.reflectiveObjects;
/** Temporary class used to indicate missing functionality */
public class NotImplementedException extends RuntimeException {
private static final long serialVersionUID = -9177857708926624790L;
}

View File

@@ -0,0 +1,242 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.generics.reflectiveObjects;
import sun.reflect.generics.tree.FieldTypeSignature;
import java.lang.reflect.MalformedParameterizedTypeException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.Arrays;
import java.util.Objects;
/** Implementing class for ParameterizedType interface. */
public class ParameterizedTypeImpl implements ParameterizedType {
private final Type[] actualTypeArguments;
private final Class<?> rawType;
private final Type ownerType;
private ParameterizedTypeImpl(Class<?> rawType,
Type[] actualTypeArguments,
Type ownerType) {
this.actualTypeArguments = actualTypeArguments;
this.rawType = rawType;
this.ownerType = (ownerType != null) ? ownerType : rawType.getDeclaringClass();
validateConstructorArguments();
}
private void validateConstructorArguments() {
TypeVariable<?>[] formals = rawType.getTypeParameters();
// check correct arity of actual type args
if (formals.length != actualTypeArguments.length){
throw new MalformedParameterizedTypeException();
}
for (int i = 0; i < actualTypeArguments.length; i++) {
// check actuals against formals' bounds
}
}
/**
* Static factory. Given a (generic) class, actual type arguments
* and an owner type, creates a parameterized type.
* This class can be instantiated with a a raw type that does not
* represent a generic type, provided the list of actual type
* arguments is empty.
* If the ownerType argument is null, the declaring class of the
* raw type is used as the owner type.
* <p> This method throws a MalformedParameterizedTypeException
* under the following circumstances:
* If the number of actual type arguments (i.e., the size of the
* array <tt>typeArgs</tt>) does not correspond to the number of
* formal type arguments.
* If any of the actual type arguments is not an instance of the
* bounds on the corresponding formal.
* @param rawType the Class representing the generic type declaration being
* instantiated
* @param actualTypeArguments - a (possibly empty) array of types
* representing the actual type arguments to the parameterized type
* @param ownerType - the enclosing type, if known.
* @return An instance of <tt>ParameterizedType</tt>
* @throws MalformedParameterizedTypeException - if the instantiation
* is invalid
*/
public static ParameterizedTypeImpl make(Class<?> rawType,
Type[] actualTypeArguments,
Type ownerType) {
return new ParameterizedTypeImpl(rawType, actualTypeArguments,
ownerType);
}
/**
* Returns an array of <tt>Type</tt> objects representing the actual type
* arguments to this type.
*
* <p>Note that in some cases, the returned array be empty. This can occur
* if this type represents a non-parameterized type nested within
* a parameterized type.
*
* @return an array of <tt>Type</tt> objects representing the actual type
* arguments to this type
* @throws <tt>TypeNotPresentException</tt> if any of the
* actual type arguments refers to a non-existent type declaration
* @throws <tt>MalformedParameterizedTypeException</tt> if any of the
* actual type parameters refer to a parameterized type that cannot
* be instantiated for any reason
* @since 1.5
*/
public Type[] getActualTypeArguments() {
return actualTypeArguments.clone();
}
/**
* Returns the <tt>Type</tt> object representing the class or interface
* that declared this type.
*
* @return the <tt>Type</tt> object representing the class or interface
* that declared this type
*/
public Class<?> getRawType() {
return rawType;
}
/**
* Returns a <tt>Type</tt> object representing the type that this type
* is a member of. For example, if this type is <tt>O<T>.I<S></tt>,
* return a representation of <tt>O<T></tt>.
*
* <p>If this type is a top-level type, <tt>null</tt> is returned.
*
* @return a <tt>Type</tt> object representing the type that
* this type is a member of. If this type is a top-level type,
* <tt>null</tt> is returned
* @throws <tt>TypeNotPresentException</tt> if the owner type
* refers to a non-existent type declaration
* @throws <tt>MalformedParameterizedTypeException</tt> if the owner type
* refers to a parameterized type that cannot be instantiated
* for any reason
*
*/
public Type getOwnerType() {
return ownerType;
}
/*
* From the JavaDoc for java.lang.reflect.ParameterizedType
* "Instances of classes that implement this interface must
* implement an equals() method that equates any two instances
* that share the same generic type declaration and have equal
* type parameters."
*/
@Override
public boolean equals(Object o) {
if (o instanceof ParameterizedType) {
// Check that information is equivalent
ParameterizedType that = (ParameterizedType) o;
if (this == that)
return true;
Type thatOwner = that.getOwnerType();
Type thatRawType = that.getRawType();
if (false) { // Debugging
boolean ownerEquality = (ownerType == null ?
thatOwner == null :
ownerType.equals(thatOwner));
boolean rawEquality = (rawType == null ?
thatRawType == null :
rawType.equals(thatRawType));
boolean typeArgEquality = Arrays.equals(actualTypeArguments, // avoid clone
that.getActualTypeArguments());
for (Type t : actualTypeArguments) {
System.out.printf("\t\t%s%s%n", t, t.getClass());
}
System.out.printf("\towner %s\traw %s\ttypeArg %s%n",
ownerEquality, rawEquality, typeArgEquality);
return ownerEquality && rawEquality && typeArgEquality;
}
return
Objects.equals(ownerType, thatOwner) &&
Objects.equals(rawType, thatRawType) &&
Arrays.equals(actualTypeArguments, // avoid clone
that.getActualTypeArguments());
} else
return false;
}
@Override
public int hashCode() {
return
Arrays.hashCode(actualTypeArguments) ^
Objects.hashCode(ownerType) ^
Objects.hashCode(rawType);
}
public String toString() {
StringBuilder sb = new StringBuilder();
if (ownerType != null) {
if (ownerType instanceof Class)
sb.append(((Class)ownerType).getName());
else
sb.append(ownerType.toString());
sb.append("$");
if (ownerType instanceof ParameterizedTypeImpl) {
// Find simple name of nested type by removing the
// shared prefix with owner.
sb.append(rawType.getName().replace( ((ParameterizedTypeImpl)ownerType).rawType.getName() + "$",
""));
} else
sb.append(rawType.getSimpleName());
} else
sb.append(rawType.getName());
if (actualTypeArguments != null &&
actualTypeArguments.length > 0) {
sb.append("<");
boolean first = true;
for(Type t: actualTypeArguments) {
if (!first)
sb.append(", ");
sb.append(t.getTypeName());
first = false;
}
sb.append(">");
}
return sb.toString();
}
}

View File

@@ -0,0 +1,272 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.generics.reflectiveObjects;
import java.lang.annotation.*;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import sun.reflect.annotation.AnnotationSupport;
import sun.reflect.annotation.TypeAnnotationParser;
import sun.reflect.annotation.AnnotationType;
import sun.reflect.generics.factory.GenericsFactory;
import sun.reflect.generics.tree.FieldTypeSignature;
import sun.reflect.generics.visitor.Reifier;
import sun.reflect.misc.ReflectUtil;
/**
* Implementation of <tt>java.lang.reflect.TypeVariable</tt> interface
* for core reflection.
*/
public class TypeVariableImpl<D extends GenericDeclaration>
extends LazyReflectiveObjectGenerator implements TypeVariable<D> {
D genericDeclaration;
private String name;
// upper bounds - evaluated lazily
private Type[] bounds;
// The ASTs for the bounds. We are required to evaluate the bounds
// lazily, so we store these at least until we are first asked
// for the bounds. This also neatly solves the
// problem with F-bounds - you can't reify them before the formal
// is defined.
private FieldTypeSignature[] boundASTs;
// constructor is private to enforce access through static factory
private TypeVariableImpl(D decl, String n, FieldTypeSignature[] bs,
GenericsFactory f) {
super(f);
genericDeclaration = decl;
name = n;
boundASTs = bs;
}
// Accessors
// accessor for ASTs for bounds. Must not be called after
// bounds have been evaluated, because we might throw the ASTs
// away (but that is not thread-safe, is it?)
private FieldTypeSignature[] getBoundASTs() {
// check that bounds were not evaluated yet
assert(bounds == null);
return boundASTs;
}
/**
* Factory method.
* @param decl - the reflective object that declared the type variable
* that this method should create
* @param name - the name of the type variable to be returned
* @param bs - an array of ASTs representing the bounds for the type
* variable to be created
* @param f - a factory that can be used to manufacture reflective
* objects that represent the bounds of this type variable
* @return A type variable with name, bounds, declaration and factory
* specified
*/
public static <T extends GenericDeclaration>
TypeVariableImpl<T> make(T decl, String name,
FieldTypeSignature[] bs,
GenericsFactory f) {
if (!((decl instanceof Class) ||
(decl instanceof Method) ||
(decl instanceof Constructor))) {
throw new AssertionError("Unexpected kind of GenericDeclaration" +
decl.getClass().toString());
}
return new TypeVariableImpl<T>(decl, name, bs, f);
}
/**
* Returns an array of <tt>Type</tt> objects representing the
* upper bound(s) of this type variable. Note that if no upper bound is
* explicitly declared, the upper bound is <tt>Object</tt>.
*
* <p>For each upper bound B:
* <ul>
* <li>if B is a parameterized type or a type variable, it is created,
* (see {@link #ParameterizedType} for the details of the creation
* process for parameterized types).
* <li>Otherwise, B is resolved.
* </ul>
*
* @throws <tt>TypeNotPresentException</tt> if any of the
* bounds refers to a non-existent type declaration
* @throws <tt>MalformedParameterizedTypeException</tt> if any of the
* bounds refer to a parameterized type that cannot be instantiated
* for any reason
* @return an array of Types representing the upper bound(s) of this
* type variable
*/
public Type[] getBounds() {
// lazily initialize bounds if necessary
if (bounds == null) {
FieldTypeSignature[] fts = getBoundASTs(); // get AST
// allocate result array; note that
// keeping ts and bounds separate helps with threads
Type[] ts = new Type[fts.length];
// iterate over bound trees, reifying each in turn
for ( int j = 0; j < fts.length; j++) {
Reifier r = getReifier();
fts[j].accept(r);
ts[j] = r.getResult();
}
// cache result
bounds = ts;
// could throw away bound ASTs here; thread safety?
}
return bounds.clone(); // return cached bounds
}
/**
* Returns the <tt>GenericDeclaration</tt> object representing the
* generic declaration that declared this type variable.
*
* @return the generic declaration that declared this type variable.
*
* @since 1.5
*/
public D getGenericDeclaration(){
if (genericDeclaration instanceof Class)
ReflectUtil.checkPackageAccess((Class)genericDeclaration);
else if ((genericDeclaration instanceof Method) ||
(genericDeclaration instanceof Constructor))
ReflectUtil.conservativeCheckMemberAccess((Member)genericDeclaration);
else
throw new AssertionError("Unexpected kind of GenericDeclaration");
return genericDeclaration;
}
/**
* Returns the name of this type variable, as it occurs in the source code.
*
* @return the name of this type variable, as it appears in the source code
*/
public String getName() { return name; }
public String toString() {return getName();}
@Override
public boolean equals(Object o) {
if (o instanceof TypeVariable &&
o.getClass() == TypeVariableImpl.class) {
TypeVariable<?> that = (TypeVariable<?>) o;
GenericDeclaration thatDecl = that.getGenericDeclaration();
String thatName = that.getName();
return Objects.equals(genericDeclaration, thatDecl) &&
Objects.equals(name, thatName);
} else
return false;
}
@Override
public int hashCode() {
return genericDeclaration.hashCode() ^ name.hashCode();
}
// Implementations of AnnotatedElement methods.
@SuppressWarnings("unchecked")
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
Objects.requireNonNull(annotationClass);
// T is an Annotation type, the return value of get will be an annotation
return (T)mapAnnotations(getAnnotations()).get(annotationClass);
}
public <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) {
Objects.requireNonNull(annotationClass);
return getAnnotation(annotationClass);
}
@Override
public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
Objects.requireNonNull(annotationClass);
return AnnotationSupport.getDirectlyAndIndirectlyPresent(mapAnnotations(getAnnotations()), annotationClass);
}
@Override
public <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) {
Objects.requireNonNull(annotationClass);
return getAnnotationsByType(annotationClass);
}
public Annotation[] getAnnotations() {
int myIndex = typeVarIndex();
if (myIndex < 0)
throw new AssertionError("Index must be non-negative.");
return TypeAnnotationParser.parseTypeVariableAnnotations(getGenericDeclaration(), myIndex);
}
public Annotation[] getDeclaredAnnotations() {
return getAnnotations();
}
public AnnotatedType[] getAnnotatedBounds() {
return TypeAnnotationParser.parseAnnotatedBounds(getBounds(),
getGenericDeclaration(),
typeVarIndex());
}
private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0];
// Helpers for annotation methods
private int typeVarIndex() {
TypeVariable<?>[] tVars = getGenericDeclaration().getTypeParameters();
int i = -1;
for (TypeVariable<?> v : tVars) {
i++;
if (equals(v))
return i;
}
return -1;
}
private static Map<Class<? extends Annotation>, Annotation> mapAnnotations(Annotation[] annos) {
Map<Class<? extends Annotation>, Annotation> result =
new LinkedHashMap<>();
for (Annotation a : annos) {
Class<? extends Annotation> klass = a.annotationType();
AnnotationType type = AnnotationType.getInstance(klass);
if (type.retention() == RetentionPolicy.RUNTIME)
if (result.put(klass, a) != null)
throw new AnnotationFormatError("Duplicate annotation for class: "+klass+": " + a);
}
return result;
}
}

View File

@@ -0,0 +1,231 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.generics.reflectiveObjects;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import sun.reflect.generics.factory.GenericsFactory;
import sun.reflect.generics.tree.FieldTypeSignature;
import sun.reflect.generics.visitor.Reifier;
import java.util.Arrays;
/**
* Implementation of WildcardType interface for core reflection.
*/
public class WildcardTypeImpl extends LazyReflectiveObjectGenerator
implements WildcardType {
// upper bounds - evaluated lazily
private Type[] upperBounds;
// lower bounds - evaluated lazily
private Type[] lowerBounds;
// The ASTs for the bounds. We are required to evaluate the bounds
// lazily, so we store these at least until we are first asked
// for the bounds. This also neatly solves the
// problem with F-bounds - you can't reify them before the formal
// is defined.
private FieldTypeSignature[] upperBoundASTs;
private FieldTypeSignature[] lowerBoundASTs;
// constructor is private to enforce access through static factory
private WildcardTypeImpl(FieldTypeSignature[] ubs,
FieldTypeSignature[] lbs,
GenericsFactory f) {
super(f);
upperBoundASTs = ubs;
lowerBoundASTs = lbs;
}
/**
* Factory method.
* @param ubs - an array of ASTs representing the upper bounds for the type
* variable to be created
* @param lbs - an array of ASTs representing the lower bounds for the type
* variable to be created
* @param f - a factory that can be used to manufacture reflective
* objects that represent the bounds of this wildcard type
* @return a wild card type with the requested bounds and factory
*/
public static WildcardTypeImpl make(FieldTypeSignature[] ubs,
FieldTypeSignature[] lbs,
GenericsFactory f) {
return new WildcardTypeImpl(ubs, lbs, f);
}
// Accessors
// accessor for ASTs for upper bounds. Must not be called after upper
// bounds have been evaluated, because we might throw the ASTs
// away (but that is not thread-safe, is it?)
private FieldTypeSignature[] getUpperBoundASTs() {
// check that upper bounds were not evaluated yet
assert(upperBounds == null);
return upperBoundASTs;
}
// accessor for ASTs for lower bounds. Must not be called after lower
// bounds have been evaluated, because we might throw the ASTs
// away (but that is not thread-safe, is it?)
private FieldTypeSignature[] getLowerBoundASTs() {
// check that lower bounds were not evaluated yet
assert(lowerBounds == null);
return lowerBoundASTs;
}
/**
* Returns an array of <tt>Type</tt> objects representing the upper
* bound(s) of this type variable. Note that if no upper bound is
* explicitly declared, the upper bound is <tt>Object</tt>.
*
* <p>For each upper bound B :
* <ul>
* <li>if B is a parameterized type or a type variable, it is created,
* (see {@link #ParameterizedType} for the details of the creation
* process for parameterized types).
* <li>Otherwise, B is resolved.
* </ul>
*
* @return an array of Types representing the upper bound(s) of this
* type variable
* @throws <tt>TypeNotPresentException</tt> if any of the
* bounds refers to a non-existent type declaration
* @throws <tt>MalformedParameterizedTypeException</tt> if any of the
* bounds refer to a parameterized type that cannot be instantiated
* for any reason
*/
public Type[] getUpperBounds() {
// lazily initialize bounds if necessary
if (upperBounds == null) {
FieldTypeSignature[] fts = getUpperBoundASTs(); // get AST
// allocate result array; note that
// keeping ts and bounds separate helps with threads
Type[] ts = new Type[fts.length];
// iterate over bound trees, reifying each in turn
for ( int j = 0; j < fts.length; j++) {
Reifier r = getReifier();
fts[j].accept(r);
ts[j] = r.getResult();
}
// cache result
upperBounds = ts;
// could throw away upper bound ASTs here; thread safety?
}
return upperBounds.clone(); // return cached bounds
}
/**
* Returns an array of <tt>Type</tt> objects representing the
* lower bound(s) of this type variable. Note that if no lower bound is
* explicitly declared, the lower bound is the type of <tt>null</tt>.
* In this case, a zero length array is returned.
*
* <p>For each lower bound B :
* <ul>
* <li>if B is a parameterized type or a type variable, it is created,
* (see {@link #ParameterizedType} for the details of the creation
* process for parameterized types).
* <li>Otherwise, B is resolved.
* </ul>
*
* @return an array of Types representing the lower bound(s) of this
* type variable
* @throws <tt>TypeNotPresentException</tt> if any of the
* bounds refers to a non-existent type declaration
* @throws <tt>MalformedParameterizedTypeException</tt> if any of the
* bounds refer to a parameterized type that cannot be instantiated
* for any reason
*/
public Type[] getLowerBounds() {
// lazily initialize bounds if necessary
if (lowerBounds == null) {
FieldTypeSignature[] fts = getLowerBoundASTs(); // get AST
// allocate result array; note that
// keeping ts and bounds separate helps with threads
Type[] ts = new Type[fts.length];
// iterate over bound trees, reifying each in turn
for ( int j = 0; j < fts.length; j++) {
Reifier r = getReifier();
fts[j].accept(r);
ts[j] = r.getResult();
}
// cache result
lowerBounds = ts;
// could throw away lower bound ASTs here; thread safety?
}
return lowerBounds.clone(); // return cached bounds
}
public String toString() {
Type[] lowerBounds = getLowerBounds();
Type[] bounds = lowerBounds;
StringBuilder sb = new StringBuilder();
if (lowerBounds.length > 0)
sb.append("? super ");
else {
Type[] upperBounds = getUpperBounds();
if (upperBounds.length > 0 && !upperBounds[0].equals(Object.class) ) {
bounds = upperBounds;
sb.append("? extends ");
} else
return "?";
}
assert bounds.length > 0;
boolean first = true;
for(Type bound: bounds) {
if (!first)
sb.append(" & ");
first = false;
sb.append(bound.getTypeName());
}
return sb.toString();
}
@Override
public boolean equals(Object o) {
if (o instanceof WildcardType) {
WildcardType that = (WildcardType) o;
return
Arrays.equals(this.getLowerBounds(),
that.getLowerBounds()) &&
Arrays.equals(this.getUpperBounds(),
that.getUpperBounds());
} else
return false;
}
@Override
public int hashCode() {
Type [] lowerBounds = getLowerBounds();
Type [] upperBounds = getUpperBounds();
return Arrays.hashCode(lowerBounds) ^ Arrays.hashCode(upperBounds);
}
}

View File

@@ -0,0 +1,85 @@
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.generics.repository;
import sun.reflect.generics.factory.GenericsFactory;
import sun.reflect.generics.tree.Tree;
import sun.reflect.generics.visitor.Reifier;
/**
* Abstract superclass for representing the generic type information for
* a reflective entity.
* The code is not dependent on a particular reflective implementation.
* It is designed to be used unchanged by at least core reflection and JDI.
*/
public abstract class AbstractRepository<T extends Tree> {
// A factory used to produce reflective objects. Provided when the
//repository is created. Will vary across implementations.
private final GenericsFactory factory;
private final T tree; // the AST for the generic type info
//accessors
private GenericsFactory getFactory() { return factory;}
/**
* Accessor for <tt>tree</tt>.
* @return the cached AST this repository holds
*/
protected T getTree(){ return tree;}
/**
* Returns a <tt>Reifier</tt> used to convert parts of the
* AST into reflective objects.
* @return a <tt>Reifier</tt> used to convert parts of the
* AST into reflective objects
*/
protected Reifier getReifier(){return Reifier.make(getFactory());}
/**
* Constructor. Should only be used by subclasses. Concrete subclasses
* should make their constructors private and provide public factory
* methods.
* @param rawSig - the generic signature of the reflective object
* that this repository is servicing
* @param f - a factory that will provide instances of reflective
* objects when this repository converts its AST
*/
protected AbstractRepository(String rawSig, GenericsFactory f) {
tree = parse(rawSig);
factory = f;
}
/**
* Returns the AST for the genric type info of this entity.
* @param s - a string representing the generic signature of this
* entity
* @return the AST for the generic type info of this entity.
*/
protected abstract T parse(String s);
}

View File

@@ -0,0 +1,116 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.generics.repository;
import sun.reflect.generics.factory.GenericsFactory;
import sun.reflect.generics.tree.ClassSignature;
import sun.reflect.generics.tree.TypeTree;
import sun.reflect.generics.visitor.Reifier;
import sun.reflect.generics.parser.SignatureParser;
import java.lang.reflect.Type;
/**
* This class represents the generic type information for a class.
* The code is not dependent on a particular reflective implementation.
* It is designed to be used unchanged by at least core reflection and JDI.
*/
public class ClassRepository extends GenericDeclRepository<ClassSignature> {
public static final ClassRepository NONE = ClassRepository.make("Ljava/lang/Object;", null);
/** The generic superclass info. Lazily initialized. */
private volatile Type superclass;
/** The generic superinterface info. Lazily initialized. */
private volatile Type[] superInterfaces;
// private, to enforce use of static factory
private ClassRepository(String rawSig, GenericsFactory f) {
super(rawSig, f);
}
protected ClassSignature parse(String s) {
return SignatureParser.make().parseClassSig(s);
}
/**
* Static factory method.
* @param rawSig - the generic signature of the reflective object
* that this repository is servicing
* @param f - a factory that will provide instances of reflective
* objects when this repository converts its AST
* @return a <tt>ClassRepository</tt> that manages the generic type
* information represented in the signature <tt>rawSig</tt>
*/
public static ClassRepository make(String rawSig, GenericsFactory f) {
return new ClassRepository(rawSig, f);
}
// public API
/*
* When queried for a particular piece of type information, the
* general pattern is to consult the corresponding cached value.
* If the corresponding field is non-null, it is returned.
* If not, it is created lazily. This is done by selecting the appropriate
* part of the tree and transforming it into a reflective object
* using a visitor.
* a visitor, which is created by feeding it the factory
* with which the repository was created.
*/
public Type getSuperclass() {
Type superclass = this.superclass;
if (superclass == null) { // lazily initialize superclass
Reifier r = getReifier(); // obtain visitor
// Extract superclass subtree from AST and reify
getTree().getSuperclass().accept(r);
// extract result from visitor and cache it
superclass = r.getResult();
this.superclass = superclass;
}
return superclass; // return cached result
}
public Type[] getSuperInterfaces() {
Type[] superInterfaces = this.superInterfaces;
if (superInterfaces == null) { // lazily initialize super interfaces
// first, extract super interface subtree(s) from AST
TypeTree[] ts = getTree().getSuperInterfaces();
// create array to store reified subtree(s)
superInterfaces = new Type[ts.length];
// reify all subtrees
for (int i = 0; i < ts.length; i++) {
Reifier r = getReifier(); // obtain visitor
ts[i].accept(r);// reify subtree
// extract result from visitor and store it
superInterfaces[i] = r.getResult();
}
this.superInterfaces = superInterfaces;
}
return superInterfaces.clone(); // return cached result
}
}

View File

@@ -0,0 +1,120 @@
/*
* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.generics.repository;
import java.lang.reflect.Type;
import sun.reflect.generics.factory.GenericsFactory;
import sun.reflect.generics.parser.SignatureParser;
import sun.reflect.generics.tree.FieldTypeSignature;
import sun.reflect.generics.tree.MethodTypeSignature;
import sun.reflect.generics.tree.TypeSignature;
import sun.reflect.generics.visitor.Reifier;
/**
* This class represents the generic type information for a constructor.
* The code is not dependent on a particular reflective implementation.
* It is designed to be used unchanged by at least core reflection and JDI.
*/
public class ConstructorRepository
extends GenericDeclRepository<MethodTypeSignature> {
private Type[] paramTypes; // caches the generic parameter types info
private Type[] exceptionTypes; // caches the generic exception types info
// protected, to enforce use of static factory yet allow subclassing
protected ConstructorRepository(String rawSig, GenericsFactory f) {
super(rawSig, f);
}
protected MethodTypeSignature parse(String s) {
return SignatureParser.make().parseMethodSig(s);
}
/**
* Static factory method.
* @param rawSig - the generic signature of the reflective object
* that this repository is servicing
* @param f - a factory that will provide instances of reflective
* objects when this repository converts its AST
* @return a <tt>ConstructorRepository</tt> that manages the generic type
* information represented in the signature <tt>rawSig</tt>
*/
public static ConstructorRepository make(String rawSig,
GenericsFactory f) {
return new ConstructorRepository(rawSig, f);
}
// public API
/*
* When queried for a particular piece of type information, the
* general pattern is to consult the corresponding cached value.
* If the corresponding field is non-null, it is returned.
* If not, it is created lazily. This is done by selecting the appropriate
* part of the tree and transforming it into a reflective object
* using a visitor.
* a visitor, which is created by feeding it the factory
* with which the repository was created.
*/
public Type[] getParameterTypes(){
if (paramTypes == null) { // lazily initialize parameter types
// first, extract parameter type subtree(s) from AST
TypeSignature[] pts = getTree().getParameterTypes();
// create array to store reified subtree(s)
Type[] ps = new Type[pts.length];
// reify all subtrees
for (int i = 0; i < pts.length; i++) {
Reifier r = getReifier(); // obtain visitor
pts[i].accept(r); // reify subtree
// extract result from visitor and store it
ps[i] = r.getResult();
}
paramTypes = ps; // cache overall result
}
return paramTypes.clone(); // return cached result
}
public Type[] getExceptionTypes(){
if (exceptionTypes == null) { // lazily initialize exception types
// first, extract exception type subtree(s) from AST
FieldTypeSignature[] ets = getTree().getExceptionTypes();
// create array to store reified subtree(s)
Type[] es = new Type[ets.length];
// reify all subtrees
for (int i = 0; i < ets.length; i++) {
Reifier r = getReifier(); // obtain visitor
ets[i].accept(r); // reify subtree
// extract result from visitor and store it
es[i] = r.getResult();
}
exceptionTypes = es; // cache overall result
}
return exceptionTypes.clone(); // return cached result
}
}

View File

@@ -0,0 +1,91 @@
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.generics.repository;
import java.lang.reflect.Type;
import sun.reflect.generics.factory.GenericsFactory;
import sun.reflect.generics.tree.TypeSignature;
import sun.reflect.generics.parser.SignatureParser;
import sun.reflect.generics.visitor.Reifier;
/**
* This class represents the generic type information for a constructor.
* The code is not dependent on a particular reflective implementation.
* It is designed to be used unchanged by at least core reflection and JDI.
*/
public class FieldRepository extends AbstractRepository<TypeSignature> {
private Type genericType; // caches the generic type info
// protected, to enforce use of static factory yet allow subclassing
protected FieldRepository(String rawSig, GenericsFactory f) {
super(rawSig, f);
}
protected TypeSignature parse(String s) {
return SignatureParser.make().parseTypeSig(s);
}
/**
* Static factory method.
* @param rawSig - the generic signature of the reflective object
* that this repository is servicing
* @param f - a factory that will provide instances of reflective
* objects when this repository converts its AST
* @return a <tt>FieldRepository</tt> that manages the generic type
* information represented in the signature <tt>rawSig</tt>
*/
public static FieldRepository make(String rawSig,
GenericsFactory f) {
return new FieldRepository(rawSig, f);
}
// public API
/*
* When queried for a particular piece of type information, the
* general pattern is to consult the corresponding cached value.
* If the corresponding field is non-null, it is returned.
* If not, it is created lazily. This is done by selecting the appropriate
* part of the tree and transforming it into a reflective object
* using a visitor.
* a visitor, which is created by feeding it the factory
* with which the repository was created.
*/
public Type getGenericType(){
if (genericType == null) { // lazily initialize generic type
Reifier r = getReifier(); // obtain visitor
getTree().accept(r); // reify subtree
// extract result from visitor and cache it
genericType = r.getResult();
}
return genericType; // return cached result
}
}

View File

@@ -0,0 +1,85 @@
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.generics.repository;
import java.lang.reflect.TypeVariable;
import sun.reflect.generics.factory.GenericsFactory;
import sun.reflect.generics.tree.FormalTypeParameter;
import sun.reflect.generics.tree.Signature;
import sun.reflect.generics.visitor.Reifier;
/**
* This class represents the generic type information for a generic
* declaration.
* The code is not dependent on a particular reflective implementation.
* It is designed to be used unchanged by at least core reflection and JDI.
*/
public abstract class GenericDeclRepository<S extends Signature>
extends AbstractRepository<S> {
/** The formal type parameters. Lazily initialized. */
private volatile TypeVariable<?>[] typeParams;
protected GenericDeclRepository(String rawSig, GenericsFactory f) {
super(rawSig, f);
}
// public API
/*
* When queried for a particular piece of type information, the
* general pattern is to consult the corresponding cached value.
* If the corresponding field is non-null, it is returned.
* If not, it is created lazily. This is done by selecting the appropriate
* part of the tree and transforming it into a reflective object
* using a visitor, which is created by feeding it the factory
* with which the repository was created.
*/
/**
* Return the formal type parameters of this generic declaration.
* @return the formal type parameters of this generic declaration
*/
public TypeVariable<?>[] getTypeParameters() {
TypeVariable<?>[] typeParams = this.typeParams;
if (typeParams == null) { // lazily initialize type parameters
// first, extract type parameter subtree(s) from AST
FormalTypeParameter[] ftps = getTree().getFormalTypeParameters();
// create array to store reified subtree(s)
typeParams = new TypeVariable<?>[ftps.length];
// reify all subtrees
for (int i = 0; i < ftps.length; i++) {
Reifier r = getReifier(); // obtain visitor
ftps[i].accept(r); // reify subtree
// extract result from visitor and store it
typeParams[i] = (TypeVariable<?>) r.getResult();
}
this.typeParams = typeParams; // cache overall result
}
return typeParams.clone(); // return cached result
}
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.generics.repository;
import java.lang.reflect.Type;
import sun.reflect.generics.factory.GenericsFactory;
import sun.reflect.generics.visitor.Reifier;
/**
* This class represents the generic type information for a method.
* The code is not dependent on a particular reflective implementation.
* It is designed to be used unchanged by at least core reflection and JDI.
*/
public class MethodRepository extends ConstructorRepository {
private Type returnType; // caches the generic return type info
// private, to enforce use of static factory
private MethodRepository(String rawSig, GenericsFactory f) {
super(rawSig, f);
}
/**
* Static factory method.
* @param rawSig - the generic signature of the reflective object
* that this repository is servicing
* @param f - a factory that will provide instances of reflective
* objects when this repository converts its AST
* @return a <tt>MethodRepository</tt> that manages the generic type
* information represented in the signature <tt>rawSig</tt>
*/
public static MethodRepository make(String rawSig, GenericsFactory f) {
return new MethodRepository(rawSig, f);
}
// public API
public Type getReturnType() {
if (returnType == null) { // lazily initialize return type
Reifier r = getReifier(); // obtain visitor
// Extract return type subtree from AST and reify
getTree().getReturnType().accept(r);
// extract result from visitor and cache it
returnType = r.getResult();
}
return returnType; // return cached result
}
}

View File

@@ -0,0 +1,98 @@
/*
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.generics.scope;
import java.lang.reflect.GenericDeclaration;
import java.lang.reflect.TypeVariable;
/**
* Abstract superclass for lazy scope objects, used when building
* factories for generic information repositories.
* The type parameter <tt>D</tt> represents the type of reflective
* object whose scope this class is representing.
* <p> To subclass this, all one needs to do is implement
* <tt>computeEnclosingScope</tt> and the subclass' constructor.
*/
public abstract class AbstractScope<D extends GenericDeclaration>
implements Scope {
private final D recvr; // the declaration whose scope this instance represents
/** The enclosing scope of this scope. Lazily initialized. */
private volatile Scope enclosingScope;
/**
* Constructor. Takes a reflective object whose scope the newly
* constructed instance will represent.
* @param D - A generic declaration whose scope the newly
* constructed instance will represent
*/
protected AbstractScope(D decl){ recvr = decl;}
/**
* Accessor for the receiver - the object whose scope this <tt>Scope</tt>
* object represents.
* @return The object whose scope this <tt>Scope</tt> object represents
*/
protected D getRecvr() {return recvr;}
/** This method must be implemented by any concrete subclass.
* It must return the enclosing scope of this scope. If this scope
* is a top-level scope, an instance of DummyScope must be returned.
* @return The enclosing scope of this scope
*/
protected abstract Scope computeEnclosingScope();
/**
* Accessor for the enclosing scope, which is computed lazily and cached.
* @return the enclosing scope
*/
protected Scope getEnclosingScope(){
Scope enclosingScope = this.enclosingScope;
if (enclosingScope == null) {
enclosingScope = computeEnclosingScope();
this.enclosingScope = enclosingScope;
}
return enclosingScope;
}
/**
* Lookup a type variable in the scope, using its name. Returns null if
* no type variable with this name is declared in this scope or any of its
* surrounding scopes.
* @param name - the name of the type variable being looked up
* @return the requested type variable, if found
*/
public TypeVariable<?> lookup(String name) {
TypeVariable<?>[] tas = getRecvr().getTypeParameters();
for (TypeVariable<?> tv : tas) {
if (tv.getName().equals(name)) {return tv;}
}
return getEnclosingScope().lookup(name);
}
}

View File

@@ -0,0 +1,83 @@
/*
* Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.reflect.generics.scope;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
/**
* This class represents the scope containing the type variables of
* a class.
*/
public class ClassScope extends AbstractScope<Class<?>> implements Scope {
// constructor is private to enforce use of factory method
private ClassScope(Class<?> c){
super(c);
}
/**
* Overrides the abstract method in the superclass.
* @return the enclosing scope
*/
protected Scope computeEnclosingScope() {
Class<?> receiver = getRecvr();
Method m = receiver.getEnclosingMethod();
if (m != null)
// Receiver is a local or anonymous class enclosed in a
// method.
return MethodScope.make(m);
Constructor<?> cnstr = receiver.getEnclosingConstructor();
if (cnstr != null)
// Receiver is a local or anonymous class enclosed in a
// constructor.
return ConstructorScope.make(cnstr);
Class<?> c = receiver.getEnclosingClass();
// if there is a declaring class, recvr is a member class
// and its enclosing scope is that of the declaring class
if (c != null)
// Receiver is a local class, an anonymous class, or a
// member class (static or not).
return ClassScope.make(c);
// otherwise, recvr is a top level class, and it has no real
// enclosing scope.
return DummyScope.make();
}
/**
* Factory method. Takes a <tt>Class</tt> object and creates a
* scope for it.
* @param c - a Class whose scope we want to obtain
* @return The type-variable scope for the class c
*/
public static ClassScope make(Class<?> c) { return new ClassScope(c);}
}

Some files were not shown because too many files have changed in this diff Show More