下面列出了org.objectweb.asm.Opcodes# FNEG 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Mutates a primitive float return (<code>Opcode.FRETURN</code>). The
* strategy used was translated from jumble BCEL code. The following is
* complicated by the problem of <tt>NaN</tt>s. By default the new value is
* <code>-(x + 1)</code>, but this doesn't work for <tt>NaN</tt>s. But for a
* <tt>NaN</tt> <code>x != x</code> is true, and we use this to detect them.
*
* @see #mutatePrimitiveDoubleReturn()
*/
private void mutatePrimitiveFloatReturn() {
if (shouldMutate("primitive float", "(x != NaN)? -(x + 1) : -1 ")) {
final Label label = new Label();
super.visitInsn(Opcodes.DUP);
super.visitInsn(Opcodes.DUP);
super.visitInsn(Opcodes.FCMPG);
super.visitJumpInsn(Opcodes.IFEQ, label);
super.visitInsn(Opcodes.POP);
super.visitInsn(Opcodes.FCONST_0);
// the following code is executed in NaN case, too
super.visitLabel(label);
super.visitInsn(Opcodes.FCONST_1);
super.visitInsn(Opcodes.FADD);
super.visitInsn(Opcodes.FNEG);
super.visitInsn(Opcodes.FRETURN);
}
}
public final void neg(Type type) {
switch (type.getOpcode(Opcodes.INEG)) {
case Opcodes.INEG:
ineg();
return;
case Opcodes.LNEG:
lneg();
return;
case Opcodes.FNEG:
fneg();
return;
case Opcodes.DNEG:
dneg();
return;
default:
throw new IllegalArgumentException();
}
}
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 InsnValue invertValue(AbstractInsnNode insn, InsnValue value) {
Object obj = value.getValue();
switch (insn.getOpcode()) {
case Opcodes.INEG:
if (obj == null) {
return InsnValue.INT_VALUE;
}
return InsnValue.intValue(-1 * (int) obj);
case Opcodes.LNEG:
if (obj == null) {
return InsnValue.LONG_VALUE;
}
return InsnValue.longValue(-1L * (long) obj);
case Opcodes.FNEG:
if (obj == null) {
return InsnValue.FLOAT_VALUE;
}
return InsnValue.floatValue(-1F * (float) obj);
case Opcodes.DNEG:
if (obj == null) {
return InsnValue.DOUBLE_VALUE;
}
return InsnValue.doubleValue(-1D * (double) obj);
}
return null;
}
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;
}