1 21 package proguard.classfile.editor; 22 23 import proguard.classfile.*; 24 import proguard.classfile.attribute.*; 25 import proguard.classfile.attribute.visitor.*; 26 import proguard.classfile.instruction.*; 27 import proguard.classfile.instruction.visitor.InstructionVisitor; 28 import proguard.classfile.util.SimplifiedVisitor; 29 30 36 public class VariableRemapper 37 extends SimplifiedVisitor 38 implements AttributeVisitor, 39 InstructionVisitor, 40 LocalVariableInfoVisitor, 41 LocalVariableTypeInfoVisitor 42 { 43 private CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(); 44 45 private int[] variableMap; 46 47 48 52 public void setVariableMap(int[] variableMap) 53 { 54 this.variableMap = variableMap; 55 } 56 57 58 60 public void visitAnyAttribute(Clazz clazz, Attribute attribute) {} 61 62 63 public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute) 64 { 65 codeAttributeEditor.reset(codeAttribute.u4codeLength); 67 68 codeAttribute.instructionsAccept(clazz, method, this); 70 71 codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute); 73 74 codeAttribute.attributesAccept(clazz, method, this); 76 } 77 78 79 public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute) 80 { 81 localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); 83 84 localVariableTableAttribute.u2localVariableTableLength = 86 removeEmptyLocalVariables(localVariableTableAttribute.localVariableTable, 87 localVariableTableAttribute.u2localVariableTableLength); 88 } 89 90 91 public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute) 92 { 93 localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this); 95 96 localVariableTypeTableAttribute.u2localVariableTypeTableLength = 98 removeEmptyLocalVariableTypes(localVariableTypeTableAttribute.localVariableTypeTable, 99 localVariableTypeTableAttribute.u2localVariableTypeTableLength); 100 } 101 102 103 105 public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo) 106 { 107 localVariableInfo.u2index = 108 remapVariable(localVariableInfo.u2index); 109 } 110 111 112 114 public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo) 115 { 116 localVariableTypeInfo.u2index = 117 remapVariable(localVariableTypeInfo.u2index); 118 } 119 120 121 123 public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {} 124 125 126 public void visitVariableInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VariableInstruction variableInstruction) 127 { 128 int oldVariableIndex = variableInstruction.variableIndex; 130 int newVariableIndex = remapVariable(oldVariableIndex); 131 if (newVariableIndex != oldVariableIndex) 132 { 133 Instruction replacementInstruction = 135 new VariableInstruction(variableInstruction.opcode, 136 newVariableIndex, 137 variableInstruction.constant).shrink(); 138 139 codeAttributeEditor.replaceInstruction(offset, replacementInstruction); 140 } 141 } 142 143 144 146 149 private int remapVariable(int variableIndex) 150 { 151 return variableMap[variableIndex]; 152 } 153 154 155 159 private int removeEmptyLocalVariables(LocalVariableInfo[] localVariableInfos, 160 int localVariableInfoCount) 161 { 162 int newIndex = 0; 164 for (int index = 0; index < localVariableInfoCount; index++) 165 { 166 LocalVariableInfo localVariableInfo = localVariableInfos[index]; 167 if (localVariableInfo.u2index >= 0) 168 { 169 localVariableInfos[newIndex++] = localVariableInfo; 170 } 171 } 172 173 return newIndex; 174 } 175 176 177 181 private int removeEmptyLocalVariableTypes(LocalVariableTypeInfo[] localVariableTypeInfos, 182 int localVariableTypeInfoCount) 183 { 184 int newIndex = 0; 186 for (int index = 0; index < localVariableTypeInfoCount; index++) 187 { 188 LocalVariableTypeInfo localVariableTypeInfo = localVariableTypeInfos[index]; 189 if (localVariableTypeInfo.u2index >= 0) 190 { 191 localVariableTypeInfos[newIndex++] = localVariableTypeInfo; 192 } 193 } 194 195 return newIndex; 196 } 197 } 198 | Popular Tags |