下面列出了org.objectweb.asm.Opcodes# DCMPL 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private boolean matchesConditionalInsn(int last, AbstractInsnNode insn) {
for (int conditionalOpcode : this.expandOpcodes) {
int opcode = insn.getOpcode();
if (opcode == conditionalOpcode) {
if (last == Opcodes.LCMP || last == Opcodes.FCMPL || last == Opcodes.FCMPG || last == Opcodes.DCMPL || last == Opcodes.DCMPG) {
this.log(" BeforeConstant is ignoring {} following {}", Bytecode.getOpcodeName(opcode), Bytecode.getOpcodeName(last));
return false;
}
this.log(" BeforeConstant found {} instruction", Bytecode.getOpcodeName(opcode));
return true;
}
}
if (this.intValue != null && this.intValue.intValue() == 0 && Bytecode.isConstant(insn)) {
Object value = Bytecode.getConstant(insn);
this.log(" BeforeConstant found INTEGER constant: value = {}", value);
return value instanceof Integer && ((Integer)value).intValue() == 0;
}
return false;
}
@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 InsnValue compareConstants(AbstractInsnNode insn, InsnValue value1, InsnValue value2) {
Object o = value1.getValue(), oo = value2.getValue();
if (o == null || oo == null) {
// Can't compare since the values haven't been resolved.
return InsnValue.INT_VALUE;
}
int v = 0;
switch (insn.getOpcode()) {
case Opcodes.LCMP:
long l1 = (long) o, l2 = (long) oo;
v = (l1 == l2) ? 0 : (l2 < l1) ? 1 : -1;
break;
case Opcodes.FCMPL:
case Opcodes.FCMPG:
float f1 = (float) o, f2 = (float) oo;
if (f1 == Float.NaN || f2 == Float.NaN) {
v = insn.getOpcode() == Opcodes.FCMPG ? -1 : 1;
} else {
v = (f1 == f2) ? 0 : (f2 < f1) ? 1 : -1;
}
break;
case Opcodes.DCMPL:
case Opcodes.DCMPG:
double d1 = (float) o, d2 = (double) oo;
if (d1 == Float.NaN || d2 == Float.NaN) {
v = insn.getOpcode() == Opcodes.DCMPG ? -1 : 1;
} else {
v = (d1 == d2) ? 0 : (d2 < d1) ? 1 : -1;
}
break;
case Opcodes.IF_ICMPEQ:
case Opcodes.IF_ICMPNE:
case Opcodes.IF_ICMPLT:
case Opcodes.IF_ICMPGE:
case Opcodes.IF_ICMPGT:
case Opcodes.IF_ICMPLE:
int i1 = (int) o, i2 = (int) oo;
switch (insn.getOpcode()) {
case Opcodes.IF_ICMPEQ:
v = i2 == i1 ? 1 : 0;
break;
case Opcodes.IF_ICMPNE:
v = i2 != i1 ? 1 : 0;
break;
case Opcodes.IF_ICMPLT:
v = i2 < i1 ? 1 : 0;
break;
case Opcodes.IF_ICMPLE:
v = i2 <= i1 ? 1 : 0;
break;
case Opcodes.IF_ICMPGE:
v = i2 >= i1 ? 1 : 0;
break;
case Opcodes.IF_ICMPGT:
v = i2 > i1 ? 1 : 0;
break;
}
break;
case Opcodes.IF_ACMPEQ:
case Opcodes.IF_ACMPNE:
v = ((insn.getOpcode() == Opcodes.IF_ACMPNE) ? !o.equals(oo) : o.equals(oo)) ? 1 : 0;
break;
}
return InsnValue.intValue(v);
}
public static boolean isBinaryOp(Instruction instr) {
switch (instr.getOpcode()) {
case Opcodes.ISHL:
case Opcodes.ISHR:
case Opcodes.LSHL:
case Opcodes.LSHR:
case Opcodes.IUSHR:
case Opcodes.LUSHR:
case Opcodes.DCMPG:
case Opcodes.DCMPL:
case Opcodes.FCMPG:
case Opcodes.FCMPL:
case Opcodes.LCMP:
case Opcodes.IOR:
case Opcodes.LOR:
case Opcodes.IXOR:
case Opcodes.LXOR:
case Opcodes.IAND:
case Opcodes.LAND:
case Opcodes.FADD:
case Opcodes.DADD:
case Opcodes.IADD:
case Opcodes.LADD:
case Opcodes.FSUB:
case Opcodes.DSUB:
case Opcodes.ISUB:
case Opcodes.LSUB:
case Opcodes.FDIV:
case Opcodes.DDIV:
case Opcodes.LDIV:
case Opcodes.IDIV:
case Opcodes.IREM:
case Opcodes.FREM:
case Opcodes.DREM:
case Opcodes.LREM:
case Opcodes.FMUL:
case Opcodes.DMUL:
case Opcodes.IMUL:
case Opcodes.LMUL:
return true;
}
return false;
}
public static boolean isArithmeticOp(Instruction instr) {
switch (instr.getOpcode()) {
case Opcodes.ISHL:
case Opcodes.ISHR:
case Opcodes.LSHL:
case Opcodes.LSHR:
case Opcodes.IUSHR:
case Opcodes.LUSHR:
case Opcodes.DCMPG:
case Opcodes.DCMPL:
case Opcodes.FCMPG:
case Opcodes.FCMPL:
case Opcodes.LCMP:
case Opcodes.FNEG:
case Opcodes.DNEG:
case Opcodes.INEG:
case Opcodes.D2F:
case Opcodes.D2I:
case Opcodes.D2L:
case Opcodes.F2D:
case Opcodes.F2I:
case Opcodes.F2L:
case Opcodes.L2D:
case Opcodes.L2F:
case Opcodes.L2I:
case Opcodes.I2L:
case Opcodes.I2B:
case Opcodes.I2C:
case Opcodes.I2D:
case Opcodes.I2F:
case Opcodes.I2S:
case Opcodes.IOR:
case Opcodes.LOR:
case Opcodes.IXOR:
case Opcodes.LXOR:
case Opcodes.IAND:
case Opcodes.LAND:
case Opcodes.FADD:
case Opcodes.DADD:
case Opcodes.IADD:
case Opcodes.LADD:
case Opcodes.FSUB:
case Opcodes.DSUB:
case Opcodes.ISUB:
case Opcodes.LSUB:
case Opcodes.FDIV:
case Opcodes.DDIV:
case Opcodes.LDIV:
case Opcodes.IDIV:
case Opcodes.IREM:
case Opcodes.FREM:
case Opcodes.DREM:
case Opcodes.LREM:
case Opcodes.FMUL:
case Opcodes.DMUL:
case Opcodes.IMUL:
case Opcodes.LMUL:
return true;
}
return false;
}