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
76 changes: 37 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,46 @@ 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 || !cached.isValidResolve(this)) {
cached = resolve(null);
this.resolveCache = cached;
}
return cached;
}

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 +166,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 +210,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 +252,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;
}

}
7 changes: 7 additions & 0 deletions src/main/java/soot/SootField.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
* #L%
*/

import java.util.Objects;
import soot.jimple.paddle.PaddleField;
import soot.jimple.spark.pag.SparkField;
import soot.options.Options;
Expand All @@ -33,6 +34,7 @@
* Soot representation of a Java field. Can be declared to belong to a SootClass.
*/
public class SootField extends AbstractHost implements ClassMember, SparkField, Numberable, PaddleField {

protected String name;
protected Type type;
protected int modifiers;
Expand Down Expand Up @@ -255,4 +257,9 @@ public final void setNumber(int number) {
public SootFieldRef makeRef() {
return Scene.v().makeFieldRef(declaringClass, name, type, isStatic());
}

public boolean isValidResolve(SootFieldRef f) {
return (this.isStatic() == f.isStatic()) && Objects.equals(this.getDeclaringClass(), f.declaringClass())
&& Objects.equals(this.getName(), f.name()) && Objects.equals(this.getType(), f.type());
}
}
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());
}

}
Loading