use of soot.LongType in project soot by Sable.
the class GroupIntPair method emitInst.
void emitInst(Inst inst) {
LineNumberTag lnTag = (LineNumberTag) inst.getTag("LineNumberTag");
if (lnTag != null)
emit(".line " + lnTag.getLineNumber());
inst.apply(new InstSwitch() {
@Override
public void caseReturnVoidInst(ReturnVoidInst i) {
emit("return");
}
@Override
public void caseReturnInst(ReturnInst i) {
i.getOpType().apply(new TypeSwitch() {
@Override
public void defaultCase(Type t) {
throw new RuntimeException("invalid return type " + t.toString());
}
@Override
public void caseDoubleType(DoubleType t) {
emit("dreturn");
}
@Override
public void caseFloatType(FloatType t) {
emit("freturn");
}
@Override
public void caseIntType(IntType t) {
emit("ireturn");
}
@Override
public void caseByteType(ByteType t) {
emit("ireturn");
}
@Override
public void caseShortType(ShortType t) {
emit("ireturn");
}
@Override
public void caseCharType(CharType t) {
emit("ireturn");
}
@Override
public void caseBooleanType(BooleanType t) {
emit("ireturn");
}
@Override
public void caseLongType(LongType t) {
emit("lreturn");
}
@Override
public void caseArrayType(ArrayType t) {
emit("areturn");
}
@Override
public void caseRefType(RefType t) {
emit("areturn");
}
@Override
public void caseNullType(NullType t) {
emit("areturn");
}
});
}
@Override
public void caseNopInst(NopInst i) {
emit("nop");
}
@Override
public void caseEnterMonitorInst(EnterMonitorInst i) {
emit("monitorenter");
}
@Override
public void casePopInst(PopInst i) {
if (i.getWordCount() == 2) {
emit("pop2");
} else
emit("pop");
}
@Override
public void caseExitMonitorInst(ExitMonitorInst i) {
emit("monitorexit");
}
@Override
public void caseGotoInst(GotoInst i) {
emit("goto " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseJSRInst(JSRInst i) {
emit("jsr " + unitToLabel.get(i.getTarget()));
}
@Override
public void casePushInst(PushInst i) {
if (i.getConstant() instanceof IntConstant) {
IntConstant v = (IntConstant) (i.getConstant());
if (v.value == -1)
emit("iconst_m1");
else if (v.value >= 0 && v.value <= 5)
emit("iconst_" + v.value);
else if (v.value >= Byte.MIN_VALUE && v.value <= Byte.MAX_VALUE)
emit("bipush " + v.value);
else if (v.value >= Short.MIN_VALUE && v.value <= Short.MAX_VALUE)
emit("sipush " + v.value);
else
emit("ldc " + v.toString());
} else if (i.getConstant() instanceof StringConstant) {
emit("ldc " + i.getConstant().toString());
} else if (i.getConstant() instanceof ClassConstant) {
emit("ldc_w " + ((ClassConstant) i.getConstant()).getValue());
} else if (i.getConstant() instanceof DoubleConstant) {
DoubleConstant v = (DoubleConstant) (i.getConstant());
if ((v.value == 0) && ((1.0 / v.value) > 0.0))
emit("dconst_0");
else if (v.value == 1)
emit("dconst_1");
else {
String s = doubleToString(v);
emit("ldc2_w " + s);
}
} else if (i.getConstant() instanceof FloatConstant) {
FloatConstant v = (FloatConstant) (i.getConstant());
if ((v.value == 0) && ((1.0f / v.value) > 1.0f))
emit("fconst_0");
else if (v.value == 1)
emit("fconst_1");
else if (v.value == 2)
emit("fconst_2");
else {
String s = floatToString(v);
emit("ldc " + s);
}
} else if (i.getConstant() instanceof LongConstant) {
LongConstant v = (LongConstant) (i.getConstant());
if (v.value == 0)
emit("lconst_0");
else if (v.value == 1)
emit("lconst_1");
else
emit("ldc2_w " + v.toString());
} else if (i.getConstant() instanceof NullConstant) {
emit("aconst_null");
} else if (i.getConstant() instanceof MethodHandle) {
throw new RuntimeException("MethodHandle constants not supported by Jasmin. Please use -asm-backend.");
} else
throw new RuntimeException("unsupported opcode");
}
@Override
public void caseIdentityInst(IdentityInst i) {
if (i.getRightOp() instanceof CaughtExceptionRef && i.getLeftOp() instanceof Local) {
int slot = localToSlot.get(i.getLeftOp()).intValue();
if (slot >= 0 && slot <= 3)
emit("astore_" + slot);
else
emit("astore " + slot);
}
}
@Override
public void caseStoreInst(StoreInst i) {
final int slot = localToSlot.get(i.getLocal()).intValue();
i.getOpType().apply(new TypeSwitch() {
@Override
public void caseArrayType(ArrayType t) {
if (slot >= 0 && slot <= 3)
emit("astore_" + slot);
else
emit("astore " + slot);
}
@Override
public void caseDoubleType(DoubleType t) {
if (slot >= 0 && slot <= 3)
emit("dstore_" + slot);
else
emit("dstore " + slot);
}
@Override
public void caseFloatType(FloatType t) {
if (slot >= 0 && slot <= 3)
emit("fstore_" + slot);
else
emit("fstore " + slot);
}
@Override
public void caseIntType(IntType t) {
if (slot >= 0 && slot <= 3)
emit("istore_" + slot);
else
emit("istore " + slot);
}
@Override
public void caseByteType(ByteType t) {
if (slot >= 0 && slot <= 3)
emit("istore_" + slot);
else
emit("istore " + slot);
}
@Override
public void caseShortType(ShortType t) {
if (slot >= 0 && slot <= 3)
emit("istore_" + slot);
else
emit("istore " + slot);
}
@Override
public void caseCharType(CharType t) {
if (slot >= 0 && slot <= 3)
emit("istore_" + slot);
else
emit("istore " + slot);
}
@Override
public void caseBooleanType(BooleanType t) {
if (slot >= 0 && slot <= 3)
emit("istore_" + slot);
else
emit("istore " + slot);
}
@Override
public void caseLongType(LongType t) {
if (slot >= 0 && slot <= 3)
emit("lstore_" + slot);
else
emit("lstore " + slot);
}
@Override
public void caseRefType(RefType t) {
if (slot >= 0 && slot <= 3)
emit("astore_" + slot);
else
emit("astore " + slot);
}
@Override
public void caseStmtAddressType(StmtAddressType t) {
isNextGotoAJsr = true;
returnAddressSlot = slot;
/*
* if ( slot >= 0 && slot <= 3) emit("astore_" + slot,
* ); else emit("astore " + slot, );
*/
}
@Override
public void caseNullType(NullType t) {
if (slot >= 0 && slot <= 3)
emit("astore_" + slot);
else
emit("astore " + slot);
}
@Override
public void defaultCase(Type t) {
throw new RuntimeException("Invalid local type:" + t);
}
});
}
@Override
public void caseLoadInst(LoadInst i) {
final int slot = localToSlot.get(i.getLocal()).intValue();
i.getOpType().apply(new TypeSwitch() {
@Override
public void caseArrayType(ArrayType t) {
if (slot >= 0 && slot <= 3)
emit("aload_" + slot);
else
emit("aload " + slot);
}
@Override
public void defaultCase(Type t) {
throw new RuntimeException("invalid local type to load" + t);
}
@Override
public void caseDoubleType(DoubleType t) {
if (slot >= 0 && slot <= 3)
emit("dload_" + slot);
else
emit("dload " + slot);
}
@Override
public void caseFloatType(FloatType t) {
if (slot >= 0 && slot <= 3)
emit("fload_" + slot);
else
emit("fload " + slot);
}
@Override
public void caseIntType(IntType t) {
if (slot >= 0 && slot <= 3)
emit("iload_" + slot);
else
emit("iload " + slot);
}
@Override
public void caseByteType(ByteType t) {
if (slot >= 0 && slot <= 3)
emit("iload_" + slot);
else
emit("iload " + slot);
}
@Override
public void caseShortType(ShortType t) {
if (slot >= 0 && slot <= 3)
emit("iload_" + slot);
else
emit("iload " + slot);
}
@Override
public void caseCharType(CharType t) {
if (slot >= 0 && slot <= 3)
emit("iload_" + slot);
else
emit("iload " + slot);
}
@Override
public void caseBooleanType(BooleanType t) {
if (slot >= 0 && slot <= 3)
emit("iload_" + slot);
else
emit("iload " + slot);
}
@Override
public void caseLongType(LongType t) {
if (slot >= 0 && slot <= 3)
emit("lload_" + slot);
else
emit("lload " + slot);
}
@Override
public void caseRefType(RefType t) {
if (slot >= 0 && slot <= 3)
emit("aload_" + slot);
else
emit("aload " + slot);
}
@Override
public void caseNullType(NullType t) {
if (slot >= 0 && slot <= 3)
emit("aload_" + slot);
else
emit("aload " + slot);
}
});
}
@Override
public void caseArrayWriteInst(ArrayWriteInst i) {
i.getOpType().apply(new TypeSwitch() {
@Override
public void caseArrayType(ArrayType t) {
emit("aastore");
}
@Override
public void caseDoubleType(DoubleType t) {
emit("dastore");
}
@Override
public void caseFloatType(FloatType t) {
emit("fastore");
}
@Override
public void caseIntType(IntType t) {
emit("iastore");
}
@Override
public void caseLongType(LongType t) {
emit("lastore");
}
@Override
public void caseRefType(RefType t) {
emit("aastore");
}
@Override
public void caseByteType(ByteType t) {
emit("bastore");
}
@Override
public void caseBooleanType(BooleanType t) {
emit("bastore");
}
@Override
public void caseCharType(CharType t) {
emit("castore");
}
@Override
public void caseShortType(ShortType t) {
emit("sastore");
}
@Override
public void defaultCase(Type t) {
throw new RuntimeException("Invalid type: " + t);
}
});
}
@Override
public void caseArrayReadInst(ArrayReadInst i) {
i.getOpType().apply(new TypeSwitch() {
@Override
public void caseArrayType(ArrayType ty) {
emit("aaload");
}
@Override
public void caseBooleanType(BooleanType ty) {
emit("baload");
}
@Override
public void caseByteType(ByteType ty) {
emit("baload");
}
@Override
public void caseCharType(CharType ty) {
emit("caload");
}
@Override
public void defaultCase(Type ty) {
throw new RuntimeException("invalid base type");
}
@Override
public void caseDoubleType(DoubleType ty) {
emit("daload");
}
@Override
public void caseFloatType(FloatType ty) {
emit("faload");
}
@Override
public void caseIntType(IntType ty) {
emit("iaload");
}
@Override
public void caseLongType(LongType ty) {
emit("laload");
}
@Override
public void caseNullType(NullType ty) {
emit("aaload");
}
@Override
public void caseRefType(RefType ty) {
emit("aaload");
}
@Override
public void caseShortType(ShortType ty) {
emit("saload");
}
});
}
@Override
public void caseIfNullInst(IfNullInst i) {
emit("ifnull " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseIfNonNullInst(IfNonNullInst i) {
emit("ifnonnull " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseIfEqInst(IfEqInst i) {
emit("ifeq " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseIfNeInst(IfNeInst i) {
emit("ifne " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseIfGtInst(IfGtInst i) {
emit("ifgt " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseIfGeInst(IfGeInst i) {
emit("ifge " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseIfLtInst(IfLtInst i) {
emit("iflt " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseIfLeInst(IfLeInst i) {
emit("ifle " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseIfCmpEqInst(final IfCmpEqInst i) {
i.getOpType().apply(new TypeSwitch() {
@Override
public void caseIntType(IntType t) {
emit("if_icmpeq " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseBooleanType(BooleanType t) {
emit("if_icmpeq " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseShortType(ShortType t) {
emit("if_icmpeq " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseCharType(CharType t) {
emit("if_icmpeq " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseByteType(ByteType t) {
emit("if_icmpeq " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseDoubleType(DoubleType t) {
emit("dcmpg");
emit("ifeq " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseLongType(LongType t) {
emit("lcmp");
emit("ifeq " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseFloatType(FloatType t) {
emit("fcmpg");
emit("ifeq " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseArrayType(ArrayType t) {
emit("if_acmpeq " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseRefType(RefType t) {
emit("if_acmpeq " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseNullType(NullType t) {
emit("if_acmpeq " + unitToLabel.get(i.getTarget()));
}
@Override
public void defaultCase(Type t) {
throw new RuntimeException("invalid type");
}
});
}
@Override
public void caseIfCmpNeInst(final IfCmpNeInst i) {
i.getOpType().apply(new TypeSwitch() {
@Override
public void caseIntType(IntType t) {
emit("if_icmpne " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseBooleanType(BooleanType t) {
emit("if_icmpne " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseShortType(ShortType t) {
emit("if_icmpne " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseCharType(CharType t) {
emit("if_icmpne " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseByteType(ByteType t) {
emit("if_icmpne " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseDoubleType(DoubleType t) {
emit("dcmpg");
emit("ifne " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseLongType(LongType t) {
emit("lcmp");
emit("ifne " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseFloatType(FloatType t) {
emit("fcmpg");
emit("ifne " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseArrayType(ArrayType t) {
emit("if_acmpne " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseRefType(RefType t) {
emit("if_acmpne " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseNullType(NullType t) {
emit("if_acmpne " + unitToLabel.get(i.getTarget()));
}
@Override
public void defaultCase(Type t) {
throw new RuntimeException("invalid type");
}
});
}
@Override
public void caseIfCmpGtInst(final IfCmpGtInst i) {
i.getOpType().apply(new TypeSwitch() {
@Override
public void caseIntType(IntType t) {
emit("if_icmpgt " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseBooleanType(BooleanType t) {
emit("if_icmpgt " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseShortType(ShortType t) {
emit("if_icmpgt " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseCharType(CharType t) {
emit("if_icmpgt " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseByteType(ByteType t) {
emit("if_icmpgt " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseDoubleType(DoubleType t) {
emit("dcmpg");
emit("ifgt " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseLongType(LongType t) {
emit("lcmp");
emit("ifgt " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseFloatType(FloatType t) {
emit("fcmpg");
emit("ifgt " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseArrayType(ArrayType t) {
emit("if_acmpgt " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseRefType(RefType t) {
emit("if_acmpgt " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseNullType(NullType t) {
emit("if_acmpgt " + unitToLabel.get(i.getTarget()));
}
@Override
public void defaultCase(Type t) {
throw new RuntimeException("invalid type");
}
});
}
@Override
public void caseIfCmpGeInst(final IfCmpGeInst i) {
i.getOpType().apply(new TypeSwitch() {
@Override
public void caseIntType(IntType t) {
emit("if_icmpge " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseBooleanType(BooleanType t) {
emit("if_icmpge " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseShortType(ShortType t) {
emit("if_icmpge " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseCharType(CharType t) {
emit("if_icmpge " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseByteType(ByteType t) {
emit("if_icmpge " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseDoubleType(DoubleType t) {
emit("dcmpg");
emit("ifge " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseLongType(LongType t) {
emit("lcmp");
emit("ifge " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseFloatType(FloatType t) {
emit("fcmpg");
emit("ifge " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseArrayType(ArrayType t) {
emit("if_acmpge " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseRefType(RefType t) {
emit("if_acmpge " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseNullType(NullType t) {
emit("if_acmpge " + unitToLabel.get(i.getTarget()));
}
@Override
public void defaultCase(Type t) {
throw new RuntimeException("invalid type");
}
});
}
@Override
public void caseIfCmpLtInst(final IfCmpLtInst i) {
i.getOpType().apply(new TypeSwitch() {
@Override
public void caseIntType(IntType t) {
emit("if_icmplt " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseBooleanType(BooleanType t) {
emit("if_icmplt " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseShortType(ShortType t) {
emit("if_icmplt " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseCharType(CharType t) {
emit("if_icmplt " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseByteType(ByteType t) {
emit("if_icmplt " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseDoubleType(DoubleType t) {
emit("dcmpg");
emit("iflt " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseLongType(LongType t) {
emit("lcmp");
emit("iflt " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseFloatType(FloatType t) {
emit("fcmpg");
emit("iflt " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseArrayType(ArrayType t) {
emit("if_acmplt " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseRefType(RefType t) {
emit("if_acmplt " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseNullType(NullType t) {
emit("if_acmplt " + unitToLabel.get(i.getTarget()));
}
@Override
public void defaultCase(Type t) {
throw new RuntimeException("invalid type");
}
});
}
@Override
public void caseIfCmpLeInst(final IfCmpLeInst i) {
i.getOpType().apply(new TypeSwitch() {
@Override
public void caseIntType(IntType t) {
emit("if_icmple " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseBooleanType(BooleanType t) {
emit("if_icmple " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseShortType(ShortType t) {
emit("if_icmple " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseCharType(CharType t) {
emit("if_icmple " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseByteType(ByteType t) {
emit("if_icmple " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseDoubleType(DoubleType t) {
emit("dcmpg");
emit("ifle " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseLongType(LongType t) {
emit("lcmp");
emit("ifle " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseFloatType(FloatType t) {
emit("fcmpg");
emit("ifle " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseArrayType(ArrayType t) {
emit("if_acmple " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseRefType(RefType t) {
emit("if_acmple " + unitToLabel.get(i.getTarget()));
}
@Override
public void caseNullType(NullType t) {
emit("if_acmple " + unitToLabel.get(i.getTarget()));
}
@Override
public void defaultCase(Type t) {
throw new RuntimeException("invalid type");
}
});
}
@Override
public void caseStaticGetInst(StaticGetInst i) {
SootFieldRef field = i.getFieldRef();
emit("getstatic " + slashify(field.declaringClass().getName()) + "/" + field.name() + " " + jasminDescriptorOf(field.type()));
}
@Override
public void caseStaticPutInst(StaticPutInst i) {
emit("putstatic " + slashify(i.getFieldRef().declaringClass().getName()) + "/" + i.getFieldRef().name() + " " + jasminDescriptorOf(i.getFieldRef().type()));
}
@Override
public void caseFieldGetInst(FieldGetInst i) {
emit("getfield " + slashify(i.getFieldRef().declaringClass().getName()) + "/" + i.getFieldRef().name() + " " + jasminDescriptorOf(i.getFieldRef().type()));
}
@Override
public void caseFieldPutInst(FieldPutInst i) {
emit("putfield " + slashify(i.getFieldRef().declaringClass().getName()) + "/" + i.getFieldRef().name() + " " + jasminDescriptorOf(i.getFieldRef().type()));
}
@Override
public void caseInstanceCastInst(InstanceCastInst i) {
Type castType = i.getCastType();
if (castType instanceof RefType)
emit("checkcast " + slashify(((RefType) castType).getClassName()));
else if (castType instanceof ArrayType)
emit("checkcast " + jasminDescriptorOf(castType));
}
@Override
public void caseInstanceOfInst(InstanceOfInst i) {
Type checkType = i.getCheckType();
if (checkType instanceof RefType)
emit("instanceof " + slashify(checkType.toString()));
else if (checkType instanceof ArrayType)
emit("instanceof " + jasminDescriptorOf(checkType));
}
@Override
public void caseNewInst(NewInst i) {
emit("new " + slashify(i.getBaseType().getClassName()));
}
@Override
public void casePrimitiveCastInst(PrimitiveCastInst i) {
emit(i.toString());
}
@Override
public void caseDynamicInvokeInst(DynamicInvokeInst i) {
SootMethodRef m = i.getMethodRef();
SootMethodRef bsm = i.getBootstrapMethodRef();
String bsmArgString = "";
for (Iterator<Value> iterator = i.getBootstrapArgs().iterator(); iterator.hasNext(); ) {
Value val = iterator.next();
bsmArgString += "(" + jasminDescriptorOf(val.getType()) + ")";
bsmArgString += escape(val.toString());
if (iterator.hasNext())
bsmArgString += ",";
}
emit("invokedynamic \"" + m.name() + "\" " + jasminDescriptorOf(m) + " " + slashify(bsm.declaringClass().getName()) + "/" + bsm.name() + jasminDescriptorOf(bsm) + "(" + bsmArgString + ")");
}
private String escape(String bsmArgString) {
return bsmArgString.replace(",", "\\comma").replace(" ", "\\blank").replace("\t", "\\tab").replace("\n", "\\newline");
}
@Override
public void caseStaticInvokeInst(StaticInvokeInst i) {
SootMethodRef m = i.getMethodRef();
emit("invokestatic " + slashify(m.declaringClass().getName()) + "/" + m.name() + jasminDescriptorOf(m));
}
@Override
public void caseVirtualInvokeInst(VirtualInvokeInst i) {
SootMethodRef m = i.getMethodRef();
emit("invokevirtual " + slashify(m.declaringClass().getName()) + "/" + m.name() + jasminDescriptorOf(m));
}
@Override
public void caseInterfaceInvokeInst(InterfaceInvokeInst i) {
SootMethodRef m = i.getMethodRef();
emit("invokeinterface " + slashify(m.declaringClass().getName()) + "/" + m.name() + jasminDescriptorOf(m) + " " + (argCountOf(m) + 1));
}
@Override
public void caseSpecialInvokeInst(SpecialInvokeInst i) {
SootMethodRef m = i.getMethodRef();
emit("invokespecial " + slashify(m.declaringClass().getName()) + "/" + m.name() + jasminDescriptorOf(m));
}
@Override
public void caseThrowInst(ThrowInst i) {
emit("athrow");
}
@Override
public void caseCmpInst(CmpInst i) {
emit("lcmp");
}
@Override
public void caseCmplInst(CmplInst i) {
if (i.getOpType().equals(FloatType.v()))
emit("fcmpl");
else
emit("dcmpl");
}
@Override
public void caseCmpgInst(CmpgInst i) {
if (i.getOpType().equals(FloatType.v()))
emit("fcmpg");
else
emit("dcmpg");
}
private void emitOpTypeInst(final String s, final OpTypeArgInst i) {
i.getOpType().apply(new TypeSwitch() {
private void handleIntCase() {
emit("i" + s);
}
@Override
public void caseIntType(IntType t) {
handleIntCase();
}
@Override
public void caseBooleanType(BooleanType t) {
handleIntCase();
}
@Override
public void caseShortType(ShortType t) {
handleIntCase();
}
@Override
public void caseCharType(CharType t) {
handleIntCase();
}
@Override
public void caseByteType(ByteType t) {
handleIntCase();
}
@Override
public void caseLongType(LongType t) {
emit("l" + s);
}
@Override
public void caseDoubleType(DoubleType t) {
emit("d" + s);
}
@Override
public void caseFloatType(FloatType t) {
emit("f" + s);
}
@Override
public void defaultCase(Type t) {
throw new RuntimeException("Invalid argument type for div");
}
});
}
@Override
public void caseAddInst(AddInst i) {
emitOpTypeInst("add", i);
}
@Override
public void caseDivInst(DivInst i) {
emitOpTypeInst("div", i);
}
@Override
public void caseSubInst(SubInst i) {
emitOpTypeInst("sub", i);
}
@Override
public void caseMulInst(MulInst i) {
emitOpTypeInst("mul", i);
}
@Override
public void caseRemInst(RemInst i) {
emitOpTypeInst("rem", i);
}
@Override
public void caseShlInst(ShlInst i) {
emitOpTypeInst("shl", i);
}
@Override
public void caseAndInst(AndInst i) {
emitOpTypeInst("and", i);
}
@Override
public void caseOrInst(OrInst i) {
emitOpTypeInst("or", i);
}
@Override
public void caseXorInst(XorInst i) {
emitOpTypeInst("xor", i);
}
@Override
public void caseShrInst(ShrInst i) {
emitOpTypeInst("shr", i);
}
@Override
public void caseUshrInst(UshrInst i) {
emitOpTypeInst("ushr", i);
}
@Override
public void caseIncInst(IncInst i) {
if (i.getUseBoxes().get(0).getValue() != i.getDefBoxes().get(0).getValue())
throw new RuntimeException("iinc def and use boxes don't match");
emit("iinc " + localToSlot.get(i.getLocal()) + " " + i.getConstant());
}
@Override
public void caseArrayLengthInst(ArrayLengthInst i) {
emit("arraylength");
}
@Override
public void caseNegInst(NegInst i) {
emitOpTypeInst("neg", i);
}
@Override
public void caseNewArrayInst(NewArrayInst i) {
if (i.getBaseType() instanceof RefType)
emit("anewarray " + slashify(((RefType) i.getBaseType()).getClassName()));
else if (i.getBaseType() instanceof ArrayType)
emit("anewarray " + jasminDescriptorOf(i.getBaseType()));
else
emit("newarray " + i.getBaseType().toString());
}
@Override
public void caseNewMultiArrayInst(NewMultiArrayInst i) {
emit("multianewarray " + jasminDescriptorOf(i.getBaseType()) + " " + i.getDimensionCount());
}
@Override
public void caseLookupSwitchInst(LookupSwitchInst i) {
emit("lookupswitch");
List<IntConstant> lookupValues = i.getLookupValues();
List<Unit> targets = i.getTargets();
for (int j = 0; j < lookupValues.size(); j++) emit(" " + lookupValues.get(j) + " : " + unitToLabel.get(targets.get(j)));
emit(" default : " + unitToLabel.get(i.getDefaultTarget()));
}
@Override
public void caseTableSwitchInst(TableSwitchInst i) {
emit("tableswitch " + i.getLowIndex() + " ; high = " + i.getHighIndex());
List<Unit> targets = i.getTargets();
for (int j = 0; j < targets.size(); j++) emit(" " + unitToLabel.get(targets.get(j)));
emit("default : " + unitToLabel.get(i.getDefaultTarget()));
}
private boolean isDwordType(Type t) {
return t instanceof LongType || t instanceof DoubleType || t instanceof DoubleWordType;
}
@Override
public void caseDup1Inst(Dup1Inst i) {
Type firstOpType = i.getOp1Type();
if (isDwordType(firstOpType))
// (form 2)
emit("dup2");
else
emit("dup");
}
@Override
public void caseDup2Inst(Dup2Inst i) {
Type firstOpType = i.getOp1Type();
Type secondOpType = i.getOp2Type();
// Use a pair of insts to simulate them.
if (isDwordType(firstOpType)) {
// (form 2)
emit("dup2");
if (isDwordType(secondOpType)) {
// (form 2 -- by simulation)
emit("dup2");
} else
// also a simulation
emit("dup");
} else if (isDwordType(secondOpType)) {
if (isDwordType(firstOpType)) {
// (form 2)
emit("dup2");
} else
emit("dup");
// (form 2 -- complete the simulation)
emit("dup2");
} else {
// form 1
emit("dup2");
}
}
@Override
public void caseDup1_x1Inst(Dup1_x1Inst i) {
Type opType = i.getOp1Type();
Type underType = i.getUnder1Type();
if (isDwordType(opType)) {
if (isDwordType(underType)) {
// (form 4)
emit("dup2_x2");
} else
// (form 2)
emit("dup2_x1");
} else {
if (isDwordType(underType))
// (form 2)
emit("dup_x2");
else
// (only one form)
emit("dup_x1");
}
}
@Override
public void caseDup1_x2Inst(Dup1_x2Inst i) {
Type opType = i.getOp1Type();
Type under1Type = i.getUnder1Type();
Type under2Type = i.getUnder2Type();
if (isDwordType(opType)) {
if (!isDwordType(under1Type) && !isDwordType(under2Type))
// (form 2)
emit("dup2_x2");
else
throw new RuntimeException("magic not implemented yet");
} else {
if (isDwordType(under1Type) || isDwordType(under2Type))
throw new RuntimeException("magic not implemented yet");
}
// (form 1)
emit("dup_x2");
}
@Override
public void caseDup2_x1Inst(Dup2_x1Inst i) {
Type op1Type = i.getOp1Type();
Type op2Type = i.getOp2Type();
Type under1Type = i.getUnder1Type();
/*
* From VM Spec: cat1 = category 1 (word type) cat2 = category 2
* (doubleword)
*
* Form 1: [..., cat1_value3, cat1_value2, cat1_value1]->[...,
* cat1_value2, cat1_value1, cat1_value3, cat1_value2,
* cat1_value1] Form 2: [..., cat1_value2, cat2_value1]->[...,
* cat2_value1, cat1_value2, cat2_value1]
*/
if (isDwordType(under1Type)) {
if (!isDwordType(op1Type) && !isDwordType(op2Type))
throw new RuntimeException("magic not implemented yet");
else
// (form 3)
emit("dup2_x2");
} else {
if ((isDwordType(op1Type) && op2Type != null) || isDwordType(op2Type))
throw new RuntimeException("magic not implemented yet");
}
// (form 1)
emit("dup2_x1");
}
@Override
public void caseDup2_x2Inst(Dup2_x2Inst i) {
Type op1Type = i.getOp1Type();
Type op2Type = i.getOp2Type();
Type under1Type = i.getUnder1Type();
Type under2Type = i.getUnder2Type();
// 07-20-2006 Michael Batchelder
// NOW handling all types of dup2_x2
/*
* From VM Spec: cat1 = category 1 (word type) cat2 = category 2
* (doubleword) Form 1: [..., cat1_value4, cat1_value3,
* cat1_value2, cat1_value1]->[..., cat1_value2, cat1_value1,
* cat1_value4, cat1_value3, cat1_value2, cat1_value1] Form 2:
* [..., cat1_value3, cat1_value2, cat2_value1]->[ ...,
* cat2_value1, cat1_value3, cat1_value2, cat2_value1] Form 3:
* [..., cat2_value3, cat1_value2, cat1_value1]->[...,
* cat1_value2, cat1_value1, cat2_value3, cat1_value2,
* cat1_value1] Form 4: [..., cat2_value2, cat2_value1]->[...,
* cat2_value1, cat2_value2, cat2_value1]
*/
boolean malformed = true;
if (isDwordType(op1Type)) {
if (op2Type == null && under1Type != null)
if ((under2Type == null && isDwordType(under1Type)) || (!isDwordType(under1Type) && under2Type != null && !isDwordType(under2Type)))
malformed = false;
} else if (op1Type != null && op2Type != null && !isDwordType(op2Type)) {
if ((under2Type == null && isDwordType(under1Type)) || (under1Type != null && !isDwordType(under1Type) && under2Type != null && !isDwordType(under2Type)))
malformed = false;
}
if (malformed)
throw new RuntimeException("magic not implemented yet");
// (form 1)
emit("dup2_x2");
}
@Override
public void caseSwapInst(SwapInst i) {
emit("swap");
}
});
}
use of soot.LongType in project soot by Sable.
the class ConstantFieldValueFinder method valuesForPrimTypeFields.
/*
* This method gives values to all the fields in all the classes if they can be determined statically
* We only care about fields which have primitive types
*/
private void valuesForPrimTypeFields() {
// go through all the classes
Iterator classIt = appClasses.iterator();
while (classIt.hasNext()) {
SootClass s = (SootClass) classIt.next();
debug("\nvaluesforPrimTypeFields", "Processing class " + s.getName());
String declaringClass = s.getName();
Iterator fieldIt = s.getFields().iterator();
while (fieldIt.hasNext()) {
SootField f = (SootField) fieldIt.next();
String fieldName = f.getName();
Type fieldType = f.getType();
if (!(fieldType instanceof PrimType))
continue;
String combined = declaringClass + combiner + fieldName;
classNameFieldNameToSootFieldMapping.put(combined, f);
Object value = null;
// check for constant value tags
if (fieldType instanceof DoubleType && f.hasTag("DoubleConstantValueTag")) {
double val = ((DoubleConstantValueTag) f.getTag("DoubleConstantValueTag")).getDoubleValue();
value = new Double(val);
} else if (fieldType instanceof FloatType && f.hasTag("FloatConstantValueTag")) {
float val = ((FloatConstantValueTag) f.getTag("FloatConstantValueTag")).getFloatValue();
value = new Float(val);
} else if (fieldType instanceof LongType && f.hasTag("LongConstantValueTag")) {
long val = ((LongConstantValueTag) f.getTag("LongConstantValueTag")).getLongValue();
value = new Long(val);
} else if (fieldType instanceof CharType && f.hasTag("IntegerConstantValueTag")) {
int val = ((IntegerConstantValueTag) f.getTag("IntegerConstantValueTag")).getIntValue();
value = new Integer(val);
} else if (fieldType instanceof BooleanType && f.hasTag("IntegerConstantValueTag")) {
int val = ((IntegerConstantValueTag) f.getTag("IntegerConstantValueTag")).getIntValue();
if (val == 0)
value = new Boolean(false);
else
value = new Boolean(true);
} else if ((fieldType instanceof IntType || fieldType instanceof ByteType || fieldType instanceof ShortType) && f.hasTag("IntegerConstantValueTag")) {
int val = ((IntegerConstantValueTag) f.getTag("IntegerConstantValueTag")).getIntValue();
value = new Integer(val);
}
// if there was a constant value tag we have its value now
if (value != null) {
debug("TAGGED value found for field: " + combined);
primTypeFieldValueToUse.put(combined, value);
// continue with next field
continue;
}
// see if the field was never assigned in which case it gets default values
Object temp = fieldToValues.get(combined);
if (temp == null) {
if (fieldType instanceof DoubleType)
value = new Double(0);
else if (fieldType instanceof FloatType)
value = new Float(0);
else if (fieldType instanceof LongType)
value = new Long(0);
else if (fieldType instanceof BooleanType)
value = new Boolean(false);
else if ((fieldType instanceof IntType || fieldType instanceof ByteType || fieldType instanceof ShortType) || fieldType instanceof CharType) {
value = new Integer(0);
} else
throw new DecompilationException("Unknown primitive type...please report to developer");
primTypeFieldValueToUse.put(combined, value);
debug("DEFAULT value for field: " + combined);
// continue with next field
continue;
}
// havent got a tag with value and havent use default since SOME method did define the field atleast once
// there was some value assigned!!!!!!!!!
debug("CHECKING USER ASSIGNED VALUES FOR: " + combined);
ArrayList values = (ArrayList) temp;
// check if they are all constants and that too the same constant
Iterator it = values.iterator();
NumericConstant tempConstant = null;
while (it.hasNext()) {
Value val = (Value) it.next();
if (!(val instanceof NumericConstant)) {
tempConstant = null;
debug("Not numeric constant hence giving up");
break;
}
if (tempConstant == null) {
tempConstant = (NumericConstant) val;
} else {
// check that this value is the same as previous
if (!tempConstant.equals(val)) {
tempConstant = null;
break;
}
}
}
if (tempConstant == null) {
// continue with next field cant do anything about this one
continue;
}
if (tempConstant instanceof LongConstant) {
Long tempVal = new Long(((LongConstant) tempConstant).value);
if (tempVal.compareTo(new Long(0)) == 0)
primTypeFieldValueToUse.put(combined, tempVal);
else
debug("Not assigning the agreed value since that is not the default value for " + combined);
} else if (tempConstant instanceof DoubleConstant) {
Double tempVal = new Double(((DoubleConstant) tempConstant).value);
if (tempVal.compareTo(new Double(0)) == 0)
primTypeFieldValueToUse.put(combined, tempVal);
else
debug("Not assigning the agreed value since that is not the default value for " + combined);
} else if (tempConstant instanceof FloatConstant) {
Float tempVal = new Float(((FloatConstant) tempConstant).value);
if (tempVal.compareTo(new Float(0)) == 0)
primTypeFieldValueToUse.put(combined, tempVal);
else
debug("Not assigning the agreed value since that is not the default value for " + combined);
} else if (tempConstant instanceof IntConstant) {
Integer tempVal = new Integer(((IntConstant) tempConstant).value);
if (tempVal.compareTo(new Integer(0)) == 0) {
SootField tempField = classNameFieldNameToSootFieldMapping.get(combined);
if (tempField.getType() instanceof BooleanType) {
primTypeFieldValueToUse.put(combined, new Boolean(false));
// System.out.println("puttingvalue false for"+combined);
} else {
primTypeFieldValueToUse.put(combined, tempVal);
// System.out.println("puttingvalue 0 for"+combined);
}
} else
debug("Not assigning the agreed value since that is not the default value for " + combined);
} else {
throw new DecompilationException("Un handled Numberic Constant....report to programmer");
}
}
// all fields of the class
}
// all classes
}
use of soot.LongType in project soot by Sable.
the class CP method createInitialInput.
/*
* constant fields added with KNOWN CONSTANT VALUE formals added with TOP
* locals added with 0 other fields IGNORED
*/
public void createInitialInput() {
initialInput = new ArrayList<CPTuple>();
// adding constant fields
initialInput.addAll(constantFieldTuples);
// String className =
// analyze.getDavaBody().getMethod().getDeclaringClass().getName();
// adding formals
formals = new ArrayList<CPTuple>();
// System.out.println("Adding following formals: with TOP");
Collection col = methodNode.getDavaBody().get_ParamMap().values();
Iterator it = col.iterator();
while (it.hasNext()) {
Object temp = it.next();
if (temp instanceof Local) {
Local tempLocal = (Local) temp;
if (!(tempLocal.getType() instanceof PrimType))
continue;
CPVariable newVar = new CPVariable(tempLocal);
// new tuple set to top since this is a formal and we dont know
// what value we will get into it
CPTuple newTuple = new CPTuple(localClassName, newVar, true);
initialInput.add(newTuple);
formals.add(newTuple);
// System.out.print("\t"+tempLocal.getName());
}
}
// System.out.println();
// adding locals
List decLocals = methodNode.getDeclaredLocals();
it = decLocals.iterator();
locals = new ArrayList<CPTuple>();
// System.out.println("Adding following locals with default values:");
while (it.hasNext()) {
Object temp = it.next();
if (temp instanceof Local) {
Local tempLocal = (Local) temp;
Type localType = tempLocal.getType();
if (!(localType instanceof PrimType))
continue;
CPVariable newVar = new CPVariable(tempLocal);
// store the default value into this object
Object value;
// depending on its type
if (localType instanceof BooleanType)
value = new Boolean(false);
else if (localType instanceof ByteType)
value = new Integer(0);
else if (localType instanceof CharType)
value = new Integer(0);
else if (localType instanceof DoubleType)
value = new Double(0);
else if (localType instanceof FloatType)
value = new Float(0);
else if (localType instanceof IntType)
value = new Integer(0);
else if (localType instanceof LongType)
value = new Long(0);
else if (localType instanceof ShortType)
value = new Integer(0);
else
throw new DavaFlowAnalysisException("Unknown PrimType");
CPTuple newTuple = new CPTuple(localClassName, newVar, value);
/*
* Commenting the next line since we dont want initial Input to
* have any locals in it all locals are considered bottom
* initially
*/
// initialInput.add(newTuple);
locals.add(newTuple);
// System.out.print("\t"+tempLocal.getName());
}
// was a local
}
// System.out.println();
}
use of soot.LongType in project soot by Sable.
the class TypeResolverBV method merge_primitive_types.
private void merge_primitive_types() throws TypeException {
// merge primitive types with all parents/children
compute_solved();
BitSetIterator varIt = solved.iterator();
while (varIt.hasNext()) {
TypeVariableBV var = typeVariableForId(varIt.next());
if (var.type().type() instanceof IntType || var.type().type() instanceof LongType || var.type().type() instanceof FloatType || var.type().type() instanceof DoubleType) {
BitVector parents;
BitVector children;
boolean finished;
do {
finished = true;
parents = var.parents();
if (parents.length() != 0) {
finished = false;
for (BitSetIterator j = parents.iterator(); j.hasNext(); ) {
if (DEBUG) {
logger.debug(".");
}
TypeVariableBV parent = typeVariableForId(j.next());
var = var.union(parent);
}
}
children = var.children();
if (children.length() != 0) {
finished = false;
for (BitSetIterator j = children.iterator(); j.hasNext(); ) {
if (DEBUG) {
logger.debug(".");
}
TypeVariableBV child = typeVariableForId(j.next());
var = var.union(child);
}
}
} while (!finished);
}
}
}
use of soot.LongType in project soot by Sable.
the class DeadAssignmentEliminator method internalTransform.
/**
* Eliminates dead code in a linear fashion. Complexity is linear
* with respect to the statements.
*
* Does not work on grimp code because of the check on the right hand
* side for side effects.
*/
@Override
protected void internalTransform(Body b, String phaseName, Map<String, String> options) {
boolean eliminateOnlyStackLocals = PhaseOptions.getBoolean(options, "only-stack-locals");
final Options soptions = Options.v();
if (soptions.verbose()) {
logger.debug("[" + b.getMethod().getName() + "] Eliminating dead code...");
}
if (soptions.time()) {
Timers.v().deadCodeTimer.start();
}
Chain<Unit> units = b.getUnits();
Deque<Unit> q = new ArrayDeque<Unit>(units.size());
// Make a first pass through the statements, noting
// the statements we must absolutely keep.
boolean isStatic = b.getMethod().isStatic();
boolean allEssential = true;
boolean checkInvoke = false;
Local thisLocal = null;
for (Iterator<Unit> it = units.iterator(); it.hasNext(); ) {
Unit s = it.next();
boolean isEssential = true;
if (s instanceof NopStmt) {
// Hack: do not remove nop if is is used for a Trap
// which is at the very end of the code.
boolean removeNop = it.hasNext();
if (!removeNop) {
removeNop = true;
for (Trap t : b.getTraps()) {
if (t.getEndUnit() == s) {
removeNop = false;
break;
}
}
}
if (removeNop) {
it.remove();
continue;
}
} else if (s instanceof AssignStmt) {
AssignStmt as = (AssignStmt) s;
Value lhs = as.getLeftOp();
Value rhs = as.getRightOp();
// Stmt is of the form a = a which is useless
if (lhs == rhs && lhs instanceof Local) {
it.remove();
continue;
}
if (lhs instanceof Local && (!eliminateOnlyStackLocals || ((Local) lhs).getName().startsWith("$") || lhs.getType() instanceof NullType)) {
isEssential = false;
if (!checkInvoke) {
checkInvoke = as.containsInvokeExpr();
}
if (rhs instanceof CastExpr) {
// CastExpr : can trigger ClassCastException, but null-casts never fail
CastExpr ce = (CastExpr) rhs;
Type t = ce.getCastType();
Value v = ce.getOp();
isEssential = !(v instanceof NullConstant && t instanceof RefType);
} else if (rhs instanceof InvokeExpr || rhs instanceof ArrayRef || rhs instanceof NewExpr || rhs instanceof NewArrayExpr || rhs instanceof NewMultiArrayExpr) {
// ArrayRef : can have side effects (like throwing a null pointer exception)
// InvokeExpr : can have side effects (like throwing a null pointer exception)
// NewArrayExpr : can throw exception
// NewMultiArrayExpr : can throw exception
// NewExpr : can trigger class initialization
isEssential = true;
} else if (rhs instanceof FieldRef) {
// Can trigger class initialization
isEssential = true;
if (rhs instanceof InstanceFieldRef) {
InstanceFieldRef ifr = (InstanceFieldRef) rhs;
if (!isStatic && thisLocal == null) {
thisLocal = b.getThisLocal();
}
// Any InstanceFieldRef may have side effects,
// unless the base is reading from 'this'
// in a non-static method
isEssential = (isStatic || thisLocal != ifr.getBase());
}
} else if (rhs instanceof DivExpr || rhs instanceof RemExpr) {
BinopExpr expr = (BinopExpr) rhs;
Type t1 = expr.getOp1().getType();
Type t2 = expr.getOp2().getType();
// Can trigger a division by zero
boolean t2Int = t2 instanceof IntType;
isEssential = t2Int || t1 instanceof IntType || t1 instanceof LongType || t2 instanceof LongType || t1 instanceof UnknownType || t2 instanceof UnknownType;
if (isEssential && t2Int) {
Value v = expr.getOp2();
if (v instanceof IntConstant) {
IntConstant i = (IntConstant) v;
isEssential = (i.value == 0);
} else
// could be 0, we don't know
isEssential = true;
}
if (isEssential && t2 instanceof LongType) {
Value v = expr.getOp2();
if (v instanceof LongConstant) {
LongConstant l = (LongConstant) v;
isEssential = (l.value == 0);
} else
// could be 0, we don't know
isEssential = true;
}
}
}
}
if (isEssential) {
q.addFirst(s);
}
allEssential &= isEssential;
}
if (checkInvoke || !allEssential) {
// Add all the statements which are used to compute values
// for the essential statements, recursively
final LocalDefs localDefs = LocalDefs.Factory.newLocalDefs(b);
if (!allEssential) {
Set<Unit> essential = new HashSet<Unit>(b.getUnits().size());
while (!q.isEmpty()) {
Unit s = q.removeFirst();
if (essential.add(s)) {
for (ValueBox box : s.getUseBoxes()) {
Value v = box.getValue();
if (v instanceof Local) {
Local l = (Local) v;
List<Unit> defs = localDefs.getDefsOfAt(l, s);
if (defs != null)
q.addAll(defs);
}
}
}
}
// Remove the dead statements
units.retainAll(essential);
}
if (checkInvoke) {
final LocalUses localUses = LocalUses.Factory.newLocalUses(b, localDefs);
// Eliminate dead assignments from invokes such as x = f(), where
// x is no longer used
List<AssignStmt> postProcess = new ArrayList<AssignStmt>();
for (Unit u : units) {
if (u instanceof AssignStmt) {
AssignStmt s = (AssignStmt) u;
if (s.containsInvokeExpr()) {
// Just find one use of l which is essential
boolean deadAssignment = true;
for (UnitValueBoxPair pair : localUses.getUsesOf(s)) {
if (units.contains(pair.unit)) {
deadAssignment = false;
break;
}
}
if (deadAssignment) {
postProcess.add(s);
}
}
}
}
final Jimple jimple = Jimple.v();
for (AssignStmt s : postProcess) {
// Transform it into a simple invoke.
Stmt newInvoke = jimple.newInvokeStmt(s.getInvokeExpr());
newInvoke.addAllTagsOf(s);
units.swapWith(s, newInvoke);
// If we have a callgraph, we need to fix it
if (Scene.v().hasCallGraph())
Scene.v().getCallGraph().swapEdgesOutOf(s, newInvoke);
}
}
}
if (soptions.time()) {
Timers.v().deadCodeTimer.end();
}
}
Aggregations