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 | * |