下面列出了org.objectweb.asm.Type#DOUBLE_TYPE 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
public static int getVariableStoreOpcode(Type type) {
if (type.getSort() >= Type.BOOLEAN && type.getSort() <= Type.INT) {
return Opcodes.ISTORE;
} else if (type == Type.LONG_TYPE) {
return Opcodes.LSTORE;
} else if (type == Type.FLOAT_TYPE) {
return Opcodes.FSTORE;
} else if (type == Type.DOUBLE_TYPE) {
return Opcodes.DSTORE;
} else if (type.getSort() >= Type.ARRAY && type.getSort() <= Type.OBJECT) {
return Opcodes.ASTORE;
} else {
return getVariableStoreOpcode(asSimpleType(type));
// throw new IllegalArgumentException(type.toString());
}
}
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));
}
}
@Override
public void visitVarInsn(final int opcode, final int var) {
Type varType;
switch (opcode) {
case Opcodes.LLOAD:
case Opcodes.LSTORE:
varType = Type.LONG_TYPE;
break;
case Opcodes.DLOAD:
case Opcodes.DSTORE:
varType = Type.DOUBLE_TYPE;
break;
case Opcodes.FLOAD:
case Opcodes.FSTORE:
varType = Type.FLOAT_TYPE;
break;
case Opcodes.ILOAD:
case Opcodes.ISTORE:
varType = Type.INT_TYPE;
break;
case Opcodes.ALOAD:
case Opcodes.ASTORE:
case Opcodes.RET:
varType = OBJECT_TYPE;
break;
default:
throw new IllegalArgumentException("Invalid opcode " + opcode);
}
super.visitVarInsn(opcode, remap(var, varType));
}
public static Type getType(VarInsnNode abstractInsnNode) {
int offset;
if (abstractInsnNode.getOpcode() >= ISTORE && abstractInsnNode.getOpcode() <= ASTORE)
offset = abstractInsnNode.getOpcode() - ISTORE;
else if (abstractInsnNode.getOpcode() >= ILOAD && abstractInsnNode.getOpcode() <= ALOAD)
offset = abstractInsnNode.getOpcode() - ILOAD;
else if (abstractInsnNode.getOpcode() == RET)
throw new UnsupportedOperationException("RET is not supported");
else
throw new UnsupportedOperationException();
switch (offset) {
case 0:
return Type.INT_TYPE;
case LLOAD - ILOAD:
return Type.LONG_TYPE;
case FLOAD - ILOAD:
return Type.FLOAT_TYPE;
case DLOAD - ILOAD:
return Type.DOUBLE_TYPE;
case ALOAD - ILOAD:
return Type.getType("Ljava/lang/Object;");
}
throw new UnsupportedOperationException();
}
public static Type resolveUnaryOpType(Type type) {
if (type.getSort() >= Type.BOOLEAN && type.getSort() <= Type.INT) {
return Type.INT_TYPE;
} else if (type == Type.LONG_TYPE || type == Type.FLOAT_TYPE || type == Type.DOUBLE_TYPE) {
return type;
} else {
throw new UnsupportedOperationException("Unsupported binop types: " + type);
}
}
public static Type getLoadType(int opcode) {
if (opcode == ILOAD) {
return Type.INT_TYPE;
} else if (opcode == LLOAD) {
return Type.LONG_TYPE;
} else if (opcode == FLOAD) {
return Type.FLOAT_TYPE;
} else if (opcode == DLOAD) {
return Type.DOUBLE_TYPE;
} else if (opcode == ALOAD) {
return OBJECT_TYPE;
} else {
throw new IllegalArgumentException(Printer.OPCODES[opcode]);
}
}
@Override
public void visitVarInsn(final int opcode, final int var) {
Type varType;
switch (opcode) {
case Opcodes.LLOAD:
case Opcodes.LSTORE:
varType = Type.LONG_TYPE;
break;
case Opcodes.DLOAD:
case Opcodes.DSTORE:
varType = Type.DOUBLE_TYPE;
break;
case Opcodes.FLOAD:
case Opcodes.FSTORE:
varType = Type.FLOAT_TYPE;
break;
case Opcodes.ILOAD:
case Opcodes.ISTORE:
varType = Type.INT_TYPE;
break;
case Opcodes.ALOAD:
case Opcodes.ASTORE:
case Opcodes.RET:
varType = OBJECT_TYPE;
break;
default:
throw new IllegalArgumentException("Invalid opcode " + opcode);
}
super.visitVarInsn(opcode, remap(var, varType));
}
public static int getAddOpcode(Type type) {
if (type == Type.INT_TYPE) {
return IADD;
} else if (type == Type.LONG_TYPE) {
return LADD;
} else if (type == Type.FLOAT_TYPE) {
return FADD;
} else if (type == Type.DOUBLE_TYPE) {
return DADD;
} else {
throw new IllegalArgumentException(type.toString());
}
}
public static int getMultiplyOpcode(Type type) {
if (type == Type.INT_TYPE) {
return IMUL;
} else if (type == Type.LONG_TYPE) {
return LMUL;
} else if (type == Type.FLOAT_TYPE) {
return FMUL;
} else if (type == Type.DOUBLE_TYPE) {
return DMUL;
} else {
throw new IllegalArgumentException(type.toString());
}
}
@Override
public EvaluationFunctor<Number> compare(Type lt, Type rt, ComparisonExpr.ValueComparisonType type) {
String name = lt.getClassName() + type.name() + rt.getClassName() + "RETint";
if(cache.containsKey(name)) {
return _get(name);
}
String desc = "(" + lt.getDescriptor() + rt.getDescriptor() + ")I";
MethodNode m = makeBase(name, desc);
{
Type opType = TypeUtils.resolveBinOpType(lt, rt);
InsnList insns = new InsnList();
insns.add(new VarInsnNode(TypeUtils.getVariableLoadOpcode(lt), 0));
cast(insns, lt, opType);
insns.add(new VarInsnNode(TypeUtils.getVariableLoadOpcode(rt), lt.getSize()));
cast(insns, rt, opType);
int op;
if (opType == Type.DOUBLE_TYPE) {
op = type == ComparisonExpr.ValueComparisonType.GT ? Opcodes.DCMPG : Opcodes.DCMPL;
} else if (opType == Type.FLOAT_TYPE) {
op = type == ComparisonExpr.ValueComparisonType.GT ? Opcodes.FCMPG : Opcodes.FCMPL;
} else if (opType == Type.LONG_TYPE) {
op = Opcodes.LCMP;
} else {
throw new IllegalArgumentException();
}
insns.add(new InsnNode(op));
insns.add(new InsnNode(Opcodes.IRETURN));
m.node.instructions = insns;
}
return buildBridge(m);
}
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());
}
}
public static Type resolveType(int bOpcode) {
switch(bOpcode) {
case IADD:
case ISUB:
case IMUL:
case IDIV:
case IREM:
case INEG:
case ISHL:
case ISHR:
case IUSHR:
case IAND:
case IOR:
case IXOR:
return Type.INT_TYPE;
case LADD:
case LSUB:
case LMUL:
case LDIV:
case LREM:
case LNEG:
case LSHL:
case LSHR:
case LUSHR:
case LAND:
case LOR:
case LXOR:
return Type.LONG_TYPE;
case FADD:
case FSUB:
case FMUL:
case FDIV:
case FREM:
case FNEG:
return Type.FLOAT_TYPE;
case DADD:
case DSUB:
case DMUL:
case DDIV:
case DREM:
case DNEG:
return Type.DOUBLE_TYPE;
default:
throw new UnsupportedOperationException(Printer.OPCODES[bOpcode]);
}
}
@Override
public int getSize() {
return type == Type.LONG_TYPE || type == Type.DOUBLE_TYPE ? 2 : 1;
}
@Override
public int getSize() {
return type == Type.LONG_TYPE || type == Type.DOUBLE_TYPE ? 2 : 1;
}
/**
* 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);
}
}
}
}
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);
}
@Override
public EvaluationFunctor<Boolean> branch(Type lt, Type rt, ConditionalJumpStmt.ComparisonType type) {
Type opType = TypeUtils.resolveBinOpType(lt, rt);
String name = lt.getClassName() + type.name() + rt.getClassName() + "OPTYPE" + opType.getClassName() + "RETbool";
String desc = "(" + lt.getDescriptor() + rt.getDescriptor() + ")Z";
if(cache.containsKey(name)) {
return _get(name);
}
MethodNode m = makeBase(name, desc);
{
InsnList insns = new InsnList();
insns.add(new VarInsnNode(TypeUtils.getVariableLoadOpcode(lt), 0));
cast(insns, lt, opType);
insns.add(new VarInsnNode(TypeUtils.getVariableLoadOpcode(rt), lt.getSize()));
cast(insns, rt, opType);
LabelNode trueSuccessor = new LabelNode();
if (opType == Type.INT_TYPE) {
insns.add(new JumpInsnNode(Opcodes.IF_ICMPEQ + type.ordinal(), trueSuccessor));
} else if (opType == Type.LONG_TYPE) {
insns.add(new InsnNode(Opcodes.LCMP));
insns.add(new JumpInsnNode(Opcodes.IFEQ + type.ordinal(), trueSuccessor));
} else if (opType == Type.FLOAT_TYPE) {
insns.add(new InsnNode((type == ConditionalJumpStmt.ComparisonType.LT || type == ConditionalJumpStmt.ComparisonType.LE) ? Opcodes.FCMPL : Opcodes.FCMPG));
insns.add(new JumpInsnNode(Opcodes.IFEQ + type.ordinal(), trueSuccessor));
} else if (opType == Type.DOUBLE_TYPE) {
insns.add(new InsnNode((type == ConditionalJumpStmt.ComparisonType.LT || type == ConditionalJumpStmt.ComparisonType.LE) ? Opcodes.DCMPL : Opcodes.DCMPG));
insns.add(new JumpInsnNode(Opcodes.IFEQ + type.ordinal(), trueSuccessor));
} else {
throw new IllegalArgumentException(opType.toString());
}
branchReturn(insns, trueSuccessor);
m.node.instructions = insns;
}
return buildBridge(m);
}
public static InsnValue doubleValue(Object cst) {
return new InsnValue(Type.DOUBLE_TYPE, cst);
}
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);
}