Store stack context with variable context, and pass up stack contexts when invoking methods. I don't think iirc is right?
This commit is contained in:
@@ -47,66 +47,66 @@ public class Deob
|
||||
// bdur = System.currentTimeMillis() - bstart;
|
||||
// System.out.println("rename unique took " + bdur/1000L + " seconds");
|
||||
|
||||
// // remove except RuntimeException
|
||||
// bstart = System.currentTimeMillis();
|
||||
// new RuntimeExceptions().run(group);
|
||||
// bdur = System.currentTimeMillis() - bstart;
|
||||
// System.out.println("runtime exception took " + bdur/1000L + " seconds");
|
||||
//
|
||||
// // remove unused methods
|
||||
// bstart = System.currentTimeMillis();
|
||||
// new UnusedMethods().run(group);
|
||||
// bdur = System.currentTimeMillis() - bstart;
|
||||
// System.out.println("unused methods took " + bdur/1000L + " seconds");
|
||||
//
|
||||
// new UnreachedCode().run(group);
|
||||
//
|
||||
// // remove illegal state exceptions, frees up some parameters
|
||||
// bstart = System.currentTimeMillis();
|
||||
// new IllegalStateExceptions().run(group);
|
||||
// bdur = System.currentTimeMillis() - bstart;
|
||||
// System.out.println("illegal state exception took " + bdur/1000L + " seconds");
|
||||
//
|
||||
// // remove constant logically dead parameters
|
||||
// bstart = System.currentTimeMillis();
|
||||
// new ConstantParameter().run(group);
|
||||
// bdur = System.currentTimeMillis() - bstart;
|
||||
// System.out.println("constant param took " + bdur/1000L + " seconds");
|
||||
//
|
||||
// // remove unhit blocks
|
||||
// bstart = System.currentTimeMillis();
|
||||
// new UnreachedCode().run(group);
|
||||
// //new UnusedBlocks().run(group);
|
||||
// bdur = System.currentTimeMillis() - bstart;
|
||||
// System.out.println("unused blocks took " + bdur/1000L + " seconds");
|
||||
//
|
||||
// // remove unused parameters
|
||||
// bstart = System.currentTimeMillis();
|
||||
// new UnusedParameters().run(group);
|
||||
// bdur = System.currentTimeMillis() - bstart;
|
||||
// System.out.println("unused params took " + bdur/1000L + " seconds");
|
||||
//
|
||||
// // remove jump obfuscation
|
||||
// //new Jumps().run(group);
|
||||
//
|
||||
// // remove unused fields
|
||||
// bstart = System.currentTimeMillis();
|
||||
// new UnusedFields().run(group);
|
||||
// bdur = System.currentTimeMillis() - bstart;
|
||||
// System.out.println("unused fields took " + bdur/1000L + " seconds");
|
||||
//
|
||||
// // remove unused methods, again?
|
||||
// bstart = System.currentTimeMillis();
|
||||
// new UnusedMethods().run(group);
|
||||
// bdur = System.currentTimeMillis() - bstart;
|
||||
// System.out.println("unused methods took " + bdur/1000L + " seconds");
|
||||
//
|
||||
//
|
||||
// new MethodInliner().run(group);
|
||||
//
|
||||
// new MethodMover().run(group);
|
||||
//
|
||||
// new FieldInliner().run(group);
|
||||
// remove except RuntimeException
|
||||
bstart = System.currentTimeMillis();
|
||||
new RuntimeExceptions().run(group);
|
||||
bdur = System.currentTimeMillis() - bstart;
|
||||
System.out.println("runtime exception took " + bdur/1000L + " seconds");
|
||||
|
||||
// remove unused methods
|
||||
bstart = System.currentTimeMillis();
|
||||
new UnusedMethods().run(group);
|
||||
bdur = System.currentTimeMillis() - bstart;
|
||||
System.out.println("unused methods took " + bdur/1000L + " seconds");
|
||||
|
||||
new UnreachedCode().run(group);
|
||||
|
||||
// remove illegal state exceptions, frees up some parameters
|
||||
bstart = System.currentTimeMillis();
|
||||
new IllegalStateExceptions().run(group);
|
||||
bdur = System.currentTimeMillis() - bstart;
|
||||
System.out.println("illegal state exception took " + bdur/1000L + " seconds");
|
||||
|
||||
// remove constant logically dead parameters
|
||||
bstart = System.currentTimeMillis();
|
||||
new ConstantParameter().run(group);
|
||||
bdur = System.currentTimeMillis() - bstart;
|
||||
System.out.println("constant param took " + bdur/1000L + " seconds");
|
||||
|
||||
// remove unhit blocks
|
||||
bstart = System.currentTimeMillis();
|
||||
new UnreachedCode().run(group);
|
||||
//new UnusedBlocks().run(group);
|
||||
bdur = System.currentTimeMillis() - bstart;
|
||||
System.out.println("unused blocks took " + bdur/1000L + " seconds");
|
||||
|
||||
// remove unused parameters
|
||||
bstart = System.currentTimeMillis();
|
||||
new UnusedParameters().run(group);
|
||||
bdur = System.currentTimeMillis() - bstart;
|
||||
System.out.println("unused params took " + bdur/1000L + " seconds");
|
||||
|
||||
// remove jump obfuscation
|
||||
//new Jumps().run(group);
|
||||
|
||||
// remove unused fields
|
||||
bstart = System.currentTimeMillis();
|
||||
new UnusedFields().run(group);
|
||||
bdur = System.currentTimeMillis() - bstart;
|
||||
System.out.println("unused fields took " + bdur/1000L + " seconds");
|
||||
|
||||
// remove unused methods, again?
|
||||
bstart = System.currentTimeMillis();
|
||||
new UnusedMethods().run(group);
|
||||
bdur = System.currentTimeMillis() - bstart;
|
||||
System.out.println("unused methods took " + bdur/1000L + " seconds");
|
||||
|
||||
|
||||
new MethodInliner().run(group);
|
||||
|
||||
new MethodMover().run(group);
|
||||
|
||||
new FieldInliner().run(group);
|
||||
|
||||
// XXX this is broken because when moving clinit around, some fields can depend on other fields
|
||||
// (like multianewarray)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package net.runelite.deob.attributes.code.instructions;
|
||||
|
||||
import net.runelite.deob.ClassFile;
|
||||
import net.runelite.deob.attributes.code.Instruction;
|
||||
import net.runelite.deob.attributes.code.InstructionType;
|
||||
import net.runelite.deob.attributes.code.Instructions;
|
||||
@@ -12,7 +11,6 @@ import net.runelite.deob.execution.Stack;
|
||||
import net.runelite.deob.execution.StackContext;
|
||||
import net.runelite.deob.execution.VariableContext;
|
||||
import net.runelite.deob.execution.Variables;
|
||||
import net.runelite.deob.pool.Class;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
@@ -55,7 +53,7 @@ public class AStore extends Instruction implements LVTInstruction, WideInstructi
|
||||
StackContext object = stack.pop();
|
||||
ins.pop(object);
|
||||
|
||||
variables.set(index, new VariableContext(ins, object.getType()));
|
||||
variables.set(index, new VariableContext(ins, object));
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public class AStore_0 extends Instruction implements LVTInstruction
|
||||
StackContext object = stack.pop();
|
||||
ins.pop(object);
|
||||
|
||||
variables.set(0, new VariableContext(ins, object.getType()));
|
||||
variables.set(0, new VariableContext(ins, object));
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public class AStore_1 extends Instruction implements LVTInstruction
|
||||
StackContext object = stack.pop();
|
||||
ins.pop(object);
|
||||
|
||||
variables.set(1, new VariableContext(ins, object.getType()));
|
||||
variables.set(1, new VariableContext(ins, object));
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public class AStore_2 extends Instruction implements LVTInstruction
|
||||
StackContext object = stack.pop();
|
||||
ins.pop(object);
|
||||
|
||||
variables.set(2, new VariableContext(ins, object.getType()));
|
||||
variables.set(2, new VariableContext(ins, object));
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public class AStore_3 extends Instruction implements LVTInstruction
|
||||
StackContext object = stack.pop();
|
||||
ins.pop(object);
|
||||
|
||||
variables.set(3, new VariableContext(ins, object.getType()));
|
||||
variables.set(3, new VariableContext(ins, object));
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public class DStore extends Instruction implements LVTInstruction, WideInstructi
|
||||
StackContext value = stack.pop();
|
||||
ins.pop(value);
|
||||
|
||||
variables.set(index, new VariableContext(ins, value.getType()));
|
||||
variables.set(index, new VariableContext(ins, value));
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public class DStore_0 extends Instruction implements LVTInstruction
|
||||
StackContext value = stack.pop();
|
||||
ins.pop(value);
|
||||
|
||||
variables.set(0, new VariableContext(ins, value.getType()));
|
||||
variables.set(0, new VariableContext(ins, value));
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public class DStore_1 extends Instruction implements LVTInstruction
|
||||
StackContext value = stack.pop();
|
||||
ins.pop(value);
|
||||
|
||||
variables.set(1, new VariableContext(ins, value.getType()));
|
||||
variables.set(1, new VariableContext(ins, value));
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public class DStore_2 extends Instruction implements LVTInstruction
|
||||
StackContext value = stack.pop();
|
||||
ins.pop(value);
|
||||
|
||||
variables.set(2, new VariableContext(ins, value.getType()));
|
||||
variables.set(2, new VariableContext(ins, value));
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public class DStore_3 extends Instruction implements LVTInstruction
|
||||
StackContext value = stack.pop();
|
||||
ins.pop(value);
|
||||
|
||||
variables.set(3, new VariableContext(ins, value.getType()));
|
||||
variables.set(3, new VariableContext(ins, value));
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public class FStore extends Instruction implements LVTInstruction, WideInstructi
|
||||
StackContext value = stack.pop();
|
||||
ins.pop(value);
|
||||
|
||||
variables.set(index, new VariableContext(ins, value.getType()));
|
||||
variables.set(index, new VariableContext(ins, value));
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public class FStore_0 extends Instruction implements LVTInstruction
|
||||
StackContext value = stack.pop();
|
||||
ins.pop(value);
|
||||
|
||||
variables.set(0, new VariableContext(ins, value.getType()));
|
||||
variables.set(0, new VariableContext(ins, value));
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public class FStore_1 extends Instruction implements LVTInstruction
|
||||
StackContext value = stack.pop();
|
||||
ins.pop(value);
|
||||
|
||||
variables.set(1, new VariableContext(ins, value.getType()));
|
||||
variables.set(1, new VariableContext(ins, value));
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public class FStore_2 extends Instruction implements LVTInstruction
|
||||
StackContext value = stack.pop();
|
||||
ins.pop(value);
|
||||
|
||||
variables.set(2, new VariableContext(ins, value.getType()));
|
||||
variables.set(2, new VariableContext(ins, value));
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public class FStore_3 extends Instruction implements LVTInstruction
|
||||
StackContext value = stack.pop();
|
||||
ins.pop(value);
|
||||
|
||||
variables.set(3, new VariableContext(ins, value.getType()));
|
||||
variables.set(3, new VariableContext(ins, value));
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public class IInc extends Instruction implements LVTInstruction, WideInstruction
|
||||
assert vctx.getType().equals(new Type(int.class.getCanonicalName()));
|
||||
ins.read(vctx);
|
||||
|
||||
vctx = new VariableContext(ins, vctx.getType());
|
||||
vctx = new VariableContext(ins, vctx.getStackContext()); // XXX this is probably not right.
|
||||
var.set(index, vctx);
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
|
||||
@@ -64,7 +64,7 @@ public class IStore extends Instruction implements LVTInstruction, WideInstructi
|
||||
assert value.getType().equals(new Type(int.class.getName()));
|
||||
ins.pop(value);
|
||||
|
||||
variables.set(index, new VariableContext(ins, value.getType()));
|
||||
variables.set(index, new VariableContext(ins, value));
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ public class IStore_0 extends Instruction implements LVTInstruction
|
||||
assert value.getType().equals(new Type(int.class.getName()));
|
||||
ins.pop(value);
|
||||
|
||||
variables.set(0, new VariableContext(ins, value.getType()));
|
||||
variables.set(0, new VariableContext(ins, value));
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ public class IStore_1 extends Instruction implements LVTInstruction
|
||||
assert value.getType().equals(new Type(int.class.getName()));
|
||||
ins.pop(value);
|
||||
|
||||
variables.set(1, new VariableContext(ins, value.getType()));
|
||||
variables.set(1, new VariableContext(ins, value));
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ public class IStore_2 extends Instruction implements LVTInstruction
|
||||
assert value.getType().equals(new Type(int.class.getName()));
|
||||
ins.pop(value);
|
||||
|
||||
variables.set(2, new VariableContext(ins, value.getType()));
|
||||
variables.set(2, new VariableContext(ins, value));
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ public class IStore_3 extends Instruction implements LVTInstruction
|
||||
assert value.getType().equals(new Type(int.class.getName()));
|
||||
ins.pop(value);
|
||||
|
||||
variables.set(3, new VariableContext(ins, value.getType()));
|
||||
variables.set(3, new VariableContext(ins, value));
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.runelite.deob.execution.Execution;
|
||||
|
||||
public class InvokeInterface extends Instruction implements InvokeInstruction
|
||||
{
|
||||
@@ -102,8 +103,16 @@ public class InvokeInterface extends Instruction implements InvokeInstruction
|
||||
for (net.runelite.deob.Method method : getMethods())
|
||||
{
|
||||
ins.invoke(method);
|
||||
|
||||
if (method.getCode() == null)
|
||||
{
|
||||
frame.getExecution().methods.add(method);
|
||||
continue;
|
||||
}
|
||||
|
||||
// add possible method call to execution
|
||||
frame.getExecution().addMethod(method);
|
||||
Execution execution = frame.getExecution();
|
||||
execution.invoke(ins, method);
|
||||
}
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.runelite.deob.execution.Execution;
|
||||
|
||||
public class InvokeSpecial extends Instruction implements InvokeInstruction
|
||||
{
|
||||
@@ -88,8 +89,16 @@ public class InvokeSpecial extends Instruction implements InvokeInstruction
|
||||
for (net.runelite.deob.Method method : getMethods())
|
||||
{
|
||||
ins.invoke(method);
|
||||
|
||||
if (method.getCode() == null)
|
||||
{
|
||||
frame.getExecution().methods.add(method);
|
||||
continue;
|
||||
}
|
||||
|
||||
// add possible method call to execution
|
||||
frame.getExecution().addMethod(method);
|
||||
Execution execution = frame.getExecution();
|
||||
execution.invoke(ins, method);
|
||||
}
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.runelite.deob.execution.Execution;
|
||||
|
||||
public class InvokeStatic extends Instruction implements InvokeInstruction
|
||||
{
|
||||
@@ -85,8 +86,16 @@ public class InvokeStatic extends Instruction implements InvokeInstruction
|
||||
for (net.runelite.deob.Method method : getMethods())
|
||||
{
|
||||
ins.invoke(method);
|
||||
|
||||
if (method.getCode() == null)
|
||||
{
|
||||
frame.getExecution().methods.add(method);
|
||||
continue;
|
||||
}
|
||||
|
||||
// add possible method call to execution
|
||||
frame.getExecution().addMethod(method);
|
||||
Execution execution = frame.getExecution();
|
||||
execution.invoke(ins, method);
|
||||
}
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.runelite.deob.execution.Execution;
|
||||
|
||||
public class InvokeVirtual extends Instruction implements InvokeInstruction
|
||||
{
|
||||
@@ -71,8 +72,16 @@ public class InvokeVirtual extends Instruction implements InvokeInstruction
|
||||
for (net.runelite.deob.Method method : getMethods())
|
||||
{
|
||||
ins.invoke(method);
|
||||
|
||||
if (method.getCode() == null)
|
||||
{
|
||||
frame.getExecution().methods.add(method);
|
||||
continue;
|
||||
}
|
||||
|
||||
// add possible method call to execution
|
||||
frame.getExecution().addMethod(method);
|
||||
Execution execution = frame.getExecution();
|
||||
execution.invoke(ins, method);
|
||||
}
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
|
||||
@@ -55,7 +55,7 @@ public class LStore extends Instruction implements LVTInstruction, WideInstructi
|
||||
assert value.getType().equals(new Type(long.class.getName()));
|
||||
ins.pop(value);
|
||||
|
||||
variables.set(index, new VariableContext(ins, value.getType()));
|
||||
variables.set(index, new VariableContext(ins, value));
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ public class LStore_0 extends Instruction implements LVTInstruction
|
||||
assert value.getType().equals(new Type(long.class.getName()));
|
||||
ins.pop(value);
|
||||
|
||||
variables.set(0, new VariableContext(ins, value.getType()));
|
||||
variables.set(0, new VariableContext(ins, value));
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ public class LStore_1 extends Instruction implements LVTInstruction
|
||||
assert value.getType().equals(new Type(long.class.getName()));
|
||||
ins.pop(value);
|
||||
|
||||
variables.set(1, new VariableContext(ins, value.getType()));
|
||||
variables.set(1, new VariableContext(ins, value));
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ public class LStore_2 extends Instruction implements LVTInstruction
|
||||
assert value.getType().equals(new Type(long.class.getName()));
|
||||
ins.pop(value);
|
||||
|
||||
variables.set(2, new VariableContext(ins, value.getType()));
|
||||
variables.set(2, new VariableContext(ins, value));
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ public class LStore_3 extends Instruction implements LVTInstruction
|
||||
assert value.getType().equals(new Type(long.class.getName()));
|
||||
ins.pop(value);
|
||||
|
||||
variables.set(3, new VariableContext(ins, value.getType()));
|
||||
variables.set(3, new VariableContext(ins, value));
|
||||
|
||||
frame.addInstructionContext(ins);
|
||||
}
|
||||
|
||||
@@ -7,18 +7,20 @@ import net.runelite.deob.Method;
|
||||
import net.runelite.deob.attributes.code.Instruction;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.apache.commons.collections4.map.MultiValueMap;
|
||||
|
||||
public class Execution
|
||||
{
|
||||
private ClassGroup group;
|
||||
public List<Frame> frames = new ArrayList<>(),
|
||||
processedFrames = new ArrayList<>();
|
||||
private List<Method> pendingMethods = new ArrayList<>(); // pending methods
|
||||
public Set<Method> methods = new HashSet<>(); // all methods
|
||||
public Set<Instruction> executed = new HashSet<>(); // executed instructions
|
||||
private MultiValueMap<InstructionContext, Method> invokes = new MultiValueMap<>();
|
||||
|
||||
public Execution(ClassGroup group)
|
||||
{
|
||||
@@ -30,58 +32,62 @@ public class Execution
|
||||
for (ClassFile cf : group.getClasses())
|
||||
{
|
||||
for (Method m : cf.getMethods().getMethods())
|
||||
{
|
||||
{
|
||||
if (!Deob.isObfuscated(m.getName()) && !m.getName().equals("<init>"))
|
||||
{
|
||||
addMethod(m); // I guess this method name is overriding a jre interface (init, run, ?).
|
||||
if (m.getCode() == null)
|
||||
{
|
||||
methods.add(m);
|
||||
continue;
|
||||
}
|
||||
|
||||
Frame frame = new Frame(this, m);
|
||||
frame.initialize();
|
||||
addFrame(frame); // I guess this method name is overriding a jre interface (init, run, ?).
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addMethod(Method method)
|
||||
private boolean hasInvoked(InstructionContext from, Method to)
|
||||
{
|
||||
assert method != null;
|
||||
Collection<Method> methods = invokes.getCollection(from);
|
||||
if (methods != null && methods.contains(to))
|
||||
return true;
|
||||
|
||||
if (methods.contains(method))
|
||||
return; // already processed
|
||||
invokes.put(from, to);
|
||||
return false;
|
||||
}
|
||||
|
||||
private void addFrame(Frame frame)
|
||||
{
|
||||
frames.add(frame);
|
||||
}
|
||||
|
||||
public void invoke(InstructionContext from, Method to)
|
||||
{
|
||||
if (hasInvoked(from, to))
|
||||
return;
|
||||
|
||||
pendingMethods.add(method);
|
||||
methods.add(method);
|
||||
Frame f = new Frame(this, to);
|
||||
f.initialize(from);
|
||||
this.addFrame(f);
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
int count = 0, fcount = 0;
|
||||
while (!pendingMethods.isEmpty())
|
||||
{
|
||||
Method method = pendingMethods.remove(0);
|
||||
|
||||
if (method.getCode() == null)
|
||||
continue;
|
||||
|
||||
Frame f = new Frame(this, method);
|
||||
frames.add(f);
|
||||
|
||||
fcount += this.runFrames();
|
||||
++count;
|
||||
}
|
||||
|
||||
System.out.println("Processed " + count + " methods and " + fcount + " paths");
|
||||
}
|
||||
|
||||
private int runFrames()
|
||||
{
|
||||
int fcount = 0;
|
||||
|
||||
while (!frames.isEmpty())
|
||||
{
|
||||
Frame frame = frames.remove(0);
|
||||
|
||||
methods.add(frame.getMethod());
|
||||
|
||||
++fcount;
|
||||
frame.execute();
|
||||
processedFrames.add(frame);
|
||||
}
|
||||
|
||||
return fcount;
|
||||
System.out.println("Processed " + fcount + " frames");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.runelite.deob.execution;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
@@ -15,6 +16,7 @@ import net.runelite.deob.attributes.code.instructions.TableSwitch;
|
||||
import net.runelite.deob.pool.NameAndType;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import net.runelite.deob.attributes.code.instruction.types.InvokeInstruction;
|
||||
import org.apache.commons.collections4.MultiMap;
|
||||
import org.apache.commons.collections4.map.MultiValueMap;
|
||||
|
||||
@@ -38,19 +40,52 @@ public class Frame
|
||||
|
||||
stack = new Stack(code.getMaxStack());
|
||||
variables = new Variables(code.getMaxLocals());
|
||||
|
||||
}
|
||||
|
||||
public void initialize()
|
||||
{
|
||||
// initialize LVT
|
||||
int pos = 0;
|
||||
if (!method.isStatic())
|
||||
variables.set(pos++, new VariableContext(null, new Type(method.getMethods().getClassFile().getName())));
|
||||
variables.set(pos++, new VariableContext(new Type(method.getMethods().getClassFile().getName())));
|
||||
|
||||
NameAndType nat = method.getNameAndType();
|
||||
for (int i = 0; i < nat.getNumberOfArgs(); ++i)
|
||||
{
|
||||
variables.set(pos, new VariableContext(null, new Type(nat.getDescriptor().getTypeOfArg(i)).toStackType()));
|
||||
variables.set(pos, new VariableContext(new Type(nat.getDescriptor().getTypeOfArg(i)).toStackType()));
|
||||
pos += nat.getDescriptor().getTypeOfArg(i).getSlots();
|
||||
}
|
||||
|
||||
Code code = method.getCode();
|
||||
cur = code.getInstructions().getInstructions().get(0);
|
||||
}
|
||||
|
||||
public void initialize(InstructionContext ctx)
|
||||
{
|
||||
// initialize frame from invoking context
|
||||
assert ctx.getInstruction() instanceof InvokeInstruction;
|
||||
|
||||
// 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
|
||||
|
||||
int lvtOffset = 0;
|
||||
if (!method.isStatic())
|
||||
variables.set(lvtOffset++, new VariableContext(ctx, pops.remove(0)));
|
||||
|
||||
NameAndType nat = method.getNameAndType();
|
||||
|
||||
for (int i = 0; i < nat.getNumberOfArgs(); ++i)
|
||||
{
|
||||
StackContext argument = pops.remove(0);
|
||||
|
||||
variables.set(lvtOffset, new VariableContext(ctx, argument));//new Type(nat.getDescriptor().getTypeOfArg(i)).toStackType()));
|
||||
lvtOffset += nat.getDescriptor().getTypeOfArg(i).getSlots();
|
||||
}
|
||||
|
||||
assert pops.isEmpty();
|
||||
|
||||
Code code = method.getCode();
|
||||
cur = code.getInstructions().getInstructions().get(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ public class InstructionContext
|
||||
Stack ours = new Stack(this.getStack()), // copy stacks since we destroy them
|
||||
theirs = new Stack(ic.getStack());
|
||||
|
||||
if (ours.getSize() != theirs.getSize())
|
||||
if (ours.getSize() != theirs.getSize()) // is this possible?
|
||||
return false;
|
||||
|
||||
while (ours.getSize() > 0)
|
||||
|
||||
@@ -2,13 +2,25 @@ package net.runelite.deob.execution;
|
||||
|
||||
public class VariableContext
|
||||
{
|
||||
private InstructionContext ic;
|
||||
private StackContext ctx; // the value stored
|
||||
private InstructionContext ic; // the instruction which stored it. also ctx.popped?
|
||||
private Type type;
|
||||
|
||||
public VariableContext(InstructionContext i, Type t)
|
||||
public VariableContext(InstructionContext i, StackContext ctx)
|
||||
{
|
||||
ic = i;
|
||||
type = t;
|
||||
this.ctx = ctx;
|
||||
type = ctx.getType();
|
||||
}
|
||||
|
||||
public VariableContext(Type type) // for entrypoints
|
||||
{
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public StackContext getStackContext()
|
||||
{
|
||||
return ctx;
|
||||
}
|
||||
|
||||
public Type getType()
|
||||
|
||||
Reference in New Issue
Block a user