summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz/enigma/bytecode/LocalVariableRenamer.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/cuchaz/enigma/bytecode/LocalVariableRenamer.java')
-rw-r--r--src/main/java/cuchaz/enigma/bytecode/LocalVariableRenamer.java150
1 files changed, 0 insertions, 150 deletions
diff --git a/src/main/java/cuchaz/enigma/bytecode/LocalVariableRenamer.java b/src/main/java/cuchaz/enigma/bytecode/LocalVariableRenamer.java
deleted file mode 100644
index 878e30a..0000000
--- a/src/main/java/cuchaz/enigma/bytecode/LocalVariableRenamer.java
+++ /dev/null
@@ -1,150 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2015 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Lesser General Public
5 * License v3.0 which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/lgpl.html
7 * <p>
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11
12package cuchaz.enigma.bytecode;
13
14import cuchaz.enigma.mapping.*;
15import javassist.CtBehavior;
16import javassist.CtClass;
17import javassist.bytecode.*;
18
19public class LocalVariableRenamer {
20
21 private Translator translator;
22
23 public LocalVariableRenamer(Translator translator) {
24 this.translator = translator;
25 }
26
27 public void rename(CtClass c) {
28 for (CtBehavior behavior : c.getDeclaredBehaviors()) {
29
30 // if there's a local variable table, just rename everything to v1, v2, v3, ... for now
31 CodeAttribute codeAttribute = behavior.getMethodInfo().getCodeAttribute();
32 if (codeAttribute == null) {
33 continue;
34 }
35
36 BehaviorEntry behaviorEntry = EntryFactory.getBehaviorEntry(behavior);
37 ConstPool constants = c.getClassFile().getConstPool();
38
39 LocalVariableAttribute table = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
40 if (table != null) {
41 renameLVT(behaviorEntry, constants, table, c);
42 }
43
44 LocalVariableTypeAttribute typeTable = (LocalVariableTypeAttribute) codeAttribute.getAttribute(LocalVariableAttribute.typeTag);
45 if (typeTable != null) {
46 renameLVTT(typeTable, table);
47 }
48 }
49 }
50
51 // DEBUG
52 @SuppressWarnings("unused")
53 private void dumpTable(LocalVariableAttribute table) {
54 for (int i = 0; i < table.tableLength(); i++) {
55 System.out.println(String.format("\t%d (%d): %s %s",
56 i, table.index(i), table.variableName(i), table.descriptor(i)
57 ));
58 }
59 }
60
61 private void renameLVT(BehaviorEntry behaviorEntry, ConstPool constants, LocalVariableAttribute table, CtClass ctClass) {
62
63 // skip empty tables
64 if (table.tableLength() <= 0) {
65 return;
66 }
67
68 // where do we start counting variables?
69 int starti = 0;
70 if (table.variableName(0).equals("this")) {
71 // skip the "this" variable
72 starti++;
73 }
74
75 // rename method arguments first
76 int numArgs = 0;
77 if (behaviorEntry.getSignature() != null) {
78 numArgs = behaviorEntry.getSignature().getArgumentTypes().size();
79 boolean isNestedClassConstructor = false;
80
81 // If the behavior is a constructor and if it have more than one arg, it's probably from a nested!
82 if (behaviorEntry instanceof ConstructorEntry && behaviorEntry.getClassEntry() != null && behaviorEntry.getClassEntry().isInnerClass() && numArgs >= 1) {
83 // Get the first arg type
84 Type firstArg = behaviorEntry.getSignature().getArgumentTypes().get(0);
85
86 // If the arg is a class and if the class name match the outer class name of the constructor, it's definitely a constructor of a nested class
87 if (firstArg.isClass() && firstArg.getClassEntry().equals(behaviorEntry.getClassEntry().getOuterClassEntry())) {
88 isNestedClassConstructor = true;
89 numArgs--;
90 }
91 }
92
93 for (int i = starti; i < starti + numArgs && i < table.tableLength(); i++) {
94 int argi = i - starti;
95 if (ctClass.isEnum())
96 argi += 2;
97 if (behaviorEntry.getClassEntry().getName().contains("ahd") && behaviorEntry instanceof ConstructorEntry)
98 System.out.println(behaviorEntry.getClassEntry() + " " + i);
99 String argName = this.translator.translate(new ArgumentEntry(behaviorEntry, argi, ""));
100 if (argName == null) {
101 int argIndex = isNestedClassConstructor ? argi + 1 : argi;
102 if (ctClass.isEnum())
103 argIndex -= 2;
104 Type argType = behaviorEntry.getSignature().getArgumentTypes().get(argIndex);
105 // Unfortunately each of these have different name getters, so they have different code paths
106 if (argType.isPrimitive()) {
107 Type.Primitive argCls = argType.getPrimitive();
108 argName = "a" + argCls.name() + (argIndex + 1);
109 } else if (argType.isArray()) {
110 // List types would require this whole block again, so just go with aListx
111 argName = "aList" + (argIndex + 1);
112 } else if (argType.isClass()) {
113 ClassEntry argClsTrans = this.translator.translateEntry(argType.getClassEntry());
114 argName = "a" + argClsTrans.getSimpleName().replace("$", "") + (argIndex + 1);
115 } else {
116 argName = "a" + (argIndex + 1);
117 }
118 }
119 renameVariable(table, i, constants.addUtf8Info(argName));
120 }
121 }
122
123 // then rename the rest of the args, if any
124 for (int i = starti + numArgs; i < table.tableLength(); i++) {
125 int firstIndex = Math.min(table.index(starti + numArgs), table.index(i));
126 renameVariable(table, i, constants.addUtf8Info("v" + (table.index(i) - firstIndex + 1)));
127 }
128 }
129
130 private void renameLVTT(LocalVariableTypeAttribute typeTable, LocalVariableAttribute table) {
131 // rename args to the same names as in the LVT
132 for (int i = 0; i < typeTable.tableLength(); i++) {
133 renameVariable(typeTable, i, getNameIndex(table, typeTable.index(i)));
134 }
135 }
136
137 private void renameVariable(LocalVariableAttribute table, int i, int stringId) {
138 // based off of LocalVariableAttribute.nameIndex()
139 ByteArray.write16bit(stringId, table.get(), i * 10 + 6);
140 }
141
142 private int getNameIndex(LocalVariableAttribute table, int index) {
143 for (int i = 0; i < table.tableLength(); i++) {
144 if (table.index(i) == index) {
145 return table.nameIndex(i);
146 }
147 }
148 return 0;
149 }
150}