| 1 21 package proguard.classfile.instruction; 22 23 import proguard.classfile.*; 24 import proguard.classfile.instruction.visitor.InstructionVisitor; 25 import proguard.classfile.attribute.*; 26 27 33 public class SimpleInstruction extends Instruction 34 { 35 public int constant; 36 37 38 41 public SimpleInstruction() {} 42 43 44 47 public SimpleInstruction(byte opcode) 48 { 49 this(opcode, embeddedConstant(opcode)); 50 } 51 52 53 56 public SimpleInstruction(byte opcode, int constant) 57 { 58 this.opcode = opcode; 59 this.constant = constant; 60 } 61 62 63 68 public SimpleInstruction copy(SimpleInstruction simpleInstruction) 69 { 70 this.opcode = simpleInstruction.opcode; 71 this.constant = simpleInstruction.constant; 72 73 return this; 74 } 75 76 77 81 private static int embeddedConstant(byte opcode) 82 { 83 switch (opcode) 84 { 85 case InstructionConstants.OP_ICONST_M1: return -1; 86 87 case InstructionConstants.OP_ICONST_1: 88 case InstructionConstants.OP_LCONST_1: 89 case InstructionConstants.OP_FCONST_1: 90 case InstructionConstants.OP_DCONST_1: return 1; 91 92 case InstructionConstants.OP_ICONST_2: 93 case InstructionConstants.OP_FCONST_2: return 2; 94 95 case InstructionConstants.OP_ICONST_3: return 3; 96 97 case InstructionConstants.OP_ICONST_4: return 4; 98 99 case InstructionConstants.OP_ICONST_5: return 5; 100 101 default: return 0; 102 } 103 } 104 105 106 108 public byte canonicalOpcode() 109 { 110 switch (opcode) 112 { 113 case InstructionConstants.OP_ICONST_M1: 114 case InstructionConstants.OP_ICONST_0: 115 case InstructionConstants.OP_ICONST_1: 116 case InstructionConstants.OP_ICONST_2: 117 case InstructionConstants.OP_ICONST_3: 118 case InstructionConstants.OP_ICONST_4: 119 case InstructionConstants.OP_ICONST_5: 120 case InstructionConstants.OP_BIPUSH: 121 case InstructionConstants.OP_SIPUSH: return InstructionConstants.OP_ICONST_0; 122 123 case InstructionConstants.OP_LCONST_0: 124 case InstructionConstants.OP_LCONST_1: return InstructionConstants.OP_LCONST_0; 125 126 case InstructionConstants.OP_FCONST_0: 127 case InstructionConstants.OP_FCONST_1: 128 case InstructionConstants.OP_FCONST_2: return InstructionConstants.OP_FCONST_0; 129 130 case InstructionConstants.OP_DCONST_0: 131 case InstructionConstants.OP_DCONST_1: return InstructionConstants.OP_DCONST_0; 132 133 default: return opcode; 134 } 135 } 136 137 public Instruction shrink() 138 { 139 if (opcode == InstructionConstants.OP_SIPUSH && 141 constant << 24 >> 24 == constant) 142 { 143 opcode = InstructionConstants.OP_BIPUSH; 144 } 145 146 if (opcode == InstructionConstants.OP_BIPUSH && 148 constant >= -1 && 149 constant <= 5) 150 { 151 opcode = (byte)(InstructionConstants.OP_ICONST_0 + constant); 152 } 153 154 return this; 155 } 156 157 protected void readInfo(byte[] code, int offset) 158 { 159 int constantSize = constantSize(); 160 161 constant = constantSize == 0 ? 163 embeddedConstant(opcode) : 164 readSignedValue(code, offset, constantSize); 165 } 166 167 168 protected void writeInfo(byte[] code, int offset) 169 { 170 int constantSize = constantSize(); 171 172 if (requiredConstantSize() > constantSize) 173 { 174 throw new IllegalArgumentException ("Instruction has invalid constant size ("+this.toString(offset)+")"); 175 } 176 177 writeSignedValue(code, offset, constant, constantSize); 178 } 179 180 181 public int length(int offset) 182 { 183 return 1 + constantSize(); 184 } 185 186 187 public void accept(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, InstructionVisitor instructionVisitor) 188 { 189 instructionVisitor.visitSimpleInstruction(clazz, method, codeAttribute, offset, this); 190 } 191 192 193 195 public String toString() 196 { 197 return getName() + 198 (constantSize() > 0 ? " "+constant : ""); 199 } 200 201 202 204 207 private int constantSize() 208 { 209 return opcode == InstructionConstants.OP_BIPUSH || 210 opcode == InstructionConstants.OP_NEWARRAY ? 1 : 211 opcode == InstructionConstants.OP_SIPUSH ? 2 : 212 0; 213 } 214 215 216 219 private int requiredConstantSize() 220 { 221 return constant >= -1 && constant <= 5 ? 0 : 222 constant << 24 >> 24 == constant ? 1 : 223 constant << 16 >> 16 == constant ? 2 : 224 4; 225 } 226 } 227 | Popular Tags |