diff options
Diffstat (limited to '')
| -rw-r--r-- | src/cuchaz/enigma/bytecode/LocalVariableRenamer.java | 70 |
1 files changed, 65 insertions, 5 deletions
diff --git a/src/cuchaz/enigma/bytecode/LocalVariableRenamer.java b/src/cuchaz/enigma/bytecode/LocalVariableRenamer.java index c87c25b..1179560 100644 --- a/src/cuchaz/enigma/bytecode/LocalVariableRenamer.java +++ b/src/cuchaz/enigma/bytecode/LocalVariableRenamer.java | |||
| @@ -6,9 +6,20 @@ import javassist.bytecode.ByteArray; | |||
| 6 | import javassist.bytecode.CodeAttribute; | 6 | import javassist.bytecode.CodeAttribute; |
| 7 | import javassist.bytecode.ConstPool; | 7 | import javassist.bytecode.ConstPool; |
| 8 | import javassist.bytecode.LocalVariableAttribute; | 8 | import javassist.bytecode.LocalVariableAttribute; |
| 9 | import javassist.bytecode.LocalVariableTypeAttribute; | ||
| 10 | import cuchaz.enigma.mapping.ArgumentEntry; | ||
| 11 | import cuchaz.enigma.mapping.BehaviorEntry; | ||
| 12 | import cuchaz.enigma.mapping.EntryFactory; | ||
| 13 | import cuchaz.enigma.mapping.Translator; | ||
| 9 | 14 | ||
| 10 | 15 | ||
| 11 | public class LocalVariableRenamer { | 16 | public class LocalVariableRenamer { |
| 17 | |||
| 18 | private Translator m_translator; | ||
| 19 | |||
| 20 | public LocalVariableRenamer(Translator translator) { | ||
| 21 | m_translator = translator; | ||
| 22 | } | ||
| 12 | 23 | ||
| 13 | public void rename(CtClass c) { | 24 | public void rename(CtClass c) { |
| 14 | for (CtBehavior behavior : c.getDeclaredBehaviors()) { | 25 | for (CtBehavior behavior : c.getDeclaredBehaviors()) { |
| @@ -18,18 +29,67 @@ public class LocalVariableRenamer { | |||
| 18 | if (codeAttribute == null) { | 29 | if (codeAttribute == null) { |
| 19 | continue; | 30 | continue; |
| 20 | } | 31 | } |
| 32 | |||
| 33 | BehaviorEntry behaviorEntry = EntryFactory.getBehaviorEntry(behavior); | ||
| 34 | ConstPool constants = c.getClassFile().getConstPool(); | ||
| 35 | |||
| 21 | LocalVariableAttribute table = (LocalVariableAttribute)codeAttribute.getAttribute(LocalVariableAttribute.tag); | 36 | LocalVariableAttribute table = (LocalVariableAttribute)codeAttribute.getAttribute(LocalVariableAttribute.tag); |
| 22 | if (table == null) { | 37 | if (table != null) { |
| 23 | continue; | 38 | renameTable(behaviorEntry, constants, table); |
| 24 | } | 39 | } |
| 25 | 40 | ||
| 26 | ConstPool constants = c.getClassFile().getConstPool(); | 41 | LocalVariableTypeAttribute typeTable = (LocalVariableTypeAttribute)codeAttribute.getAttribute(LocalVariableAttribute.typeTag); |
| 27 | for (int i=0; i<table.tableLength(); i++) { | 42 | if (typeTable != null) { |
| 28 | renameVariable(table, i, constants.addUtf8Info("v" + i)); | 43 | renameTable(behaviorEntry, constants, typeTable); |
| 29 | } | 44 | } |
| 30 | } | 45 | } |
| 31 | } | 46 | } |
| 32 | 47 | ||
| 48 | // DEBUG | ||
| 49 | @SuppressWarnings("unused") | ||
| 50 | private void dumpTable(LocalVariableAttribute table) { | ||
| 51 | for (int i=0; i<table.tableLength(); i++) { | ||
| 52 | System.out.println(String.format("\t%d (%d): %s %s", | ||
| 53 | i, table.index(i), table.variableName(i), table.descriptor(i) | ||
| 54 | )); | ||
| 55 | } | ||
| 56 | } | ||
| 57 | |||
| 58 | private void renameTable(BehaviorEntry behaviorEntry, ConstPool constants, LocalVariableAttribute table) { | ||
| 59 | |||
| 60 | // skip empty tables | ||
| 61 | if (table.tableLength() <= 0) { | ||
| 62 | return; | ||
| 63 | } | ||
| 64 | |||
| 65 | // where do we start counting variables? | ||
| 66 | int starti = 0; | ||
| 67 | if (table.variableName(0).equals("this")) { | ||
| 68 | // skip the "this" variable | ||
| 69 | starti = 1; | ||
| 70 | } | ||
| 71 | |||
| 72 | // rename method arguments first | ||
| 73 | int numArgs = 0; | ||
| 74 | if (behaviorEntry.getSignature() != null) { | ||
| 75 | numArgs = behaviorEntry.getSignature().getArgumentTypes().size(); | ||
| 76 | for (int i=starti; i<starti + numArgs && i<table.tableLength(); i++) { | ||
| 77 | int argi = i - starti; | ||
| 78 | String argName = m_translator.translate(new ArgumentEntry(behaviorEntry, argi, "")); | ||
| 79 | if (argName == null) { | ||
| 80 | argName = "a" + (argi + 1); | ||
| 81 | } | ||
| 82 | renameVariable(table, i, constants.addUtf8Info(argName)); | ||
| 83 | } | ||
| 84 | } | ||
| 85 | |||
| 86 | // then rename the rest of the args, if any | ||
| 87 | for (int i=starti + numArgs; i<table.tableLength(); i++) { | ||
| 88 | int firstIndex = table.index(starti + numArgs); | ||
| 89 | renameVariable(table, i, constants.addUtf8Info("v" + (table.index(i) - firstIndex + 1))); | ||
| 90 | } | ||
| 91 | } | ||
| 92 | |||
| 33 | private void renameVariable(LocalVariableAttribute table, int i, int stringId) { | 93 | private void renameVariable(LocalVariableAttribute table, int i, int stringId) { |
| 34 | // based off of LocalVariableAttribute.nameIndex() | 94 | // based off of LocalVariableAttribute.nameIndex() |
| 35 | ByteArray.write16bit(stringId, table.get(), i*10 + 6); | 95 | ByteArray.write16bit(stringId, table.get(), i*10 + 6); |