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>
|
<artifactId>gson</artifactId>
|
||||||
<version>2.4</version>
|
<version>2.4</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>3.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
|
|||||||
@@ -129,41 +129,35 @@ public class Rename
|
|||||||
groupOne = one;
|
groupOne = one;
|
||||||
groupTwo = two;
|
groupTwo = two;
|
||||||
|
|
||||||
Execution eone = new Execution(one);
|
// Execution eone = new Execution(one);
|
||||||
eone.setBuildGraph(true);
|
// eone.setBuildGraph(true);
|
||||||
eone.setFollowInvokes(false);
|
// eone.setFollowInvokes(false);
|
||||||
eone.populateInitialMethods();
|
// eone.populateInitialMethods();
|
||||||
List<Method> initial1 = eone.getInitialMethods().stream().sorted((m1, m2) -> m1.getName().compareTo(m2.getName())).collect(Collectors.toList());
|
// List<Method> initial1 = eone.getInitialMethods().stream().sorted((m1, m2) -> m1.getName().compareTo(m2.getName())).collect(Collectors.toList());
|
||||||
eone.run();
|
// 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 etwo = new Execution(two);
|
process(
|
||||||
etwo.setBuildGraph(true);
|
one.findClass("class143").findMethod("method3014"),
|
||||||
etwo.setFollowInvokes(false);
|
two.findClass("class143").findMethod("method2966")
|
||||||
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"));
|
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -115,15 +115,16 @@ public class Execution
|
|||||||
|
|
||||||
public void invoke(InstructionContext from, Method to)
|
public void invoke(InstructionContext from, Method to)
|
||||||
{
|
{
|
||||||
if (!this.isFollowInvokes())
|
if (!this.isFollowInvokes() && !to.isStatic())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (hasInvoked(from, to))
|
// if (hasInvoked(from, to))
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
Frame f = new Frame(this, to);
|
Frame f = new Frame(this, to);
|
||||||
f.initialize(from);
|
f.initialize(from);
|
||||||
this.addFrame(f);
|
frames.add(0, f);
|
||||||
|
//this.addFrame(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addMethod(Method to)
|
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.attributes.code.instruction.types.InvokeInstruction;
|
||||||
import net.runelite.deob.util.IdGen;
|
import net.runelite.deob.util.IdGen;
|
||||||
import org.apache.commons.collections4.map.MultiValueMap;
|
import org.apache.commons.collections4.map.MultiValueMap;
|
||||||
|
import org.apache.commons.lang3.mutable.MutableInt;
|
||||||
|
|
||||||
public class Frame
|
public class Frame
|
||||||
{
|
{
|
||||||
@@ -30,8 +31,9 @@ public class Frame
|
|||||||
private Variables variables;
|
private Variables variables;
|
||||||
private List<InstructionContext> instructions = new ArrayList<>(); // instructions executed in this frame
|
private List<InstructionContext> instructions = new ArrayList<>(); // instructions executed in this frame
|
||||||
private MethodContext ctx;
|
private MethodContext ctx;
|
||||||
protected int prevVertex = -1;
|
protected MutableInt prevVertex = new MutableInt(-1);
|
||||||
private List<Method> prevInvokes;
|
//protected int prevVertex = -1;
|
||||||
|
//private List<Method> prevInvokes;
|
||||||
|
|
||||||
public Frame(Execution execution, Method method)
|
public Frame(Execution execution, Method method)
|
||||||
{
|
{
|
||||||
@@ -68,6 +70,12 @@ public class Frame
|
|||||||
// initialize frame from invoking context
|
// initialize frame from invoking context
|
||||||
assert ctx.getInstruction() instanceof InvokeInstruction;
|
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]
|
// initialize LVT. the last argument is popped first, and is at arguments[0]
|
||||||
List<StackContext> pops = ctx.getPops();
|
List<StackContext> pops = ctx.getPops();
|
||||||
pops = Lists.reverse(new ArrayList<>(pops)); // reverse the list so first argument is at index 0
|
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.stack = new Stack(other.stack);
|
||||||
this.variables = new Variables(other.variables);
|
this.variables = new Variables(other.variables);
|
||||||
this.ctx = other.ctx;
|
this.ctx = other.ctx;
|
||||||
this.prevVertex = other.prevVertex;
|
this.prevVertex = new MutableInt(other.prevVertex);
|
||||||
this.prevInvokes = other.prevInvokes;
|
//this.prevInvokes = other.prevInvokes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Frame dup()
|
public Frame dup()
|
||||||
@@ -193,12 +201,15 @@ public class Frame
|
|||||||
|
|
||||||
execution.executed.add(oldCur);
|
execution.executed.add(oldCur);
|
||||||
|
|
||||||
|
if (!execution.frames.isEmpty() && execution.frames.get(0) != this)
|
||||||
|
break;
|
||||||
|
|
||||||
processExceptions(oldCur);
|
processExceptions(oldCur);
|
||||||
|
|
||||||
if (oldCur instanceof InvokeInstruction)
|
if (oldCur instanceof InvokeInstruction)
|
||||||
{
|
{
|
||||||
InvokeInstruction ii = (InvokeInstruction) oldCur;
|
InvokeInstruction ii = (InvokeInstruction) oldCur;
|
||||||
this.prevInvokes = ii.getMethods();
|
// this.prevInvokes = ii.getMethods();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!executing)
|
if (!executing)
|
||||||
@@ -253,7 +264,7 @@ public class Frame
|
|||||||
assert to.getInstructions() == method.getCode().getInstructions();
|
assert to.getInstructions() == method.getCode().getInstructions();
|
||||||
assert method.getCode().getInstructions().getInstructions().contains(to);
|
assert method.getCode().getInstructions().getInstructions().contains(to);
|
||||||
|
|
||||||
if (ctx.hasJumped(this.prevInvokes, from, to))
|
if (ctx.hasJumped(prevVertex, from, to))
|
||||||
{
|
{
|
||||||
executing = false;
|
executing = false;
|
||||||
return;
|
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.attributes.code.instructions.InvokeStatic;
|
||||||
import net.runelite.deob.util.IdGen;
|
import net.runelite.deob.util.IdGen;
|
||||||
import org.apache.commons.collections4.map.MultiValueMap;
|
import org.apache.commons.collections4.map.MultiValueMap;
|
||||||
|
import org.apache.commons.lang3.mutable.MutableInt;
|
||||||
|
|
||||||
class MIKey
|
class MIKey
|
||||||
{
|
{
|
||||||
private List<Method> method;
|
private int prevVertex;
|
||||||
private InstructionContext ictx;
|
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;
|
this.ictx = ictx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode()
|
public int hashCode()
|
||||||
{
|
{
|
||||||
int hash = 5;
|
int hash = 7;
|
||||||
hash = 61 * hash + Objects.hashCode(this.method);
|
hash = 97 * hash + this.prevVertex;
|
||||||
hash = 61 * hash + Objects.hashCode(this.ictx);
|
hash = 97 * hash + Objects.hashCode(this.ictx);
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +53,7 @@ class MIKey
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final MIKey other = (MIKey) obj;
|
final MIKey other = (MIKey) obj;
|
||||||
if (!Objects.equals(this.method, other.method))
|
if (this.prevVertex != other.prevVertex)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -62,8 +63,6 @@ class MIKey
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MethodContext
|
public class MethodContext
|
||||||
@@ -90,10 +89,10 @@ public class MethodContext
|
|||||||
return graph;
|
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.
|
// 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);
|
Collection<Instruction> i = visited.getCollection(key);
|
||||||
if (i != null && i.contains(to))
|
if (i != null && i.contains(to))
|
||||||
return true;
|
return true;
|
||||||
@@ -124,8 +123,8 @@ public class MethodContext
|
|||||||
|
|
||||||
if (i instanceof InvokeInstruction)
|
if (i instanceof InvokeInstruction)
|
||||||
{
|
{
|
||||||
// if (i instanceof InvokeStatic)
|
if (i instanceof InvokeStatic)
|
||||||
// return;
|
return;
|
||||||
|
|
||||||
InvokeInstruction ii = (InvokeInstruction) i;
|
InvokeInstruction ii = (InvokeInstruction) i;
|
||||||
|
|
||||||
@@ -145,12 +144,12 @@ public class MethodContext
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frame.prevVertex == -1)
|
if (frame.prevVertex.intValue() == -1)
|
||||||
{
|
{
|
||||||
int id = getIdFor(i);
|
int id = getIdFor(i);
|
||||||
//int id = ids.get();
|
//int id = ids.get();
|
||||||
//graph.add(id);
|
//graph.add(id);
|
||||||
frame.prevVertex = id;
|
frame.prevVertex.setValue(id);
|
||||||
//this.idMap.put(id, i);
|
//this.idMap.put(id, i);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -160,12 +159,16 @@ public class MethodContext
|
|||||||
//graph.add(id);
|
//graph.add(id);
|
||||||
//idMap.put(id, i);
|
//idMap.put(id, i);
|
||||||
|
|
||||||
if (id == frame.prevVertex)
|
if (frame.prevVertex.intValue() == id)
|
||||||
return;
|
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);
|
graph.add(edge);
|
||||||
|
|
||||||
frame.prevVertex = id;
|
frame.prevVertex.setValue(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user