下面列出了org.objectweb.asm.Opcodes# IADD 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void mutatePrimitiveIntegerReturn() {
if (shouldMutate("primitive boolean/byte/short/integer",
"(x == 1) ? 0 : x + 1")) {
final Label label = new Label();
super.visitInsn(Opcodes.DUP);
super.visitInsn(Opcodes.ICONST_1);
super.visitJumpInsn(Opcodes.IF_ICMPEQ, label);
super.visitInsn(Opcodes.ICONST_1);
super.visitInsn(Opcodes.IADD);
super.visitInsn(Opcodes.IRETURN);
super.visitLabel(label);
super.visitInsn(Opcodes.ICONST_0);
super.visitInsn(Opcodes.IRETURN);
}
}
public final void add(Type type) {
switch (type.getOpcode(Opcodes.IADD)) {
case Opcodes.IADD:
iadd();
return;
case Opcodes.LADD:
ladd();
return;
case Opcodes.FADD:
fadd();
return;
case Opcodes.DADD:
dadd();
return;
default:
throw new IllegalArgumentException();
}
}
/**
* Determine if the given opcode is an ADD of some kind (xADD).
*
* @param opcode the opcode
* @return true if the opcode is one of the ADDs, false otherwise
*/
public static boolean isXadd(final int opcode) {
switch(opcode) {
case Opcodes.IADD:
case Opcodes.DADD:
case Opcodes.FADD:
case Opcodes.LADD:
return true;
}
return false;
}
public static int getOperatorOpcode(OperatorExprToken operator, StackItem.Type type){
if (operator instanceof PlusExprToken){
switch (type){
case DOUBLE: return Opcodes.DADD;
case FLOAT: return Opcodes.FADD;
case LONG: return Opcodes.LADD;
case BYTE:
case SHORT:
case INT: return Opcodes.IADD;
}
}
if (operator instanceof MinusExprToken){
switch (type){
case DOUBLE: return Opcodes.DSUB;
case FLOAT: return Opcodes.FSUB;
case LONG: return Opcodes.LSUB;
case BYTE:
case SHORT:
case INT: return Opcodes.ISUB;
}
}
if (operator instanceof MulExprToken){
switch (type){
case DOUBLE: return Opcodes.DMUL;
case FLOAT: return Opcodes.FMUL;
case LONG: return Opcodes.LMUL;
case BYTE:
case SHORT:
case INT: return Opcodes.IMUL;
}
}
throw new IllegalArgumentException("Unknown operator " + operator.getWord() + " for type " + type.name());
}
private List<AbstractInsnNode> getPossibleInsns2(AbstractInsnNode ain)
{
List<AbstractInsnNode> instrs = new ArrayList<>();
while(ain != null)
{
if(ain instanceof LineNumberNode || ain instanceof FrameNode)
{
ain = ain.getNext();
continue;
}
instrs.add(ain);
if(instrs.size() >= 14)
break;
ain = ain.getNext();
}
if(instrs.size() == 14 && instrs.get(0).getOpcode() == Opcodes.ILOAD
&& instrs.get(1).getOpcode() == Opcodes.ICONST_1
&& instrs.get(2).getOpcode() == Opcodes.ISUB
&& instrs.get(3).getOpcode() == Opcodes.ISTORE)
{
int var1 = ((VarInsnNode)instrs.get(0)).var;
int var2 = ((VarInsnNode)instrs.get(3)).var;
if(instrs.get(4).getOpcode() == Opcodes.ILOAD
&& ((VarInsnNode)instrs.get(4)).var == var1
&& instrs.get(5).getOpcode() == Opcodes.ILOAD
&& ((VarInsnNode)instrs.get(5)).var == var2
&& instrs.get(6).getOpcode() == Opcodes.IMUL
&& instrs.get(7).getOpcode() == Opcodes.ISTORE
&& ((VarInsnNode)instrs.get(7)).var == var2
&& instrs.get(8).getOpcode() == Opcodes.ILOAD
&& ((VarInsnNode)instrs.get(8)).var == var2
&& instrs.get(9).getOpcode() == Opcodes.ICONST_2
&& instrs.get(10).getOpcode() == Opcodes.IREM
&& instrs.get(11).getOpcode() == Opcodes.ISTORE
&& ((VarInsnNode)instrs.get(11)).var == var2
&& instrs.get(12).getOpcode() == Opcodes.ILOAD
&& ((VarInsnNode)instrs.get(12)).var == var2
&& instrs.get(13).getOpcode() == Opcodes.IADD)
return instrs;
}
return null;
}
public static MathOperationBS createMathOperation(JvmTypeCategory operandsType, MathOperation.Operator operator) {
int opcode;
switch (operator) {
case MULTIPLICATION:
switch (operandsType) {
case INT:
opcode = Opcodes.IMUL;
break;
case LONG:
opcode = Opcodes.LMUL;
break;
case FLOAT:
opcode = Opcodes.FMUL;
break;
case DOUBLE:
opcode = Opcodes.DMUL;
break;
default:
throw new UnsupportedOperationException(operator + " " +operandsType.name());
}
break;
case SUM:
switch (operandsType) {
case INT:
opcode = Opcodes.IADD;
break;
case LONG:
opcode = Opcodes.LADD;
break;
case FLOAT:
opcode = Opcodes.FADD;
break;
case DOUBLE:
opcode = Opcodes.DADD;
break;
default:
throw new UnsupportedOperationException(operator + " " +operandsType.name());
}
break;
case SUBTRACTION:
switch (operandsType) {
case INT:
opcode = Opcodes.ISUB;
break;
case LONG:
opcode = Opcodes.LSUB;
break;
case FLOAT:
opcode = Opcodes.FSUB;
break;
case DOUBLE:
opcode = Opcodes.DSUB;
break;
default:
throw new UnsupportedOperationException(operator + " " +operandsType.name());
}
break;
case DIVISION:
switch (operandsType) {
case INT:
opcode = Opcodes.IDIV;
break;
case LONG:
opcode = Opcodes.LDIV;
break;
case FLOAT:
opcode = Opcodes.FDIV;
break;
case DOUBLE:
opcode = Opcodes.DDIV;
break;
default:
throw new UnsupportedOperationException(operator + " " +operandsType.name());
}
break;
default:
throw new UnsupportedOperationException(operator.name());
}
return new MathOperationBS(opcode);
}
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;
}
@Override
public void visitInsn(int opcode) {
switch (opcode) {
case Opcodes.IADD:
case Opcodes.ISUB:
case Opcodes.IMUL:
case Opcodes.IDIV:
case Opcodes.IREM:
if (this.shouldMutate("integer")) {
mv.visitInsn(Opcodes.POP);
} else {
mv.visitInsn(opcode);
}
break;
case Opcodes.FADD:
case Opcodes.FSUB:
case Opcodes.FMUL:
case Opcodes.FDIV:
case Opcodes.FREM:
if (this.shouldMutate("float")) {
mv.visitInsn(Opcodes.POP);
} else {
mv.visitInsn(opcode);
}
break;
case Opcodes.LADD:
case Opcodes.LSUB:
case Opcodes.LMUL:
case Opcodes.LDIV:
case Opcodes.LREM:
if (this.shouldMutate("long")) {
mv.visitInsn(Opcodes.POP2);
} else {
mv.visitInsn(opcode);
}
break;
case Opcodes.DADD:
case Opcodes.DSUB:
case Opcodes.DMUL:
case Opcodes.DDIV:
case Opcodes.DREM:
if (this.shouldMutate("double")) {
mv.visitInsn(Opcodes.POP2);
} else {
mv.visitInsn(opcode);
}
break;
default:
mv.visitInsn(opcode);
break;
}
}