Commit a6a6084a00b237a9539ff52c653587b25aec2570
1 parent
1bfcfd90
add new convenience function replaceConstructors to ByteCodeUtilities
Showing
1 changed file
with
51 additions
and
11 deletions
java/common/com/mumfrey/liteloader/transformers/ByteCodeUtilities.java
@@ -9,22 +9,15 @@ import java.util.Map; | @@ -9,22 +9,15 @@ import java.util.Map; | ||
9 | 9 | ||
10 | import org.objectweb.asm.Opcodes; | 10 | import org.objectweb.asm.Opcodes; |
11 | import org.objectweb.asm.Type; | 11 | import org.objectweb.asm.Type; |
12 | -import org.objectweb.asm.tree.AbstractInsnNode; | ||
13 | -import org.objectweb.asm.tree.AnnotationNode; | ||
14 | -import org.objectweb.asm.tree.ClassNode; | ||
15 | -import org.objectweb.asm.tree.FieldNode; | ||
16 | -import org.objectweb.asm.tree.FrameNode; | ||
17 | -import org.objectweb.asm.tree.InsnList; | ||
18 | -import org.objectweb.asm.tree.LabelNode; | ||
19 | -import org.objectweb.asm.tree.LocalVariableNode; | ||
20 | -import org.objectweb.asm.tree.MethodNode; | ||
21 | -import org.objectweb.asm.tree.VarInsnNode; | 12 | +import org.objectweb.asm.tree.*; |
22 | import org.objectweb.asm.tree.analysis.Analyzer; | 13 | import org.objectweb.asm.tree.analysis.Analyzer; |
23 | import org.objectweb.asm.tree.analysis.AnalyzerException; | 14 | import org.objectweb.asm.tree.analysis.AnalyzerException; |
24 | import org.objectweb.asm.tree.analysis.BasicValue; | 15 | import org.objectweb.asm.tree.analysis.BasicValue; |
25 | import org.objectweb.asm.tree.analysis.Frame; | 16 | import org.objectweb.asm.tree.analysis.Frame; |
26 | import org.objectweb.asm.tree.analysis.SimpleVerifier; | 17 | import org.objectweb.asm.tree.analysis.SimpleVerifier; |
27 | 18 | ||
19 | +import com.mumfrey.liteloader.core.runtime.Obf; | ||
20 | + | ||
28 | /** | 21 | /** |
29 | * Utility methods for working with bytecode using ASM | 22 | * Utility methods for working with bytecode using ASM |
30 | * | 23 | * |
@@ -35,7 +28,54 @@ public abstract class ByteCodeUtilities | @@ -35,7 +28,54 @@ public abstract class ByteCodeUtilities | ||
35 | private static Map<String, List<LocalVariableNode>> calculatedLocalVariables = new HashMap<String, List<LocalVariableNode>>(); | 28 | private static Map<String, List<LocalVariableNode>> calculatedLocalVariables = new HashMap<String, List<LocalVariableNode>>(); |
36 | 29 | ||
37 | private ByteCodeUtilities() {} | 30 | private ByteCodeUtilities() {} |
38 | - | 31 | + |
32 | + /** | ||
33 | + * Replace all constructor invokations for the target class in the supplied classNode with invokations of the replacement class | ||
34 | + * | ||
35 | + * @param classNode Class to search in | ||
36 | + * @param target Target type | ||
37 | + * @param replacement Replacement type | ||
38 | + */ | ||
39 | + public static void replaceConstructors(ClassNode classNode, Obf target, Obf replacement) | ||
40 | + { | ||
41 | + for (MethodNode method : classNode.methods) | ||
42 | + { | ||
43 | + ByteCodeUtilities.replaceConstructors(method, target, replacement); | ||
44 | + } | ||
45 | + } | ||
46 | + | ||
47 | + /** | ||
48 | + * Replace all constructor invokations for the target class in the supplied method with invokations of the replacement class | ||
49 | + * | ||
50 | + * @param method Method to look in | ||
51 | + * @param target Target type | ||
52 | + * @param replacement Replacement type | ||
53 | + */ | ||
54 | + public static void replaceConstructors(MethodNode method, Obf target, Obf replacement) | ||
55 | + { | ||
56 | + Iterator<AbstractInsnNode> iter = method.instructions.iterator(); | ||
57 | + while (iter.hasNext()) | ||
58 | + { | ||
59 | + AbstractInsnNode insn = iter.next(); | ||
60 | + if (insn.getOpcode() == Opcodes.NEW) | ||
61 | + { | ||
62 | + TypeInsnNode typeInsn = (TypeInsnNode)insn; | ||
63 | + if (target.obf.equals(typeInsn.desc) || target.name.equals(typeInsn.desc)) | ||
64 | + { | ||
65 | + typeInsn.desc = replacement.name; | ||
66 | + } | ||
67 | + } | ||
68 | + else if (insn instanceof MethodInsnNode && insn.getOpcode() == Opcodes.INVOKESPECIAL) | ||
69 | + { | ||
70 | + MethodInsnNode methodInsn = (MethodInsnNode)insn; | ||
71 | + if ((target.obf.equals(methodInsn.owner) || target.name.equals(methodInsn.owner)) && "<init>".equals(methodInsn.name)) | ||
72 | + { | ||
73 | + methodInsn.owner = replacement.name; | ||
74 | + } | ||
75 | + } | ||
76 | + } | ||
77 | + } | ||
78 | + | ||
39 | /** | 79 | /** |
40 | * Injects appropriate LOAD opcodes into the supplied InsnList appropriate for each entry in the args array starting at pos | 80 | * Injects appropriate LOAD opcodes into the supplied InsnList appropriate for each entry in the args array starting at pos |
41 | * | 81 | * |