Skip to content

Commit

Permalink
Make FF'ers de class (IntPair) implement Comparable, strip util down …
Browse files Browse the repository at this point in the history
…to single sortComparable function. Much faster then stirng manipulation. Thanks Fry for inital broken code, closes #3
  • Loading branch information
LexManos committed Mar 30, 2014
1 parent 9c4a47e commit 8484eff
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,7 @@ public void processJar(String inFile, String outFile) throws IOException

// Add Out Util class:
String[] extras = {
Util.class.getCanonicalName().replace('.', '/') + ".class",
Util.class.getCanonicalName().replace('.', '/') + "$1.class"
Util.class.getCanonicalName().replace('.', '/') + ".class"
};
for (String name : extras)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* Thanks to fry for finding this issue and pointing me in the right direction.
*
* Code Injected:
* var15 = net.minecraftfroge.lex.fffixer.Util.sortStrings(var15);
* var15 = net.minecraftfroge.lex.fffixer.Util.sortComparable(var15);
*
* @author LexManos
*
Expand Down Expand Up @@ -53,7 +53,7 @@ public void process(ClassNode node)
VarInsnNode var = (VarInsnNode)insn;
InsnList toAdd = new InsnList();
toAdd.add(new VarInsnNode (ALOAD, var.var)); // var15 = fixInnerOrder(var15)
toAdd.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(Util.class), "sortStrings", "(Ljava/util/Iterator;)Ljava/util/Iterator;", false));
toAdd.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(Util.class), "sortComparable", "(Ljava/util/Iterator;)Ljava/util/Iterator;", false));
toAdd.add(new VarInsnNode (ASTORE, var.var));

mtd.instructions.insert(insn, toAdd); // Inject static call
Expand Down
44 changes: 3 additions & 41 deletions src/main/java/net/minecraftforge/lex/fffixer/Util.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,58 +2,20 @@

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

public class Util
{
public static Iterator<String> sortStrings(Iterator<String> itr)
@SuppressWarnings({ "unchecked", "rawtypes" })
public static <T extends Comparable> Iterator<T> sortComparable(Iterator<T> itr)
{
List<String> list = new ArrayList<String>();
List<T> list = new ArrayList<T>();

while (itr.hasNext())
list.add(itr.next());

Collections.sort(list);
return list.iterator();
}

public static void putIntercept(HashMap<Integer, Integer> map, Integer key, Integer value)
{
System.out.println("====================== " + key + " " + value);
map.put(key, value);
}
public static Iterator<Object> sortLvs(Iterator<Object> itr)
{
List<Object> list = new ArrayList<Object>();

while (itr.hasNext())
list.add(itr.next());

Collections.sort(list, new Comparator<Object>()
{
@Override
public int compare(Object o1, Object o2)
{
int[] a = getInts(o1.toString());
int[] b = getInts(o2.toString());
if (a[0] != b[0]) return a[0] - b[0];
return a[1] - b[1];

}
private int[] getInts(String val)
{
val = val.substring(1, val.length() - 1);
String[] tmp = val.split(",");
return new int[]
{
Integer.parseInt(tmp[0]),
Integer.parseInt(tmp[1])
};
}
});
return list.iterator();
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package net.minecraftforge.lex.fffixer;

import static org.objectweb.asm.Opcodes.ALOAD;
import static org.objectweb.asm.Opcodes.ASTORE;
import static org.objectweb.asm.Opcodes.INVOKESTATIC;
import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
import static org.objectweb.asm.Opcodes.*;

import java.util.Iterator;

import org.objectweb.asm.Label;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
Expand All @@ -20,10 +18,20 @@
* Simple solution is to hijack the Iterator to make it use a properly sorted one.
* Thanks to fry for finding this issue with class names, which then led me to look for var names.
*
* Code Injected:
* var = net.minecraftfroge.lex.fffixer.Util.sortLvs(var);
* Code Injected in d:
* var = net.minecraftfroge.lex.fffixer.Util.sortComparable(var);
*
* @author LexManos
* Code Injected in de (IntPair):
* implements Comparable<de>
* public int compareTo(de o)
* {
* if (this.a != o.a) return this.a - o.a;
* return this.b - o.b
* }
* public int compareTo(Object o)
* {
* return compareTo((de)o);
* }
*
*/
public class VariableNumberFixer implements IClassProcessor
Expand All @@ -37,8 +45,12 @@ public VariableNumberFixer(FFFixerImpl inst)
@Override
public void process(ClassNode node)
{
if (!node.name.equals("d")) return;
if (node.name.equals("d" )) fix_d (node);
if (node.name.equals("de")) fixIntPair(node);
}

private void fix_d(ClassNode node)
{
MethodNode mtd = FFFixerImpl.getMethod(node, "b", "(Lcu;Lq;)V");

Iterator<AbstractInsnNode> itr = mtd.instructions.iterator();
Expand All @@ -56,7 +68,7 @@ public void process(ClassNode node)
VarInsnNode var = (VarInsnNode)insn;
InsnList toAdd = new InsnList();
toAdd.add(new VarInsnNode (ALOAD, var.var)); // var15 = fixInnerOrder(var15)
toAdd.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(Util.class), "sortLvs", "(Ljava/util/Iterator;)Ljava/util/Iterator;", false));
toAdd.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(Util.class), "sortComparable", "(Ljava/util/Iterator;)Ljava/util/Iterator;", false));
toAdd.add(new VarInsnNode (ASTORE, var.var));

