package janala.interpreters; import janala.solvers.History; public class LongValue extends Value { private SymbolicInt symbolic; // mutable in make_symbolic public SymbolicInt getSymbolic() { return symbolic; } private final long concrete; @Override public Object getConcrete() { return concrete; } @Override public boolean equals(Object other) { if (other == null ) { return false; } if (other instanceof LongValue) { LongValue otherVal = (LongValue) other; return (this.concrete == otherVal.concrete && this.symbolic == otherVal.symbolic); } else { return false; } } public long getConcreteLong() { return concrete; } public LongValue(long concrete) { this.concrete = concrete; symbolic = null; } public LongValue(long concrete, SymbolicInt symbolic) { this.concrete = concrete; this.symbolic = symbolic; } public int MAKE_SYMBOLIC(History history) { symbol = symbol + inc; symbolic = new SymbolicInt(symbol - inc); return symbol - inc; } public LongValue LADD(LongValue i) { long concreteVal = concrete + i.concrete; SymbolicInt x = null; if (symbolic == null && i.symbolic == null) { return new LongValue(concreteVal); } else if (symbolic != null && i.symbolic != null) { x = symbolic.add(i.symbolic); return new LongValue(concreteVal, x); } else if (symbolic != null) { x = symbolic.add(i.concrete); return new LongValue(concreteVal, x); } else { x = i.symbolic.add(concrete); return new LongValue(concreteVal, x); } } public LongValue LSUB(LongValue i) { long concreteVal = concrete - i.concrete; SymbolicInt x = null; if (symbolic == null && i.symbolic == null) { return new LongValue(concreteVal); } else if (symbolic != null && i.symbolic != null) { x = symbolic.subtract(i.symbolic); return new LongValue(concreteVal, x); } else if (symbolic != null) { x = symbolic.subtract(i.concrete); return new LongValue(concreteVal, x); } else { x = i.symbolic.subtractFrom(concrete); return new LongValue(concreteVal, x); } } public LongValue LMUL(LongValue i) { long concreteVal = concrete * i.concrete; if (symbolic == null && i.symbolic == null) { return new LongValue(concreteVal); } else if (symbolic != null && i.symbolic != null) { SymbolicInt s = symbolic.multiply(i.concrete); return new LongValue(concreteVal, s); } else if (symbolic != null) { SymbolicInt s = symbolic.multiply(i.concrete); return new LongValue(concreteVal, s); } else { SymbolicInt s = i.symbolic.multiply(concrete); return new LongValue(concreteVal, s); } } public LongValue LDIV(LongValue i) { return new LongValue(concrete / i.concrete); } public LongValue LREM(LongValue i) { return new LongValue(concrete % i.concrete); } public LongValue LNEG() { if (symbolic == null) { return new LongValue(-concrete); } else { return new LongValue( -concrete, symbolic.subtractFrom(0)); } } public LongValue LSHL(LongValue i) { return new LongValue(concrete << i.concrete); } public LongValue LSHR(LongValue i) { return new LongValue(concrete >> i.concrete); } public LongValue LUSHR(LongValue i) { return new LongValue(concrete >>> i.concrete); } public LongValue LAND(LongValue i) { return new LongValue(concrete & i.concrete); } public LongValue LOR(LongValue i) { return new LongValue(concrete | i.concrete); } public LongValue LXOR(LongValue i) { return new LongValue(concrete ^ i.concrete); } public IntValue L2I() { return new IntValue((int) concrete, symbolic); } public FloatValue L2F() { return new FloatValue((float) concrete); } public DoubleValue L2D() { return new DoubleValue((double) concrete); } public IntValue LCMP(LongValue i2) { int val = 0; if (concrete == i2.concrete) { val = 0; } else if (concrete > i2.concrete) { val = 1; } else { val = -1; } if (symbolic == null && i2.symbolic == null) { return new IntValue(val); } else if (symbolic != null && i2.symbolic != null) { return new IntValue(val, symbolic.subtract(i2.symbolic)); } else if (symbolic != null) { return new IntValue(val, symbolic.subtract(i2.concrete)); } else { return new IntValue(val, i2.symbolic.subtractFrom(concrete)); } } @Override public String toString() { return "LongValue{" + "symbolic=" + symbolic + ", concrete=" + concrete + '}'; } }