Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update FieldRef classes #1519

Open
wants to merge 10 commits into
base: develop
Choose a base branch
from
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;
tim-hoffman marked this conversation as resolved.
Show resolved Hide resolved

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) {
tim-hoffman marked this conversation as resolved.
Show resolved Hide resolved
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