feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
716
jdkSrc/jdk8/sun/reflect/AccessorGenerator.java
Normal file
716
jdkSrc/jdk8/sun/reflect/AccessorGenerator.java
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
37
jdkSrc/jdk8/sun/reflect/ByteVector.java
Normal file
37
jdkSrc/jdk8/sun/reflect/ByteVector.java
Normal 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();
|
||||
}
|
||||
36
jdkSrc/jdk8/sun/reflect/ByteVectorFactory.java
Normal file
36
jdkSrc/jdk8/sun/reflect/ByteVectorFactory.java
Normal 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);
|
||||
}
|
||||
}
|
||||
88
jdkSrc/jdk8/sun/reflect/ByteVectorImpl.java
Normal file
88
jdkSrc/jdk8/sun/reflect/ByteVectorImpl.java
Normal 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;
|
||||
}
|
||||
}
|
||||
41
jdkSrc/jdk8/sun/reflect/CallerSensitive.java
Normal file
41
jdkSrc/jdk8/sun/reflect/CallerSensitive.java
Normal 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 {
|
||||
}
|
||||
74
jdkSrc/jdk8/sun/reflect/ClassDefiner.java
Normal file
74
jdkSrc/jdk8/sun/reflect/ClassDefiner.java
Normal 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);
|
||||
}
|
||||
}
|
||||
671
jdkSrc/jdk8/sun/reflect/ClassFileAssembler.java
Normal file
671
jdkSrc/jdk8/sun/reflect/ClassFileAssembler.java
Normal 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);
|
||||
}
|
||||
}
|
||||
140
jdkSrc/jdk8/sun/reflect/ClassFileConstants.java
Normal file
140
jdkSrc/jdk8/sun/reflect/ClassFileConstants.java
Normal 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;
|
||||
}
|
||||
80
jdkSrc/jdk8/sun/reflect/ConstantPool.java
Normal file
80
jdkSrc/jdk8/sun/reflect/ConstantPool.java
Normal 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);
|
||||
}
|
||||
41
jdkSrc/jdk8/sun/reflect/ConstructorAccessor.java
Normal file
41
jdkSrc/jdk8/sun/reflect/ConstructorAccessor.java
Normal 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;
|
||||
}
|
||||
41
jdkSrc/jdk8/sun/reflect/ConstructorAccessorImpl.java
Normal file
41
jdkSrc/jdk8/sun/reflect/ConstructorAccessorImpl.java
Normal 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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
49
jdkSrc/jdk8/sun/reflect/DelegatingMethodAccessorImpl.java
Normal file
49
jdkSrc/jdk8/sun/reflect/DelegatingMethodAccessorImpl.java
Normal 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;
|
||||
}
|
||||
}
|
||||
96
jdkSrc/jdk8/sun/reflect/FieldAccessor.java
Normal file
96
jdkSrc/jdk8/sun/reflect/FieldAccessor.java
Normal 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;
|
||||
}
|
||||
105
jdkSrc/jdk8/sun/reflect/FieldAccessorImpl.java
Normal file
105
jdkSrc/jdk8/sun/reflect/FieldAccessorImpl.java
Normal 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;
|
||||
}
|
||||
71
jdkSrc/jdk8/sun/reflect/FieldInfo.java
Normal file
71
jdkSrc/jdk8/sun/reflect/FieldInfo.java
Normal 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()));
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
76
jdkSrc/jdk8/sun/reflect/Label.java
Normal file
76
jdkSrc/jdk8/sun/reflect/Label.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
112
jdkSrc/jdk8/sun/reflect/LangReflectAccess.java
Normal file
112
jdkSrc/jdk8/sun/reflect/LangReflectAccess.java
Normal 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);
|
||||
}
|
||||
47
jdkSrc/jdk8/sun/reflect/MagicAccessorImpl.java
Normal file
47
jdkSrc/jdk8/sun/reflect/MagicAccessorImpl.java
Normal 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 {
|
||||
}
|
||||
40
jdkSrc/jdk8/sun/reflect/MethodAccessor.java
Normal file
40
jdkSrc/jdk8/sun/reflect/MethodAccessor.java
Normal 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;
|
||||
}
|
||||
780
jdkSrc/jdk8/sun/reflect/MethodAccessorGenerator.java
Normal file
780
jdkSrc/jdk8/sun/reflect/MethodAccessorGenerator.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
48
jdkSrc/jdk8/sun/reflect/MethodAccessorImpl.java
Normal file
48
jdkSrc/jdk8/sun/reflect/MethodAccessorImpl.java
Normal 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;
|
||||
}
|
||||
73
jdkSrc/jdk8/sun/reflect/NativeConstructorAccessorImpl.java
Normal file
73
jdkSrc/jdk8/sun/reflect/NativeConstructorAccessorImpl.java
Normal 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;
|
||||
}
|
||||
70
jdkSrc/jdk8/sun/reflect/NativeMethodAccessorImpl.java
Normal file
70
jdkSrc/jdk8/sun/reflect/NativeMethodAccessorImpl.java
Normal 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);
|
||||
}
|
||||
351
jdkSrc/jdk8/sun/reflect/Reflection.java
Normal file
351
jdkSrc/jdk8/sun/reflect/Reflection.java
Normal 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;
|
||||
}
|
||||
}
|
||||
708
jdkSrc/jdk8/sun/reflect/ReflectionFactory.java
Normal file
708
jdkSrc/jdk8/sun/reflect/ReflectionFactory.java
Normal 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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 {
|
||||
}
|
||||
81
jdkSrc/jdk8/sun/reflect/SignatureIterator.java
Normal file
81
jdkSrc/jdk8/sun/reflect/SignatureIterator.java
Normal 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());
|
||||
}
|
||||
}
|
||||
76
jdkSrc/jdk8/sun/reflect/UTF8.java
Normal file
76
jdkSrc/jdk8/sun/reflect/UTF8.java
Normal 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;
|
||||
}
|
||||
}
|
||||
140
jdkSrc/jdk8/sun/reflect/UnsafeBooleanFieldAccessorImpl.java
Normal file
140
jdkSrc/jdk8/sun/reflect/UnsafeBooleanFieldAccessorImpl.java
Normal 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);
|
||||
}
|
||||
}
|
||||
140
jdkSrc/jdk8/sun/reflect/UnsafeByteFieldAccessorImpl.java
Normal file
140
jdkSrc/jdk8/sun/reflect/UnsafeByteFieldAccessorImpl.java
Normal 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);
|
||||
}
|
||||
}
|
||||
140
jdkSrc/jdk8/sun/reflect/UnsafeCharacterFieldAccessorImpl.java
Normal file
140
jdkSrc/jdk8/sun/reflect/UnsafeCharacterFieldAccessorImpl.java
Normal 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);
|
||||
}
|
||||
}
|
||||
164
jdkSrc/jdk8/sun/reflect/UnsafeDoubleFieldAccessorImpl.java
Normal file
164
jdkSrc/jdk8/sun/reflect/UnsafeDoubleFieldAccessorImpl.java
Normal 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);
|
||||
}
|
||||
}
|
||||
130
jdkSrc/jdk8/sun/reflect/UnsafeFieldAccessorFactory.java
Normal file
130
jdkSrc/jdk8/sun/reflect/UnsafeFieldAccessorFactory.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
206
jdkSrc/jdk8/sun/reflect/UnsafeFieldAccessorImpl.java
Normal file
206
jdkSrc/jdk8/sun/reflect/UnsafeFieldAccessorImpl.java
Normal 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));
|
||||
}
|
||||
|
||||
}
|
||||
160
jdkSrc/jdk8/sun/reflect/UnsafeFloatFieldAccessorImpl.java
Normal file
160
jdkSrc/jdk8/sun/reflect/UnsafeFloatFieldAccessorImpl.java
Normal 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);
|
||||
}
|
||||
}
|
||||
152
jdkSrc/jdk8/sun/reflect/UnsafeIntegerFieldAccessorImpl.java
Normal file
152
jdkSrc/jdk8/sun/reflect/UnsafeIntegerFieldAccessorImpl.java
Normal 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);
|
||||
}
|
||||
}
|
||||
156
jdkSrc/jdk8/sun/reflect/UnsafeLongFieldAccessorImpl.java
Normal file
156
jdkSrc/jdk8/sun/reflect/UnsafeLongFieldAccessorImpl.java
Normal 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);
|
||||
}
|
||||
}
|
||||
134
jdkSrc/jdk8/sun/reflect/UnsafeObjectFieldAccessorImpl.java
Normal file
134
jdkSrc/jdk8/sun/reflect/UnsafeObjectFieldAccessorImpl.java
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
144
jdkSrc/jdk8/sun/reflect/UnsafeShortFieldAccessorImpl.java
Normal file
144
jdkSrc/jdk8/sun/reflect/UnsafeShortFieldAccessorImpl.java
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
137
jdkSrc/jdk8/sun/reflect/UnsafeStaticByteFieldAccessorImpl.java
Normal file
137
jdkSrc/jdk8/sun/reflect/UnsafeStaticByteFieldAccessorImpl.java
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
161
jdkSrc/jdk8/sun/reflect/UnsafeStaticDoubleFieldAccessorImpl.java
Normal file
161
jdkSrc/jdk8/sun/reflect/UnsafeStaticDoubleFieldAccessorImpl.java
Normal 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);
|
||||
}
|
||||
}
|
||||
52
jdkSrc/jdk8/sun/reflect/UnsafeStaticFieldAccessorImpl.java
Normal file
52
jdkSrc/jdk8/sun/reflect/UnsafeStaticFieldAccessorImpl.java
Normal 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);
|
||||
}
|
||||
}
|
||||
157
jdkSrc/jdk8/sun/reflect/UnsafeStaticFloatFieldAccessorImpl.java
Normal file
157
jdkSrc/jdk8/sun/reflect/UnsafeStaticFloatFieldAccessorImpl.java
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
153
jdkSrc/jdk8/sun/reflect/UnsafeStaticLongFieldAccessorImpl.java
Normal file
153
jdkSrc/jdk8/sun/reflect/UnsafeStaticLongFieldAccessorImpl.java
Normal 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);
|
||||
}
|
||||
}
|
||||
132
jdkSrc/jdk8/sun/reflect/UnsafeStaticObjectFieldAccessorImpl.java
Normal file
132
jdkSrc/jdk8/sun/reflect/UnsafeStaticObjectFieldAccessorImpl.java
Normal 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);
|
||||
}
|
||||
}
|
||||
141
jdkSrc/jdk8/sun/reflect/UnsafeStaticShortFieldAccessorImpl.java
Normal file
141
jdkSrc/jdk8/sun/reflect/UnsafeStaticShortFieldAccessorImpl.java
Normal 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);
|
||||
}
|
||||
}
|
||||
319
jdkSrc/jdk8/sun/reflect/annotation/AnnotatedTypeFactory.java
Normal file
319
jdkSrc/jdk8/sun/reflect/annotation/AnnotatedTypeFactory.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
869
jdkSrc/jdk8/sun/reflect/annotation/AnnotationParser.java
Normal file
869
jdkSrc/jdk8/sun/reflect/annotation/AnnotationParser.java
Normal 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; }
|
||||
}
|
||||
239
jdkSrc/jdk8/sun/reflect/annotation/AnnotationSupport.java
Normal file
239
jdkSrc/jdk8/sun/reflect/annotation/AnnotationSupport.java
Normal 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
238
jdkSrc/jdk8/sun/reflect/annotation/AnnotationType.java
Normal file
238
jdkSrc/jdk8/sun/reflect/annotation/AnnotationType.java
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
41
jdkSrc/jdk8/sun/reflect/annotation/ExceptionProxy.java
Normal file
41
jdkSrc/jdk8/sun/reflect/annotation/ExceptionProxy.java
Normal 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();
|
||||
}
|
||||
229
jdkSrc/jdk8/sun/reflect/annotation/TypeAnnotation.java
Normal file
229
jdkSrc/jdk8/sun/reflect/annotation/TypeAnnotation.java
Normal 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();
|
||||
}
|
||||
}
|
||||
503
jdkSrc/jdk8/sun/reflect/annotation/TypeAnnotationParser.java
Normal file
503
jdkSrc/jdk8/sun/reflect/annotation/TypeAnnotationParser.java
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;}
|
||||
}
|
||||
190
jdkSrc/jdk8/sun/reflect/generics/factory/GenericsFactory.java
Normal file
190
jdkSrc/jdk8/sun/reflect/generics/factory/GenericsFactory.java
Normal 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();
|
||||
}
|
||||
634
jdkSrc/jdk8/sun/reflect/generics/parser/SignatureParser.java
Normal file
634
jdkSrc/jdk8/sun/reflect/generics/parser/SignatureParser.java
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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());}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
116
jdkSrc/jdk8/sun/reflect/generics/repository/ClassRepository.java
Normal file
116
jdkSrc/jdk8/sun/reflect/generics/repository/ClassRepository.java
Normal 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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
98
jdkSrc/jdk8/sun/reflect/generics/scope/AbstractScope.java
Normal file
98
jdkSrc/jdk8/sun/reflect/generics/scope/AbstractScope.java
Normal 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);
|
||||
}
|
||||
}
|
||||
83
jdkSrc/jdk8/sun/reflect/generics/scope/ClassScope.java
Normal file
83
jdkSrc/jdk8/sun/reflect/generics/scope/ClassScope.java
Normal 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
Reference in New Issue
Block a user