下面列出了怎么用org.objectweb.asm.ConstantDynamic的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Returns a {@code static}, {@code final} field constant.
*
* @param fieldDescription The field to represent a value of.
* @return A dynamically resolved field value constant.
*/
public static Dynamic ofField(FieldDescription.InDefinedShape fieldDescription) {
if (!fieldDescription.isStatic() || !fieldDescription.isFinal()) {
throw new IllegalArgumentException("Field must be static and final: " + fieldDescription);
}
boolean selfDeclared = fieldDescription.getType().isPrimitive()
? fieldDescription.getType().asErasure().asBoxed().equals(fieldDescription.getType().asErasure())
: fieldDescription.getDeclaringType().equals(fieldDescription.getType().asErasure());
return new Dynamic(new ConstantDynamic(fieldDescription.getInternalName(),
fieldDescription.getDescriptor(),
new Handle(Opcodes.H_INVOKESTATIC,
CONSTANT_BOOTSTRAPS,
"getStaticFinal",
selfDeclared
? "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;"
: "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;)Ljava/lang/Object;",
false), selfDeclared
? new Object[0]
: new Object[]{Type.getType(fieldDescription.getDeclaringType().getDescriptor())}), fieldDescription.getType().asErasure());
}
/**
* Resolves this {@link Dynamic} constant to resolve the returned instance to the supplied type. The type must be a subtype of the
* bootstrap method's return type. Constructors cannot be resolved to a different type.
*
* @param typeDescription The type to resolve the bootstrapped value to.
* @return This dynamic constant but resolved to the supplied type.
*/
public JavaConstant withType(TypeDescription typeDescription) {
if (typeDescription.represents(void.class)) {
throw new IllegalArgumentException("Constant value cannot represent void");
} else if (value.getBootstrapMethod().getName().equals(MethodDescription.CONSTRUCTOR_INTERNAL_NAME)
? !this.typeDescription.isAssignableTo(typeDescription)
: (!typeDescription.asBoxed().isInHierarchyWith(this.typeDescription.asBoxed()))) {
throw new IllegalArgumentException(typeDescription + " is not compatible with bootstrapped type " + this.typeDescription);
}
Object[] bootstrapMethodArgument = new Object[value.getBootstrapMethodArgumentCount()];
for (int index = 0; index < value.getBootstrapMethodArgumentCount(); index++) {
bootstrapMethodArgument[index] = value.getBootstrapMethodArgument(index);
}
return new Dynamic(new ConstantDynamic(value.getName(),
typeDescription.getDescriptor(),
value.getBootstrapMethod(),
bootstrapMethodArgument), typeDescription);
}
/**
* Returns the given value, remapped with this remapper. Possible values are {@link Boolean},
* {@link Byte}, {@link Short}, {@link Character}, {@link Integer}, {@link Long}, {@link Double},
* {@link Float}, {@link String}, {@link Type}, {@link Handle}, {@link ConstantDynamic} or arrays
* of primitive types .
*
* @param value an object. Only {@link Type}, {@link Handle} and {@link ConstantDynamic} values
* are remapped.
* @return the given value, remapped with this remapper.
*/
public Object mapValue(final Object value) {
if (value instanceof Type) {
return mapType((Type) value);
}
if (value instanceof Handle) {
Handle handle = (Handle) value;
return new Handle(
handle.getTag(),
mapType(handle.getOwner()),
mapMethodName(handle.getOwner(), handle.getName(), handle.getDesc()),
handle.getTag() <= Opcodes.H_PUTSTATIC
? mapDesc(handle.getDesc())
: mapMethodDesc(handle.getDesc()),
handle.isInterface());
}
if (value instanceof ConstantDynamic) {
ConstantDynamic constantDynamic = (ConstantDynamic) value;
int bootstrapMethodArgumentCount = constantDynamic.getBootstrapMethodArgumentCount();
Object[] remappedBootstrapMethodArguments = new Object[bootstrapMethodArgumentCount];
for (int i = 0; i < bootstrapMethodArgumentCount; ++i) {
remappedBootstrapMethodArguments[i] =
mapValue(constantDynamic.getBootstrapMethodArgument(i));
}
String descriptor = constantDynamic.getDescriptor();
return new ConstantDynamic(
mapInvokeDynamicMethodName(constantDynamic.getName(), descriptor),
mapDesc(descriptor),
(Handle) mapValue(constantDynamic.getBootstrapMethod()),
remappedBootstrapMethodArguments);
}
return value;
}
@Override
public void visitLdcInsn(final Object value) {
if (value instanceof Long
|| value instanceof Double
|| (value instanceof ConstantDynamic && ((ConstantDynamic) value).getSize() == 2)) {
minSize += 3;
maxSize += 3;
} else {
minSize += 2;
maxSize += 3;
}
super.visitLdcInsn(value);
}
@Override
public void visitLdcInsn(final Object value) {
super.visitLdcInsn(value);
if (this.locals == null) {
labels = null;
return;
}
if (value instanceof Integer) {
push(Opcodes.INTEGER);
} else if (value instanceof Long) {
push(Opcodes.LONG);
push(Opcodes.TOP);
} else if (value instanceof Float) {
push(Opcodes.FLOAT);
} else if (value instanceof Double) {
push(Opcodes.DOUBLE);
push(Opcodes.TOP);
} else if (value instanceof String) {
push("java/lang/String");
} else if (value instanceof Type) {
int sort = ((Type) value).getSort();
if (sort == Type.OBJECT || sort == Type.ARRAY) {
push("java/lang/Class");
} else if (sort == Type.METHOD) {
push("java/lang/invoke/MethodType");
} else {
throw new IllegalArgumentException();
}
} else if (value instanceof Handle) {
push("java/lang/invoke/MethodHandle");
} else if (value instanceof ConstantDynamic) {
pushDescriptor(((ConstantDynamic) value).getDescriptor());
} else {
throw new IllegalArgumentException();
}
labels = null;
}
@Override
public void visitLdcInsn(final Object value) {
if (api < Opcodes.ASM5
&& (value instanceof Handle
|| (value instanceof Type && ((Type) value).getSort() == Type.METHOD))) {
throw new UnsupportedOperationException("This feature requires ASM5");
}
if (api != Opcodes.ASM7 && value instanceof ConstantDynamic) {
throw new UnsupportedOperationException("This feature requires ASM7");
}
if (value instanceof Integer) {
iconst((Integer) value);
} else if (value instanceof Byte) {
iconst(((Byte) value).intValue());
} else if (value instanceof Character) {
iconst(((Character) value).charValue());
} else if (value instanceof Short) {
iconst(((Short) value).intValue());
} else if (value instanceof Boolean) {
iconst(((Boolean) value).booleanValue() ? 1 : 0);
} else if (value instanceof Float) {
fconst((Float) value);
} else if (value instanceof Long) {
lconst((Long) value);
} else if (value instanceof Double) {
dconst((Double) value);
} else if (value instanceof String) {
aconst(value);
} else if (value instanceof Type) {
tconst((Type) value);
} else if (value instanceof Handle) {
hconst((Handle) value);
} else if (value instanceof ConstantDynamic) {
cconst((ConstantDynamic) value);
} else {
throw new IllegalArgumentException();
}
}
@Override
public void visitLdcInsn(final Object value) {
super.visitLdcInsn(value);
if (isConstructor && !superClassConstructorCalled) {
pushValue(OTHER);
if (value instanceof Double
|| value instanceof Long
|| (value instanceof ConstantDynamic && ((ConstantDynamic) value).getSize() == 2)) {
pushValue(OTHER);
}
}
}
/**
* Generates the instruction to push a constant dynamic on the stack.
*
* @param constantDynamic the constant dynamic to be pushed on the stack.
*/
public void push(final ConstantDynamic constantDynamic) {
if (constantDynamic == null) {
mv.visitInsn(Opcodes.ACONST_NULL);
} else {
mv.visitLdcInsn(constantDynamic);
}
}
@Override
public void visitLdcInsn(final Object value) {
super.visitLdcInsn(value);
if (this.locals == null) {
labels = null;
return;
}
if (value instanceof Integer) {
push(Opcodes.INTEGER);
} else if (value instanceof Long) {
push(Opcodes.LONG);
push(Opcodes.TOP);
} else if (value instanceof Float) {
push(Opcodes.FLOAT);
} else if (value instanceof Double) {
push(Opcodes.DOUBLE);
push(Opcodes.TOP);
} else if (value instanceof String) {
push("java/lang/String");
} else if (value instanceof Type) {
int sort = ((Type) value).getSort();
if (sort == Type.OBJECT || sort == Type.ARRAY) {
push("java/lang/Class");
} else if (sort == Type.METHOD) {
push("java/lang/invoke/MethodType");
} else {
throw new IllegalArgumentException();
}
} else if (value instanceof Handle) {
push("java/lang/invoke/MethodHandle");
} else if (value instanceof ConstantDynamic) {
pushDescriptor(((ConstantDynamic) value).getDescriptor());
} else {
throw new IllegalArgumentException();
}
labels = null;
}
@Override
public void visitLdcInsn(final Object value) {
if (api < Opcodes.ASM5
&& (value instanceof Handle
|| (value instanceof Type && ((Type) value).getSort() == Type.METHOD))) {
throw new UnsupportedOperationException();
}
if (api != Opcodes.ASM7_EXPERIMENTAL && value instanceof ConstantDynamic) {
throw new UnsupportedOperationException();
}
if (value instanceof Integer) {
iconst((Integer) value);
} else if (value instanceof Byte) {
iconst(((Byte) value).intValue());
} else if (value instanceof Character) {
iconst(((Character) value).charValue());
} else if (value instanceof Short) {
iconst(((Short) value).intValue());
} else if (value instanceof Boolean) {
iconst(((Boolean) value).booleanValue() ? 1 : 0);
} else if (value instanceof Float) {
fconst((Float) value);
} else if (value instanceof Long) {
lconst((Long) value);
} else if (value instanceof Double) {
dconst((Double) value);
} else if (value instanceof String) {
aconst(value);
} else if (value instanceof Type) {
tconst((Type) value);
} else if (value instanceof Handle) {
hconst((Handle) value);
} else if (value instanceof ConstantDynamic) {
cconst((ConstantDynamic) value);
} else {
throw new IllegalArgumentException();
}
}
/**
* Returns the given value, remapped with this remapper. Possible values are {@link Boolean},
* {@link Byte}, {@link Short}, {@link Character}, {@link Integer}, {@link Long}, {@link Double},
* {@link Float}, {@link String}, {@link Type}, {@link Handle}, {@link ConstantDynamic} or arrays
* of primitive types .
*
* @param value an object. Only {@link Type}, {@link Handle} and {@link ConstantDynamic} values
* are remapped.
* @return the given value, remapped with this remapper.
*/
public Object mapValue(final Object value) {
if (value instanceof Type) {
return mapType((Type) value);
}
if (value instanceof Handle) {
Handle handle = (Handle) value;
return new Handle(
handle.getTag(),
mapType(handle.getOwner()),
mapMethodName(handle.getOwner(), handle.getName(), handle.getDesc()),
handle.getTag() <= Opcodes.H_PUTSTATIC
? mapDesc(handle.getDesc())
: mapMethodDesc(handle.getDesc()),
handle.isInterface());
}
if (value instanceof ConstantDynamic) {
ConstantDynamic constantDynamic = (ConstantDynamic) value;
int bootstrapMethodArgumentCount = constantDynamic.getBootstrapMethodArgumentCount();
Object[] remappedBootstrapMethodArguments = new Object[bootstrapMethodArgumentCount];
for (int i = 0; i < bootstrapMethodArgumentCount; ++i) {
remappedBootstrapMethodArguments[i] =
mapValue(constantDynamic.getBootstrapMethodArgument(i));
}
String descriptor = constantDynamic.getDescriptor();
return new ConstantDynamic(
mapInvokeDynamicMethodName(constantDynamic.getName(), descriptor),
mapDesc(descriptor),
(Handle) mapValue(constantDynamic.getBootstrapMethod()),
remappedBootstrapMethodArguments);
}
return value;
}
@Override
public void visitLdcInsn(final Object value) {
if (value instanceof Long
|| value instanceof Double
|| (value instanceof ConstantDynamic && ((ConstantDynamic) value).getSize() == 2)) {
minSize += 3;
maxSize += 3;
} else {
minSize += 2;
maxSize += 3;
}
super.visitLdcInsn(value);
}
@Override
public void visitLdcInsn(final Object value) {
super.visitLdcInsn(value);
if (this.locals == null) {
labels = null;
return;
}
if (value instanceof Integer) {
push(Opcodes.INTEGER);
} else if (value instanceof Long) {
push(Opcodes.LONG);
push(Opcodes.TOP);
} else if (value instanceof Float) {
push(Opcodes.FLOAT);
} else if (value instanceof Double) {
push(Opcodes.DOUBLE);
push(Opcodes.TOP);
} else if (value instanceof String) {
push("java/lang/String");
} else if (value instanceof Type) {
int sort = ((Type) value).getSort();
if (sort == Type.OBJECT || sort == Type.ARRAY) {
push("java/lang/Class");
} else if (sort == Type.METHOD) {
push("java/lang/invoke/MethodType");
} else {
throw new IllegalArgumentException();
}
} else if (value instanceof Handle) {
push("java/lang/invoke/MethodHandle");
} else if (value instanceof ConstantDynamic) {
pushDescriptor(((ConstantDynamic) value).getDescriptor());
} else {
throw new IllegalArgumentException();
}
labels = null;
}
@Override
public void visitLdcInsn(final Object value) {
if (api < Opcodes.ASM5
&& (value instanceof Handle
|| (value instanceof Type && ((Type) value).getSort() == Type.METHOD))) {
throw new UnsupportedOperationException("This feature requires ASM5");
}
if (api != Opcodes.ASM7 && value instanceof ConstantDynamic) {
throw new UnsupportedOperationException("This feature requires ASM7");
}
if (value instanceof Integer) {
iconst((Integer) value);
} else if (value instanceof Byte) {
iconst(((Byte) value).intValue());
} else if (value instanceof Character) {
iconst(((Character) value).charValue());
} else if (value instanceof Short) {
iconst(((Short) value).intValue());
} else if (value instanceof Boolean) {
iconst(((Boolean) value).booleanValue() ? 1 : 0);
} else if (value instanceof Float) {
fconst((Float) value);
} else if (value instanceof Long) {
lconst((Long) value);
} else if (value instanceof Double) {
dconst((Double) value);
} else if (value instanceof String) {
aconst(value);
} else if (value instanceof Type) {
tconst((Type) value);
} else if (value instanceof Handle) {
hconst((Handle) value);
} else if (value instanceof ConstantDynamic) {
cconst((ConstantDynamic) value);
} else {
throw new IllegalArgumentException();
}
}
@Override
public void visitLdcInsn(final Object value) {
super.visitLdcInsn(value);
if (isConstructor && !superClassConstructorCalled) {
pushValue(OTHER);
if (value instanceof Double
|| value instanceof Long
|| (value instanceof ConstantDynamic && ((ConstantDynamic) value).getSize() == 2)) {
pushValue(OTHER);
}
}
}
/**
* Generates the instruction to push a constant dynamic on the stack.
*
* @param constantDynamic the constant dynamic to be pushed on the stack.
*/
public void push(final ConstantDynamic constantDynamic) {
if (constantDynamic == null) {
mv.visitInsn(Opcodes.ACONST_NULL);
} else {
mv.visitLdcInsn(constantDynamic);
}
}
/**
* Returns the given value, remapped with this remapper. Possible values are {@link Boolean},
* {@link Byte}, {@link Short}, {@link Character}, {@link Integer}, {@link Long}, {@link Double},
* {@link Float}, {@link String}, {@link Type}, {@link Handle}, {@link ConstantDynamic} or arrays
* of primitive types .
*
* @param value an object. Only {@link Type}, {@link Handle} and {@link ConstantDynamic} values
* are remapped.
* @return the given value, remapped with this remapper.
*/
public Object mapValue(final Object value) {
if (value instanceof Type) {
return mapType((Type) value);
}
if (value instanceof Handle) {
Handle handle = (Handle) value;
return new Handle(
handle.getTag(),
mapType(handle.getOwner()),
mapMethodName(handle.getOwner(), handle.getName(), handle.getDesc()),
handle.getTag() <= Opcodes.H_PUTSTATIC
? mapDesc(handle.getDesc())
: mapMethodDesc(handle.getDesc()),
handle.isInterface());
}
if (value instanceof ConstantDynamic) {
ConstantDynamic constantDynamic = (ConstantDynamic) value;
int bootstrapMethodArgumentCount = constantDynamic.getBootstrapMethodArgumentCount();
Object[] remappedBootstrapMethodArguments = new Object[bootstrapMethodArgumentCount];
for (int i = 0; i < bootstrapMethodArgumentCount; ++i) {
remappedBootstrapMethodArguments[i] =
mapValue(constantDynamic.getBootstrapMethodArgument(i));
}
String descriptor = constantDynamic.getDescriptor();
return new ConstantDynamic(
mapInvokeDynamicMethodName(constantDynamic.getName(), descriptor),
mapDesc(descriptor),
(Handle) mapValue(constantDynamic.getBootstrapMethod()),
remappedBootstrapMethodArguments);
}
return value;
}
@Override
public void visitLdcInsn(final Object value) {
if (value instanceof Long
|| value instanceof Double
|| (value instanceof ConstantDynamic && ((ConstantDynamic) value).getSize() == 2)) {
minSize += 3;
maxSize += 3;
} else {
minSize += 2;
maxSize += 3;
}
super.visitLdcInsn(value);
}
@Override
public void visitLdcInsn(final Object value) {
super.visitLdcInsn(value);
if (this.locals == null) {
labels = null;
return;
}
if (value instanceof Integer) {
push(Opcodes.INTEGER);
} else if (value instanceof Long) {
push(Opcodes.LONG);
push(Opcodes.TOP);
} else if (value instanceof Float) {
push(Opcodes.FLOAT);
} else if (value instanceof Double) {
push(Opcodes.DOUBLE);
push(Opcodes.TOP);
} else if (value instanceof String) {
push("java/lang/String");
} else if (value instanceof Type) {
int sort = ((Type) value).getSort();
if (sort == Type.OBJECT || sort == Type.ARRAY) {
push("java/lang/Class");
} else if (sort == Type.METHOD) {
push("java/lang/invoke/MethodType");
} else {
throw new IllegalArgumentException();
}
} else if (value instanceof Handle) {
push("java/lang/invoke/MethodHandle");
} else if (value instanceof ConstantDynamic) {
pushDescriptor(((ConstantDynamic) value).getDescriptor());
} else {
throw new IllegalArgumentException();
}
labels = null;
}
@Override
public void visitLdcInsn(final Object value) {
if (api < Opcodes.ASM5
&& (value instanceof Handle
|| (value instanceof Type && ((Type) value).getSort() == Type.METHOD))) {
throw new UnsupportedOperationException("This feature requires ASM5");
}
if (api != Opcodes.ASM7 && value instanceof ConstantDynamic) {
throw new UnsupportedOperationException("This feature requires ASM7");
}
if (value instanceof Integer) {
iconst((Integer) value);
} else if (value instanceof Byte) {
iconst(((Byte) value).intValue());
} else if (value instanceof Character) {
iconst(((Character) value).charValue());
} else if (value instanceof Short) {
iconst(((Short) value).intValue());
} else if (value instanceof Boolean) {
iconst(((Boolean) value).booleanValue() ? 1 : 0);
} else if (value instanceof Float) {
fconst((Float) value);
} else if (value instanceof Long) {
lconst((Long) value);
} else if (value instanceof Double) {
dconst((Double) value);
} else if (value instanceof String) {
aconst(value);
} else if (value instanceof Type) {
tconst((Type) value);
} else if (value instanceof Handle) {
hconst((Handle) value);
} else if (value instanceof ConstantDynamic) {
cconst((ConstantDynamic) value);
} else {
throw new IllegalArgumentException();
}
}
@Override
public void visitLdcInsn(final Object value) {
super.visitLdcInsn(value);
if (isConstructor && !superClassConstructorCalled) {
pushValue(OTHER);
if (value instanceof Double
|| value instanceof Long
|| (value instanceof ConstantDynamic && ((ConstantDynamic) value).getSize() == 2)) {
pushValue(OTHER);
}
}
}
/**
* Generates the instruction to push a constant dynamic on the stack.
*
* @param constantDynamic the constant dynamic to be pushed on the stack.
*/
public void push(final ConstantDynamic constantDynamic) {
if (constantDynamic == null) {
mv.visitInsn(Opcodes.ACONST_NULL);
} else {
mv.visitLdcInsn(constantDynamic);
}
}
@Override
public void visitLdcInsn(final Object value) {
super.visitLdcInsn(value);
if (stackFrameTracking) {
pushValue(OTHER);
if (value instanceof Double || value instanceof Long
|| (value instanceof ConstantDynamic
&& ((ConstantDynamic) value).getSize() == 2)) {
pushValue(SECOND_WORD);
}
}
}
/**
* Returns a constant {@code null} value of type {@link Object}.
*
* @return A dynamically resolved null constant.
*/
public static Dynamic ofNullConstant() {
return new Dynamic(new ConstantDynamic("nullConstant",
TypeDescription.OBJECT.getDescriptor(),
new Handle(Opcodes.H_INVOKESTATIC,
CONSTANT_BOOTSTRAPS,
"nullConstant",
"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;",
false)), TypeDescription.OBJECT);
}
/**
* Returns a {@link Class} constant for a primitive type.
*
* @param typeDescription The primitive type to represent.
* @return A dynamically resolved primitive type constant.
*/
public static JavaConstant ofPrimitiveType(TypeDescription typeDescription) {
if (!typeDescription.isPrimitive()) {
throw new IllegalArgumentException("Not a primitive type: " + typeDescription);
}
return new Dynamic(new ConstantDynamic(typeDescription.getDescriptor(),
TypeDescription.CLASS.getDescriptor(),
new Handle(Opcodes.H_INVOKESTATIC,
CONSTANT_BOOTSTRAPS,
"primitiveClass",
"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Class;",
false)), TypeDescription.CLASS);
}
/**
* Returns a {@link Enum} value constant.
*
* @param enumerationDescription The enumeration value to represent.
* @return A dynamically resolved enumeration constant.
*/
public static JavaConstant ofEnumeration(EnumerationDescription enumerationDescription) {
return new Dynamic(new ConstantDynamic(enumerationDescription.getValue(),
enumerationDescription.getEnumerationType().getDescriptor(),
new Handle(Opcodes.H_INVOKESTATIC,
CONSTANT_BOOTSTRAPS,
"enumConstant",
"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Enum;",
false)), enumerationDescription.getEnumerationType());
}
/**
* Resolves a var handle constant for a field.
*
* @param fieldDescription The field to represent a var handle for.
* @return A dynamic constant that represents the created var handle constant.
*/
public static JavaConstant ofVarHandle(FieldDescription.InDefinedShape fieldDescription) {
return new Dynamic(new ConstantDynamic(fieldDescription.getInternalName(),
JavaType.VAR_HANDLE.getTypeStub().getDescriptor(),
new Handle(Opcodes.H_INVOKESTATIC,
CONSTANT_BOOTSTRAPS,
fieldDescription.isStatic()
? "staticFieldVarHandle"
: "fieldVarHandle",
"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Class;)Ljava/lang/invoke/VarHandle;",
false),
Type.getType(fieldDescription.getDeclaringType().getDescriptor()),
Type.getType(fieldDescription.getType().asErasure().getDescriptor())), JavaType.VAR_HANDLE.getTypeStub());
}
/**
* Resolves a var handle constant for an array.
*
* @param typeDescription The array type for which the var handle is resolved.
* @return A dynamic constant that represents the created var handle constant.
*/
public static JavaConstant ofArrayVarHandle(TypeDescription typeDescription) {
if (!typeDescription.isArray()) {
throw new IllegalArgumentException("Not an array type: " + typeDescription);
}
return new Dynamic(new ConstantDynamic("arrayVarHandle",
JavaType.VAR_HANDLE.getTypeStub().getDescriptor(),
new Handle(Opcodes.H_INVOKESTATIC,
CONSTANT_BOOTSTRAPS,
"arrayVarHandle",
"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;)Ljava/lang/invoke/VarHandle;",
false),
Type.getType(typeDescription.getDescriptor())), JavaType.VAR_HANDLE.getTypeStub());
}
@Override
public BasicValue newOperation(final AbstractInsnNode insn) throws AnalyzerException {
switch (insn.getOpcode()) {
case ACONST_NULL:
return newValue(NULL_TYPE);
case ICONST_M1:
case ICONST_0:
case ICONST_1:
case ICONST_2:
case ICONST_3:
case ICONST_4:
case ICONST_5:
return BasicValue.INT_VALUE;
case LCONST_0:
case LCONST_1:
return BasicValue.LONG_VALUE;
case FCONST_0:
case FCONST_1:
case FCONST_2:
return BasicValue.FLOAT_VALUE;
case DCONST_0:
case DCONST_1:
return BasicValue.DOUBLE_VALUE;
case BIPUSH:
case SIPUSH:
return BasicValue.INT_VALUE;
case LDC:
Object value = ((LdcInsnNode) insn).cst;
if (value instanceof Integer) {
return BasicValue.INT_VALUE;
} else if (value instanceof Float) {
return BasicValue.FLOAT_VALUE;
} else if (value instanceof Long) {
return BasicValue.LONG_VALUE;
} else if (value instanceof Double) {
return BasicValue.DOUBLE_VALUE;
} else if (value instanceof String) {
return newValue(Type.getObjectType("java/lang/String"));
} else if (value instanceof Type) {
int sort = ((Type) value).getSort();
if (sort == Type.OBJECT || sort == Type.ARRAY) {
return newValue(Type.getObjectType("java/lang/Class"));
} else if (sort == Type.METHOD) {
return newValue(Type.getObjectType("java/lang/invoke/MethodType"));
} else {
throw new AnalyzerException(insn, "Illegal LDC value " + value);
}
} else if (value instanceof Handle) {
return newValue(Type.getObjectType("java/lang/invoke/MethodHandle"));
} else if (value instanceof ConstantDynamic) {
return newValue(Type.getType(((ConstantDynamic) value).getDescriptor()));
} else {
throw new AnalyzerException(insn, "Illegal LDC value " + value);
}
case JSR:
return BasicValue.RETURNADDRESS_VALUE;
case GETSTATIC:
return newValue(Type.getType(((FieldInsnNode) insn).desc));
case NEW:
return newValue(Type.getObjectType(((TypeInsnNode) insn).desc));
default:
throw new AssertionError();
}
}
@Override
public CoffeeValue newOperation(final AbstractInsnNode insn) throws AnalyzerException {
switch (insn.getOpcode()) {
case ACONST_NULL:
return newValue(NULL_TYPE);
case ICONST_M1:
case ICONST_0:
case ICONST_1:
case ICONST_2:
case ICONST_3:
case ICONST_4:
case ICONST_5:
return CoffeeValue.INT_VALUE;
case LCONST_0:
case LCONST_1:
return CoffeeValue.LONG_VALUE;
case FCONST_0:
case FCONST_1:
case FCONST_2:
return CoffeeValue.FLOAT_VALUE;
case DCONST_0:
case DCONST_1:
return CoffeeValue.DOUBLE_VALUE;
case BIPUSH:
case SIPUSH:
return CoffeeValue.INT_VALUE;
case LDC:
Object value = ((LdcInsnNode) insn).cst;
if (value instanceof Integer) {
return CoffeeValue.INT_VALUE;
} else if (value instanceof Float) {
return CoffeeValue.FLOAT_VALUE;
} else if (value instanceof Long) {
return CoffeeValue.LONG_VALUE;
} else if (value instanceof Double) {
return CoffeeValue.DOUBLE_VALUE;
} else if (value instanceof String) {
return newValue(Type.getObjectType("java/lang/String"));
} else if (value instanceof Type) {
int sort = ((Type) value).getSort();
if (sort == Type.OBJECT || sort == Type.ARRAY) {
return newValue(Type.getObjectType("java/lang/Class"));
} else if (sort == Type.METHOD) {
return newValue(Type.getObjectType("java/lang/invoke/MethodType"));
} else {
throw new AnalyzerException(insn, "Illegal LDC value " + value);
}
} else if (value instanceof Handle) {
return newValue(Type.getObjectType("java/lang/invoke/MethodHandle"));
} else if (value instanceof ConstantDynamic) {
return newValue(Type.getType(((ConstantDynamic) value).getDescriptor()));
} else {
throw new AnalyzerException(insn, "Illegal LDC value " + value);
}
case JSR:
return CoffeeValue.RETURNADDRESS_VALUE; // missing implementation
case GETSTATIC:
return newValue(Type.getType(((FieldInsnNode) insn).desc));
case NEW:
return newValue(Type.getObjectType(((TypeInsnNode) insn).desc));
default:
throw new AssertionError();
}
}