Split up if/if0s for mapping stuff, maybe

This commit is contained in:
Adam
2015-12-13 00:38:14 -05:00
parent a0a0d1e645
commit 69600fbf4e
24 changed files with 240 additions and 129 deletions

View File

@@ -32,7 +32,7 @@ public abstract class Instruction implements Cloneable
public String toString()
{
Method m = this.getInstructions().getCode().getAttributes().getMethod();
return super.toString() + " in " + m;
return super.toString() + " in " + m + " at pc " + this.getPc();
}
@Override

View File

@@ -121,8 +121,20 @@ import net.runelite.deob.attributes.code.instructions.IStore_3;
import net.runelite.deob.attributes.code.instructions.ISub;
import net.runelite.deob.attributes.code.instructions.IUShR;
import net.runelite.deob.attributes.code.instructions.IXor;
import net.runelite.deob.attributes.code.instructions.If;
import net.runelite.deob.attributes.code.instructions.If0;
import net.runelite.deob.attributes.code.instructions.IfCmpEq;
import net.runelite.deob.attributes.code.instructions.IfCmpGe;
import net.runelite.deob.attributes.code.instructions.IfCmpGt;
import net.runelite.deob.attributes.code.instructions.IfCmpLe;
import net.runelite.deob.attributes.code.instructions.IfCmpLt;
import net.runelite.deob.attributes.code.instructions.IfCmpNe;
import net.runelite.deob.attributes.code.instructions.IfEq;
import net.runelite.deob.attributes.code.instructions.IfGe;
import net.runelite.deob.attributes.code.instructions.IfGt;
import net.runelite.deob.attributes.code.instructions.IfLe;
import net.runelite.deob.attributes.code.instructions.IfLt;
import net.runelite.deob.attributes.code.instructions.IfNe;
import net.runelite.deob.attributes.code.instructions.IfNonNull;
import net.runelite.deob.attributes.code.instructions.IfNull;
import net.runelite.deob.attributes.code.instructions.InstanceOf;
import net.runelite.deob.attributes.code.instructions.InvokeInterface;
import net.runelite.deob.attributes.code.instructions.InvokeSpecial;
@@ -335,20 +347,20 @@ public enum InstructionType
FCMPG(0x96, "fcmpg", FCmpG.class),
DCMPL(0x97, "dcmpl", DCmpL.class),
DCMPG(0x98, "dcmpg", DCmpG.class),
IFEQ(0x99, "ifeq", If0.class),
IFNE(0x9a, "ifne", If0.class),
IFLT(0x9b, "iflt", If0.class),
IFGE(0x9c, "ifge", If0.class),
IFGT(0x9d, "ifgt", If0.class),
IFLE(0x9e, "ifle", If0.class),
IF_ICMPEQ(0x9f, "if_icmpeq", If.class),
IF_ICMPNE(0xa0, "if_icmpne", If.class),
IF_ICMPLT(0xa1, "if_cmplt", If.class),
IF_ICMPGE(0xa2, "if_icmpge", If.class),
IF_ICMPGT(0xa3, "if_icmpgt", If.class),
IF_ICMPLE(0xa4, "if_icmple", If.class),
IF_ACMPEQ(0xa5, "if_acmpeq", If.class),
IF_ACMPNE(0xa6, "if_acmpne", If.class),
IFEQ(0x99, "ifeq", IfEq.class),
IFNE(0x9a, "ifne", IfNe.class),
IFLT(0x9b, "iflt", IfLt.class),
IFGE(0x9c, "ifge", IfGe.class),
IFGT(0x9d, "ifgt", IfGt.class),
IFLE(0x9e, "ifle", IfLe.class),
IF_ICMPEQ(0x9f, "if_icmpeq", IfCmpEq.class),
IF_ICMPNE(0xa0, "if_icmpne", IfCmpNe.class),
IF_ICMPLT(0xa1, "if_cmplt", IfCmpLt.class),
IF_ICMPGE(0xa2, "if_icmpge", IfCmpGe.class),
IF_ICMPGT(0xa3, "if_icmpgt", IfCmpGt.class),
IF_ICMPLE(0xa4, "if_icmple", IfCmpLe.class),
IF_ACMPEQ(0xa5, "if_acmpeq", IfCmpEq.class),
IF_ACMPNE(0xa6, "if_acmpne", IfCmpNe.class),
GOTO(0xa7, "goto", Goto.class),
TABLESWITCH(0xaa, "tableswitch", TableSwitch.class),
LOOKUPSWITCH(0xab, "lookupswitch", LookupSwitch.class),
@@ -377,8 +389,8 @@ public enum InstructionType
MONITOREXIT(0xc3, "monitorexit", MonitorExit.class),
WIDE(0xc4, "wide", Wide.class),
MULTIANEWARRAY(0xc5, "multianewarray", MultiANewArray.class),
IFNULL(0xc6, "ifnull", If0.class),
IFNONNULL(0xc7, "ifnonnull", If0.class),
IFNULL(0xc6, "ifnull", IfNull.class),
IFNONNULL(0xc7, "ifnonnull", IfNonNull.class),
GOTO_W(0xc8, "goto_w", GotoW.class);
private byte code;

