Instead execute static functions inline as if they arent there to build the graph. Involved changing the executor to execute new frames as they appear. Can match my simple test method.
This commit is contained in:
5
pom.xml
5
pom.xml
@@ -34,6 +34,11 @@
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
|
||||
@@ -129,41 +129,35 @@ public class Rename
|
||||
groupOne = one;
|
||||
groupTwo = two;
|
||||
|
||||
Execution eone = new Execution(one);
|
||||
eone.setBuildGraph(true);
|
||||
eone.setFollowInvokes(false);
|
||||
eone.populateInitialMethods();
|
||||
List<Method> initial1 = eone.getInitialMethods().stream().sorted((m1, m2) -> m1.getName().compareTo(m2.getName())).collect(Collectors.toList());
|
||||
eone.run();
|
||||
|
||||
Execution etwo = new Execution(two);
|
||||
etwo.setBuildGraph(true);
|
||||
etwo.setFollowInvokes(false);
|
||||
etwo.populateInitialMethods();
|
||||
List<Method> initial2 = etwo.getInitialMethods().stream().sorted((m1, m2) -> m1.getName().compareTo(m2.getName())).collect(Collectors.toList());
|
||||
etwo.run();
|
||||
|
||||
assert initial1.size() == initial2.size();
|
||||
|
||||
for (int i = 0; i < initial1.size(); ++i)
|
||||
{
|
||||
Method m1 = initial1.get(i), m2 = initial2.get(i);
|
||||
|
||||
assert m1.getName().equals(m2.getName());
|
||||
|
||||
objMap.put(m1, m2);
|
||||
}
|
||||
// Execution eone = new Execution(one);
|
||||
// eone.setBuildGraph(true);
|
||||
// eone.setFollowInvokes(false);
|
||||
// eone.populateInitialMethods();
|
||||
// List<Method> initial1 = eone.getInitialMethods().stream().sorted((m1, m2) -> m1.getName().compareTo(m2.getName())).collect(Collectors.toList());
|
||||
// eone.run();
|
||||
//
|
||||
// Execution etwo = new Execution(two);
|
||||
// etwo.setBuildGraph(true);
|
||||
// etwo.setFollowInvokes(false);
|
||||
// etwo.populateInitialMethods();
|
||||
// List<Method> initial2 = etwo.getInitialMethods().stream().sorted((m1, m2) -> m1.getName().compareTo(m2.getName())).collect(Collectors.toList());
|
||||
// etwo.run();
|
||||
//
|
||||
// assert initial1.size() == initial2.size();
|
||||
//
|
||||
// for (int i = 0; i < initial1.size(); ++i)
|
||||
// {
|
||||
// Method m1 = initial1.get(i), m2 = initial2.get(i);
|
||||
//
|
||||
// assert m1.getName().equals(m2.getName());
|
||||
//
|
||||
// objMap.put(m1, m2);
|
||||
// }
|
||||
|
||||
// process(
|
||||
// initial1.get(0).getMethod(),
|
||||
// initial2.get(0).getMethod()
|
||||
// );
|
||||
// processed.add(initial1.get(0).getMethod());
|
||||
// process(
|
||||
// one.findClass("class143").findMethod("run"),
|
||||
// two.findClass("class143").findMethod("run")
|
||||
// );
|
||||
// processed.add(one.findClass("client").findMethod("init"));
|
||||
process(
|
||||
one.findClass("class143").findMethod("method3014"),
|
||||
two.findClass("class143").findMethod("method2966")
|
||||
);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
||||
@@ -115,15 +115,16 @@ public class Execution
|
||||
|
||||
public void invoke(InstructionContext from, Method to)
|
||||
{
|
||||
if (!this.isFollowInvokes())
|
||||
if (!this.isFollowInvokes() && !to.isStatic())
|
||||
return;
|
||||
|
||||
if (hasInvoked(from, to))
|
||||
return;
|
||||
// if (hasInvoked(from, to))
|
||||
// return;
|
||||
|
||||
Frame f = new Frame(this, to);
|
||||
f.initialize(from);
|
||||
this.addFrame(f);
|
||||
frames.add(0, f);
|
||||
//this.addFrame(f);
|
||||
}
|
||||
|
||||
public void addMethod(Method to)
|
||||
|
||||
@@ -19,6 +19,7 @@ import net.runelite.deob.pool.NameAndType;
|
||||
import net.runelite.deob.attributes.code.instruction.types.InvokeInstruction;
|
||||
import net.runelite.deob.util.IdGen;
|
||||
import org.apache.commons.collections4.map.MultiValueMap;
|
||||
import org.apache.commons.lang3.mutable.MutableInt;
|
||||
|
||||
public class Frame
|
||||
{
|
||||
@@ -30,8 +31,9 @@ public class Frame
|
||||
private Variables variables;
|
||||
private List<InstructionContext> instructions = new ArrayList<>(); // instructions executed in this frame
|
||||
private MethodContext ctx;
|
||||
protected int prevVertex = -1;
|
||||
private List<Method> prevInvokes;
|
||||
protected MutableInt prevVertex = new MutableInt(-1);
|
||||
//protected int prevVertex = -1;
|
||||
//private List<Method> prevInvokes;
|
||||
|
||||
public Frame(Execution execution, Method method)
|
||||
{
|
||||
@@ -68,6 +70,12 @@ public class Frame
|
||||
// initialize frame from invoking context
|
||||
assert ctx.getInstruction() instanceof InvokeInstruction;
|
||||
|
||||
if (this.getMethod().isStatic())
|
||||
{
|
||||
this.ctx = ctx.getFrame().ctx; // share ctx if this method is static
|
||||
this.prevVertex = ctx.getFrame().prevVertex;
|
||||
}
|
||||
|
||||
// initialize LVT. the last argument is popped first, and is at arguments[0]
|
||||
List<StackContext> pops = ctx.getPops();
|
||||
pops = Lists.reverse(new ArrayList<>(pops)); // reverse the list so first argument is at index 0
|
||||
@@ -101,8 +109,8 @@ public class Frame
|
||||
this.stack = new Stack(other.stack);
|
||||
this.variables = new Variables(other.variables);
|
||||
this.ctx = other.ctx;
|
||||
this.prevVertex = other.prevVertex;
|
||||
this.prevInvokes = other.prevInvokes;
|
||||
this.prevVertex = new MutableInt(other.prevVertex);
|
||||
//this.prevInvokes = other.prevInvokes;
|
||||
}
|
||||
|
||||
public Frame dup()
|
||||
@@ -193,12 +201,15 @@ public class Frame
|
||||
|
||||
execution.executed.add(oldCur);
|
||||
|
||||
if (!execution.frames.isEmpty() && execution.frames.get(0) != this)
|
||||
break;
|
||||
|
||||
processExceptions(oldCur);
|
||||
|
||||
if (oldCur instanceof InvokeInstruction)
|
||||
{
|
||||
InvokeInstruction ii = (InvokeInstruction) oldCur;
|
||||
this.prevInvokes = ii.getMethods();
|
||||
// this.prevInvokes = ii.getMethods();
|
||||
}
|
||||
|
||||
if (!executing)
|
||||
@@ -253,7 +264,7 @@ public class Frame
|
||||
assert to.getInstructions() == method.getCode().getInstructions();
|
||||
assert method.getCode().getInstructions().getInstructions().contains(to);
|
||||
|
||||
if (ctx.hasJumped(this.prevInvokes, from, to))
|
||||
if (ctx.hasJumped(prevVertex, from, to))
|
||||
{
|
||||
executing = false;
|
||||
return;
|
||||
|
||||
@@ -15,24 +15,25 @@ import net.runelite.deob.attributes.code.instruction.types.InvokeInstruction;
|
||||
import net.runelite.deob.attributes.code.instructions.InvokeStatic;
|
||||
import net.runelite.deob.util.IdGen;
|
||||
import org.apache.commons.collections4.map.MultiValueMap;
|
||||
import org.apache.commons.lang3.mutable.MutableInt;
|
||||
|
||||
class MIKey
|
||||
{
|
||||
private List<Method> method;
|
||||
private int prevVertex;
|
||||
private InstructionContext ictx;
|
||||
|
||||
public MIKey(List<Method> method, InstructionContext ictx)
|
||||
public MIKey(int prevVertex, InstructionContext ictx)
|
||||
{
|
||||
this.method = method;
|
||||
this.prevVertex = prevVertex;
|
||||
this.ictx = ictx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
int hash = 5;
|
||||
hash = 61 * hash + Objects.hashCode(this.method);
|
||||
hash = 61 * hash + Objects.hashCode(this.ictx);
|
||||
int hash = 7;
|
||||
hash = 97 * hash + this.prevVertex;
|
||||
hash = 97 * hash + Objects.hashCode(this.ictx);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@@ -52,7 +53,7 @@ class MIKey
|
||||
return false;
|
||||
}
|
||||
final MIKey other = (MIKey) obj;
|
||||
if (!Objects.equals(this.method, other.method))
|
||||
if (this.prevVertex != other.prevVertex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -62,8 +63,6 @@ class MIKey
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class MethodContext
|
||||
@@ -90,10 +89,10 @@ public class MethodContext
|
||||
return graph;
|
||||
}
|
||||
|
||||
protected boolean hasJumped(List<Method> fromm, InstructionContext from, Instruction to)
|
||||
protected boolean hasJumped(MutableInt prevVertex, InstructionContext from, Instruction to)
|
||||
{
|
||||
// with this true, there are so many frames I can't run a full execution without oom.
|
||||
MIKey key = execution.isBuildGraph() ? new MIKey(fromm, from) : new MIKey(null, from);
|
||||
MIKey key = execution.isBuildGraph() ? new MIKey(prevVertex.intValue(), from) : new MIKey(-1, from);
|
||||
Collection<Instruction> i = visited.getCollection(key);
|
||||
if (i != null && i.contains(to))
|
||||
return true;
|
||||
@@ -124,8 +123,8 @@ public class MethodContext
|
||||
|
||||
if (i instanceof InvokeInstruction)
|
||||
{
|
||||
// if (i instanceof InvokeStatic)
|
||||
// return;
|
||||
if (i instanceof InvokeStatic)
|
||||
return;
|
||||
|
||||
InvokeInstruction ii = (InvokeInstruction) i;
|
||||
|
||||
@@ -145,12 +144,12 @@ public class MethodContext
|
||||
return;
|
||||
}
|
||||
|
||||
if (frame.prevVertex == -1)
|
||||
if (frame.prevVertex.intValue() == -1)
|
||||
{
|
||||
int id = getIdFor(i);
|
||||
//int id = ids.get();
|
||||
//graph.add(id);
|
||||
frame.prevVertex = id;
|
||||
frame.prevVertex.setValue(id);
|
||||
//this.idMap.put(id, i);
|
||||
return;
|
||||
}
|
||||
@@ -160,12 +159,16 @@ public class MethodContext
|
||||
//graph.add(id);
|
||||
//idMap.put(id, i);
|
||||
|
||||
if (id == frame.prevVertex)
|
||||
if (frame.prevVertex.intValue() == id)
|
||||
return;
|
||||
|
||||
DirectedEdge edge = new SimpleDirectedEdge(frame.prevVertex, id);
|
||||
InvokeInstruction from = (InvokeInstruction) this.idMap.get(frame.prevVertex.intValue()), to = (InvokeInstruction) this.idMap.get(id);
|
||||
System.out.println("Added edge " + from.getMethods().get(0).getMethods().getClassFile().getName() + "." + from.getMethods().get(0).getName() +
|
||||
" to " + to.getMethods().get(0).getMethods().getClassFile().getName() + "." + to.getMethods().get(0).getName());
|
||||
|
||||
DirectedEdge edge = new SimpleDirectedEdge(frame.prevVertex.intValue(), id);
|
||||
graph.add(edge);
|
||||
|
||||
frame.prevVertex = id;
|
||||
frame.prevVertex.setValue(id);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user