下面列出了org.objectweb.asm.Type#INT_TYPE 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
static Type deferLocalDesc(Object object) {
if (object instanceof String)
return Type.getObjectType((String) object);
// TODO: analyze opcode at pos label
if (object instanceof Label)
return Type.getType(Object.class);
int intObject = (Integer) object;
if (intObject == Opcodes.TOP)
return null;
if (intObject == Opcodes.INTEGER)
return Type.INT_TYPE;
if (intObject == Opcodes.FLOAT)
return Type.FLOAT_TYPE;
if (intObject == Opcodes.LONG)
return Type.LONG_TYPE;
if (intObject == Opcodes.DOUBLE)
return Type.getType(double.class);
if (intObject == Opcodes.LONG)
return Type.getType(long.class);
if (intObject == Opcodes.NULL)
return Type.getType(Object.class);
// TODO: defer from containing class
if (intObject == Opcodes.UNINITIALIZED_THIS)
return Type.getType(Object.class);
throw new BuildStackFrameException("Couldnt defer desc for " + object);
}
/**
* @param cst
* @return
*/
private static Type typeFromClass ( Object cst ) {
if ( cst instanceof Integer ) {
return Type.INT_TYPE;
}
else if ( cst instanceof Float ) {
return Type.FLOAT_TYPE;
}
else if ( cst instanceof Long ) {
return Type.LONG_TYPE;
}
else if ( cst instanceof Double ) {
return Type.DOUBLE_TYPE;
}
return Type.getType(cst.getClass());
}
public void testSynthCopyStmt() throws Throwable {
VarExpr v = new VarExpr(new VersionedLocal(1, 0), Type.INT_TYPE);
CopyVarStmt stmt = new CopyVarStmt(v, v, true);
assertEquals(v, stmt.getVariable());
assertEquals(v, stmt.getExpression());
testOutOfBoundsWrite(stmt, stmt.getClass());
}
Type[] getArrayArgs(Type... extra) {
int dimensions = this.getTotalDimensions();
Type[] args = new Type[dimensions + extra.length];
for (int i = 0; i < args.length; i++) {
args[i] = i == 0 ? this.type : i < dimensions ? Type.INT_TYPE : extra[dimensions - i];
}
return args;
}
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);
}
}
}
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 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]);
}
}
/**
* Test method for {@link AnnotationInfo#annotationParameterSize()} .
*/
public void testAnnotationParameterSize() {
final String name = "newParam";
final String val = String.valueOf(34);
final Type type = Type.INT_TYPE;
infoMain.addAnnotationParameter(name, val, type);
assertEquals(1, infoMain.annotationParameterSize());
}
public static int getRemainderOpcode(Type type) {
if (type == Type.INT_TYPE) {
return IREM;
} else if (type == Type.LONG_TYPE) {
return LREM;
} else if (type == Type.FLOAT_TYPE) {
return FREM;
} else if (type == Type.DOUBLE_TYPE) {
return DREM;
} else {
throw new IllegalArgumentException(type.toString());
}
}
public static int getBitShiftLeftOpcode(Type type) {
if (type == Type.INT_TYPE) {
return ISHL;
} else if (type == Type.LONG_TYPE) {
return LSHL;
} else {
throw new IllegalArgumentException(type.toString());
}
}
/**
* @param arg
* Operand value of a NEWARRAY instruction.
*
* @return Array element type.
*/
public static Type newArrayArgToType(int arg) {
switch(arg) {
case 4: return Type.BOOLEAN_TYPE;
case 5: return Type.CHAR_TYPE;
case 6: return Type.FLOAT_TYPE;
case 7: return Type.DOUBLE_TYPE;
case 8: return Type.BYTE_TYPE;
case 9: return Type.SHORT_TYPE;
case 10: return Type.INT_TYPE;
case 11: return Type.LONG_TYPE;
default: break;
}
throw new IllegalArgumentException("Unexpected NEWARRAY arg: " + arg);
}
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);
}
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<Number> arithmetic(Type t1, Type t2, Type rt, ArithmeticExpr.Operator op) {
String name = t1.getClassName() + op.name() + t2.getClassName() + "RET" + rt.getClassName();
if(cache.containsKey(name)) {
return _get(name);
}
String desc = ("(" + t1.getDescriptor() + t2.getDescriptor() + ")" + rt.getDescriptor());
MethodNode m = makeBase(name, desc);
InsnList insns = new InsnList();
{
Type leftType = null;
Type rightType = null;
if (op == ArithmeticExpr.Operator.SHL || op == ArithmeticExpr.Operator.SHR || op == ArithmeticExpr.Operator.USHR) {
leftType = rt;
rightType = Type.INT_TYPE;
} else {
leftType = rightType = rt;
}
insns.add(new VarInsnNode(TypeUtils.getVariableLoadOpcode(t1), 0));
cast(insns, t1, leftType);
insns.add(new VarInsnNode(TypeUtils.getVariableLoadOpcode(t2), t1.getSize() /*D,J=2, else 1*/));
cast(insns, t2, rightType);
int opcode;
switch (op) {
case ADD:
opcode = TypeUtils.getAddOpcode(rt);
break;
case SUB:
opcode = TypeUtils.getSubtractOpcode(rt);
break;
case MUL:
opcode = TypeUtils.getMultiplyOpcode(rt);
break;
case DIV:
opcode = TypeUtils.getDivideOpcode(rt);
break;
case REM:
opcode = TypeUtils.getRemainderOpcode(rt);
break;
case SHL:
opcode = TypeUtils.getBitShiftLeftOpcode(rt);
break;
case SHR:
opcode = TypeUtils.bitShiftRightOpcode(rt);
break;
case USHR:
opcode = TypeUtils.getBitShiftRightUnsignedOpcode(rt);
break;
case OR:
opcode = TypeUtils.getBitOrOpcode(rt);
break;
case AND:
opcode = TypeUtils.getBitAndOpcode(rt);
break;
case XOR:
opcode = TypeUtils.getBitXorOpcode(rt);
break;
default:
throw new RuntimeException();
}
insns.add(new InsnNode(opcode));
insns.add(new InsnNode(TypeUtils.getReturnOpcode(rt)));
m.node.instructions = insns;
}
return buildBridge(m);
}
private void canThrowExpr(Expr u, Set<Type> set) {
switch(u.getOpcode()) {
case ARRAY_LOAD:
set.add(Type.getType(NullPointerException.class));
set.add(Type.getType(IndexOutOfBoundsException.class));
break;
case NEW_ARRAY:
set.add(Type.getType(NegativeArraySizeException.class));
set.add(Type.getType(IllegalAccessError.class));
break;
case ARRAY_LEN:
set.add(Type.getType(NullPointerException.class));
break;
case CAST:
set.add(Type.getType(NullPointerException.class));
set.add(Type.getType(ClassCastException.class));
break;
case INSTANCEOF:
set.add(Type.getType(ClassCastException.class));
break;
case FIELD_LOAD:{
// FIXME: depends on the lookup method
// and field access
set.add(Type.getType(IncompatibleClassChangeError.class));
set.add(Type.getType(NullPointerException.class));
break;
}
case ARITHMETIC: {
ArithmeticExpr ar = (ArithmeticExpr) u;
Operator op = ar.getOperator();
if(op == Operator.DIV || op == Operator.REM) {
Type t = ar.getType();
if(t == Type.INT_TYPE || t == Type.LONG_TYPE) {
set.add(Type.getType(ArithmeticException.class));
}
}
break;
}
case INVOKE:
if (((InvocationExpr) u).isDynamic())
throw new UnsupportedOperationException(u.toString());
set.add(ANY);
set.add(Type.getType(Error.class));
set.add(Type.getType(RuntimeException.class));
set.add(Type.getType(NullPointerException.class));
set.add(Type.getType(IncompatibleClassChangeError.class));
set.add(Type.getType(AbstractMethodError.class));
set.add(Type.getType(UnsatisfiedLinkError.class));
set.add(Type.getType(IllegalAccessError.class));
set.add(Type.getType(WrongMethodTypeException.class));
break;
case ALLOC_OBJ:
set.add(Type.getType(InstantiationError.class));
break;
case INIT_OBJ:
set.add(ANY);
set.add(Type.getType(Error.class));
set.add(Type.getType(RuntimeException.class));
set.add(Type.getType(InstantiationError.class));
set.add(Type.getType(NullPointerException.class));
set.add(Type.getType(IncompatibleClassChangeError.class));
set.add(Type.getType(AbstractMethodError.class));
set.add(Type.getType(UnsatisfiedLinkError.class));
set.add(Type.getType(IllegalAccessError.class));
set.add(Type.getType(WrongMethodTypeException.class));
break;
case COMPARE:
case NEGATE:
case PHI:
case EPHI:
case LOCAL_LOAD:
case CONST_LOAD:
case CATCH:
break;
default:
throw new UnsupportedOperationException(String.format("%s: %s", Opcode.opname(u.getOpcode()), u));
}
}
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]);
}
}
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);
}
}
}
@Override
public void toCode(MethodVisitor visitor, BytecodeFrontend assembler) {
Type leftType = null;
Type rightType = null;
if (operator == Operator.SHL || operator == Operator.SHR || operator == Operator.USHR) {
leftType = getType();
rightType = Type.INT_TYPE;
} else {
leftType = rightType = getType();
}
left.toCode(visitor, assembler);
int[] lCast = TypeUtils.getPrimitiveCastOpcodes(left.getType(), leftType);
for (int i = 0; i < lCast.length; i++)
visitor.visitInsn(lCast[i]);
right.toCode(visitor, assembler);
int[] rCast = TypeUtils.getPrimitiveCastOpcodes(right.getType(), rightType);
for (int i = 0; i < rCast.length; i++)
visitor.visitInsn(rCast[i]);
int opcode;
switch (operator) {
case ADD:
opcode = TypeUtils.getAddOpcode(getType());
break;
case SUB:
opcode = TypeUtils.getSubtractOpcode(getType());
break;
case MUL:
opcode = TypeUtils.getMultiplyOpcode(getType());
break;
case DIV:
opcode = TypeUtils.getDivideOpcode(getType());
break;
case REM:
opcode = TypeUtils.getRemainderOpcode(getType());
break;
case SHL:
opcode = TypeUtils.getBitShiftLeftOpcode(getType());
break;
case SHR:
opcode = TypeUtils.bitShiftRightOpcode(getType());
break;
case USHR:
opcode = TypeUtils.getBitShiftRightUnsignedOpcode(getType());
break;
case OR:
opcode = TypeUtils.getBitOrOpcode(getType());
break;
case AND:
opcode = TypeUtils.getBitAndOpcode(getType());
break;
case XOR:
opcode = TypeUtils.getBitXorOpcode(getType());
break;
default:
throw new RuntimeException();
}
visitor.visitInsn(opcode);
}
private static UnknownValue intSymbolicValue(AbstractInsnNode insnNode) {
return new UnknownValue(insnNode, Type.INT_TYPE);
}
public static InsnValue intValue(Object cst) {
return new InsnValue(Type.INT_TYPE, cst);
}