View File

@@ -73,10 +73,12 @@ public class If extends Instruction implements JumpingInstruction, ComparisonIns
ins.pop(one, two);
frame.addInstructionContext(ins);
Frame other = frame.dup();
other.jump(ins, to);
ins.branch(other);
frame.addInstructionContext(ins);
}
@Override

View File

@@ -74,10 +74,12 @@ public class If0 extends Instruction implements JumpingInstruction, ComparisonIn
ins.pop(one);
frame.addInstructionContext(ins);
Frame other = frame.dup();
other.jump(ins, to);
ins.branch(other);
frame.addInstructionContext(ins);
}
@Override

View File

@@ -0,0 +1,13 @@
package net.runelite.deob.attributes.code.instructions;
import net.runelite.deob.attributes.code.InstructionType;
import net.runelite.deob.attributes.code.Instructions;
import net.runelite.deob.execution.InstructionContext;
public class IfCmpEq extends If
{
public IfCmpEq(Instructions instructions, InstructionType type, int pc)
{
super(instructions, type, pc);
}
}

View File

@@ -0,0 +1,13 @@
package net.runelite.deob.attributes.code.instructions;
import net.runelite.deob.attributes.code.InstructionType;
import net.runelite.deob.attributes.code.Instructions;
public class IfCmpGe extends If
{
public IfCmpGe(Instructions instructions, InstructionType type, int pc)
{
super(instructions, type, pc);
}
}

View File

@@ -0,0 +1,13 @@
package net.runelite.deob.attributes.code.instructions;
import net.runelite.deob.attributes.code.InstructionType;
import net.runelite.deob.attributes.code.Instructions;
public class IfCmpGt extends If
{
public IfCmpGt(Instructions instructions, InstructionType type, int pc)
{
super(instructions, type, pc);
}
}

View File

@@ -0,0 +1,13 @@
package net.runelite.deob.attributes.code.instructions;
import net.runelite.deob.attributes.code.InstructionType;
import net.runelite.deob.attributes.code.Instructions;
public class IfCmpLe extends If
{
public IfCmpLe(Instructions instructions, InstructionType type, int pc)
{
super(instructions, type, pc);
}
}

View File

@@ -0,0 +1,13 @@
package net.runelite.deob.attributes.code.instructions;
import net.runelite.deob.attributes.code.InstructionType;
import net.runelite.deob.attributes.code.Instructions;
public class IfCmpLt extends If
{
public IfCmpLt(Instructions instructions, InstructionType type, int pc)
{
super(instructions, type, pc);
}
}

View File

@@ -0,0 +1,13 @@
package net.runelite.deob.attributes.code.instructions;
import net.runelite.deob.attributes.code.InstructionType;
import net.runelite.deob.attributes.code.Instructions;
public class IfCmpNe extends If
{
public IfCmpNe(Instructions instructions, InstructionType type, int pc)
{
super(instructions, type, pc);
}
}

View File

@@ -0,0 +1,13 @@
package net.runelite.deob.attributes.code.instructions;
import net.runelite.deob.attributes.code.InstructionType;
import net.runelite.deob.attributes.code.Instructions;
public class IfEq extends If0
{
public IfEq(Instructions instructions, InstructionType type, int pc)
{
super(instructions, type, pc);
}
}

