下面列出了org.objectweb.asm.Type#BYTE_TYPE 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
Type getArrayElementType(int type) {
switch (type) {
case T_BOOLEAN:
return Type.BOOLEAN_TYPE;
case T_BYTE:
return Type.BYTE_TYPE;
case T_CHAR:
return Type.CHAR_TYPE;
case T_DOUBLE:
return Type.DOUBLE_TYPE;
case T_FLOAT:
return Type.FLOAT_TYPE;
case T_INT:
return Type.INT_TYPE;
case T_LONG:
return Type.LONG_TYPE;
case T_SHORT:
return Type.SHORT_TYPE;
}
throw new BuildStackFrameException("Illegal array type code: " + type);
}
public static Number rebox(Number cst, Type t) {
if(t == Type.BYTE_TYPE) {
return cst.byteValue();
} else if(t == Type.SHORT_TYPE) {
return cst.shortValue();
} else if(t == Type.INT_TYPE) {
return cst.intValue();
} else if(t == Type.LONG_TYPE) {
return cst.longValue();
} else if(t == Type.FLOAT_TYPE) {
return cst.floatValue();
} else if(t == Type.DOUBLE_TYPE) {
return cst.doubleValue();
} else {
throw new UnsupportedOperationException(String.format("%s (%s) to %s", cst, cst.getClass(), t));
}
}
public static Type getUnboxedType(Type type) {
if (Constants.TYPE_INTEGER.equals(type)) {
return Type.INT_TYPE;
} else if (Constants.TYPE_BOOLEAN.equals(type)) {
return Type.BOOLEAN_TYPE;
} else if (Constants.TYPE_DOUBLE.equals(type)) {
return Type.DOUBLE_TYPE;
} else if (Constants.TYPE_LONG.equals(type)) {
return Type.LONG_TYPE;
} else if (Constants.TYPE_CHARACTER.equals(type)) {
return Type.CHAR_TYPE;
} else if (Constants.TYPE_BYTE.equals(type)) {
return Type.BYTE_TYPE;
} else if (Constants.TYPE_FLOAT.equals(type)) {
return Type.FLOAT_TYPE;
} else if (Constants.TYPE_SHORT.equals(type)) {
return Type.SHORT_TYPE;
} else {
return type;
}
}
@VisibleForTesting
static Type getType(String type) {
if (type.equals(Void.TYPE.getName())) {
return Type.VOID_TYPE;
} else if (type.equals(Boolean.TYPE.getName())) {
return Type.BOOLEAN_TYPE;
} else if (type.equals(Character.TYPE.getName())) {
return Type.CHAR_TYPE;
} else if (type.equals(Byte.TYPE.getName())) {
return Type.BYTE_TYPE;
} else if (type.equals(Short.TYPE.getName())) {
return Type.SHORT_TYPE;
} else if (type.equals(Integer.TYPE.getName())) {
return Type.INT_TYPE;
} else if (type.equals(Float.TYPE.getName())) {
return Type.FLOAT_TYPE;
} else if (type.equals(Long.TYPE.getName())) {
return Type.LONG_TYPE;
} else if (type.equals(Double.TYPE.getName())) {
return Type.DOUBLE_TYPE;
} else if (type.endsWith("[]")) {
return getArrayType(type);
} else {
return Type.getObjectType(type.replace('.', '/'));
}
}
public static Type getCastType(int opcode) {
switch (opcode) {
case I2B:
return Type.BYTE_TYPE;
case I2C:
return Type.CHAR_TYPE;
case I2S:
return Type.SHORT_TYPE;
case L2I:
case F2I:
case D2I:
return Type.INT_TYPE;
case I2L:
case F2L:
case D2L:
return Type.LONG_TYPE;
case I2F:
case L2F:
case D2F:
return Type.FLOAT_TYPE;
case I2D:
case L2D:
case F2D:
return Type.DOUBLE_TYPE;
default:
throw new IllegalArgumentException(Printer.OPCODES[opcode]);
}
}
public static int getNegateOpcode(Type type) {
if (type == Type.INT_TYPE || type == Type.SHORT_TYPE || type == Type.BYTE_TYPE) {
return Opcodes.INEG;
} else if (type == Type.LONG_TYPE) {
return Opcodes.LNEG;
} else if (type == Type.FLOAT_TYPE) {
return Opcodes.FNEG;
} else if (type == Type.DOUBLE_TYPE) {
return Opcodes.DNEG;
} else {
throw new IllegalArgumentException(type.toString());
}
}
void pushLocals(StackInfo info) {
super.visitIntInsn(SIPUSH, info.localsSize());
super.visitTypeInsn(ANEWARRAY, "java/lang/Object");
for (int i = 0; i < info.localsSize(); ++i) {
Type t = info.getLocal(i);
if (t != null) {
super.visitInsn(DUP);
super.visitIntInsn(SIPUSH, i);
if (t == Type.BOOLEAN_TYPE || t == Type.BYTE_TYPE || t == Type.SHORT_TYPE || t == Type.INT_TYPE || t == Type.CHAR_TYPE) {
super.visitVarInsn(ILOAD, i);
super.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
} else if (t == Type.FLOAT_TYPE) {
super.visitVarInsn(FLOAD, i);
super.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false);
} else if (t == Type.LONG_TYPE) {
super.visitVarInsn(LLOAD, i);
super.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false);
} else if (t == Type.DOUBLE_TYPE) {
super.visitVarInsn(DLOAD, i);
super.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false);
} else if (t == StackInfo.AconstNullType) {
super.visitInsn(ACONST_NULL);
} else {
super.visitVarInsn(ALOAD, i);
}
super.visitInsn(AASTORE);
}
}
}
/**
* @param opcode
* @return
*/
private static Type toType ( int opcode ) {
switch ( opcode ) {
case Opcodes.LLOAD:
return Type.LONG_TYPE;
case Opcodes.ILOAD:
return Type.INT_TYPE;
case Opcodes.FLOAD:
return Type.FLOAT_TYPE;
case Opcodes.DLOAD:
return Type.DOUBLE_TYPE;
case Opcodes.ALOAD:
return Type.getType("Ljava/lang/Object;"); //$NON-NLS-1$
case Opcodes.IALOAD:
return Type.INT_TYPE;
case Opcodes.LALOAD:
return Type.LONG_TYPE;
case Opcodes.FALOAD:
return Type.FLOAT_TYPE;
case Opcodes.DALOAD:
return Type.DOUBLE_TYPE;
case Opcodes.BALOAD:
return Type.BYTE_TYPE;
case Opcodes.CALOAD:
return Type.CHAR_TYPE;
case Opcodes.SALOAD:
return Type.SHORT_TYPE;
}
return Type.VOID_TYPE;
}
protected void _jump_cmp0(BasicBlock target, ComparisonType type) {
save_stack(false);
Expr left = pop();
ConstantExpr right = new ConstantExpr((byte)0, Type.BYTE_TYPE, false);
_jump_cmp(target, type, left, right);
}
public static Type computeType(Object cst) {
if (cst == null) {
return Type.getType("Ljava/lang/Object;");
} else if (cst instanceof Integer) {
int val = ((Integer) cst).intValue();
if (val >= Byte.MIN_VALUE && val <= Byte.MAX_VALUE) {
return Type.BYTE_TYPE;
} else if (val >= Short.MIN_VALUE && val <= Short.MAX_VALUE) {
return Type.SHORT_TYPE;
} else {
return Type.INT_TYPE;
}
// return Type.INT_TYPE;
} else if (cst instanceof Long) {
return Type.LONG_TYPE;
} else if (cst instanceof Float) {
return Type.FLOAT_TYPE;
} else if (cst instanceof Double) {
return Type.DOUBLE_TYPE;
} else if (cst instanceof String) {
return Type.getType("Ljava/lang/String;");
} else if (cst instanceof Type) {
Type type = (Type) cst;
if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
return Type.getType("Ljava/lang/Class;");
} else if (type.getSort() == Type.METHOD) {
return Type.getType("Ljava/lang/invoke/MethodType;");
} else {
throw new RuntimeException("Invalid type: " + cst);
}
} else if (cst instanceof Handle) {
return Type.getType("Ljava/lang/invoke/MethodHandle;");
} else if (cst instanceof Boolean) {
return Type.BOOLEAN_TYPE;
} else if(cst instanceof Byte) {
return Type.BYTE_TYPE;
} else if (cst instanceof Character) {
return Type.CHAR_TYPE;
} else if(cst instanceof Short) {
return Type.SHORT_TYPE;
} else {
throw new RuntimeException("Invalid type: " + cst);
}
}
void recreateLocals(StackInfo info) {
if (info.localsSize() == 0)
return;
visitVarInsn(ALOAD, 0);
visitFieldInsn(GETFIELD, currentClassName, "__stack", "Ljava/util/Stack;");
visitVarInsn(ALOAD, 0);
visitFieldInsn(GETFIELD, currentClassName, "__stackPosition", "I");
visitMethodInsn(INVOKEVIRTUAL, "java/util/Stack", "get", "(I)Ljava/lang/Object;");
visitTypeInsn(CHECKCAST, "org/copperengine/core/StackEntry");
visitFieldInsn(GETFIELD, "org/copperengine/core/StackEntry", "locals", "[Ljava/lang/Object;");
for (int i = 0; i < info.localsSize(); ++i) {
Type t = info.getLocal(i);
if (t != null) {
if (t != StackInfo.AconstNullType) {
super.visitInsn(DUP);
super.visitIntInsn(SIPUSH, i);
super.visitInsn(AALOAD);
} else {
super.visitInsn(ACONST_NULL);
}
if (t == Type.BOOLEAN_TYPE || t == Type.BYTE_TYPE || t == Type.SHORT_TYPE || t == Type.INT_TYPE || t == Type.CHAR_TYPE) {
super.visitTypeInsn(CHECKCAST, Type.getInternalName(Integer.class));
super.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false);
super.visitVarInsn(ISTORE, i);
} else if (t == Type.FLOAT_TYPE) {
super.visitTypeInsn(CHECKCAST, Type.getInternalName(Float.class));
super.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false);
super.visitVarInsn(FSTORE, i);
} else if (t == Type.LONG_TYPE) {
super.visitTypeInsn(CHECKCAST, Type.getInternalName(Long.class));
super.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false);
super.visitVarInsn(LSTORE, i);
} else if (t == Type.DOUBLE_TYPE) {
super.visitTypeInsn(CHECKCAST, Type.getInternalName(Double.class));
super.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false);
super.visitVarInsn(DSTORE, i);
} else {
if (!t.getInternalName().equals(Type.getInternalName(Object.class)) && t != StackInfo.AconstNullType)
super.visitTypeInsn(CHECKCAST, t.getInternalName());
super.visitVarInsn(ASTORE, i);
}
}
}
visitInsn(POP);
}
public static InsnValue byteValue(Object cst) {
return new InsnValue(Type.BYTE_TYPE, cst);
}
private void callTheDecoder(MethodVisitor methodVisitor, Type type) {
if (type == Type.BYTE_TYPE) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOneByte", "()B", false);
} else if (type == Type.BOOLEAN_TYPE) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOneBoolean", "()Z", false);
} else if (type == Type.CHAR_TYPE) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOneCharacter", "()C", false);
} else if (type == Type.SHORT_TYPE) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOneShort", "()S", false);
} else if (type == Type.INT_TYPE) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOneInteger", "()I", false);
} else if (type == Type.LONG_TYPE) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOneLong", "()J", false);
} else if (type == Type.FLOAT_TYPE) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOneFloat", "()F", false);
} else if (type == Type.DOUBLE_TYPE) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOneDouble", "()D", false);
} else if (isArrayOfTypeAndDimensions(type, Type.BYTE_TYPE, 1)) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOneByteArray", "()[B", false);
} else if (isArrayOfTypeAndDimensions(type, Type.BOOLEAN_TYPE, 1)) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOneBooleanArray", "()[Z", false);
} else if (isArrayOfTypeAndDimensions(type, Type.CHAR_TYPE, 1)) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOneCharacterArray", "()[C", false);
} else if (isArrayOfTypeAndDimensions(type, Type.SHORT_TYPE, 1)) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOneShortArray", "()[S", false);
} else if (isArrayOfTypeAndDimensions(type, Type.INT_TYPE, 1)) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOneIntegerArray", "()[I", false);
} else if (isArrayOfTypeAndDimensions(type, Type.LONG_TYPE, 1)) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOneLongArray", "()[J", false);
} else if (isArrayOfTypeAndDimensions(type, Type.FLOAT_TYPE, 1)) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOneFloatArray", "()[F", false);
} else if (isArrayOfTypeAndDimensions(type, Type.DOUBLE_TYPE, 1)) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOneDoubleArray", "()[D", false);
} else if (isString(type)) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOneString", "()Ljava/lang/String;", false);
} else if (isAddress(type)) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOneAddress", "()Lavm/Address;", false);
} else if(isBigInteger(type)) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOneBigInteger", "()Ljava/math/BigInteger;", false);
} else if (isArrayOfTypeAndDimensions(type, Type.BYTE_TYPE, 2)) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOne2DByteArray", "()[[B", false);
} else if (isArrayOfTypeAndDimensions(type, Type.BOOLEAN_TYPE, 2)) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOne2DBooleanArray", "()[[Z", false);
} else if (isArrayOfTypeAndDimensions(type, Type.CHAR_TYPE, 2)) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOne2DCharacterArray", "()[[C", false);
} else if (isArrayOfTypeAndDimensions(type, Type.SHORT_TYPE, 2)) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOne2DShortArray", "()[[S", false);
} else if (isArrayOfTypeAndDimensions(type, Type.INT_TYPE, 2)) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOne2DIntegerArray", "()[[I", false);
} else if (isArrayOfTypeAndDimensions(type, Type.LONG_TYPE, 2)) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOne2DLongArray", "()[[J", false);
} else if (isArrayOfTypeAndDimensions(type, Type.FLOAT_TYPE, 2)) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOne2DFloatArray", "()[[F", false);
} else if (isArrayOfTypeAndDimensions(type, Type.DOUBLE_TYPE, 2)) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOne2DDoubleArray", "()[[D", false);
} else if (type.getSort() == Type.ARRAY && type.getDimensions() == 1 && isString(type.getElementType())) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOneStringArray", "()[Ljava/lang/String;", false);
} else if (type.getSort() == Type.ARRAY && type.getDimensions() == 1 && isAddress(type.getElementType())) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOneAddressArray", "()[Lavm/Address;", false);
} else if(type.getSort() == Type.ARRAY && type.getDimensions() == 1 && isBigInteger(type.getElementType())) {
methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "org/aion/avm/userlib/abi/ABIDecoder", "decodeOneBigIntegerArray", "()[Ljava/math/BigInteger;", false);
} else {
throw new ABICompilerException("Need to decode an unsupported ABI type");
}
}
void pushStack(StackInfo info) {
super.visitIntInsn(SIPUSH, info.stackSize());
super.visitTypeInsn(ANEWARRAY, "java/lang/Object");
for (int i = info.stackSize() - 1; i >= 0; --i) {
Type t = info.getStack(i);
if (t != null) {
if (t == Type.BOOLEAN_TYPE || t == Type.BYTE_TYPE || t == Type.SHORT_TYPE || t == Type.INT_TYPE || t == Type.CHAR_TYPE) {
super.visitInsn(DUP_X1);
super.visitInsn(SWAP);
super.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
super.visitIntInsn(SIPUSH, i);
super.visitInsn(SWAP);
} else if (t == Type.FLOAT_TYPE) {
super.visitInsn(DUP_X1);
super.visitInsn(SWAP);
super.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false);
super.visitIntInsn(SIPUSH, i);
super.visitInsn(SWAP);
} else if (t == Type.LONG_TYPE) {
super.visitInsn(DUP_X2);
super.visitInsn(DUP_X2);
super.visitInsn(POP);
super.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false);
super.visitIntInsn(SIPUSH, i);
super.visitInsn(SWAP);
} else if (t == Type.DOUBLE_TYPE) {
super.visitInsn(DUP_X2);
super.visitInsn(DUP_X2);
super.visitInsn(POP);
super.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false);
super.visitIntInsn(SIPUSH, i);
super.visitInsn(SWAP);
} else {
super.visitInsn(DUP_X1);
super.visitInsn(SWAP);
super.visitIntInsn(SIPUSH, i);
super.visitInsn(SWAP);
}
super.visitInsn(AASTORE);
}
}
}
public void cast(final Type from, final Type to) {
if (from != to) {
if (from == Type.DOUBLE_TYPE) {
if (to == Type.FLOAT_TYPE) {
mv.visitInsn(Opcodes.D2F);
} else if (to == Type.LONG_TYPE) {
mv.visitInsn(Opcodes.D2L);
} else {
mv.visitInsn(Opcodes.D2I);
cast(Type.INT_TYPE, to);
}
} else if (from == Type.FLOAT_TYPE) {
if (to == Type.DOUBLE_TYPE) {
mv.visitInsn(Opcodes.F2D);
} else if (to == Type.LONG_TYPE) {
mv.visitInsn(Opcodes.F2L);
} else {
mv.visitInsn(Opcodes.F2I);
cast(Type.INT_TYPE, to);
}
} else if (from == Type.LONG_TYPE) {
if (to == Type.DOUBLE_TYPE) {
mv.visitInsn(Opcodes.L2D);
} else if (to == Type.FLOAT_TYPE) {
mv.visitInsn(Opcodes.L2F);
} else {
mv.visitInsn(Opcodes.L2I);
cast(Type.INT_TYPE, to);
}
} else {
if (to == Type.BYTE_TYPE) {
mv.visitInsn(Opcodes.I2B);
} else if (to == Type.CHAR_TYPE) {
mv.visitInsn(Opcodes.I2C);
} else if (to == Type.DOUBLE_TYPE) {
mv.visitInsn(Opcodes.I2D);
} else if (to == Type.FLOAT_TYPE) {
mv.visitInsn(Opcodes.I2F);
} else if (to == Type.LONG_TYPE) {
mv.visitInsn(Opcodes.I2L);
} else if (to == Type.SHORT_TYPE) {
mv.visitInsn(Opcodes.I2S);
}
}
}
}
/**
* Generates the instructions to cast a numerical value from one type to another.
*
* @param from the type of the top stack value
* @param to the type into which this value must be cast.
*/
public void cast(final Type from, final Type to) {
if (from != to) {
if (from.getSort() < Type.BOOLEAN
|| from.getSort() > Type.DOUBLE
|| to.getSort() < Type.BOOLEAN
|| to.getSort() > Type.DOUBLE) {
throw new IllegalArgumentException("Cannot cast from " + from + " to " + to);
}
if (from == Type.DOUBLE_TYPE) {
if (to == Type.FLOAT_TYPE) {
mv.visitInsn(Opcodes.D2F);
} else if (to == Type.LONG_TYPE) {
mv.visitInsn(Opcodes.D2L);
} else {
mv.visitInsn(Opcodes.D2I);
cast(Type.INT_TYPE, to);
}
} else if (from == Type.FLOAT_TYPE) {
if (to == Type.DOUBLE_TYPE) {
mv.visitInsn(Opcodes.F2D);
} else if (to == Type.LONG_TYPE) {
mv.visitInsn(Opcodes.F2L);
} else {
mv.visitInsn(Opcodes.F2I);
cast(Type.INT_TYPE, to);
}
} else if (from == Type.LONG_TYPE) {
if (to == Type.DOUBLE_TYPE) {
mv.visitInsn(Opcodes.L2D);
} else if (to == Type.FLOAT_TYPE) {
mv.visitInsn(Opcodes.L2F);
} else {
mv.visitInsn(Opcodes.L2I);
cast(Type.INT_TYPE, to);
}
} else {
if (to == Type.BYTE_TYPE) {
mv.visitInsn(Opcodes.I2B);
} else if (to == Type.CHAR_TYPE) {
mv.visitInsn(Opcodes.I2C);
} else if (to == Type.DOUBLE_TYPE) {
mv.visitInsn(Opcodes.I2D);
} else if (to == Type.FLOAT_TYPE) {
mv.visitInsn(Opcodes.I2F);
} else if (to == Type.LONG_TYPE) {
mv.visitInsn(Opcodes.I2L);
} else if (to == Type.SHORT_TYPE) {
mv.visitInsn(Opcodes.I2S);
}
}
}
}
private void recreateStack(StackInfo info) {
if (info.stackSize() == 0)
return;
visitVarInsn(ALOAD, 0);
visitFieldInsn(GETFIELD, currentClassName, "__stack", "Ljava/util/Stack;");
visitVarInsn(ALOAD, 0);
visitFieldInsn(GETFIELD, currentClassName, "__stackPosition", "I");
visitMethodInsn(INVOKEVIRTUAL, "java/util/Stack", "get", "(I)Ljava/lang/Object;");
visitTypeInsn(CHECKCAST, "org/copperengine/core/StackEntry");
visitFieldInsn(GETFIELD, "org/copperengine/core/StackEntry", "stack", "[Ljava/lang/Object;");
for (int i = 0; i < info.stackSize(); ++i) {
Type t = info.getStack(i);
if (t != null) {
if (t != StackInfo.AconstNullType) {
super.visitInsn(DUP);
super.visitIntInsn(SIPUSH, i);
super.visitInsn(AALOAD);
} else {
super.visitInsn(ACONST_NULL);
}
if (t == Type.BOOLEAN_TYPE || t == Type.BYTE_TYPE || t == Type.SHORT_TYPE || t == Type.INT_TYPE || t == Type.CHAR_TYPE) {
super.visitTypeInsn(CHECKCAST, Type.getInternalName(Integer.class));
super.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false);
super.visitInsn(SWAP);
} else if (t == Type.FLOAT_TYPE) {
super.visitTypeInsn(CHECKCAST, Type.getInternalName(Float.class));
super.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false);
super.visitInsn(SWAP);
} else if (t == Type.LONG_TYPE) {
super.visitTypeInsn(CHECKCAST, Type.getInternalName(Long.class));
super.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false);
super.visitInsn(DUP2_X1);
super.visitInsn(POP2);
} else if (t == Type.DOUBLE_TYPE) {
super.visitTypeInsn(CHECKCAST, Type.getInternalName(Double.class));
super.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false);
super.visitInsn(DUP2_X1);
super.visitInsn(POP2);
} else {
if (!t.getInternalName().equals(Type.getInternalName(Object.class)) && t != StackInfo.AconstNullType)
super.visitTypeInsn(CHECKCAST, t.getInternalName());
super.visitInsn(SWAP);
}
}
}
super.visitInsn(POP);
}
/**
* Generates the instructions to cast a numerical value from one type to another.
*
* @param from the type of the top stack value
* @param to the type into which this value must be cast.
*/
public void cast(final Type from, final Type to) {
if (from != to) {
if (from.getSort() < Type.BOOLEAN
|| from.getSort() > Type.DOUBLE
|| to.getSort() < Type.BOOLEAN
|| to.getSort() > Type.DOUBLE) {
throw new IllegalArgumentException("Cannot cast from " + from + " to " + to);
}
if (from == Type.DOUBLE_TYPE) {
if (to == Type.FLOAT_TYPE) {
mv.visitInsn(Opcodes.D2F);
} else if (to == Type.LONG_TYPE) {
mv.visitInsn(Opcodes.D2L);
} else {
mv.visitInsn(Opcodes.D2I);
cast(Type.INT_TYPE, to);
}
} else if (from == Type.FLOAT_TYPE) {
if (to == Type.DOUBLE_TYPE) {
mv.visitInsn(Opcodes.F2D);
} else if (to == Type.LONG_TYPE) {
mv.visitInsn(Opcodes.F2L);
} else {
mv.visitInsn(Opcodes.F2I);
cast(Type.INT_TYPE, to);
}
} else if (from == Type.LONG_TYPE) {
if (to == Type.DOUBLE_TYPE) {
mv.visitInsn(Opcodes.L2D);
} else if (to == Type.FLOAT_TYPE) {
mv.visitInsn(Opcodes.L2F);
} else {
mv.visitInsn(Opcodes.L2I);
cast(Type.INT_TYPE, to);
}
} else {
if (to == Type.BYTE_TYPE) {
mv.visitInsn(Opcodes.I2B);
} else if (to == Type.CHAR_TYPE) {
mv.visitInsn(Opcodes.I2C);
} else if (to == Type.DOUBLE_TYPE) {
mv.visitInsn(Opcodes.I2D);
} else if (to == Type.FLOAT_TYPE) {
mv.visitInsn(Opcodes.I2F);
} else if (to == Type.LONG_TYPE) {
mv.visitInsn(Opcodes.I2L);
} else if (to == Type.SHORT_TYPE) {
mv.visitInsn(Opcodes.I2S);
}
}
}
}
/**
* Generates the instruction to cast from the first given type to the other.
*
* @param from a Type.
* @param to a Type.
*/
public void cast(final Type from, final Type to) {
if (from != to) {
if (from == Type.DOUBLE_TYPE) {
if (to == Type.FLOAT_TYPE) {
mv.visitInsn(Opcodes.D2F);
} else if (to == Type.LONG_TYPE) {
mv.visitInsn(Opcodes.D2L);
} else {
mv.visitInsn(Opcodes.D2I);
cast(Type.INT_TYPE, to);
}
} else if (from == Type.FLOAT_TYPE) {
if (to == Type.DOUBLE_TYPE) {
mv.visitInsn(Opcodes.F2D);
} else if (to == Type.LONG_TYPE) {
mv.visitInsn(Opcodes.F2L);
} else {
mv.visitInsn(Opcodes.F2I);
cast(Type.INT_TYPE, to);
}
} else if (from == Type.LONG_TYPE) {
if (to == Type.DOUBLE_TYPE) {
mv.visitInsn(Opcodes.L2D);
} else if (to == Type.FLOAT_TYPE) {
mv.visitInsn(Opcodes.L2F);
} else {
mv.visitInsn(Opcodes.L2I);
cast(Type.INT_TYPE, to);
}
} else {
if (to == Type.BYTE_TYPE) {
mv.visitInsn(Opcodes.I2B);
} else if (to == Type.CHAR_TYPE) {
mv.visitInsn(Opcodes.I2C);
} else if (to == Type.DOUBLE_TYPE) {
mv.visitInsn(Opcodes.I2D);
} else if (to == Type.FLOAT_TYPE) {
mv.visitInsn(Opcodes.I2F);
} else if (to == Type.LONG_TYPE) {
mv.visitInsn(Opcodes.I2L);
} else if (to == Type.SHORT_TYPE) {
mv.visitInsn(Opcodes.I2S);
}
}
}
}
/**
* Generates the instructions to cast a numerical value from one type to another.
*
* @param from the type of the top stack value
* @param to the type into which this value must be cast.
*/
public void cast(final Type from, final Type to) {
if (from != to) {
if (from.getSort() < Type.BOOLEAN
|| from.getSort() > Type.DOUBLE
|| to.getSort() < Type.BOOLEAN
|| to.getSort() > Type.DOUBLE) {
throw new IllegalArgumentException("Cannot cast from " + from + " to " + to);
}
if (from == Type.DOUBLE_TYPE) {
if (to == Type.FLOAT_TYPE) {
mv.visitInsn(Opcodes.D2F);
} else if (to == Type.LONG_TYPE) {
mv.visitInsn(Opcodes.D2L);
} else {
mv.visitInsn(Opcodes.D2I);
cast(Type.INT_TYPE, to);
}
} else if (from == Type.FLOAT_TYPE) {
if (to == Type.DOUBLE_TYPE) {
mv.visitInsn(Opcodes.F2D);
} else if (to == Type.LONG_TYPE) {
mv.visitInsn(Opcodes.F2L);
} else {
mv.visitInsn(Opcodes.F2I);
cast(Type.INT_TYPE, to);
}
} else if (from == Type.LONG_TYPE) {
if (to == Type.DOUBLE_TYPE) {
mv.visitInsn(Opcodes.L2D);
} else if (to == Type.FLOAT_TYPE) {
mv.visitInsn(Opcodes.L2F);
} else {
mv.visitInsn(Opcodes.L2I);
cast(Type.INT_TYPE, to);
}
} else {
if (to == Type.BYTE_TYPE) {
mv.visitInsn(Opcodes.I2B);
} else if (to == Type.CHAR_TYPE) {
mv.visitInsn(Opcodes.I2C);
} else if (to == Type.DOUBLE_TYPE) {
mv.visitInsn(Opcodes.I2D);
} else if (to == Type.FLOAT_TYPE) {
mv.visitInsn(Opcodes.I2F);
} else if (to == Type.LONG_TYPE) {
mv.visitInsn(Opcodes.I2L);
} else if (to == Type.SHORT_TYPE) {
mv.visitInsn(Opcodes.I2S);
}
}
}
}