mtd.instructions.insert(insn, toAdd); // Inject static call
Expand All @@ -67,4 +79,53 @@ public void process(ClassNode node)
}
}
}

/**
* Make IntPair (de) extend Comparable, was doing this via string manipulation before because I was tired,
* but converted to ASM method injection for speed by fry, thanks.
*
* @param node The IntPair (de) class node
*/
private void fixIntPair(ClassNode node)
{
FFFixerImpl.log.info("Making IntPair Comparable");
node.signature = "Ljava/lang/Object;Ljava/lang/Comparable<Lde;>;";
node.interfaces.add("java/lang/Comparable");

MethodNode mn = new MethodNode(ACC_PUBLIC, "compareTo", "(Lde;)I", null, null);
mn.visitCode();
mn.visitVarInsn(ALOAD, 0);
mn.visitFieldInsn(GETFIELD, "de", "a", "I");
mn.visitVarInsn(ALOAD, 1);
mn.visitFieldInsn(GETFIELD, "de", "a", "I");
Label a_equals = new Label();
mn.visitJumpInsn(IF_ICMPEQ, a_equals); // if this.a == o.a goto a_euqals
mn.visitVarInsn(ALOAD, 0);
mn.visitFieldInsn(GETFIELD, "de", "a", "I");
mn.visitVarInsn(ALOAD, 1);
mn.visitFieldInsn(GETFIELD, "de", "a", "I");
mn.visitInsn(ISUB);
mn.visitInsn(IRETURN); // return this.a - o.a
mn.visitLabel(a_equals); // a_equals
mn.visitVarInsn(ALOAD, 0);
mn.visitFieldInsn(GETFIELD, "de", "b", "I");
mn.visitVarInsn(ALOAD, 1);
mn.visitFieldInsn(GETFIELD, "de", "b", "I");
mn.visitInsn(ISUB);
mn.visitInsn(IRETURN); // return this.b - o.b
mn.visitEnd();
node.methods.add(mn);

mn = new MethodNode(ACC_PUBLIC | ACC_BRIDGE | ACC_SYNTHETIC, "compareTo", "(Ljava/lang/Object;)I", null, null);
mn.visitCode();
mn.visitVarInsn(ALOAD, 0);
mn.visitVarInsn(ALOAD, 1);
mn.visitTypeInsn(CHECKCAST, "de");
mn.visitMethodInsn(INVOKEVIRTUAL, "de", "compareTo", "(Lde;)I", false); // Synthetic bounce of (Object) -> (IntPair)
mn.visitInsn(IRETURN);
mn.visitEnd();
node.methods.add(mn);

inst.setWorkDone();
}
}

0 comments on commit 8484eff

Please # to comment.