View File

@@ -0,0 +1,13 @@
package net.runelite.deob.attributes.code.instructions;
import net.runelite.deob.attributes.code.InstructionType;
import net.runelite.deob.attributes.code.Instructions;
public class IfGe extends If0
{
public IfGe(Instructions instructions, InstructionType type, int pc)
{
super(instructions, type, pc);
}
}

View File

@@ -0,0 +1,13 @@
package net.runelite.deob.attributes.code.instructions;
import net.runelite.deob.attributes.code.InstructionType;
import net.runelite.deob.attributes.code.Instructions;
public class IfGt extends If0
{
public IfGt(Instructions instructions, InstructionType type, int pc)
{
super(instructions, type, pc);
}
}

View File

@@ -0,0 +1,13 @@
package net.runelite.deob.attributes.code.instructions;
import net.runelite.deob.attributes.code.InstructionType;
import net.runelite.deob.attributes.code.Instructions;
public class IfLe extends If0
{
public IfLe(Instructions instructions, InstructionType type, int pc)
{
super(instructions, type, pc);
}
}

View File

@@ -0,0 +1,13 @@
package net.runelite.deob.attributes.code.instructions;
import net.runelite.deob.attributes.code.InstructionType;
import net.runelite.deob.attributes.code.Instructions;
public class IfLt extends If0
{
public IfLt(Instructions instructions, InstructionType type, int pc)
{
super(instructions, type, pc);
}
}

View File

@@ -0,0 +1,13 @@
package net.runelite.deob.attributes.code.instructions;
import net.runelite.deob.attributes.code.InstructionType;
import net.runelite.deob.attributes.code.Instructions;
public class IfNe extends If0
{
public IfNe(Instructions instructions, InstructionType type, int pc)
{
super(instructions, type, pc);
}
}

View File

@@ -0,0 +1,13 @@
package net.runelite.deob.attributes.code.instructions;
import net.runelite.deob.attributes.code.InstructionType;
import net.runelite.deob.attributes.code.Instructions;
public class IfNonNull extends If0
{
public IfNonNull(Instructions instructions, InstructionType type, int pc)
{
super(instructions, type, pc);
}
}

View File

@@ -0,0 +1,13 @@
package net.runelite.deob.attributes.code.instructions;
import net.runelite.deob.attributes.code.InstructionType;
import net.runelite.deob.attributes.code.Instructions;
public class IfNull extends If0
{
public IfNull(Instructions instructions, InstructionType type, int pc)
{
super(instructions, type, pc);
}
}

View File

@@ -118,15 +118,17 @@ public class LookupSwitch extends Instruction implements JumpingInstruction
StackContext value = stack.pop();
ins.pop(value);
frame.addInstructionContext(ins);
for (Instruction i : branchi)
{
Frame other = frame.dup();
other.jump(ins, i);
ins.branch(other);
}
frame.jump(ins, defi);
frame.addInstructionContext(ins);
}
@Override

View File

@@ -114,15 +114,17 @@ public class TableSwitch extends Instruction implements JumpingInstruction
StackContext value = stack.pop();
ins.pop(value);
frame.addInstructionContext(ins);
for (Instruction i : branchi)
{
Frame other = frame.dup();
other.jump(ins, i);
ins.branch(other);
}
frame.jump(ins, defi);
frame.addInstructionContext(ins);
}
@Override

View File

