Skip to content
81 changes: 42 additions & 39 deletions src/main/java/soot/AbstractSootFieldRef.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,17 @@
* actually exist; the actual target of the reference is determined according to the resolution procedure in the Java Virtual
* Machine Specification, 2nd ed, section 5.4.3.2.
*/

public class AbstractSootFieldRef implements SootFieldRef {
private static final Logger logger = LoggerFactory.getLogger(AbstractSootFieldRef.class);

private final SootClass declaringClass;
private final String name;
private final Type type;
private final boolean isStatic;

private SootField resolveCache = null;

public AbstractSootFieldRef(SootClass declaringClass, String name, Type type, boolean isStatic) {
this.declaringClass = declaringClass;
this.name = name;
this.type = type;
this.isStatic = isStatic;
if (declaringClass == null) {
throw new RuntimeException("Attempt to create SootFieldRef with null class");
}
Expand All @@ -52,13 +54,12 @@ public AbstractSootFieldRef(SootClass declaringClass, String name, Type type, bo
if (type == null) {
throw new RuntimeException("Attempt to create SootFieldRef with null type");
}
this.declaringClass = declaringClass;
this.name = name;
this.type = type;
this.isStatic = isStatic;
}

private final SootClass declaringClass;
private final String name;
private final Type type;
private final boolean isStatic;

@Override
public SootClass declaringClass() {
return declaringClass;
Expand All @@ -85,9 +86,6 @@ public String getSignature() {
}

public class FieldResolutionFailedException extends ResolutionFailedException {
/**
*
*/
private static final long serialVersionUID = -4657113720516199499L;

public FieldResolutionFailedException() {
Expand All @@ -97,42 +95,51 @@ public FieldResolutionFailedException() {

@Override
public String toString() {
StringBuffer ret = new StringBuffer();
ret.append(super.toString());
StringBuilder ret = new StringBuilder(super.toString());
resolve(ret);
return ret.toString();
}
}

@Override
public SootField resolve() {
return resolve(null);
SootField cached = this.resolveCache;
// Use the cached SootField if available and still valid
if (cached == null || !isValidResolve(cached)) {
cached = resolve(null);
this.resolveCache = cached;
}
return cached;
}

private boolean isValidResolve(SootField f) {
return (this.isStatic() == f.isStatic()) && this.declaringClass().equals(f.getDeclaringClass())
&& this.name().equals(f.getName()) && this.type().equals(f.getType());
}

private SootField checkStatic(SootField ret) {
if ((Options.v().wrong_staticness() == Options.wrong_staticness_fail
|| Options.v().wrong_staticness() == Options.wrong_staticness_fixstrict)
&& ret.isStatic() != isStatic() && !ret.isPhantom()) {
|| Options.v().wrong_staticness() == Options.wrong_staticness_fixstrict) && ret.isStatic() != isStatic()
&& !ret.isPhantom()) {
throw new ResolutionFailedException("Resolved " + this + " to " + ret + " which has wrong static-ness");
}
return ret;
}

private SootField resolve(StringBuffer trace) {
private SootField resolve(StringBuilder trace) {
SootClass cl = declaringClass;
while (true) {
if (trace != null) {
trace.append("Looking in " + cl + " which has fields " + cl.getFields() + "\n");
trace.append("Looking in ").append(cl).append(" which has fields ").append(cl.getFields()).append('\n');
}

// Check whether we have the field in the current class
SootField clField = cl.getFieldUnsafe(name, type);
if (clField != null) {
return checkStatic(clField);
}
// If we have a phantom class, we directly construct a phantom field
// in it and don't care about superclasses.
else if (Scene.v().allowsPhantomRefs() && cl.isPhantom()) {
} else if (Scene.v().allowsPhantomRefs() && cl.isPhantom()) {
// If we have a phantom class, we directly construct a phantom field
// in it and don't care about superclasses.
synchronized (cl) {
// Check that no other thread has created the field in the
// meantime
Expand Down Expand Up @@ -164,7 +171,7 @@ else if (Scene.v().allowsPhantomRefs() && cl.isPhantom()) {
}

if (trace != null) {
trace.append("Looking in " + iface + " which has fields " + iface.getFields() + "\n");
trace.append("Looking in ").append(iface).append(" which has fields ").append(iface.getFields()).append('\n');
}
SootField ifaceField = iface.getFieldUnsafe(name, type);
if (ifaceField != null) {
Expand Down Expand Up @@ -208,7 +215,7 @@ else if (Scene.v().allowsPhantomRefs() && cl.isPhantom()) {
if (trace == null) {
FieldResolutionFailedException e = new FieldResolutionFailedException();
if (Options.v().ignore_resolution_errors()) {
logger.debug("" + e.getMessage());
logger.debug(e.getMessage());
} else {
throw e;
}
Expand Down Expand Up @@ -250,38 +257,34 @@ public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
if (obj == null || this.getClass() != obj.getClass()) {
return false;
}
if (getClass() != obj.getClass()) {
AbstractSootFieldRef other = (AbstractSootFieldRef) obj;
if (this.isStatic != other.isStatic) {
return false;
}
AbstractSootFieldRef other = (AbstractSootFieldRef) obj;
if (declaringClass == null) {
if (this.declaringClass == null) {
if (other.declaringClass != null) {
return false;
}
} else if (!declaringClass.equals(other.declaringClass)) {
return false;
}
if (isStatic != other.isStatic) {
} else if (!this.declaringClass.equals(other.declaringClass)) {
return false;
}
if (name == null) {
if (this.name == null) {
if (other.name != null) {
return false;
}
} else if (!name.equals(other.name)) {
} else if (!this.name.equals(other.name)) {
return false;
}
if (type == null) {
if (this.type == null) {
if (other.type != null) {
return false;
}
} else if (!type.equals(other.type)) {
} else if (!this.type.equals(other.type)) {
return false;
}
return true;
}

}
20 changes: 12 additions & 8 deletions src/main/java/soot/dava/internal/javaRep/DInstanceFieldRef.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,39 +23,43 @@
* #L%
*/

import java.util.HashSet;
import java.util.Set;

import soot.SootFieldRef;
import soot.UnitPrinter;
import soot.Value;
import soot.grimp.internal.GInstanceFieldRef;

public class DInstanceFieldRef extends GInstanceFieldRef {
private HashSet<Object> thisLocals;

public DInstanceFieldRef(Value base, SootFieldRef fieldRef, HashSet<Object> thisLocals) {
private final Set<Object> thisLocals;

public DInstanceFieldRef(Value base, SootFieldRef fieldRef, Set<Object> thisLocals) {
super(base, fieldRef);

this.thisLocals = thisLocals;
}

@Override
public void toString(UnitPrinter up) {
if (thisLocals.contains(getBase())) {
up.fieldRef(fieldRef);
up.fieldRef(getFieldRef());
} else {
super.toString(up);
}
}

@Override
public String toString() {
if (thisLocals.contains(getBase())) {
return fieldRef.name();
return getFieldRef().name();
} else {
return super.toString();
}

return super.toString();
}

@Override
public Object clone() {
return new DInstanceFieldRef(getBase(), fieldRef, thisLocals);
return new DInstanceFieldRef(getBase(), getFieldRef(), thisLocals);
}
}
25 changes: 14 additions & 11 deletions src/main/java/soot/dava/internal/javaRep/DStaticFieldRef.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,27 +28,30 @@
import soot.jimple.StaticFieldRef;

public class DStaticFieldRef extends StaticFieldRef {
private boolean supressDeclaringClass;

public void toString(UnitPrinter up) {
if (!supressDeclaringClass) {
up.type(fieldRef.declaringClass().getType());
up.literal(".");
}
up.fieldRef(fieldRef);
}
private final boolean supressDeclaringClass;

public DStaticFieldRef(SootFieldRef fieldRef, String myClassName) {
super(fieldRef);
supressDeclaringClass = myClassName.equals(fieldRef.declaringClass().getName());
this(fieldRef, myClassName.equals(fieldRef.declaringClass().getName()));
}

public DStaticFieldRef(SootFieldRef fieldRef, boolean supressDeclaringClass) {
super(fieldRef);
this.supressDeclaringClass = supressDeclaringClass;
}

@Override
public Object clone() {
return new DStaticFieldRef(fieldRef, supressDeclaringClass);
return new DStaticFieldRef(getFieldRef(), supressDeclaringClass);
}

@Override
public void toString(UnitPrinter up) {
SootFieldRef fRef = getFieldRef();
if (!supressDeclaringClass) {
up.type(fRef.declaringClass().getType());
up.literal(".");
}
up.fieldRef(fRef);
}
}
24 changes: 13 additions & 11 deletions src/main/java/soot/grimp/internal/GInstanceFieldRef.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,29 +30,31 @@
import soot.jimple.internal.AbstractInstanceFieldRef;

public class GInstanceFieldRef extends AbstractInstanceFieldRef implements Precedence {

public GInstanceFieldRef(Value base, SootFieldRef fieldRef) {
super(Grimp.v().newObjExprBox(base), fieldRef);
}

private String toString(Value op, String opString, String rightString) {
String leftOp = opString;

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
final Value op = getBase();
if (op instanceof Precedence && ((Precedence) op).getPrecedence() < getPrecedence()) {
leftOp = "(" + leftOp + ")";
sb.append('(').append(op.toString()).append(')');
} else {
sb.append(op.toString());
}
return leftOp + rightString;
}

public String toString() {
return toString(getBase(), getBase().toString(), "." + fieldRef.getSignature());
sb.append('.').append(getFieldRef().getSignature());
return sb.toString();
}

@Override
public int getPrecedence() {
return 950;
}

@Override
public Object clone() {
return new GInstanceFieldRef(Grimp.cloneIfNecessary(getBase()), fieldRef);
return new GInstanceFieldRef(Grimp.cloneIfNecessary(getBase()), getFieldRef());
}

}
15 changes: 13 additions & 2 deletions src/main/java/soot/jimple/StaticFieldRef.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,26 +46,32 @@ protected StaticFieldRef(SootFieldRef fieldRef) {
this.fieldRef = fieldRef;
}

@Override
public Object clone() {
return new StaticFieldRef(fieldRef);
}

@Override
public String toString() {
return fieldRef.getSignature();
}

@Override
public void toString(UnitPrinter up) {
up.fieldRef(fieldRef);
}

@Override
public SootFieldRef getFieldRef() {
return fieldRef;
}

@Override
public void setFieldRef(SootFieldRef fieldRef) {
this.fieldRef = fieldRef;
}

@Override
public SootField getField() {
return fieldRef.resolve();
}
Expand All @@ -75,26 +81,31 @@ public List<ValueBox> getUseBoxes() {
return Collections.emptyList();
}

@Override
public Type getType() {
return fieldRef.type();
}

@Override
public void apply(Switch sw) {
((RefSwitch) sw).caseStaticFieldRef(this);
}

@Override
public boolean equivTo(Object o) {
if (o instanceof StaticFieldRef) {
return ((StaticFieldRef) o).getField().equals(getField());
} else {
return false;
}

return false;
}

@Override
public int equivHashCode() {
return getField().equivHashCode();
}

@Override
public void convertToBaf(JimpleToBafContext context, List<Unit> out) {
Unit u = Baf.v().newStaticGetInst(fieldRef);
u.addAllTagsOf(context.getCurrentUnit());
Expand Down
Loading