diff --git a/pom.xml b/pom.xml
index 9e5f2a3779..bc0a1b08cd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,6 +9,11 @@
commons-collections4
4.0
+
+ com.google.guava
+ guava
+ 18.0
+
1.7
diff --git a/src/main/java/net/runelite/deob/Deob.java b/src/main/java/net/runelite/deob/Deob.java
index e4a2f0e852..c06da885e0 100644
--- a/src/main/java/net/runelite/deob/Deob.java
+++ b/src/main/java/net/runelite/deob/Deob.java
@@ -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)
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/AStore.java b/src/main/java/net/runelite/deob/attributes/code/instructions/AStore.java
index c9be0e2871..bc60499d24 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/AStore.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/AStore.java
@@ -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);
}
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/AStore_0.java b/src/main/java/net/runelite/deob/attributes/code/instructions/AStore_0.java
index b50facc376..35398c1d24 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/AStore_0.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/AStore_0.java
@@ -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);
}
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/AStore_1.java b/src/main/java/net/runelite/deob/attributes/code/instructions/AStore_1.java
index cdf7eef8bf..d84cb9c720 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/AStore_1.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/AStore_1.java
@@ -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);
}
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/AStore_2.java b/src/main/java/net/runelite/deob/attributes/code/instructions/AStore_2.java
index 0fe269e06c..64ac69d01a 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/AStore_2.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/AStore_2.java
@@ -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);
}
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/AStore_3.java b/src/main/java/net/runelite/deob/attributes/code/instructions/AStore_3.java
index 83a68173d3..7c23783764 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/AStore_3.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/AStore_3.java
@@ -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);
}
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/DStore.java b/src/main/java/net/runelite/deob/attributes/code/instructions/DStore.java
index 86aa156eb2..a42a618723 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/DStore.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/DStore.java
@@ -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);
}
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/DStore_0.java b/src/main/java/net/runelite/deob/attributes/code/instructions/DStore_0.java
index ebf6d23823..3322e85d71 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/DStore_0.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/DStore_0.java
@@ -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);
}
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/DStore_1.java b/src/main/java/net/runelite/deob/attributes/code/instructions/DStore_1.java
index 820414446c..cdfde5640f 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/DStore_1.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/DStore_1.java
@@ -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);
}
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/DStore_2.java b/src/main/java/net/runelite/deob/attributes/code/instructions/DStore_2.java
index e36647d59d..3788b920ca 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/DStore_2.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/DStore_2.java
@@ -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);
}
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/DStore_3.java b/src/main/java/net/runelite/deob/attributes/code/instructions/DStore_3.java
index 6cf08eb68a..67d3bf2bec 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/DStore_3.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/DStore_3.java
@@ -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);
}
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/FStore.java b/src/main/java/net/runelite/deob/attributes/code/instructions/FStore.java
index 1d5fab31b6..53f08a4966 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/FStore.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/FStore.java
@@ -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);
}
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/FStore_0.java b/src/main/java/net/runelite/deob/attributes/code/instructions/FStore_0.java
index 3b0da59b63..a3dab0aa92 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/FStore_0.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/FStore_0.java
@@ -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);
}
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/FStore_1.java b/src/main/java/net/runelite/deob/attributes/code/instructions/FStore_1.java
index d0736386ed..98d60c641a 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/FStore_1.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/FStore_1.java
@@ -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);
}
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/FStore_2.java b/src/main/java/net/runelite/deob/attributes/code/instructions/FStore_2.java
index 84793108d6..d5523c228b 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/FStore_2.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/FStore_2.java
@@ -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);
}
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/FStore_3.java b/src/main/java/net/runelite/deob/attributes/code/instructions/FStore_3.java
index 5c66bb1749..7bc1cf4360 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/FStore_3.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/FStore_3.java
@@ -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);
}
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IInc.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IInc.java
index 027623c711..0ab042b8af 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/IInc.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IInc.java
@@ -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);
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IStore.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IStore.java
index 8361f18a08..df295480f0 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/IStore.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IStore.java
@@ -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);
}
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IStore_0.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IStore_0.java
index f15f07b2db..7b006d99a8 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/IStore_0.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IStore_0.java
@@ -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);
}
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IStore_1.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IStore_1.java
index 418de02b5b..1479303179 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/IStore_1.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IStore_1.java
@@ -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);
}
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IStore_2.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IStore_2.java
index a8676da489..446174772d 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/IStore_2.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IStore_2.java
@@ -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);
}
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IStore_3.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IStore_3.java
index b267b2e363..5577669d07 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/IStore_3.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IStore_3.java
@@ -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);
}
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeInterface.java b/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeInterface.java
index f6a02de4ae..316a96b001 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeInterface.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeInterface.java
@@ -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);
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeSpecial.java b/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeSpecial.java
index f5d08d2547..4620440f14 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeSpecial.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeSpecial.java
@@ -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);
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeStatic.java b/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeStatic.java
index 8b5532d352..6c3b057f73 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeStatic.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeStatic.java
@@ -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);
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeVirtual.java b/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeVirtual.java
index 4f1637fa4e..8a33320d8e 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeVirtual.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/InvokeVirtual.java
@@ -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);
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/LStore.java b/src/main/java/net/runelite/deob/attributes/code/instructions/LStore.java
index b8b95937b8..7f519055e2 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/LStore.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/LStore.java
@@ -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);
}
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/LStore_0.java b/src/main/java/net/runelite/deob/attributes/code/instructions/LStore_0.java
index 2f7032d8c1..c8078a299e 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/LStore_0.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/LStore_0.java
@@ -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);
}
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/LStore_1.java b/src/main/java/net/runelite/deob/attributes/code/instructions/LStore_1.java
index 798be7d83d..37abaf59e1 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/LStore_1.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/LStore_1.java
@@ -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);
}
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/LStore_2.java b/src/main/java/net/runelite/deob/attributes/code/instructions/LStore_2.java
index 879c116d9b..943cd3adef 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/LStore_2.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/LStore_2.java
@@ -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);
}
diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/LStore_3.java b/src/main/java/net/runelite/deob/attributes/code/instructions/LStore_3.java
index ba25d5acaf..67f80040c7 100644
--- a/src/main/java/net/runelite/deob/attributes/code/instructions/LStore_3.java
+++ b/src/main/java/net/runelite/deob/attributes/code/instructions/LStore_3.java
@@ -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);
}
diff --git a/src/main/java/net/runelite/deob/execution/Execution.java b/src/main/java/net/runelite/deob/execution/Execution.java
index 9cfad7e2a7..0aa5489201 100644
--- a/src/main/java/net/runelite/deob/execution/Execution.java
+++ b/src/main/java/net/runelite/deob/execution/Execution.java
@@ -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 frames = new ArrayList<>(),
processedFrames = new ArrayList<>();
- private List pendingMethods = new ArrayList<>(); // pending methods
public Set methods = new HashSet<>(); // all methods
public Set executed = new HashSet<>(); // executed instructions
+ private MultiValueMap 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(""))
{
- 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 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");
}
}
diff --git a/src/main/java/net/runelite/deob/execution/Frame.java b/src/main/java/net/runelite/deob/execution/Frame.java
index efb9ecc243..9761555f08 100644
--- a/src/main/java/net/runelite/deob/execution/Frame.java
+++ b/src/main/java/net/runelite/deob/execution/Frame.java
@@ -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 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);
}
diff --git a/src/main/java/net/runelite/deob/execution/InstructionContext.java b/src/main/java/net/runelite/deob/execution/InstructionContext.java
index 07a6126c0a..903cdbd837 100644
--- a/src/main/java/net/runelite/deob/execution/InstructionContext.java
+++ b/src/main/java/net/runelite/deob/execution/InstructionContext.java
@@ -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)
diff --git a/src/main/java/net/runelite/deob/execution/VariableContext.java b/src/main/java/net/runelite/deob/execution/VariableContext.java
index 737f49713f..3e6a0f9fd6 100644
--- a/src/main/java/net/runelite/deob/execution/VariableContext.java
+++ b/src/main/java/net/runelite/deob/execution/VariableContext.java
@@ -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()