@@ -37,8 +37,6 @@ public class Execution
public Set<Instruction> executed = new HashSet<>(); // executed instructions
private MultiValueMap<InstructionContext, Method> invokes = new MultiValueMap<>();
public MultiValueMap<Instruction, InstructionContext> contexts = new MultiValueMap<>();
private boolean buildGraph; // if true the frame graph is built and execution hasJumped also compares previous instructions
private Graph graph = new Graph();
public Execution(ClassGroup group)
{
@@ -125,7 +123,6 @@ public class Execution
public void run()
{
initializeGraph();
int fcount = 0;
while (!frames.isEmpty())
@@ -147,106 +144,10 @@ public class Execution
System.out.println("Processed " + fcount + " frames");
}
public Collection<InstructionContext> getInstructonContexts(Instruction i)
{
return contexts.getCollection(i);
}
public boolean isBuildGraph()
{
return buildGraph;
}
public void setBuildGraph(boolean buildGraph)
{
this.buildGraph = buildGraph;
}
private void initializeGraph()
{
if (!isBuildGraph())
return;
for (ClassFile cf : this.group.getClasses())
{
//graph.addVertex(cf, VertexType.CLASS);
for (Method m : cf.getMethods().getMethods())
{
if (m.isStatic() && !m.getName().equals("<clinit>"))
continue;
graph.addVertex(m, VertexType.METHOD);
}
for (Field f : cf.getFields().getFields())
{
graph.addVertex(f, VertexType.FIELD);
}
}
}
protected void buildGraph(Frame frame, Instruction i, InstructionContext ctx)
{
if (!isBuildGraph())
return;
assert frame.getMethod() == frame.nonStatic || frame.nonStatic.isStatic() == false;
assert ctx.getInstruction() == i;
if (i instanceof InvokeInstruction)
{
if (i instanceof InvokeStatic)
return;
InvokeInstruction ii = (InvokeInstruction) i;
List<Method> methods = ii.getMethods();
if (methods.isEmpty())
return;
for (Method m : methods)
{
graph.addEdge(new Edge(ctx, graph.getVertexFor(frame.nonStatic), graph.getVertexFor(m), EdgeType.INVOKE));
graph.addEdge(new Edge(ctx, graph.getVertexFor(m), graph.getVertexFor(frame.nonStatic), EdgeType.INVOKED_FROM));
}
}
else if (i instanceof FieldInstruction)
{
FieldInstruction fi = (FieldInstruction) i;
if (fi.getMyField() == null)
return;
EdgeType type = fi instanceof GetFieldInstruction ? EdgeType.GETFIELD : EdgeType.SETFIELD;
graph.addEdge(new Edge(ctx, graph.getVertexFor(frame.nonStatic), graph.getVertexFor(fi.getMyField()), type));
EdgeType typeRev = fi instanceof GetFieldInstruction ? EdgeType.GETFIELD_FROM : EdgeType.SETFIELD_FROM;
graph.addEdge(new Edge(ctx, graph.getVertexFor(fi.getMyField()), graph.getVertexFor(frame.nonStatic), typeRev));
}
}
private static List<InstructionContext> getInsInExpr(InstructionContext ctx, Set<Instruction> set)
{
List<InstructionContext> l = new ArrayList<>();
if (ctx == null || set.contains(ctx.getInstruction()))
return l;
set.add(ctx.getInstruction());
l.add(ctx);
for (StackContext s : ctx.getPops())
l.addAll(getInsInExpr(s.getPushed(), set));
for (StackContext s : ctx.getPushes())
for (InstructionContext i : s.getPopped())
l.addAll(getInsInExpr(i, set));
return l;
}
public Graph getGraph()
{
return graph;
}
}

View File

@@ -209,8 +209,6 @@ public class Frame
if (!executing)
break;
execution.buildGraph(this, oldCur, ictx);
if (oldCur == cur)
{
int idx = instructions.indexOf(cur);

View File

@@ -17,6 +17,7 @@ public class InstructionContext
private List<StackContext> pushes = new ArrayList<>(); // stack contexts pushed by instruction execution
private List<VariableContext> reads = new ArrayList<>(); // lvt reads
private List<Method> invokes = new ArrayList<>(); // invokes
private List<Frame> branches = new ArrayList<>();
public InstructionContext(Instruction i, Frame f)
{
@@ -55,6 +56,14 @@ public class InstructionContext
invokes.add(method);
}
public void branch(Frame frame)
{
assert frame != this.frame;
assert !branches.contains(frame);
branches.add(frame);
}
public Instruction getInstruction()
{
return ins;

View File

@@ -23,6 +23,7 @@ public class VariableContext
public VariableContext(Type type) // for entrypoints
{
this.type = type;
value = Value.NULL;
}
public VariableContext(InstructionContext i, VariableContext other)