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